This commit is contained in:
Nick Bebout 2014-11-19 16:16:16 -06:00
parent e195ab3906
commit 65fd3eac5d
27 changed files with 1382 additions and 879 deletions

View file

@ -1,17 +1,64 @@
RCS file: RCS/imapsync,v
Working file: imapsync
head: 1.596
head: 1.607
branch:
locks: strict
gilles: 1.596
gilles: 1.607
access list:
symbolic names:
keyword substitution: kv
total revisions: 596; selected revisions: 596
total revisions: 607; selected revisions: 607
description:
----------------------------
revision 1.596 locked by: gilles;
revision 1.607 locked by: gilles;
date: 2014/11/14 16:25:06; author: gilles; state: Exp; lines: +46 -40
Added several checks if IsUnconnected. Goal avoid imap commands while disconnected.
----------------------------
revision 1.606
date: 2014/11/14 14:49:13; author: gilles; state: Exp; lines: +16 -13
Added total size transferred after each message copied.
Added number of total to be synced as a denominator dddd after each message copied, nnn/dddd, where nnn is the number of messages copied.
----------------------------
revision 1.605
date: 2014/11/11 00:00:37; author: gilles; state: Exp; lines: +40 -10
Bugfix. On Windows file path with brackets [] are special. [a] must be written [[]a[]]
----------------------------
revision 1.604
date: 2014/11/08 00:29:26; author: gilles; state: Exp; lines: +36 -9
Added --skipemptyfolders to skip empty host1 folders. They are not created on host2.
----------------------------
revision 1.603
date: 2014/11/07 22:06:33; author: gilles; state: Exp; lines: +26 -26
Typo from previous save with gedit and ¤
----------------------------
revision 1.602
date: 2014/11/07 21:57:57; author: gilles; state: Exp; lines: +82 -19
Added utf8 output for folder names that use special characters in utf7imap
----------------------------
revision 1.601
date: 2014/10/28 10:48:07; author: gilles; state: Exp; lines: +22 -22
Moved foldersizes call after folders lists print.
----------------------------
revision 1.600
date: 2014/10/27 10:41:52; author: gilles; state: Exp; lines: +8 -8
Remove /x from regex applied with --include and --exclude. Blanks no longer have to be explicit with \ or [ ].
----------------------------
revision 1.599
date: 2014/10/26 23:42:12; author: gilles; state: Exp; lines: +14 -10
Added help usage for --nomixfolders
----------------------------
revision 1.598
date: 2014/10/21 00:27:07; author: gilles; state: Exp; lines: +20 -7
Added tests to check --regextrans2 's,(.*),\L$1,'
Exchange issue with folders with same name and --delete2.
----------------------------
revision 1.597
date: 2014/10/06 10:48:26; author: gilles; state: Exp; lines: +12 -11
Changed --nomixdiffcasefolders to --nomixfolders.
Bugfix. --nomixdiffcasefolders was not parsed in command line so it did not work.
----------------------------
revision 1.596
date: 2014/09/04 17:17:36; author: gilles; state: Exp; lines: +11 -6
Added --logfile in help output.
Added --nolog in help output.

48
FAQ
View file

@ -1,5 +1,5 @@
#!/bin/cat
# $Id: FAQ,v 1.186 2014/09/06 07:39:40 gilles Exp gilles $
# $Id: FAQ,v 1.190 2014/11/14 17:08:02 gilles Exp gilles $
+------------------+
| FAQ for imapsync |
@ -1241,7 +1241,7 @@ the flow to go the other way):
--proxyauth1 --password1 '$pass_with_dollars$' \
--host2 cyrusimapbackend.mycompany.com \
--user2 SameOrDiffererentUser@mycompany.com \
--authuser2 CyrusAdminAccount --proxyauth2
--authuser2 CyrusAdminAccount --password2 CyrusAdminPassword
We also needed to:
@ -1280,6 +1280,11 @@ or the NETBIOS or DNS name of the domain.
The exact format might vary depending on local configuration and you
should experiment with the different formats.
PLAIN authentication is the only way to go with --authuser1 for now.
So don't use --authmech1 SOMETHING with --authuser1 admin_user,
it will not work.
Same behavior with the --authuser2 option.
A little note from Michael Scherer.
The previous workaround in the FAQ seems to be obsolete.
I can confirm that
@ -1320,6 +1325,12 @@ but previous in Office365 you must do something like that, using powershell:
Add-MailboxPermission -identity user_to_be_migrated@domain.com -user user_admin@domain.com -accessrights fullaccess -inheritancetype all
PLAIN authentication is the only way to go with --authuser1 for now.
So don't use --authmech1 SOMETHING with --authuser1 admin_user,
it will not work.
Same behavior with the --authuser2 option.
======================================================================
Q. How to migrate from uw-imap with an admin/authuser account?
@ -1347,14 +1358,19 @@ R. Use:
--authuser1 admin_user ----password1 admin_user_password \
--user1 foo_user --ssl1
In this case, --authmech1 PLAIN will be used by default since it
is the only way to go for now. So don't use --authmech1 SOMETHING
with --authuser1 admin_user, it will not work.
Instead of --ssl1 the alternative --tls1 can be used.
With --authuser1, the option --authmech1 PLAIN is set
automatically, you don't have to add it.
PLAIN authentication is the only way to go with --authuser1 for now.
So don't use --authmech1 SOMETHING with --authuser1 admin_user,
it will not work.
Same behavior with the --authuser2 option.
Do not forget the option --ssl1 since PLAIN auth is only
Do not forget the option --ssl1 or --tls1 since PLAIN auth is only
supported with ssl encryption most of the time. But it can
work without --ssl1 if PLAIN is permitted in normal use.
work without --ssl1 nor --tls1 if PLAIN is permitted in clear text
transmissions (the normal mode).
Add the AdminAccount to admins line in /etc/imapd.conf
Give AdminAccount lrswipkxtecda to the Cyrus Imap account
@ -1770,6 +1786,7 @@ imapsync --host1 mail.oldhost.com \
--ssl2 \
--exitwhenover 500000000 \
--maxsize 25000000 \
--expunge1 \
--addheader \
--exclude "\[Gmail\]$" \
--regextrans2 "s/[ ]+/_/g" \
@ -1794,6 +1811,13 @@ up to 25 MB. This value increases over time, it was 10 MB some
years ago so you can try higher values. The Gmail page about
this limit is https://support.google.com/mail/answer/6584
--expunge1 is optional. It deletes messages marked \Deleted on host1.
Imapsync syncs messages with all their flags, Gmail takes the messages
marked \Deleted but deletes or moves them just after.
Option --expunge1 really removes messages marked \Deleted on host1
so they are not synced at all.
The --addheader option is there because "Sent" folder messages
sometimes lack the "Message-Id:" and "Received:" headers needed
by imapsync to identify messages (only when --useuid is not used).
@ -2005,6 +2029,16 @@ No specific option for HMailServer 5.3.3 since NAMESPACE is supported.
Maybe --subscribe_all will help you to see all migrated folders.
=======================================================================
Q. Synchronizing from Kerio Connect to XXX
R. No special options required.
See also:
http://www.linux-france.org/prj/imapsync_list/msg01756.html
http://www.safetynet-it.com/it-support/mac-kerio-server-to-microsoft-exchange-2010-migration-1/
http://www.safetynet-it.com/it-support/mac-kerio-server-to-microsoft-exchange-2010-migration-2/
=======================================================================
Q. Synchronizing from SmarterMail to XXX

14
INSTALL
View file

