This commit is contained in:
Nick Bebout 2017-09-23 16:54:48 -05:00
parent 3afeea4a16
commit 8d76e44c5e
243 changed files with 57452 additions and 10330 deletions

View file

@ -441,3 +441,139 @@
1471606171 BEGIN 1.727 : vendredi 19 août 2016, 13:29:31 (UTC+0200)
1471616659 BEGIN 1.727 : vendredi 19 août 2016, 16:24:19 (UTC+0200)
1471617309 END 1.727 : vendredi 19 août 2016, 16:35:09 (UTC+0200)
1474122976 BEGIN 1.730 : samedi 17 septembre 2016, 16:36:16 (UTC+0200)
1474123287 END 1.730 : samedi 17 septembre 2016, 16:41:27 (UTC+0200)
1475152767 BEGIN 1.731 : jeudi 29 septembre 2016, 14:39:27 (UTC+0200)
1475153042 END 1.731 : jeudi 29 septembre 2016, 14:44:02 (UTC+0200)
1475183016 BEGIN 1.732 : jeudi 29 septembre 2016, 23:03:36 (UTC+0200)
1475183329 END 1.732 : jeudi 29 septembre 2016, 23:08:49 (UTC+0200)
1476189796 BEGIN 1.737 : mardi 11 octobre 2016, 14:43:16 (UTC+0200)
1476190171 END 1.737 : mardi 11 octobre 2016, 14:49:31 (UTC+0200)
1478207726 BEGIN 1.739 : jeudi 3 novembre 2016, 22:15:26 (UTC+0100)
1478208016 END 1.739 : jeudi 3 novembre 2016, 22:20:16 (UTC+0100)
1479397595 BEGIN 1.740 : jeudi 17 novembre 2016, 16:46:36 (UTC+0100)
1479397878 END 1.740 : jeudi 17 novembre 2016, 16:51:18 (UTC+0100)
1479853031 BEGIN 1.741 : mardi 22 novembre 2016, 23:17:11 (UTC+0100)
1479853321 END 1.741 : mardi 22 novembre 2016, 23:22:01 (UTC+0100)
1482594346 BEGIN 1.747 : samedi 24 décembre 2016, 16:45:46 (UTC+0100)
1483589059 BEGIN 1.749 : jeudi 5 janvier 2017, 05:04:19 (UTC+0100)
1483589684 BEGIN 1.749 : jeudi 5 janvier 2017, 05:14:44 (UTC+0100)
1483589923 END 1.749 : jeudi 5 janvier 2017, 05:18:43 (UTC+0100)
1483624220 BEGIN 1.750 : jeudi 5 janvier 2017, 14:50:20 (UTC+0100)
1483624536 END 1.750 : jeudi 5 janvier 2017, 14:55:36 (UTC+0100)
1483945333 BEGIN 1.751 : lundi 9 janvier 2017, 08:02:13 (UTC+0100)
1483949465 BEGIN 1.751 : lundi 9 janvier 2017, 09:11:05 (UTC+0100)
1483984043 BEGIN 1.751 : lundi 9 janvier 2017, 18:47:23 (UTC+0100)
1484009458 BEGIN 1.752 : mardi 10 janvier 2017, 01:50:58 (UTC+0100)
1484009742 END 1.752 : mardi 10 janvier 2017, 01:55:42 (UTC+0100)
1484112177 BEGIN 1.753 : mercredi 11 janvier 2017, 06:22:57 (UTC+0100)
1484112484 END 1.753 : mercredi 11 janvier 2017, 06:28:04 (UTC+0100)
1484217375 BEGIN 1.757 : jeudi 12 janvier 2017, 11:36:15 (UTC+0100)
1484217700 END 1.757 : jeudi 12 janvier 2017, 11:41:40 (UTC+0100)
1484516992 BEGIN 1.758 : dimanche 15 janvier 2017, 22:49:52 (UTC+0100)
1484517360 END 1.758 : dimanche 15 janvier 2017, 22:56:00 (UTC+0100)
1484577677 BEGIN 1.759 : lundi 16 janvier 2017, 15:41:17 (UTC+0100)
1484578003 END 1.759 : lundi 16 janvier 2017, 15:46:43 (UTC+0100)
1484628512 BEGIN 1.760 : mardi 17 janvier 2017, 05:48:32 (UTC+0100)
1484628850 END 1.760 : mardi 17 janvier 2017, 05:54:10 (UTC+0100)
1484633474 BEGIN 1.761 : mardi 17 janvier 2017, 07:11:14 (UTC+0100)
1484633792 END 1.761 : mardi 17 janvier 2017, 07:16:32 (UTC+0100)
1484788241 BEGIN 1.763 : jeudi 19 janvier 2017, 02:10:41 (UTC+0100)
1484788555 END 1.763 : jeudi 19 janvier 2017, 02:15:55 (UTC+0100)
1484803145 BEGIN 1.765 : jeudi 19 janvier 2017, 06:19:05 (UTC+0100)
1484804058 BEGIN 1.766 : jeudi 19 janvier 2017, 06:34:18 (UTC+0100)
1484804378 END 1.766 : jeudi 19 janvier 2017, 06:39:38 (UTC+0100)
1484805361 BEGIN 1.767 : jeudi 19 janvier 2017, 06:56:01 (UTC+0100)
1484805735 END 1.767 : jeudi 19 janvier 2017, 07:02:16 (UTC+0100)
1484806480 BEGIN 1.768 : jeudi 19 janvier 2017, 07:14:40 (UTC+0100)
1484806804 END 1.768 : jeudi 19 janvier 2017, 07:20:04 (UTC+0100)
1485900842 BEGIN 1.771 : mardi 31 janvier 2017, 23:14:02 (UTC+0100)
1485901133 BEGIN 1.771 : mardi 31 janvier 2017, 23:18:53 (UTC+0100)
1485901561 END 1.771 : mardi 31 janvier 2017, 23:26:01 (UTC+0100)
1487116017 BEGIN 1.773 : mercredi 15 février 2017, 00:46:57 (UTC+0100)
1487157193 BEGIN 1.773 : mercredi 15 février 2017, 12:13:13 (UTC+0100)
1487169674 BEGIN 1.774 : mercredi 15 février 2017, 15:41:14 (UTC+0100)
1487188465 BEGIN 1.774 : mercredi 15 février 2017, 20:54:25 (UTC+0100)
1487240884 BEGIN 1.774 : jeudi 16 février 2017, 11:28:04 (UTC+0100)
1487296664 BEGIN 1.775 : vendredi 17 février 2017, 02:57:44 (UTC+0100)
1487296925 END 1.775 : vendredi 17 février 2017, 03:02:05 (UTC+0100)
1488337707 BEGIN 1.777 : mercredi 1 mars 2017, 04:08:28 (UTC+0100)
1488338331 END 1.777 : mercredi 1 mars 2017, 04:18:51 (UTC+0100)
1489416028 BEGIN 1.783 : lundi 13 mars 2017, 15:40:28 (UTC+0100)
1489416325 END 1.783 : lundi 13 mars 2017, 15:45:25 (UTC+0100)
1489514968 BEGIN 1.785 : mardi 14 mars 2017, 19:09:28 (UTC+0100)
1489515233 END 1.785 : mardi 14 mars 2017, 19:13:53 (UTC+0100)
1489980931 BEGIN 1.786 : lundi 20 mars 2017, 04:35:31 (UTC+0100)
1490084192 BEGIN 1.788 : mardi 21 mars 2017, 09:16:32 (UTC+0100)
1490084443 END 1.788 : mardi 21 mars 2017, 09:20:43 (UTC+0100)
1492680526 BEGIN 1.794 : jeudi 20 avril 2017, 11:28:46 (UTC+0200)
1492680802 END 1.794 : jeudi 20 avril 2017, 11:33:22 (UTC+0200)
1493248850 BEGIN 1.803 : jeudi 27 avril 2017, 01:20:50 (UTC+0200)
1493249119 END 1.803 : jeudi 27 avril 2017, 01:25:19 (UTC+0200)
1493253906 BEGIN 1.804 : jeudi 27 avril 2017, 02:45:06 (UTC+0200)
1493254173 END 1.804 : jeudi 27 avril 2017, 02:49:33 (UTC+0200)
1493298460 BEGIN 1.805 : jeudi 27 avril 2017, 15:07:40 (UTC+0200)
1493299002 BEGIN 1.805 : jeudi 27 avril 2017, 15:16:42 (UTC+0200)
1493299269 END 1.805 : jeudi 27 avril 2017, 15:21:09 (UTC+0200)
1493387151 BEGIN 1.807 : vendredi 28 avril 2017, 15:45:51 (UTC+0200)
1493387431 END 1.807 : vendredi 28 avril 2017, 15:50:31 (UTC+0200)
1493578212 BEGIN 1.807 : dimanche 30 avril 2017, 20:50:12 (UTC+0200)
1493578413 END 1.807 : dimanche 30 avril 2017, 20:53:33 (UTC+0200)
1493586266 BEGIN 1.807 : dimanche 30 avril 2017, 23:04:26 (UTC+0200)
1493586762 END 1.807 : dimanche 30 avril 2017, 23:12:42 (UTC+0200)
1493587646 BEGIN 1.807 : dimanche 30 avril 2017, 23:27:26 (UTC+0200)
1493588141 END 1.807 : dimanche 30 avril 2017, 23:35:41 (UTC+0200)
1493642636 BEGIN 1.807 : lundi 1 mai 2017, 14:43:56 (UTC+0200)
1493642871 END 1.807 : lundi 1 mai 2017, 14:47:51 (UTC+0200)
1493662775 BEGIN 1.807 : lundi 1 mai 2017, 20:19:35 (UTC+0200)
1493663003 END 1.807 : lundi 1 mai 2017, 20:23:23 (UTC+0200)
1493676290 BEGIN 1.807 : mardi 2 mai 2017, 00:04:50 (UTC+0200)
1493676496 END 1.807 : mardi 2 mai 2017, 00:08:16 (UTC+0200)
1493676673 BEGIN 1.807 : mardi 2 mai 2017, 00:11:13 (UTC+0200)
1493676871 END 1.807 : mardi 2 mai 2017, 00:14:31 (UTC+0200)
1493685869 BEGIN 1.807 : mardi 2 mai 2017, 02:44:29 (UTC+0200)
1493686077 END 1.807 : mardi 2 mai 2017, 02:47:57 (UTC+0200)
1493709285 BEGIN 1.807 : mardi 2 mai 2017, 09:14:45 (UTC+0200)
1493709482 END 1.807 : mardi 2 mai 2017, 09:18:02 (UTC+0200)
1493710750 BEGIN 1.807 : mardi 2 mai 2017, 09:39:10 (UTC+0200)
1493710951 END 1.807 : mardi 2 mai 2017, 09:42:31 (UTC+0200)
1493714417 BEGIN 1.807 : mardi 2 mai 2017, 10:40:17 (UTC+0200)
1493714614 END 1.807 : mardi 2 mai 2017, 10:43:34 (UTC+0200)
1493746207 BEGIN 1.807 : mardi 2 mai 2017, 19:30:07 (UTC+0200)
1493746268 BEGIN 1.807 : mardi 2 mai 2017, 19:31:08 (UTC+0200)
1493746540 END 1.807 : mardi 2 mai 2017, 19:35:40 (UTC+0200)
1493747268 BEGIN 1.808 : mardi 2 mai 2017, 19:47:48 (UTC+0200)
1493747469 END 1.808 : mardi 2 mai 2017, 19:51:09 (UTC+0200)
1493749409 BEGIN 1.808 : mardi 2 mai 2017, 20:23:29 (UTC+0200)
1493749606 END 1.808 : mardi 2 mai 2017, 20:26:46 (UTC+0200)
1493750039 BEGIN 1.808 : mardi 2 mai 2017, 20:33:59 (UTC+0200)
1493750963 BEGIN 1.810 : mardi 2 mai 2017, 20:49:23 (UTC+0200)
1493751248 END 1.810 : mardi 2 mai 2017, 20:54:08 (UTC+0200)
1495648275 BEGIN 1.813 : mercredi 24 mai 2017, 19:51:15 (UTC+0200)
1495648641 END 1.813 : mercredi 24 mai 2017, 19:57:21 (UTC+0200)
1499474148 BEGIN 1.819 : samedi 8 juillet 2017, 02:35:48 (UTC+0200)
1499537272 BEGIN 1.819 : samedi 8 juillet 2017, 20:07:52 (UTC+0200)
1499610623 BEGIN 1.819 : dimanche 9 juillet 2017, 16:30:23 (UTC+0200)
1499627770 BEGIN 1.819 : dimanche 9 juillet 2017, 21:16:10 (UTC+0200)
1499628010 END 1.819 : dimanche 9 juillet 2017, 21:20:10 (UTC+0200)
1499729465 BEGIN 1.819 : mardi 11 juillet 2017, 01:31:05 (UTC+0200)
1499729716 END 1.819 : mardi 11 juillet 2017, 01:35:16 (UTC+0200)
1501096358 BEGIN 1.825 : mercredi 26 juillet 2017, 21:12:38 (UTC+0200)
1501096497 BEGIN 1.825 : mercredi 26 juillet 2017, 21:14:57 (UTC+0200)
1501096673 BEGIN 1.825 : mercredi 26 juillet 2017, 21:17:53 (UTC+0200)
1501096738 BEGIN 1.825 : mercredi 26 juillet 2017, 21:18:58 (UTC+0200)
1501097034 END 1.825 : mercredi 26 juillet 2017, 21:23:54 (UTC+0200)
1502873680 BEGIN 1.825 : mercredi 16 août 2017, 10:54:41 (UTC+0200)
1502886497 BEGIN 1.825 : mercredi 16 août 2017, 14:28:17 (UTC+0200)
1502887469 BEGIN 1.825 : mercredi 16 août 2017, 14:44:29 (UTC+0200)
1502887710 END 1.825 : mercredi 16 août 2017, 14:48:30 (UTC+0200)
1503494561 BEGIN 1.829 : mercredi 23 août 2017, 15:22:41 (UTC+0200)
1503939535 BEGIN 1.831 : lundi 28 août 2017, 18:58:55 (UTC+0200)
1503939776 END 1.831 : lundi 28 août 2017, 19:02:56 (UTC+0200)
1504149108 BEGIN 1.833 : jeudi 31 août 2017, 05:11:48 (UTC+0200)
1504149402 END 1.833 : jeudi 31 août 2017, 05:16:42 (UTC+0200)
1504156366 BEGIN 1.834 : jeudi 31 août 2017, 07:12:46 (UTC+0200)
1504156668 END 1.834 : jeudi 31 août 2017, 07:17:48 (UTC+0200)
1504415626 BEGIN 1.835 : dimanche 3 septembre 2017, 07:13:46 (UTC+0200)
1504628756 BEGIN 1.836 : mardi 5 septembre 2017, 18:25:56 (UTC+0200)
1504629099 END 1.836 : mardi 5 septembre 2017, 18:31:39 (UTC+0200)

File diff suppressed because it is too large Load diff

View file

@ -1,36 +0,0 @@
---
abstract: 'IMAP4 client library'
author:
- 'Phil Pearl (Lobbes) <phil@zimbra.com>'
build_requires:
ExtUtils::MakeMaker: 0
configure_requires:
ExtUtils::MakeMaker: 0
dynamic_config: 1
generated_by: 'ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.120921'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: 1.4
name: Mail-IMAPClient
no_index:
directory:
- t
- inc
requires:
Carp: 0
Errno: 0
Fcntl: 0
File::Temp: 0
IO::File: 0
IO::Select: 0
IO::Socket: 0
IO::Socket::INET: 1.26
List::Util: 0
MIME::Base64: 0
Parse::RecDescent: 1.94
Test::More: 0
perl: 5.008
resources:
homepage: http://sourceforge.net/projects/mail-imapclient/
version: 3.38

View file

@ -5,6 +5,18 @@ Changes from 2.99_01 to 3.16 made by Mark Overmeer
Changes from 0.09 to 2.99_01 made by David Kernen
- Potential compatibility issues from 3.17+ highlighted with '*'
version 3.39: Fri Feb 3 00:43:00 UTC 2017
- rt.cpan.org#115726: uninitialized value via fetch_hash
[Malte Stretz]
- rt.cpan.org#119523: better error reporting on failed TLS connections
[Matthew Horsfall]
- rt.cpan.org#114904: document noop()
[Glenn Golden]
- rt.cpan.org#97718: (redux) never retry DONE
[Laurence Darby]
- _imap_command() new doretry => 0|1 option to suppress/allow retry
- updated copyright for 2017
version 3.38: Tue Feb 9 02:48:21 UTC 2016
- rt.cpan.org#107592: redact credentials via debug if !Showcredentials
[Gilles Lamiral]

View file

@ -4,7 +4,7 @@
"Phil Pearl (Lobbes) <phil@zimbra.com>"
],
"dynamic_config" : 1,
"generated_by" : "ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.120921",
"generated_by" : "ExtUtils::MakeMaker version 7.0401, CPAN::Meta::Converter version 2.150001",
"license" : [
"perl_5"
],
@ -52,5 +52,5 @@
"resources" : {
"homepage" : "http://sourceforge.net/projects/mail-imapclient/"
},
"version" : "3.38"
"version" : "3.39"
}

View file

@ -0,0 +1,36 @@
---
abstract: 'IMAP4 client library'
author:
- 'Phil Pearl (Lobbes) <phil@zimbra.com>'
build_requires:
ExtUtils::MakeMaker: '0'
configure_requires:
ExtUtils::MakeMaker: '0'
dynamic_config: 1
generated_by: 'ExtUtils::MakeMaker version 7.0401, CPAN::Meta::Converter version 2.150001'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: '1.4'
name: Mail-IMAPClient
no_index:
directory:
- t
- inc
requires:
Carp: '0'
Errno: '0'
Fcntl: '0'
File::Temp: '0'
IO::File: '0'
IO::Select: '0'
IO::Socket: '0'
IO::Socket::INET: '1.26'
List::Util: '0'
MIME::Base64: '0'
Parse::RecDescent: '1.94'
Test::More: '0'
perl: '5.008'
resources:
homepage: http://sourceforge.net/projects/mail-imapclient/
version: '3.39'

View file

@ -84,7 +84,7 @@ COPYRIGHT AND LICENSE
=====================
Copyright (C) 1999-2003 The Kernen Group, Inc.
Copyright (C) 2007-2009 Mark Overmeer
Copyright (C) 2010-2016 Phil Pearl (Lobbes)
Copyright (C) 2010-2017 Phil Pearl (Lobbes)
All rights reserved.
This library is free software; you can redistribute it and/or modify

View file

@ -7,7 +7,7 @@ use strict;
use warnings;
package Mail::IMAPClient;
our $VERSION = '3.38';
our $VERSION = '3.39';
use Mail::IMAPClient::MessageSet;
@ -46,7 +46,7 @@ my %SEARCH_KEYS = map { ( $_ => 1 ) } qw(
# modules require(d) during runtime when applicable
my %Load_Module = (
"Compress-Zlib" => "Compress::Zlib",
"INET" => "IO::Socket::INET",
"INET" => "IO::Socket::INET6",
"SSL" => "IO::Socket::SSL",
"UNIX" => "IO::Socket::UNIX",
"BodyStructure" => "Mail::IMAPClient::BodyStructure",
@ -366,7 +366,11 @@ sub connect(@) {
return $self->Socket($sock);
}
else {
my $lasterr = $self->LastError || "";
my $lasterr = $self->LastError;
if ( !$lasterr and $self->Ssl and $ioclass ) {
$lasterr = $ioclass->errstr;
}
$lasterr ||= "";
$self->LastError("Unable to connect to $server: $lasterr");
return undef;
}
@ -1165,7 +1169,8 @@ sub done {
my $count = shift || $self->Count;
# DONE looks like a tag when sent and not already in IDLE
$self->_imap_command( { addtag => 0, tag => qr/(?:$count|DONE)/ }, "DONE" )
$self->_imap_command(
{ addtag => 0, tag => qr/(?:$count|DONE)/, doretry => 0 }, "DONE" )
or return undef;
return $self->Results;
}
@ -1211,8 +1216,11 @@ sub reconnect {
}
# wrapper for _imap_command_do to enable retrying on lost connections
# options:
# doretry => 0|1 - suppress|allow retry after reconnect
sub _imap_command {
my $self = shift;
my $opt = ref( $_[0] ) eq "HASH" ? $_[0] : {};
my $tries = 0;
my $retry = $self->Reconnectretry || 0;
@ -1241,6 +1249,7 @@ sub _imap_command {
my $ret = $self->reconnect;
if ($ret) {
$self->_debug("reconnect success($ret) on try #$tries/$retry");
last if exists $opt->{doretry} and !$opt->{doretry};
}
elsif ( defined $ret and $ret == 0 ) { # escaping recursion
return undef;
@ -2297,9 +2306,15 @@ sub fetch_hash {
# NOTE: old code tried to remove any "unrequested" data in $entry
# - UID is sometimes not explicitly requested, are there others?
# - rt#115726: Uid and $entry->{UID} not set, ignore unsolicited data
if ( $self->Uid ) {
$uids->{ $entry->{UID} } = $entry;
delete $entry->{UID} unless $asked_for_uid;
if ( $entry->{UID} ) {
$uids->{ $entry->{UID} } = $entry;
delete $entry->{UID} unless $asked_for_uid;
}
else {
$self->_debug("ignoring unsolicited response: $l");
}
}
else {
$uids->{$mid} = $entry;

View file

@ -2116,9 +2116,24 @@ the IMAP client command "STATUS folder RECENT"), or C<undef> in the
case of an error. The B<recent_count> method was contributed by Rob
Deker (deker@ikimbo.com).
=head2 noop
Example:
$imap->noop or die "noop failed: $@\n";
The B<noop> method performs an IMAP NOOP command. Per RFC3501 this
command does nothing and always succeeds. However, if a connection
times out or other errors occur while communicating with the server,
this method can still fail. This command can be used as a periodic
poll to check for (untagged) status updates (new messages, etc.) from
the server and also to reset any inactivity/auto-logout timers the
server may maintain.
=head2 reconnect
Example:
$imap->noop or $imap->reconnect or die "noop failed: $@\n";
Attempt to reconnect if the IMAP connection unless $imap is already in
@ -3969,7 +3984,7 @@ http://rt.cpan.org/Public/Dist/Display.html?Name=Mail-IMAPClient
Copyright (C) 1999-2003 The Kernen Group, Inc.
Copyright (C) 2007-2009 Mark Overmeer
Copyright (C) 2010-2016 Phil Pearl (Lobbes)
Copyright (C) 2010-2017 Phil Pearl (Lobbes)
All rights reserved.
This library is free software; you can redistribute it and/or modify

View file

@ -1,10 +1,10 @@
REM $Id: build_exe.bat,v 1.40 2016/08/19 14:12:29 gilles Exp gilles $
REM $Id: build_exe.bat,v 1.46 2017/08/23 13:04:40 gilles Exp gilles $
@SETLOCAL
ECHO Currently running through %0 %*
@ECHO Currently running through %0 %*
ECHO Building imapsync.exe
@ECHO Building imapsync.exe
@REM the following command change current directory to the dirname of the current batch pathname
CD /D %~dp0
@ -24,8 +24,13 @@ EXIT /B
:pp_exe
@SETLOCAL
CALL pp -o imapsync.exe --link libeay32_.dll --link zlib1_.dll --link ssleay32_.dll .\imapsync
IF ERRORLEVEL 1 CALL pp -o imapsync.exe .\imapsync
@REM CALL pp -o imapsync.exe --link libeay32_.dll --link zlib1_.dll --link ssleay32_.dll .\imapsync
IF %PROCESSOR_ARCHITECTURE% == x86 (
CALL pp -o imapsync.exe -M Test2::Formatter -M Test2::Formatter::TAP -M Test2::Event -M Test2::Event::Info --link zlib1_.dll --link libcrypto-1_1_.dll --link libssl-1_1_.dll .\imapsync
REM CALL pp -o imapsync.exe -M Test2::Formatter -M Test2::Formatter::TAP -M Test2::Event -M Test2::Event::Info --link zlib1_.dll .\imapsync
) ELSE (
CALL pp -o imapsync.exe -M Test2::Formatter -M Test2::Formatter::TAP -M Test2::Event -M Test2::Event::Info .\imapsync
)
@ENDLOCAL
EXIT /B
@ -64,6 +69,7 @@ perl ^
-mIO::Socket::SSL ^
-mIO::Tee ^
-mMail::IMAPClient ^
-mNet::Ping ^
-mTerm::ReadKey ^
-mTime::Local ^
-mUnicode::String ^

View file

@ -1,6 +1,6 @@
#!/bin/sh
# $Id: build_mac.sh,v 1.6 2016/06/22 20:04:16 gilles Exp gilles $
# $Id: build_mac.sh,v 1.8 2017/03/01 03:06:46 gilles Exp gilles $
# exit on any failure
set -e
@ -26,8 +26,9 @@ cpanm Mail::IMAPClient IO::Socket::SSL PAR::Packer
pp -o $BIN_NAME \
-M Mail::IMAPClient -M IO::Socket -M IO::Socket::SSL \
-M Digest::MD5 -M Digest::HMAC_MD5 -M Term::ReadKey \
-M Authen::NTLM \
-M Authen::NTLM -M Net::Ping \
-M Crypt::OpenSSL::RSA -M JSON -M JSON::WebToken -M LWP -M HTML::Entities \
-M Sys::MemInfo \
imapsync
./imapsync_bin_Darwin

View file

@ -1,11 +0,0 @@
Processing http://lamiral.info/~gilles/imapsync/
List of broken links and other issues:
http://fr.linkedin.com/in/gilleslamiral
Line: 185
Code: 405 Method Not Allowed
To do: The server does not allow HTTP HEAD requests, which prevents the
Link Checker to check the link automatically. Check the link
manually.

View file

@ -1,4 +1,4 @@
.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.28)
.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
.\"
.\" Standard preamble:
.\" ========================================================================
@ -133,21 +133,20 @@
.\" ========================================================================
.\"
.IX Title "IMAPSYNC 1"
.TH IMAPSYNC 1 "2016-08-19" "perl v5.18.2" "User Contributed Perl Documentation"
.TH IMAPSYNC 1 "2017-09-05" "perl v5.22.1" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
imapsync \- Email IMAP tool for syncing, copying and migrating email mailboxes.
.PP
The imapsync command synchronises mailboxes between two imap servers.
More than 69 different IMAP server softwares supported with success,
few failures.
.PP
$Revision: 1.727 $
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
imapsync \- Email IMAP tool for syncing, copying and migrating
email mailboxes between two imap servers, one way,
and without duplicates.
.SH "VERSION"
.IX Header "VERSION"
This documentation refers to Imapsync \f(CW$Revision:\fR 1.836 $
.SH "USAGE"
.IX Header "USAGE"
.Vb 5
\& To synchronize the source imap account
\& "test1" on server "test1.lamiral.info" with password "secret1"
@ -159,86 +158,104 @@ $Revision: 1.727 $
\& \-\-host1 test1.lamiral.info \-\-user1 test1 \-\-password1 secret1 \e
\& \-\-host2 test2.lamiral.info \-\-user2 test2 \-\-password2 secret2
.Ve
.SH "REQUIRED ARGUMENTS"
.IX Header "REQUIRED ARGUMENTS"
The required argmuments are the six values, three on each sides,
needed to login into the \s-1IMAP\s0 servers,
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
We sometimes need to transfer mailboxes from one imap server to
another.
.PP
Imapsync command is a tool allowing incremental and
recursive imap transfers from one mailbox to another.
.PP
By default all folders are transferred, recursively, meaning
the whole folder hierarchy is taken, all messages in them,
and all messages flags (\eSeen \eAnswered \eFlagged etc.)
are synced too.
.PP
Imapsync reduces the amount
of data transferred by not transferring a given message
if it resides already on both sides. Same specific headers
and the transfer is done only once (by default it's
\&\*(L"Message-Id:\*(R" and \*(L"Received:\*(R" lines but it can be changed with
\&\-\-useheader option).
.PP
All flags are preserved, unread will stay unread, read will stay read,
deleted will stay deleted.
.PP
You can stop the transfer at any
time and restart it later, imapsync works well with bad
connections and interruptions.
.PP
You can decide to delete the messages from the source mailbox
after a successful transfer, it can be a good feature when migrating
live mailboxes since messages will be only on one side.
In that case, use the \-\-delete1 option. Option \-\-delete1 implies
also option \-\-expunge1 so all messages marked deleted on host1
will be really deleted.
.PP
A different scenario is synchronizing a mailbox B from another mailbox A
in case you just want to keep a \*(L"live\*(R" copy of A in B.
In that case \-\-delete2 has to be used, it deletes messages in host2
folder B that are not in host1 folder A. If you also need to destroy
host2 folders that are not in host1 then use \-\-delete2folders (see also
\&\-\-delete2foldersonly and \-\-delete2foldersbutnot).
.PP
Imapsync is not adequate for maintaining two active imap accounts
in synchronization when the user plays independently on both sides.
Use offlineimap (written by John Goerzen) or mbsync (written by
Michael R. Elkins) for a 2 ways synchronization.
.SH "OPTIONS"
.IX Header "OPTIONS"
.Vb 1
\& usage: imapsync [options]
.Ve
.PP
Mandatory options are the six values, three on each sides,
needed to log in into the \s-1IMAP\s0 servers, ie,
a host, a username, and a password, two times.
.SH "INSTALL"
.IX Header "INSTALL"
.Vb 5
\& Imapsync works under any Unix with perl.
\& Imapsync works under Windows (2000, XP, Vista, Seven)
\& as a standalone binary software called imapsync.exe
\& Imapsync works under OS X as a standalone binary
\& software called imapsync_bin_Darwin.
\&
\& Purchase latest imapsync at
\& http://imapsync.lamiral.info/
\&
\& You\*(Aqll receive a link to a compressed tarball called imapsync\-x.xx.tgz
\& where x.xx is the version number. Untar the tarball where
\& you want (on Unix):
\&
\& tar xzvf imapsync\-x.xx.tgz
\&
\& Go into the directory imapsync\-x.xx and read the INSTALL file.
\& As mentioned at http://imapsync.lamiral.info/#install
\& the INSTALL file can also be found at
\& http://imapsync.lamiral.info/INSTALL
\& It is now split in several files for each system
\& http://imapsync.lamiral.info/INSTALL.d/
.Ve
.SH "CONFIGURATION"
.IX Header "CONFIGURATION"
There is no specific configuration file for imapsync,
everything is specified by the command line parameteres
and the default behavior.
.SH "USAGE"
.IX Header "USAGE"
To get a description of each option just run imapsync
with no argument, like this:
.PP
.Vb 1
\& imapsync
.Ve
Conventions used:
.PP
This description of options is also available at
http://imapsync.lamiral.info/OPTIONS and is
reproduced here:
.PP
.Vb 1
\& usage: ./imapsync [options]
\&
\& Several options are mandatory.
.Vb 4
\& str means string
\& int means integer
\& reg means regular expression
\& cmd means command
\&
\& \-\-dry : Makes imapsync doing nothing, just print what would
\& be done without \-\-dry.
\&
\& \-\-dry : Makes imapsync doing nothing for real, just print what
\& would be done without \-\-dry.
.Ve
.SS "OPTIONS/credentials"
.IX Subsection "OPTIONS/credentials"
.Vb 8
\& \-\-host1 str : Source or "from" imap server. Mandatory.
\& \-\-port1 int : Port to connect on host1. Default is 143, 993 if \-\-ssl1
\& \-\-user1 str : User to login on host1. Mandatory.
\& \-\-showpasswords : Shows passwords on output instead of "MASKED".
\& Useful to restart a complete run by just reading the log.
\& \-\-password1 str : Password for the user1.
\& \-\-host2 str : "destination" imap server. Mandatory.
\& \-\-port2 int : Port to connect on host2. Default is 143, 993 if \-\-ssl2
\& \-\-user2 str : User to login on host2. Mandatory.
\& \-\-password2 str : Password for the user2.
\&
\& \-\-showpasswords : Shows passwords on output instead of "MASKED".
\& Useful to restart a complete run by just reading the log,
\& or to debug passwords. It\*(Aqs not a secure practice.
\&
\& \-\-passfile1 str : Password file for the user1. It must contain the
\& password on the first line. This option avoids to show
\& the password on the command line like \-\-password1 does.
\& \-\-passfile2 str : Password file for the user2. Contains the password.
\&
\& \-\-ssl1 : Use a SSL connection on host1.
\& \-\-ssl2 : Use a SSL connection on host2.
\& \-\-tls1 : Use a TLS connection on host1.
\& \-\-tls2 : Use a TLS connection on host2.
.Ve
.SS "OPTIONS/encryption"
.IX Subsection "OPTIONS/encryption"
.Vb 10
\& \-\-nossl1 : Do not use a SSL connection on host1.
\& \-\-ssl1 : Use a SSL connection on host1. On by default if possible.
\& \-\-nossl2 : Do not use a SSL connection on host2.
\& \-\-ssl2 : Use a SSL connection on host2. On by default if possible.
\& \-\-notls1 : Do not use a TLS connection on host1.
\& \-\-tls1 : Use a TLS connection on host1. On by default if possible.
\& \-\-notls2 : Do not use a TLS connection on host2.
\& \-\-tls2 : Use a TLS connection on host2. On by default if possible.
\& \-\-debugssl int : SSL debug mode from 0 to 4.
\& \-\-sslargs1 str : Pass any ssl parameter for host1 ssl or tls connection. Example:
\& \-\-sslargs1 SSL_verify_mode=1 \-\-sslargs1 SSL_version=SSLv3
@ -251,7 +268,10 @@ reproduced here:
\& Default is 120 and 0 means no timeout at all.
\& \-\-timeout2 int : Connection timeout in seconds for host2.
\& Default is 120 and 0 means no timeout at all.
\&
.Ve
.SS "OPTIONS/authentication"
.IX Subsection "OPTIONS/authentication"
.Vb 3
\& \-\-authmech1 str : Auth mechanism to use with host1:
\& PLAIN, LOGIN, CRAM\-MD5 etc. Use UPPERCASE.
\& \-\-authmech2 str : Auth mechanism to use with host2. See \-\-authmech1
@ -264,12 +284,14 @@ reproduced here:
\& be able to use an administrative user.
\& \-\-proxyauth2 : Use proxyauth on host2. Requires \-\-authuser2.
\&
\& \-\-authmd51 : Use MD5 authentification for host1.
\& \-\-authmd52 : Use MD5 authentification for host2.
\& \-\-authmd51 : Use MD5 authentication for host1.
\& \-\-authmd52 : Use MD5 authentication for host2.
\& \-\-domain1 str : Domain on host1 (NTLM authentication).
\& \-\-domain2 str : Domain on host2 (NTLM authentication).
\&
\&
.Ve
.SS "OPTIONS/folders"
.IX Subsection "OPTIONS/folders"
.Vb 4
\& \-\-folder str : Sync this folder.
\& \-\-folder str : and this one, etc.
\& \-\-folderrec str : Sync this folder recursively.
@ -280,17 +302,16 @@ reproduced here:
\& \-\-folderlast str : Sync this folder last. \-\-folderlast "[Gmail]/All Mail"
\& \-\-folderlast str : then this one, etc.
\&
\& \-\-nomixfolders : Do not merge folders when host1 is case sensitive
\& \-\-nomixfolders : Do not merge folders when host1 is case\-sensitive
\& while host2 is not (like Exchange). Only the first
\& similar folder is synced (ex: Sent SENT sent \-> Sent).
\&
\& \-\-skipemptyfolders : Empty host1 folders are not created on host2.
\&
\& \-\-f1f2 str1=str2 : Force folder str1 to be synced to str2.
\& \-\-include reg : Sync folders matching this regular expression
\& \-\-include reg : or this one, etc.
\& in case both \-\-include \-\-exclude options are
\& use, include is done before.
\& If both \-\-include \-\-exclude options are used, then
\& include is done before.
\& \-\-exclude reg : Skips folders matching this regular expression
\& Several folders to avoid:
\& \-\-exclude \*(Aqfold1|fold2|f3\*(Aq skips fold1, fold2 and f3.
@ -301,37 +322,73 @@ reproduced here:
\& It does it by adding two \-\-regextrans2 options before
\& all others. Add \-\-debug to see what\*(Aqs really going on.
\&
\& \-\-automap : guesses folders mapping, for folders like
\& "Sent", "Junk", "Drafts", "All", "Archive", "Flagged".
\& \-\-f1f2 str1=str2 : Force folder str1 to be synced to str2,
\& \-\-f1f2 overrides \-\-automap and \-\-regextrans2.
\&
\& \-\-nomixfolders : Avoid merging folders that are considered different on
\& host1 but the same on destination host2 because of
\& case sensitivities and insensitivities.
\&
\& \-\-subscribed : Transfers subscribed folders.
\& \-\-subscribe : Subscribe to the folders transferred on the
\& host2 that are subscribed on host1. On by default.
\& \-\-subscribeall : Subscribe to the folders transferred on the
\& host2 even if they are not subscribed on host1.
\&
\& \-\-prefix1 str : Remove prefix str to all destination folders,
\& usually INBOX. or INBOX/ or an empty string "".
\& imapsync guesses the prefix if host1 imap server
\& does not have NAMESPACE capability. This option
\& should not be used, most of the time.
\& \-\-prefix2 str : Add prefix to all host2 folders. See \-\-prefix1
\& \-\-sep1 str : Host1 separator in case NAMESPACE is not supported.
\& \-\-sep2 str : Host2 separator in case NAMESPACE is not supported.
\&
\& \-\-regextrans2 reg : Apply the whole regex to each destination folders.
\& \-\-regextrans2 reg : and this one. etc.
\& When you play with the \-\-regextrans2 option, first
\& add also the safe options \-\-dry \-\-justfolders
\& Then, when happy, remove \-\-dry, remove \-\-justfolders.
\& Have in mind that \-\-regextrans2 is applied after prefix
\& and separator inversion.
\&
\& and separator inversion. For examples see
\& http://imapsync.lamiral.info/FAQ.d/FAQ.Folders_Mapping.txt
.Ve
.SS "OPTIONS/folders sizes"
.IX Subsection "OPTIONS/folders sizes"
.Vb 5
\& \-\-nofoldersizes : Do not calculate the size of each folder at the
\& beginning of the sync. Default is to calculate them.
\& \-\-nofoldersizesatend: Do not calculate the size of each folder at the
\& end of the sync. Default is to calculate them.
\& \-\-justfoldersizes : Exit after having printed the initial folder sizes.
.Ve
.SS "OPTIONS/tmp"
.IX Subsection "OPTIONS/tmp"
.Vb 10
\& \-\-tmpdir str : Where to store temporary files and subdirectories.
\& Will be created if it doesn\*(Aqt exist.
\& Default is system specific, Unix is /tmp but
\& it\*(Aqs often small and deleted at reboot.
\& /tmp is often too small and deleted at reboot.
\& \-\-tmpdir /var/tmp should be better.
\& \-\-pidfile str : The file where imapsync pid is written.
\& \-\-pidfilelocking : Abort if pidfile already exists. Usefull to avoid
\& \-\-pidfile str : The file where imapsync pid is written,
\& it can be dirname/filename.
\& Default name is imapsync.pid in tmpdir.
\& \-\-pidfilelocking : Abort if pidfile already exists. Useful to avoid
\& concurrent transfers on the same mailbox.
\&
.Ve
.SS "OPTIONS/log"
.IX Subsection "OPTIONS/log"
.Vb 3
\& \-\-nolog : Turn off logging on file
\& \-\-logfile str : Change the default log filename (can be dirname/filename).
\& \-\-logdir str : Change the default log directory. Default is LOG_imapsync
\&
\& \-\-prefix1 str : Remove prefix to all destination folders
\& (usually INBOX. or INBOX/ or an empty string "")
\& you have to use \-\-prefix1 if host1 imap server
\& does not have NAMESPACE capability, so imapsync
\& suggests to use it. All other cases are bad.
\& \-\-prefix2 str : Add prefix to all host2 folders. See \-\-prefix1
\& \-\-sep1 str : Host1 separator in case NAMESPACE is not supported.
\& \-\-sep2 str : Host2 separator in case NAMESPACE is not supported.
\&
\& \-\-skipmess reg : Skips messages maching the regex.
\& \-\-logdir str : Change the default log directory. Default is LOG_imapsync/
.Ve
.SS "OPTIONS/messages"
.IX Subsection "OPTIONS/messages"
.Vb 4
\& \-\-skipmess reg : Skips messages matching the regex.
\& Example: \*(Aqm/[\ex80\-ff]/\*(Aq # to avoid 8bits messages.
\& \-\-skipmess is applied before \-\-regexmess
\& \-\-skipmess reg : or this one, etc.
@ -345,16 +402,33 @@ reproduced here:
\& \-\-regexmess reg : Apply the whole regex to each message before transfer.
\& Example: \*(Aqs/\e000/ /g\*(Aq # to replace null by space.
\& \-\-regexmess reg : and this one, etc.
\&
.Ve
.SS "OPTIONS/flags"
.IX Subsection "OPTIONS/flags"
.Vb 3
\& \-\-regexflag reg : Apply the whole regex to each flags list.
\& Example: \*(Aqs/"Junk"//g\*(Aq # to remove "Junk" flag.
\& \-\-regexflag reg : and this one, etc.
\&
\& \-\-delete : Deletes messages on host1 server after a successful
\& transfer. Option \-\-delete has the following behavior:
\& \-\-regexflag reg : then this one, etc.
.Ve
.SS "OPTIONS/deletions"
.IX Subsection "OPTIONS/deletions"
.Vb 10
\& \-\-delete1 : Deletes messages on host1 server after a successful
\& transfer. Option \-\-delete1 has the following behavior:
\& it marks messages as deleted with the IMAP flag
\& \eDeleted, then messages are really deleted with an
\& EXPUNGE IMAP command.
\& EXPUNGE IMAP command. If expunging after each message
\& slows down too much the sync then use
\& \-\-noexpungeaftereach to speed up.
\& \-\-expunge1 : Expunge messages on host1 just before syncing a folder.
\& Expunge is done per folder.
\& Expunge aims is to really delete messages marked deleted.
\& An expunge is also done after each message copied
\& if option \-\-delete1 is set.
\& \-\-noexpunge1 : Do not expunge messages on host1.
\& \-\-delete1emptyfolders : Deletes empty folders on host1, INBOX excepted.
\& Useful with \-\-delete1 since what remains on host1
\& is only what failed to be synced.
\&
\& \-\-delete2 : Delete messages in host2 that are not in
\& host1 server. Useful for backup or pre\-sync.
@ -369,26 +443,23 @@ reproduced here:
\& Example: \-\-delete2foldersonly "/^Junk$|^INBOX.Junk$/"
\& \-\-delete2foldersbutnot reg : Do not delete folders matching regex.
\& Example: \-\-delete2foldersbutnot "/Tasks$|Contacts$|Foo$/"
\& \-\-noexpunge : Do not expunge messages on host1.
\& Expunge really deletes messages marked deleted.
\& Expunge is made at the beginning, on host1 only.
\& Newly transferred messages are also expunged if
\& option \-\-delete is given.
\& No expunge is done on host2 account (unless \-\-expunge2)
\& \-\-expunge1 : Expunge messages on host1 after messages transfer.
\&
\& \-\-expunge2 : Expunge messages on host2 after messages transfer.
\& \-\-uidexpunge2 : uidexpunge messages on the host2 account
\& that are not on the host1 account, requires \-\-delete2
\& \-\-nomixfolders : Avoid merging folders that are considered different on
\& host1 but the same on destination host2 because of
\& case sensitivities and insensitivities.
\&
.Ve
.SS "OPTIONS/dates"
.IX Subsection "OPTIONS/dates"
.Vb 5
\& \-\-syncinternaldates : Sets the internal dates on host2 same as host1.
\& Turned on by default. Internal date is the date
\& a message arrived on a host (mtime).
\& \-\-idatefromheader : Sets the internal dates on host2 same as the
\& "Date:" headers.
\&
.Ve
.SS "OPTIONS/message selection"
.IX Subsection "OPTIONS/message selection"
.Vb 12
\& \-\-maxsize int : Skip messages larger (or equal) than int bytes
\& \-\-minsize int : Skip messages smaller (or equal) than int bytes
\& \-\-maxage int : Skip messages older than int days.
@ -408,44 +479,34 @@ reproduced here:
\& \-\-search2 str : Same as \-\-search for selecting host2 messages only.
\& \-\-search CRIT equals \-\-search1 CRIT \-\-search2 CRIT
\&
\& \-\-exitwhenover int : Stop syncing when total bytes transferred reached.
\& Gmail per day allows
\& 2500000000 = 2.5 GB downloaded from Gmail as host2
\& 500000000 = 500 MB uploaded to Gmail as host1.
\&
\& \-\-maxlinelength int : skip messages with a line length longer than int bytes.
\& RFC 2822 says it must be no more than 1000 bytes.
\&
\&
\& \-\-useheader str : Use this header to compare messages on both sides.
\& Ex: Message\-ID or Subject or Date.
\& \-\-useheader str and this one, etc.
\&
\& \-\-subscribed : Transfers subscribed folders.
\& \-\-subscribe : Subscribe to the folders transferred on the
\& host2 that are subscribed on host1. On by default.
\& \-\-subscribeall : Subscribe to the folders transferred on the
\& host2 even if they are not subscribed on host1.
\&
\& \-\-nofoldersizes : Do not calculate the size of each folder in bytes
\& and message counts. Default is to calculate them.
\& \-\-nofoldersizesatend: Do not calculate the size of each folder in bytes
\& and message counts at the end. Default is on.
\& \-\-justfoldersizes : Exit after having printed the folder sizes.
\&
\& \-\-syncacls : Synchronises acls (Access Control Lists).
\& \-\-nosyncacls : Does not synchronize acls. This is the default.
\& Acls in IMAP are not standardized, be careful.
\&
\& \-\-usecache : Use cache to speedup.
\& \-\-usecache : Use cache to speed up the sync.
\& \-\-nousecache : Do not use cache. Caveat: \-\-useuid \-\-nousecache creates
\& duplicates on multiple runs.
\& \-\-useuid : Use uid instead of header as a criterium to recognize
\& messages. Option \-\-usecache is then implied unless
\& \-\-nousecache is used.
\&
.Ve
.SS "OPTIONS/miscelaneous"
.IX Subsection "OPTIONS/miscelaneous"
.Vb 3
\& \-\-syncacls : Synchronizes acls (Access Control Lists).
\& \-\-nosyncacls : Does not synchronize acls. This is the default.
\& Acls in IMAP are not standardized, be careful.
.Ve
.SS "OPTIONS/debugging"
.IX Subsection "OPTIONS/debugging"
.Vb 8
\& \-\-debug : Debug mode.
\& \-\-debugfolders : Debug mode for the folders part only.
\& \-\-debugcontent : Debug content of the messages transfered. Huge ouput.
\& \-\-debugcontent : Debug content of the messages transferred. Huge output.
\& \-\-debugflags : Debug mode for flags.
\& \-\-debugimap1 : IMAP debug mode for host1. Very verbose.
\& \-\-debugimap2 : IMAP debug mode for host2. Very verbose.
@ -457,6 +518,40 @@ reproduced here:
\& \-\-tests : Run local non\-regression tests. Exit code 0 means all ok.
\& \-\-testslive : Run a live test with test1.lamiral.info imap server.
\& Useful to check the basics. Needs internet connexion.
\& \-\-testslive6 : Run a live test with ks2ipv6.lamiral.info imap server.
\& Useful to check the ipv6 connectivity. Needs internet.
.Ve
.SS "OPTIONS/specific"
.IX Subsection "OPTIONS/specific"
.Vb 2
\& \-\-gmail1 : sets \-\-host1 to Gmail and options from FAQ.Gmail.txt
\& \-\-gmail2 : sets \-\-host2 to Gmail and options from FAQ.Gmail.txt
\&
\& \-\-office1 : sets \-\-host1 to Office365 options from FAQ.Exchange.txt
\& \-\-office2 : sets \-\-host2 to Office365 options from FAQ.Exchange.txt
\&
\& \-\-exchange1 : sets options from FAQ.Exchange.txt, account1 part
\& \-\-exchange2 : sets options from FAQ.Exchange.txt, account2 part
\&
\& \-\-domino1 : sets options from FAQ.Domino.txt, account1 part
\& \-\-domino2 : sets options from FAQ.Domino.txt, account2 part
.Ve
.SS "OPTIONS/behavior"
.IX Subsection "OPTIONS/behavior"
.Vb 1
\& \-\-maxmessagespersecond int : limits the number of messages transferred per second.
\&
\& \-\-maxbytespersecond int : limits the average transfer rate per second.
\& \-\-maxbytesafter int : starts \-\-maxbytespersecond limitation only after
\& \-\-maxbytesafter amount of data transferred.
\&
\& \-\-maxsleep int : do not sleep more than int seconds.
\& On by default, 2 seconds max, like \-\-maxsleep 2
\&
\& \-\-abort : terminates a previous call still running.
\& It uses the pidfile to know what processus to abort.
\&
\& \-\-exitwhenover int : Stop syncing when total bytes transferred reached.
\&
\& \-\-version : Print only software version.
\& \-\-noreleasecheck : Do not check for new imapsync release (a http request).
@ -470,97 +565,15 @@ reproduced here:
\&
\& \-\-help : print this help.
\&
\& Example:
\& To synchronize the source imap account
\& "test1" on server "test1.lamiral.info" with password "secret1"
\& to the destination imap account
\& "test2" on server "test2.lamiral.info" with password "secret2"
\& do:
\& Example: to synchronize imap account "test1" on "test1.lamiral.info"
\& to imap account "test2" on "test2.lamiral.info"
\& with test1 password "secret1"
\& and test2 password "secret2"
\&
\& imapsync \e
\& \-\-host1 test1.lamiral.info \-\-user1 test1 \-\-password1 secret1 \e
\& \-\-host2 test2.lamiral.info \-\-user2 test2 \-\-password2 secret2
.Ve
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
Imapsync command is a tool allowing incremental and
recursive imap transfers from one mailbox to another.
.PP
By default all folders are transferred, recursively, all
possible flags (\eSeen \eAnswered \eFlagged etc.) are synced too.
.PP
We sometimes need to transfer mailboxes from one imap server to
another. This is called migration.
.PP
Imapsync reduces the amount
of data transferred by not transferring a given message
if it resides already on both sides. Same specific headers
and the transfer is done only once; taken into account are by default
Message-Id and Received header lines.
All flags are
preserved, unread will stay unread, read will stay read,
deleted will stay deleted. You can stop the transfer at any
time and restart it later, imapsync works well with bad
connections and interruptions.
.PP
You can decide to delete the messages from the source mailbox
after a successful transfer, it can be a good feature when migrating
live mailboxes since messages will be only on one side.
In that case, use the \-\-delete option. Option \-\-delete implies
also option \-\-expunge so all messages marked deleted on host1
will be really deleted.
(you can use \-\-noexpunge to avoid this but I don't see any
good real world scenario for the combination \-\-delete \-\-noexpunge).
.PP
A different scenario is synchronizing a mailbox B from another mailbox A
in case you just want to keep a \*(L"live\*(R" copy of A in B.
In that case \-\-delete2 has to be used, it deletes messages in host2
folder B that are not in host1 folder A. If you also need to destroy
host2 folders that are not in host1 then use \-\-delete2folders (see also
\&\-\-delete2foldersonly and \-\-delete2foldersbutnot).
.PP
Imapsync is not adequate for maintaining two active imap accounts
in synchronization when the user plays independently on both sides.
Use offlineimap (written by John Goerzen) or mbsync (written by
Michael R. Elkins) for 2 ways synchronizations.
.SH "OPTIONS"
.IX Header "OPTIONS"
To get a description of each option just invoke:
.PP
.Vb 1
\& imapsync
.Ve
.PP
or read the previous section named \s-1USAGE,\s0
.PP
or read http://imapsync.lamiral.info/OPTIONS
.SH "HISTORY"
.IX Header "HISTORY"
I wrote imapsync because an enterprise (basystemes) paid me to install
a new imap server without losing huge old mailboxes located on a far
away remote imap server accessible by a low bandwidth link. The tool
imapcp (written in python) could not help me because I had to verify
every mailbox was well transferred and delete it after a good
transfer. imapsync started its life as a copy_folder.pl patch.
The tool copy_folder.pl comes from the Mail\-IMAPClient\-2.1.3 perl
module tarball source (in the examples/ directory of the tarball).
.SH "EXAMPLE"
.IX Header "EXAMPLE"
While working on imapsync parameters please run imapsync in
dry mode (no modification induced) with the \-\-dry
option. Nothing bad can be done this way.
.PP
To synchronize the imap account \*(L"buddy\*(R" (with password \*(L"secret1\*(R")
on host \*(L"imap.src.fr\*(R" to the imap account \*(L"max\*(R" (with password \*(L"secret2\*(R")
on host \*(L"imap.dest.fr\*(R":
.PP
.Vb 2
\& imapsync \-\-host1 imap.src.fr \-\-user1 buddy \-\-password1 secret1 \e
\& \-\-host2 imap.dest.fr \-\-user2 max \-\-password2 secret2
.Ve
.PP
Then you will have max's mailbox updated from buddy's
mailbox.
.SH "SECURITY"
.IX Header "SECURITY"
You can use \-\-passfile1 instead of \-\-password1 to give the
@ -571,84 +584,42 @@ dangerous because of the 'ps auxwwwwe' command. So, saving
the password in a well protected file (600 or rw\-\-\-\-\-\-\-) is
the best solution.
.PP
imasync is not totally protected against sniffers on the
network since passwords may be transferred in plain text
if \s-1CRAM\-MD5\s0 is not supported by your imap servers. Use
\&\-\-ssl1 (or \-\-tls1) and \-\-ssl2 (or \-\-tls2) to enable
encryption on host1 and host2.
Imapsync activates ssl or tls encryption by default, if possible.
What details are under this \*(L"if possible\*(R"?
Imapsync activates ssl if the well known port imaps port (993) is open
on the imap servers. If the imaps port is closed then it open a
normal (clear) connection on port 143 but it looks for \s-1TLS\s0 support
in the \s-1CAPABILITY\s0 list of the servers. If \s-1TLS\s0 is supported
then imapsync goes to encryption.
.PP
You may authenticate as one user (typically an admin user),
but be authorized as someone else, which means you don't
need to know every user's personal password. Specify
\&\-\-authuser1 \*(L"adminuser\*(R" to enable this on host1. In this
case, \-\-authmech1 \s-1PLAIN\s0 will be used by default since it
is the only way to go for now. So don't use \-\-authmech1 \s-1SOMETHING\s0
with \-\-authuser1 \*(L"adminuser\*(R", it will not work.
Same behavior with the \-\-authuser2 option.
Authenticate with an admin account must be supported by your
imap server to work with imapsync.
If the automatic ssl/tls detection fails then imapsync will
not protect against sniffing activities on the
network, especially for passwords.
.PP
When working on Sun/iPlanet/Netscape \s-1IMAP\s0 servers you must use
\&\-\-proxyauth1 to enable administrative user to masquerade as another user.
Can also be used on destination server with \-\-proxyauth2
.PP
You can authenticate with \s-1OAUTH\s0 when transfering from Google Apps.
The consumer key will be the domain part of the \-\-user, and the
\&\-\-password will be used as the consumer secret. It does not work
with Google Apps free edition.
See also the document \s-1FAQ\s0.Security.txt in the \s-1FAQ\s0.d/ directory
or at https://imapsync.lamiral.info/FAQ.d/FAQ.Security.txt
.SH "EXIT STATUS"
.IX Header "EXIT STATUS"
imapsync will exit with a 0 status (return code) if everything went good.
Imapsync will exit with a 0 status (return code) if everything went good.
Otherwise, it exits with a non-zero status.
.PP
So if you have an unreliable internet connection, you can use this loop
in a Bourne shell:
.PP
.Vb 3
\& while ! imapsync ...; do
\& echo imapsync not complete
\& done
.Ve
.SH "LICENSE AND COPYRIGHT"
.IX Header "LICENSE AND COPYRIGHT"
imapsync is free, open, public but not always gratis software
Imapsync is free, open, public but not always gratis software
cover by the \s-1NOLIMIT\s0 Public License.
See the \s-1LICENSE\s0 file included in the distribution or just read this
simple sentence as it is the licence text:
simple sentence as it \s-1IS\s0 the licence text:
.PP
.Vb 1
\& "No limit to do anything with this work and this license."
.Ve
.PP
In case it is not long enough I repeat:
In case it is not long enough, I repeat:
.PP
.Vb 1
\& "No limit to do anything with this work and this license."
.Ve
.SH "MAILING-LIST"
.IX Header "MAILING-LIST"
The public mailing-list may be the best way to get free support.
.PP
To write on the mailing-list, the address is:
<imapsync@linux\-france.org>
.PP
To subscribe, send any message (even empty) to:
<imapsync\-subscribe@listes.linux\-france.org>
then just reply to the confirmation message.
.PP
To unsubscribe, send a message to:
<imapsync\-unsubscribe@listes.linux\-france.org>
.PP
To contact the person in charge for the list:
<imapsync\-request@listes.linux\-france.org>
.PP
The list archives are available at:
http://www.linux\-france.org/prj/imapsync_list/
So consider that the list is public, anyone
can see your post. Use a pseudonym or do not
post to this list if you want to stay private.
.PP
Thank you for your participation.
https://imapsync.lamiral.info/LICENSE
.SH "AUTHOR"
.IX Header "AUTHOR"
Gilles \s-1LAMIRAL\s0 <gilles.lamiral@laposte.net>
@ -657,80 +628,22 @@ Feedback good or bad is very often welcome.
.PP
Gilles \s-1LAMIRAL\s0 earns his living by writing, installing,
configuring and teaching free, open and often gratis
softwares. It used to be \*(L"always gratis\*(R" but now it is
\&\*(L"often\*(R" because imapsync is sold by its author, a good
way to stay maintening and supporting free open public
softwares (see the license) over decades.
software. Imapsync used to be \*(L"always gratis\*(R" but now it is
only \*(L"often gratis\*(R" because imapsync is sold by its author,
a good way to maintain and support free open public
software over decades.
.SH "BUGS AND LIMITATIONS"
.IX Header "BUGS AND LIMITATIONS"
Help me to help you: follow the following guidelines.
.PP
Report any bugs or feature requests to the public mailing-list
or to the author.
.PP
Before reporting bugs, read the FAQs, the \s-1README\s0 and the
\&\s-1TODO\s0 files. http://imapsync.lamiral.info/
.PP
Upgrade to last imapsync release, maybe the bug
is already fixed.
.PP
Upgrade to last Mail-IMAPClient Perl module.
http://search.cpan.org/dist/Mail\-IMAPClient/
maybe the bug is already fixed there.
.PP
Make a good title with word \*(L"imapsync\*(R" in it (my spam filters won't filter it),
Try to write an email title with more words than just \*(L"imapsync\*(R" or \*(L"problem\*(R",
a good title is made of keywords summary, but not too long (one visible line).
.PP
Help us to help you: in your report, please include:
.PP
.Vb 1
\& \- imapsync version.
\&
\& \- output near the first failures, a few lines before is good to get the context
\& of the issue. First failures messages are often more significant than
\& the last ones.
\&
\& \- if the issue is always related to the same messages, include the output
\& with \-\-debug \-\-debugimap, near the failure point. For example,
\& Isolate a buggy message or two in a folder \*(AqBUG\*(Aq and use
\&
\& imapsync ... \-\-folder \*(AqBUG\*(Aq \-\-debug \-\-debugimap
\&
\& \- imap server softwares on both sides and their version number.
\&
\& \- imapsync with all the options you use, the full command line
\& you use (except the passwords of course).
\&
\& \- IMAPClient.pm version.
\&
\& \- the run context. Do you run imapsync.exe, a unix binary
\& or the perl script imapsync.
\&
\& \- operating system running imapsync.
\&
\& \- virtual software context (vmware, xen etc.)
\&
\& \- operating systems on both sides and the third side in case
\& you run imapsync on a foreign host from the both.
.Ve
.PP
Most of those values can be found as a copy/paste at the begining of the output,
so a carbon copy of the output is a very easy and very good debug report for me.
.PP
One time in your life, read the paper
\&\*(L"How To Ask Questions The Smart Way\*(R"
http://www.catb.org/~esr/faqs/smart\-questions.html
and then forget it.
.SH "IMAP SERVERS"
.IX Header "IMAP SERVERS"
See http://imapsync.lamiral.info/S/imapservers.shtml
See https://imapsync.lamiral.info/FAQ.d/FAQ.Reporting_Bugs.txt
.SH "IMAP SERVERS supported"
.IX Header "IMAP SERVERS supported"
See https://imapsync.lamiral.info/S/imapservers.shtml
.SH "HUGE MIGRATION"
.IX Header "HUGE MIGRATION"
Pay special attention to options
\&\-\-subscribed
\&\-\-subscribe
\&\-\-delete
\&\-\-delete1
\&\-\-delete2
\&\-\-delete2folders
\&\-\-maxage
@ -771,17 +684,43 @@ On Windows the batch program can be:
.Ve
.PP
The ... have to be replaced by nothing or any imapsync option.
Welcome in shell programming !
Welcome in shell or batch programming !
.PP
You will find already written scripts at
http://imapsync.lamiral.info/examples/
.SH "INSTALL"
.IX Header "INSTALL"
.Vb 5
\& Imapsync works under any Unix with perl.
\& Imapsync works under Windows (2000, XP, Vista, Seven)
\& as a standalone binary software called imapsync.exe
\& Imapsync works under OS X as a standalone binary
\& software called imapsync_bin_Darwin.
\&
\& Purchase latest imapsync at
\& http://imapsync.lamiral.info/
\&
\& You\*(Aqll receive a link to a compressed tarball called imapsync\-x.xx.tgz
\& where x.xx is the version number. Untar the tarball where
\& you want (on Unix):
\&
\& tar xzvf imapsync\-x.xx.tgz
\&
\& Go into the directory imapsync\-x.xx and read the INSTALL file.
\& As mentioned at http://imapsync.lamiral.info/#install
\& the INSTALL file can also be found at
\& http://imapsync.lamiral.info/INSTALL
\& It is now split in several files for each system
\& http://imapsync.lamiral.info/INSTALL.d/
.Ve
.SH "CONFIGURATION"
.IX Header "CONFIGURATION"
There is no specific configuration file for imapsync,
everything is specified by the command line parameters
and the default behavior.
.SH "HACKING"
.IX Header "HACKING"
Feel free to hack imapsync as the \s-1NOLIMIT\s0 license permits it.
.SH "LINKS"
.IX Header "LINKS"
Entries for imapsync:
https://web.archive.org/web/20070202005121/http://www.imap.org/products/showall.php
.SH "SIMILAR SOFTWARES"
.IX Header "SIMILAR SOFTWARES"
.Vb 10
@ -803,5 +742,14 @@ https://web.archive.org/web/20070202005121/http://www.imap.org/products/showall.
.Ve
.PP
Feedback (good or bad) will often be welcome.
.PP
\&\f(CW$Id:\fR imapsync,v 1.727 2016/08/19 10:30:36 gilles Exp gilles $
.SH "HISTORY"
.IX Header "HISTORY"
I wrote imapsync because an enterprise (basystemes) paid me to install
a new imap server without losing huge old mailboxes located in a far
away remote imap server, accessible by a low-bandwidth link. The tool
imapcp (written in python) could not help me because I had to verify
every mailbox was well transferred, and then delete it after a good
transfer. Imapsync started its life as a patch of the copy_folder.pl
script. The script copy_folder.pl comes from the Mail\-IMAPClient\-2.1.3 perl
module tarball source (more precisely in the examples/ directory of the
Mail-IMAPClient tarball).

View file

@ -1,5 +1,5 @@
@REM $Id: install_module_one.bat,v 1.4 2016/07/20 21:44:40 gilles Exp gilles $
@REM $Id: install_module_one.bat,v 1.5 2017/07/08 00:11:49 gilles Exp gilles $
@ECHO OFF
SET SHELL=
@ -13,13 +13,14 @@ IF ERRORLEVEL 1 ECHO Perl needed. Install Strawberry Perl. Get it at http://stra
&& EXIT /B
@ECHO perl is here
PAUSE
EXIT
FOR %%M in (
IO::Socket::SSL Net::SSLeay PAR::Packer^
IO::Socket::SSL Net::SSLeay PAR::Packer ^
) DO perl -m%%M -e "print qq{Updating %%M $%%M::VERSION \n}" ^
& cpanm --force %%M
REM IO::Socket::SSL
REM IO::Socket::SSL Net::SSLeay PAR::Packer
@ECHO Perl modules for imapsync installed
PAUSE

View file

@ -1,4 +1,4 @@
REM $Id: install_modules.bat,v 1.27 2016/08/17 02:03:46 gilles Exp gilles $
REM $Id: install_modules.bat,v 1.32 2017/08/31 01:57:50 gilles Exp gilles $
::------------------------------------------------------
::--------------- Main of install_modules.bat ----------
@ -39,9 +39,9 @@ EXIT /B
:update_modules
@SETLOCAL
FOR %%M in ( ^
Sys::MemInfo ^
Test::MockObject ^
Readonly ^
Filesys::DfPortable ^
Authen::NTLM ^
Crypt::SSLeay ^
Data::Uniqid ^
@ -60,6 +60,7 @@ FOR %%M in ( ^
Net::SSL ^
Net::SSLeay ^
PAR::Packer ^
Pod::Usage ^
Test::Pod ^
Unicode::String ^
URI::Escape ^
@ -76,6 +77,8 @@ ECHO Perl modules for imapsync updated
REM PAUSE
@ENDLOCAL
EXIT /B
::------------------------------------------------------

14
W/learn/digest Executable file
View file

@ -0,0 +1,14 @@
#!/usr/bin/perl
use strict ;
use warnings ;
require Digest ;
my $digest ;
eval { $digest = Digest->new( 'Whirlpool' ) ; } ;
$digest->add( '' ) ;
print $digest->hexdigest( ) . "\n" ;

81
W/learn/oauth2 Executable file
View file

@ -0,0 +1,81 @@
#!/usr/bin/perl
use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
use Data::Dumper;
use Mail::IMAPClient;
use URI::Escape;
use MIME::Base64;
print "\n\nType your email address here: ";
$username = "gilles.lamiral@gmail.com" ;
chomp($username);
print "\n\nPaste the client_id here: ";
$client_id = '108687549524-86sjq07f3ch8otl9fnr56mjnniltdrvn.apps.googleusercontent.com' ;
chomp($client_id);
print "\n\nPaste the client_secret here: ";
$client_secret = 'zAJO4PLxzeJ4yOaiJRk6f69k' ;
chomp($client_secret);
$scope_string = "https%3A%2F%2Fmail.google.com%2F";
print "Please open the following in your web browser:\n\nhttps://accounts.google.com/o/oauth2/auth?scope=$scope_string&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&client_id=$client_id";
print "\n\nPaste the code here: ";
$code = '4/-e6wojtOSXCjZnwZKKhvg3AdDqDjGLOF0nXxfAFcdmk';
#
chomp($code);
$ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0;
my $ua = LWP::UserAgent->new;
$ua->timeout(10);
$ua->env_proxy;
print "Exchanging the code for an access token and refresh token...\n";
my $exchange_response = $ua->request(POST 'https://accounts.google.com/o/oauth2/token',
'Content_Type' => 'application/x-www-form-urlencoded',
'Content' => [
'code' => $code,
'client_id' => $client_id,
'client_secret' => $client_secret,
'redirect_uri' => 'urn:ietf:wg:oauth:2.0:oob',
'grant_type' => 'authorization_code',
],
);
my ($access_token) = ($exchange_response->decoded_content =~ m/access_token"."(.)"/);
my ($refresh_token) = ($exchange_response->decoded_content =~ m/refresh_token"."(.)"/);
print "exchange_response: ", $exchange_response->decoded_content, "\n" ;
print "access token: $access_token\n";
print "refresh token: $refresh_token\n";
print "Refreshing the access token...\n";
my $auth_response = $ua->request(POST 'https://accounts.google.com/o/oauth2/token',
'Host' => 'accounts.google.com',
'Content_Type' => 'application/x-www-form-urlencoded',
'Content' => [
'client_id' => $client_id,
'client_secret' => $client_secret,
'refresh_token' => $refresh_token,
'grant_type' => 'refresh_token',
],
);
my ($access_token) = ($auth_response->decoded_content =~ m/access_token"."(.)"/);
my $oauth_sign = encode_base64("user=". $username ."\x01auth=Bearer ". $access_token ."\x01\x01", '');
my $imap = Mail::IMAPClient->new(
Server => 'imap.gmail.com',
Port => 993,
Ssl => 1,
Uid => 1,
) or die("Can't connect to imap server.");
$imap->authenticate('XOAUTH2', sub { return $oauth_sign }) or die("Auth error: ". $imap->LastError);
print join(", ",$imap->folders),".\n" or die("List folders error: ". $imap->LastError);

53
W/learn/resolvme Executable file
View file

@ -0,0 +1,53 @@
#!/usr/bin/perl
use strict ;
use warnings ;
use English ;
use Socket qw( SOCK_STREAM AI_CANONNAME NI_NUMERICHOST NIx_NOSERV getaddrinfo getnameinfo );
#use Socket::GetAddrInfo qw( getaddrinfo getnameinfo );
use IO::Socket;
check_name_and_service( @ARGV ) ;
sub check_name_and_service {
my ( $name, $service ) = @ARG ;
my %hints = ( socktype => SOCK_STREAM, flags => AI_CANONNAME );
my ( $err, @res ) = getaddrinfo( $name, $service, \%hints );
print "Cannot resolve name - $err\n" if $err;
my $sock;
foreach my $ai ( @res ) {
my $candidate = IO::Socket->new();
$candidate->timeout( 2 ) ;
print "family: ", $ai->{family},
"\nsocktype: ", $ai->{socktype},
"\nprotocol: ", $ai->{protocol},
"\ncanonname: ", $ai->{canonname},
"\ntimeout: ", $candidate->timeout,
"\n" ;
$candidate->socket( $ai->{family}, $ai->{socktype}, $ai->{protocol} )
or next ;
$candidate->connect( $ai->{addr} ) or next ;
$sock = $candidate;
if( $sock ) {
my ( $err, $host, $service ) = getnameinfo( $sock->peername );
print "Connected to $host:$service\n" if !$err;
my ($err, $ipaddr) = getnameinfo($ai->{addr}, NI_NUMERICHOST, NIx_NOSERV);
print "ipaddr: $ipaddr\n";
$sock->close ;
#last ;
}
}
}

81
W/memo
View file

@ -1,6 +1,6 @@
#!/bin/sh
# $Id: memo,v 1.63 2015/12/18 20:53:37 gilles Exp gilles $
# $Id: memo,v 1.66 2017/04/12 20:57:37 gilles Exp gilles $
count_nice() {
@ -281,7 +281,7 @@ verify_month_year() {
cd $HOME/imapsync_stats
fmy="stats_imapsync_${year}_${month}.ip"
test -f "$fmy" || { echo "No $fmy" ; statistics_VERSION_monthly_ip ${month} ${year} ; }
test -f "$fmy" || { echo "No $fmy" ; return 1 ; }
test -f "$fmy" || { echo "No $fmy" ; return 0 ; }
fmy_YYYYmm=`date -r "$fmy" +%Y%m`
diff_month=`expr $fmy_YYYYmm - ${year}${month}` || :
echo -n $diff_month
@ -337,9 +337,10 @@ statistics_VERSION_yearly_os() {
FreeBSD=`grep -i freebsd stats_imapsync_${year}.ip | wc -l`
Solaris=`grep -i solaris stats_imapsync_${year}.ip | wc -l`
OpenBSD=`grep -i openbsd stats_imapsync_${year}.ip | wc -l`
Other=`egrep -i -v 'linux|MSWin32|darwin|freebsd|solaris|openbsd' stats_imapsync_${year}.ip |wc -l`
Nb_All=`cat stats_imapsync_${year}.ip | wc -l`
for OS in Linux Win32 Darwin FreeBSD Solaris OpenBSD Other; do
Unknown=`grep -i '"-"' stats_imapsync_${year}.ip | wc -l`
Other=`egrep -i -v 'linux|MSWin32|darwin|freebsd|solaris|openbsd|"-"' stats_imapsync_${year}.ip |wc -l`
Nb_All=`cat stats_imapsync_${year}.ip | wc -l`
for OS in Linux Win32 Darwin FreeBSD Solaris OpenBSD Unknown Other; do
#echo $OS `eval "echo \\$$OS"` / $Nb_All
Nb_OS=`eval "echo \\$$OS"`
PerCent=`echo "scale=2; 100*$Nb_OS/$Nb_All" | bc -l`
@ -416,7 +417,7 @@ wget http://download.maxmind.com/download/geoip/database/asnum/GeoIPASNum.dat.gz
gunzip GeoIP.dat.gz
gunzip GeoIPASNum.dat.gz
gunzip GeoLiteCity.dat.gz
sudo cp GeoIP.dat GeoIPASNum.dat GeoLiteCity.dat /usr/share/GeoIP/
sudo mv GeoIP.dat GeoIPASNum.dat GeoLiteCity.dat /usr/share/GeoIP/
EOF
}
@ -469,6 +470,13 @@ statistics_releases_monthly() {
)
}
statistics_releases_previous_month() {
month=${1:-`date '+%m' -d 'last month'`}
year=${2:-`date '+%Y' -d 'last month'`}
statistics_releases_monthly $month $year
}
statistics_releases_yearly() {
year=${1:-`date '+%Y'`}
(
@ -574,11 +582,15 @@ statistics_VERSION_synthesis() {
echo && echo "==== % Operating systems in ${year} "
statistics_VERSION_yearly_os $year
echo && echo "==== Perl releases in ${year} "
statistics_perl_yearly $year | tail -9
statistics_perl_yearly $year | tail -15
echo && echo "==== Biggest users in ${year} "
tail -n 9 stats_imapsync_${year}.ip
tail -n 15 stats_imapsync_${year}.ip
echo && echo "==== Most releases used in ${year} "
statistics_releases_yearly ${year} | tail -9
statistics_releases_yearly ${year} | tail -15
echo && echo "==== Most releases used the previous month "
statistics_releases_previous_month | tail -10
echo && echo "==== Most releases used this month "
statistics_releases_monthly | tail -10
echo && echo "==== Nb users each year "
wc -l stats_imapsync_????.ip
echo && echo "==== Nb runs each year : "
@ -593,8 +605,6 @@ statistics_VERSION_synthesis() {
)
}
}
test X"`hostname`" = Xks2 && statistics_VERSION_ks
@ -632,54 +642,5 @@ niouzes_compil
#' nedit sucks with syntax color
fm_init() {
software_version
NEWS_FILE_FM="./freshmeat_submition"
NEWS_FILE_FM_INP=${NEWS_FILE_FM}.inp
NEWS_FILE_FM_OUT=${NEWS_FILE_FM}.json
}
fm_read_param() {
# read definitions
. $NEWS_FILE_FM_INP
}
fm_read_announce() {
fm_init
fm_read_param
cat << EOF
{
"release": {
"tag_list": "stable, $RELEASE_FOCUS",
"version": "$VERSION",
"hidden_from_frontpage": false,
"changelog": "$TEXT_BODY"
}
}
EOF
}
fm_announce() {
fm_init
if ! newer VERSION $NEWS_FILE_FM_OUT; then
echo "$VERSION already submitted on freshmeat"
else
if newer VERSION $NEWS_FILE_FM_INP; then
echo "Update $NEWS_FILE_FM_INP please"
return 1
fi
fm_read_announce > $NEWS_FILE_FM_OUT
curl -X PUT -d @../../var/pass/secret.freshmeat -d @$NEWS_FILE_FM_OUT \
-H "Content-Type: application/json" \
http://freshmeat.net/projects/imapsync.json
fi
}

View file

@ -1,7 +1,6 @@
m4_dnl $Id: ml_announce.in,v 1.16 2016/08/18 09:38:48 gilles Exp gilles $
m4_dnl $Id: ml_announce.in,v 1.18 2017/09/07 00:42:57 gilles Exp gilles $
m4_dnl
m4_define(`M4_imapsync_VERSION',m4_esyscmd(cat VERSION|tr -d '\n'))m4_dnl
m4_define(`M4_SECRET_PATH',m4_esyscmd(cat dist/path_last.txt|tr -d '\n'))m4_dnl
m4_dnl
From: Gilles LAMIRAL <gilles.lamiral@laposte.net>
Bcc: gilles@lamiral.info
@ -11,29 +10,29 @@ To: imapsync_update@lists.lamiral.info
Dear imapsync user,
You're subscribed to the newsletter announcing imapsync new releases
(very few traffic) and the way to get them. Send me a note if you
don't want to receive those announces anymore.
(very few traffic) and the way to get them.
Send me a note if you don't want to receive those announces anymore.
You will find the latest imapsync.exe binary (release M4_imapsync_VERSION),
the latest imapsync source code (release M4_imapsync_VERSION),
OS X and Linux (i386) binaries at the following link:
You will find
https://imapsync.lamiral.info/dist/M4_SECRET_PATH
* imapsync.exe binary (release M4_imapsync_VERSION)
* Mac OS X binary
* imapsync perl source code (release M4_imapsync_VERSION)
or also more permanently from this page
at the following link:
https://imapsync.lamiral.info/paypal_return.shtml
https://imapsync.lamiral.info/dist/
Three important files are there:
* imapsync is directly the perl script (also found in the tarball and zip) for a fast upgrade.
* imapsync-M4_imapsync_VERSION.tgz is the tarball containing everything of the project (maybe too much)
* imapsync.M4_imapsync_VERSION.zip is the win32 zip archive including standalone binary imapsync.exe.
* imapsync is the perl script for a fast upgrade (also found in the tarball and zip).
* imapsync-M4_imapsync_VERSION.tgz is the tarball containing the most part of the project (maybe too much)
* imapsync.M4_imapsync_VERSION.zip is the win32 zip archive including standalone binary imapsync.exe
What's new in this M4_imapsync_VERSION release can be found at
https://imapsync.lamiral.info/S/news.shtml
Vote for better imapsync and services at
http://imapsync.lamiral.info/poll.shtml
http://imapsync.lamiral.info/S/poll.shtml
I thank you again for buying and using imapsync,
I wish you successful imap transfers!

25
W/paypal_reply/MapUTF8_bug Executable file
View file

@ -0,0 +1,25 @@
#!/usr/bin/perl -w
# $Id: 8859_utf8,v 1.1 2010/10/01 13:00:09 gilles Exp gilles $
use Unicode::MapUTF8 qw(to_utf8 from_utf8 utf8_supported_charset);
use strict ;
use warnings ;
die unless (utf8_supported_charset('ISO-8859-1'));
local $/ ;
my $string = <> ;
# print $string ;
my $string_utf8 = to_utf8({ -string => $string, -charset => 'ISO-8859-1' }) ;
print $string_utf8 ;
#foreach my $string ( "A", "\xE9", "\xE9\x1A" ) {
# print to_utf8({ -string => $string, -charset => 'ISO-8859-1' }), "\n";
#}

26
W/paypal_reply/MapUTF8_bug2 Executable file
View file

@ -0,0 +1,26 @@
#!/usr/bin/perl -w
# $Id: 8859_utf8,v 1.1 2010/10/01 13:00:09 gilles Exp gilles $
use Unicode::MapUTF8 qw(to_utf8 from_utf8 utf8_supported_charset);
use strict ;
use warnings ;
die unless (utf8_supported_charset('ISO-8859-1'));
#local $/ ;
my @string = <> ;
my $string = join( q{}, @string ) ;
# print $string ;
my $string_utf8 = to_utf8({ -string => $string, -charset => 'ISO-8859-1' }) ;
print $string_utf8 ;
#foreach my $string ( "A", "\xE9", "\xE9\x1A" ) {
# print to_utf8({ -string => $string, -charset => 'ISO-8859-1' }), "\n";
#}

View file

@ -1,86 +1,92 @@
1225 Etats-Unis______________ 24.84 % 25 % 1
918 Allemagne_______________ 18.62 % 43 % 2
454 Royaume-Uni_____________ 9.21 % 53 % 3
253 Italie__________________ 5.13 % 58 % 4
243 France__________________ 4.93 % 63 % 5
219 Canada__________________ 4.44 % 67 % 6
199 Suisse__________________ 4.04 % 71 % 7
183 Pays-Bas________________ 3.71 % 75 % 8
172 Australie_______________ 3.49 % 78 % 9
98 Autriche________________ 1.99 % 80 % 10
91 Espagne_________________ 1.85 % 82 % 11
88 Belgique________________ 1.78 % 84 % 12
71 Suede___________________ 1.44 % 85 % 13
58 Danemark________________ 1.18 % 87 % 14
51 Bresil__________________ 1.03 % 88 % 15
43 Norvege_________________ 0.87 % 89 % 16
36 Pologne_________________ 0.73 % 89 % 17
33 Finlande________________ 0.67 % 90 % 18
28 Republique_tcheque______ 0.57 % 91 % 19
26 Russie__________________ 0.53 % 91 % 20
26 Japon___________________ 0.53 % 92 % 21
25 ________________________ 0.51 % 92 % 22
23 Nouvelle-Zelande________ 0.47 % 93 % 23
23 Irlande_________________ 0.47 % 93 % 24
23 Hongrie_________________ 0.47 % 93 % 25
19 Portugal________________ 0.39 % 94 % 26
18 Hong-Kong_______________ 0.37 % 94 % 27
18 Grece___________________ 0.37 % 95 % 28
18 Afrique_du_Sud__________ 0.37 % 95 % 29
14 Slovaquie_______________ 0.28 % 95 % 30
14 Malaisie________________ 0.28 % 96 % 31
13 Luxembourg______________ 0.26 % 96 % 32
13 Inde____________________ 0.26 % 96 % 33
12 Singapour_______________ 0.24 % 96 % 34
12 Mexique_________________ 0.24 % 97 % 35
12 Argentine_______________ 0.24 % 97 % 36
11 Israel__________________ 0.22 % 97 % 37
11 Chine___________________ 0.22 % 97 % 38
11 Chili___________________ 0.22 % 97 % 39
10 Roumanie________________ 0.20 % 98 % 40
9 Slovenie________________ 0.18 % 98 % 41
9 Lettonie________________ 0.18 % 98 % 42
9 Emirats_Arabes_Unis_____ 0.18 % 98 % 43
7 Croatie_________________ 0.14 % 98 % 44
6 Thailande_______________ 0.12 % 98 % 45
5 Malte___________________ 0.10 % 99 % 46
5 Islande_________________ 0.10 % 99 % 47
4 Turquie_________________ 0.08 % 99 % 48
4 Indonesie_______________ 0.08 % 99 % 49
4 Estonie_________________ 0.08 % 99 % 50
4 Egypte__________________ 0.08 % 99 % 51
4 Bulgarie________________ 0.08 % 99 % 52
3 Venezuela_______________ 0.06 % 99 % 53
3 Serbie__________________ 0.06 % 99 % 54
3 Philippines_____________ 0.06 % 99 % 55
2 Vietnam_________________ 0.04 % 99 % 56
2 Uruguay_________________ 0.04 % 99 % 57
2 Perou___________________ 0.04 % 99 % 58
2 Lituanie________________ 0.04 % 99 % 59
2 Costa_Rica______________ 0.04 % 99 % 60
2 Chypre__________________ 0.04 % 99 % 61
2 Antilles_neerlandaises__ 0.04 % 100 % 62
1 Ukraine_________________ 0.02 % 100 % 63
1 Trinite-et-Tobago_______ 0.02 % 100 % 64
1 Tanzanie________________ 0.02 % 100 % 65
1 Taiwan__________________ 0.02 % 100 % 66
1 Senegal_________________ 0.02 % 100 % 67
1 Saint_Christophe-Nevis-Anguilla__ 0.02 % 100 % 68
1 Qatar___________________ 0.02 % 100 % 69
1 Panama__________________ 0.02 % 100 % 70
1 Nouvelle-Caledonie______ 0.02 % 100 % 71
1 Nigeria_________________ 0.02 % 100 % 72
1 Namibie_________________ 0.02 % 100 % 73
1 Mongolie________________ 0.02 % 100 % 74
1 Moldavie________________ 0.02 % 100 % 75
1 Maldives________________ 0.02 % 100 % 76
1 Koweit__________________ 0.02 % 100 % 77
1 Jordanie________________ 0.02 % 100 % 78
1 Iles_Vierges_britanniques__ 0.02 % 100 % 79
1 Grenade_________________ 0.02 % 100 % 80
1 Coree_du_Sud____________ 0.02 % 100 % 81
1 Colombie________________ 0.02 % 100 % 82
1 Cameroun________________ 0.02 % 100 % 83
1 Burkina_Faso____________ 0.02 % 100 % 84
1 Bahrein_________________ 0.02 % 100 % 85
TOTAL = 4931 sales 219147 EUR over 85 countries on Tue Aug 16 19:44:43 CEST 2016
1370 Etats-Unis______________ 23.66 % 24 % 1
1108 Allemagne_______________ 19.14 % 43 % 2
521 Royaume-Uni_____________ 9.00 % 52 % 3
341 Italie__________________ 5.89 % 58 % 4
282 France__________________ 4.87 % 63 % 5
241 Canada__________________ 4.16 % 67 % 6
232 Pays-Bas________________ 4.01 % 71 % 7
231 Suisse__________________ 3.99 % 75 % 8
195 Australie_______________ 3.37 % 78 % 9
127 Autriche________________ 2.19 % 80 % 10
119 Espagne_________________ 2.06 % 82 % 11
96 Belgique________________ 1.66 % 84 % 12
87 Suede___________________ 1.50 % 85 % 13
77 Danemark________________ 1.33 % 87 % 14
55 Bresil__________________ 0.95 % 88 % 15
47 Pologne_________________ 0.81 % 89 % 16
45 Norvege_________________ 0.78 % 89 % 17
37 Republique_tcheque______ 0.64 % 90 % 18
37 Finlande________________ 0.64 % 91 % 19
31 Russie__________________ 0.54 % 91 % 20
28 Nouvelle-Zelande________ 0.48 % 92 % 21
28 Hongrie_________________ 0.48 % 92 % 22
27 Japon___________________ 0.47 % 93 % 23
25 ________________________ 0.43 % 93 % 24
23 Irlande_________________ 0.40 % 93 % 25
22 Grece___________________ 0.38 % 94 % 26
21 Portugal________________ 0.36 % 94 % 27
20 Afrique_du_Sud__________ 0.35 % 95 % 28
19 Hong-Kong_______________ 0.33 % 95 % 29
17 Slovaquie_______________ 0.29 % 95 % 30
17 Inde____________________ 0.29 % 95 % 31
16 Mexique_________________ 0.28 % 96 % 32
16 Argentine_______________ 0.28 % 96 % 33
15 Malaisie________________ 0.26 % 96 % 34
15 Chili___________________ 0.26 % 97 % 35
14 Singapour_______________ 0.24 % 97 % 36
14 Luxembourg______________ 0.24 % 97 % 37
14 Chine___________________ 0.24 % 97 % 38
13 Roumanie________________ 0.22 % 97 % 39
12 Slovenie________________ 0.21 % 98 % 40
11 Israel__________________ 0.19 % 98 % 41
10 Emirats_Arabes_Unis_____ 0.17 % 98 % 42
9 Lettonie________________ 0.16 % 98 % 43
7 Croatie_________________ 0.12 % 98 % 44
6 Thailande_______________ 0.10 % 98 % 45
6 Islande_________________ 0.10 % 99 % 46
5 Malte___________________ 0.09 % 99 % 47
5 Estonie_________________ 0.09 % 99 % 48
5 Egypte__________________ 0.09 % 99 % 49
4 Turquie_________________ 0.07 % 99 % 50
4 Indonesie_______________ 0.07 % 99 % 51
4 Chypre__________________ 0.07 % 99 % 52
4 Bulgarie________________ 0.07 % 99 % 53
3 Venezuela_______________ 0.05 % 99 % 54
3 Serbie__________________ 0.05 % 99 % 55
3 Philippines_____________ 0.05 % 99 % 56
3 Lituanie________________ 0.05 % 99 % 57
3 Ireland_________________ 0.05 % 99 % 58
2 Vietnam_________________ 0.03 % 99 % 59
2 Uruguay_________________ 0.03 % 99 % 60
2 Ukraine_________________ 0.03 % 99 % 61
2 Perou___________________ 0.03 % 99 % 62
2 Nouvelle-Caledonie______ 0.03 % 99 % 63
2 Costa_Rica______________ 0.03 % 100 % 64
2 Antilles_neerlandaises__ 0.03 % 100 % 65
1 Trinite-et-Tobago_______ 0.02 % 100 % 66
1 Tanzanie________________ 0.02 % 100 % 67
1 Taiwan__________________ 0.02 % 100 % 68
1 Senegal_________________ 0.02 % 100 % 69
1 Saint_Christophe-Nevis-Anguilla__ 0.02 % 100 % 70
1 Qatar___________________ 0.02 % 100 % 71
1 Panama__________________ 0.02 % 100 % 72
1 Nigeria_________________ 0.02 % 100 % 73
1 Namibie_________________ 0.02 % 100 % 74
1 Mongolie________________ 0.02 % 100 % 75
1 Monaco__________________ 0.02 % 100 % 76
1 Moldavie________________ 0.02 % 100 % 77
1 Maldives________________ 0.02 % 100 % 78
1 Koweit__________________ 0.02 % 100 % 79
1 Jordanie________________ 0.02 % 100 % 80
1 Jamaique________________ 0.02 % 100 % 81
1 Iles_Vierges_britanniques__ 0.02 % 100 % 82
1 Grenade_________________ 0.02 % 100 % 83
1 Coree_du_Sud____________ 0.02 % 100 % 84
1 Colombie________________ 0.02 % 100 % 85
1 Cameroun________________ 0.02 % 100 % 86
1 Burkina_Faso____________ 0.02 % 100 % 87
1 Bosnie-Herzegovine______ 0.02 % 100 % 88
1 Bahrein_________________ 0.02 % 100 % 89
1 Arabie_Saoudite_________ 0.02 % 100 % 90
1 Albanie_________________ 0.02 % 100 % 91
TOTAL = 5790 sales 267809 EUR over 91 countries on Thu Aug 31 17:19:20 CEST 2017

277
W/paypal_reply/memo Normal file → Executable file
View file

@ -1,6 +1,6 @@
#!/bin/sh
# $Id: memo,v 1.19 2016/08/09 10:50:30 gilles Exp gilles $
# $Id: memo,v 1.27 2017/08/13 18:27:35 gilles Exp gilles $
echo paypal_bilan_todo
@ -23,13 +23,270 @@ Hors Europe : Article 262 => Exoneration
Europe a un autre assujetti : Article 262 ter => Exoneration
- Article 262 ter-1 sur livraisons de biens expédiés. Question : oeuvre immaterielle, service ?
EOF
}
echo paypal_bilan_changefix_Commission_Frais
echo paypal_bilan_online_summary_bug2
paypal_bilan_online_summary_bug2() {
# DID output diff between paypal_bilan_1.100 and next one
(
#set -x
perl -c /g/public_html/imapsync/W/paypal_reply/paypal_bilan || return 1
perl -c /g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.100 || return 1
cd /g/var/paypal_bilan_online_summary_bug2/ || return 1
echo Working in `pwd`
/g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.100 \
--first_in 147 --avoid_numbers '292 293 643 644 731 732 1093
1330 1331 1332 1333 1334 1652 1653 2131 2132
2295 2296 2297 2298 2625 2626 2970 2971 2972
3093 3296 3411 3412 3450 3451 3614 3615 3616 3617
3807 3808 3957 3958 4030 4194 4195 4381 4382 4449 4450
4574 4641 5213 5214 5215 5355 5406
5489 5650' \
/g/paypal/paypal_201?_??_complet.csv \
> all.out1 2>&1 || return 1
/g/public_html/imapsync/W/paypal_reply/paypal_bilan \
--first_in 147 --avoid_numbers '292 293 643 644 731 732 1093
1330 1331 1332 1333 1334 1652 1653 2131 2132
2295 2296 2297 2298 2625 2626 2970 2971 2972
3093 3296 3411 3412 3450 3451 3614 3615 3616 3617
3807 3808 3957 3958 4030 4194 4195 4381 4382 4449 4450
4574 4641 5213 5214 5215 5355 5406
5489 5650' \
/g/paypal/paypal_201?_??_complet.csv \
> all.out2 2>&1 || return 1
echo diff all.out1 all.out2
diff all.out1 all.out2
)
}
echo paypal_bilan_online_summary_bug
paypal_bilan_online_summary_bug() {
# DID output diff between paypal_bilan_1.100 and next one
(
#set -x
perl -c /g/public_html/imapsync/W/paypal_reply/paypal_bilan || return 1
perl -c /g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.100 || return 1
cd /g/var/paypal_bilan_online_summary_bug/ || return 1
echo Working in `pwd`
test -f 2017_07.csv || { echo no 2017_07.csv; return 1; }
/g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.100 \
--debug --debug_csv --debug_email --details --debug_invoice --debug_invoice_utf8 \
--dir_invoices /g/var/paypal_bilan_online_summary_bug/ --first_in 52001 \
2017_07.csv \
> 2017_07.out1 2>&1 || return 1
rm 52???/imapsync_var_manual.tex
/g/public_html/imapsync/W/paypal_reply/paypal_bilan \
--debug --debug_csv --debug_email --details --debug_invoice --debug_invoice_utf8 \
--dir_invoices /g/var/paypal_bilan_online_summary_bug/ --first_in 52001 \
2017_07.csv \
> 2017_07.out2 2>&1 || return 1
echo diff 2017_07.out1 2017_07.out2
diff 2017_07.out1 2017_07.out2
)
}
echo paypal_bilan_online
paypal_bilan_online() {
# DID output diff between paypal_bilan_1.96 and next one
(
#set -x
perl -c /g/public_html/imapsync/W/paypal_reply/paypal_bilan || return 1
perl -c /g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.96 || return 1
cd /g/var/paypal_bilan_online/ || return 1
echo Working in `pwd`
test -f 2017_06.csv || { echo no 2017_06.csv; return 1; }
/g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.96 \
--debug --debug_csv --debug_email --details --debug_invoice --debug_invoice_utf8 \
--dir_invoices /g/var/paypal_bilan_online/ --write_invoices --first_in 51001 \
2017_06.csv \
> 2017_06.out1 2>&1 || return 1
rm 51???/imapsync_var_manual.tex
/g/public_html/imapsync/W/paypal_reply/paypal_bilan \
--debug --debug_csv --debug_email --details --debug_invoice --debug_invoice_utf8 \
--dir_invoices /g/var/paypal_bilan_online/ --write_invoices --first_in 51001 \
2017_06.csv \
> 2017_06.out2 2>&1 || return 1
echo diff 2017_06.out1 2017_06.out2
diff 2017_06.out1 2017_06.out2
)
}
#echo paypal_bilan_invoices_utf8_bug
paypal_bilan_invoices_utf8_bug() {
# DID output diff between paypal_bilan_1.93 and next one
(
#set -x
perl -c /g/public_html/imapsync/W/paypal_reply/paypal_bilan || return 1
perl -c /g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.93 || return 1
cd /g/var/paypal_bilan_invoices_utf8_bug/ || return 1
echo Working in `pwd`
test -f 2017_02.csv || { echo no 2017_02.csv; return 1; }
/g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.93 \
--debug --debug_csv --debug_email --details --debug_invoice --debug_invoice_utf8 \
--dir_invoices /g/var/paypal_bilan_invoices_utf8_bug/ --write_invoices --first_in 51001 \
2017_02.csv \
> 2017_02.out1 2>&1 || return 1
rm 51???/imapsync_var_manual.tex
/g/public_html/imapsync/W/paypal_reply/paypal_bilan \
--debug --debug_csv --debug_email --details --debug_invoice --debug_invoice_utf8 \
--dir_invoices /g/var/paypal_bilan_invoices_utf8_bug/ --write_invoices --first_in 51001 \
2017_02.csv \
> 2017_02.out2 2>&1 || return 1
echo diff 2017_02.out1 2017_02.out2
diff 2017_02.out1 2017_02.out2
)
}
#echo paypal_bilan_no_US_if_0_dollars
paypal_bilan_no_US_if_0_dollars() {
# DID output diff between paypal_bilan_1.92 and next one
(
#set -x
perl -c /g/public_html/imapsync/W/paypal_reply/paypal_bilan || return 1
perl -c /g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.92 || return 1
cd /g/var/paypal_bilan_no_US_if_0_dollars/ || return 1
test -f /g/paypal/paypal_2017_03_complet.csv || { echo no /g/paypal/paypal_2017_03_complet.csv; return 1; }
/g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.92 --first_in 54001 \
/g/paypal/paypal_2017_03_complet.csv \
> 2017_03.out1 2>&1 || return 1
/g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 54001 \
/g/paypal/paypal_2017_03_complet.csv \
> 2017_03.out2 2>&1 || return 1
echo diff 2017_03.out1 2017_03.out2
diff 2017_03.out1 2017_03.out2
/g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.92 --first_in 55001 \
/g/paypal/paypal_201?_??_complet.csv \
> all.out1 2>&1 || return 1
/g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 55001 \
/g/paypal/paypal_201?_??_complet.csv \
> all.out2 2>&1 || return 1
echo diff all.out1 all.out2
diff all.out1 all.out2
)
}
#echo paypal_bilan_client_type_VAT_imply_pro
paypal_bilan_client_type_VAT_imply_pro() {
# DID output diff between paypal_bilan_1.91 and next one
(
#set -x
perl -c /g/public_html/imapsync/W/paypal_reply/paypal_bilan || return 1
perl -c /g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.91 || return 1
cd /g/var/paypal_bilan_client_type_VAT_imply_pro/ || return 1
cp /g/paypal/paypal_2017_03_complet.csv 2017_03.csv || return 1
test -f 2017_03.csv || { echo no 2017_03.csv; return 1; }
/g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.91 \
--debug --debug_csv --debug_email --details --debug_invoice_utf8 \
--dir_invoices /g/var/paypal_bilan_client_type_VAT_imply_pro/ --first_in 52001 \
2017_03.csv \
> 2017_03.out1 2>&1 || return 1
/g/public_html/imapsync/W/paypal_reply/paypal_bilan \
--debug --debug_csv --debug_email --details --debug_invoice_utf8 \
--dir_invoices /g/var/paypal_bilan_client_type_VAT_imply_pro/ --first_in 52001 \
2017_03.csv \
> 2017_03.out2 2>&1 || return 1
echo diff 2017_03.out1 2017_03.out2
diff 2017_03.out1 2017_03.out2
cp /g/paypal/paypal_201[67]_??_complet.csv .
/g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.91 \
--debug --debug_csv --debug_email --details --debug_invoice_utf8 \
--dir_invoices /g/var/paypal_bilan_client_type_VAT_imply_pro/ --first_in 53001 \
paypal_201[67]_??_complet.csv \
> all.out1 2>&1 || return 1
#cp /g/paypal/paypal_201[67]_??_complet.csv .
/g/public_html/imapsync/W/paypal_reply/paypal_bilan \
--debug --debug_csv --debug_email --details --debug_invoice_utf8 \
--dir_invoices /g/var/paypal_bilan_client_type_VAT_imply_pro/ --first_in 53001 \
paypal_201[67]_??_complet.csv \
> all.out2 2>&1 || return 1
echo diff all.out1 all.out2
diff all.out1 all.out2
)
}
#echo paypal_bilan_individual_or_france_bug
paypal_bilan_individual_or_france_bug() {
# DID output diff between paypal_bilan_1.84 and next
(
#set -x
perl -c /g/public_html/imapsync/W/paypal_reply/paypal_bilan || return 1
perl -c /g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.84 || return 1
cd /g/var/paypal_bilan_individual_or_france_bug/ || return 1
test -f 2016_10.csv || { echo no 2016_10.csv; return 1; }
/g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.84 \
--debug --debug_csv --debug_email --details --debug_invoice \
--dir_invoices /g/var/paypal_invoices_dev --write_invoices --first_in 50001 \
2016_10.csv \
> 2016_10.out1 2>&1 || return 1
/g/public_html/imapsync/W/paypal_reply/paypal_bilan \
--debug --debug_csv --debug_email --details --debug_invoice \
--dir_invoices /g/var/paypal_invoices_dev --write_invoices --first_in 50001 \
2016_10.csv \
> 2016_10.out2 2>&1 || return 1
echo diff 2016_10.out1 2016_10.out2
diff 2016_10.out1 2016_10.out2
/g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.84 \
--first_in 4575 --avoid_numbers '4574 4641 5213 5214 5215' \
/g/paypal/paypal_2016_??_complet.csv > 2016.out1 2>&1 || return 1
/g/public_html/imapsync/W/paypal_reply/paypal_bilan \
--first_in 4575 --avoid_numbers '4574 4641 5213 5214 5215' \
/g/paypal/paypal_2016_??_complet.csv > 2016.out2 2>&1 || return 1
echo diff 2016.out1 2016.out2
diff 2016.out1 2016.out2
)
}
#echo paypal_bilan_changefix_Commission_Frais
paypal_bilan_changefix_Commission_Frais() {
# DID output diff between
(
@ -73,7 +330,7 @@ echo diff 2016_07_old.out3 2016_07_new.out3
echo paypal_bilan_licence_support_only_csv
#echo paypal_bilan_licence_support_only_csv
paypal_bilan_licence_support_only_csv() {
# DID output diff between paypal_bilan_1.79 and next
(
@ -100,7 +357,7 @@ echo diff 2015_08.out1 2015_08.out2
echo paypal_bilan_licence_support_same_button_04_2014_04_csv
#echo paypal_bilan_licence_support_same_button_04_2014_04_csv
paypal_bilan_licence_support_same_button_04_2014_04_csv() {
# DID output diff between paypal_bilan_1.78 and next
(
@ -126,7 +383,7 @@ echo diff 2014_04.out1 2014_04.out2
echo paypal_bilan_licence_support_same_button_03_A_B_several_csv
#echo paypal_bilan_licence_support_same_button_03_A_B_several_csv
paypal_bilan_licence_support_same_button_03_A_B_several_csv() {
# DID output diff between paypal_bilan_1.78 and next
(
@ -152,7 +409,7 @@ echo diff several.out1 several.out2
echo paypal_bilan_licence_support_same_button_02_A_B_one_line
#echo paypal_bilan_licence_support_same_button_02_A_B_one_line
paypal_bilan_licence_support_same_button_02_A_B_one_line() {
# DID output diff between paypal_bilan_1.78 and next
(
@ -180,7 +437,7 @@ done
}
echo paypal_bilan_licence_support_same_button_01_ALL_before_B_C
#echo paypal_bilan_licence_support_same_button_01_ALL_before_B_C
paypal_bilan_licence_support_same_button_01_ALL_before_B_C() {
# DID output diff between paypal_bilan_1.77 and next
(
@ -206,7 +463,7 @@ echo diff /g/var/paypal_bilan/tests/paypal_invoice.out1 /g/var/paypal_bilan/test
}
echo paypal_bilan_final_presentation_for_tva
#echo paypal_bilan_final_presentation_for_tva
paypal_bilan_final_presentation_for_tva() {
# DID output diff between paypal_bilan_1.72 and 1.73
(

View file

@ -1,6 +1,6 @@
#!/usr/bin/perl
# $Id: paypal_bilan,v 1.83 2016/08/18 09:43:40 gilles Exp gilles $
# $Id: paypal_bilan,v 1.104 2017/08/17 11:06:03 gilles Exp gilles $
use strict;
use warnings;
@ -11,22 +11,31 @@ use Data::Dumper ;
use Unicode::MapUTF8 qw(to_utf8 from_utf8 utf8_supported_charset);
use Test::More 'no_plan' ;
#print join( "\n", utf8_supported_charset( ) ) ;
die unless (utf8_supported_charset('ISO-8859-1'));
my $rcs = '$Id: paypal_bilan,v 1.83 2016/08/18 09:43:40 gilles Exp gilles $ ' ;
my $rcs = '$Id: paypal_bilan,v 1.104 2017/08/17 11:06:03 gilles Exp gilles $ ' ;
$rcs =~ m/,v (\d+\.\d+)/ ;
my $VERSION = ($1) ? $1: "UNKNOWN" ;
my $total_usd_received = 0 ;
my $total_usd_invoice = 0 ;
my $total_HT_EUR_logi_exo = 0 ;
my $total_HT_EUR_logi_ass = 0 ;
my $total_TVA_EUR_logi = 0 ;
my $total_HT_EUR_sup = 0 ;
my $total_TVA_EUR_sup = 0 ;
my $total_HT_EUR_sup_exo = 0 ;
my $total_HT_EUR_sup_ass = 0 ;
my $total_TVA_EUR_sup = 0 ;
my $total_HT_EUR_serv_exo = 0 ;
my $total_HT_EUR_serv_ass = 0 ;
my $total_TVA_EUR_serv = 0 ;
my $total_eur_received = 0 ;
my $total_eur_invoice = 0 ;
@ -149,7 +158,7 @@ foreach my $invoice ( @invoices_wanted ) {
my $email_address = $action->{ "De l'adresse email" } ;
my $invoice_sent = invoice_sent( $dir_invoices, $invoice, $email_address ) ;
#print "$invoice $invoice_sent\n" ;
#print "$invoice $invoice_sent $email_address\n" ;
if ( $invoice_sent ) {
$invoice_sent{ $invoice }++ ;
@ -173,9 +182,9 @@ print( "\n", "=" x 60, "\n" ) ;
my $total_usd_paypal_cost ;
$total_usd_paypal_cost = sprintf('%2.2f', $total_usd_invoice - $total_usd_received ) ;
print "USD received $total_usd_received\n" ;
print "USD invoice $total_usd_invoice\n" ;
print "USD costs $total_usd_paypal_cost\n" ;
if ( 0 < $total_usd_received ) { print "USD received $total_usd_received\n" ; }
if ( 0 < $total_usd_invoice ) { print "USD invoice $total_usd_invoice\n" ; }
if ( 0 < $total_usd_paypal_cost ) { print "USD costs $total_usd_paypal_cost\n" ; }
my $total_eur_invoice_from_usd ;
my $total_eur_received_from_usd ;
@ -189,7 +198,7 @@ $total_eur_paypal_cost_from_usd = sprintf('%2.2f', $total_usd_paypal_cost / $
# EUR
$total_eur_received = sprintf('%2.2f', $total_eur_received) ;
$total_eur_invoice = sprintf('%2.2f', $total_eur_invoice) ;
print "EUR invoice from USD $total_eur_invoice_from_usd\n" ;
if ( 0 < $total_eur_invoice_from_usd ) { print "EUR invoice from USD $total_eur_invoice_from_usd\n" ; }
print "EUR received from EUR $total_eur_received\n" ;
print "EUR invoice from EUR $total_eur_invoice\n" ;
@ -202,10 +211,18 @@ $total_HT_EUR_logi_exo = sprintf('%2.2f', $total_HT_EUR_logi_exo) ;
$total_HT_EUR_logi_ass = sprintf('%2.2f', $total_HT_EUR_logi_ass) ;
$total_TVA_EUR_logi = sprintf('%2.2f', $total_TVA_EUR_logi) ;
$total_HT_EUR_sup = sprintf('%2.2f', $total_HT_EUR_sup) ;
$total_HT_EUR_sup_ass = sprintf('%2.2f', $total_HT_EUR_sup_ass) ;
$total_TVA_EUR_sup = sprintf('%2.2f', $total_TVA_EUR_sup) ;
$total_HT_EUR_sup_exo = sprintf('%2.2f', $total_HT_EUR_sup_exo) ;
$total_HT_EUR_serv_exo = sprintf('%2.2f', $total_HT_EUR_serv_exo) ;
$total_HT_EUR_serv_ass = sprintf('%2.2f', $total_HT_EUR_serv_ass) ;
$total_TVA_EUR_serv = sprintf('%2.2f', $total_TVA_EUR_serv) ;
my $total_HT_EUR_exo = $total_HT_EUR_sup_exo + $total_HT_EUR_logi_exo + $total_HT_EUR_serv_exo ;
$total_HT_EUR_exo = sprintf('%2.2f', $total_HT_EUR_exo) ;
$total_eur_invoice_from_eur_usd = sprintf('%2.2f', $total_eur_invoice_from_eur_usd) ;
$total_eur_paypal_cost = sprintf('%2.2f', $total_eur_paypal_cost) ;
@ -215,14 +232,16 @@ print "EUR total received $total_eur_received_from_eur_usd\n" ;
print "EUR total paypal cost $total_eur_paypal_cost\n" ;
print ;
print( "---- Assujeti TVA ----\n" ) ;
print "EUR total HT licen assuj $total_HT_EUR_logi_ass (autres operations imposables)\n" ;
#print "EUR total TVA licen assuj $total_TVA_EUR_logi\n" ;
print "EUR total HT supp assuj $total_HT_EUR_sup (ventes, prestations)\n" ;
#print "EUR total TVA supp assuj $total_TVA_EUR_sup\n" ;
#print "EUR total HT supp assuj $total_HT_EUR_sup_ass (ventes, prestations)\n" ;
print "EUR total HT serv+supp assuj ", $total_HT_EUR_serv_ass + $total_HT_EUR_sup_ass, " (ventes, prestations)\n" ;
print "EUR total HT licences assuj $total_HT_EUR_logi_ass (autres operations imposables)\n" ;
print( "---- Exonere TVA ----\n" ) ;
print "EUR total HT licen exo $total_HT_EUR_logi_exo (autres operations NON imposables)\n" ;
print "EUR total HT suppo exo $total_HT_EUR_sup_exo (autres operations NON imposables)\n" ;
#print "EUR total HT suppo exo $total_HT_EUR_sup_exo (autres operations NON imposables)\n" ;
print "EUR total HT serv+supp exo ", $total_HT_EUR_serv_exo + $total_HT_EUR_sup_exo, " (autres operations NON imposables)\n" ;
print "EUR total HT licences exo $total_HT_EUR_logi_exo (autres operations NON imposables)\n" ;
print "EUR total HT autres operations NON imposables: $total_HT_EUR_serv_exo + $total_HT_EUR_sup_exo + $total_HT_EUR_logi_exo = $total_HT_EUR_exo\n" ;
print( "---- Invoices ----\n" ) ;
@ -233,9 +252,12 @@ print "Nb invoice refund ($nb_invoice_refund) @invoice_refund\n" ;
print "Nb invoice sent $nb_invoice_sent\n" ;
print "Have to send invoices @invoice_not_sent\n" if ( @invoice_not_sent ) ;
my $total_eur2 = $total_HT_EUR_logi_exo + $total_HT_EUR_logi_ass + $total_TVA_EUR_logi + $total_HT_EUR_sup + $total_TVA_EUR_sup + $total_HT_EUR_sup_exo ;
my $total_eur2 = $total_HT_EUR_logi_exo + $total_HT_EUR_logi_ass + $total_TVA_EUR_logi
+ $total_HT_EUR_sup_exo + $total_HT_EUR_sup_ass + $total_TVA_EUR_sup
+ $total_HT_EUR_serv_exo + $total_HT_EUR_serv_ass + $total_TVA_EUR_serv ;
$total_eur2 = sprintf('%2.2f', $total_eur2) ;
print "$total_eur_invoice_from_eur_usd != $total_eur2 = $total_HT_EUR_logi_exo + $total_HT_EUR_logi_ass + $total_TVA_EUR_logi + $total_HT_EUR_sup + $total_TVA_EUR_sup + $total_HT_EUR_sup_exo\n"
print "$total_eur_invoice_from_eur_usd != $total_eur2 = $total_HT_EUR_logi_exo + $total_HT_EUR_logi_ass + $total_TVA_EUR_logi + $total_HT_EUR_sup_ass + $total_TVA_EUR_sup + $total_HT_EUR_sup_exo\n"
if ( $total_eur_invoice_from_eur_usd != $total_eur2 ) ;
sub parse_one_line_io {
@ -490,9 +512,15 @@ sub paiement_eur_termine {
$total_HT_EUR_logi_exo += $A->{montant_HT_EUR_logi_exo} ;
$total_HT_EUR_logi_ass += $A->{montant_HT_EUR_logi_ass} ;
$total_TVA_EUR_logi += $A->{montant_TVA_EUR_logi} ;
$total_HT_EUR_sup += $A->{montant_HT_EUR_sup} ;
$total_TVA_EUR_sup += $A->{montant_TVA_EUR_sup} ;
$total_HT_EUR_sup_exo += $A->{montant_HT_EUR_sup_exo} ;
$total_HT_EUR_sup_ass += $A->{montant_HT_EUR_sup} ;
$total_TVA_EUR_sup += $A->{montant_TVA_EUR_sup} ;
$total_HT_EUR_sup_exo += $A->{montant_HT_EUR_sup_exo} ;
$total_HT_EUR_serv_exo += $A->{montant_HT_EUR_serv_exo} ;
$total_HT_EUR_serv_ass += $A->{montant_HT_EUR_serv_ass} ;
$total_TVA_EUR_serv += $A->{montant_TVA_EUR_serv} ;
$A->{invoice} = next_invoice( ) ;
$nb_invoice++ ;
@ -597,11 +625,6 @@ sub compute_line {
( $A->{N_de_transaction} ) = @action{ ( 'N° de transaction' ) } || @action{ ( 'Numéro de transaction' ) } ;
#( $A->{} ) = @action{ ( '' ) } || @action{ ( '' ) } ;
#( $A->{} ) = @action{ ( '' ) } || @action{ ( '' ) } ;
#( $A->{} ) = @action{ ( '' ) } || @action{ ( '' ) } ;
#( $A->{} ) = @action{ ( '' ) } || @action{ ( '' ) } ;
#( $A->{} ) = @action{ ( '' ) } || @action{ ( '' ) } ;
#( $A->{} ) = @action{ ( '' ) } || @action{ ( '' ) } ;
#( $A->{} ) = @action{ ( '' ) } || @action{ ( '' ) } ;
#
$A->{Impact_sur_le_solde} ||= '' ;
@ -631,7 +654,7 @@ sub compute_line {
}
sub BNC_output {
# FE 1359 FR IND imapsync Bougon Edouard
# FE 1359 FR IND imapsync HisName
# [12/01/2012] FR IND 28.73 EUR
my( $invoice, $FR_flag, $IND_flag, $SUPPORT_flag,
$Nom, $Date, $MontantEUR, $Devise, $Titre_de_l_objet, $Impact_sur_le_solde, $Type ) = @_ ;
@ -718,9 +741,7 @@ sub build_invoice {
$F->{Adresse_1} = $action->{'Adresse 1'} || $action->{'Adresse (ligne 1)'} ;
#$F->{} = $action->{''} || $action->{''} ;
#$F->{} = $action->{''} || $action->{''} ;
#$F->{} = $action->{''} || $action->{''} ;
#$F->{} = $action->{''} || $action->{''} ;
#
#etc
$F->{Etat_Province} = $action->{'Etat/Province/Région/Comté/Territoire/Préfecture/République'}
|| $action->{'État/Province/Région/Comté/Territoire/Préfecture/République'}
@ -743,25 +764,60 @@ sub build_invoice {
write_csv_info( $dir_invoices, $F->{invoice}, $F->{file_csv}, $F->{line_number}, $F->{line_csv} ) ;
}
$F->{date_aaaa_mm_jj} = date_aaaa_mm_jj( $F->{Date} ) ;
build_address( $F ) ;
escape_for_tex( $F ) ;
clientVAT( $F ) ;
client_type( $F ) ;
object_type( $F ) ;
vat_type( $F ) ;
description_stuff( $F ) ;
tva_stuff( $F ) ;
$F->{quantity} = '1' ;
download_urls( $F ) ;
( $F->{Nom1} ) = cut( $F->{Nom}, 42 ) ;
$F->{clientVAT} = '' ;
if ( ( 'VAT if professional in Europe' eq $F->{Nom_Option_2} ) and $F->{Option_2_Valeur} ) {
$F->{clientVAT} = $F->{Option_2_Valeur} ;
}
foreach my $key ( keys( %{ $F } ) ) {
#if ( not defined $F->{ $key } ) { print "$key\n" ; }
}
foreach my $key ( qw{
invoice
Nom1
De_l_adresse_email
clientAdrA
clientAdrB
clientAdrC
clientAdrD
clientAdrE
clientAdrF
clientVAT
Date
Heure
descriptionFR
descriptionEN
descriptionBFR
descriptionBEN
usageFR
usageEN
quantity
quantityB
priceHT
priceBHT
priceZHT
tvaFR
priceZTVA
HTorTTC
priceZTTC
messageTVAFR
messageTVAEN
urlSrc
} ) {
#if ( not defined $F->{ $key } ) { print "$key $F->{invoice}\n" ; }
}
my $tex_variables = qq{
%% Begin input from paypal_bilan $VERSION
%% Begin input from paypal_bilan $VERSION éèàù
\\providecommand{\\invoiceNumber}{$F->{invoice}}
\\providecommand{\\clientName}{$F->{Nom1}}
\\providecommand{\\clientEmail}{$F->{De_l_adresse_email}}
@ -797,14 +853,15 @@ sub build_invoice {
%% End input from paypal_bilan
} ;
my $tex_variables_utf8 = to_utf8( { -string => $tex_variables, -charset => 'ISO-8859-1' } ) ;
my $tex_variables_utf8 = Unicode::MapUTF8::to_utf8( { -string => $tex_variables, -charset => 'ISO-8859-1' } ) ;#
$debug_invoice_utf8 and print $tex_variables_utf8 ;
$debug_invoice and print $tex_variables ;
#print "$F->{invoice} ", invoice_sent( $dir_invoices, $F->{invoice}, $F->{De_l_adresse_email} ), "\n" ;
if ( $write_invoices and ! invoice_sent( $dir_invoices, $F->{invoice}, $F->{De_l_adresse_email} ) ) {
write_tex_variables_file( $dir_invoices, $F->{invoice}, $F->{Date}, $tex_variables_utf8 ) ;
if ( $write_invoices
and ! invoice_sent( $dir_invoices, $F->{invoice}, $F->{De_l_adresse_email} ) ) {
write_tex_variables_file( $dir_invoices, $F->{invoice}, $F->{Date}, $tex_variables_utf8, $tex_variables ) ;
}
}
@ -823,26 +880,33 @@ sub description_stuff {
$F->{descriptionEN} = '(Imapsync software. ALL rights conceded, allowed.)' ;
}
if ( 'professional' eq $F->{clientTypeEN}
if ( 'professional' eq $F->{client_type}
and 'software' eq $F->{object_type} ) {
$F->{usageFR} = 'Usage à titre professionnel.' ;
$F->{usageEN} = '(professional usage.)' ;
}
if ( 'individual' eq $F->{clientTypeEN}
if ( 'individual' eq $F->{client_type}
and 'software' eq $F->{object_type} ) {
$F->{usageFR} = 'Usage à titre individuel.' ;
$F->{usageEN} = '(individual usage.)' ;
}
if ( 'support' eq $F->{object_type} ) {
$F->{usageFR} = '' ;
$F->{usageEN} = '' ;
$F->{usageFR} = 'Usage à titre professionnel.' ;
$F->{usageEN} = '(professional usage.)' ;
$F->{descriptionFR} = 'Support sur le logiciel imapsync.' ;
$F->{descriptionEN} = '(Imapsync support.)' ;
}
if ( 'service' eq $F->{object_type} ) {
$F->{usageFR} = 'Usage à titre professionnel.' ;
$F->{usageEN} = '(professional usage.)' ;
$F->{descriptionFR} = 'Service en ligne avec le logiciel imapsync.' ;
$F->{descriptionEN} = '(Imapsync software online service.)' ;
}
if ( 'professional' eq $F->{clientTypeEN}
if ( 'professional' eq $F->{client_type}
and 'software + support' eq $F->{object_type} ) {
$F->{usageFR} = 'Usage à titre professionnel.' ;
$F->{usageEN} = '(professional usage.)' ;
@ -887,6 +951,21 @@ sub object_type {
}elsif ( ( 'imapsync any' eq $F->{Titre_de_l_objet} )
and ( 'Support only. For professional use.' eq $F->{Valeur_Option_1} ) ) {
$F->{object_type} = 'support' ;
}elsif ( (
'imapsync any' eq $F->{Titre_de_l_objet}
or 'imapsync online' eq $F->{Titre_de_l_objet}
)
and (
( 'Tiny' eq $F->{Valeur_Option_1} )
or ( 'Small' eq $F->{Valeur_Option_1} )
or ( 'Normal' eq $F->{Valeur_Option_1} )
or ( 'High' eq $F->{Valeur_Option_1} )
) ) {
$F->{object_type} = 'service' ;
}elsif ( ( 'imapsync any' eq $F->{Titre_de_l_objet} )
and ( '' eq $F->{Valeur_Option_1} ) ) {
# one is like this: 2 oct 2016 00:04:12 CEST 50 EUR
$F->{object_type} = 'software' ;
}
}
@ -911,19 +990,36 @@ Hello $F->{Nom},
First of all, I'm sorry for the delay in getting back to you.
Last imapsync release is available from the page
http://imapsync.lamiral.info/paypal_return.shtml
https://imapsync.lamiral.info/paypal_return.shtml
Help me improving imapsync and its services by voting at
http://imapsync.lamiral.info/#poll
You're also free to use the online imapsync GUI as you wish:
https://imapsync.lamiral.info/X/
You'll find in the attachment the invoice of imapsync
$F->{object_type} you bought and paid (dd/mm/yyyy $F->{Date}).
$F->{object_type} that you bought and you paid (dd/mm/yyyy $F->{Date}).
The invoice file is named facture_imapsync-${invoice}.pdf
This invoice is in PDF format, ready to be print.
Should you need a hardcopy of this invoice,
Should you need a hard-copy of this invoice,
I'll send it to you upon request by regular mail.
Once more, thank you for buying and using imapsync $F->{object_type}.
Any feedback is welcome!
Best Regards.
--
Gilles Lamiral.
add: 22 La Billais 35580 Baulon, France
mob: +33 6 19 22 03 54
fix: +33 9 51 84 42 42
} ;
my $message_body_blabla = qq{
Help me improving imapsync and its services via the pole
http://imapsync.lamiral.info/S/poll.shtml
As the law requires, this numeric invoice PDF file
is signed with my private gpg key.
@ -938,20 +1034,6 @@ this invoice with the following command line:
or any other gpg graphical tool.
Once more, thank you for buying and using imapsync $F->{object_type}.
Any feedback is welcome!
Best Regards.
--
Gilles Lamiral.
add: La Billais 35580 Baulon, France
mob: +33 6 19 22 03 54
fix: +33 9 51 84 42 42
} ;
my $message_body_blabla = qq{
Here is the fingerprint of my public key
pub 1024D/FDA2B3DC 2002-05-08
Key fingerprint = 7906 F53D 0D62 0C67 304A 4CF0 6928 869B FDA2 B3DC
@ -1001,7 +1083,7 @@ sub invoice_sent {
sub write_email_message {
my ( $dir_invoices, $invoice, $message_header, $message_body, $email_address ) = @_ ;
my $message_body_utf8 = to_utf8({ -string => $message_body, -charset => 'ISO-8859-1' });
my $message_body_utf8 = Unicode::MapUTF8::to_utf8({ -string => $message_body, -charset => 'ISO-8859-1' });
my $invoice_00000 = invoice_00000( $invoice ) ;
@ -1027,7 +1109,7 @@ sub write_email_message {
sub write_tex_variables_file {
my ( $dir_invoices, $invoice, $Date, $tex_variables_utf8 ) = @_ ;
my ( $dir_invoices, $invoice, $Date, $tex_variables_utf8, $tex_variables ) = @_ ;
my $invoice_00000 = invoice_00000( $invoice ) ;
@ -1039,16 +1121,20 @@ sub write_tex_variables_file {
$debug and print "Writing imapsync_var.tex $dir_invoices/$invoice_00000/imapsync_var.tex\n" ;
$dry and return( ) ;
open( FILE, "> $dir_invoices/$invoice_00000/imapsync_var.tex") or die ;
# original input
open( FILE, "> $dir_invoices/$invoice_00000/imapsync_var_latin1.tex") or die ;
print FILE $tex_variables ;
close( FILE ) ;
# utf8 conversion
open( FILE, "> $dir_invoices/$invoice_00000/imapsync_var_utf8.tex") or die ;
print FILE $tex_variables_utf8 ;
close( FILE ) ;
system( "cat $dir_invoices/$invoice_00000/imapsync_var_latin1.tex | 8859_utf8 > $dir_invoices/$invoice_00000/imapsync_var.tex" ) ;
if ( ! -f "$dir_invoices/$invoice_00000/imapsync_var_manual.tex" ) {
open( FILE, "> $dir_invoices/$invoice_00000/imapsync_var_manual.tex") or die ;
print FILE "%% $0 created this file
%% Can be used to override imapsync_var.tex definitions\n" ;
print FILE $tex_variables_utf8 ;
close( FILE ) ;
system( "cp $dir_invoices/$invoice_00000/imapsync_var.tex $dir_invoices/$invoice_00000/imapsync_var_manual.tex" ) ;
}
}
@ -1064,6 +1150,8 @@ sub download_urls {
( 'software + support' eq $F->{object_type} )
or
( 'support' eq $F->{object_type} )
or
( 'service' eq $F->{object_type} )
)
) {
$F->{urlSrc} = 'http://imapsync.lamiral.info/paypal_return.shtml' ;
@ -1202,36 +1290,34 @@ sub tva_line_one_button_for_the_software {
or 'imapsync source code' eq $A->{Titre_de_l_objet}
) {
if (
( 'individual' eq $A->{client_type} )
or
( 'France' eq $A->{Pays} )
) {
$debug and print "tva_line_one_button_for_the_software $A->{Titre_de_l_objet}\n" ;
if ( 'TAXED' eq $A->{vat_type} ) {
$A->{montant_HT_EUR_logi_ass} = $A->{Montant2} / ( 1 + tva_rate( $A->{date_aaaa_mm_jj} ) ) ;
$A->{montant_TVA_EUR_logi} = $A->{Montant2} / ( 1 + tva_rate( $A->{date_aaaa_mm_jj} ) ) * tva_rate( $A->{date_aaaa_mm_jj} ) ;
}else{
$A->{montant_HT_EUR_logi_exo} = $A->{Montant2} ;
}
}
}
sub tva_line_one_button_for_the_support {
my $A = shift ;
if ( 'single' ne $A->{button_type} ) { return ; }
if ( 'support' eq $A->{object_type} ) {
if (
( 'individual' eq $A->{client_type} )
or
( 'France' eq $A->{Pays} )
( 'TAXED' eq $A->{vat_type} )
or
( '2013_02_19' gt $A->{date_aaaa_mm_jj} )
)
)
{
$debug and print "tva_line_one_button_for_the_support $A->{Montant2} $A->{date_aaaa_mm_jj} $A->{Titre_de_l_objet}\n" ;
$A->{montant_HT_EUR_sup} = $A->{Montant2} / ( 1 + tva_rate( $A->{date_aaaa_mm_jj} ) ) ;
$A->{montant_TVA_EUR_sup} = $A->{Montant2} / ( 1 + tva_rate( $A->{date_aaaa_mm_jj} ) ) * tva_rate( $A->{date_aaaa_mm_jj} ) ;
}else{
$debug and print "tva_line_one_button_for_the_support $A->{Montant2} $A->{date_aaaa_mm_jj} $A->{Titre_de_l_objet}\n" ;
$A->{montant_HT_EUR_sup_exo} = $A->{Montant2} ;
}
}
@ -1251,20 +1337,53 @@ sub button_type {
}
}
sub tva_line_one_button_for_support_and_software {
sub tva_line_one_button_for_support_and_software_and_service {
my $A = shift ;
$A->{Montant2_logi} = software_price( $A->{date_aaaa_mm_jj} ) ;
$A->{Montant2_supp} = $A->{Montant2} - $A->{Montant2_logi} ;
if ( 'mixed' ne $A->{button_type} ) { return ; }
$debug and print "tva_line_one_button_for_support_and_software_and_service $A->{object_type} $A->{Titre_de_l_objet}\n" ;
if ( 'service' eq $A->{object_type} ) {
$A->{Montant2_serv} = $A->{Montant2} ;
if ( 'TAXED' eq $A->{vat_type} ) {
$A->{montant_HT_EUR_serv_ass} = $A->{Montant2_serv} / ( 1 + tva_rate( $A->{date_aaaa_mm_jj} ) ) ;
$A->{montant_TVA_EUR_serv} = $A->{Montant2_serv} / ( 1 + tva_rate( $A->{date_aaaa_mm_jj} ) ) * tva_rate( $A->{date_aaaa_mm_jj} ) ;
}else{
$A->{montant_HT_EUR_serv_exo} = $A->{Montant2_serv} ;
}
return ;
}
if ( 'support' eq $A->{object_type} ) {
$A->{Montant2_supp} = $A->{Montant2} ;
if ( 'TAXED' eq $A->{vat_type} ) {
$A->{montant_HT_EUR_sup} = $A->{Montant2_supp} / ( 1 + tva_rate( $A->{date_aaaa_mm_jj} ) ) ;
$A->{montant_TVA_EUR_sup} = $A->{Montant2_supp} / ( 1 + tva_rate( $A->{date_aaaa_mm_jj} ) ) * tva_rate( $A->{date_aaaa_mm_jj} ) ;
}else{
$A->{montant_HT_EUR_sup_exo} = $A->{Montant2_supp} ;
}
return ;
}
if ( 'software' eq $A->{object_type} ) {
$A->{Montant2_logi} = $A->{Montant2} ;
if ( 'TAXED' eq $A->{vat_type} ) {
$A->{montant_HT_EUR_logi_ass} = $A->{Montant2_logi} / ( 1 + tva_rate( $A->{date_aaaa_mm_jj} ) ) ;
$A->{montant_TVA_EUR_logi} = $A->{Montant2_logi} / ( 1 + tva_rate( $A->{date_aaaa_mm_jj} ) ) * tva_rate( $A->{date_aaaa_mm_jj} ) ;
}else{
$A->{montant_HT_EUR_logi_exo} = $A->{Montant2_logi} ;
}
return ;
}
if ( 'software + support' eq $A->{object_type} ) {
$A->{Montant2_logi} = software_price( $A->{date_aaaa_mm_jj} ) ;
$A->{Montant2_supp} = $A->{Montant2} - $A->{Montant2_logi} ;
if ( 'mixed' eq $A->{button_type} ) {
if ( 'individual' eq $A->{client_type}
or
'France' eq $A->{Pays}
)
{
$A->{montant_HT_EUR_sup} = $A->{Montant2_supp} / ( 1 + tva_rate( $A->{date_aaaa_mm_jj} ) ) ;
if ( 'TAXED' eq $A->{vat_type} ) {
$A->{montant_HT_EUR_sup} = $A->{Montant2_supp} / ( 1 + tva_rate( $A->{date_aaaa_mm_jj} ) ) ;
$A->{montant_TVA_EUR_sup} = $A->{Montant2_supp} / ( 1 + tva_rate( $A->{date_aaaa_mm_jj} ) ) * tva_rate( $A->{date_aaaa_mm_jj} ) ;
$A->{montant_HT_EUR_logi_ass} = $A->{Montant2_logi} / ( 1 + tva_rate( $A->{date_aaaa_mm_jj} ) ) ;
$A->{montant_TVA_EUR_logi} = $A->{Montant2_logi} / ( 1 + tva_rate( $A->{date_aaaa_mm_jj} ) ) * tva_rate( $A->{date_aaaa_mm_jj} ) ;
@ -1272,7 +1391,11 @@ sub tva_line_one_button_for_support_and_software {
$A->{montant_HT_EUR_logi_exo} = $A->{Montant2_logi} ;
$A->{montant_HT_EUR_sup_exo} = $A->{Montant2_supp} ;
}
return ;
}
print "tva_line_one_button_for_support_and_software_and_service type $A->{object_type} title $A->{Titre_de_l_objet} mont $A->{Montant2} Option_1 $A->{Valeur_Option_1} Option_2 $A->{Option_2_Valeur}\n" ;
print Data::Dumper->Dump( [$A] ) ;
}
@ -1282,19 +1405,53 @@ sub tva_line {
$A->{montant_HT_EUR_logi_exo} = $A->{montant_HT_EUR_logi_ass} = $A->{montant_TVA_EUR_logi} = 0 ;
$A->{montant_HT_EUR_sup} = $A->{montant_TVA_EUR_sup} = $A->{montant_HT_EUR_sup_exo} = 0 ;
$A->{montant_HT_EUR_serv_exo} = $A->{montant_HT_EUR_serv_ass} = $A->{montant_TVA_EUR_serv} = 0 ;
$A->{date_aaaa_mm_jj} = date_aaaa_mm_jj( $A->{Date} ) ;
clientVAT( $A ) ;
client_type( $A ) ;
object_type( $A ) ;
button_type( $A ) ;
$A->{date_aaaa_mm_jj} = date_aaaa_mm_jj( $A->{Date} ) ;
vat_type( $A ) ;
$A->{Montant2} = $A->{Montant2}/$usdeur if 'USD' eq $A->{Devise} ;
tva_line_one_button_for_the_software( $A ) ;
tva_line_one_button_for_the_support( $A ) ;
tva_line_one_button_for_support_and_software( $A ) ;
return( ) ;
tva_line_one_button_for_support_and_software_and_service( $A ) ;
return ;
}
sub vat_type {
my $F = shift ;
if (
( 'individual' eq $F->{client_type} )
or ( 'France' eq $F->{Pays} )
) {
$F->{vat_type} = 'TAXED' ;
}else{
$F->{vat_type} = 'EXEMPT' ;
}
return ;
}
sub clientVAT {
my $F = shift ;
$F->{clientVAT} = '' ;
if (
( 'VAT if professional in Europe' eq $F->{Nom_Option_2} )
and ( $F->{Option_2_Valeur} )
and ( $F->{Option_2_Valeur} !~ /^\s+$/ )
and ( 'N/A' ne $F->{Option_2_Valeur} )
) {
$F->{clientVAT} = $F->{Option_2_Valeur} ;
}
return ;
}
sub tva_stuff_one_button_for_support_xor_software {
@ -1302,14 +1459,13 @@ sub tva_stuff_one_button_for_support_xor_software {
if ( not ( 'software' eq $F->{object_type}
or 'support' eq $F->{object_type}
or 'service' eq $F->{object_type}
) ) {
return( ) ;
return ;
}
if ( ( 'individual' eq $F->{clientTypeEN})
or
( 'France' eq $F->{Pays} )
) {
if ( 'TAXED' eq $F->{vat_type} ) {
$F->{priceHT} = sprintf('%2.2f', $F->{Hors_taxe} / ( 1 + tva_rate( $F->{date_aaaa_mm_jj} ) ) ) ;
$F->{priceBHT} = '' ;
$F->{priceZHT} = $F->{priceHT} ;
@ -1336,25 +1492,34 @@ sub tva_stuff_one_button_for_support_xor_software {
$price =~ s{\.}{, } ;
}
return( ) ;
return ;
}
sub tva_stuff_one_button_for_support_and_software {
my $F = shift ;
if ( not ( 'software + support' eq $F->{object_type} ) ) {
return( ) ;
if ( ! ( 'software + support' eq $F->{object_type} ) ) {
return ;
}
# Default values
$F->{priceHT} = '' ;
$F->{priceBHT} = '' ;
$F->{priceZHT} = '' ;
$F->{tvaFR} = '' ;
$F->{priceZTVA} = '' ;
$F->{priceZTTC} = '' ;
$F->{HTorTTC} = '' ;
$F->{messageTVAFR} = '' ;
$F->{messageTVAEN} = '' ;
# Now the stuff
my $amountZ = $F->{Hors_taxe} ;
my $amountA = software_price( $F->{date_aaaa_mm_jj} ) ;
my $amountB = $amountZ - $amountA ;
if ( ( 'individual' eq $F->{clientTypeEN})
or
( 'France' eq $F->{Pays} )
) {
if ( 'TAXED' eq $F->{vat_type} ) {
$F->{priceHT} = sprintf('%2.2f', $amountA / ( 1 + tva_rate( $F->{date_aaaa_mm_jj} ) ) ) ;
$F->{priceBHT} = sprintf('%2.2f', $amountB / ( 1 + tva_rate( $F->{date_aaaa_mm_jj} ) ) ) ;
$F->{priceZHT} = $F->{Hors_taxe} ;
@ -1392,8 +1557,6 @@ sub tva_stuff {
$F->{priceTTCusd} = '' ;
$F->{Hors_taxe} =~ s{,}{.} ;
$F->{date_aaaa_mm_jj} = date_aaaa_mm_jj( $F->{Date} ) ;
tva_stuff_one_button_for_support_xor_software( $F ) ;
tva_stuff_one_button_for_support_and_software( $F ) ;
return( ) ;
@ -1401,11 +1564,15 @@ sub tva_stuff {
sub client_type {
my $F = shift ;
#print "$F->{date_aaaa_mm_jj} $F->{Date}\n" ;
# Default to professional
$F->{client_type} = 'professional' ;
$F->{clientTypeEN} = 'professional' ;
$F->{clientTypeFR} = 'professionnel' ;
# Otherwise
if ('imapsync usage' eq $F->{Nom_Option_1} and 'individual' eq $F->{Valeur_Option_1} ) {
$F->{client_type} = 'individual' ;
$F->{clientTypeEN} = 'individual' ;
@ -1418,6 +1585,16 @@ sub client_type {
$F->{client_type} = 'individual' ;
$F->{clientTypeEN} = 'individual' ;
$F->{clientTypeFR} = 'individuel' ;
}elsif (
'imapsync choice' eq $F->{Nom_Option_1}
and ( $F->{Valeur_Option_1} =~ /individual/ )
and ( '2016_10_01' le $F->{date_aaaa_mm_jj} )
and ( not $F->{clientVAT} )
) {
$F->{client_type} = 'individual' ;
$F->{clientTypeEN} = 'individual' ;
$F->{clientTypeFR} = 'individuel' ;
}
return( ) ;

1581
W/paypal_reply/paypal_bilan_1.100 Executable file

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
#!/bin/sh
# $Id: paypal_build_invoices,v 1.111 2016/08/09 02:10:07 gilles Exp gilles $
# $Id: paypal_build_invoices,v 1.139 2017/09/09 19:31:54 gilles Exp gilles $
# usage: sh paypal_build_invoices /g/var/paypal_invoices/????
@ -79,9 +79,29 @@ cp /home/gilles/public_html/AGIL/factures/000/facture_imapsync-000.tex /g/var/pa
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 4860 /g/paypal/paypal_2016_05_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 4931 /g/paypal/paypal_2016_06_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5009 /g/paypal/paypal_2016_07_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5081 /g/paypal/paypal_2016_08_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5147 /g/paypal/paypal_2016_09_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5216 /g/paypal/paypal_2016_10_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5216 /g/paypal/paypal_2016_10_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5276 /g/paypal/paypal_2016_11_complet.csv
# Two bank transfer in 2016_12
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5355 /g/paypal/virements_2016_12_06.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5338 --avoid_numbers '5355' /g/paypal/paypal_2016_12_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5406 /g/paypal/virements_2016_12_31.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5407 /g/paypal/paypal_2017_01_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5490 /g/paypal/paypal_2017_02_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5558 /g/paypal/paypal_2017_03_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5651 /g/paypal/paypal_2017_04_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5714 /g/paypal/paypal_2017_05_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5780 /g/paypal/paypal_2017_06_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5833 /g/paypal/paypal_2017_07_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5903 /g/paypal/paypal_2017_08_complet.csv
set -x
/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5081 /g/paypal/paypal_2016_08_complet.csv
/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 5978 /g/paypal/paypal_2017_09_complet.csv
set +x
@ -155,10 +175,26 @@ set +x
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 4776 /g/paypal/paypal_2016_04_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 4860 /g/paypal/paypal_2016_05_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 4931 /g/paypal/paypal_2016_06_complet.csv
set -x
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 5009 /g/paypal/paypal_2016_07_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 5081 /g/paypal/paypal_2016_08_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 5147 /g/paypal/paypal_2016_09_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 5216 /g/paypal/paypal_2016_10_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 5276 /g/paypal/paypal_2016_11_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 5355 /g/paypal/virements_2016_12_06.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 5338 --avoid_numbers '5355' /g/paypal/paypal_2016_12_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 5406 /g/paypal/virements_2016_12_31.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 5407 /g/paypal/paypal_2017_01_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 5490 /g/paypal/paypal_2017_02_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 5558 /g/paypal/paypal_2017_03_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 5651 /g/paypal/paypal_2017_04_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 5714 /g/paypal/paypal_2017_05_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 5780 /g/paypal/paypal_2017_06_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 5833 /g/paypal/paypal_2017_07_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 5903 /g/paypal/paypal_2017_08_complet.csv
set -x
# TVA a faire
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 5978 /g/paypal/paypal_2017_09_complet.csv
set +x
# La totale
@ -169,7 +205,8 @@ set +x
2295 2296 2297 2298 2625 2626 2970 2971 2972
3093 3296 3411 3412 3450 3451 3614 3615 3616 3617
3807 3808 3957 3958 4030 4194 4195 4381 4382 4449 4450
4574 4641' \
4574 4641 5213 5214 5215 5355 5406
5489 5650' \
/g/paypal/paypal_201?_??_complet.csv
#set -v
@ -179,14 +216,23 @@ set +x
2295 2296 2297 2298 2625 2626 2970 2971 2972
3093 3296 3411 3412 3450 3451 3614 3615 3616 3617
3807 3808 3957 3958 4030 4194 4195 4381 4382 4449 4450
4574 4641' \
4574 4641 5213 5214 5215 5355 5406
5489 5650' \
/g/paypal/paypal_201?_??_complet.csv
#set +v
#echo 2016 : ( from 4574 to ???? ) EUR
#echo 2017 : ( from 5407 to ???? ) EUR
#set -v
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan \
--first_in 4575 --avoid_numbers '4574 4641' \
--first_in 5407 --avoid_numbers '5489 5650' \
/g/paypal/paypal_2017_??_complet.csv
#set +v
#echo 2016 : ( from 4574 to 5406 ) EUR
#set -v
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan \
--first_in 4575 --avoid_numbers '4574 4641 5213 5214 5215 5355 5406' \
/g/paypal/paypal_2016_??_complet.csv
#set +v
@ -230,14 +276,15 @@ set +x
echo 'sh paypal_build_invoices /g/var/paypal_invoices/5???'
# USD de 147 \E0 340
# EUR de 341 \E0 ...
# USD de 147 a 340
# EUR de 341 a ...
# 20110413 Found problems with 189 199 249 258 263 359 537
# 20110412 Found problems with 189 199 242 249 258 263 359 382 537
# cen cen JAP cen cen cen cen TCH JAP
# cen
for d in "$@"; do
echo "==== $d ===="
cd $d
@ -265,7 +312,7 @@ for d in "$@"; do
continue
fi
fi
gpg --use-agent --armor --detach-sign --yes facture_imapsync-$bd.pdf
#gpg --use-agent --armor --detach-sign --yes facture_imapsync-$bd.pdf
done
echo "Found problems with $PB_LIST"

View file

@ -1,6 +1,6 @@
#!/usr/bin/perl
# $Id: paypal_build_reply,v 1.29 2016/08/18 09:48:27 gilles Exp gilles $
# $Id: paypal_build_reply,v 1.33 2017/07/03 22:49:06 gilles Exp gilles $
use warnings;
use strict;
@ -11,7 +11,7 @@ my ($amount, $name, $email);
my (
$paypal_line, $paypal_info,
$buyer, $description, $object,
$url, $release, $release_exe,
$release, $release_exe,
);
my $help ;
@ -32,22 +32,20 @@ $release = firstline( '/g/public_html/imapsync/VERSION' ) ;
$release_exe = firstline( '/g/public_html/imapsync/VERSION_EXE' ) ;
#my $path_last = firstline( '/g/public_html/imapsync/dist/path_last.txt' ) ;
$url = "http://ks.lamiral.info/imapsync/dist/" ;
$debug and print "Hi!\n" ;
my @input = <> ;
while( my $line = shift @input ) {
next if ( $line !~ /^(.*Num.+ro de transaction.*)$/ );
next if ( $line !~ /^(.*de transaction.*)$/ );
$paypal_line = $1;
$paypal_info = "===== Paypal id =====\n$paypal_line\n";
$debug and print "$paypal_info" ;
last;
}
while( my $line = shift @input ) {
if ( $line =~ /^Vous avez re.*paiement d'un montant de (.*) de la part de (.*) \((.*)\)/) {
if ( $line =~ /^Vous avez re.*paiement d'un montant de (.*) de la part de (.*) ?\((.*)\)/) {
($amount, $name, $email) = ($1, $2, $3);
$debug and print "1 ($amount, $name, $email)\n" ;
last;
@ -78,11 +76,20 @@ while( my $line = shift @input ) {
$debug and print "2 $buyer\n" ;
last;
}
if ( $line =~ /^"Informations sur l'acheteur :"/ ) {
$buyer .= "===== Acheteur =====\n";
shift @input ;
chomp( $name = shift @input );
$buyer .= "$name\n" ;
$debug and print "2 $buyer\n" ;
last;
}
}
while( my $line = shift @input ) {
$buyer .= $line if ( $line !~ /^-----------------------------------/ );
last if ( $line =~ /^-----------------------------------/ );
$buyer .= $line if ( ( $line !~ /^-----------------------------------/ ) and ( $line !~ /^Veuillez conserver ce num/ ) );
last if ( ( $line =~ /^-----------------------------------/ ) or ( $line =~ /^Veuillez conserver ce num/ ) or ( $line =~ /tails de l'achat/) ) ;
}
$debug and print "3 $buyer\n" ;
@ -107,53 +114,65 @@ while( my $line = shift @input ) {
my $address = 'gilles.lamiral@laposte.net';
my $address2 = 'gilles@lamiral.info';
my $rcstag = '$Id: paypal_build_reply,v 1.29 2016/08/18 09:48:27 gilles Exp gilles $';
my $rcstag = '$Id: paypal_build_reply,v 1.33 2017/07/03 22:49:06 gilles Exp gilles $';
my $download_info = "You will find the latest imapsync.exe binary (release $release_exe)
and the latest imapsync source code (release $release) at the following link:
$url" ;
my $next_releases =
"Next imapsync releases will be available to you for lifetime without extra payment.
You are subscribed to a newsletter [imapsync_update] announcing new releases.
Just keep this message and ask for the new links in case you miss the newsletter.
Ask me to be unsubscribed, you can also do it yourself at
http://lists.lamiral.info/cgi-bin/mailman/listinfo/imapsync_update
Run imapsync without any argument to know if a new release is available.
A permanent link to last release is http://imapsync.lamiral.info/paypal_return.shtml
also written on the invoice you'll receive soon, I edit invoices once a week or on demand." ;
my $support_info = 'For imapsync professional support,
my $contact =
q{
For imapsync professional support or any other request,
contact me (Gilles LAMIRAL) by email or phone at:
Email address: gilles.lamiral@laposte.net.
Professionnal phone number: +33 9 51 84 42 42 (France)
Mobile phone number: +33 6 19 22 03 54 (France, SFR operator).
Email address: gilles.lamiral@laposte.net
Mobile phone number: +33 6 19 22 03 54 (France, SFR operator)
Professionnal phone number: +33 9 51 84 42 42 (France, Free operator)
} ;
I can call you back toll-free in many countries on landline telephone numbers
and to mobile numbers in the United States and France. So do not hesitate
to send me a note if you need vocal support.' ;
my $download_info =
qq{
Software users, you will find the latest stable imapsync software
(release $release) at the following link:
https://imapsync.lamiral.info/dist/
Next imapsync releases will be available to you for lifetime without
extra payment. To know if a new release is available, just
run imapsync with no arguments or look at the end of any logfile.
} ;
my $online_info =
q{
Online users, the imapsync service is at
https://imapsync.lamiral.info/X/
Don't hesitate to drop me a note in case of problems or
clarifications about this online visual interface.
} ;
my $newsletter =
q{
As a buyer, you are also subscribed to a very low traffic newsletter
called [imapsync_update], announcing new releases or new services.
You might have reveived a welcome email message from the list manager,
telling you how to unsubscribe by yourself at
http://lists.lamiral.info/cgi-bin/mailman/listinfo/imapsync_update
In any case, you can also ask me to unsubscribe you, as
it's often frustrating to deal with unsubscriptions.
} ;
my $thanks_software = "I thank you for buying and using imapsync,
I wish you successful transfers!" ;
my $thanks =
q{
I thank you for buying and using imapsync services or products,
I wish you very successful transfers!
You will receive an invoice soon.
} ;
my $text_software = "$download_info\n
$next_releases\n
$support_info\n
You will receive an invoice soon.\n
$thanks_software" ;
my $text = $thanks
. $contact
. $download_info
. $online_info
. $newsletter
;
my $subject_software = "[imapsync download] imapsync release $release [$amount_ascii from $email]" ;
my $subject ;
my $text ;
$text = $text_software ;
$subject = $subject_software ;
my $subject = "[imapsync download/support/online] imapsync payment done [$amount_ascii from $email]" ;
@ -162,7 +181,7 @@ X-Comment: $rcstag
In-Reply-To: $msg_id
From: Gilles LAMIRAL <$address>
To: <$email>
Bcc: Gilles LAMIRAL <$address>, <$address2>
Cc: Gilles LAMIRAL <$address>, <$address2>
Subject: $subject
Hello $name,

View file

@ -1,6 +1,6 @@
#!/bin/sh
# $Id: paypal_functions,v 1.21 2013/08/21 21:46:16 gilles Exp gilles $
# $Id: paypal_functions,v 1.23 2017/03/28 10:41:55 gilles Exp gilles $
paypal_prerequisites() {
perl -mMIME::Lite -e '' || echo 'sudo aptitude install libmime-lite-perl'
@ -38,7 +38,7 @@ paypal_init_petite_dev() {
passfile=/g/var/pass/secret.gilles_mbox
host=p
tmpdir=/g/var/paypal_reply_dev
folder='INBOX.03_imapsync_less.imapsync_paypal_dev'
folder='INBOX.03_imapsync_less.imapsync_paypal_dev_tmp'
}

View file

@ -1,6 +1,6 @@
#!/usr/bin/perl -w
# $Id: paypal_imapget,v 1.10 2013/08/21 22:19:35 gilles Exp gilles $
# $Id: paypal_imapget,v 1.13 2017/03/28 10:41:36 gilles Exp gilles $
use Getopt::Long;
use Mail::IMAPClient;
@ -59,7 +59,14 @@ print "@search\n" ;
my @uids_01 = $imap->search('HEADER', 'Return-Path','<payment@paypal.com>', @search );
my @uids_02 = $imap->search('HEADER', 'Return-Path','<member@paypal.fr>', @search );
my @uids_03 = $imap->search('HEADER', 'Return-Path','<member@paypal.com>', @search );
my @uids = ( @uids_01, @uids_02, @uids_03 ) ;
my @uids_04 = $imap->search('HEADER', 'X-Email-Type-Id','PPX001033' ) ;
my @uids_05 = $imap->search('HEADER', 'X-Email-Type-Id','PPX001069' ) ;
my @uids_06 = $imap->search('HEADER', 'X-Email-Type-Id','PP341' ) ;
# New on 18 oct 2016 03:24:42 CEST
# Return-Path: <service@paypal.fr>
# X-Email-Type-Id: PPX001033
my @uids = ( @uids_01, @uids_02, @uids_03, @uids_04, @uids_05, @uids_06 ) ;
print "Search: [@uids]\n";
foreach $msg (@uids) {

View file

@ -1,13 +1,13 @@
#!/bin/sh
# $Id: paypal_run_dev,v 1.10 2014/03/31 09:19:43 gilles Exp gilles $
# $Id: paypal_run_dev,v 1.12 2017/02/27 04:41:36 gilles Exp gilles $
set -e
#set -x
# Add path to commands at home
PATH=$PATH:/g/public_html/imapsync/W/paypal_reply
PERL5LIB=/g/public_html/imapsync/W/Mail-IMAPClient-3.35/lib
PERL5LIB=/g/public_html/imapsync/W/Mail-IMAPClient-3.39/lib
export PERL5LIB
test -f /g/public_html/imapsync/W/paypal_reply/paypal_functions \

View file

@ -1,13 +1,13 @@
#!/bin/sh
# $Id: paypal_run_laposte,v 1.8 2015/03/09 17:48:48 gilles Exp gilles $
# $Id: paypal_run_laposte,v 1.10 2017/02/27 04:41:36 gilles Exp gilles $
set -e
#set -x
# Add path to commands at home
PATH=$PATH:/g/public_html/imapsync/W/paypal_reply
PERL5LIB=/g/public_html/imapsync/W/Mail-IMAPClient-3.35/lib
PERL5LIB=/g/public_html/imapsync/W/Mail-IMAPClient-3.39/lib
export PERL5LIB
test -f /g/public_html/imapsync/W/paypal_reply/paypal_functions \

View file

@ -1,6 +1,6 @@
#!/bin/sh
# $Id: paypal_run_petite,v 1.6 2013/02/08 14:57:59 gilles Exp gilles $
# $Id: paypal_run_petite,v 1.8 2017/02/27 04:41:36 gilles Exp gilles $
set -e
#set -x
@ -8,7 +8,7 @@ set -e
# Add path to commands at home
PATH=$PATH:/g/public_html/imapsync/W/paypal_reply
PERL5LIB=/g/public_html/imapsync/W/Mail-IMAPClient-3.35/lib
PERL5LIB=/g/public_html/imapsync/W/Mail-IMAPClient-3.39/lib
export PERL5LIB
test -f /g/public_html/imapsync/W/paypal_reply/paypal_functions \

View file

@ -1,6 +1,6 @@
#!/bin/sh
# $Id: paypal_send_invoices,v 1.14 2015/02/04 11:36:26 gilles Exp gilles $
# $Id: paypal_send_invoices,v 1.15 2017/02/02 02:23:48 gilles Exp gilles $
# usages:
# sh paypal_send_invoices /g/var/paypal_invoices/147
@ -21,7 +21,7 @@ send_invoice() {
continue
fi
test -f facture_imapsync-${invoice}.pdf || { echo NO facture_imapsync-${invoice}.pdf ; return; }
test -f facture_imapsync-${invoice}.pdf.asc || { echo NO facture_imapsync-${invoice}.pdf.asc ; return; }
#test -f facture_imapsync-${invoice}.pdf.asc || { echo NO facture_imapsync-${invoice}.pdf.asc ; return; }
test -f facture_message_header.txt || { echo NO facture_message_header.txt ; return; }
test -f facture_message_body.txt || { echo NO facture_message_body.txt ; return; }
test -f email_address.txt || { echo NO email_address.txt ; return; }
@ -43,7 +43,8 @@ send_invoice() {
mailq
echo SAID "[$r]"
test X"$r" = Xy && {
echo | mutt -H facture_message.txt -a facture_imapsync-${invoice}.pdf facture_imapsync-${invoice}.pdf.asc --
#echo | mutt -H facture_message.txt -a facture_imapsync-${invoice}.pdf facture_imapsync-${invoice}.pdf.asc --
echo | mutt -H facture_message.txt -a facture_imapsync-${invoice}.pdf --
touch SENT_TO_$email
sleep 3
}

21
W/paypal_reply/texput.log Normal file
View file

@ -0,0 +1,21 @@
This is pdfTeX, Version 3.14159265-2.6-1.40.16 (TeX Live 2015/Debian) (preloaded format=pdflatex 2017.2.2) 22 JUL 2017 15:17
entering extended mode
restricted \write18 enabled.
%&-line parsing enabled.
**facture_imapsync-sh.tex
! Emergency stop.
<*> facture_imapsync-sh.tex
End of file on the terminal!
Here is how much of TeX's memory you used:
3 strings out of 494421
121 string characters out of 6172372
49430 words of memory out of 5000000
3408 multiletter control sequences out of 15000+600000
3640 words of font info for 14 fonts, out of 8000000 for 9000
430 hyphenation exceptions out of 8191
0i,0n,0p,1b,6s stack positions out of 5000i,500n,10000p,200000b,80000s
! ==> Fatal error occurred, no output PDF file produced!

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,174 +1,121 @@
Main code has high complexity score (401) at line 1, column 1. Consider refactoring. (Severity: 3)
"$ssl1_ssl_version" is declared but not used at line 814, column 1. Unused variables clutter code and make it harder to read. (Severity: 3)
"$ssl2_ssl_version" is declared but not used at line 814, column 1. Unused variables clutter code and make it harder to read. (Severity: 3)
Single-quote used as quote-like operator delimiter at line 1442, column 3. Using quotes as delimiters for quote-like operators obfuscates code. (Severity: 3)
Single-quote used as quote-like operator delimiter at line 1443, column 3. Using quotes as delimiters for quote-like operators obfuscates code. (Severity: 3)
Regular expression without "/x" flag at line 1481, column 33. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 1490, column 33. See page 236 of PBP. (Severity: 3)
Code structure is deeply nested at line 2013, column 41. Consider refactoring. (Severity: 3)
Reused variable name in lexical scope: $sync at line 2255, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $sync at line 2365, column 2. Invent unique variable names. (Severity: 3)
Regular expression without "/x" flag at line 2414, column 29. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 2436, column 31. See page 236 of PBP. (Severity: 3)
Reused variable name in lexical scope: $sync at line 2445, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $sync at line 2468, column 2. Invent unique variable names. (Severity: 3)
Regular expression without "/x" flag at line 2501, column 30. See page 236 of PBP. (Severity: 3)
Reused variable name in lexical scope: $sync at line 2512, column 53. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $sync at line 2520, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $sync at line 2570, column 2. Invent unique variable names. (Severity: 3)
Regular expression without "/x" flag at line 2607, column 26. See page 236 of PBP. (Severity: 3)
Too many arguments at line 2727, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2745, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2755, column 1. See page 182 of PBP. (Severity: 3)
Subroutine "modulesversion" with high complexity score (27) at line 2868, column 1. Consider refactoring. (Severity: 3)
Too many arguments at line 3075, column 1. See page 182 of PBP. (Severity: 3)
Subroutine "authenticate_imap" with high complexity score (21) at line 3144, column 1. Consider refactoring. (Severity: 3)
Too many arguments at line 3144, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 3274, column 1. See page 182 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3358, column 32. See page 236 of PBP. (Severity: 3)
Use "local $/ = undef" or File::Slurp instead of joined readline at line 3363, column 43. See page 213 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3373, column 69. See page 236 of PBP. (Severity: 3)
Backtick operator used at line 3381, column 20. Use IPC::Open3 instead. (Severity: 3)
Return value of eval not tested at line 3538, column 2. You can't depend upon the value of $@/$EVAL_ERROR to tell whether an eval failed. (Severity: 3)
"die" used instead of "croak" at line 3606, column 2. See page 283 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3714, column 15. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3715, column 15. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3716, column 15. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3725, column 8. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3726, column 8. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3727, column 8. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3770, column 31. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3857, column 24. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3860, column 20. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 4061, column 24. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 4062, column 19. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 4066, column 19. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 4136, column 39. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 4137, column 39. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 4138, column 41. See page 236 of PBP. (Severity: 3)
Expression form of "eval" at line 4391, column 13. See page 161 of PBP. (Severity: 5)
Single-quote used as quote-like operator delimiter at line 4522, column 6. Using quotes as delimiters for quote-like operators obfuscates code. (Severity: 3)
Single-quote used as quote-like operator delimiter at line 4522, column 45. Using quotes as delimiters for quote-like operators obfuscates code. (Severity: 3)
Single-quote used as quote-like operator delimiter at line 4528, column 6. Using quotes as delimiters for quote-like operators obfuscates code. (Severity: 3)
Single-quote used as quote-like operator delimiter at line 4528, column 38. Using quotes as delimiters for quote-like operators obfuscates code. (Severity: 3)
Single-quote used as quote-like operator delimiter at line 4529, column 17. Using quotes as delimiters for quote-like operators obfuscates code. (Severity: 3)
Single-quote used as quote-like operator delimiter at line 4530, column 39. Using quotes as delimiters for quote-like operators obfuscates code. (Severity: 3)
Single-quote used as quote-like operator delimiter at line 4534, column 6. Using quotes as delimiters for quote-like operators obfuscates code. (Severity: 3)
Single-quote used as quote-like operator delimiter at line 4534, column 40. Using quotes as delimiters for quote-like operators obfuscates code. (Severity: 3)
Single-quote used as quote-like operator delimiter at line 4537, column 45. Using quotes as delimiters for quote-like operators obfuscates code. (Severity: 3)
Single-quote used as quote-like operator delimiter at line 4538, column 45. Using quotes as delimiters for quote-like operators obfuscates code. (Severity: 3)
Single-quote used as quote-like operator delimiter at line 4539, column 22. Using quotes as delimiters for quote-like operators obfuscates code. (Severity: 3)
Single-quote used as quote-like operator delimiter at line 4541, column 17. Using quotes as delimiters for quote-like operators obfuscates code. (Severity: 3)
Single-quote used as quote-like operator delimiter at line 4550, column 17. Using quotes as delimiters for quote-like operators obfuscates code. (Severity: 3)
Single-quote used as quote-like operator delimiter at line 4556, column 17. Using quotes as delimiters for quote-like operators obfuscates code. (Severity: 3)
Expression form of "eval" at line 4629, column 13. See page 161 of PBP. (Severity: 5)
Subroutine "copy_message" with high complexity score (25) at line 4990, column 1. Consider refactoring. (Severity: 3)
Too many arguments at line 4990, column 1. See page 182 of PBP. (Severity: 3)
Reused variable name in lexical scope: $sync at line 4993, column 2. Invent unique variable names. (Severity: 3)
Too many arguments at line 5074, column 1. See page 182 of PBP. (Severity: 3)
Subroutine "message_for_host2" with high complexity score (27) at line 5107, column 1. Consider refactoring. (Severity: 3)
Too many arguments at line 5107, column 1. See page 182 of PBP. (Severity: 3)
Reused variable name in lexical scope: $sync at line 5129, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $sync at line 5223, column 9. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $string_ref at line 5242, column 25. Invent unique variable names. (Severity: 3)
Too many arguments at line 5419, column 1. See page 182 of PBP. (Severity: 3)
Reused variable name in lexical scope: $total_bytes_transferred at line 5486, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $nb_msg_transferred at line 5486, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $nb_msg_transferred at line 5499, column 9. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $maxmessagespersecond at line 5499, column 9. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $total_bytes_transferred at line 5520, column 9. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $maxbytespersecond at line 5520, column 9. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $h1_nb_msg_start at line 5557, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $h1_nb_msg_start at line 5568, column 2. Invent unique variable names. (Severity: 3)
Expression form of "eval" at line 6706, column 13. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 6942, column 13. See page 161 of PBP. (Severity: 5)
Regular expression without "/x" flag at line 7132, column 21. See page 236 of PBP. (Severity: 3)
Too many arguments at line 7204, column 1. See page 182 of PBP. (Severity: 3)
Close filehandles as soon as possible after opening them at line 7338, column 9. See page 209 of PBP. (Severity: 4)
Literal line breaks in a string at line 7379, column 1. See pages 60,61 of PBP. (Severity: 3)
Backtick operator used at line 7403, column 17. Use IPC::Open3 instead. (Severity: 3)
Split long regexps into smaller qr// chunks at line 7489, column 32. See page 261 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 7489, column 32. See page 236 of PBP. (Severity: 3)
Split long regexps into smaller qr// chunks at line 7493, column 32. See page 261 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 7493, column 32. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 7502, column 33. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 7507, column 33. See page 236 of PBP. (Severity: 3)
Split long regexps into smaller qr// chunks at line 7511, column 33. See page 261 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 7511, column 33. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 7515, column 33. See page 236 of PBP. (Severity: 3)
Split long regexps into smaller qr// chunks at line 7521, column 24. See page 261 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 7521, column 24. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 7671, column 33. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 7672, column 33. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 7673, column 43. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 7675, column 36. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 7676, column 37. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 7677, column 38. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 7679, column 30. See page 236 of PBP. (Severity: 3)
Backtick operator used at line 7696, column 12. Use IPC::Open3 instead. (Severity: 3)
Backtick operator used at line 7718, column 11. Use IPC::Open3 instead. (Severity: 3)
Split long regexps into smaller qr// chunks at line 7866, column 12. See page 261 of PBP. (Severity: 3)
Split long regexps into smaller qr// chunks at line 7892, column 12. See page 261 of PBP. (Severity: 3)
Split long regexps into smaller qr// chunks at line 7933, column 12. See page 261 of PBP. (Severity: 3)
Split long regexps into smaller qr// chunks at line 7945, column 12. See page 261 of PBP. (Severity: 3)
Expression form of "eval" at line 8051, column 42. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 8055, column 44. See page 161 of PBP. (Severity: 5)
Reused variable name in lexical scope: $sync at line 8072, column 9. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $sync at line 8093, column 9. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $sync at line 8145, column 9. Invent unique variable names. (Severity: 3)
Split long regexps into smaller qr// chunks at line 8481, column 20. See page 261 of PBP. (Severity: 3)
Close filehandles as soon as possible after opening them at line 8693, column 2. See page 209 of PBP. (Severity: 4)
Magic variable "*STDERR" should be assigned as "local" at line 8696, column 10. See pages 81,82 of PBP. (Severity: 4)
One-argument "select" used at line 8697, column 2. See page 224 of PBP. (Severity: 4)
Multiple "package" declarations at line 9395, column 1. Limit to one per file. (Severity: 4)
Subroutine "GetOptions" with high complexity score (32) at line 9407, column 1. Consider refactoring. (Severity: 3)
Regular expression without "/x" flag at line 9425, column 22. See page 236 of PBP. (Severity: 3)
Capture variable used outside conditional at line 9430, column 32. See page 253 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 9438, column 42. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 9439, column 30. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 9443, column 35. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 9460, column 30. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 9462, column 35. See page 236 of PBP. (Severity: 3)
Main code has high complexity score (392) at line 1, column 1. Consider refactoring. (Severity: 3)
Regular expression without "/x" flag at line 1483, column 47. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 1492, column 47. See page 236 of PBP. (Severity: 3)
Code structure is deeply nested at line 2021, column 41. Consider refactoring. (Severity: 3)
Too many arguments at line 3338, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 3356, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 3366, column 1. See page 182 of PBP. (Severity: 3)
Warnings disabled at line 3441, column 9. See page 431 of PBP. (Severity: 4)
Warnings disabled at line 3442, column 9. See page 431 of PBP. (Severity: 4)
Warnings disabled at line 3474, column 9. See page 431 of PBP. (Severity: 4)
Warnings disabled at line 3475, column 9. See page 431 of PBP. (Severity: 4)
Use "<>" or "<ARGV>" or a prompting module instead of "<STDIN>" at line 3623, column 24. See pages 216,220,221 of PBP. (Severity: 4)
Regular expression without "/x" flag at line 3877, column 42. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3878, column 33. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3887, column 42. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3898, column 42. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3919, column 42. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 4009, column 64. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 4012, column 56. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 4013, column 56. See page 236 of PBP. (Severity: 3)
Too many arguments at line 4040, column 1. See page 182 of PBP. (Severity: 3)
Subroutine "authenticate_imap" with high complexity score (21) at line 4120, column 1. Consider refactoring. (Severity: 3)
Too many arguments at line 4120, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 4260, column 1. See page 182 of PBP. (Severity: 3)
Use "local $/ = undef" or Path::Tiny instead of joined readline at line 4354, column 43. See page 213 of PBP. (Severity: 3)
Backtick operator used at line 4372, column 20. Use IPC::Open3 instead. (Severity: 3)
Expression form of "eval" at line 5413, column 27. See page 161 of PBP. (Severity: 5)
Single-quote used as quote-like operator delimiter at line 5557, column 24. Using quotes as delimiters for quote-like operators obfuscates code. (Severity: 3)
Expression form of "eval" at line 5658, column 27. See page 161 of PBP. (Severity: 5)
Subroutine "copy_message" with high complexity score (25) at line 6036, column 1. Consider refactoring. (Severity: 3)
Too many arguments at line 6036, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 6120, column 1. See page 182 of PBP. (Severity: 3)
Subroutine "message_for_host2" with high complexity score (27) at line 6153, column 1. Consider refactoring. (Severity: 3)
Too many arguments at line 6153, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 6472, column 1. See page 182 of PBP. (Severity: 3)
Expression form of "eval" at line 7896, column 27. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 8135, column 27. See page 161 of PBP. (Severity: 5)
Too many arguments at line 8398, column 1. See page 182 of PBP. (Severity: 3)
Literal line breaks in a string at line 8660, column 1. See pages 60,61 of PBP. (Severity: 3)
Backtick operator used at line 8684, column 17. Use IPC::Open3 instead. (Severity: 3)
Split long regexps into smaller qr// chunks at line 8772, column 32. See page 261 of PBP. (Severity: 3)
Split long regexps into smaller qr// chunks at line 8776, column 32. See page 261 of PBP. (Severity: 3)
Split long regexps into smaller qr// chunks at line 8795, column 33. See page 261 of PBP. (Severity: 3)
Split long regexps into smaller qr// chunks at line 8806, column 24. See page 261 of PBP. (Severity: 3)
Reused variable name in lexical scope: $version at line 8982, column 9. Invent unique variable names. (Severity: 3)
Backtick operator used at line 9047, column 17. Use IPC::Open3 instead. (Severity: 3)
Return value of eval not tested at line 9139, column 3. You can't depend upon the value of $@/$EVAL_ERROR to tell whether an eval failed. (Severity: 3)
Backtick operator used at line 9140, column 15. Use IPC::Open3 instead. (Severity: 3)
Split long regexps into smaller qr// chunks at line 9149, column 16. See page 261 of PBP. (Severity: 3)
Return value of eval not tested at line 9162, column 3. You can't depend upon the value of $@/$EVAL_ERROR to tell whether an eval failed. (Severity: 3)
Capture variable used outside conditional at line 9173, column 12. See page 253 of PBP. (Severity: 3)
Backtick operator used at line 9274, column 26. Use IPC::Open3 instead. (Severity: 3)
Backtick operator used at line 9296, column 18. Use IPC::Open3 instead. (Severity: 3)
Return value of eval not tested at line 9325, column 2. You can't depend upon the value of $@/$EVAL_ERROR to tell whether an eval failed. (Severity: 3)
Split long regexps into smaller qr// chunks at line 9487, column 19. See page 261 of PBP. (Severity: 3)
Split long regexps into smaller qr// chunks at line 9513, column 19. See page 261 of PBP. (Severity: 3)
Split long regexps into smaller qr// chunks at line 9554, column 19. See page 261 of PBP. (Severity: 3)
Split long regexps into smaller qr// chunks at line 9566, column 19. See page 261 of PBP. (Severity: 3)
Hard tabs used at line 9748, column 84. See page 20 of PBP. (Severity: 3)
Expression form of "eval" at line 9789, column 56. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 9793, column 58. See page 161 of PBP. (Severity: 5)
Split long regexps into smaller qr// chunks at line 10248, column 20. See page 261 of PBP. (Severity: 3)
Magic variable "*STDERR" should be assigned as "local" at line 10509, column 17. See pages 81,82 of PBP. (Severity: 4)
One-argument "select" used at line 10510, column 9. See page 224 of PBP. (Severity: 4)
Ambiguously named variable "last" at line 10529, column 2. See page 48 of PBP. (Severity: 3)
Reused variable name in lexical scope: $err at line 10806, column 3. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $err at line 10873, column 3. Invent unique variable names. (Severity: 3)
Hard tabs used at line 10944, column 44. See page 20 of PBP. (Severity: 3)
Close filehandles as soon as possible after opening them at line 11091, column 9. See page 209 of PBP. (Severity: 4)
"warn" used instead of "carp" at line 11092, column 17. See page 283 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 11117, column 40. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 11119, column 23. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 11120, column 23. See page 236 of PBP. (Severity: 3)
Literal line breaks in a string at line 11137, column 9. See pages 60,61 of PBP. (Severity: 3)
Subroutine "myGetOptions" with high complexity score (27) at line 11174, column 1. Consider refactoring. (Severity: 3)
Capture variable used outside conditional at line 11201, column 32. See page 253 of PBP. (Severity: 3)
1 files.
263 subroutines/methods.
8,603 statements.
1 files.
367 subroutines/methods.
11,872 statements.
9,486 lines, consisting of:
1,684 blank lines.
551 comment lines.
11,937 lines, consisting of:
2,225 blank lines.
764 comment lines.
0 data lines.
6,579 lines of Perl code.
672 lines of POD.
8,314 lines of Perl code.
634 lines of POD.
Average McCabe score of subroutines was 4.35.
Average McCabe score of subroutines was 4.10.
131 violations.
Violations per file was 131.000.
Violations per statement was 0.015.
Violations per line of code was 0.014.
76 violations.
Violations per file was 76.000.
Violations per statement was 0.006.
Violations per line of code was 0.006.
6 severity 5 violations.
5 severity 4 violations.
120 severity 3 violations.
6 severity 5 violations.
8 severity 4 violations.
62 severity 3 violations.
6 violations of BuiltinFunctions::ProhibitStringyEval.
2 violations of CodeLayout::ProhibitHardTabs.
1 violations of ControlStructures::ProhibitDeepNests.
1 violations of ErrorHandling::RequireCarping.
1 violations of ErrorHandling::RequireCheckingReturnValueOfEval.
4 violations of InputOutput::ProhibitBacktickOperators.
3 violations of ErrorHandling::RequireCheckingReturnValueOfEval.
6 violations of InputOutput::ProhibitBacktickOperators.
1 violations of InputOutput::ProhibitExplicitStdin.
1 violations of InputOutput::ProhibitJoinedReadline.
1 violations of InputOutput::ProhibitOneArgSelect.
2 violations of InputOutput::RequireBriefOpen.
1 violations of InputOutput::RequireBriefOpen.
1 violations of Modules::ProhibitExcessMainComplexity.
1 violations of Modules::ProhibitMultiplePackages.
1 violations of RegularExpressions::ProhibitCaptureWithoutTest.
9 violations of RegularExpressions::ProhibitComplexRegexes.
44 violations of RegularExpressions::RequireExtendedFormatting.
5 violations of Subroutines::ProhibitExcessComplexity.
1 violations of NamingConventions::ProhibitAmbiguousNames.
2 violations of RegularExpressions::ProhibitCaptureWithoutTest.
10 violations of RegularExpressions::ProhibitComplexRegexes.
13 violations of RegularExpressions::RequireExtendedFormatting.
4 violations of Subroutines::ProhibitExcessComplexity.
11 violations of Subroutines::ProhibitManyArgs.
1 violations of ValuesAndExpressions::ProhibitImplicitNewlines.
16 violations of ValuesAndExpressions::ProhibitQuotesAsQuotelikeOperatorDelimiters.
22 violations of Variables::ProhibitReusedNames.
2 violations of Variables::ProhibitUnusedVariables.
4 violations of TestingAndDebugging::ProhibitNoWarnings.
2 violations of ValuesAndExpressions::ProhibitImplicitNewlines.
1 violations of ValuesAndExpressions::ProhibitQuotesAsQuotelikeOperatorDelimiters.
3 violations of Variables::ProhibitReusedNames.
1 violations of Variables::RequireLocalizedPunctuationVars.

View file

@ -1,38 +1,42 @@
Expression form of "eval" at line 4391, column 13. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 4629, column 13. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 6706, column 13. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 6942, column 13. See page 161 of PBP. (Severity: 5)
Close filehandles as soon as possible after opening them at line 7338, column 9. See page 209 of PBP. (Severity: 4)
Expression form of "eval" at line 8051, column 42. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 8055, column 44. See page 161 of PBP. (Severity: 5)
Close filehandles as soon as possible after opening them at line 8693, column 2. See page 209 of PBP. (Severity: 4)
Magic variable "*STDERR" should be assigned as "local" at line 8696, column 10. See pages 81,82 of PBP. (Severity: 4)
One-argument "select" used at line 8697, column 2. See page 224 of PBP. (Severity: 4)
Multiple "package" declarations at line 9395, column 1. Limit to one per file. (Severity: 4)
Warnings disabled at line 3441, column 9. See page 431 of PBP. (Severity: 4)
Warnings disabled at line 3442, column 9. See page 431 of PBP. (Severity: 4)
Warnings disabled at line 3474, column 9. See page 431 of PBP. (Severity: 4)
Warnings disabled at line 3475, column 9. See page 431 of PBP. (Severity: 4)
Use "<>" or "<ARGV>" or a prompting module instead of "<STDIN>" at line 3623, column 24. See pages 216,220,221 of PBP. (Severity: 4)
Expression form of "eval" at line 5413, column 27. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 5658, column 27. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 7896, column 27. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 8135, column 27. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 9789, column 56. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 9793, column 58. See page 161 of PBP. (Severity: 5)
Magic variable "*STDERR" should be assigned as "local" at line 10509, column 17. See pages 81,82 of PBP. (Severity: 4)
One-argument "select" used at line 10510, column 9. See page 224 of PBP. (Severity: 4)
Close filehandles as soon as possible after opening them at line 11091, column 9. See page 209 of PBP. (Severity: 4)
1 files.
263 subroutines/methods.
8,603 statements.
1 files.
367 subroutines/methods.
11,872 statements.
9,486 lines, consisting of:
1,684 blank lines.
551 comment lines.
11,937 lines, consisting of:
2,225 blank lines.
764 comment lines.
0 data lines.
6,579 lines of Perl code.
672 lines of POD.
8,314 lines of Perl code.
634 lines of POD.
Average McCabe score of subroutines was 4.35.
Average McCabe score of subroutines was 4.10.
11 violations.
Violations per file was 11.000.
14 violations.
Violations per file was 14.000.
Violations per statement was 0.001.
Violations per line of code was 0.001.
6 severity 5 violations.
5 severity 4 violations.
8 severity 4 violations.
6 violations of BuiltinFunctions::ProhibitStringyEval.
1 violations of InputOutput::ProhibitExplicitStdin.
1 violations of InputOutput::ProhibitOneArgSelect.
2 violations of InputOutput::RequireBriefOpen.
1 violations of Modules::ProhibitMultiplePackages.
1 violations of InputOutput::RequireBriefOpen.
4 violations of TestingAndDebugging::ProhibitNoWarnings.
1 violations of Variables::RequireLocalizedPunctuationVars.

View file

@ -1,12 +1,13 @@
$SHELL says /bin/bash
$0 gives ./INSTALL.d/prerequisites_imapsync
ps -ef gives gilles 11305 11304 0 12:55 pts/27 00:00:00 /bin/sh ./INSTALL.d/prerequisites_imapsync
ps -ef gives gilles 4068 4067 0 01:12 pts/14 00:00:00 /bin/sh ./INSTALL.d/prerequisites_imapsync
Distributor ID: Ubuntu
Description: Ubuntu 14.04.5 LTS
Release: 14.04
Codename: trusty
Linux petite 3.13.0-92-generic #139-Ubuntu SMP Tue Jun 28 20:42:32 UTC 2016 i686 i686 i686 GNU/Linux
Ok: Found Perl 5.18.2
Description: Ubuntu 16.04.2 LTS
Release: 16.04
Codename: xenial
Linux petite 4.4.0-62-generic #83-Ubuntu SMP Wed Jan 18 14:09:55 UTC 2017 i686 i686 i686 GNU/Linux
Ok: Found Perl 5.22.1
Ok: Found make GNU Make 4.1
Ok: Found Perl module Authen::NTLM
Ok: Found Perl module Compress::Zlib
Ok: Found Perl module Data::Dumper
@ -21,8 +22,10 @@ Ok: Found Perl module IO::Socket::SSL
Ok: Found Perl module IO::Tee
Ok: Found Perl module JSON::WebToken
Ok: Found Perl module Mail::IMAPClient
Ok: Found Perl module Net::Ping
Ok: Found Perl module Parse::RecDescent
Ok: Found Perl module Readonly
Ok: Found Perl module Sys::MemInfo
Ok: Found Perl module Term::ReadKey
Ok: Found Perl module Test::MockObject
Ok: Found Perl module Test::More

35
W/prereq.Ubuntu_16.04.txt Normal file
View file

@ -0,0 +1,35 @@
$SHELL says /bin/bash
$0 gives ./INSTALL.d/prerequisites_imapsync
ps -ef gives gilles 8190 8189 0 01:36 pts/33 00:00:00 /bin/sh ./INSTALL.d/prerequisites_imapsync
Distributor ID: Ubuntu
Description: Ubuntu 16.04.2 LTS
Release: 16.04
Codename: xenial
Linux petite 4.4.0-64-generic #85-Ubuntu SMP Mon Feb 20 11:49:39 UTC 2017 i686 i686 i686 GNU/Linux
Ok: Found Perl 5.22.1
Ok: Found make GNU Make 4.1
Ok: Found Perl module Authen::NTLM
Ok: Found Perl module Compress::Zlib
Ok: Found Perl module Data::Dumper
Ok: Found Perl module Data::Uniqid
Ok: Found Perl module Digest::HMAC_MD5
Ok: Found Perl module Digest::HMAC
Ok: Found Perl module Digest::MD5
Ok: Found Perl module File::Copy::Recursive
Ok: Found Perl module IO::Socket::INET
Ok: Found Perl module IO::Socket::INET6
Ok: Found Perl module IO::Socket::SSL
Ok: Found Perl module IO::Tee
Ok: Found Perl module JSON::WebToken
Ok: Found Perl module Mail::IMAPClient
Ok: Found Perl module Net::Ping
Ok: Found Perl module Parse::RecDescent
Ok: Found Perl module Readonly
Ok: Found Perl module Sys::MemInfo
Ok: Found Perl module Term::ReadKey
Ok: Found Perl module Test::MockObject
Ok: Found Perl module Test::More
Ok: Found Perl module Test::Pod
Ok: Found Perl module Unicode::String
Ok: Found Perl module URI::Escape
All needed modules are already installed

View file

@ -0,0 +1,55 @@
$SHELL says /bin/bash
$0 gives ./INSTALL.d/prerequisites_imapsync
ps -ef gives gilles 5273 5272 0 14:39 pts/8 00:00:00 /bin/sh ./INSTALL.d/prerequisites_imapsync
Distributor ID: Ubuntu
Description: Ubuntu 16.04.3 LTS
Release: 16.04
Codename: xenial
Linux petite 4.4.0-92-generic #115-Ubuntu SMP Thu Aug 10 16:02:55 UTC 2017 i686 i686 i686 GNU/Linux
Ok: Found Perl 5.22.1
Ok: Found make GNU Make 4.1
Ok: Found Perl module Authen::NTLM
Ok: Found Perl module Class::Load
Ok: Found Perl module Compress::Zlib
Ok: Found Perl module Crypt::OpenSSL::RSA
Ok: Found Perl module Data::Dumper
Ok: Found Perl module Data::Uniqid
Ok: Found Perl module Digest::HMAC
Ok: Found Perl module Digest::HMAC_MD5
Ok: Found Perl module Digest::MD5
Ok: Found Perl module Dist::CheckConflicts
Ok: Found Perl module Encode::Byte
Ok: Found Perl module File::Copy::Recursive
Ok: Found Perl module IO::Socket::INET
Ok: Found Perl module IO::Socket::INET6
Ok: Found Perl module IO::Socket::SSL
Ok: Found Perl module IO::Tee
Ok: Found Perl module JSON
Ok: Found Perl module JSON::WebToken
Ok: Found Perl module JSON::WebToken::Crypt::RSA
Ok: Found Perl module HTML::Entities
Ok: Found Perl module LWP::UserAgent
Ok: Found Perl module Mail::IMAPClient
Ok: Found Perl module Module::Implementation
Ok: Found Perl module Module::Runtime
Ok: Found Perl module Module::ScanDeps
Ok: Found Perl module Net::Ping
Ok: Found Perl module Net::SSLeay
Ok: Found Perl module Package::Stash
Ok: Found Perl module Package::Stash::XS
Ok: Found Perl module PAR::Packer
Ok: Found Perl module Parse::RecDescent
Ok: Found Perl module Pod::Usage
Ok: Found Perl module Readonly
Ok: Found Perl module Sys::MemInfo
Ok: Found Perl module Term::ReadKey
Ok: Found Perl module Test::Fatal
Ok: Found Perl module Test::Mock::Guard
Ok: Found Perl module Test::MockObject
Ok: Found Perl module Test::More
Ok: Found Perl module Test::Pod
Ok: Found Perl module Test::Requires
Ok: Found Perl module Try::Tiny
Ok: Found Perl module Unicode::String
Ok: Found Perl module URI::Escape
All needed modules are already installed

View file

@ -145,11 +145,22 @@
Example: 's/"Junk"//g' # to remove "Junk" flag.
--regexflag reg : and this one, etc.
--delete : Deletes messages on host1 server after a successful
transfer. Option --delete has the following behavior:
--delete1 : Deletes messages on host1 server after a successful
transfer. Option --delete1 has the following behavior:
it marks messages as deleted with the IMAP flag
\Deleted, then messages are really deleted with an
EXPUNGE IMAP command.
EXPUNGE IMAP command. If expunging after each message
slows down too much the sync then use
--noexpungeaftereach to speed up.
--expunge1 : Expunge messages on host1 just before syncing a folder.
Expunge is done per folder.
Expunge aims is to really delete messages marked deleted.
An expunge is also done after each message copied
if option --delete1 is set.
--noexpunge1 : Do not expunge messages on host1.
--delete1emptyfolders : Deletes empty folders on host1, INBOX excepted.
Useful with --delete1 since what remains on host1
is only what failed to be synced.
--delete2 : Delete messages in host2 that are not in
host1 server. Useful for backup or pre-sync.
@ -164,16 +175,11 @@
Example: --delete2foldersonly "/^Junk$|^INBOX.Junk$/"
--delete2foldersbutnot reg : Do not delete folders matching regex.
Example: --delete2foldersbutnot "/Tasks$|Contacts$|Foo$/"
--noexpunge : Do not expunge messages on host1.
Expunge really deletes messages marked deleted.
Expunge is made at the beginning, on host1 only.
Newly transferred messages are also expunged if
option --delete is given.
No expunge is done on host2 account (unless --expunge2)
--expunge1 : Expunge messages on host1 after messages transfer.
--expunge2 : Expunge messages on host2 after messages transfer.
--uidexpunge2 : uidexpunge messages on the host2 account
that are not on the host1 account, requires --delete2
--nomixfolders : Avoid merging folders that are considered different on
host1 but the same on destination host2 because of
case sensitivities and insensitivities.
@ -227,7 +233,7 @@
and message counts at the end. Default is on.
--justfoldersizes : Exit after having printed the folder sizes.
--syncacls : Synchronises acls (Access Control Lists).
--syncacls : Synchronizes acls (Access Control Lists).
--nosyncacls : Does not synchronize acls. This is the default.
Acls in IMAP are not standardized, be careful.
@ -274,213 +280,177 @@
--host1 test1.lamiral.info --user1 test1 --password1 secret1 \
--host2 test2.lamiral.info --user2 test2 --password2 secret2
Here is a [linux] system (Linux petite 3.13.0-92-generic #139-Ubuntu SMP Tue Jun 28 20:42:32 UTC 2016 i686)
with Perl 5.18.2 Mail::IMAPClient 3.35
$Id: prereq.scandeps,v 1.4 2016/08/19 10:55:47 gilles Exp gilles $
This imapsync is up to date
Here is a [linux] system (Linux petite 4.4.0-62-generic #83-Ubuntu SMP Wed Jan 18 14:09:55 UTC 2017 i686)
with Perl 5.22.1 Mail::IMAPClient 3.38
$Id: prereq.scandeps,v 1.7 2017/03/01 00:12:42 gilles Exp gilles $
This imapsync is up to date. ( local 1.776 >= official 1.727 )
Homepage: http://imapsync.lamiral.info/
[MSG] No '/home/gilles/.cpanplus/custom-sources' dir, skipping custom sources
[MSG] No '/home/gilles/.cpanplus/custom-sources' dir, skipping custom sources
[MSG] No '/home/gilles/.cpanplus/custom-sources' dir, skipping custom sources
'Tie::Hash::NamedCapture' => '0.09',
'Authen::NTLM::DES' => '1.02',
'Authen::NTLM::MD4' => '1.02',
'IO::Compress::Gzip' => '2.063',
'IO::Compress::Base::Common' => '2.063',
'IO::Compress::Gzip::Constants' => '2.063',
'IO::Uncompress::Gunzip' => '2.063',
'Compress::Raw::Zlib' => '2.063',
'Convert::ASN1::IO' => '0.26',
'Convert::ASN1::_decode' => '0.26',
'Convert::ASN1::_encode' => '0.26',
'Convert::ASN1::parser' => '0.26',
'Crypt::SSLeay::X509' => 'undef',
'Crypt::SSLeay::CTX' => 'undef',
'Digest::HMAC' => '1.03',
'Encode::HanExtra' => '0.23',
'HTML::Parser' => '3.71',
'HTTP::Cookies::Netscape' => '6.00',
'Time::Zone' => '2.24',
'IO::Compress::Bzip2' => '2.063',
'IO::Compress::Deflate' => '2.063',
'IO::HTML' => '1.00',
'IO::Uncompress::Bunzip2' => '2.063',
'IO::Uncompress::Inflate' => '2.063',
'IO::Uncompress::RawInflate' => '2.063',
'HTTP::Message' => '6.06',
'File::GlobMapper' => '1.000',
'IO::Compress::Base' => '2.063',
'IO::Compress::Adapter::Bzip2' => '2.063',
'IO::Compress::Zlib::Constants' => '2.063',
'IO::Compress::RawDeflate' => '2.063',
'IO::Compress::Adapter::Deflate' => '2.063',
'Socket6' => '0.25',
'URI::data' => 'undef',
'URI::_idna' => 'undef',
'URI::_generic' => 'undef',
'URI::mailto' => 'undef',
'URI::_query' => 'undef',
'URI::QueryParam' => 'undef',
'URI::Split' => 'undef',
'URI::_foreign' => 'undef',
'URI::_segment' => 'undef',
'URI::file::FAT' => 'undef',
'URI::file::Mac' => 'undef',
'URI::file::OS2' => 'undef',
'URI::file::QNX' => 'undef',
'URI::ftp' => 'undef',
'URI::gopher' => 'undef',
'URI::https' => 'undef',
'URI::ldapi' => 'undef',
'URI::ldaps' => 'undef',
'URI::mms' => 'undef',
'URI::nntp' => 'undef',
'URI::pop' => 'undef',
'URI::rlogin' => 'undef',
'URI::rsync' => 'undef',
'URI::rtspu' => 'undef',
'URI::sips' => 'undef',
'URI::snews' => 'undef',
'URI::ssh' => 'undef',
'URI::telnet' => 'undef',
'URI::tn3270' => 'undef',
'URI::file::Win32' => 'undef',
'URI::file::Unix' => 'undef',
'URI::file::Base' => 'undef',
'URI::_punycode' => '0.04',
'URI::IRI' => 'undef',
'URI::_ldap' => '1.12',
'URI::ldap' => '1.12',
'URI::news' => 'undef',
'URI::rtsp' => 'undef',
'URI::Heuristic' => '4.20',
'URI::sip' => '0.11',
'URI::_userpass' => 'undef',
'URI::_login' => 'undef',
'URI::file' => '4.21',
'URI::WithBase' => '2.20',
'URI' => '1.60',
'URI::_server' => 'undef',
'Net::SSLeay' => '1.58',
'Compress::Raw::Bzip2' => '2.063',
'IO::Uncompress::Adapter::Bunzip2' => '2.063',
'IO::Uncompress::Base' => '2.063',
'IO::Compress::Zlib::Extra' => '2.063',
'IO::Uncompress::Adapter::Inflate' => '2.063',
'JSON::WebToken::Constants' => 'undef',
'JSON::WebToken::Exception' => 'undef',
'Module::Runtime' => '0.013',
'JSON::WebToken::Crypt' => 'undef',
'common::sense' => '3.72',
'Authen::NTLM' => '1.09',
'HTTP::Status' => '6.03',
'LWP::Protocol' => '6.00',
'HTTP::Response' => '6.04',
'CPAN::Config' => 'undef',
'LWP::MediaTypes' => '6.02',
'HTTP::Request' => '6.00',
'HTTP::Date' => '6.02',
'File::Listing' => '6.04',
'HTTP::Negotiate' => '6.00',
'Net::HTTP' => '6.06',
'Net::HTTPS' => '6.04',
'Net::SSL' => '2.85',
'LWP::Debug' => 'undef',
'Net::LDAP::DSML' => '0.16',
'Net::LDAP' => '0.58',
'Net::LDAP::LDIF' => '0.22',
'Mail::Internet' => '2.12',
'HTML::HeadParser' => '3.71',
'HTTP::Config' => '6.00',
'HTTP::Request::Common' => '6.04',
'LWP::ConnCache' => '6.02',
'HTTP::Cookies' => '6.00',
'HTTP::Headers' => '6.05',
'Encode::Locale' => '1.03',
'HTTP::Headers::Util' => '6.03',
'LWP::MemberMixin' => 'undef',
'LWP' => '6.05',
'Compress::Zlib' => '2.063',
'Mail::IMAPClient::MessageSet' => 'undef',
'Digest::HMAC_MD5' => '1.01',
'Mail::Address' => '2.12',
'Mail::Header' => '2.12',
'Mail::Mailer' => '2.12',
'Mail::Util' => '2.12',
'Net::HTTP::Methods' => '6.06',
'Net::LDAP::Bind' => '1.04',
'Net::LDAP::Extension' => '1.03',
'Net::LDAP::RootDSE' => '0.02',
'Net::LDAP::Search' => '0.14',
'Convert::ASN1::Debug' => '0.26',
'Convert::ASN1' => '0.26',
'Net::LDAP::Constant' => '0.22',
'Net::LDAP::ASN' => '0.11',
'Net::LDAP::Message' => '1.12',
'Net::LDAP::Filter' => '0.19',
'XML::SAX::Base' => '1.07',
'Net::LDAP::Schema' => '0.9908',
'Net::LDAP::Entry' => '0.26',
'Net::LDAP::Control' => '0.15',
'Net::LDAP::Util' => '0.18',
'Net::LDAP::Intermediate' => '0.04',
'Crypt::SSLeay::Conn' => 'undef',
'Crypt::SSLeay::Err' => 'undef',
'Crypt::SSLeay::MainContext' => 'undef',
'Crypt::SSLeay' => '0.58',
'Readonly::Array' => '1.04',
'Readonly::Hash' => '1.04',
'Readonly::Scalar' => '1.04',
'Test::Builder::IO::Scalar' => '2.110',
'UNIVERSAL::can' => '1.20140124',
'UNIVERSAL::isa' => '1.20120726',
'Test::Builder' => '1.001002',
'Test::Builder::Module' => '1.001002',
'Unicode::CharName' => '1.07',
'XML::SAX::Exception' => '1.07',
'Crypt::OpenSSL::Bignum' => '0.04',
'Crypt::OpenSSL::Random' => '0.04',
'Data::Uniqid' => '0.12',
'Digest::HMAC_SHA1' => '1.03',
'File::Copy::Recursive' => '0.38',
'IO::Tee' => '0.64',
'JSON::WebToken' => '0.10',
'JSON::WebToken::Crypt::RSA' => 'undef',
'Readonly' => '1.04',
'Term::ReadKey' => '2.31',
'Test::MockObject' => '1.20120301',
'Test::More' => '1.001002',
'Unicode::String' => '2.09',
'File::Spec::Unix' => '3.40',
'File::Spec' => '3.40',
'Cwd' => '3.40',
'URI::http' => 'undef',
'URI::URL' => '5.04',
'URI::Escape' => '3.31',
'JSON' => '2.61',
'JSON::XS::Boolean' => 'undef',
'JSON::XS' => '2.34',
'Crypt::OpenSSL::RSA' => '0.28',
'LWP::UserAgent' => '6.05',
'HTML::Entities' => '3.69',
'LWP::Protocol::http' => 'undef',
'IO::Socket::SSL' => '1.965',
'LWP::Protocol::ldap' => '1.25',
'LWP::Authen::Digest' => 'undef',
'LWP::Authen::Ntlm' => '6.00',
'LWP::Protocol::GHTTP' => 'undef',
'LWP::Protocol::cpan' => 'undef',
'LWP::Protocol::data' => 'undef',
'LWP::Protocol::file' => 'undef',
'LWP::Protocol::ftp' => 'undef',
'LWP::Protocol::gopher' => 'undef',
'LWP::Protocol::https' => '6.04',
'LWP::Protocol::ldapi' => 'undef',
'LWP::Protocol::ldaps' => 'undef',
'LWP::Protocol::loopback' => 'undef',
'LWP::Protocol::mailto' => 'undef',
'LWP::Protocol::nntp' => 'undef',
'LWP::Protocol::nogo' => 'undef',
'LWP::Authen::Basic' => 'undef',
'Tie::Hash::NamedCapture' => '0.09',
'Authen::NTLM::DES' => '1.02',
'Authen::NTLM::MD4' => '1.02',
'CGI::Cookie' => '4.26',
'CGI::File::Temp' => '4.26',
'CGI::Util' => '4.26',
'Fh' => '4.26',
'Convert::ASN1::IO' => '0.27',
'Convert::ASN1::_decode' => '0.27',
'Convert::ASN1::_encode' => '0.27',
'Convert::ASN1::parser' => '0.27',
'Digest::HMAC' => '1.03',
'HTML::Parser' => '3.72',
'HTTP::Cookies::Netscape' => '6.00',
'IO::HTML' => '1.001',
'HTTP::Headers' => '6.11',
'HTTP::Message' => '6.11',
'IO::Socket::SSL::PublicSuffix' => 'undef',
'Net::SSLeay' => '1.72',
'Socket6' => '0.25',
'JSON::WebToken::Constants' => 'undef',
'JSON::WebToken::Exception' => 'undef',
'Module::Runtime' => '0.014',
'JSON::WebToken::Crypt' => 'undef',
'Types::Serialiser' => '1.0',
'common::sense' => '3.74',
'CPAN::Config' => 'undef',
'URI::_foreign' => '1.71',
'URI::mailto' => '1.71',
'URI::data' => '1.71',
'URI::_query' => '1.71',
'URI' => '1.71',
'URI::QueryParam' => '1.71',
'URI::Split' => '1.71',
'URI::_segment' => '1.71',
'URI::file::FAT' => '1.71',
'URI::file::Mac' => '1.71',
'URI::file::OS2' => '1.71',
'URI::file::QNX' => '1.71',
'URI::ftp' => '1.71',
'URI::gopher' => '1.71',
'URI::https' => '1.71',
'URI::ldapi' => '1.71',
'URI::ldaps' => '1.71',
'URI::mms' => '1.71',
'URI::nntp' => '1.71',
'URI::pop' => '1.71',
'URI::rlogin' => '1.71',
'URI::rsync' => '1.71',
'URI::rtspu' => '1.71',
'URI::sftp' => '1.71',
'URI::sips' => '1.71',
'URI::snews' => '1.71',
'URI::telnet' => '1.71',
'URI::tn3270' => '1.71',
'URI::file::Win32' => '1.71',
'URI::file::Unix' => '1.71',
'URI::file::Base' => '1.71',
'URI::_punycode' => '1.71',
'URI::IRI' => '1.71',
'URI::_ldap' => '1.71',
'URI::ldap' => '1.71',
'URI::news' => '1.71',
'URI::rtsp' => '1.71',
'URI::ssh' => '1.71',
'URI::sip' => '1.71',
'URI::Heuristic' => '4.20',
'URI::_generic' => '1.71',
'URI::_login' => '1.71',
'URI::_idna' => '1.71',
'URI::_userpass' => '1.71',
'LWP::MediaTypes' => '6.02',
'File::Listing' => '6.04',
'HTTP::Negotiate' => '6.00',
'Net::HTTP' => '6.09',
'HTTP::Status' => '6.11',
'Net::HTTPS' => '6.09',
'Net::LDAP::DSML' => '0.16',
'Net::LDAP' => '0.65',
'Net::LDAP::LDIF' => '0.26',
'Mail::Internet' => '2.13',
'HTML::HeadParser' => '3.71',
'HTTP::Config' => '6.11',
'HTTP::Request::Common' => '6.11',
'LWP::ConnCache' => '6.15',
'HTTP::Cookies' => '6.01',
'HTTP::Headers::Util' => '6.11',
'Encode::Locale' => '1.05',
'LWP::MemberMixin' => 'undef',
'LWP' => '6.15',
'HTTP::Date' => '6.02',
'HTTP::Request' => '6.11',
'LWP::Protocol' => '6.15',
'HTTP::Response' => '6.11',
'Mail::IMAPClient::MessageSet' => 'undef',
'Digest::HMAC_MD5' => '1.01',
'Authen::NTLM' => '1.09',
'Mail::Address' => '2.13',
'Mail::Header' => '2.13',
'Mail::Mailer' => '2.13',
'Mail::Util' => '2.13',
'IO::Socket::INET6' => '2.72',
'Net::HTTP::Methods' => '6.09',
'Net::LDAP::Bind' => '1.05',
'Net::LDAP::Extension' => '1.04',
'Net::LDAP::RootDSE' => '0.02',
'Net::LDAP::Search' => '0.14',
'Convert::ASN1::Debug' => '0.27',
'Convert::ASN1' => '0.27',
'Net::LDAP::Message' => '1.12',
'Net::LDAP::Schema' => '0.9908',
'Net::LDAP::Entry' => '0.27',
'Net::LDAP::ASN' => '0.12',
'Net::LDAP::Filter' => '0.20',
'Net::LDAP::Constant' => '0.23',
'XML::SAX::Base' => '1.07',
'Net::LDAP::Control' => '0.18',
'Net::LDAP::Util' => '0.19',
'Net::LDAP::Intermediate' => '0.04',
'UNIVERSAL::can' => '1.20140328',
'UNIVERSAL::isa' => '1.20150614',
'URI::WithBase' => '2.20',
'URI::file' => '4.21',
'URI::_server' => '1.71',
'Unicode::CharName' => '1.07',
'XML::SAX::Exception' => '1.07',
'CGI::Carp' => '4.26',
'Data::Uniqid' => '0.12',
'Digest::HMAC_SHA1' => '1.03',
'File::Copy::Recursive' => '0.38',
'IO::Tee' => '0.64',
'JSON::WebToken' => '0.10',
'JSON::WebToken::Crypt::RSA' => 'undef',
'Readonly' => '2.00',
'Sys::MemInfo' => '0.98',
'Term::ReadKey' => '2.33',
'Test::MockObject' => '1.20150527',
'Unicode::String' => '2.09',
'HTML::Entities' => '3.69',
'CGI' => '4.26',
'LWP::Authen::Digest' => 'undef',
'LWP::Authen::Ntlm' => '6.15',
'LWP::Protocol::GHTTP' => 'undef',
'LWP::Protocol::cpan' => 'undef',
'LWP::Protocol::data' => 'undef',
'LWP::Protocol::file' => 'undef',
'LWP::Protocol::ftp' => 'undef',
'LWP::Protocol::gopher' => 'undef',
'LWP::Protocol::https' => '6.06',
'LWP::Protocol::ldapi' => 'undef',
'LWP::Protocol::ldaps' => 'undef',
'LWP::Protocol::loopback' => 'undef',
'LWP::Protocol::mailto' => 'undef',
'LWP::Protocol::nntp' => 'undef',
'LWP::UserAgent' => '6.15',
'JSON' => '2.90',
'JSON::XS::Boolean' => 'undef',
'Crypt::OpenSSL::RSA' => '0.28',
'JSON::XS' => '3.01',
'LWP::Authen::Basic' => 'undef',
'URI::URL' => '5.04',
'URI::http' => '1.71',
'URI::Escape' => '3.31',
'LWP::Protocol::http' => 'undef',
'IO::Socket::SSL' => '2.024',
'LWP::Protocol::ldap' => '1.25',
'LWP::Protocol::nogo' => 'undef',

View file

@ -0,0 +1,457 @@
usage: imapsync [options]
Several options are mandatory.
str means string
int means integer
reg means regular expression
cmd means command
--dry : Makes imapsync doing nothing, just print what would
be done without --dry.
--host1 str : Source or "from" imap server. Mandatory.
--port1 int : Port to connect on host1. Default is 143, 993 if --ssl1
--user1 str : User to login on host1. Mandatory.
--showpasswords : Shows passwords on output instead of "MASKED".
Useful to restart a complete run by just reading the log.
--password1 str : Password for the user1.
--host2 str : "destination" imap server. Mandatory.
--port2 int : Port to connect on host2. Default is 143, 993 if --ssl2
--user2 str : User to login on host2. Mandatory.
--password2 str : Password for the user2.
--passfile1 str : Password file for the user1. It must contain the
password on the first line. This option avoids to show
the password on the command line like --password1 does.
--passfile2 str : Password file for the user2. Contains the password.
--ssl1 : Use a SSL connection on host1.
--ssl2 : Use a SSL connection on host2.
--tls1 : Use a TLS connection on host1.
--tls2 : Use a TLS connection on host2.
--debugssl int : SSL debug mode from 0 to 4.
--sslargs1 str : Pass any ssl parameter for host1 ssl or tls connection. Example:
--sslargs1 SSL_verify_mode=1 --sslargs1 SSL_version=SSLv3
See all possibilities in the new() method of IO::Socket::SSL
http://search.cpan.org/perldoc?IO::Socket::SSL#Description_Of_Methods
--sslargs2 str : Pass any ssl parameter for host2 ssl or tls connection.
See --sslargs1
--timeout1 int : Connection timeout in seconds for host1.
Default is 120 and 0 means no timeout at all.
--timeout2 int : Connection timeout in seconds for host2.
Default is 120 and 0 means no timeout at all.
--authmech1 str : Auth mechanism to use with host1:
PLAIN, LOGIN, CRAM-MD5 etc. Use UPPERCASE.
--authmech2 str : Auth mechanism to use with host2. See --authmech1
--authuser1 str : User to auth with on host1 (admin user).
Avoid using --authmech1 SOMETHING with --authuser1.
--authuser2 str : User to auth with on host2 (admin user).
--proxyauth1 : Use proxyauth on host1. Requires --authuser1.
Required by Sun/iPlanet/Netscape IMAP servers to
be able to use an administrative user.
--proxyauth2 : Use proxyauth on host2. Requires --authuser2.
--authmd51 : Use MD5 authentification for host1.
--authmd52 : Use MD5 authentification for host2.
--domain1 str : Domain on host1 (NTLM authentication).
--domain2 str : Domain on host2 (NTLM authentication).
--folder str : Sync this folder.
--folder str : and this one, etc.
--folderrec str : Sync this folder recursively.
--folderrec str : and this one, etc.
--folderfirst str : Sync this folder first. --folderfirst "Work"
--folderfirst str : then this one, etc.
--folderlast str : Sync this folder last. --folderlast "[Gmail]/All Mail"
--folderlast str : then this one, etc.
--nomixfolders : Do not merge folders when host1 is case sensitive
while host2 is not (like Exchange). Only the first
similar folder is synced (ex: Sent SENT sent -> Sent).
--skipemptyfolders : Empty host1 folders are not created on host2.
--include reg : Sync folders matching this regular expression
--include reg : or this one, etc.
in case both --include --exclude options are
use, include is done before.
--exclude reg : Skips folders matching this regular expression
Several folders to avoid:
--exclude 'fold1|fold2|f3' skips fold1, fold2 and f3.
--exclude reg : or this one, etc.
--subfolder2 str : Move whole host1 folders hierarchy under this
host2 folder str .
It does it by adding two --regextrans2 options before
all others. Add --debug to see what's really going on.
--automap : guesses folders mapping, for folders like
"Sent", "Junk", "Drafts", "All", "Archive", "Flagged".
--f1f2 str1=str2 : Force folder str1 to be synced to str2,
--f1f2 overrides --automap and --regextrans2.
--regextrans2 reg : Apply the whole regex to each destination folders.
--regextrans2 reg : and this one. etc.
When you play with the --regextrans2 option, first
add also the safe options --dry --justfolders
Then, when happy, remove --dry, remove --justfolders.
Have in mind that --regextrans2 is applied after prefix
and separator inversion. For examples see
http://imapsync.lamiral.info/FAQ.d/FAQ.Folders_Mapping.txt
--tmpdir str : Where to store temporary files and subdirectories.
Will be created if it doesn't exist.
Default is system specific, Unix is /tmp but
it's often small and deleted at reboot.
--tmpdir /var/tmp should be better.
--pidfile str : The file where imapsync pid is written.
--pidfilelocking : Abort if pidfile already exists. Usefull to avoid
concurrent transfers on the same mailbox.
--nolog : Turn off logging on file
--logfile str : Change the default log filename (can be dirname/filename).
--logdir str : Change the default log directory. Default is LOG_imapsync
--prefix1 str : Remove prefix to all destination folders
(usually INBOX. or INBOX/ or an empty string "")
you have to use --prefix1 if host1 imap server
does not have NAMESPACE capability, so imapsync
suggests to use it. All other cases are bad.
--prefix2 str : Add prefix to all host2 folders. See --prefix1
--sep1 str : Host1 separator in case NAMESPACE is not supported.
--sep2 str : Host2 separator in case NAMESPACE is not supported.
--skipmess reg : Skips messages maching the regex.
Example: 'm/[\x80-ff]/' # to avoid 8bits messages.
--skipmess is applied before --regexmess
--skipmess reg : or this one, etc.
--pipemess cmd : Apply this cmd command to each message content
before the copy.
--pipemess cmd : and this one, etc.
--disarmreadreceipts : Disarms read receipts (host2 Exchange issue)
--regexmess reg : Apply the whole regex to each message before transfer.
Example: 's/\000/ /g' # to replace null by space.
--regexmess reg : and this one, etc.
--regexflag reg : Apply the whole regex to each flags list.
Example: 's/"Junk"//g' # to remove "Junk" flag.
--regexflag reg : and this one, etc.
--delete1 : Deletes messages on host1 server after a successful
transfer. Option --delete1 has the following behavior:
it marks messages as deleted with the IMAP flag
\Deleted, then messages are really deleted with an
EXPUNGE IMAP command. If expunging after each message
slows down too much the sync then use
--noexpungeaftereach to speed up.
--expunge1 : Expunge messages on host1 just before syncing a folder.
Expunge is done per folder.
Expunge aims is to really delete messages marked deleted.
An expunge is also done after each message copied
if option --delete1 is set.
--noexpunge1 : Do not expunge messages on host1.
--delete1emptyfolders : Deletes empty folders on host1, INBOX excepted.
Useful with --delete1 since what remains on host1
is only what failed to be synced.
--delete2 : Delete messages in host2 that are not in
host1 server. Useful for backup or pre-sync.
--delete2duplicates : Delete messages in host2 that are duplicates.
Works only without --useuid since duplicates are
detected with an header part of each message.
--delete2folders : Delete folders in host2 that are not in host1 server.
For safety, first try it like this (it is safe):
--delete2folders --dry --justfolders --nofoldersizes
--delete2foldersonly reg : Deleted only folders matching regex.
Example: --delete2foldersonly "/^Junk$|^INBOX.Junk$/"
--delete2foldersbutnot reg : Do not delete folders matching regex.
Example: --delete2foldersbutnot "/Tasks$|Contacts$|Foo$/"
--expunge2 : Expunge messages on host2 after messages transfer.
--uidexpunge2 : uidexpunge messages on the host2 account
that are not on the host1 account, requires --delete2
--nomixfolders : Avoid merging folders that are considered different on
host1 but the same on destination host2 because of
case sensitivities and insensitivities.
--syncinternaldates : Sets the internal dates on host2 same as host1.
Turned on by default. Internal date is the date
a message arrived on a host (mtime).
--idatefromheader : Sets the internal dates on host2 same as the
"Date:" headers.
--maxsize int : Skip messages larger (or equal) than int bytes
--minsize int : Skip messages smaller (or equal) than int bytes
--maxage int : Skip messages older than int days.
final stats (skipped) don't count older messages
see also --minage
--minage int : Skip messages newer than int days.
final stats (skipped) don't count newer messages
You can do (+ are the messages selected):
past|----maxage+++++++++++++++>now
past|+++++++++++++++minage---->now
past|----maxage+++++minage---->now (intersection)
past|++++minage-----maxage++++>now (union)
--search str : Selects only messages returned by this IMAP SEARCH
command. Applied on both sides.
--search1 str : Same as --search for selecting host1 messages only.
--search2 str : Same as --search for selecting host2 messages only.
--search CRIT equals --search1 CRIT --search2 CRIT
--exitwhenover int : Stop syncing when total bytes transferred reached.
Gmail per day allows
2500000000 = 2.5 GB downloaded from Gmail as host2
500000000 = 500 MB uploaded to Gmail as host1.
--maxlinelength int : skip messages with a line length longer than int bytes.
RFC 2822 says it must be no more than 1000 bytes.
--useheader str : Use this header to compare messages on both sides.
Ex: Message-ID or Subject or Date.
--useheader str and this one, etc.
--subscribed : Transfers subscribed folders.
--subscribe : Subscribe to the folders transferred on the
host2 that are subscribed on host1. On by default.
--subscribeall : Subscribe to the folders transferred on the
host2 even if they are not subscribed on host1.
--nofoldersizes : Do not calculate the size of each folder in bytes
and message counts. Default is to calculate them.
--nofoldersizesatend: Do not calculate the size of each folder in bytes
and message counts at the end. Default is on.
--justfoldersizes : Exit after having printed the folder sizes.
--syncacls : Synchronizes acls (Access Control Lists).
--nosyncacls : Does not synchronize acls. This is the default.
Acls in IMAP are not standardized, be careful.
--usecache : Use cache to speedup.
--nousecache : Do not use cache. Caveat: --useuid --nousecache creates
duplicates on multiple runs.
--useuid : Use uid instead of header as a criterium to recognize
messages. Option --usecache is then implied unless
--nousecache is used.
--debug : Debug mode.
--debugfolders : Debug mode for the folders part only.
--debugcontent : Debug content of the messages transfered. Huge ouput.
--debugflags : Debug mode for flags.
--debugimap1 : IMAP debug mode for host1. Very verbose.
--debugimap2 : IMAP debug mode for host2. Very verbose.
--debugimap : IMAP debug mode for host1 and host2.
--debugmemory : Debug mode showing memory consumption after each copy.
--errorsmax int : Exit when int number of errors is reached. Default is 50.
--tests : Run local non-regression tests. Exit code 0 means all ok.
--testslive : Run a live test with test1.lamiral.info imap server.
Useful to check the basics. Needs internet connexion.
--version : Print only software version.
--noreleasecheck : Do not check for new imapsync release (a http request).
--releasecheck : Check for new imapsync release (a http request).
--noid : Do not send/receive ID command to imap servers.
--justconnect : Just connect to both servers and print useful
information. Need only --host1 and --host2 options.
--justlogin : Just login to both host1 and host2 with users
credentials, then exit.
--justfolders : Do only things about folders (ignore messages).
--help : print this help.
Example: to synchronize imap account "test1" on "test1.lamiral.info"
to imap account "test2" on "test2.lamiral.info"
with test1 password "secret1"
and test2 password "secret2"
imapsync \
--host1 test1.lamiral.info --user1 test1 --password1 secret1 \
--host2 test2.lamiral.info --user2 test2 --password2 secret2
Here is a 2.0 GiB [linux] system (Linux petite 4.4.0-64-generic #85-Ubuntu SMP Mon Feb 20 11:49:39 UTC 2017 i686)
with Perl 5.22.1and Mail::IMAPClient 3.38
$Id: prereq.scandeps.Ubuntu_16.04.txt,v 1.1 2017/03/22 00:36:33 gilles Exp gilles $
This imapsync is up to date. ( local 1.788 >= official 1.727 )
Homepage: http://imapsync.lamiral.info/
'Tie::Hash::NamedCapture' => '0.09',
'Authen::NTLM::DES' => '1.02',
'Authen::NTLM::MD4' => '1.02',
'CGI::Cookie' => '4.26',
'CGI::File::Temp' => '4.26',
'CGI::Util' => '4.26',
'Fh' => '4.26',
'Convert::ASN1::IO' => '0.27',
'Convert::ASN1::_decode' => '0.27',
'Convert::ASN1::_encode' => '0.27',
'Convert::ASN1::parser' => '0.27',
'Digest::HMAC' => '1.03',
'HTML::Parser' => '3.72',
'HTTP::Headers' => '6.11',
'HTTP::Cookies::Netscape' => '6.00',
'IO::HTML' => '1.001',
'HTTP::Message' => '6.11',
'IO::Socket::SSL::PublicSuffix' => 'undef',
'Net::SSLeay' => '1.72',
'Socket6' => '0.25',
'JSON::WebToken::Constants' => 'undef',
'JSON::WebToken::Exception' => 'undef',
'Module::Runtime' => '0.014',
'JSON::WebToken::Crypt' => 'undef',
'Types::Serialiser' => '1.0',
'common::sense' => '3.74',
'Authen::NTLM' => '1.09',
'CPAN::Config' => 'undef',
'URI::_foreign' => '1.71',
'URI::_generic' => '1.71',
'URI::mailto' => '1.71',
'URI::data' => '1.71',
'URI::_query' => '1.71',
'URI' => '1.71',
'URI::QueryParam' => '1.71',
'URI::Split' => '1.71',
'URI::_segment' => '1.71',
'URI::file::FAT' => '1.71',
'URI::file::Mac' => '1.71',
'URI::file::OS2' => '1.71',
'URI::file::QNX' => '1.71',
'URI::ftp' => '1.71',
'URI::gopher' => '1.71',
'URI::https' => '1.71',
'URI::ldapi' => '1.71',
'URI::ldaps' => '1.71',
'URI::mms' => '1.71',
'URI::nntp' => '1.71',
'URI::pop' => '1.71',
'URI::rlogin' => '1.71',
'URI::rsync' => '1.71',
'URI::rtspu' => '1.71',
'URI::sftp' => '1.71',
'URI::sips' => '1.71',
'URI::snews' => '1.71',
'URI::telnet' => '1.71',
'URI::tn3270' => '1.71',
'URI::file::Win32' => '1.71',
'URI::file::Unix' => '1.71',
'URI::file::Base' => '1.71',
'URI::_idna' => '1.71',
'URI::_punycode' => '1.71',
'URI::IRI' => '1.71',
'URI::_ldap' => '1.71',
'URI::ldap' => '1.71',
'URI::news' => '1.71',
'URI::rtsp' => '1.71',
'URI::ssh' => '1.71',
'URI::sip' => '1.71',
'URI::_userpass' => '1.71',
'URI::Heuristic' => '4.20',
'URI::_login' => '1.71',
'LWP::MediaTypes' => '6.02',
'File::Listing' => '6.04',
'HTTP::Negotiate' => '6.00',
'Net::HTTP' => '6.09',
'HTTP::Status' => '6.11',
'Net::HTTPS' => '6.09',
'Net::LDAP::DSML' => '0.16',
'Net::LDAP' => '0.65',
'Net::LDAP::LDIF' => '0.26',
'Mail::Internet' => '2.13',
'HTML::HeadParser' => '3.71',
'HTTP::Config' => '6.11',
'HTTP::Request::Common' => '6.11',
'LWP::ConnCache' => '6.15',
'HTTP::Cookies' => '6.01',
'HTTP::Headers::Util' => '6.11',
'Encode::Locale' => '1.05',
'LWP::MemberMixin' => 'undef',
'LWP' => '6.15',
'HTTP::Date' => '6.02',
'HTTP::Request' => '6.11',
'LWP::Protocol' => '6.15',
'HTTP::Response' => '6.11',
'Mail::IMAPClient::MessageSet' => 'undef',
'Digest::HMAC_MD5' => '1.01',
'Mail::Address' => '2.13',
'Mail::Header' => '2.13',
'Mail::Mailer' => '2.13',
'Mail::Util' => '2.13',
'Net::HTTP::Methods' => '6.09',
'Net::LDAP::Bind' => '1.05',
'Net::LDAP::Extension' => '1.04',
'Net::LDAP::RootDSE' => '0.02',
'Net::LDAP::Search' => '0.14',
'Convert::ASN1::Debug' => '0.27',
'Convert::ASN1' => '0.27',
'Net::LDAP::Schema' => '0.9908',
'Net::LDAP::Entry' => '0.27',
'Net::LDAP::Message' => '1.12',
'Net::LDAP::ASN' => '0.12',
'Net::LDAP::Constant' => '0.23',
'Net::LDAP::Filter' => '0.20',
'XML::SAX::Base' => '1.07',
'Net::LDAP::Control' => '0.18',
'Net::LDAP::Util' => '0.19',
'Net::LDAP::Intermediate' => '0.04',
'IO::Socket::INET6' => '2.72',
'UNIVERSAL::can' => '1.20140328',
'UNIVERSAL::isa' => '1.20150614',
'URI::WithBase' => '2.20',
'URI::file' => '4.21',
'URI::_server' => '1.71',
'Unicode::CharName' => '1.07',
'XML::SAX::Exception' => '1.07',
'CGI::Carp' => '4.26',
'Data::Uniqid' => '0.12',
'Digest::HMAC_SHA1' => '1.03',
'File::Copy::Recursive' => '0.38',
'IO::Tee' => '0.64',
'JSON::WebToken' => '0.10',
'JSON::WebToken::Crypt::RSA' => 'undef',
'Mail::IMAPClient' => '3.38',
'Readonly' => '2.00',
'Sys::MemInfo' => '0.98',
'Term::ReadKey' => '2.33',
'Test::MockObject' => '1.20150527',
'Unicode::String' => '2.09',
'CGI' => '4.26',
'Crypt::OpenSSL::RSA' => '0.28',
'LWP::Authen::Digest' => 'undef',
'LWP::Authen::Ntlm' => '6.15',
'LWP::Protocol::GHTTP' => 'undef',
'LWP::Protocol::cpan' => 'undef',
'LWP::Protocol::data' => 'undef',
'LWP::Protocol::file' => 'undef',
'LWP::Protocol::ftp' => 'undef',
'LWP::Protocol::gopher' => 'undef',
'LWP::Protocol::https' => '6.06',
'LWP::Protocol::ldapi' => 'undef',
'LWP::Protocol::ldaps' => 'undef',
'LWP::Protocol::loopback' => 'undef',
'LWP::Protocol::mailto' => 'undef',
'LWP::Protocol::nntp' => 'undef',
'LWP::UserAgent' => '6.15',
'LWP::Authen::Basic' => 'undef',
'URI::URL' => '5.04',
'URI::http' => '1.71',
'HTML::Entities' => '3.69',
'URI::Escape' => '3.31',
'LWP::Protocol::http' => 'undef',
'IO::Socket::SSL' => '2.024',
'JSON' => '2.90',
'JSON::XS::Boolean' => 'undef',
'JSON::XS' => '3.01',
'LWP::Protocol::ldap' => '1.25',
'LWP::Protocol::nogo' => 'undef',

View file

@ -0,0 +1,582 @@
Name:
imapsync - Email IMAP tool for syncing, copying and migrating email
mailboxes between two imap servers, one way, and without duplicates.
Version:
This documentation refers to Imapsync $Revision: 1.1 $
Usage:
To synchronize the source imap account
"test1" on server "test1.lamiral.info" with password "secret1"
to the destination imap account
"test2" on server "test2.lamiral.info" with password "secret2"
do:
imapsync \
--host1 test1.lamiral.info --user1 test1 --password1 secret1 \
--host2 test2.lamiral.info --user2 test2 --password2 secret2
Options:
usage: imapsync [options]
Mandatory options are the six values, three on each sides, needed to log in
into the IMAP servers, ie, a host, a username, and a password, two times.
Conventions used:
str means string
int means integer
reg means regular expression
cmd means command
--dry : Makes imapsync doing nothing for real, just print what
would be done without --dry.
Options/credentials:
--host1 str : Source or "from" imap server. Mandatory.
--port1 int : Port to connect on host1. Default is 143, 993 if --ssl1
--user1 str : User to login on host1. Mandatory.
--password1 str : Password for the user1.
--host2 str : "destination" imap server. Mandatory.
--port2 int : Port to connect on host2. Default is 143, 993 if --ssl2
--user2 str : User to login on host2. Mandatory.
--password2 str : Password for the user2.
--showpasswords : Shows passwords on output instead of "MASKED".
Useful to restart a complete run by just reading the log,
or to debug passwords. It's not a secure practice.
--passfile1 str : Password file for the user1. It must contain the
password on the first line. This option avoids to show
the password on the command line like --password1 does.
--passfile2 str : Password file for the user2. Contains the password.
Options/encryption:
--nossl1 : Do not use a SSL connection on host1.
--ssl1 : Use a SSL connection on host1. On by default if possible.
--nossl2 : Do not use a SSL connection on host2.
--ssl2 : Use a SSL connection on host2. On by default if possible.
--notls1 : Do not use a TLS connection on host1.
--tls1 : Use a TLS connection on host1. On by default if possible.
--notls2 : Do not use a TLS connection on host2.
--tls2 : Use a TLS connection on host2. On by default if possible.
--debugssl int : SSL debug mode from 0 to 4.
--sslargs1 str : Pass any ssl parameter for host1 ssl or tls connection. Example:
--sslargs1 SSL_verify_mode=1 --sslargs1 SSL_version=SSLv3
See all possibilities in the new() method of IO::Socket::SSL
http://search.cpan.org/perldoc?IO::Socket::SSL#Description_Of_Methods
--sslargs2 str : Pass any ssl parameter for host2 ssl or tls connection.
See --sslargs1
--timeout1 int : Connection timeout in seconds for host1.
Default is 120 and 0 means no timeout at all.
--timeout2 int : Connection timeout in seconds for host2.
Default is 120 and 0 means no timeout at all.
Options/authentication:
--authmech1 str : Auth mechanism to use with host1:
PLAIN, LOGIN, CRAM-MD5 etc. Use UPPERCASE.
--authmech2 str : Auth mechanism to use with host2. See --authmech1
--authuser1 str : User to auth with on host1 (admin user).
Avoid using --authmech1 SOMETHING with --authuser1.
--authuser2 str : User to auth with on host2 (admin user).
--proxyauth1 : Use proxyauth on host1. Requires --authuser1.
Required by Sun/iPlanet/Netscape IMAP servers to
be able to use an administrative user.
--proxyauth2 : Use proxyauth on host2. Requires --authuser2.
--authmd51 : Use MD5 authentication for host1.
--authmd52 : Use MD5 authentication for host2.
--domain1 str : Domain on host1 (NTLM authentication).
--domain2 str : Domain on host2 (NTLM authentication).
Options/folders:
--folder str : Sync this folder.
--folder str : and this one, etc.
--folderrec str : Sync this folder recursively.
--folderrec str : and this one, etc.
--folderfirst str : Sync this folder first. --folderfirst "Work"
--folderfirst str : then this one, etc.
--folderlast str : Sync this folder last. --folderlast "[Gmail]/All Mail"
--folderlast str : then this one, etc.
--nomixfolders : Do not merge folders when host1 is case-sensitive
while host2 is not (like Exchange). Only the first
similar folder is synced (ex: Sent SENT sent -> Sent).
--skipemptyfolders : Empty host1 folders are not created on host2.
--include reg : Sync folders matching this regular expression
--include reg : or this one, etc.
If both --include --exclude options are used, then
include is done before.
--exclude reg : Skips folders matching this regular expression
Several folders to avoid:
--exclude 'fold1|fold2|f3' skips fold1, fold2 and f3.
--exclude reg : or this one, etc.
--subfolder2 str : Move whole host1 folders hierarchy under this
host2 folder str .
It does it by adding two --regextrans2 options before
all others. Add --debug to see what's really going on.
--automap : guesses folders mapping, for folders like
"Sent", "Junk", "Drafts", "All", "Archive", "Flagged".
--f1f2 str1=str2 : Force folder str1 to be synced to str2,
--f1f2 overrides --automap and --regextrans2.
--nomixfolders : Avoid merging folders that are considered different on
host1 but the same on destination host2 because of
case sensitivities and insensitivities.
--subscribed : Transfers subscribed folders.
--subscribe : Subscribe to the folders transferred on the
host2 that are subscribed on host1. On by default.
--subscribeall : Subscribe to the folders transferred on the
host2 even if they are not subscribed on host1.
--prefix1 str : Remove prefix str to all destination folders,
usually INBOX. or INBOX/ or an empty string "".
imapsync guesses the prefix if host1 imap server
does not have NAMESPACE capability. This option
should not be used, most of the time.
--prefix2 str : Add prefix to all host2 folders. See --prefix1
--sep1 str : Host1 separator in case NAMESPACE is not supported.
--sep2 str : Host2 separator in case NAMESPACE is not supported.
--regextrans2 reg : Apply the whole regex to each destination folders.
--regextrans2 reg : and this one. etc.
When you play with the --regextrans2 option, first
add also the safe options --dry --justfolders
Then, when happy, remove --dry, remove --justfolders.
Have in mind that --regextrans2 is applied after prefix
and separator inversion. For examples see
http://imapsync.lamiral.info/FAQ.d/FAQ.Folders_Mapping.txt
Options/folders sizes:
--nofoldersizes : Do not calculate the size of each folder at the
beginning of the sync. Default is to calculate them.
--nofoldersizesatend: Do not calculate the size of each folder at the
end of the sync. Default is to calculate them.
--justfoldersizes : Exit after having printed the initial folder sizes.
Options/tmp:
--tmpdir str : Where to store temporary files and subdirectories.
Will be created if it doesn't exist.
Default is system specific, Unix is /tmp but
/tmp is often too small and deleted at reboot.
--tmpdir /var/tmp should be better.
--pidfile str : The file where imapsync pid is written,
it can be dirname/filename.
Default name is imapsync.pid in tmpdir.
--pidfilelocking : Abort if pidfile already exists. Useful to avoid
concurrent transfers on the same mailbox.
Options/log:
--nolog : Turn off logging on file
--logfile str : Change the default log filename (can be dirname/filename).
--logdir str : Change the default log directory. Default is LOG_imapsync/
Options/messages:
--skipmess reg : Skips messages matching the regex.
Example: 'm/[\x80-ff]/' # to avoid 8bits messages.
--skipmess is applied before --regexmess
--skipmess reg : or this one, etc.
--pipemess cmd : Apply this cmd command to each message content
before the copy.
--pipemess cmd : and this one, etc.
--disarmreadreceipts : Disarms read receipts (host2 Exchange issue)
--regexmess reg : Apply the whole regex to each message before transfer.
Example: 's/\000/ /g' # to replace null by space.
--regexmess reg : and this one, etc.
Options/flags:
--regexflag reg : Apply the whole regex to each flags list.
Example: 's/"Junk"//g' # to remove "Junk" flag.
--regexflag reg : then this one, etc.
Options/deletions:
--delete1 : Deletes messages on host1 server after a successful
transfer. Option --delete1 has the following behavior:
it marks messages as deleted with the IMAP flag
\Deleted, then messages are really deleted with an
EXPUNGE IMAP command. If expunging after each message
slows down too much the sync then use
--noexpungeaftereach to speed up.
--expunge1 : Expunge messages on host1 just before syncing a folder.
Expunge is done per folder.
Expunge aims is to really delete messages marked deleted.
An expunge is also done after each message copied
if option --delete1 is set.
--noexpunge1 : Do not expunge messages on host1.
--delete1emptyfolders : Deletes empty folders on host1, INBOX excepted.
Useful with --delete1 since what remains on host1
is only what failed to be synced.
--delete2 : Delete messages in host2 that are not in
host1 server. Useful for backup or pre-sync.
--delete2duplicates : Delete messages in host2 that are duplicates.
Works only without --useuid since duplicates are
detected with an header part of each message.
--delete2folders : Delete folders in host2 that are not in host1 server.
For safety, first try it like this (it is safe):
--delete2folders --dry --justfolders --nofoldersizes
--delete2foldersonly reg : Deleted only folders matching regex.
Example: --delete2foldersonly "/^Junk$|^INBOX.Junk$/"
--delete2foldersbutnot reg : Do not delete folders matching regex.
Example: --delete2foldersbutnot "/Tasks$|Contacts$|Foo$/"
--expunge2 : Expunge messages on host2 after messages transfer.
--uidexpunge2 : uidexpunge messages on the host2 account
that are not on the host1 account, requires --delete2
Options/dates:
--syncinternaldates : Sets the internal dates on host2 same as host1.
Turned on by default. Internal date is the date
a message arrived on a host (mtime).
--idatefromheader : Sets the internal dates on host2 same as the
"Date:" headers.
Options/message selection:
--maxsize int : Skip messages larger (or equal) than int bytes
--minsize int : Skip messages smaller (or equal) than int bytes
--maxage int : Skip messages older than int days.
final stats (skipped) don't count older messages
see also --minage
--minage int : Skip messages newer than int days.
final stats (skipped) don't count newer messages
You can do (+ are the messages selected):
past|----maxage+++++++++++++++>now
past|+++++++++++++++minage---->now
past|----maxage+++++minage---->now (intersection)
past|++++minage-----maxage++++>now (union)
--search str : Selects only messages returned by this IMAP SEARCH
command. Applied on both sides.
--search1 str : Same as --search for selecting host1 messages only.
--search2 str : Same as --search for selecting host2 messages only.
--search CRIT equals --search1 CRIT --search2 CRIT
--maxlinelength int : skip messages with a line length longer than int bytes.
RFC 2822 says it must be no more than 1000 bytes.
--useheader str : Use this header to compare messages on both sides.
Ex: Message-ID or Subject or Date.
--useheader str and this one, etc.
--usecache : Use cache to speed up the sync.
--nousecache : Do not use cache. Caveat: --useuid --nousecache creates
duplicates on multiple runs.
--useuid : Use uid instead of header as a criterium to recognize
messages. Option --usecache is then implied unless
--nousecache is used.
Options/miscelaneous:
--syncacls : Synchronizes acls (Access Control Lists).
--nosyncacls : Does not synchronize acls. This is the default.
Acls in IMAP are not standardized, be careful.
Options/debugging:
--debug : Debug mode.
--debugfolders : Debug mode for the folders part only.
--debugcontent : Debug content of the messages transferred. Huge output.
--debugflags : Debug mode for flags.
--debugimap1 : IMAP debug mode for host1. Very verbose.
--debugimap2 : IMAP debug mode for host2. Very verbose.
--debugimap : IMAP debug mode for host1 and host2.
--debugmemory : Debug mode showing memory consumption after each copy.
--errorsmax int : Exit when int number of errors is reached. Default is 50.
--tests : Run local non-regression tests. Exit code 0 means all ok.
--testslive : Run a live test with test1.lamiral.info imap server.
Useful to check the basics. Needs internet connexion.
--testslive6 : Run a live test with ks2ipv6.lamiral.info imap server.
Useful to check the ipv6 connectivity. Needs internet.
Options/specific:
--gmail1 : sets --host1 to Gmail and options from FAQ.Gmail.txt
--gmail2 : sets --host2 to Gmail and options from FAQ.Gmail.txt
--office1 : sets --host1 to Office365 options from FAQ.Exchange.txt
--office2 : sets --host2 to Office365 options from FAQ.Exchange.txt
--exchange1 : sets options from FAQ.Exchange.txt, account1 part
--exchange2 : sets options from FAQ.Exchange.txt, account2 part
--domino1 : sets options from FAQ.Domino.txt, account1 part
--domino2 : sets options from FAQ.Domino.txt, account2 part
Options/behavior:
--maxmessagespersecond int : limits the number of messages transferred per second.
--maxbytespersecond int : limits the average transfer rate per second.
--maxbytesafter int : starts --maxbytespersecond limitation only after
--maxbytesafter amount of data transferred.
--maxsleep int : do not sleep more than int seconds.
On by default, 2 seconds max, like --maxsleep 2
--abort : terminates a previous call still running.
It uses the pidfile to know what processus to abort.
--exitwhenover int : Stop syncing when total bytes transferred reached.
--version : Print only software version.
--noreleasecheck : Do not check for new imapsync release (a http request).
--releasecheck : Check for new imapsync release (a http request).
--noid : Do not send/receive ID command to imap servers.
--justconnect : Just connect to both servers and print useful
information. Need only --host1 and --host2 options.
--justlogin : Just login to both host1 and host2 with users
credentials, then exit.
--justfolders : Do only things about folders (ignore messages).
--help : print this help.
Example: to synchronize imap account "test1" on "test1.lamiral.info"
to imap account "test2" on "test2.lamiral.info"
with test1 password "secret1"
and test2 password "secret2"
imapsync \
--host1 test1.lamiral.info --user1 test1 --password1 secret1 \
--host2 test2.lamiral.info --user2 test2 --password2 secret2
Here is petite, a 2.0 GiB [linux] system (Linux petite 4.4.0-92-generic #115-Ubuntu SMP Thu Aug 10 16:02:55 UTC 2017 i686)
with Perl 5.22.1 and Mail::IMAPClient 3.38
$Id: prereq.scandeps.Ubuntu_16.04_xenial.txt,v 1.1 2017/09/07 12:39:54 gilles Exp gilles $
This imapsync is up to date. ( local 1.836 >= official 1.727 )
Homepage: http://imapsync.lamiral.info/
'Tie::Hash::NamedCapture' => '0.09',
'Authen::NTLM::DES' => '1.02',
'Authen::NTLM::MD4' => '1.02',
'Crypt::Random::Seed' => '0.03',
'Math::Random::ISAAC' => '1.003',
'CGI::Cookie' => '4.26',
'CGI::File::Temp' => '4.26',
'CGI::Util' => '4.26',
'Fh' => '4.26',
'Convert::ASN1::IO' => '0.27',
'Convert::ASN1::_decode' => '0.27',
'Convert::ASN1::_encode' => '0.27',
'Convert::ASN1::parser' => '0.27',
'Bytes::Random::Secure' => '0.28',
'Crypt::SSLeay::X509' => 'undef',
'Crypt::SSLeay::CTX' => 'undef',
'Digest::HMAC' => '1.03',
'Encode::HanExtra' => '0.23',
'HTML::Parser' => '3.72',
'HTTP::Headers' => '6.11',
'HTTP::Cookies::Netscape' => '6.00',
'IO::Compress::Bzip2' => '2.069',
'IO::Compress::Deflate' => '2.069',
'IO::Compress::Gzip' => '2.069',
'IO::HTML' => '1.001',
'IO::Uncompress::Bunzip2' => '2.069',
'IO::Uncompress::Inflate' => '2.069',
'IO::Uncompress::RawInflate' => '2.069',
'IO::Uncompress::Gunzip' => '2.069',
'HTTP::Message' => '6.11',
'File::GlobMapper' => '1.000',
'IO::Compress::Adapter::Bzip2' => '2.069',
'IO::Compress::Base' => '2.069',
'IO::Compress::Zlib::Constants' => '2.069',
'IO::Compress::RawDeflate' => '2.069',
'IO::Compress::Adapter::Deflate' => '2.069',
'Socket6' => '0.25',
'IO::Socket::SSL::PublicSuffix' => 'undef',
'Net::SSLeay' => '1.72',
'Compress::Raw::Bzip2' => '2.069',
'IO::Uncompress::Adapter::Bunzip2' => '2.069',
'IO::Compress::Zlib::Extra' => '2.069',
'IO::Compress::Gzip::Constants' => '2.069',
'IO::Compress::Base::Common' => '2.069',
'IO::Uncompress::Adapter::Inflate' => '2.069',
'IO::Uncompress::Base' => '2.069',
'JSON::WebToken::Constants' => 'undef',
'JSON::WebToken::Exception' => 'undef',
'Module::Runtime' => '0.014',
'JSON::WebToken::Crypt' => 'undef',
'Types::Serialiser' => '1.0',
'common::sense' => '3.74',
'Authen::NTLM' => '1.09',
'HTTP::Status' => '6.11',
'LWP::Protocol' => '6.15',
'HTTP::Response' => '6.11',
'CPAN::Config' => 'undef',
'URI::_query' => '1.71',
'URI::data' => '1.71',
'URI::_idna' => '1.71',
'URI::mailto' => '1.71',
'URI' => '1.71',
'URI::QueryParam' => '1.71',
'URI::Split' => '1.71',
'URI::_segment' => '1.71',
'URI::file::FAT' => '1.71',
'URI::file::Mac' => '1.71',
'URI::file::OS2' => '1.71',
'URI::file::QNX' => '1.71',
'URI::ftp' => '1.71',
'URI::gopher' => '1.71',
'URI::https' => '1.71',
'URI::ldapi' => '1.71',
'URI::ldaps' => '1.71',
'URI::mms' => '1.71',
'URI::nntp' => '1.71',
'URI::pop' => '1.71',
'URI::rlogin' => '1.71',
'URI::rsync' => '1.71',
'URI::rtspu' => '1.71',
'URI::sftp' => '1.71',
'URI::sips' => '1.71',
'URI::snews' => '1.71',
'URI::telnet' => '1.71',
'URI::tn3270' => '1.71',
'URI::_foreign' => '1.71',
'URI::file::Win32' => '1.71',
'URI::file::Unix' => '1.71',
'URI::file::Base' => '1.71',
'URI::Heuristic' => '4.20',
'URI::_login' => '1.71',
'URI::IRI' => '1.71',
'URI::ldap' => '1.71',
'URI::news' => '1.71',
'URI::ssh' => '1.71',
'URI::_punycode' => '1.71',
'URI::_generic' => '1.71',
'URI::_ldap' => '1.71',
'URI::rtsp' => '1.71',
'URI::_userpass' => '1.71',
'URI::sip' => '1.71',
'URI::WithBase' => '2.20',
'URI::file' => '4.21',
'URI::_server' => '1.71',
'HTTP::Date' => '6.02',
'LWP' => '6.15',
'LWP::MediaTypes' => '6.02',
'HTTP::Request' => '6.11',
'File::Listing' => '6.04',
'HTTP::Negotiate' => '6.00',
'Net::HTTP' => '6.09',
'Net::HTTPS' => '6.09',
'Net::SSL' => '2.88',
'Net::LDAP::DSML' => '0.16',
'Net::LDAP' => '0.65',
'Net::LDAP::LDIF' => '0.26',
'Mail::Internet' => '2.13',
'HTML::HeadParser' => '3.71',
'HTTP::Config' => '6.11',
'HTTP::Request::Common' => '6.11',
'LWP::ConnCache' => '6.15',
'HTTP::Cookies' => '6.01',
'Encode::Locale' => '1.05',
'HTTP::Headers::Util' => '6.11',
'LWP::MemberMixin' => 'undef',
'Mail::IMAPClient::MessageSet' => 'undef',
'Digest::HMAC_MD5' => '1.01',
'Mail::Address' => '2.13',
'Mail::Header' => '2.13',
'Mail::Mailer' => '2.13',
'Mail::Util' => '2.13',
'Math::Random::ISAAC::PP' => '1.003',
'Math::Random::ISAAC::XS' => '1.004',
'Net::HTTP::Methods' => '6.09',
'Compress::Raw::Zlib' => '2.069',
'Net::LDAP::Bind' => '1.05',
'Net::LDAP::Extension' => '1.04',
'Net::LDAP::RootDSE' => '0.02',
'Net::LDAP::Search' => '0.14',
'Convert::ASN1::Debug' => '0.27',
'Convert::ASN1' => '0.27',
'Net::LDAP::Constant' => '0.23',
'Net::LDAP::ASN' => '0.12',
'Net::LDAP::Message' => '1.12',
'Net::LDAP::Filter' => '0.20',
'XML::SAX::Base' => '1.07',
'Net::LDAP::Schema' => '0.9908',
'Net::LDAP::Entry' => '0.27',
'Net::LDAP::Control' => '0.18',
'Net::LDAP::Util' => '0.19',
'Net::LDAP::Intermediate' => '0.04',
'Crypt::SSLeay::MainContext' => 'undef',
'Crypt::SSLeay' => '0.73_04',
'Test::Builder::IO::Scalar' => '2.113',
'UNIVERSAL::can' => '1.20140328',
'UNIVERSAL::isa' => '1.20150614',
'Test::Builder' => '1.001014',
'Test::Builder::Module' => '1.001014',
'Unicode::CharName' => '1.07',
'XML::SAX::Exception' => '1.07',
'CGI::Carp' => '4.26',
'Data::Uniqid' => '0.12',
'Digest::HMAC_SHA1' => '1.03',
'File::Copy::Recursive' => '0.38',
'IO::Tee' => '0.64',
'JSON::WebToken' => '0.10',
'JSON::WebToken::Crypt::RSA' => 'undef',
'Mail::IMAPClient' => '3.38',
'Readonly' => '2.00',
'Sys::MemInfo' => '0.98',
'Term::ReadKey' => '2.33',
'Test::MockObject' => '1.20150527',
'Test::More' => '1.001014',
'Unicode::String' => '2.09',
'CGI' => '4.26',
'Crypt::OpenSSL::RSA' => '0.28',
'LWP::Authen::Digest' => 'undef',
'LWP::Authen::Ntlm' => '6.15',
'LWP::Protocol::GHTTP' => 'undef',
'LWP::Protocol::cpan' => 'undef',
'LWP::Protocol::data' => 'undef',
'LWP::Protocol::file' => 'undef',
'LWP::Protocol::ftp' => 'undef',
'LWP::Protocol::gopher' => 'undef',
'LWP::Protocol::https' => '6.06',
'LWP::Protocol::ldapi' => 'undef',
'LWP::Protocol::ldaps' => 'undef',
'LWP::Protocol::loopback' => 'undef',
'LWP::Protocol::mailto' => 'undef',
'LWP::Protocol::nntp' => 'undef',
'LWP::UserAgent' => '6.15',
'LWP::Authen::Basic' => 'undef',
'URI::URL' => '5.04',
'URI::http' => '1.71',
'HTML::Entities' => '3.69',
'URI::Escape' => '3.31',
'LWP::Protocol::http' => 'undef',
'IO::Socket::SSL' => '2.047',
'JSON' => '2.90',
'JSON::XS::Boolean' => 'undef',
'JSON::XS' => '3.01',
'LWP::Protocol::ldap' => '1.25',
'LWP::Protocol::nogo' => 'undef',
'IO::Socket::INET6' => '2.72',

1
W/t/loadavg.out Normal file
View file

@ -0,0 +1 @@
0.39 0.30 0.37 1/602 6073

View file

@ -1,12 +1,26 @@
@REM $Id: test3.bat,v 1.24 2016/08/05 14:22:42 gilles Exp gilles $
@REM $Id: test3.bat,v 1.26 2017/07/08 00:11:24 gilles Exp gilles $
cd /D %~dp0
@REM \$1 must be $1 on Windows
@REM ==== password within double-quotes
perl ./imapsync --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi ^
--debugimap2 --debugcontent --folder INBOX --maxage 1
@ECHO ==== --justloadavg --justbanner
@REM perl .\imapsync --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi --justbanner
@REM perl -V
@REM perl -e "print 'zzz'"
@REM perl -c .\imapsync
@REM perl .\imapsync --version
@REM --testsdebug --debugdev
@REM perl .\imapsync --host1 imap.gmail.com --host2 ks2ipv6.lamiral.info --ssl1 --ssl2 --justconnect --debugimap
@REM perl .\imapsync --host1 test.lamiral.info --host2 ks2ipv6.lamiral.info --nossl1 --justconnect --debugimap
perl .\imapsync --host1 test.lamiral.info --user1 test1 --password1 secret1 --host2 p --user2 titi --passfile2 secret.titi --nossl1 --justlogin --debugimap
@EXIT

View file

@ -60,7 +60,7 @@ perl .\imapsync --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2
--prefix1 "" ^
--sep2 "\\" --prefix2 "" --regextrans2 "s,^Inbox\\(.*),$1,i" --justfolders --dry --debug --folder INBOX.yop.yap.yip
@REM ==== split lon lines
@ECHO ==== split long lines
perl ./imapsync ^
--host1 p --user1 tata ^
--passfile1 secret.tata ^
@ -68,6 +68,19 @@ perl ./imapsync ^
--passfile2 secret.titi ^
--nofoldersizes --folder "INBOX.longline" --regexmess "s,(.{9900}),$1\r\n,g" --dry --debugcontent
@ECHO ==== password within double-quotes via --passfile1
perl ./imapsync --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi ^
--debugimap2 --debugcontent --folder INBOX --maxage 1
@ECHO ==== \Seen set in case unset
perl ./imapsync --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 tata --passfile2 secret.tata ^
--nofoldersizes --no-modulesversion --folder INBOX.flagsetSeen --debugflags --dry --regexflag "s,^((?!\\Seen)).*$,$1 \\Seen,"
@ECHO ==== password double-quotes within via --password1
@REM perl ./imapsync --host1 p --user1 tata --password1 \"ami\\\"seen\" --host2 p --user2 titi --passfile2 secret.titi --debugimap1 --showpasswords --justlogin
perl ./imapsync --host1 p --user1 tata --password1 ami\\\"seen --host2 p --user2 titi --passfile2 secret.titi --debugimap1 --showpasswords --justlogin
@REM

View file

@ -1,5 +1,5 @@
@REM $Id: test3_gmail.bat,v 1.4 2016/08/19 14:11:00 gilles Exp gilles $
@REM $Id: test3_gmail.bat,v 1.5 2016/08/19 18:27:13 gilles Exp gilles $
cd /D %~dp0
@ -13,4 +13,4 @@ cd /D %~dp0
perl .\imapsync --host1 imap.gmail.com --ssl1 --user1 gilles.lamiral@gmail.com --passfile1 secret.gilles_gmail ^
--host2 p --user2 tata --passfile2 secret.tata ^
--regextrans2 "s,\[Gmail\].,," --dry --justfolders
--regextrans2 "s,\[Gmail\].,," --dry --justfolders

View file

@ -1,11 +1,16 @@
REM $Id: test_cook_exe.bat,v 1.1 2015/04/02 23:38:23 gilles Exp gilles $
REM $Id: test_cook_exe.bat,v 1.4 2017/09/07 00:59:35 gilles Exp gilles $
cd /D %~dp0
@REM EXIT
.\imapsync.exe
@PAUSE
.\imapsync.exe --tests
.\imapsync.exe --testslive
@PAUSE
.\imapsync.exe --testslive --nossl2
@PAUSE
.\imapsync.exe --testslive6 --nossl2
@ECHO The previous test fails with "Invalid argument" usually (August 2017)
@ECHO Tests ended, bye.
@PAUSE
@PAUSE
@REM EXIT

View file

@ -1,11 +1,15 @@
REM $Id: test_cook_src.bat,v 1.1 2015/04/02 23:38:16 gilles Exp gilles $
REM $Id: test_cook_src.bat,v 1.3 2017/09/07 00:59:26 gilles Exp gilles $
cd /D %~dp0
@REM EXIT
perl .\imapsync
@PAUSE
perl .\imapsync --tests
@PAUSE
perl .\imapsync --testslive
@PAUSE
perl .\imapsync --testslive6
@ECHO Tests for imapsync script are finished, bye!
@PAUSE

View file

@ -1,4 +1,4 @@
REM $Id: test_exe.bat,v 1.15 2016/08/19 14:09:56 gilles Exp gilles $
REM $Id: test_exe.bat,v 1.19 2017/08/31 01:57:33 gilles Exp gilles $
@SETLOCAL
@ECHO OFF
@ -6,12 +6,14 @@ ECHO Currently running through %0 %*
cd /D %~dp0
REM Remove the error file because its existence means an error occured during this script execution
@REM Remove the error file because its existence means an error occured during this script execution
IF EXIST LOG_bat\%~nx0.txt DEL LOG_bat\%~nx0.txt
REM CALL :handle_error .\imapsync.exe --thisoptionnoexists
CALL :handle_error perl imapsync --tests
@REM CALL :handle_error .\imapsync.exe --thisoptionnoexists
@REM CALL :handle_error perl imapsync --tests
CALL :handle_error .\imapsync.exe --tests
CALL :handle_error .\imapsync.exe --testslive
CALL :handle_error .\imapsync.exe --testslive --nossl2
@REM CALL :handle_error .\imapsync.exe --testslive6 --nossl2
EXIT /B
@ECHO ==== All 8 combinaisons between ssl1/tls1 ssl2/tls2 justconnect/justlogin

36
W/test_exe_tests.bat Normal file
View file

@ -0,0 +1,36 @@
@REM $Id: test_exe_tests.bat,v 1.2 2017/05/02 08:43:02 gilles Exp gilles $
@SETLOCAL
@ECHO OFF
ECHO Currently running through %0 %*
CD /D %~dp0
REM Remove the error file because its existence means an error occured during this script execution
IF EXIST LOG_bat\%~nx0.txt DEL LOG_bat\%~nx0.txt
REM CALL :handle_error .\imapsync.exe --testsunit tests_always_fail
CALL :handle_error .\imapsync.exe --tests
@REM @PAUSE
@ENDLOCAL
@EXIT /B
:handle_error
SETLOCAL
ECHO IN %0 with parameters %*
%*
SET CMD_RETURN=%ERRORLEVEL%
IF %CMD_RETURN% EQU 0 (
ECHO GOOD END
) ELSE (
ECHO BAD END
IF NOT EXIST LOG_bat MKDIR LOG_bat
ECHO Failure running %* >> LOG_bat\%~nx0.txt
)
ENDLOCAL
EXIT /B

View file

@ -1,14 +1,22 @@
REM $Id: test_reg.bat,v 1.3 2015/05/11 01:08:05 gilles Exp gilles $
REM $Id: test_reg.bat,v 1.4 2016/09/28 03:41:38 gilles Exp gilles $
cd /D %~dp0
perl ./imapsync --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi ^
--justfolders --dry --nofoldersizes ^
--regextrans2 "s/\./_/g"
perl ./imapsync --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi ^
--justfolders --folder INBOX --dry ^
--regextrans2 "s,(/|^) +,$1,g" ^
--regextrans2 "s, +(/|$),$1,g" ^
--regextrans2 "s/[\^]/_/g" ^
--regextrans2 "s/['\\]/_/g" ^
--regextrans2 "s,^&AC8-,-,g" ^
--regextrans2 "s,^&APg-,oe,g"
@REM --regextrans2 "s/\./_/g"
@REM --regextrans2 "s,${h2_prefix}(.*),${h2_prefix}old_mail${h2_sep}$1," ^
@REM --regextrans2 "s,^INBOX$,${h2_prefix}old_mail${h2_sep}INBOX,"
@REM --regextrans2 "s,(.*),old_mail/$1,"

View file

@ -1,4 +1,4 @@
@REM $Id: test_testsdebug.bat,v 1.1 2016/08/19 08:20:53 gilles Exp gilles $
@REM $Id: test_testsdebug.bat,v 1.3 2017/07/08 00:02:13 gilles Exp gilles $
@SETLOCAL
@ECHO OFF
@ -11,7 +11,7 @@ REM Remove the error file because its existence means an error occured during th
IF EXIST LOG_bat\%~nx0.txt DEL LOG_bat\%~nx0.txt
@REM CALL :handle_error perl .\imapsync --justbanner
CALL :handle_error perl .\imapsync --testsdebug
CALL :handle_error perl .\imapsync --testsdebug --debug
@REM CALL :handle_error perl .\imapsync --tests
@REM @PAUSE

183
W/tools/IMAPSyncInputs.bat Executable file
View file

@ -0,0 +1,183 @@
@echo off
@REM Written by Liam Patrick <liam.patrick@flonix.co.uk>
@REM imapsync example batch for Windows users
@REM lines beginning with @REM are just comments
@REM Double quotes are necessary if a value contain one or more blanks.
@REM value for --host1 is the IMAP source server hostname or IP address
@REM value for --user1 is the IMAP source user login
@REM value for --password1 is the IMAP source user password
@REM value for --host2 is the IMAP destination server hostname or IP address
@REM value for --user2 is the IMAP destination user login
@REM value for --password2 is the IMAP destination user password
@REM Character ^ at the end of the first line is essential and means
@REM "this command continues on the next line". You can add other lines
@REM but don't forget ^ character lasting each line, except the last one.
@REM ------------------------------------------------------------------------------------
:start
echo.
echo This will run IMAPSync letting you Migrate mail to another account on
echo another server.
echo.
echo The information to be entered is as follows.
echo.
echo -Host1 -User1 -Password1 -require ssl for 1?
echo -Host2 -User2 -Password2 -require ssl for 2?
echo.
pause
:vari1
cls
echo ---------------------------------------------
echo.
SET /P ANSWER= enter host1?
echo.
SET HOST1=%ANSWER%
SET /P ANSWER= enter user1?
echo.
SET USER1=%ANSWER%
SET /P ANSWER= enter password1?
echo.
SET PASS1=%ANSWER%
:ssl1
SET /P ANSWER= enable ssl1? (y/n)
echo.
if /i {%ANSWER%}=={y} (goto :ssl11)
if /i {%ANSWER%}=={n} (goto :ssl12)
(goto :ssl1)
:ssl11
SET SSL1=-ssl1
echo ssl Enabled
echo.
(goto :ask1)
:ssl12
SET SSL1=
echo ssl Disabled
echo.
(goto :ask1)
:ask1
cls
SET /P ANSWER= Check " %HOST1% %USER1% %PASS1% %SSL1% " Correct details? (y/n)
if /i {%ANSWER%}=={y} (goto :vari2)
if /i {%ANSWER%}=={n} (goto :vari1)
(goto :ask1)
@REM --------------------------------------------------------------------------------------
:vari2
cls
echo ---------------------------------------------
echo.
SET /P ANSWER= enter host2?
echo.
SET HOST2=%ANSWER%
SET /P ANSWER= enter user2?
echo.
SET USER2=%ANSWER%
SET /P ANSWER= enter password2?
echo.
SET PASS2=%ANSWER%
:ssl2
SET /P ANSWER= enable ssl2? (y/n)
echo.
if /i {%ANSWER%}=={y} (goto :ssl21)
if /i {%ANSWER%}=={n} (goto :ssl22)
(goto :ssl2)
:ssl21
SET SSL2=-ssl2
echo ssl Enabled
echo.
(goto :ask2)
:ssl22
SET SSL2=
echo ssl Disabled
echo.
(goto :ask2)
:ask2
cls
SET /P ANSWER= Check " -%HOST2% -%USER2% -%PASS2% %SSL2% " Correct details? (y/n)
if /i {%ANSWER%}=={y} (goto :run)
if /i {%ANSWER%}=={n} (goto :vari2)
(goto :ask2)
@REM ------------------------------------------------------------------------------------
:run
cls
echo ---------------------------------------------------------------------------
echo.
echo Now that all the data has been entered we will run IMAPSync
echo.
echo This is the final step. Please read the information carefully
echo to avoid issues with migration.
echo.
echo If any of the details are incorrect please exit and re-enter your
echo details to run correctly
echo.
echo the following is what will be saved to a file which can later be run or edited
echo.
echo .\imapsync.exe --host1 %HOST1% --user1 %USER1% --password1 "%PASS1%"
echo --host2 %HOST2% --user2 %USER2% --password2 "%PASS2%" %SSL1% %SSL2%
echo.
echo To exit without running, please enter n. to Save settings to a file, please enter s
echo.
SET /P ANSWER= (n/s)
if /i {%ANSWER%}=={n} (goto :end)
if /i {%ANSWER%}=={s} (goto :savefinal)
(goto :run)
:runfinal
.\imapsync.exe --host1 %HOST1% --user1 %USER1% --password1 "%PASS1%" ^
--host2 %HOST2% --user2 %USER2% --password2 "%PASS2%" %SSL1% %SSL2% --regextrans2 "s/\\/./g" --maxsize 250000000 --maxlinelength 9900
(goto :end)
:savefinal
@echo .\imapsync.exe --host1 %HOST1% --user1 %USER1% --password1 "%PASS1%" ^
--host2 %HOST2% --user2 %USER2% --password2 "%PASS2%" %SSL1% %SSL2% --regextrans2 "s/\\/./g" --maxsize 250000000 --maxlinelength 9900 > ".\%USER1%.bat"
echo.
echo File Saved in .\%USER1%.bat
echo.
(goto :end)
:end
echo.
@PAUSE

32
W/tools/backup_old_dist Executable file
View file

@ -0,0 +1,32 @@
#!/bin/sh
# $Id: backup_old_dist,v 1.3 2017/09/11 03:04:20 gilles Exp gilles $
# Bye on any error not handled
set -e
! test -f dist/imapsync && return
version_previous=`dist/imapsync --version || echo ERROR`
echo "previous: [$version_previous]"
test "ERROR" != "$version_previous" || return 1
version_current=`cat VERSION || echo ERROR`
test "ERROR" != "$version_current" || return 1
echo "current: [$version_current]"
# nothing to backup
test "$version_previous" = "$version_current" && return 0
test -d dist/old_releases/$version_previous || mkdir dist/old_releases/$version_previous && ( cd dist/old_releases/$version_previous )
pwd
# all or nothing
ls -ld dist/imapsync dist/imapsync-$version_previous.tgz dist/imapsync_$version_previous.zip || return 1
# let's do it
mv -vf dist/imapsync dist/imapsync_bin_Darwin dist/imapsync-$version_previous.tgz dist/imapsync_$version_previous.zip dist/old_releases/$version_previous

275
W/tools/fix_email_for_exchange.py Executable file
View file

@ -0,0 +1,275 @@
#!/usr/bin/python
#
# $Cambridge: hermes/src/2exchange/scripts/fix_email_for_exchange.py,v 1.20 2017/01/25 18:33:48 dpc22 Exp $
#
# Convert message into form that Exchange Online will accept.
#
# This is a combination of lossless conversions (for example recoding text
# attachments with long lines) and more aggresive conversions which remove
# headers and attachments which Exchange Online cannot accept because of
# hard limits listed on:
#
# https://technet.microsoft.com/en-GB/library/exchange-online-limits.aspx
MAX_MSG_SIZE = 35*1024*1024
MAX_LINE_LENGTH = 996
MAX_ATTACHMENTS = 250 # Across the entire message
MAX_SUBPARTS = 250 # In single multipart.
MAX_FILENAME = 255 # for attachments
MAX_DEPTH = 30 # Nested multipart
NUKE_8BIT = True
NUKE_HDRS = [
# (hdr, max_lines, max_items, max_bytes). (-1 => unlimited).
("References", 485, 485, 40000),
("Subject", -1, -1, 255),
]
FORCE_REWRITE = False
import sys
import binascii
from email.parser import Parser
from email.generator import Generator
from email import utils
from cStringIO import StringIO
# NB: utils._qencode() replaces ALL ' ' with '=20', as required by QP
# header strings. We only need to encode trailing whitespace in message
# body. quopri.encodestring (used by utils._qencode()) does this already.
from quopri import encodestring as qp_encode
fp = open(sys.argv[1], "rb") if len(sys.argv) > 1 else sys.stdin
msg_text_crnl = fp.read(); fp.close()
msg_text_nl = msg_text_crnl.replace("\r\n", "\n")
# We want to preserve CRLF and any leading "From" from source message
CRLF = "\r\n" if (len(msg_text_nl) < len(msg_text_crnl)) else "\n"
UNIXFROM = msg_text_nl.startswith("From ")
def max_line_len(str):
return(max([len(i) for i in str.split('\n')]))
def count_attachments(part):
if part.is_multipart():
count = 0 # multipart wrapper doesn't count as attachment itself?
for subpart in part.get_payload():
count += count_attachments(subpart)
else:
count = 1
return count
def find_depth(part):
max_depth = 0
if part.is_multipart():
for subpart in part.get_payload():
depth = find_depth(subpart)
if depth > max_depth:
max_depth = depth
return max_depth + 1
# Replace complex bodypart with simple text/plain explanation
def nuke_part(part, print_stderr, text):
for hdr in ['Content-Transfer-Encoding', 'Content-Disposition']:
if part.has_key(hdr):
del part[hdr]
if part.has_key('Content-Type'):
part.replace_header('Content-Type', 'text/plain')
part.add_header('X-Mime-Autoconverted', text)
part.set_payload(text)
if print_stderr:
sys.stderr.write("FIXUP NEXT: " + text + "\n")
def rewrite(part, drop_all_multipart_err):
need_rewrite = False
if (part.preamble and max_line_len(part.preamble) > MAX_LINE_LENGTH):
part.preamble = "\n"
sys.stderr.write("FIXUP NEXT: Removed over-long MIME preamble\n")
need_rewrite = True
if (part.epilogue and max_line_len(part.epilogue) > MAX_LINE_LENGTH):
part.epilogue = "\n"
sys.stderr.write("FIXUP NEXT: Removed over-long MIME epilogue\n")
need_rewrite = True
for hdr in part.values():
if max_line_len(hdr) > MAX_LINE_LENGTH:
need_rewrite = True # Force MIME rewrite if we have long headers
sys.stderr.write("FIXUP NEXT: Rewrite forced by long header line\n")
for hdr, max_lines, max_items, max_bytes in NUKE_HDRS:
(hdr, val) = (hdr.lower(), part.get(hdr))
if (val and ((max_lines >= 0 and len(val.split('\n')) > max_lines) or
(max_items >= 0 and len(val.split()) > max_items) or
(max_bytes >= 0 and len(val) > max_bytes))):
del part[hdr]
sys.stderr.write("FIXUP NEXT: Removed long header line: "+hdr+"\n")
need_rewrite = True
# Exchange Online can't cope with very long component in address list
for hdr in ['To', 'Cc', 'Bcc']:
val = part.get(hdr, "")
for addr in val.split(','): # Need better parsing here!
if len(addr) > 1950:
part['X-Broken-' + hdr] = val
del part[hdr]
sys.stderr.write("FIXUP NEXT: Renamed broken " + hdr +
" to X-Broken-" + hdr + "\n")
need_rewrite = True
ct = part.get_content_type()
max_name_len = 0
params = part.get_params()
if params:
for (key,value) in part.get_params():
if key in ['name', 'filename']:
if len(value) > max_name_len:
max_name_len = len(value)
if max_name_len > MAX_FILENAME:
need_rewrite = True
part_count=len(part.get_payload())
part_str = ('Removed ' + ct +
' with long filename (' + str(max_name_len) +
' characters) which chokes Exchange Online')
nuke_part(part, 1, part_str)
return need_rewrite
if part.is_multipart():
if (drop_all_multipart_err):
need_rewrite = True
part_count=len(part.get_payload())
part_str = drop_all_multipart_err
nuke_part(part, 0, part_str)
elif (len(part.get_payload()) > MAX_SUBPARTS):
need_rewrite = True
part_count=len(part.get_payload())
part_str = ('Removed ' + ct +
' with ' + str(part_count) +
' subparts/attachments which chokes Exchange Online')
nuke_part(part, 1, part_str)
elif ct in ['multipart/appledouble']:
need_rewrite = True
part_str = ('Removed ' + ct +
' which chokes Exchange Online')
nuke_part(part, 1, part_str)
else:
for subpart in part.get_payload():
if rewrite(subpart, drop_all_multipart_err):
need_rewrite = True
return need_rewrite
payload = part.get_payload()
max_line_length = max_line_len(payload)
cte = part.get('content-transfer-encoding', '').lower().strip()
if cte in ['8bit', '7bit', 'binary', '']:
# Encode unencoded forms which contain 8bit characters or long lines
update_cte = part.replace_header if (cte != '') else part.add_header
nonascii_count = [(ord(c) >= 128) for c in payload].count(True)
if ((NUKE_8BIT and nonascii_count > 0) or
max_line_length > MAX_LINE_LENGTH):
if nonascii_count < 100:
part.set_payload(qp_encode(payload))
update_cte('Content-Transfer-Encoding', "quoted-printable")
else:
part.set_payload(utils._bencode(payload))
update_cte('Content-Transfer-Encoding', "base64")
need_rewrite = True
elif (cte in ['quoted-printable', 'base64']):
decode_error = False
try:
if cte == 'quoted-printable':
raw=utils._qdecode(payload)
else:
raw=utils._bdecode(payload)
if (len(payload) > 100) and (len(raw) < len(payload)/10):
raise binascii.Error
except binascii.Error:
decode_error = True
if decode_error:
# Discard broken attachment which would no decode
need_rewrite = True
part_str = ('Removed ' + ct +
' with broken attachment which failed to decode')
nuke_part(part, 1, part_str)
elif max_line_length > MAX_LINE_LENGTH:
sys.stderr.write("FIXUP NEXT: Recoded " +
(cte or "none") + " attachment [Long lines]\n")
# Recode quoted-printable or base64 with long lines
need_rewrite = True
if cte == 'quoted-printable':
part.set_payload(qp_encode(raw))
else:
part.set_payload(utils._bencode(raw))
newcte = part.get('content-transfer-encoding', '').lower().strip()
if (newcte and (newcte != cte)):
part.add_header('X-Mime-Autoconverted',
"from " + (cte or "none") + " to " + newcte)
if max_line_length > MAX_LINE_LENGTH:
sys.stderr.write("FIXUP NEXT: Attachment converted " +
"from " + (cte or "none") + " to " + newcte +
" [Long lines]\n")
else:
sys.stderr.write("FIXUP NEXT: Attachment converted " +
"from " + (cte or "none") + " to " + newcte +
" [Raw Binary data]\n")
return need_rewrite
msg=Parser().parsestr(msg_text_nl)
msg_size = len(msg_text_nl)
msg_depth = find_depth(msg)
attachments_count = count_attachments(msg)
if msg_size > MAX_MSG_SIZE:
err= ("message is too large for" +
" Exchange Online (" + str(msg_size / (1024*1024)) + " Mbytes)")
need_rewrite=rewrite(msg, err)
if need_rewrite:
sys.stderr.write("FIXUP NEXT: " + err + "\n")
elif msg_depth > MAX_DEPTH:
err=("Removed multipart message with " + str(msg_depth) +
" nested messages which chokes Exchange Online")
need_rewrite=rewrite(msg, err)
if need_rewrite:
sys.stderr.write("FIXUP NEXT: " + err + "\n")
elif attachments_count > MAX_SUBPARTS:
err=("Removed multipart message with " + str(attachments_count) +
" attachments which chokes Exchange Online")
need_rewrite=rewrite(msg, err)
if need_rewrite:
sys.stderr.write("FIXUP NEXT: " + err + "\n")
else:
need_rewrite=rewrite(msg, '')
if not need_rewrite and not FORCE_REWRITE:
sys.stdout.write(msg_text_crnl)
sys.exit(0)
if need_rewrite:
# Log message headers if structure has changed
for hdr in ['Message-Id', 'From', 'Subject', 'Date']:
if msg.get(hdr):
sys.stderr.write(" " + hdr + ": " + msg.get(hdr) + "\n")
buffer = StringIO()
gen=Generator(buffer, mangle_from_=False, maxheaderlen=MAX_LINE_LENGTH)
gen.flatten(msg, unixfrom=UNIXFROM)
buffer.seek(0)
for line in buffer.readlines():
sys.stdout.write(line.rstrip('\n')); sys.stdout.write(CRLF)
buffer.close()
sys.exit(0)

View file

@ -1,107 +0,0 @@
#!/usr/bin/python
NUKE_HDRS = [
# (hdr, max_lines, max_items, max_bytes). (-1 => unlimited).
("References", 485, 485, 40000),
]
MAX_LINE_LENGTH = 996
NUKE_8BIT = True
FORCE_REWRITE = False
import sys
from email.parser import Parser
from email.generator import Generator
from email import utils
from cStringIO import StringIO
# NB: utils._qencode() replaces ALL ' ' with '=20', as required by QP
# header strings. We only need to encode trailing whitespace in message
# body. quopri.encodestring (used by utils._qencode()) does this already.
from quopri import encodestring as qp_encode
fp = open(sys.argv[1], "rb") if len(sys.argv) > 1 else sys.stdin
msg_text_crnl = fp.read(); fp.close()
msg_text_nl = msg_text_crnl.replace("\r\n", "\n")
# We want to preserve CRLF and any leading "From" from source message
CRLF = "\r\n" if (len(msg_text_nl) < len(msg_text_crnl)) else "\n"
UNIXFROM = msg_text_nl.startswith("From ")
def rewrite(part):
need_rewrite = False
for hdr in part.values():
if max([len(i) for i in hdr.split('\n')]) > MAX_LINE_LENGTH:
need_rewrite = True # Force MIME rewrite if we have long headers
sys.stderr.write("FIXUP NEXT: Rewrite forced by long header line\n")
for hdr, max_lines, max_items, max_bytes in NUKE_HDRS:
(hdr, val) = (hdr.lower(), msg.get(hdr))
if (val and ((max_lines >= 0 and len(val.split('\n')) > max_lines) or
(max_items >= 0 and len(val.split()) > max_items) or
(max_bytes >= 0 and len(val) > max_bytes))):
del msg[hdr]
sys.stderr.write("FIXUP NEXT: Removed long header line: "+hdr+"\n")
need_rewrite = True
if part.is_multipart():
for subpart in part.get_payload():
if rewrite(subpart):
need_rewrite = True
return need_rewrite
payload = part.get_payload()
max_line_length = max([ len(i) for i in payload.split('\n') ])
cte = part.get('content-transfer-encoding', '').lower().strip()
if cte in ['8bit', '7bit', 'binary', '']:
# Encode unencoded forms which contain 8bit characters or long lines
update_cte = part.replace_header if (cte != '') else part.add_header
nonascii_count = [(ord(c) >= 128) for c in payload].count(True)
if ((NUKE_8BIT and nonascii_count > 0) or
max_line_length > MAX_LINE_LENGTH):
if nonascii_count < 100:
part.set_payload(qp_encode(payload))
update_cte('Content-Transfer-Encoding', "quoted-printable")
else:
part.set_payload(utils._bencode(payload))
update_cte('Content-Transfer-Encoding', "base64")
need_rewrite = True
elif cte in ['quoted-printable', 'base64']:
# Recode quoted-printable or base64 with long lines
if max_line_length > MAX_LINE_LENGTH:
if cte == 'quoted-printable':
raw=utils._qdecode(payload)
part.set_payload(qp_encode(raw))
need_rewrite = True
elif cte == 'base64':
try:
raw=utils._bdecode(payload)
part.set_payload(utils._bencode(raw))
need_rewrite = True
except binascii.Error:
pass
newcte = part.get('content-transfer-encoding', '').lower().strip()
if (newcte != cte):
part.add_header('X-Mime-Autoconverted',
"from " + (cte or "none") + " to " + newcte)
sys.stderr.write("FIXUP NEXT: Attachment converted " +
"from " + (cte or "none") + " to " + newcte + "\n")
return need_rewrite
msg=Parser().parsestr(msg_text_nl)
if not rewrite(msg) and not FORCE_REWRITE:
sys.stdout.write(msg_text_crnl)
sys.exit(0)
buffer = StringIO()
gen=Generator(buffer, mangle_from_=False, maxheaderlen=MAX_LINE_LENGTH)
gen.flatten(msg, unixfrom=UNIXFROM)
buffer.seek(0)
for line in buffer.readlines():
sys.stdout.write(line.rstrip('\n')); sys.stdout.write(CRLF)
buffer.close()
sys.exit(0)

View file

@ -1,6 +1,6 @@
#!/bin/sh
# $Id: gen_README_dist,v 1.1 2014/05/29 23:33:19 gilles Exp gilles $
# $Id: gen_README_dist,v 1.2 2017/09/11 02:19:34 gilles Exp gilles $
VERSION_UNX=`cat VERSION`
#echo $VERSION_UNX
@ -9,11 +9,18 @@ VERSION_EXE=`cat VERSION_EXE`
cat <<EOF
imapsync-$VERSION_EXE.zip is for Windows users.
The file "imapsync-$VERSION_EXE.zip" is for Windows users.
imapsync-$VERSION_UNX.tgz is for Unix and Mac users.
The file "imapsync-$VERSION_UNX.tgz" is for Unix and OS X users, it contains the source
code and also the standalone OS X binary named "imapsync_bin_Darwin".
The binary "imapsync_bin_Darwin" is for OS X users, as a shortcut for a fast upgrade.
The file "imapsync" is the source code perl script, it is there just for a fast
upgrade on Unix, just download and replace the old one with this one.
Sometimes new Perl modules need to be installed, see
https://imapsync.lamiral.info/S/news.shtml
imapsync file script is for a fast upgrade on Unix (just download and install it).
EOF

View file

@ -158,6 +158,7 @@ while (status == 302 or status == 301 or status == 307) and redirectCount < 10:
connection = httplib.HTTPConnection(parsed[1])
connection.connect()
connection.putrequest("POST", "%s?%s" % (parsed[2], parsed[3]), skip_accept_encoding=1)
connection.putheader("User-Agent", 'html5check.py/2008-02-12')
connection.putheader("Accept-Encoding", 'gzip')
connection.putheader("Content-Type", contentType)
connection.putheader("Content-Encoding", 'gzip')

746
W/tools/validate Executable file
View file

@ -0,0 +1,746 @@
#!/usr/bin/perl -T
# See http://www.htmlhelp.com/tools/validator/offline/
#####################################################################
#
# Offline HTMLHelp.com Validator
# by Liam Quinn <liam@htmlhelp.com>
#
# This is a simplified version of the online WDG HTML Validator
# found at <http://www.htmlhelp.com/tools/validator/>.
#
# Copyright (c) 1998-2010 by Liam Quinn
# This program is free software; you can redistribute it
# and/or modify it under the same terms as Perl itself.
#
# Contributors:
# * Ville Skytta
# * John Goebel
#
#####################################################################
#####################################################################
# Required libraries #
######################
# These are all standard Perl modules; we'll check for URI and LWP
# later on demand.
use strict;
use Getopt::Long qw(GetOptions);
use Text::Wrap qw(wrap);
use POSIX qw(:fcntl_h);
# If File::Spec::Functions isn't available, let's fall back quietly
# to a replacement function.
eval {
require File::Spec::Functions;
File::Spec::Functions->import('catfile');
};
*catfile = sub { join('/', @_) } if $@;
#####################################################################
#####################################################################
# Variables to define #
#######################
# Version and identifier of this program
my $VERSION = '1.2.3';
my $progname = "Offline HTMLHelp.com Validator, Version $VERSION
by Liam Quinn <liam\@htmlhelp.com>";
my $usage = "Usage: validate [OPTION] [FILE...]";
# SGML directory (catalog, DTDs, SGML declarations)
my $sgmlDir = '/usr/local/share/wdg/sgml-lib';
# Location of lq-nsgmls executable
my $nsgmlsLocation = '/usr/bin/nsgmls';
# lq-nsgmls command line
# The SGML declaration and HTML document's filename will be appended
# to this string
my $nsgmls = "$nsgmlsLocation -E0 -s";
# Warnings to pass on command-line to lq-nsgmls, if desired
my $nsgmlsWarnings = '-wnon-sgml-char-ref -wmin-tag';
my $nsgmlsXMLWarnings = '-wxml';
# lq-nsgmls "errors" that are not reported unless warnings are requested.
# These are true errors in XML validation, but they should only be
# reported as warnings otherwise.
my %errorAsWarning = (
' net-enabling start-tag not supported in {{XML}}' => 1,
' unclosed start-tag' => 1,
' unclosed end-tag' => 1
);
# Catalog files for HTML/SGML and XHTML/XML
my $htmlCatalog = catfile($sgmlDir, 'catalog');
my $xhtmlCatalog = catfile($sgmlDir, 'xhtml.soc');
# Where to direct errors (typically *STDOUT or *STDERR)
my $errout = *STDOUT;
# Versions of HTML associated with a given FPI
my %HTMLversion = (
'PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN"' => 'XHTML-MP 1.2',
'PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.1//EN"' => 'XHTML-MP 1.1',
'PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN"' => 'XHTML-MP 1.0',
'PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN"' => 'XHTML+RDFa 1.0',
'PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"' => 'XHTML 1.1 plus MathML 2.0 plus SVG 1.1',
'PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN"' => 'XHTML 1.1 plus MathML 2.0',
'PUBLIC "-//W3C//DTD MathML 2.0//EN"' => 'MathML 2.0',
'PUBLIC "-//W3C//DTD XHTML 1.1//EN"' => 'XHTML 1.1',
'PUBLIC "-//WAPFORUM//DTD WML 1.3//EN"' => 'WML 1.3',
'PUBLIC "-//WAPFORUM//DTD WML 1.2//EN"' => 'WML 1.2',
'PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"' => 'WML 1.1',
'PUBLIC "-//WAPFORUM//DTD WML 1.0//EN"' => 'WML 1.0',
'PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN"' => 'XHTML Basic',
'PUBLIC "ISO/IEC 15445:2000//DTD HyperText Markup Language//EN"' => 'ISO/IEC 15445:2000',
'PUBLIC "ISO/IEC 15445:2000//DTD HTML//EN"' => 'ISO/IEC 15445:2000',
'PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"' => 'XHTML 1.0 Strict',
'PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' => 'XHTML 1.0 Transitional',
'PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"' => 'XHTML 1.0 Frameset',
'PUBLIC "-//W3C//DTD HTML 4.01//EN"' => 'HTML 4.01 Strict',
'PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"' => 'HTML 4.01 Transitional',
'PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"' => 'HTML 4.01 Frameset',
'PUBLIC "-//W3C//DTD HTML 4.0//EN"' => 'HTML 4.0 Strict',
'PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"' => 'HTML 4.0 Transitional',
'PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN"' => 'HTML 4.0 Frameset',
'PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"' => 'HTML 3.2',
'PUBLIC "-//W3C//DTD HTML 3.2 Draft//EN"' => 'HTML 3.2',
'PUBLIC "-//W3C//DTD HTML 3.2//EN"' => 'HTML 3.2',
'PUBLIC "-//W3C//DTD HTML Experimental 970421//EN"' => 'HTML 3.2 + Style',
'PUBLIC "-//W3O//DTD W3 HTML 3.0//EN"' => 'HTML 3.0 Draft',
'PUBLIC "-//IETF//DTD HTML 3.0//EN//"' => 'HTML 3.0 Draft',
'PUBLIC "-//IETF//DTD HTML 3.0//EN"' => 'HTML 3.0 Draft',
'PUBLIC "-//IETF//DTD HTML i18n//EN"' => 'HTML 2.0 + i18n',
'PUBLIC "-//IETF//DTD HTML//EN"' => 'HTML 2.0',
'PUBLIC "-//IETF//DTD HTML 2.0//EN"' => 'HTML 2.0',
'PUBLIC "-//IETF//DTD HTML Level 2//EN"' => 'HTML 2.0',
'PUBLIC "-//IETF//DTD HTML 2.0 Level 2//EN"' => 'HTML 2.0',
'PUBLIC "-//IETF//DTD HTML Level 1//EN"' => 'HTML 2.0 Level 1',
'PUBLIC "-//IETF//DTD HTML 2.0 Level 1//EN"' => 'HTML 2.0 Level 1',
'PUBLIC "-//IETF//DTD HTML Strict//EN"' => 'HTML 2.0 Strict',
'PUBLIC "-//IETF//DTD HTML 2.0 Strict//EN"' => 'HTML 2.0 Strict',
'PUBLIC "-//IETF//DTD HTML Strict Level 2//EN"' => 'HTML 2.0 Strict',
'PUBLIC "-//IETF//DTD HTML 2.0 Strict Level 2//EN"' => 'HTML 2.0 Strict',
'PUBLIC "-//IETF//DTD HTML Strict Level 1//EN"' => 'HTML 2.0 Strict Level 1',
'PUBLIC "-//IETF//DTD HTML 2.0 Strict Level 1//EN"' => 'HTML 2.0 Strict Level 1'
);
# SGML declarations for a given level of HTML
my %sgmlDecl = (
'XHTML-MP 1.2' => catfile($sgmlDir, 'xhtml-basic10','xml1.dcl'),
'XHTML-MP 1.1' => catfile($sgmlDir, 'xhtml-basic10','xml1.dcl'),
'XHTML-MP 1.0' => catfile($sgmlDir, 'xhtml-basic10','xml1.dcl'),
'XHTML+RDFa 1.0' => catfile($sgmlDir, 'xhtml11', 'xml1n.dcl'),
'XHTML 1.1 plus MathML 2.0 plus SVG 1.1' => catfile($sgmlDir, 'xhtml11', 'xml1n.dcl'),
'XHTML 1.1 plus MathML 2.0' => catfile($sgmlDir, 'xhtml11', 'xml1n.dcl'),
'MathML 2.0' => catfile($sgmlDir, 'xhtml11', 'xml1n.dcl'),
'XHTML 1.1' => catfile($sgmlDir, 'xhtml11', 'xml1n.dcl'),
'WML 1.3' => catfile($sgmlDir, 'xhtml1', 'xhtml1.dcl'),
'WML 1.2' => catfile($sgmlDir, 'xhtml1', 'xhtml1.dcl'),
'WML 1.1' => catfile($sgmlDir, 'xhtml1', 'xhtml1.dcl'),
'WML 1.0' => catfile($sgmlDir, 'xhtml1', 'xhtml1.dcl'),
'XHTML Basic' => catfile($sgmlDir, 'xhtml-basic10','xml1.dcl'),
'ISO/IEC 15445:2000' => catfile($sgmlDir, '15445.dcl'),
'XHTML 1.0 Strict' => catfile($sgmlDir ,'xhtml1', 'xhtml1.dcl'),
'XHTML 1.0 Transitional' => catfile($sgmlDir, 'xhtml1', 'xhtml1.dcl'),
'XHTML 1.0 Frameset' => catfile($sgmlDir, 'xhtml1', 'xhtml1.dcl'),
'HTML 4.01 Strict' => catfile($sgmlDir, 'HTML4.dcl'),
'HTML 4.01 Transitional' => catfile($sgmlDir, 'HTML4.dcl'),
'HTML 4.01 Frameset' => catfile($sgmlDir, 'HTML4.dcl'),
'HTML 4.0 Strict' => catfile($sgmlDir, 'HTML4.dcl'),
'HTML 4.0 Transitional' => catfile($sgmlDir, 'HTML4.dcl'),
'HTML 4.0 Frameset' => catfile($sgmlDir, 'HTML4.dcl'),
'HTML 3.2' => catfile($sgmlDir, 'HTML32.dcl'),
'HTML 3.2 + Style' => catfile($sgmlDir, 'html-970421.decl'),
'HTML 3.0 Draft' => catfile($sgmlDir, 'HTML3.dcl'),
'HTML 2.0 + i18n' => catfile($sgmlDir, 'i18n.dcl'),
'HTML 2.0' => catfile($sgmlDir, 'html.dcl'),
'HTML 2.0 Strict' => catfile($sgmlDir, 'html.dcl'),
'HTML 2.0 Level 1' => catfile($sgmlDir, 'html.dcl'),
'HTML 2.0 Strict Level 1' => catfile($sgmlDir, 'html.dcl'),
'Unknown' => catfile($sgmlDir, 'custom.dcl'),
# For generic XML validation (using the --xml option)
'XML' => catfile($sgmlDir, 'xhtml1', 'xhtml1.dcl'),
);
# XHTML DTDs
my %xhtml = (
'XHTML-MP 1.2' => 1,
'XHTML-MP 1.1' => 1,
'XHTML-MP 1.0' => 1,
'XHTML+RDFa 1.0' => 1,
'XHTML 1.1 plus MathML 2.0 plus SVG 1.1' => 1,
'XHTML 1.1 plus MathML 2.0' => 1,
'MathML 2.0' => 1,
'XHTML 1.1' => 1,
'WML 1.3' => 1,
'WML 1.2' => 1,
'WML 1.1' => 1,
'WML 1.0' => 1,
'XHTML Basic' => 1,
'XHTML 1.0 Strict' => 1,
'XHTML 1.0 Transitional' => 1,
'XHTML 1.0 Frameset' => 1,
'XML' => 1,
);
# Default DOCTYPE if the document is missing a DOCTYPE
my $defaultDoctype = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">';
# Default DOCTYPE if the document contains frames
my $defaultFramesetDoctype = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd">';
# Error for missing DOCTYPE
my $noDoctype = "missing document type declaration; assuming HTML 4.01 Transitional";
# Error for missing DOCTYPE in a Frameset document
my $noFramesetDoctype = "missing document type declaration; assuming HTML 4.01 Frameset";
#####################################################################
#####################################################################
#
# The rest of the script...
#
#####################################################################
# Get rid of unsafe environment variables, see perlsec
delete(@ENV{qw(PATH IFS CDPATH ENV BASH_ENV)});
# Flush output buffer
$| = 1;
### Get user input ###
# Character encoding to use (optional)
my $charsetOverride;
# Verbose output (optional)
my $verbose;
# Emacs-friendly output
my $emacs = ($ENV{EMACS} && $ENV{EMACS} eq 't');
# XML mode
my $xml;
# Whether warnings are desired
my $warnings;
# HTTP headers to send
my @headers;
# Help and version info
my $help;
my $versionInfo;
GetOptions("xml" => \$xml, "charset=s" => \$charsetOverride,
"verbose" => \$verbose, "help|h" => \$help,
"version|v" => \$versionInfo, "emacs!" => \$emacs,
"warn|w|W" => \$warnings, "header=s" => \@headers);
# Files to validate
my @files = @ARGV;
######################
my $errors = 0;
if ($versionInfo || $help) {
if ($versionInfo) {
print "$progname\n";
}
if ($help) {
&helpText;
}
exit $errors;
}
if ($#files == -1) {
push(@files, '-');
}
# Check that nsgmls is available before we get too far
unless (-e $nsgmlsLocation) {
&error("$nsgmlsLocation is not installed");
exit $errors;
}
unless (-x _) {
&error("$nsgmlsLocation is not executable");
exit $errors;
}
# Check if we can use URIs.
eval {
require URI;
require LWP::UserAgent;
};
my $uri_ok = !$@;
my $ua;
my $file;
foreach $file (@files) {
my $tempname = undef;
my $tempfh = undef;
my $charset = $charsetOverride;
# Read in document
my $document = "";
my $fileIsURL = 0;
if ($file ne '-') {
if ($uri_ok && $file =~ m|^\w+://.+|i) {
$fileIsURL = 1;
unless ($ua) {
$ua = LWP::UserAgent->new(env_proxy => 1, keep_alive => 1);
foreach (@headers) {
if (/^([^\s:]+)\s*:\s*(.*)/) {
if (lc($1) eq 'user-agent') {
$ua->agent($2);
} else {
$ua->default_header($1 => $2);
}
}
}
}
my $uri = URI->new($file);
unless ($ua->is_protocol_supported($uri)) {
&error('Unsupported protocol: ' . $uri->scheme());
next;
}
my $res = $ua->get($uri->canonical());
if ($res->is_success()) {
$document = $res->content();
unless ($charset) {
my $contentType = $res->header('Content-Type');
if ($contentType && $contentType =~ /[\s;]charset\s*=\s*"?([^,"\s]+)/io) {
$charset = $1;
}
}
} else {
&error($res->status_line());
next;
}
} else {
unless (-e $file) {
&error("File $file does not exist.");
next;
}
unless (-r _) {
&error("File $file is not readable.");
next;
}
open(IN, $file) || die "Unexpected error reading $file: $!\n";
while (<IN>) {
$document .= $_;
}
close(IN);
}
} else {
while (<>) {
$document .= $_;
}
}
unless ($charset) {
# Check for a META element specifying the character encoding
if ($document =~ m#<META(\s[^>]*http\-equiv\s*=\s*["']?Content\-Type["']?[^>]*)>#iso) {
my $metaAttributes = $1;
if ($metaAttributes =~ m#\scontent\s*=\s*["']?.*[\s;]charset\s*=\s*['"]?([^"']+)#iso) {
$charset = $1;
}
}
}
my @errors; # queue of errors
my @externalErrors; # queue of errors in an external DTD
my $lineAdjust = 0; # account for line number changes if we add a DOCTYPE
# Determine the level of HTML
my $htmlLevel;
my $fileToValidate = $file;
if ($xml) {
$htmlLevel = 'XML';
} else {
$htmlLevel = 'Unknown';
}
if ($document =~ /<!DOCTYPE([^>]*)>/iso) {
my $doctypeMeat = $1;
if ($doctypeMeat =~ /PUBLIC\s+["']([^"']*)["']/iso) {
$htmlLevel = $HTMLversion{"PUBLIC \"$1\""} || $htmlLevel;
}
if ($fileIsURL || $file eq '-') {
($tempname, $tempfh) = getTempFile();
print $tempfh "$document";
close($tempfh);
$fileToValidate = $tempname;
}
} else { # Missing DOCTYPE
# Add a default DOCTYPE
my ($insertedDoctype, $doctypeError);
if ($document =~ /<FRAMESET/io) {
$insertedDoctype = $defaultFramesetDoctype;
$doctypeError = $noFramesetDoctype;
} else {
$insertedDoctype = $defaultDoctype;
$doctypeError = $noDoctype;
}
($tempname, $tempfh) = getTempFile();
print $tempfh "$insertedDoctype\n$document";
close($tempfh);
$fileToValidate = $tempname;
$lineAdjust = 2;
push(@errors, "::" . (1 + $lineAdjust) . ":0:E: $doctypeError");
}
# Determine whether we're dealing with HTML or XHTML and set the SP
# environment accordingly.
if ($xhtml{$htmlLevel}) {
$ENV{'SGML_CATALOG_FILES'} = $xhtmlCatalog;
$ENV{'SP_ENCODING'} = 'xml';
$xml = 1;
} else {
$ENV{'SGML_CATALOG_FILES'} = $htmlCatalog;
if (defined $charset) {
$ENV{'SP_ENCODING'} = $charset;
} else {
$ENV{'SP_ENCODING'} = "ISO-8859-1";
}
}
$ENV{'SP_CHARSET_FIXED'} = 1;
if ($verbose) {
if ($file eq '-') {
print wrap("", "\t",
"Checking with $htmlLevel document type...\n");
} else {
print wrap("", "\t",
"Checking $file with $htmlLevel document type...\n");
}
}
my $warningsCmd = '';
if ($warnings) {
if ($xml) {
$warningsCmd = "$nsgmlsXMLWarnings";
} else {
$warningsCmd = "$nsgmlsWarnings";
}
}
# Run the validator
open(NSGMLS, "$nsgmls $warningsCmd $sgmlDecl{$htmlLevel} "
. &quoteFilename($fileToValidate) . " 2>&1 |")
|| die("Unable to execute $nsgmls: $!\n");
# Create a queue of errors
while (<NSGMLS>) {
chomp;
my @error = split(/:/, $_, 6);
if ($#error < 4) {
next;
} elsif ($error[4] eq 'E' || $error[4] eq 'X') {
# With warnings enabled in non-XML validation, some "errors"
# reported by lq-nsgmls are probably better reported as "warnings"
# since they are only reported with warnings enabled.
if ($warnings && !$xml) {
if ($errorAsWarning{$error[5]}) {
$error[4] = 'W';
# lq-nsgmls uses an XML-specific message for one of
# these warnings. Let's try something more helpful
# for HTML.
if ($error[5] eq ' net-enabling start-tag not supported in {{XML}}') {
$error[5] = ' net-enabling start-tag; possibly missing required quotes around an attribute value or using XHTML syntax in HTML';
}
$_ = join(':', @error);
}
}
push(@errors, $_);
# If the DOCTYPE is bad, bail out
last if ($error[5] eq ' unrecognized {{DOCTYPE}}; unable to check document');
} elsif ($error[4] eq 'W') {
unless ($error[5] eq ' characters in the document character set with numbers exceeding 65535 not supported')
{
push(@errors, $_);
}
} elsif ($error[1] =~ /^<URL>/o) { # error from external DTD
push(@externalErrors, $_);
} elsif (length($error[4]) > 1 # Allow secondary messages about preceding error
&& $error[3] ne 'W') # Prevent error about SGML declaration not implied with -wxml
{
push(@errors, $_);
}
}
close(NSGMLS);
# If we created a tempfile, unlink it
if (defined $tempname) {
unlink($tempname);
}
# Report errors
if ($#errors > -1 || $#externalErrors > -1) {
&startErrors($file);
foreach (@externalErrors) {
my @error = split(/:/, $_, 7);
# Determine URL containing the error
my $errorURL;
if ($error[1] =~ /<URL>(.+)/o) {
$errorURL = "$1:$error[2]";
}
my $lineNumber = $error[3];
my $character = $error[4] + 1;
my $errorMsg;
if ($emacs) {
$errorMsg = "$errorURL:$lineNumber:$character:";
} else {
$errorMsg = "$errorURL, line $lineNumber, character $character: ";
}
if ($error[6]) {
$errorMsg .= superChomp($error[6]);
} else {
$errorMsg .= superChomp($error[5]);
}
&htmlError(stripLqNsgmlsGunk($errorMsg));
}
foreach (@errors) {
my @error = split(/:/, $_, 6);
# I don't think this should happen, but I'm not sure
next if $#error < 4;
# Determine line number and character of error
my $lineNumber = $error[2] - $lineAdjust;
next unless $lineNumber > 0;
my $character = $error[3] + 1;
my $msgType;
if ($error[4] eq 'E' || $error[4] eq 'X') { # Error message
$msgType = $emacs ? 'E' : 'Error at';
} elsif ($error[4] eq 'W') {
$msgType = $emacs ? 'W' : 'Warning at';
}
# Prepare error message
my $errorMsg;
if ($emacs) {
$errorMsg = "$file:$lineNumber:$character:";
if (defined $msgType) {
$errorMsg .= "$msgType:";
}
} else {
my $line;
if (defined $msgType) {
$line = ' line';
} else {
$line = 'Line';
$msgType = "\t";
}
$errorMsg = "$msgType$line $lineNumber, character $character: ";
}
if ($error[5]) {
$errorMsg .= superChomp($error[5]);
} else {
$errorMsg .= superChomp($error[4]);
}
&htmlError(stripLqNsgmlsGunk($errorMsg));
}
} else {
if ($verbose) {
print "No errors!\n";
}
}
}
exit $errors;
# Return an error message
# The error message must be given as the first argument
sub error {
my $error_message = shift;
print $errout wrap("", "\t", "ERROR: \t$error_message\n");
++$errors;
}
# Heading to start HTML errors
# The file being validated should be given as the first argument
sub startErrors {
my $file = shift;
if (length $file) {
my $andWarnings = $warnings ? ' and warnings' : '';
if ($file eq '-') {
print $errout "*** Errors$andWarnings: ***\n";
} else {
if ($emacs) {
print $errout "*** Errors" . $andWarnings . " validating $file: ***\n";
} else {
print $errout wrap("", "\t",
"*** Errors" . $andWarnings . " validating $file: ***\n");
}
}
}
}
sub quoteFilename {
my $filename = shift;
$filename =~ s/\\/\\\\/go;
$filename =~ s/"/\\"/go;
# Untaint
if ($filename =~ /^(.*)$/) {
$filename = $1;
}
return "\"$filename\"";
}
# Clean the "{{foo}}" used in lq-nsgmls error messages
# The error message must be given as the first argument
sub stripLqNsgmlsGunk {
my $errorMsg = shift;
while ($errorMsg =~ m#\{\{"?(.+?)"?\}\}#gos) {
my $linkText = $1;
$errorMsg =~ s#\{\{(")?$linkText(")?\}\}#$1$linkText$2#;
}
return $errorMsg;
}
# Report an HTML error
# The error message must be given as the first argument
sub htmlError {
my $error_message = shift;
if ($emacs) {
print $errout "$error_message\n";
} else {
print $errout wrap("", "\t", "$error_message\n");
}
++$errors;
}
# Remove any newline characters (\r or \n) at the end of a string
# First argument is the string
# Returns the new string
sub superChomp {
my $str = shift || return;
$str =~ s/[\r\n]+$//o;
return $str;
}
# Create temporary file securely
# Returns the name and file handle of the created file
sub getTempFile {
my $filename;
do {
$filename = POSIX::tmpnam();
} until sysopen(FH, $filename, O_RDWR|O_CREAT|O_EXCL, 0666);
return ($filename, \*FH);
}
sub helpText {
print<<"EndOfHelp";
"validate", the Offline HTMLHelp.com Validator, checks the syntax of HTML
documents using an SGML parser and reports any errors. XHTML documents
may also be validated using an XML parser.
$usage
The program's options are as follows:
-w, --warn include warnings
--xml indicate that the documents to be validated are
XML documents. Known document types, such as
HTML 4.01 and XHTML 1.0, are automatically
handled by "validate". For unknown document
types, "validate" will assume XHTML/XML if this
option is specified and HTML/SGML otherwise.
--header='Name: value' set an HTTP header for HTTP requests (may be
used multiple times for separate headers)
--charset=ENCODING force ENCODING to be used as the character
encoding when validating HTML/SGML documents.
This option is ignored when validating XHTML/XML
documents, which are assumed to use XML rules for
specifying the character encoding. The following
encodings (case-insensitive) are supported:
"utf-8", "iso-10646-ucs-2", "euc-jp", "euc-kr",
"gb2312", "shift_jis", "big5", and "iso-8859-n"
where n is between 1 and 9 inclusive.
--verbose turn on verbose output messages
--[no]emacs (don't) use an output format intended for parsing
by (X)Emacs, autodetected
-h, --help display this help and exit
-v, --version output version information and exit
Any number of files may be specified after the options. With no FILE,
standard input is read.
Files can also be URIs if you have the URI and libwww-perl packages
installed. Support for different URI schemes is also determined by these
packages. Proxy settings are loaded from environment variables for
each scheme--e.g., http_proxy=http://localhost:3128.
"validate" is written by Liam Quinn <liam\@htmlhelp.com> and is based on the
WDG HTML Validator, an online validation service available at
<http://www.htmlhelp.com/tools/validator/>.
EndOfHelp
}

View file

@ -0,0 +1,43 @@
#!/usr/bin/perl
use strict;
use warnings;
use WebService::Validator::HTML::W3C;
=head1 DESCRIPTION
This script takes a directory as an argument and then submits every file
in that directory to the W3C validator. It will print out a line for each
file stating if it is valid or otherwise. For the invalid files it will
also print out the errors returned by the validator.
=cut
my $v = WebService::Validator::HTML::W3C->new(
# you should probably install a local validator if you
# are indenting to run this against a lot of files and
# then uncomment this line and change the uri
# validator_uri => 'http://localhost/w3c-validator/check',
detailed => 1
) or die "failed to init validator object";
my $dir = shift;
for my $file ( glob( "$dir/*.html" ) ) {
if ( $v->validate_file( $file ) ) {
if ( $v->is_valid ) {
print "$file: valid\n";
} else {
print "$file: invalid\n";
for my $err ( @{ $v->errors } ) {
printf(" line: %s, col: %s\n error: %s\n\n",
$err->line, $err->col, $err->msg);
}
}
} else {
die "failed to validate $file: " . $v->validator_error . "\n";
}
print "\n" . '-' x 60 . "\n";
# sleep between files so as not to hammer the validator
sleep 1;
}

47
W/tools/validate_html4 Executable file
View file

@ -0,0 +1,47 @@
#!/usr/bin/perl
use strict;
use warnings;
use WebService::Validator::HTML::W3C;
=head1 DESCRIPTION
This script takes files as arguments and then submits those file
to the W3C validator. It will print out a line for each
file stating if it is valid or otherwise. For the invalid files it will
also print out the errors returned by the validator.
=cut
my $v = WebService::Validator::HTML::W3C->new(
# you should probably install a local validator if you
# are indenting to run this against a lot of files and
# then uncomment this line and change the uri
# validator_uri => 'http://localhost/w3c-validator/check',
detailed => 1
) or die "failed to init validator object";
my $invalid_found = 0 ;
for my $file ( @ARGV ) {
if ( $v->validate_file( $file ) ) {
if ( $v->is_valid ) {
print "$file: valid\n";
} else {
$invalid_found = 1 ;
print "$file: invalid\n";
for my $err ( @{ $v->errors } ) {
printf(" line: %s, col: %s\n error: %s\n\n",
$err->line, $err->col, $err->msg);
}
}
} else {
die "failed to validate $file: " . $v->validator_error . "\n";
}
print "\n" . '-' x 60 . "\n";
# sleep between files so as not to hammer the validator
sleep 1;
}
exit( $invalid_found ) ;

Some files were not shown because too many files have changed in this diff Show more