@ -1,4 +1,4 @@
# $Id: INSTALL,v 1.39 2014/09/19 19:37:08 gilles Exp gilles $
# $Id: INSTALL,v 1.40 2014/11/14 17:07:21 gilles Exp gilles $
#
# INSTALL file for imapsync
# imapsync : IMAP sync and migrate tool.
@ -80,7 +80,8 @@ Test all Perl modules dependency in one command:
perl -mMail::IMAPClient -mDigest::MD5 -mTerm::ReadKey -mIO::Socket::SSL \
-mDigest::HMAC_MD5 -mAuthen::NTLM -e -mTime::HiRes \
-mData::Uniqid -mURI::Escape -mFile::Copy::Recursive -mIO::Tee ""
-mData::Uniqid -mURI::Escape -mFile::Copy::Recursive -mIO::Tee \
-mUnicode::String ""
You can install easily those Perl modules in latest release via the
following commands (with root permissions)
@ -92,6 +93,7 @@ following commands (with root permissions)
perl -MCPAN -e "install URI::Escape"
perl -MCPAN -e "install File::Copy::Recursive"
perl -MCPAN -e "install IO::Tee"
perl -MCPAN -e "install Unicode::String"
perl -MCPAN -e "install Data::Uniqid"
perl -MCPAN -e "install Authen::NTLM"
@ -117,11 +119,14 @@ On Debian/Ubuntu:
aptitude install liburi-perl # URI::Escape
aptitude install libfile-copy-recursive-perl # File::Copy::Recursive
aptitude install libio-tee-perl # IO::Tee
aptitude install libunicode-string-perl # Unicode::String
On Ubuntu 14 (thanks to http://www.jverdeyen.be/ubuntu/imapsync-on-ubuntu/):
sudo apt-get install makepasswd rcs perl-doc libio-tee-perl git
sudo apt-get install libmail-imapclient-perl libdigest-md5-file-perl libterm-readkey-perl libfile-copy-recursive-perl
sudo apt-get install libmail-imapclient-perl libdigest-md5-file-perl
sudo apt-get install libterm-readkey-perl libfile-copy-recursive-perl
sudo apt-get install libunicode-string-perl
On Mandriva:
@ -132,7 +137,7 @@ On Mandriva:
urpmi perl-URI # URI::Escape
urpmi perl-File-Copy-Recursive # File::Copy::Recursive
urpmi perl-IO-Tee # IO::Tee
urpmi perl-Unicode-String # Unicode::String
On CentOS (thanks to Ralf Hauber)
@ -148,6 +153,7 @@ On CentOS (thanks to Ralf Hauber)
yum install perl-Data-Uniqid # Data::Uniqid
yum install perl-File-Copy-Recursive # File::Copy::Recursive
yum install perl-IO-Tee # IO::Tee
yum install perl-Unicode-String # Unicode::String
INSTALLING on Unix

View file

@ -1,5 +1,5 @@
# $Id: Makefile,v 1.151 2014/09/21 08:35:07 gilles Exp gilles $
# $Id: Makefile,v 1.155 2014/11/14 23:54:52 gilles Exp gilles $
.PHONY: help usage all
@ -15,11 +15,13 @@ usage:
@echo "make testf # run tests"
@echo "make testv # run tests verbosely"
@echo "make test_quick # few tests verbosely"
@echo "make tests_win32 # run --test and W/test.bat on win32"
@echo "make tests_win32_dev # run W/test2.bat on win32"
@echo "make tests_win32_dev3 # run W/test3.bat on win32"
@echo "make .prereq_win32 # run examples/install_modules.bat on win32"
@echo "make W/test.bat # run --test and W/test.bat on win32"
@echo "make W/test2.bat # run W/test2.bat on win32"
@echo "make W/test3.bat # run W/test3.bat on win32"
@echo "make W/test_exe_2.bat # run W/test_exe_2.bat on win32"
@echo "make prereq_win32 # run examples/install_modules.bat on win32"
@echo "make all "
@echo "make upload_tests # upload tests.sh"
@echo "make upload_index"
@echo "make valid_index # check index.shtml for good syntax"
@echo "make upload_ks"
@ -138,7 +140,6 @@ test_quick_3xx: imapsync tests.sh
testv3: imapsync tests.sh
CMD_PERL='perl -I./$(IMAPClient_3xx)' /usr/bin/time sh tests.sh
./i3 --version >> .test_3xx
testv: testv3
@ -146,19 +147,16 @@ test: .test_3xx
tests: test
# .test_3xx is created by tests.sh with success at all mandatory tests
.test_3xx: imapsync tests.sh
CMD_PERL='perl -I./$(IMAPClient_3xx)' /usr/bin/time sh tests.sh 1>/dev/null
./i3 --version >> .test_3xx
testf: clean_test test
.PHONY: lfo upload_lfo public imapsync_cidone
.PHONY: lfo upload_lfo dosify_bat public imapsync_cidone
.dosify_bat: W/*.bat examples/*.bat build_exe.bat
dosify_bat:
unix2dos W/*.bat examples/*.bat build_exe.bat
touch .dosify_bat
dosify_bat: .dosify_bat
copy_win32:
scp imapsync Admin@c:'C:/msys/1.0/home/Admin/imapsync/'
@ -171,29 +169,47 @@ tests_win32: dosify_bat
# ssh Admin@c 'tasklist /FI "PID eq 0"'
# ssh Admin@c 'tasklist /NH /FO CSV'
tests_win32_dev: dosify_bat
.PHONY: W/*.bat
W/test2.bat:
unix2dos W/*.bat
scp imapsync examples/file.txt W/test2.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/'
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/test2.bat'
tests_win32_dev3: dosify_bat
W/test3.bat:
unix2dos W/*.bat
scp imapsync W/test3.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/'
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/test3.bat'
test_imapsync_exe: dosify_bat
W/test_exe_2.bat:
unix2dos W/*.bat
scp imapsync W/test_exe_2.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/'
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/test_exe_2.bat'
W/test3_gmail.bat:
unix2dos W/*.bat
scp imapsync W/test3_gmail.bat /g/var/pass/secret.gilles_gmail Admin@c:'C:/msys/1.0/home/Admin/imapsync/'
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/test3_gmail.bat'
test_imapsync_exe:
unix2dos W/*.bat
scp W/test_exe.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/'
time ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/test_exe.bat'
.prereq_win32: examples/install_modules.bat .dosify_bat
prereq_win32:
unix2dos W/*.bat examples/*.bat build_exe.bat
scp examples/install_modules.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/examples/'
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/examples/install_modules.bat'
touch .prereq_win32
imapsync.exe: imapsync .prereq_win32
imapsync.exe: imapsync
rcsdiff imapsync
ssh Admin@c 'perl -V'
(date "+%s"| tr "\n" " "; echo -n "BEGIN " $(VERSION) ": "; date) >> W/.BUILD_EXE_TIME
scp imapsync build_exe.bat W/test_exe.bat \
Admin@c:'C:/msys/1.0/home/Admin/imapsync/'
unix2dos W/*.bat examples/*.bat build_exe.bat
scp examples/install_modules.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/examples/'
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/examples/install_modules.bat'
scp imapsync build_exe.bat W/test_exe.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/'
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/build_exe.bat'
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/test_exe.bat'
scp Admin@c:'C:/msys/1.0/home/Admin/imapsync/imapsync.exe' .
@ -201,7 +217,7 @@ imapsync.exe: imapsync .prereq_win32
dos2unix ./VERSION_EXE
(date "+%s"| tr "\n" " "; echo -n "END " $(VERSION) ": "; date) >> W/.BUILD_EXE_TIME
exe: imapsync build_exe.bat .dosify_bat
exe: imapsync build_exe.bat dosify_bat
(date "+%s"| tr "\n" " "; echo -n "BEGIN " $(VERSION) ": "; date) >> W/.BUILD_EXE_TIME
scp imapsync build_exe.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/'
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/build_exe.bat'
@ -218,6 +234,7 @@ zip: dosify_bat
unix2dos ../prepa_zip/imapsync_$(VERSION_EXE)/*.txt
cd ../prepa_zip/ && rm -f ./imapsync_$(VERSION_EXE).zip && zip -r ./imapsync_$(VERSION_EXE).zip ./imapsync_$(VERSION_EXE)/
scp ../prepa_zip/imapsync_$(VERSION_EXE).zip Admin@c:'C:/msys/1.0/home/Admin/'
cp ../prepa_zip/imapsync_$(VERSION_EXE).zip /ee/imapsync/
@ -331,6 +348,13 @@ ksa:
rsync -avHz --delete -P \
. gilles@ks.lamiral.info:public_html/imapsync/
upload_tests: tests.sh
rsync -avHz --delete -P \
tests.sh \
gilles@ks.lamiral.info:public_html/imapsync/
upload_ks: ci tarball
rsync -lptvHzP $(PUBLIC_FILES) \
root@ks.lamiral.info:/var/www/imapsync/

5
README
View file

@ -4,7 +4,7 @@ NAME
More than 52 different IMAP server softwares supported with success, few
failures.
$Revision: 1.596 $
$Revision: 1.607 $
SYNOPSIS
To synchronize imap account "foo" on "imap.truc.org" to imap account
@ -374,6 +374,7 @@ IMAP SERVERS
- MailEnable 4.23 [host1] [host2], 4.26 [host1][host2], 5 [host1]
- MDaemon 7.0.1, 8.0.2, 8.1, 9.5.4 (Windows server 2003 R2 platform),
9.6.5 [host1], 12 [host2], 12.0.3 [host1], 12.5.5 [host1],
13.5 [host2], 14.5 [host2]
- Mercury 4.1 (Windows server 2000 platform)
- Microsoft Exchange Server 5.5, 6.0.6249.0[host1], 6.0.6487.0[host1],
6.5.7638.1 [host2], 6.5 [host1], Exchange 2007 SP1 (with Update Rollup 2),
@ -486,5 +487,5 @@ SIMILAR SOFTWARES
Feedback (good or bad) will often be welcome.
$Id: imapsync,v 1.596 2014/09/04 17:17:36 gilles Exp gilles $
$Id: imapsync,v 1.607 2014/11/14 16:25:06 gilles Exp gilles $

View file

@ -1,6 +0,0 @@
imapsync-1.592.tgz is for Unix and Mac users.
imapsync-1.592.zip is for Windows users.
the file script imapsync for a fast upgrade on Unix.

21
TODO
View file

@ -1,5 +1,5 @@
#!/bin/cat
# $Id: TODO,v 1.126 2014/05/21 01:15:47 gilles Exp gilles $
# $Id: TODO,v 1.127 2014/11/14 17:06:17 gilles Exp gilles $
TODO file for imapsync
----------------------
@ -17,7 +17,11 @@ http://www.yippiemove.com/
http://www.migrationwiz.com/
http://www.microsoft.com/download/en/details.aspx?id=1329 "Microsoft Transporter Suite"
Separate the online site in a subfolder site/ or www/ and make the upper directory simple.
Add an option to remove empty folders on host1, except INBOX.
Is it possible to run imapsync in a way that empty folders on host1
aren't created at all on host2?
Apply --disarmreadreceipts only to UNSEEN messages.
@ -73,11 +77,6 @@ Does \lalala can be forbidden (courier does a
with
* OK [PERMANENTFLAGS (\* \Draft \Answered \Flagged \Deleted \Seen)] Limited
Suggestion: it's very difficult to track down messages which are behaving
funny during the sync. It would be great - and presumably easy to code -
to have an option to have imapsync display e.g. the subject of an
e-mail when it gets synced, rather than just the message ID and the date/time.
Add a well described problem for each problem detected
and counted in error counter statistics.
@ -156,6 +155,16 @@ http://asg.web.cmu.edu/cyrus/download/imapd/altnamespace.html
===========================================================================
DONE. Subject is output when APPEND fails. Done since a long time.
Suggestion: it's very difficult to track down messages which are behaving
funny during the sync. It would be great - and presumably easy to code -
to have an option to have imapsync display e.g. the subject of an
e-mail when it gets synced, rather than just the message ID and the date/time.
DONE. Add W/learn/imap_utf7 in imapsync, the folders lists output looks a good place,
if transcription is needed.
DONE. Add options --log and --logfile to log both on screen and to a file.
DONE. Document the tee command solution (Unix and Windows) in the FAQ.

View file

@ -25,14 +25,14 @@
<A NAME="toc2"></A>
<H2>Introduction</H2>
<P>
Three Internet protocols share the big pie
access of almost all email accounts : POP, IMAP, HTTP.
Three Internet protocols are used to access almost all email accounts:
POP, IMAP, HTTP.
</P>
<P>
The oldest one is POP, Post Office Protocol, it allows only
one main box, also called INBOX.
The second protocol is IMAP, Internet Message Access Protocol, which allows
a hierarchy of mailboxes also called folders, allows also concurrent accesses,
a hierarchy of mailboxes also called folders, it also allows concurrent accesses,
tagging with flags, search by many criterium like date, subject, size etc.
The third protocol is HTTP, HyperText Transfer Protocol, via webmails.
Webmails often offer the same features than imap servers and,
@ -125,5 +125,5 @@ is equivalent to
<P></P>
<!-- html code generated by txt2tags 2.5 (http://txt2tags.sf.net) -->
<!-- cmdline: txt2tags -i TUTORIAL.t2t -t html -\-toc -o TUTORIAL.html -->
<!-- cmdline: txt2tags -i W/TUTORIAL.t2t -t html -\-toc -o TUTORIAL.html -->
</BODY></HTML>

View file

@ -1 +1 @@
1.596
1.607

View file

@ -1 +1 @@
1.596
1.607

View file

@ -293,3 +293,12 @@
1411228014 BEGIN 1.596 : samedi 20 septembre 2014, 17:46:54 (UTC+0200)
1411266788 BEGIN 1.596 : dimanche 21 septembre 2014, 04:33:08 (UTC+0200)
1411267953 END 1.596 : dimanche 21 septembre 2014, 04:52:33 (UTC+0200)
1412693514 BEGIN 1.597 : mardi 7 octobre 2014, 16:51:54 (UTC+0200)
1412750854 BEGIN 1.597 : mercredi 8 octobre 2014, 08:47:34 (UTC+0200)
1412751726 END 1.597 : mercredi 8 octobre 2014, 09:02:06 (UTC+0200)
1415448836 BEGIN 1.604 : samedi 8 novembre 2014, 13:13:56 (UTC+0100)
1415449975 END 1.604 : samedi 8 novembre 2014, 13:32:55 (UTC+0100)
1415818269 BEGIN 1.605 : mercredi 12 novembre 2014, 19:51:09 (UTC+0100)
1415819173 END 1.605 : mercredi 12 novembre 2014, 20:06:13 (UTC+0100)
1415985918 BEGIN 1.607 : vendredi 14 novembre 2014, 18:25:18 (UTC+0100)
1415986823 END 1.607 : vendredi 14 novembre 2014, 18:40:23 (UTC+0100)

View file

@ -1,19 +1,19 @@
% $Id: TUTORIAL.t2t,v 1.2 2013/08/16 00:48:57 gilles Exp gilles $
% $Id: TUTORIAL.t2t,v 1.3 2014/10/08 08:49:29 gilles Exp gilles $
= Tutorial for imapsync =
== Introduction ==
Three Internet protocols share the big pie
access of almost all email accounts : POP, IMAP, HTTP.
Three Internet protocols are used to access almost all email accounts:
POP, IMAP, HTTP.
The oldest one is POP, Post Office Protocol, it allows only
one main box, also called INBOX.
The second protocol is IMAP, Internet Message Access Protocol, which allows
a hierarchy of mailboxes also called folders, allows also concurrent accesses,
a hierarchy of mailboxes also called folders, it also allows concurrent accesses,
tagging with flags, search by many criterium like date, subject, size etc.
The third protocol is HTTP, HyperText Transfer Protocol, via webmails.
Webmails often offer the same features than imap servers and,

29
W/learn/imap_utf7_decode Executable file
View file

@ -0,0 +1,29 @@
#!/usr/bin/perl
use Unicode::String ;
while (<>) {
chomp ;
#push( @result, sprintf( "%33s %s\n", $_, decode( $_ ) ) ) ;
push( @result, sprintf( "%s\n", imap_utf7_decode( $_ ) ) ) ;
}
print @result ;
# http://cpansearch.perl.org/src/FABPOT/Unicode-IMAPUtf7-2.01/lib/Unicode/IMAPUtf7.pm
sub imap_utf7_decode {
my ($s) = @_;
# Algorithm
# On remplace , par / dans les BASE 64 (, entre & et -)
# On remplace les &, non suivi d'un - par +
# On remplace les &- par &
$s =~ s/\+/PLUSPLACEHOLDER/g;
$s =~ s/&([^,&\-]*),([^,\-&]*)\-/&$1\/$2\-/g;
$s =~ s/&(?!\-)/\+/g;
$s =~ s/&\-/&/g;
$s =~ s/PLUSPLACEHOLDER/+-/g;
return( Unicode::String::utf7( $s )->utf8 ) ;
}

View file

@ -1,4 +1,4 @@
m4_dnl $Id: ml_announce.in,v 1.7 2014/05/30 01:39:23 gilles Exp gilles $
m4_dnl $Id: ml_announce.in,v 1.8 2014/10/22 11:04:30 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
@ -19,6 +19,10 @@ and the latest imapsync source code (release M4_imapsync_VERSION) at the followi
http://imapsync.lamiral.info/dist/M4_SECRET_PATH/
or also from this page
http://imapsync.lamiral.info/paypal_return.shtml
Three files are there:
- imapsync is directly the perl script (also found in the tarball) for a fast upgrade.
- imapsync-M4_imapsync_VERSION.tgz is the tarball containing everything of the project (maybe too much)

View file

@ -1,6 +1,6 @@
#!/bin/sh
# $Id: paypal_build_invoices,v 1.76 2014/09/02 23:40:15 gilles Exp gilles $
# $Id: paypal_build_invoices,v 1.78 2014/10/22 11:26:06 gilles Exp gilles $
# usage: sh paypal_build_invoices /g/var/paypal_invoices/????
@ -54,9 +54,9 @@ 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 3413 --avoid_numbers '3450 3451' /g/paypal/paypal_2014_07_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 3450 /g/paypal/virements_2014_07.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 3475 /g/paypal/paypal_2014_08_complet.csv
/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 3538 /g/paypal/paypal_2014_09_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 3538 /g/paypal/paypal_2014_09_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 3614 /g/paypal/virements_2014_10.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 3618 /g/paypal/paypal_2014_10_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 147 /g/paypal/paypal_2010_11_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 214 /g/paypal/paypal_2010_12_complet.csv
@ -105,9 +105,12 @@ cp /home/gilles/public_html/AGIL/factures/000/facture_imapsync-000.tex /g/var/pa
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 3413 --avoid_numbers '3450 3451' /g/paypal/paypal_2014_07_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 3450 /g/paypal/virements_2014_07.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 3475 /g/paypal/paypal_2014_08_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 3538 /g/paypal/paypal_2014_09_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 3614 /g/paypal/virements_2014_10.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 3618 /g/paypal/paypal_2014_10_complet.csv
set -x
/g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 3538 /g/paypal/paypal_2014_09_complet.csv
/g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 3691 /g/paypal/paypal_2014_11_complet.csv
set +x
# La totale
@ -116,7 +119,7 @@ set +x
--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' \
3093 3296 3411 3412 3450 3451 3614 3615 3616 3617' \
/g/paypal/paypal_201?_??_complet.csv
#set -v
@ -124,7 +127,7 @@ set +x
--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' \
3093 3296 3411 3412 3450 3451 3614 3615 3616 3617' \
/g/paypal/paypal_201?_??_complet.csv
#set +v

View file

@ -5,7 +5,7 @@
<title>imapsync download</title>
<meta name="generator" content="Bluefish 1.0.7"/>
<meta name="author" content="Gilles LAMIRAL"/>
<meta name="date" content="2014-04-17T13:01:45+0200"/>
<meta name="date" content="2014-10-22T13:13:21+0200"/>
<meta name="copyright" content=""/>
<meta name="keywords" content=""/>
<meta name="description" content=""/>
@ -57,7 +57,7 @@ You will be soon subscribed to the newsletter announcing new releases (and only
<p>For <b>professionnal support</b>, in order to explain your <b>specific needs</b>,
find <b>best solutions</b> for them, <b>avoid loosing time</b>,
and then <b>succeed</b> your migration <b>quickly</b>, <b>contact me</b>
and <b>succeed</b> your migration in the best conditions, <b>contact me</b>
(Gilles LAMIRAL) by email or phone at:</p>
<ul>
<li>Email address: <b>gilles.lamiral@laposte.net</b>.</li>
@ -91,7 +91,7 @@ gilles.lamiral@laposte.net</p>
<!--#config timefmt="%D" -->
<!--#config timefmt="%A %B %d, %Y" -->
<b>This document last modified on <!--#echo var="LAST_MODIFIED" --></b><br/>
($Id: paypal_return.shtml,v 1.15 2014/05/21 01:22:13 gilles Exp gilles $)
($Id: paypal_return.shtml,v 1.16 2014/10/22 11:13:36 gilles Exp gilles $)
</p>
<!-- Google Code for Achat imapsync Conversion Page -->

File diff suppressed because it is too large Load diff

View file

@ -1,49 +1,58 @@
Main code has high complexity score (358) at line 1, column 1. Consider refactoring. (Severity: 3)
Expression form of "map" at line 1142, column 51. See page 169 of PBP. (Severity: 4)
Expression form of "map" at line 1152, column 51. See page 169 of PBP. (Severity: 4)
Code structure is deeply nested at line 1586, column 41. Consider refactoring. (Severity: 3)
Too many arguments at line 1770, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 1788, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 1798, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2032, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2093, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2153, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2256, column 1. See page 182 of PBP. (Severity: 3)
Subroutine "is_valid_directory" does not end with "return" at line 2392, column 1. See page 197 of PBP. (Severity: 4)
"die" used instead of "croak" at line 2433, column 2. See page 283 of PBP. (Severity: 3)
Reused variable name in lexical scope: $imap2 at line 2548, column 9. Invent unique variable names. (Severity: 3)
Regular expression without "/x" flag at line 2567, column 25. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 2570, column 20. See page 236 of PBP. (Severity: 3)
Mixed high and low-precedence booleans at line 2571, column 13. See page 70 of PBP. (Severity: 4)
Expression form of "eval" at line 2996, column 13. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 3217, column 13. See page 161 of PBP. (Severity: 5)
Subroutine "select_msgs" does not end with "return" at line 3358, column 1. See page 197 of PBP. (Severity: 4)
Subroutine "tests_msgs_from_maxmin" does not end with "return" at line 3497, column 1. See page 197 of PBP. (Severity: 4)
Subroutine "copy_message" with high complexity score (30) at line 3574, column 1. Consider refactoring. (Severity: 3)
Too many arguments at line 3574, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 3665, column 1. See page 182 of PBP. (Severity: 3)
Subroutine "tests_subject" does not end with "return" at line 3759, column 1. See page 197 of PBP. (Severity: 4)
Too many arguments at line 3822, column 1. See page 182 of PBP. (Severity: 3)
Subroutine "sleep_if_needed" does not end with "return" at line 3878, column 1. See page 197 of PBP. (Severity: 4)
Reused variable name in lexical scope: $total_bytes_transferred at line 3879, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $nb_msg_transferred at line 3879, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $nb_msg_transferred at line 3891, column 9. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $maxmessagespersecond at line 3891, column 9. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $total_bytes_transferred at line 3912, column 9. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $maxbytespersecond at line 3912, column 9. Invent unique variable names. (Severity: 3)
Mismatched operator at line 4380, column 75. Numeric/string operators and operands should match. (Severity: 3)
Hard tabs used at line 4464, column 10. See page 20 of PBP. (Severity: 3)
Expression form of "eval" at line 4736, column 13. See page 161 of PBP. (Severity: 5)
Too many arguments at line 4892, column 1. See page 182 of PBP. (Severity: 3)
Backtick operator used at line 5205, column 12. Use IPC::Open3 instead. (Severity: 3)
Backtick operator used at line 5225, column 11. Use IPC::Open3 instead. (Severity: 3)
Expression form of "eval" at line 5526, column 43. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 5530, column 45. See page 161 of PBP. (Severity: 5)
"$i" is declared but not used at line 5794, column 9. Unused variables clutter code and make it harder to read. (Severity: 3)
Reused variable name in lexical scope: $logfile at line 5846, column 2. Invent unique variable names. (Severity: 3)
Subroutine "teelaunch" does not end with "return" at line 5853, column 1. See page 197 of PBP. (Severity: 4)
Reused variable name in lexical scope: $logfile at line 5854, column 2. Invent unique variable names. (Severity: 3)
Close filehandles as soon as possible after opening them at line 5857, column 2. See page 209 of PBP. (Severity: 4)
"die" used instead of "croak" at line 5858, column 7. See page 283 of PBP. (Severity: 3)
Magic variable "*STDERR" should be assigned as "local" at line 5860, column 10. See pages 81,82 of PBP. (Severity: 4)
One-argument "select" used at line 5861, column 2. See page 224 of PBP. (Severity: 4)
Main code has high complexity score (361) at line 1, column 1. Consider refactoring. (Severity: 3)
Regular expression without "/x" flag at line 1143, column 33. See page 236 of PBP. (Severity: 3)
Expression form of "map" at line 1145, column 51. See page 169 of PBP. (Severity: 4)
Regular expression without "/x" flag at line 1153, column 33. See page 236 of PBP. (Severity: 3)
Expression form of "map" at line 1155, column 51. See page 169 of PBP. (Severity: 4)
Code structure is deeply nested at line 1598, column 41. Consider refactoring. (Severity: 3)
Subroutine "foldersizesatend" does not end with "return" at line 1758, column 1. See page 197 of PBP. (Severity: 4)
Too many arguments at line 1784, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 1802, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 1812, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2049, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2110, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2170, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2273, column 1. See page 182 of PBP. (Severity: 3)
Subroutine "is_valid_directory" does not end with "return" at line 2409, column 1. See page 197 of PBP. (Severity: 4)
"die" used instead of "croak" at line 2450, column 2. See page 283 of PBP. (Severity: 3)
Always unpack @_ first at line 2544, column 1. See page 178 of PBP. (Severity: 4)
Regular expression without "/x" flag at line 2551, column 15. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 2552, column 15. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 2553, column 15. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 2554, column 15. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 2581, column 31. See page 236 of PBP. (Severity: 3)
Reused variable name in lexical scope: $imap2 at line 2638, column 9. Invent unique variable names. (Severity: 3)
Regular expression without "/x" flag at line 2657, column 25. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 2660, column 20. See page 236 of PBP. (Severity: 3)
Mixed high and low-precedence booleans at line 2661, column 13. See page 70 of PBP. (Severity: 4)
Expression form of "eval" at line 3098, column 13. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 3322, column 13. See page 161 of PBP. (Severity: 5)
Subroutine "select_msgs" does not end with "return" at line 3463, column 1. See page 197 of PBP. (Severity: 4)
Subroutine "tests_msgs_from_maxmin" does not end with "return" at line 3602, column 1. See page 197 of PBP. (Severity: 4)
Subroutine "copy_message" with high complexity score (30) at line 3679, column 1. Consider refactoring. (Severity: 3)
Too many arguments at line 3679, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 3770, column 1. See page 182 of PBP. (Severity: 3)
Subroutine "tests_subject" does not end with "return" at line 3864, column 1. See page 197 of PBP. (Severity: 4)
Too many arguments at line 3927, column 1. See page 182 of PBP. (Severity: 3)
Subroutine "sleep_if_needed" does not end with "return" at line 3986, column 1. See page 197 of PBP. (Severity: 4)
Reused variable name in lexical scope: $total_bytes_transferred at line 3987, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $nb_msg_transferred at line 3987, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $nb_msg_transferred at line 3999, column 9. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $maxmessagespersecond at line 3999, column 9. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $total_bytes_transferred at line 4020, column 9. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $maxbytespersecond at line 4020, column 9. Invent unique variable names. (Severity: 3)
Mismatched operator at line 4508, column 75. Numeric/string operators and operands should match. (Severity: 3)
Hard tabs used at line 4592, column 10. See page 20 of PBP. (Severity: 3)
Expression form of "eval" at line 4866, column 13. See page 161 of PBP. (Severity: 5)
Too many arguments at line 5022, column 1. See page 182 of PBP. (Severity: 3)
Backtick operator used at line 5335, column 12. Use IPC::Open3 instead. (Severity: 3)
Backtick operator used at line 5355, column 11. Use IPC::Open3 instead. (Severity: 3)
Expression form of "eval" at line 5656, column 43. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 5660, column 45. See page 161 of PBP. (Severity: 5)
"$i" is declared but not used at line 5924, column 9. Unused variables clutter code and make it harder to read. (Severity: 3)
Reused variable name in lexical scope: $logfile at line 5976, column 2. Invent unique variable names. (Severity: 3)
Subroutine "teelaunch" does not end with "return" at line 5983, column 1. See page 197 of PBP. (Severity: 4)
Reused variable name in lexical scope: $logfile at line 5984, column 2. Invent unique variable names. (Severity: 3)
Close filehandles as soon as possible after opening them at line 5987, column 2. See page 209 of PBP. (Severity: 4)
"die" used instead of "croak" at line 5988, column 7. See page 283 of PBP. (Severity: 3)
Magic variable "*STDERR" should be assigned as "local" at line 5990, column 10. See pages 81,82 of PBP. (Severity: 4)
One-argument "select" used at line 5991, column 2. See page 224 of PBP. (Severity: 4)

View file

@ -1,16 +1,18 @@
REM $Id: test3.bat,v 1.13 2014/09/15 22:23:14 gilles Exp gilles $
@REM $Id: test3.bat,v 1.16 2014/11/14 17:09:50 gilles Exp gilles $
cd /D %~dp0
REM \$1 must be $1 on Windows
perl ./imapsync ^
--host1 p --user1 tata ^
--passfile1 secret.tata ^
--host2 p --user2 titi ^
--passfile2 secret.titi ^
--justfolders --nofoldersizes --folder "INBOX. blanc_begin" --regextrans2 "s,(\.|^) +,$1,g"
@REM \$1 must be $1 on Windows
@REM .\imapsync.exe --host1 ex-cashub1.caltech.edu --justconnect --host2 ex-cashub1.caltech.edu --ssl1 --ssl2 --ssl1_SSL_version SSLv3 --ssl2_SSL_version SSLv3
perl .\imapsync --tests_debug
@REM @EXIT
perl .\imapsync --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi ^
--foldersizes --usecache --folder "INBOX.[bracket]" --debugcache
@EXIT
EXIT

View file

@ -1,16 +1,16 @@
REM $Id: test3_gmail.bat,v 1.1 2013/07/23 13:29:56 gilles Exp gilles $
@REM $Id: test3_gmail.bat,v 1.2 2014/11/14 17:09:34 gilles Exp gilles $
cd /D %~dp0
REM ./imapsync.exe --modules_version
@REM ./imapsync.exe --modules_version
perl .\imapsync --host1 imap.gmail.com --ssl1 --user1 gilles.lamiral@gmail.com --passfile1 secret.gilles_gmail ^
--host2 imap.gmail.com --ssl2 --user2 gilles.lamiral@gmail.com --passfile2 secret.gilles_gmail ^
--folder INBOX --dry
@REM perl .\imapsync --host1 imap.gmail.com --ssl1 --user1 gilles.lamiral@gmail.com --passfile1 secret.gilles_gmail ^
@REM --host2 imap.gmail.com --ssl2 --user2 gilles.lamiral@gmail.com --passfile2 secret.gilles_gmail ^
@REM --folder INBOX --dry
PAUSE
@REM PAUSE
.\imapsync.exe --host1 imap.gmail.com --ssl1 --user1 gilles.lamiral@gmail.com --passfile1 secret.gilles_gmail ^
--host2 imap.gmail.com --ssl2 --user2 gilles.lamiral@gmail.com --passfile2 secret.gilles_gmail ^
--folder INBOX --dry
--usecache --nofoldersizes

17
W/test4.bat Normal file
View file

@ -0,0 +1,17 @@
@REM $Id: test4.bat,v 1.3 2014/11/14 17:09:34 gilles Exp gilles $
cd /D %~dp0
REM \$1 must be $1 on Windows
perl ./imapsync ^
--host1 p --user1 tata ^
--passfile1 secret.tata ^
--host2 p --user2 titi ^
--passfile2 secret.titi ^
--justfolders --nofoldersizes --folder "INBOX. blanc_begin" --regextrans2 "s,(\.|^) +,$1,g"
EXIT

View file

@ -1,6 +1,15 @@
REM
@REM
cd C:\msys\1.0\home\Admin\imapsync
@REM $Id: test_exe_2.bat,v 1.5 2014/11/14 17:09:34 gilles Exp gilles $
REM imapsync.exe \ --host1 p --user1 toto --passfile1 secret.toto \ --host2 p --user2 titi --passfile2 secret.titi
.\imapsync.exe \ --host1 p --user1 tata --passfile1 secret.tata \ --host2 p --user2 titi --passfile2 secret.titi
@REM cd C:\msys\1.0\home\Admin\imapsync
cd /D %~dp0
@REM imapsync.exe --host1 p --user1 toto --passfile1 secret.toto --host2 p --user2 titi --passfile2 secret.titi
@REM .\imapsync.exe --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi
.\imapsync.exe --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi ^
--foldersizes --usecache --folder "INBOX.[bracket]" --debugcache
@REM.\imapsync.exe --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi ^
@REM --dry --nofoldersizes --regextrans2 "s,(.*),\L$1," --justfolders

View file

@ -1,5 +1,5 @@
REM $Id: build_exe.bat,v 1.22 2014/05/21 01:15:28 gilles Exp gilles $
REM $Id: build_exe.bat,v 1.23 2014/11/14 17:05:08 gilles Exp gilles $
@ECHO OFF
ECHO Building imapsync.exe
@ -15,12 +15,14 @@ perl -mMail::IMAPClient ^
-mTime::Local -mURI::Escape -mData::Uniqid ^
-mFile::Copy::Recursive ^
-mIO::Tee ^
-mUnicode::String ^
-e ''
cd
@ECHO ON
@REM --link libssl32_.dll
pp -o imapsync.exe ^
--link libeay32_.dll --link libssl32_.dll ^
--link libeay32_.dll ^
--link zlib1_.dll --link ssleay32_.dll ^
-M Mail::IMAPClient ^
-M IO::Socket -M IO::Socket::IP -M IO::Socket::SSL -M IO::Socket::INET ^
@ -29,7 +31,8 @@ pp -o imapsync.exe ^
-M Time::Local -M URI::Escape -M Data::Uniqid ^
-M File::Copy::Recursive ^
-M IO::Tee ^
-M Unicode::String ^
imapsync
echo Done building imapsync.exe
pause

View file

@ -1,5 +1,5 @@
REM $Id: install_modules.bat,v 1.12 2014/05/22 10:16:12 gilles Exp gilles $
REM $Id: install_modules.bat,v 1.13 2014/11/14 17:10:17 gilles Exp gilles $
@ECHO OFF
@ -13,7 +13,10 @@ IF ERRORLEVEL 1 ECHO Perl needed. Install Strawberry Perl. Get it at http://stra
REM perl is there
FOR %%M in ( Mail::IMAPClient ^
Unicode::String ^
File::Copy::Recursive ^
Getopt::ArgvFile ^
Module::ScanDeps ^
PAR::Packer ^
Test::Pod ^
IO::Socket::IP ^
@ -26,15 +29,12 @@ FOR %%M in ( Mail::IMAPClient ^
Digest::HMAC_MD5 ^
Data::Uniqid URI::Escape ^
Authen::NTLM ^
Getopt::ArgvFile ^
Module::ScanDeps ^
IO::Tee ^
) DO ECHO Updating %%M ^
& perl -MCPAN -e "install %%M"
REM & perl -m%%M -e "" || perl -MCPAN -e "install %%M"
ECHO Perl modules for imapsync installed
REM PAUSE

363
imapsync
View file

@ -22,7 +22,7 @@ Synchronises mailboxes between two imap servers.
Good at IMAP migration. More than 52 different IMAP server softwares
supported with success, few failures.
$Revision: 1.596 $
$Revision: 1.607 $
=head1 SYNOPSIS
@ -424,6 +424,7 @@ Success stories reported with the following 62 imap servers
- MailEnable 4.23 [host1] [host2], 4.26 [host1][host2], 5 [host1]
- MDaemon 7.0.1, 8.0.2, 8.1, 9.5.4 (Windows server 2003 R2 platform),
9.6.5 [host1], 12 [host2], 12.0.3 [host1], 12.5.5 [host1],
13.5 [host2], 14.5 [host2]
- Mercury 4.1 (Windows server 2000 platform)
- Microsoft Exchange Server 5.5, 6.0.6249.0[host1], 6.0.6487.0[host1],
6.5.7638.1 [host2], 6.5 [host1], Exchange 2007 SP1 (with Update Rollup 2),
@ -558,7 +559,7 @@ Entries for imapsync:
Feedback (good or bad) will often be welcome.
$Id: imapsync,v 1.596 2014/09/04 17:17:36 gilles Exp gilles $
$Id: imapsync,v 1.607 2014/11/14 16:25:06 gilles Exp gilles $
=cut
@ -592,6 +593,7 @@ use Time::HiRes qw( time sleep ) ;
use Test::More 'no_plan' ;
use IPC::Open3 'open3' ;
use IO::Tee ;
use Unicode::String ;
#use Unix::Sysexits ;
# global variables
@ -691,14 +693,14 @@ my(
$skipcrossduplicates, $debugcrossduplicates,
$log, $logfile,
$disarmreadreceipts,
$mixdiffcasefolders,
$mixfolders, $skipemptyfolders,
);
# main program
# global variables initialisation
$rcs = '$Id: imapsync,v 1.596 2014/09/04 17:17:36 gilles Exp gilles $ ';
$rcs = '$Id: imapsync,v 1.607 2014/11/14 16:25:06 gilles Exp gilles $ ';
$total_bytes_transferred = 0;
$total_bytes_skipped = 0;
@ -772,8 +774,8 @@ $modules_version = defined( $modules_version ) ? $modules_version : 1 ;
# The second line (ending with "1 ;") can stay active or be commented,
# the result will be the same: no releasecheck by default.
$releasecheck = defined($releasecheck) ? $releasecheck : 0 ;
#$releasecheck = defined($releasecheck) ? $releasecheck : 1 ;
#$releasecheck = defined($releasecheck) ? $releasecheck : 0 ;
$releasecheck = defined($releasecheck) ? $releasecheck : 1 ;
my $warn_release = ($releasecheck) ? check_last_release() : '' ;
@ -825,7 +827,7 @@ $showpasswords = defined( $showpasswords ) ? $showpasswords : 0 ;
$fixslash2 = defined( $fixslash2 ) ? $fixslash2 : 1 ;
$fixInboxINBOX = defined( $fixInboxINBOX ) ? $fixInboxINBOX : 1 ;
$create_folder_old = defined( $create_folder_old ) ? $create_folder_old : 0 ;
$mixdiffcasefolders = defined( $mixdiffcasefolders ) ? $mixdiffcasefolders : 1 ;
$mixfolders = defined( $mixfolders ) ? $mixfolders : 1 ;
$delete2duplicates = 1 if ( $delete2 and ( ! defined( $delete2duplicates ) ) ) ;
@ -1036,7 +1038,8 @@ if ( @regexmess ) {
}
if ( @regexflag and not ( defined( flags_regex( '' ) ) ) ) {
die_clean( "Error: one of --regexmess option is bad, check it" ) ;
# string undef means one of the eval regex was bad.
die_clean( "Error: one of --regexflag option is bad, check it" ) ;
}
my $imap1 = ();
@ -1137,7 +1140,7 @@ else {
# consider (optional) includes and excludes
if ( scalar( @include ) ) {
foreach my $include ( @include ) {
my @included_folders = grep { /$include/x } @h1_folders_all ;
my @included_folders = grep { /$include/ } @h1_folders_all ;
add_to_requested_folders( @included_folders ) ;
my $included_folders = join( " ", map( "[$_]", @included_folders ) ) ;
print "Including folders matching pattern '$include': " . $included_folders . "\n" ;
@ -1147,7 +1150,7 @@ if ( scalar( @include ) ) {
if ( scalar( @exclude ) ) {
foreach my $exclude ( @exclude ) {
my @requested_folder = sort( keys( %requested_folder ) ) ;
my @excluded_folders = grep { /$exclude/x } @requested_folder ;
my @excluded_folders = grep { /$exclude/ } @requested_folder ;
remove_from_requested_folders( @excluded_folders ) ;
my $excluded_folders = join( " ", map( "[$_]", @excluded_folders ) ) ;
print "Excluding folders matching pattern '$exclude': " . $excluded_folders . "\n" ;
@ -1206,39 +1209,41 @@ foreach my $h1_fold ( @h1_folders_wanted ) {
}
@h2_folders_from_1_wanted = sort keys(%h2_folders_from_1_wanted);
foreach my $h1_fold (@h1_folders_all) {
my $h2_fold;
$h2_fold = imap2_folder_name($h1_fold);
$h2_folders_from_1_all{$h2_fold}++;
foreach my $h1_fold ( @h1_folders_all ) {
my $h2_fold ;
$h2_fold = imap2_folder_name( $h1_fold ) ;
$h2_folders_from_1_all{ $h2_fold }++ ;
}
print
"++++ Listing folders\n",
"Host1 folders list:\n", jux_utf8_list( @h1_folders_all ), "\n",
"Host2 folders list:\n", jux_utf8_list( @h2_folders_all ), "\n" ;
print
"Host1 subscribed folders list: ",
jux_utf8_list( sort keys( %h1_subscribed_folder ) ), "\n"
if ( $subscribed ) ;
my @h2_folders_not_in_1;
@h2_folders_not_in_1 = list_folders_in_2_not_in_1( ) ;
print "Folders in host2 not in host1:\n",
jux_utf8_list( @h2_folders_not_in_1 ), "\n" ;
if ( $foldersizes ) {
( $h1_nb_msg_at_start, $h1_bytes_start ) = foldersizes( "Host1", $imap1, $search1, @h1_folders_wanted ) ;
( $h2_nb_msg_start, $h2_bytes_start ) = foldersizes( "Host2", $imap2, $search2, @h2_folders_from_1_wanted ) ;
$fast or sleep( 2 ) ;
}
exit_clean( 0 ) if ( $justfoldersizes ) ;
exit_clean(0) if ($justfoldersizes);
print
"++++ Listing folders\n",
"Host1 folders list:\n", map( { "[$_]\n" } @h1_folders_all ), "\n",
"Host2 folders list:\n", map( { "[$_]\n" } @h2_folders_all ), "\n" ;
print
"Host1 subscribed folders list: ",
map( { "[$_] " } sort keys( %h1_subscribed_folder ) ), "\n"
if ( $subscribed ) ;
my @h2_folders_not_in_1;
@h2_folders_not_in_1 = list_folders_in_2_not_in_1();
print "Folders in host2 not in host1:\n",
map( { "[$_]\n" } @h2_folders_not_in_1 ), "\n" ;
delete_folders_in_2_not_in_1() if $delete2folders;
delete_folders_in_2_not_in_1( ) if $delete2folders;
# folder loop
print "++++ Looping on each folder\n";
@ -1253,15 +1258,24 @@ my %h2_folders_of_md5 = ( ) ;
FOLDER: foreach my $h1_fold ( @h1_folders_wanted ) {
last FOLDER if $imap1->IsUnconnected();
last FOLDER if $imap2->IsUnconnected();
last FOLDER if $imap1->IsUnconnected( ) ;
last FOLDER if $imap2->IsUnconnected( ) ;
my $h2_fold = imap2_folder_name( $h1_fold ) ;
#relogin1( ) if ( $relogin1 ) ;
printf( "%-35s -> %-35s\n", "[$h1_fold]", "[$h2_fold]" ) ;
printf( "%-35s -> %-35s\n", jux_utf8( $h1_fold ), jux_utf8( $h2_fold ) ) ;
# host1 can not be fetched read only, select is needed because of expunge.
select_folder( $imap1, $h1_fold, 'Host1' ) or next FOLDER ;
#print $imap1->History( ) ;
my $messages_count = count_from_select( $imap1->History ) ;
$debug and print "Host1 messages count = [$messages_count]\n" ;
if ( $skipemptyfolders and 0 == $messages_count ) {
print "Skipping empty host1 folder [$h1_fold]\n" ;
next FOLDER ;
}
if ( ! exists( $h2_folders_all{ $h2_fold } ) ) {
create_folder( $imap2, $h2_fold, $h1_fold ) or next FOLDER ;
@ -1279,13 +1293,11 @@ FOLDER: foreach my $h1_fold ( @h1_folders_wanted ) {
#print "%%% @select_results\n" ;
my $permanentflags2 = permanentflags( @select_results ) ;
( $debug or $debugflags ) and print "permanentflags: $permanentflags2\n" ;
( $debug or $debugflags ) and print "Host2 permanentflags: $permanentflags2\n" ;
if ( $expunge or $expunge1 ){
print "Expunging host1 $h1_fold $dry_message\n" ;
unless($dry) { $imap1->expunge() } ;
#print "Expunging host2 $h2_fold\n" ;
#unless($dry) { $imap2->expunge() } ;
unless( $dry ) { $imap1->expunge( ) } ;
}
if ( ( ( $subscribe and exists $h1_subscribed_folder{ $h1_fold } ) or $subscribe_all )
@ -1296,12 +1308,12 @@ FOLDER: foreach my $h1_fold ( @h1_folders_wanted ) {
next FOLDER if ($justfolders);
last FOLDER if $imap1->IsUnconnected();
last FOLDER if $imap2->IsUnconnected();
last FOLDER if $imap1->IsUnconnected( ) ;
last FOLDER if $imap2->IsUnconnected( ) ;
my $h1_msgs_all_hash_ref = { } ;
my @h1_msgs = select_msgs( $imap1, $h1_msgs_all_hash_ref, $search1, $h1_fold );
last FOLDER if $imap1->IsUnconnected();
last FOLDER if $imap1->IsUnconnected( ) ;
my $h1_msgs_nb = scalar( @h1_msgs ) ;
$h1{ $h1_fold }{ 'messages_nb' } = $h1_msgs_nb ;
@ -1311,7 +1323,7 @@ FOLDER: foreach my $h1_fold ( @h1_folders_wanted ) {
my $h2_msgs_all_hash_ref = { } ;
my @h2_msgs = select_msgs( $imap2, $h2_msgs_all_hash_ref, $search2, $h2_fold ) ;
last FOLDER if $imap2->IsUnconnected();
last FOLDER if $imap2->IsUnconnected( ) ;
my $h2_msgs_nb = scalar( @h2_msgs ) ;
$h2{ $h2_fold }{ 'messages_nb' } = $h2_msgs_nb ;
@ -1326,8 +1338,8 @@ FOLDER: foreach my $h1_fold ( @h1_folders_wanted ) {
my $h1_uidvalidity = $imap1->uidvalidity( ) || '' ;
my $h2_uidvalidity = $imap2->uidvalidity( ) || '' ;
last FOLDER if $imap1->IsUnconnected() ;
last FOLDER if $imap2->IsUnconnected() ;
last FOLDER if $imap1->IsUnconnected( ) ;
last FOLDER if $imap2->IsUnconnected( ) ;
if ( $usecache ) {
print "cache directory: $cache_dir\n" ;
@ -1609,8 +1621,8 @@ FOLDER: foreach my $h1_fold ( @h1_folders_wanted ) {
$debug and print "Host2 uidnext: $h2_uidnext\n" ;
$h2_uidguess = $h2_uidnext ;
MESS: foreach my $m_id (@h1_hash_keys_sorted_by_uid) {
last FOLDER if $imap1->IsUnconnected() ;
last FOLDER if $imap2->IsUnconnected() ;
last FOLDER if $imap1->IsUnconnected( ) ;
last FOLDER if $imap2->IsUnconnected( ) ;
#print "h1_nb_msg_processed: $h1_nb_msg_processed\n" ;
my $h1_size = $h1_hash{$m_id}{'s'};
@ -1659,7 +1671,7 @@ FOLDER: foreach my $h1_fold ( @h1_folders_wanted ) {
$debug and print
"Host1 size msg $h1_fold/$h1_msg = $h1_size <> $h2_size = Host2 $h2_fold/$h2_msg\n";
}
last FOLDER if $imap2->IsUnconnected() ;
last FOLDER if $imap2->IsUnconnected( ) ;
if( $delete ) {
my $expunge_message = '' ;
@ -1673,8 +1685,8 @@ FOLDER: foreach my $h1_fold ( @h1_folders_wanted ) {
}
}
# END MESS: loop
last FOLDER if $imap1->IsUnconnected();
last FOLDER if $imap2->IsUnconnected();
last FOLDER if $imap1->IsUnconnected( ) ;
last FOLDER if $imap2->IsUnconnected( ) ;
MESS_IN_CACHE: foreach my $h1_msg ( @h1_msgs_in_cache ) {
my $h2_msg = $cache_1_2_ref->{ $h1_msg } ;
$debugcache and print "cache messages update flags $h1_msg->$h2_msg\n";
@ -1683,15 +1695,15 @@ FOLDER: foreach my $h1_fold ( @h1_folders_wanted ) {
$total_bytes_skipped += $h1_size;
$nb_msg_skipped += 1;
$h1_nb_msg_processed +=1 ;
last FOLDER if $imap2->IsUnconnected();
last FOLDER if $imap2->IsUnconnected( ) ;
}
#print "Messages by uid: ", map { "$_ " } keys %h1_msgs_copy_by_uid, "\n" ;
MESS_BY_UID: foreach my $h1_msg ( sort { $a <=> $b } keys %h1_msgs_copy_by_uid ) {
#
$debug and print "Copy by uid $h1_fold/$h1_msg\n" ;
last FOLDER if $imap1->IsUnconnected();
last FOLDER if $imap2->IsUnconnected();
last FOLDER if $imap1->IsUnconnected( ) ;
last FOLDER if $imap2->IsUnconnected( ) ;
my $h2_msg = copy_message( $h1_msg, $h1_fold, $h2_fold, $h1_fir_ref, $permanentflags2, $cache_dir ) ;
if( $delete2 and exists( $h2_folders_from_1_several{ $h2_fold } ) and $h2_msg ) {
print "msg $h2_fold/$h2_msg will cancel deletion [fresh copy] on host2\n" ;
@ -1726,20 +1738,9 @@ sub total_bytes_max_reached {
print "++++ End looping on each folder\n";
$debug and print "Time: ", timenext(), " s\n";
#print memory_consumption();
print memory_consumption( ) if ( $debugmemory ) ;
if ( $foldersizesatend ) {
timenext() ;
# Get all folders on host2 again since new were created
@h2_folders_all = sort $imap2->folders();
for ( @h2_folders_all ) {
$h2_folders_all{ $_ } = 1 ;
$h2_folders_all_UPPER{ uc( $_ ) } = 1 ;
} ;
( $h1_nb_msg_end, $h1_bytes_end ) = foldersizes( "Host1", $imap1, $search1, @h1_folders_wanted ) ;
( $h2_nb_msg_end, $h2_bytes_end ) = foldersizes( "Host2", $imap2, $search2, @h2_folders_from_1_wanted ) ;
}
foldersizesatend( ) if ( $foldersizesatend ) ;
$imap1->logout( ) unless lost_connection($imap1, "for host1 [$host1]");
$imap2->logout( ) unless lost_connection($imap2, "for host2 [$host2]");
@ -1754,6 +1755,19 @@ exit_clean( 0 ) ;
# subroutines
sub foldersizesatend {
timenext( ) ;
return( ) if ( $imap1->IsUnconnected( ) ) ;
return( ) if ( $imap2->IsUnconnected( ) ) ;
# Get all folders on host2 again since new were created
@h2_folders_all = sort $imap2->folders();
for ( @h2_folders_all ) {
$h2_folders_all{ $_ } = 1 ;
$h2_folders_all_UPPER{ uc( $_ ) } = 1 ;
} ;
( $h1_nb_msg_end, $h1_bytes_end ) = foldersizes( "Host1", $imap1, $search1, @h1_folders_wanted ) ;
( $h2_nb_msg_end, $h2_bytes_end ) = foldersizes( "Host2", $imap2, $search2, @h2_folders_from_1_wanted ) ;
}
sub size_filtered_flag {
my $h1_size = shift ;
@ -1849,7 +1863,7 @@ sub _filter {
sub lost_connection {
my($imap, $error_message) = @_;
if ( $imap->IsUnconnected() ) {
if ( $imap->IsUnconnected( ) ) {
$nb_errors++;
my $lcomm = $imap->LastIMAPCommand || "";
my $einfo = $imap->LastError || @{$imap->History}[-1] || "";
@ -1962,6 +1976,9 @@ sub modules_VERSION {
eval { require Data::Uniqid; $v = $Data::Uniqid::VERSION } or $v = "?" ;
push ( @list_version, module_version_str( 'Data::Uniqid', $v ) ) ;
eval { require Unicode::String; $v = $Unicode::String::VERSION } or $v = "?" ;
push ( @list_version, module_version_str( 'Unicode::String', $v ) ) ;
return( @list_version ) ;
}
@ -2380,8 +2397,8 @@ sub banner_imapsync {
my @argv = @_ ;
my $banner_imapsync = join("",
'$RCSfile: imapsync,v $ ',
'$Revision: 1.596 $ ',
'$Date: 2014/09/04 17:17:36 $ ',
'$Revision: 1.607 $ ',
'$Date: 2014/11/14 16:25:06 $ ',
"\n",localhost_info(), "\n",
"Command line used:\n",
"$0 ", command_line_nopassword( @argv ), "\n",
@ -2484,6 +2501,64 @@ sub tests_fix_Inbox_INBOX_mapping {
return( ) ;
}
sub jux_utf8_list {
my @s_inp = @_ ;
my $s_out = '' ;
foreach my $s ( @s_inp ) {
$s_out .= jux_utf8( $s ) . "\n" ;
}
return( $s_out ) ;
}
sub tests_jux_utf8_list {
ok( '' eq jux_utf8_list( ), 'jux_utf8_list: void' ) ;
ok( "[]\n" eq jux_utf8_list( '' ), 'jux_utf8_list: empty string' ) ;
ok( "[INBOX]\n" eq jux_utf8_list( 'INBOX' ), 'jux_utf8_list: INBOX' ) ;
ok( "[&ANY-] = [Ö]\n" eq jux_utf8_list( '&ANY-' ), 'jux_utf8_list: &ANY-' ) ;
return( 0 ) ;
}
sub jux_utf8 {
# juxtapose utf8 at the right if different
my ( $s_utf7 ) = shift ;
my ( $s_utf8 ) = imap_utf7_decode( $s_utf7 ) ;
if ( $s_utf7 eq $s_utf8 ) {
return( "[$s_utf7]" ) ;
}else{
#print "[$s_utf7] = [$s_utf8]\n" ;
return( "[$s_utf7] = [$s_utf8]" ) ;
}
}
sub tests_jux_utf8 {
ok( '[INBOX]' eq jux_utf8( 'INBOX'), 'jux_utf8: INBOX => [INBOX]' ) ;
ok( '[&ZTZO9nux-] = [æ”¶ä»¶ç®±]' eq jux_utf8( '&ZTZO9nux-'), 'jux_utf8: &ZTZO9nux- => [&ZTZO9nux-] = [æ”¶ä»¶ç®±]' ) ;
ok( '[&ANY-] = [Ö]' eq jux_utf8( '&ANY-'), 'jux_utf8: &ANY- => [&ANY-] = [Ö]' ) ;
return( 0 ) ;
}
# Copied from http://cpansearch.perl.org/src/FABPOT/Unicode-IMAPUtf7-2.01/lib/Unicode/IMAPUtf7.pm
sub imap_utf7_decode {
my ( $s ) = shift( @_ ) ;
# Algorithm
# On remplace , par / dans les BASE 64 (, entre & et -)
# On remplace les &, non suivi d'un - par +
# On remplace les &- par &
$s =~ s/\+/PLUSPLACEHOLDER/g ;
$s =~ s/&([^,&\-]*),([^,\-&]*)\-/&$1\/$2\-/g ;
$s =~ s/&(?!\-)/\+/g ;
$s =~ s/&\-/&/g ;
$s =~ s/PLUSPLACEHOLDER/+-/g ;
return( Unicode::String::utf7( $s )->utf8 ) ;
}
sub select_folder {
my ( $imap, $folder, $hostside ) = @_ ;
if ( ! $imap->select( $folder ) ) {
@ -2498,6 +2573,21 @@ sub select_folder {
}
}
sub count_from_select {
my @lines = @_ ;
my $count ;
foreach my $line ( @lines ) {
#print "line = [$line]\n" ;
if ( $line =~ m/^\*\s+(\d+)\s+EXISTS/ ) {
$count = $1 ;
return( $count ) ;
}
}
return( undef ) ;
}
sub examine_folder {
my ( $imap, $folder, $hostside ) = @_ ;
if ( ! $imap->examine( $folder ) ) {
@ -2558,9 +2648,9 @@ sub create_folder {
return( 1 ) ;
}
if ( ( not $mixdiffcasefolders )
if ( ( not $mixfolders )
and ( $imap2->exists( $h2_fold ) ) ) {
print "Folder [$h2_fold] already exists and --nomixdiffcasefolders is set\n" ;
print "Folder [$h2_fold] already exists and --nomixfolders is set\n" ;
return( 0 ) ;
}
@ -2966,12 +3056,24 @@ ok('spam.spam' eq imap2_folder_name('spam/spam'), 'imap2_folder_name: spam/spam
ok('spam/spam' eq imap2_folder_name('spam.spam'), 'imap2_folder_name: spam.spam -> spam/spam');
ok('spam.spam/spam' eq imap2_folder_name('spam/spam.spam'), 'imap2_folder_name: spam/spam.spam -> spam.spam/spam');
$fixslash2 = 0 ;
$h1_prefix = ' ';
ok('spam.spam/spam' eq imap2_folder_name('spam/spam.spam'), 'imap2_folder_name: spam/spam.spam -> spam.spam/spam');
ok('spam.spam/spam' eq imap2_folder_name(' spam/spam.spam'), 'imap2_folder_name: spam/spam.spam -> spam.spam/spam');
$h1_sep = '.' ;
$h2_sep = '/' ;
$h1_prefix = 'INBOX.' ;
$h2_prefix = '' ;
@regextrans2 = ('s,(.*),\U$1,') ;
ok( 'BLABLA' eq imap2_folder_name( 'blabla' ), 'imap2_folder_name: blabla' ) ;
ok( 'TEST/TEST/TEST/TEST' eq imap2_folder_name( 'INBOX.TEST.test.Test.tesT' ), 'imap2_folder_name: INBOX.TEST.test.Test.tesT' ) ;
@regextrans2 = ( 's,(.*),\L$1,' ) ;
ok( 'test/test/test/test' eq imap2_folder_name( 'INBOX.TEST.test.Test.tesT' ), 'imap2_folder_name: INBOX.TEST.test.Test.tesT' ) ;
return( ) ;
@ -3030,7 +3132,7 @@ sub foldersizes {
foreach my $folder ( @folders ) {
my $stot = 0 ;
my $nb_msgs = 0 ;
printf( "$side folder %-35s", "[$folder]" ) ;
printf( "$side folder %-35s", jux_utf8( $folder ) ) ;
if ( 'Host2' eq $side and not exists( $h2_folders_all_UPPER{ uc( $folder ) } ) ) {
print(" does not exist yet\n") ;
next ;
@ -3040,6 +3142,7 @@ sub foldersizes {
next ;
}
last if $imap->IsUnconnected( ) ;
# FTGate is RFC buggy with EXAMINE it does not act as SELECT
#unless ( $imap->examine( $folder ) ) {
unless ( $imap->select( $folder ) ) {
@ -3049,13 +3152,15 @@ sub foldersizes {
$nb_errors++ ;
next ;
}
last if $imap->IsUnconnected() ;
last if $imap->IsUnconnected( ) ;
my $hash_ref = { } ;
my @msgs = select_msgs( $imap, undef, $search_cmd, $folder ) ;
$nb_msgs = scalar( @msgs ) ;
my $biggest_in_folder = 0 ;
@$hash_ref{ @msgs } = ( undef ) if @msgs ;
last if $imap->IsUnconnected( ) ;
if ( $nb_msgs > 0 and @msgs ) {
if ( $abletosearch ) {
$imap->fetch_hash( \@msgs, "RFC822.SIZE", $hash_ref) or die_clean("$@" ) ;
@ -3850,10 +3955,13 @@ sub append_message_on_host2 {
my $time_spent = timesince( $begin_transfer_time ) ;
my $rate = bytes_display_string( $total_bytes_transferred / $time_spent ) ;
my $eta = eta( $time_spent, $h1_nb_msg_processed, $h1_nb_msg_at_start, $nb_msg_transferred ) ;
printf( "msg %s/%-19s copied to %s/%-10s %.2f msgs/s %s/s %s\n",
$h1_fold, "$h1_msg {$string_len}", $h2_fold, $new_id, $nb_msg_transferred/$time_spent, $rate, $eta );
my $eta = eta( $time_spent,
$h1_nb_msg_processed, $h1_nb_msg_at_start, $nb_msg_transferred ) ;
my $amount_transferred = bytes_display_string( $total_bytes_transferred ) ;
printf( "msg %s/%-19s copied to %s/%-10s %.2f msgs/s %s/s %s copied %s\n",
$h1_fold, "$h1_msg {$string_len}", $h2_fold, $new_id, $nb_msg_transferred/$time_spent, $rate,
$amount_transferred,
$eta );
sleep_if_needed( $time_spent, $total_bytes_transferred, $nb_msg_transferred ) ;
if ( $usecache and $cacheaftercopy and $new_id =~ m{^\d+$}x ) {
$debugcache and print "touch $cache_dir/${h1_msg}_$new_id\n" ;
@ -3950,7 +4058,7 @@ sub eta {
my $time_remaining = time_remaining( $my_time_spent, $h1_nb_processed, $h1_nb_msg_start, $nb_transferred ) ;
my $nb_msg_remaining = $h1_nb_msg_start - $h1_nb_processed ;
my $eta_date = localtime( time + $time_remaining ) ;
return( sprintf( "ETA: %s %1.0f s %s msgs left", $eta_date, $time_remaining, $nb_msg_remaining ) ) ;
return( sprintf( "ETA: %s %1.0f s %s/%s msgs left", $eta_date, $time_remaining, $nb_msg_remaining, $h1_nb_msg_start ) ) ;
}
sub time_remaining {
@ -4066,10 +4174,26 @@ sub tests_cache_dir_fix {
ok( 'i\\\\ii' eq cache_dir_fix('i\\ii'), 'cache_dir_fix: i\\ii -> i\\\\\\\\ii' );
ok( '\\\\ ' eq cache_dir_fix('\\ '), 'cache_dir_fix: \\ -> \\\\\ ' );
ok( '\\\\ ' eq cache_dir_fix('\ '), 'cache_dir_fix: \ -> \\\\\ ' );
ok( '\[bracket\]' eq cache_dir_fix('[bracket]'), 'cache_dir_fix: [bracket] -> \[bracket\]' );
return( ) ;
}
sub cache_dir_fix_win {
my $cache_dir = shift ;
$cache_dir =~ s/(\[|\])/[$1]/xg ;
#print "cache_dir_fix_win: $cache_dir\n" ;
return( $cache_dir ) ;
}
sub tests_cache_dir_fix_win {
ok( 'lalala' eq cache_dir_fix_win('lalala'), 'cache_dir_fix_win: lalala -> lalala' );
ok( '[[]bracket[]]' eq cache_dir_fix_win('[bracket]'), 'cache_dir_fix_win: [bracket] -> [[]bracket[]]' );
return( ) ;
}
sub get_cache {
my ( $cache_dir, $h1_msgs_ref, $h2_msgs_ref, $h1_msgs_all_hash_ref, $h2_msgs_all_hash_ref ) = @_;
@ -4078,8 +4202,12 @@ sub get_cache {
-d $cache_dir or return( undef ); # exit if cache directory doesn't exist
$debugcache and print "cache_dir : $cache_dir\n";
#$cache_dir =~ s{\\}{\\\\}g;
$cache_dir = cache_dir_fix( $cache_dir ) if ( 'MSWin32' ne $OSNAME ) ;
if ( 'MSWin32' ne $OSNAME ) {
$cache_dir = cache_dir_fix( $cache_dir ) ;
}else{
$cache_dir = cache_dir_fix_win( $cache_dir ) ;
}
$debugcache and print "cache_dir_fix: $cache_dir\n" ;
@ -4503,6 +4631,8 @@ sub tests_cache_folder {
ok( 'D:/path/fold1/fold2' eq cache_folder( 'D:', '/path', 'fold1', 'fold2'), 'cache_folder: /path, fold1, fold2 -> /path/fold1/fold2' ) ;
ok( 'D:/pa_th/fold1/fold2' eq cache_folder( 'D:', '/pa*th', 'fold1', 'fold2'), 'cache_folder: /pa*th, fold1, fold2 -> /path/fold1/fold2' ) ;
ok( 'D:/_p_a__th/fol_d1/fold2' eq cache_folder( 'D:', '/>p<a|*th', 'fol*d1', 'fold2'), 'cache_folder: />p<a|*th, fol*d1, fold2 -> /path/fol_d1/fold2' ) ;
ok( '//' eq cache_folder( '', '', '', ''), 'cache_folder: -> //' ) ;
ok( '//_______' eq cache_folder( '', '', '', '*|?:"<>'), 'cache_folder: *|?:"<> -> //_______' ) ;
return( ) ;
}
@ -5079,7 +5209,7 @@ sub check_last_release {
}
sub imapsync_version {
my $rcs_imapsync = '$Id: imapsync,v 1.596 2014/09/04 17:17:36 gilles Exp gilles $ ' ;
my $rcs_imapsync = '$Id: imapsync,v 1.607 2014/11/14 16:25:06 gilles Exp gilles $ ' ;
my $imapsync_version ;
if ( $rcs_imapsync =~ m{,v\s+(\d+\.\d+)}xo ) {
@ -5476,7 +5606,7 @@ sub tests_good_date {
ok('"18-Dec-2002 15:07:00 +0000"' eq good_date('Wednesday, December 18, 2002 03:07 PM'), 'good_date kbtoys.com orders');
ok('"16-Dec-2004 02:01:49 -0500"' eq good_date('Dec 16 2004 02:01:49 -0500'), 'good_date jr.com orders');
ok('"21-Jun-2001 11:11:11 +0000"' eq good_date('21-Jun-2001'), 'good_date register.com domain transfer');
ok('"18-Nov-2012 18:34:38 +0100"' eq good_date('Sun, 18 Nov 2012 18:34:38 +0100'), 'good_date pop2imap bug (Westeuropäische Normalzeit)');
ok('"18-Nov-2012 18:34:38 +0100"' eq good_date('Sun, 18 Nov 2012 18:34:38 +0100'), 'good_date pop2imap bug (Westeuropäische Normalzeit)');
return( ) ;
}
@ -5908,10 +6038,10 @@ Several options are mandatory.
--authmech1 <string> : Auth mechanism to use with host1:
PLAIN, LOGIN, CRAM-MD5 etc. Use UPPERCASE.
--authmech2 <string> : Auth mechanism to use with host2. See --authmech1
--ssl1 : Use an SSL connection on host1.
--ssl2 : Use an SSL connection on host2.
--tls1 : Use an TLS connection on host1.
--tls2 : Use an TLS connection on host2.
--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.
--timeout <int> : Connections timeout in seconds. Default is 120.
0 means no timeout.
@ -5925,6 +6055,12 @@ Several options are mandatory.
--folderlast <string> : Sync this folder last. --folderlast "[Gmail]/All Mail"
--folderlast <string> : 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 <regex> : Sync folders matching this regular expression
Blancs like in "foo bar" have to be written "foo\\ bar"
--include <regex> : or this one, etc.
@ -5998,7 +6134,7 @@ Several options are mandatory.
--expunge2 : Expunge messages on host2 after messages transfer.
--uidexpunge2 : uidexpunge messages on the host2 account
that are not on the host1 account, requires --delete2
--nomixdiffcasefolders : Avoid merging folders that are considered different on
--nomixfolders : Avoid merging folders that are considered different on
host1 but the same on destination host2 because of
case sensitivities and insensitivities.
@ -6122,15 +6258,15 @@ EOF
sub get_options {
my $numopt = scalar(@ARGV);
my $argv = join("¤", @ARGV);
my $numopt = scalar( @ARGV ) ;
my $argv = join( "¤", @ARGV ) ;
$test_builder = Test::More->builder;
$test_builder->no_ending(1);
$test_builder = Test::More->builder ;
$test_builder->no_ending( 1 ) ;
if($argv =~ m/-delete¤2/x) {
print "May be you mean --delete2 instead of --delete 2\n";
exit 1;
if ( $argv =~ m/-delete¤2/x ) {
print "May be you mean --delete2 instead of --delete 2\n" ;
exit( 1 ) ;
}
my $opt_ret = GetOptions(
"debug!" => \$debug,
@ -6172,6 +6308,8 @@ sub get_options {
"fixslash2!" => \$fixslash2,
"fixInboxINBOX!" => \$fixInboxINBOX,
"regextrans2=s" => \@regextrans2,
"mixfolders!" => \$mixfolders,
"skipemptyfolders!" => \$skipemptyfolders,
"regexmess=s" => \@regexmess,
"disarmreadreceipts!" => \$disarmreadreceipts,
"regexflag=s" => \@regexflag,
@ -6271,26 +6409,26 @@ sub get_options {
"debugcrossduplicates!" => \$debugcrossduplicates,
"log!" => \$log,
"logfile=s" => \$logfile,
);
) ;
$debug and print "get options: [$opt_ret]\n";
$debug and print "get options: [$opt_ret]\n" ;
# just the version
print imapsync_version(), "\n" and exit if ($version) ;
if ($tests) {
$test_builder->no_ending(0);
tests();
exit;
if ( $tests ) {
$test_builder->no_ending( 0 ) ;
tests( ) ;
exit ;
}
if ($tests_debug) {
$test_builder->no_ending(0);
tests_debug();
exit;
if ( $tests_debug ) {
$test_builder->no_ending( 0 ) ;
tests_debug( ) ;
exit ;
}
$help = 1 if ! $numopt;
load_modules();
load_modules( );
# exit with --help option or no option at all
usage( ) and exit( ) if ( $help or not $numopt ) ;
@ -6304,10 +6442,16 @@ sub get_options {
sub tests_debug {
SKIP: {
skip "No test in normal run" if ( not $tests_debug );
skip "No test in normal run" if ( not $tests_debug ) ;
#tests_mkpath( ) ;
#tests_logfile( ) ;
tests_regexmess();
#tests_regexmess( ) ;
#tests_imap2_folder_name( ) ;
#tests_jux_utf8( ) ;
#tests_jux_utf8_list( ) ;
tests_cache_folder( ) ;
tests_cache_dir_fix( ) ;
tests_cache_dir_fix_win( ) ;
}
return( ) ;
}
@ -6347,6 +6491,7 @@ sub tests {
tests_epoch( ) ;
tests_add_header( ) ;
tests_cache_dir_fix( ) ;
tests_cache_dir_fix_win( ) ;
tests_filter_forbidden_characters( ) ;
tests_cache_folder( ) ;
tests_time_remaining( ) ;
@ -6363,6 +6508,8 @@ sub tests {
tests_sleep_max_messages( ) ;
tests_sleep_max_bytes( ) ;
tests_logfile( ) ;
tests_jux_utf8( ) ;
tests_jux_utf8_list( ) ;
}
return( ) ;
}

View file

@ -7,7 +7,7 @@
<title>Official imapsync migration tool ( release <!--#exec cmd="cat ./VERSION"--> )</title>
<meta name="generator" content="Bluefish 1.0.7"/>
<meta name="author" content="Gilles LAMIRAL"/>
<meta name="date" content="2014-09-16T00:19:01+0200"/>
<meta name="date" content="2014-11-14T18:01:28+0100"/>
<meta name="copyright" content="None"/>
<meta name="keywords" content="imap, transfert, migration"/>
<meta name="description" content="imap migration tool"/>
@ -23,9 +23,10 @@
<body>
<!--
<div id="fb-root"></div>
<script type="text/javascript" src="W/fb-root.js"></script>
-->
<ul class="none">
<li>Are your <a href="#imap_server_success">imap servers <b>supported</b></a> by imapsync?</li>
<li>Buy <a href="#buy_all"><b>imapsync</b></a> ( imapsync.exe + source code for any OS )</li>
@ -112,7 +113,8 @@ See detailed explanation and motivation here when
<ul>
<li><b>4000 to 5000 </b>users per month (48000 users a year).</li>
<li>6 to 39 millions mailboxes transfers per month.</li>
<li><b>158 millions</b> transfers for 2013, that is five whole mailboxes synced per second. 2014 should reach more than 300 millions transfers.</li>
<li><b>158 millions</b> transfers for 2013, that is five whole mailboxes synced per second.
2014 should reach more than 220 millions transfers.</li>
<li><b>Operating systems</b> run by imapsync users (in 2013):
<ul>
@ -162,7 +164,7 @@ Check <a href="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-4279">CV
<!--
<ul>
<li><b>1.584</b></li>
<li><b>1.604</b></li>
<li><b>Enhancement</b>: </li>
<li><b>Enhancement</b>: </li>
<li><b>Enhancement</b>: </li>
@ -182,6 +184,30 @@ Check <a href="http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-4279">CV
</ul>
-->
<ul>
<li><b>1.607</b> Folders showed also in utf8.</li>
<li><b>Caveat to upgrade on Unix!</b>: New <b>Unicode::String</b> Perl module dependency, for utf8 output. See the <a href="INSTALL">INSTALL</a> file.</li>
<li><b>Enhancement</b>: Added --skipemptyfolders to skip empty host1 folders. They are not created on host2.</li>
<li><b>Enhancement</b>: Windows exe now uses IO::SSL 2.002 instead of 1.98 (is it an really an enhancement?).</li>
<li><b>Usability</b>: Remove /x from regexes applied with --include and --exclude. Blanks no longer have to be explicit with \ or [ ].</li>
<li><b>Usability</b>: Added utf8 output for folder names, utf7imap special characters are not user friendly readable</li>
<li><b>Usability</b>: Moved foldersizes output after folders lists output.</li>
<li><b>Usability</b>: Added total size transferred after each message copied.</li>
<li><b>Usability</b>: After ETA added number of total to be synced, as a denominator dddd after each message copied, nnn/dddd,
where nnn is the number of messages copied. Before there was only nnn without /dddd.</li>
<li><b>Bug fix</b>: Cache fix on Windows. File paths with brackets [] are special, they have to be escaped with glob.
For example, [Gmail] must be written [[]Gmail[]].</li>
<li><b>Bug fix</b>: Added several checks if IsUnconnected. Goal avoid imap commands while disconnected.
Reconnexion would be better anyway.</li>
</ul>
<ul>
<li><b>1.597</b> Small things</li>
<li><b>Enhancement</b>: Added --nomixfolders to avoid merging folders that are considered different on host1 but the same on destination host2
because of case sensitivities and insensitivities.</li>
<li><b>Bug fix</b>: Fixed "imapsync doesn't see created folders in the listing of folder sizes at the end". (second time this bug shows up)</li>
</ul>
<ul>
<li><b>1.592</b> Logging by default! (an internal feature now)</li>
@ -640,7 +666,7 @@ that's my job.
<li><b>MailEnable</b> 4.23 [host1][host2], 4.26 [host1][host2], 5 [host1]
(<a href="http://www.mailenable.com/">http://www.mailenable.com/</a>) </li>
<li>MDaemon 7.0.1, 8.0.2, 8.1, 9.5.4 (Windows server 2003 R2 platform), 9.6.5 [host1],
12 [host2], 12.0.3 [host1], 12.5.5 [host1]
12 [host2], 12.0.3 [host1], 12.5.5 [host1], 13.5 [host2], 14.5 [host2]
(<a href="http://www.altn.com/">http://www.altn.com/</a>) </li>
<li>Mercury 4.1 (Windows server 2000 platform) (<a href="http://www.pmail.com/">http://www.pmail.com/</a>) </li>
<li><b>Microsoft Exchange Server</b> 5.5, 6.0.6249.0[host1], 6.0.6487.0[host1],
@ -688,6 +714,7 @@ that's my job.
<h2><a id="similar"></a>Similar softwares</h2>
<ul>
<li> <b>imapsync</b>: <a href="https://github.com/imapsync/imapsync">https://github.com/imapsync/imapsync</a> (imapsync copy, sometimes delayed)</li>
<li> imap_tools: <a href="http://www.athensfbc.com/imap_tools">http://www.athensfbc.com/imap_tools</a></li>
<li> imaputils: <a href="http://code.google.com/p/imaputils/">http://code.google.com/p/imaputils/</a> (imap_tools fork)</li>
<li> <b>offlineimap</b>: <a href="http://offlineimap.org/">http://offlineimap.org/</a></li>
@ -701,8 +728,8 @@ that's my job.
<li> imapcopy (Java): <a href="https://code.google.com/p/imapcopy/">https://code.google.com/p/imapcopy/</a></li>
<li> migrationtool: <a href="http://sourceforge.net/projects/migrationtool/">http://sourceforge.net/projects/migrationtool/</a></li>
<li> imapmigrate: <a href="http://sourceforge.net/projects/cyrus-utils/">http://sourceforge.net/projects/cyrus-utils/</a></li>
<li> larch: <a href="https://github.com/rgrove/larch">https://github.com/rgrove/larch</a> (derived from wonko_imapsync)</li>
<li> wonko_imapsync: <a href="http://wonko.com/article/554">http://wonko.com/article/554</a></li>
<li> larch: <a href="https://github.com/rgrove/larch">https://github.com/rgrove/larch</a> (derived from wonko_imapsync, good at Gmail)</li>
<li> wonko_imapsync: <a href="http://web.archive.org/web/20130807173030/http://wonko.com/post/ruby_script_to_sync_email_from_any_imap_server_to_gmail">http://wonko.com/article/554</a> (superseded by larch)</li>
<li> pop2imap: <a href="http://www.linux-france.org/prj/pop2imap/">http://www.linux-france.org/prj/pop2imap/</a></li>
<li> exchange-away: <a href="http://exchange-away.sourceforge.net/">http://exchange-away.sourceforge.net/</a></li>
<li> SyncBackPro <a href="http://www.2brightsparks.com/syncback/sbpro.html">http://www.2brightsparks.com/syncback/sbpro.html</a></li>
@ -753,7 +780,7 @@ alt="Viewable With Any Browser" />
<!--#config timefmt="%D" -->
<!--#config timefmt="%A %B %d, %Y" -->
<b>This document last modified on <!--#echo var="LAST_MODIFIED" --></b>
($Id: index.shtml,v 1.220 2014/09/15 22:21:05 gilles Exp gilles $)
($Id: index.shtml,v 1.227 2014/11/14 23:43:32 gilles Exp gilles $)
</p>
</body>

View file

@ -1,6 +1,6 @@
#!/bin/sh
# $Id: tests.sh,v 1.240 2014/09/19 19:36:25 gilles Exp gilles $
# $Id: tests.sh,v 1.245 2014/11/14 23:43:08 gilles Exp gilles $
# Example 1:
# CMD_PERL='perl -I./W/Mail-IMAPClient-3.35/lib' sh -x tests.sh
@ -168,6 +168,18 @@ locallocal() {
--passfile2 ../../var/pass/secret.titi
}
ll_eta() {
can_send && sendtestmessage
can_send && sendtestmessage
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--foldersizes --folder INBOX
}
ll_debug() {
#can_send && sendtestmessage
$CMD_PERL ./imapsync \
@ -359,6 +371,18 @@ ll_folder_noexist() {
--folder INBOX.noexist --folder INBOX.noexist2
}
ll_folder_mixfolders() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--mixfolders --justfolders --nofoldersizes
}
# Way to check it each time:
# sh -x tests.sh ll_folder_create ll_delete2folders
ll_folder_create() {
@ -562,6 +586,18 @@ ll_justfolders() {
echo "sudo rm -rf /home/vmail/titi/.new_folder/"
}
ll_justfolders_skipemptyfolders() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--justfolders --nofoldersizes --skipemptyfolders
echo "sudo rm -rf /home/vmail/titi/.new_folder/"
}
ll_justfolders_foldersizes() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
@ -2504,7 +2540,8 @@ xxxxx_gmail_4_Sent() {
--user2 gilles.lamiral@gmail.com \
--passfile2 ../../var/pass/secret.gilles_gmail \
--folder INBOX.Sent \
--regextrans2 's{Sent}{[Gmail]/Messages envoy&AOk-s}'
--regextrans2 's{Sent}{[Gmail]/Messages envoy&AOk-s}' \
--debugflags
}
xxxxx_gmail_5_justfolders() {
@ -3027,6 +3064,14 @@ ll_usecache_all() {
--usecache --nofoldersizes
}
ll_usecache_bracket() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--usecache --nofoldersizes --debugcache --folder "INBOX.[bracket]"
}
@ -3249,6 +3294,49 @@ l_exchange_maxline()
##########################
xgenplus() {
$CMD_PERL ./imapsync \
--host1 imap.dataone.in --user1 imapsynctest@dataone.in \
--passfile1 ../../var/pass/secret.xgenplus \
--host2 imap.dataone.in --user2 imapsynctest@dataone.in \
--passfile2 ../../var/pass/secret.xgenplus \
--sep1 / --sep2 / --prefix1 "" --prefix2 "" --debugimap
}
xgenplus_feed() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 imap.dataone.in --user2 imapsynctest@dataone.in \
--passfile2 ../../var/pass/secret.xgenplus \
--sep2 / --prefix2 "" \
--include "Junk.2013" --regextrans2 "s,Junk.2013,Junk,"
}
xgenplus_few() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 imap.dataone.in --user2 imapsynctest@dataone.in \
--passfile2 ../../var/pass/secret.xgenplus \
--sep2 / --prefix2 "" \
--include "few_emails"
}
courier_45() {
$CMD_PERL ./imapsync \
--host1 imap.timeweb.ru --user1 imaptest@avanta-consulting.ru \
@ -3874,9 +3962,11 @@ ll_bug_folder_name_with_blank
ll_timeout
ll_folder
ll_folder_noexist
ll_folder_mixfolders
ll_oneemail
ll_buffersize
ll_justfolders
ll_justfolders_skipemptyfolders
ll_prefix12
ll_nosyncinternaldates
ll_idatefromheader
@ -3970,7 +4060,7 @@ run_tests perl_syntax
# All tests
test $# -eq 0 && run_tests $mandatory_tests
test $# -eq 0 && run_tests $mandatory_tests && ./i3 --version >> .test_3xx
# selective tests