mirror of
https://github.com/imapsync/imapsync.git
synced 2024-11-16 15:52:47 +01:00
1.836
This commit is contained in:
parent
3afeea4a16
commit
8d76e44c5e
7
CREDITS
7
CREDITS
@ -1,5 +1,5 @@
|
||||
#!/bin/cat
|
||||
# $Id: CREDITS,v 1.187 2016/03/07 02:08:16 gilles Exp gilles $
|
||||
# $Id: CREDITS,v 1.190 2017/01/25 23:58:21 gilles Exp gilles $
|
||||
|
||||
If you want to make a donation to me, imapsync author, Gilles LAMIRAL,
|
||||
use any of the following ways:
|
||||
@ -24,6 +24,11 @@ I thank very much all of these people.
|
||||
I thank also very much all people who bought imapsync from the homepage
|
||||
but I don't cite them here.
|
||||
|
||||
Sean McDougall from New Brunswick, Ian Thomas & Matt Wilks from Toronto
|
||||
Sean found the solution and wrote the FAQ item in FAQ.Exchange.txt
|
||||
"NO Maximum size of appendable message has been exceeded"
|
||||
and Ian & Matt reported it to me.
|
||||
|
||||
Joe Pruett
|
||||
Bugfix about delete_message_on_host1() not using --noexpungeaftereach
|
||||
|
||||
|
506
ChangeLog
506
ChangeLog
@ -1,17 +1,515 @@
|
||||
|
||||
RCS file: RCS/imapsync,v
|
||||
Working file: imapsync
|
||||
head: 1.727
|
||||
head: 1.836
|
||||
branch:
|
||||
locks: strict
|
||||
gilles: 1.727
|
||||
gilles: 1.836
|
||||
access list:
|
||||
symbolic names:
|
||||
keyword substitution: kv
|
||||
total revisions: 727; selected revisions: 727
|
||||
total revisions: 836; selected revisions: 836
|
||||
description:
|
||||
----------------------------
|
||||
revision 1.727 locked by: gilles;
|
||||
revision 1.836 locked by: gilles;
|
||||
date: 2017/09/05 16:14:53; author: gilles; state: Exp; lines: +189 -182
|
||||
Reread the README part. Changed order, rewrote some parts, added options.
|
||||
----------------------------
|
||||
revision 1.835
|
||||
date: 2017/09/03 04:11:31; author: gilles; state: Exp; lines: +53 -92
|
||||
Reviewed the pod part that goes to README
|
||||
----------------------------
|
||||
revision 1.834
|
||||
date: 2017/08/31 04:14:04; author: gilles; state: Exp; lines: +18 -15
|
||||
Some crit level 4 fixed.
|
||||
----------------------------
|
||||
revision 1.833
|
||||
date: 2017/08/31 01:58:57; author: gilles; state: Exp; lines: +9 -305
|
||||
Removed sub usage_old()
|
||||
----------------------------
|
||||
revision 1.832
|
||||
date: 2017/08/31 01:47:48; author: gilles; state: Exp; lines: +285 -127
|
||||
Rewrote sub usage() and use Pod::Usage now.
|
||||
Dependency added: Pod::Usage
|
||||
ID on by default now. Use --noid to avoid it.
|
||||
Splited sub tests_mailimapclient_connect() to put pure ipv6 test in sub tests_mailimapclient_connect_bug() which is not
|
||||
run with --tests
|
||||
Added some warning in --testsunit when sub called do not exist.
|
||||
----------------------------
|
||||
revision 1.831
|
||||
date: 2017/08/27 01:52:48; author: gilles; state: Exp; lines: +17 -14
|
||||
Updated from OPTIONS file
|
||||
----------------------------
|
||||
revision 1.830
|
||||
date: 2017/08/27 01:27:49; author: gilles; state: Exp; lines: +35 -35
|
||||
Inline help to remove sslcheck
|
||||
----------------------------
|
||||
revision 1.829
|
||||
date: 2017/08/23 12:40:10; author: gilles; state: Exp; lines: +14 -12
|
||||
Bugfix. Fixed guess \ separator.
|
||||
----------------------------
|
||||
revision 1.828
|
||||
date: 2017/08/22 22:06:27; author: gilles; state: Exp; lines: +10 -10
|
||||
Syntax fix
|
||||
----------------------------
|
||||
revision 1.827
|
||||
date: 2017/08/22 22:04:38; author: gilles; state: Exp; lines: +12 -12
|
||||
Increased gmail1 maxbytespersecond to 40_000
|
||||
Increased gmail2 maxbytespersecond to 20_000
|
||||
----------------------------
|
||||
revision 1.826
|
||||
date: 2017/08/22 21:55:26; author: gilles; state: Exp; lines: +13 -11
|
||||
Added \ separator guess. List is now . / \\ and \
|
||||
----------------------------
|
||||
revision 1.825
|
||||
date: 2017/07/26 19:05:56; author: gilles; state: Exp; lines: +19 -10
|
||||
Skip ipv6 tests on cuillere.
|
||||
Skip a connect in void context on macosx polarhome, it stalls.
|
||||
----------------------------
|
||||
revision 1.824
|
||||
date: 2017/07/24 08:04:18; author: gilles; state: Exp; lines: +22 -21
|
||||
Better output for failed tests.
|
||||
----------------------------
|
||||
revision 1.823
|
||||
date: 2017/07/21 23:55:17; author: gilles; state: Exp; lines: +53 -20
|
||||
Better output in sub tests_mailimapclient_connect()
|
||||
----------------------------
|
||||
revision 1.822
|
||||
date: 2017/07/20 23:22:08; author: gilles; state: Exp; lines: +11 -11
|
||||
Bugfix. --skipmess could not work most of the time.
|
||||
----------------------------
|
||||
revision 1.821
|
||||
date: 2017/07/18 00:16:43; author: gilles; state: Exp; lines: +24 -26
|
||||
Bugfix. Guess prefix '' even when there is no folders.
|
||||
----------------------------
|
||||
revision 1.820
|
||||
date: 2017/07/11 12:12:49; author: gilles; state: Exp; lines: +14 -14
|
||||
loadavg on Win32 => 0 => unknown.
|
||||
----------------------------
|
||||
revision 1.819
|
||||
date: 2017/07/07 23:21:45; author: gilles; state: Exp; lines: +70 -27
|
||||
Added --testslive6 to check ipv6 connectivity
|
||||
----------------------------
|
||||
revision 1.818
|
||||
date: 2017/07/06 03:06:36; author: gilles; state: Exp; lines: +42 -27
|
||||
Removed from --tests call to:
|
||||
tests_imapsping()
|
||||
tests_tcpping()
|
||||
tests_resolv()
|
||||
tests_resolvrev()
|
||||
----------------------------
|
||||
revision 1.817
|
||||
date: 2017/07/05 21:58:42; author: gilles; state: Exp; lines: +30 -22
|
||||
--ipv4 is now synonim of --inet4
|
||||
--ipv6 is now synonim of --inet6
|
||||
----------------------------
|
||||
revision 1.816
|
||||
date: 2017/07/05 14:50:28; author: gilles; state: Exp; lines: +101 -16
|
||||
Added dependency use IO::Socket::INET6
|
||||
Added sub probe_imapssl(). Not use yet. Will replace imapsping()
|
||||
----------------------------
|
||||
revision 1.815
|
||||
date: 2017/06/27 16:45:20; author: gilles; state: Exp; lines: +10 -10
|
||||
MAX_SLEEP 30 => 2
|
||||
----------------------------
|
||||
revision 1.814
|
||||
date: 2017/06/26 22:50:41; author: gilles; state: Exp; lines: +213 -66
|
||||
Added raw LIST folders.
|
||||
Added IP print of both hosts, using peerhost().
|
||||
Added sub resolv() and others but not using them for now.
|
||||
Still a problem with IPv6 on port 143 only, 993 with ssl is ok. "Invalid argument" when connecting.
|
||||
Solved with Mail::IMAPClient patched like this:
|
||||
use IO::Socket::INET6 instead of IO::Socket::INET
|
||||
----------------------------
|
||||
revision 1.813
|
||||
date: 2017/05/24 17:46:13; author: gilles; state: Exp; lines: +93 -38
|
||||
Added --maxsleep in order to avoid timeouts with --maxbytespersecond and --maxmessagespersecond
|
||||
Default is like --maxsleep 30
|
||||
30 seconds sleeping at max.
|
||||
----------------------------
|
||||
revision 1.812
|
||||
date: 2017/05/23 21:12:37; author: gilles; state: Exp; lines: +10 -10
|
||||
941 unit tests.
|
||||
----------------------------
|
||||
revision 1.811
|
||||
date: 2017/05/23 21:10:12; author: gilles; state: Exp; lines: +24 -24
|
||||
Sync also messages with no internal date.
|
||||
No blanks in automatic logfile name.
|
||||
----------------------------
|
||||
revision 1.810
|
||||
date: 2017/05/02 18:46:30; author: gilles; state: Exp; lines: +10 -10
|
||||
Fixed a test in tests_umask_str() in order to pass it on Darwin
|
||||
----------------------------
|
||||
revision 1.809
|
||||
date: 2017/05/02 18:34:34; author: gilles; state: Exp; lines: +45 -45
|
||||
Isolated bad tests in notmatch() and match(): q{} against q{}, so commented now.
|
||||
----------------------------
|
||||
revision 1.808
|
||||
date: 2017/05/02 17:35:25; author: gilles; state: Exp; lines: +160 -75
|
||||
Better tests ending in exe in case of failure (was 0 I do not know why, a PAR bug)
|
||||
Report which tests failed at the end of tests.
|
||||
----------------------------
|
||||
revision 1.807
|
||||
date: 2017/04/28 13:43:07; author: gilles; state: Exp; lines: +30 -25
|
||||
testsunit() isolated.
|
||||
----------------------------
|
||||
revision 1.806
|
||||
date: 2017/04/28 09:50:40; author: gilles; state: Exp; lines: +81 -31
|
||||
Added --testsunit in order to run any unit test individualy from the command line.
|
||||
Several --testsunit are allowed. Example:
|
||||
imapsync --testsunit tests_true --testsunit tests_always_fail
|
||||
----------------------------
|
||||
revision 1.805
|
||||
date: 2017/04/27 13:04:58; author: gilles; state: Exp; lines: +50 -40
|
||||
Added test to mkpath with trailing dots foo... in folder name for --usecache.
|
||||
It does not fail.
|
||||
----------------------------
|
||||
revision 1.804
|
||||
date: 2017/04/27 00:39:51; author: gilles; state: Exp; lines: +10 -10
|
||||
Fix number of fake test on Win32.
|
||||
----------------------------
|
||||
revision 1.803
|
||||
date: 2017/04/26 17:52:34; author: gilles; state: Exp; lines: +123 -119
|
||||
Perl crit fixes:
|
||||
* $! $OS_ERROR
|
||||
* $@ $EVAL_ERROR
|
||||
many others.
|
||||
----------------------------
|
||||
revision 1.802
|
||||
date: 2017/04/25 16:13:33; author: gilles; state: Exp; lines: +231 -229
|
||||
crit about blanks
|
||||
----------------------------
|
||||
revision 1.801
|
||||
date: 2017/04/24 20:51:00; author: gilles; state: Exp; lines: +116 -75
|
||||
Bugfix. logfile must not have / from user1 and user2.
|
||||
----------------------------
|
||||
revision 1.800
|
||||
date: 2017/04/24 13:51:44; author: gilles; state: Exp; lines: +19 -18
|
||||
Bugfix. passfile1 passfile2 failure only if used!
|
||||
----------------------------
|
||||
revision 1.799
|
||||
date: 2017/04/24 12:47:34; author: gilles; state: Exp; lines: +20 -10
|
||||
Check passfile exist before reading it and exit on failure.
|
||||
----------------------------
|
||||
revision 1.798
|
||||
date: 2017/04/24 02:41:46; author: gilles; state: Exp; lines: +61 -29
|
||||
Make all tests run on MSWin32, either success or skip
|
||||
----------------------------
|
||||
revision 1.797
|
||||
date: 2017/04/23 13:35:47; author: gilles; state: Exp; lines: +353 -23
|
||||
Moved /etc/imapsync.hash to $CGI_HASHFILE => '/var/tmp/imapsync_hash'
|
||||
Added note( 'Entering ...' ) and note( 'Leaving ...' ) to all tests_...() functions
|
||||
----------------------------
|
||||
revision 1.796
|
||||
date: 2017/04/23 12:25:22; author: gilles; state: Exp; lines: +115 -28
|
||||
Added umask setting to 0077 in cgi context.
|
||||
----------------------------
|
||||
revision 1.795
|
||||
date: 2017/04/22 13:01:28; author: gilles; state: Exp; lines: +55 -16
|
||||
Refactor. Replaced hard cgi context test $ENV{SERVER_SOFTWARE} by function call to under_cgi_context()
|
||||
----------------------------
|
||||
revision 1.794
|
||||
date: 2017/04/15 16:59:24; author: gilles; state: Exp; lines: +10 -10
|
||||
871 unit tests
|
||||
----------------------------
|
||||
revision 1.793
|
||||
date: 2017/04/15 16:56:06; author: gilles; state: Exp; lines: +136 -54
|
||||
Tests should pass under nobody in /var/tmp/ now.
|
||||
----------------------------
|
||||
revision 1.792
|
||||
date: 2017/04/05 03:06:42; author: gilles; state: Exp; lines: +22 -22
|
||||
Added GMT setting to test setlogfile()
|
||||
----------------------------
|
||||
revision 1.791
|
||||
date: 2017/04/05 02:27:50; author: gilles; state: Exp; lines: +26 -9
|
||||
Added docker context in order to be run under nobody without permission issues.
|
||||
----------------------------
|
||||
revision 1.790
|
||||
date: 2017/04/04 11:27:09; author: gilles; state: Exp; lines: +10 -10
|
||||
Added 'Objets envoy&AOk-s' for --automap
|
||||
----------------------------
|
||||
revision 1.789
|
||||
date: 2017/03/24 22:44:11; author: gilles; state: Exp; lines: +11 -9
|
||||
Fix issue "SSL routines:ssl3_check_cert_and_algorithm:dh key too small" with
|
||||
http://stackoverflow.com/questions/36417224/openssl-dh-key-too-small-error
|
||||
SSL_cipher_list => 'DEFAULT:!DH'
|
||||
----------------------------
|
||||
revision 1.788
|
||||
date: 2017/03/20 23:26:26; author: gilles; state: Exp; lines: +10 -10
|
||||
852 unit tests
|
||||
----------------------------
|
||||
revision 1.787
|
||||
date: 2017/03/20 23:23:39; author: gilles; state: Exp; lines: +130 -84
|
||||
Added --maxbytesafter in order to start --maxbytespersecond limitation only after --maxbytesafter amount of data transferred
|
||||
----------------------------
|
||||
revision 1.786
|
||||
date: 2017/03/20 03:32:12; author: gilles; state: Exp; lines: +44 -39
|
||||
Bugfix. Abort on heavy load was not working because of load_and_delay strictly needed 4 arguments
|
||||
----------------------------
|
||||
revision 1.785
|
||||
date: 2017/03/14 18:06:38; author: gilles; state: Exp; lines: +12 -10
|
||||
No systematic NOP!
|
||||
----------------------------
|
||||
revision 1.784
|
||||
date: 2017/03/14 17:51:48; author: gilles; state: Exp; lines: +120 -30
|
||||
Changed abandon points (last FOLDER) to reconnection points.
|
||||
----------------------------
|
||||
revision 1.783
|
||||
date: 2017/03/13 06:22:43; author: gilles; state: Exp; lines: +24 -90
|
||||
Removed Mail::IMAPClient ads!
|
||||
----------------------------
|
||||
revision 1.782
|
||||
date: 2017/03/13 01:20:24; author: gilles; state: Exp; lines: +486 -384
|
||||
Added --domino1 --domino2 to facilitate Domino options setting.
|
||||
Added password setting via environment variables IMAPSYNC_PASSWORD1 IMAPSYNC_PASSWORD2
|
||||
----------------------------
|
||||
revision 1.781
|
||||
date: 2017/03/09 12:50:07; author: gilles; state: Exp; lines: +30 -22
|
||||
Usability. No more "... says it has NO CAPABILITY for AUTHENTICATE LOGIN"
|
||||
----------------------------
|
||||
revision 1.780
|
||||
date: 2017/03/09 11:00:05; author: gilles; state: Exp; lines: +54 -20
|
||||
Added --office1 --office2 to load simplify sync from and to office 365 (parameters from the FAQ.d/FAQ.Exchange.txt)
|
||||
----------------------------
|
||||
revision 1.779
|
||||
date: 2017/03/07 13:05:02; author: gilles; state: Exp; lines: +85 -65
|
||||
Removed most of the perlcrit (Severity: 3) Regular expression without "/x" flag
|
||||
----------------------------
|
||||
revision 1.778
|
||||
date: 2017/03/02 00:22:59; author: gilles; state: Exp; lines: +125 -83
|
||||
Fixed some perlcrit level 4
|
||||
----------------------------
|
||||
revision 1.777
|
||||
date: 2017/03/01 01:25:58; author: gilles; state: Exp; lines: +20 -16
|
||||
Added memory_available
|
||||
----------------------------
|
||||
revision 1.776
|
||||
date: 2017/02/28 22:58:38; author: gilles; state: Exp; lines: +89 -68
|
||||
Added tests_not_long_imapsync_version_public()
|
||||
----------------------------
|
||||
revision 1.775
|
||||
date: 2017/02/17 01:54:27; author: gilles; state: Exp; lines: +27 -23
|
||||
loadavg on Win32
|
||||
----------------------------
|
||||
revision 1.774
|
||||
date: 2017/02/15 12:55:50; author: gilles; state: Exp; lines: +40 -25
|
||||
Bugfix. $tls1 and $tls2 vs $mysync->{tls1} $mysync->{tls2} somewhere
|
||||
----------------------------
|
||||
revision 1.773
|
||||
date: 2017/02/14 23:21:05; author: gilles; state: Exp; lines: +155 -41
|
||||
Splited loadavg() in 3 calls loadavg_windows() loadavg_darwin() loadavg_linux()
|
||||
Bugfix. Output "Load is" was not complete, miss the important 3 load values!
|
||||
----------------------------
|
||||
revision 1.772
|
||||
date: 2017/02/01 01:31:22; author: gilles; state: Exp; lines: +14 -14
|
||||
Bugfix. Output Load is was inacurate
|
||||
----------------------------
|
||||
revision 1.771
|
||||
date: 2017/01/31 22:10:51; author: gilles; state: Exp; lines: +10 -10
|
||||
Bugfix. gmail2() had bad regextrans2
|
||||
----------------------------
|
||||
revision 1.770
|
||||
date: 2017/01/29 21:48:44; author: gilles; state: Exp; lines: +52 -45
|
||||
Added $imap1->reconnect in case getting metadata from host2 is too long and host1 timesout.
|
||||
Bugfix. getoption uses $mysync not $sync
|
||||
----------------------------
|
||||
revision 1.769
|
||||
date: 2017/01/28 05:54:43; author: gilles; state: Exp; lines: +60 -61
|
||||
Removed global $dry and $dry_message => $sync->{dry} $sync->{dry_message}
|
||||
----------------------------
|
||||
revision 1.768
|
||||
date: 2017/01/19 06:12:02; author: gilles; state: Exp; lines: +12 -11
|
||||
Bugfix. CGI context a newline was bad in $sync->{loadavg}
|
||||
----------------------------
|
||||
revision 1.767
|
||||
date: 2017/01/19 05:53:02; author: gilles; state: Exp; lines: +11 -10
|
||||
use Net::Ping instead of just require.
|
||||
----------------------------
|
||||
revision 1.766
|
||||
date: 2017/01/19 05:29:42; author: gilles; state: Exp; lines: +12 -12
|
||||
sslcheck localhost => imapsync.lamiral.info
|
||||
----------------------------
|
||||
revision 1.765
|
||||
date: 2017/01/19 05:16:42; author: gilles; state: Exp; lines: +10 -10
|
||||
806 unit tests
|
||||
----------------------------
|
||||
revision 1.764
|
||||
date: 2017/01/19 05:12:17; author: gilles; state: Exp; lines: +184 -59
|
||||
Added --sslcheck and made it on by default. Use --nosslcheck to unset it.
|
||||
--sslcheck checks ssl port 993 and turn on ssl if it is open.
|
||||
----------------------------
|
||||
revision 1.763
|
||||
date: 2017/01/19 00:49:43; author: gilles; state: Exp; lines: +10 -10
|
||||
792 unit tests
|
||||
----------------------------
|
||||
revision 1.762
|
||||
date: 2017/01/19 00:46:30; author: gilles; state: Exp; lines: +113 -90
|
||||
--showpasswords now show also passwords with --debugimap
|
||||
Load does not generate Perl warnings on Win32
|
||||
----------------------------
|
||||
revision 1.761
|
||||
date: 2017/01/17 06:08:49; author: gilles; state: Exp; lines: +12 -9
|
||||
debug for --gmail1 --gmail2
|
||||
----------------------------
|
||||
revision 1.760
|
||||
date: 2017/01/17 04:43:51; author: gilles; state: Exp; lines: +90 -11
|
||||
Added --gmail1 --gmail2 --gmail12 to simplify gmail syncs. It sets parameters from the FAQ --ssl --host etc.
|
||||
Allow parameters passed by POST.
|
||||
----------------------------
|
||||
revision 1.759
|
||||
date: 2017/01/16 13:20:57; author: gilles; state: Exp; lines: +10 -10
|
||||
Bugfix. Add / after CGI_TMPDIR_TOP
|
||||
----------------------------
|
||||
revision 1.758
|
||||
date: 2017/01/15 19:34:42; author: gilles; state: Exp; lines: +71 -26
|
||||
Splitted get_options(). Now call either get_options_cgi() or get_options_cmd()
|
||||
I applied David M advice, remove all but what is safe in the context.
|
||||
----------------------------
|
||||
revision 1.757
|
||||
date: 2017/01/12 10:33:47; author: gilles; state: Exp; lines: +10 -10
|
||||
nb tests
|
||||
----------------------------
|
||||
revision 1.756
|
||||
date: 2017/01/12 10:14:32; author: gilles; state: Exp; lines: +175 -154
|
||||
tmpdir is cgidir in cgi context. different for each account couple (host,user,pass).
|
||||
----------------------------
|
||||
revision 1.755
|
||||
date: 2017/01/12 03:25:42; author: gilles; state: Exp; lines: +28 -22
|
||||
Now goes to TLS if STARTTLS is in CAPABILITY and ssl is off and notls is not there.
|
||||
----------------------------
|
||||
revision 1.754
|
||||
date: 2017/01/11 06:43:05; author: gilles; state: Exp; lines: +11 -14
|
||||
*** empty log message ***
|
||||
----------------------------
|
||||
revision 1.753
|
||||
date: 2017/01/11 04:59:22; author: gilles; state: Exp; lines: +280 -80
|
||||
Added load average from /proc/loadavg
|
||||
Added abort if load is too heavy in cgi context.
|
||||
----------------------------
|
||||
revision 1.752
|
||||
date: 2017/01/10 00:48:45; author: gilles; state: Exp; lines: +13 -13
|
||||
timestart with milliseconds.
|
||||
----------------------------
|
||||
revision 1.751
|
||||
date: 2017/01/09 06:57:00; author: gilles; state: Exp; lines: +30 -36
|
||||
Added milliseconds in logfile name since in cgi context several runs is possible in one second.
|
||||
----------------------------
|
||||
revision 1.750
|
||||
date: 2017/01/05 13:47:10; author: gilles; state: Exp; lines: +57 -36
|
||||
Added /dist/ link in releasecheck.
|
||||
Added tests_check_last_release( )
|
||||
Made check_last_release() testable.
|
||||
----------------------------
|
||||
revision 1.749
|
||||
date: 2017/01/05 03:18:01; author: gilles; state: Exp; lines: +10 -10
|
||||
*** empty log message ***
|
||||
----------------------------
|
||||
revision 1.748
|
||||
date: 2017/01/05 01:48:34; author: gilles; state: Exp; lines: +166 -109
|
||||
Added cookie imapsync_runs in cgi context.
|
||||
Refactor. $host1 $user1 $password1 $host2 $user2 $password2 under $sync now.
|
||||
Added output() to delay some output in cgi context.
|
||||
----------------------------
|
||||
revision 1.747
|
||||
date: 2016/12/24 15:38:49; author: gilles; state: Exp; lines: +152 -26
|
||||
Added sub rand32()
|
||||
Added sub createhashfileifneeded()
|
||||
Added sub hashsync()
|
||||
Added sub hashsynclocal()
|
||||
Temporary dir different for each individual sync but same dir if same parameters host1 host2 user1 user2 password1 password2
|
||||
----------------------------
|
||||
revision 1.746
|
||||
date: 2016/12/19 20:14:37; author: gilles; state: Exp; lines: +81 -23
|
||||
Extracted the $cgi object creation from sub myGetOptions()
|
||||
Started sub tests_get_options_cgi()
|
||||
Added tests to sub tests_get_options()
|
||||
----------------------------
|
||||
revision 1.745
|
||||
date: 2016/12/14 23:12:37; author: gilles; state: Exp; lines: +102 -41
|
||||
Refactoring. get_options( @ARGV ) uses @ARGV as a parameter.
|
||||
Refactoring. sub get_options() only gets options (use to add stuff about their values).
|
||||
Refactoring. What was in sub get_options() has gone into sub after_get_options()
|
||||
Refactoring. sub unsetunsafe( ) is now sub sub setcgicontext( ) and has more settings.
|
||||
Bugfix. sub ask_for_password used <> which could open remaining options from @ARGS. Uses now <STDIN>
|
||||
Refactoring. Use Getopt::Long::GetOptionsFromArray() instead of Getopt::Long::GetOptions()
|
||||
Added test sub tests_get_options()
|
||||
Refactoring. Added sub printenv() extracted code from sub get_options()
|
||||
----------------------------
|
||||
revision 1.744
|
||||
date: 2016/12/13 13:04:21; author: gilles; state: Exp; lines: +105 -106
|
||||
Removed local package Imapsync::Getopt::Long
|
||||
----------------------------
|
||||
revision 1.743
|
||||
date: 2016/12/12 11:43:46; author: gilles; state: Exp; lines: +60 -18
|
||||
Added --abort option to terminate a previous call still running. Useful in remote context, ie online.
|
||||
----------------------------
|
||||
revision 1.742
|
||||
date: 2016/12/07 16:17:10; author: gilles; state: Exp; lines: +25 -11
|
||||
Added --simulong int. To simulate a long response in web context.
|
||||
----------------------------
|
||||
revision 1.741
|
||||
date: 2016/11/22 21:27:43; author: gilles; state: Exp; lines: +10 -10
|
||||
Now print " could not append ( Subject:[$subject], Date:[$h1_date], Size:[$h1_size] ) " whn append fails.
|
||||
----------------------------
|
||||
revision 1.740
|
||||
date: 2016/11/17 15:05:01; author: gilles; state: Exp; lines: +10 -10
|
||||
Print always permanentflags info. Was only in debug mode.
|
||||
----------------------------
|
||||
revision 1.739
|
||||
date: 2016/11/03 20:31:10; author: gilles; state: Exp; lines: +87 -36
|
||||
Added sub tests_match( ).
|
||||
Changed name sub tests_dontmatch( ) => tests_notmatch( )
|
||||
710 tests noregression.
|
||||
----------------------------
|
||||
revision 1.738
|
||||
date: 2016/11/01 10:11:31; author: gilles; state: Exp; lines: +115 -59
|
||||
--expunge --expunge1 are pure aliases now (don't know why they were distinct).
|
||||
----------------------------
|
||||
revision 1.737
|
||||
date: 2016/10/11 12:40:59; author: gilles; state: Exp; lines: +16 -16
|
||||
blanks
|
||||
----------------------------
|
||||
revision 1.736
|
||||
date: 2016/10/10 21:02:49; author: gilles; state: Exp; lines: +3215 -3215
|
||||
all tabs converted to spaces. By notepad++
|
||||
----------------------------
|
||||
revision 1.735
|
||||
date: 2016/10/10 20:48:53; author: gilles; state: Exp; lines: +21 -21
|
||||
crit fix. open my
|
||||
----------------------------
|
||||
revision 1.734
|
||||
date: 2016/10/10 14:05:09; author: gilles; state: Exp; lines: +60 -60
|
||||
Renamed sub is_valid_directory() to do_valid_directory()
|
||||
Rewrote modulesversion() tp avoid no strict 'refs' usage.
|
||||
use a closure instead
|
||||
----------------------------
|
||||
revision 1.733
|
||||
date: 2016/10/09 21:38:44; author: gilles; state: Exp; lines: +166 -184
|
||||
Some crit fixes.
|
||||
----------------------------
|
||||
revision 1.732
|
||||
date: 2016/09/29 20:56:35; author: gilles; state: Exp; lines: +106 -106
|
||||
Small perlcritics.
|
||||
----------------------------
|
||||
revision 1.731
|
||||
date: 2016/09/29 12:24:56; author: gilles; state: Exp; lines: +32 -26
|
||||
Added --noabletosearch1 --noabletosearch2; Still support --noabletosearch, which turn on both --noabletosearch1 --noabletosearch2
|
||||
----------------------------
|
||||
revision 1.730
|
||||
date: 2016/09/17 14:30:45; author: gilles; state: Exp; lines: +32 -28
|
||||
Variable $delete is now $delete1
|
||||
Change doc --delete => --delete1
|
||||
--delete still supported, --delete1 and --delete are aliases.
|
||||
----------------------------
|
||||
revision 1.729
|
||||
date: 2016/09/12 06:24:07; author: gilles; state: Exp; lines: +16 -14
|
||||
typo.
|
||||
----------------------------
|
||||
revision 1.728
|
||||
date: 2016/08/30 11:38:30; author: gilles; state: Exp; lines: +11 -11
|
||||
Typo
|
||||
----------------------------
|
||||
revision 1.727
|
||||
date: 2016/08/19 10:30:36; author: gilles; state: Exp; lines: +53 -110
|
||||
Bugfix. Fall back separator to / even when host has no mailbox at all.
|
||||
Usability. Better warning about default ssl SSL_VERIFY_NONE
|
||||
|
724
FAQ
724
FAQ
@ -1,724 +0,0 @@
|
||||
#!/bin/cat
|
||||
# $Id: FAQ,v 1.224 2016/06/08 21:32:09 gilles Exp gilles $
|
||||
|
||||
+-------------------+
|
||||
| FAQs for imapsync |
|
||||
+-------------------+
|
||||
|
||||
http://imapsync.lamiral.info/FAQ
|
||||
http://imapsync.lamiral.info/FAQ.d/
|
||||
|
||||
Unix versus Windows syntax.
|
||||
There are several differences between Unix and Windows
|
||||
in the command line syntax.
|
||||
- Character \ versus ^
|
||||
- Character ' versus "
|
||||
|
||||
|
||||
A) \ versus ^
|
||||
|
||||
On Unix shells you can write a single command on multiple lines
|
||||
by using the escape character \ at the end of each line
|
||||
(except the last one). On Windows this character is ^
|
||||
|
||||
Unix example:
|
||||
|
||||
./imapsync \
|
||||
--host1 imap.truc.org --user1 foo --password1 secret1 \
|
||||
--host2 imap.trac.org --user2 bar --password2 secret2
|
||||
|
||||
|
||||
Windows example:
|
||||
|
||||
imapsync ^
|
||||
--host1 imap.truc.org --user1 foo --password1 secret1 ^
|
||||
--host2 imap.trac.org --user2 bar --password2 secret2
|
||||
|
||||
|
||||
Of course you can write the command on one only line without
|
||||
characters \ nor ^. I use them because the output is
|
||||
better, no truncation, pretty print. It's just sugar.
|
||||
|
||||
In this FAQ I use \ for examples. Transcript to ^ if
|
||||
you're on a Windows system.
|
||||
|
||||
B) ' versus "
|
||||
|
||||
On Windows the single quote character ' doesn't work
|
||||
like on Unix so in the examples of this FAQ the
|
||||
command containing single quotes ' will fail on Windows.
|
||||
To fix it just replace single quotes ' by double quotes "
|
||||
|
||||
Also on Windows, in examples with \$1 replace
|
||||
any \$1 by $1 (remove the \ before $).
|
||||
|
||||
=======================================================================
|
||||
Q. How to verify imapsync.exe I got is the right file bit per bit?
|
||||
|
||||
R. Use md5sum to check integrity of the file.
|
||||
Get md5sum.exe at http://etree.org/md5com.html
|
||||
|
||||
md5sum imapsync.exe
|
||||
|
||||
Then compare the checksum with the one given by the author.
|
||||
|
||||
=======================================================================
|
||||
Q. How to install imapsync?
|
||||
|
||||
R. Read the INSTALL files in the tarball also available at
|
||||
http://imapsync.lamiral.info/INSTALL
|
||||
http://imapsync.lamiral.info/INSTALL.d/
|
||||
|
||||
=======================================================================
|
||||
Q. How to configure and run imapsync?
|
||||
|
||||
R. Read the README, OPTIONS and FAQ files in the tarball also
|
||||
available at:
|
||||
http://imapsync.lamiral.info/README
|
||||
http://imapsync.lamiral.info/OPTIONS
|
||||
http://imapsync.lamiral.info/FAQ
|
||||
|
||||
=======================================================================
|
||||
Q. Can you give some configuration examples?
|
||||
|
||||
R1. Basic usage is described there:
|
||||
http://imapsync.lamiral.info/#DOC_BASIC
|
||||
|
||||
imapsync --host1 test1.lamiral.info --user1 test1 --password1 secret1 \
|
||||
--host2 test2.lamiral.info --user2 test2 --password2 secret2
|
||||
|
||||
R2. The FAQ files contains many examples for several scenarios
|
||||
http://imapsync.lamiral.info/FAQ
|
||||
|
||||
=======================================================================
|
||||
Q. How can I have commercial support?
|
||||
|
||||
R. Buy support from imapsync author and expert: Gilles LAMIRAL
|
||||
http://imapsync.lamiral.info/#buy_all
|
||||
|
||||
=======================================================================
|
||||
Q. How can I have gratis support?
|
||||
|
||||
R. Use the mailing-list
|
||||
|
||||
To write on the mailing-list, the address is:
|
||||
<imapsync@linux-france.org>
|
||||
|
||||
To subscribe, send a message to:
|
||||
<imapsync-subscribe@listes.linux-france.org>
|
||||
|
||||
To unsubscribe, send a message to:
|
||||
<imapsync-unsubscribe@listes.linux-france.org>
|
||||
|
||||
To contact the person in charge for the list:
|
||||
<imapsync-request@listes.linux-france.org>
|
||||
|
||||
The list archives may be 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.
|
||||
|
||||
Thank you for your participation.
|
||||
|
||||
=======================================================================
|
||||
Q. Where I can find old imapsync releases?
|
||||
|
||||
R. Search the Internet.
|
||||
|
||||
=======================================================================
|
||||
Q. Where I can find free open and gratis imapsync releases?
|
||||
|
||||
R. Search the Internet.
|
||||
|
||||
Q. Is is legal to find imapsync gratis (or not) elsewhere?
|
||||
|
||||
R. Yes, the license permits it
|
||||
http://imapsync.lamiral.info/NOLIMIT
|
||||
|
||||
=======================================================================
|
||||
Q. How "Facts and figures" are known on http://imapsync.lamiral.info/
|
||||
|
||||
R. To know wether a newer imapsync exists or not imapsync does a http
|
||||
GET to http://imapsync.lamiral.info/VERSION
|
||||
Via the User-agent parameter it also send:
|
||||
|
||||
* imapsync release
|
||||
* Perl version
|
||||
* Mail::IMAPClient version
|
||||
* Operating System
|
||||
|
||||
You can remove this behavior by adding option --noreleasecheck on the
|
||||
command line (or by setting $releasecheck = 0 in the source code)
|
||||
or by using github release.
|
||||
|
||||
=======================================================================
|
||||
Q. I use --useuid which uses a cache in /tmp or --tmpdir, the hostnames
|
||||
host1 or host2 has changed but mailboxes are the same. Will imapsync
|
||||
generate duplicate messages on next runs?
|
||||
|
||||
R. Yes
|
||||
|
||||
Q. How can I fix this?
|
||||
|
||||
R. The cache path reflects exactly hostnames or ip addresses given via
|
||||
--host1 and --host2 values. So just change the directory names
|
||||
of host1 or host2. Use --dry to see if next runs will generate
|
||||
duplicates.
|
||||
By default on Unix the cache is like
|
||||
|
||||
/tmp/imapsync_cache/host1/user1/host2/user2/...
|
||||
|
||||
=======================================================================
|
||||
Q. How can I speed up transfers?
|
||||
|
||||
R. By using --useuid imapsync avoid getting messages headers and build
|
||||
a cache. On Unix a good thing is to add also --tmpdir /var/tmp
|
||||
to keep the cache since /tmp is often cleared on reboot.
|
||||
|
||||
imapsync ... --useuid
|
||||
|
||||
On Unix:
|
||||
|
||||
imapsync ... --useuid --tmpdir /var/tmp/
|
||||
|
||||
R. Add also --nofoldersizes since the default behavior is to compute
|
||||
folder sizes. Folder sizes are useless for the transfer, just
|
||||
useful to see what has to be done on each folder and guess when
|
||||
the transfer will end (ETA).
|
||||
|
||||
R. Add also --noexpungeaftereach if you use --delete.
|
||||
But be warn that an interrupted transfer can loose messages
|
||||
on host2 in a second run if you use a (silly) combination like
|
||||
|
||||
imapsync ... --delete --noexpunge --noexpungeaftereach --expunge2
|
||||
|
||||
R. Add also --nocheckmessageexists
|
||||
--nocheckmessageexists is on by default since release 1.520.
|
||||
Since transfer can be long on a huge mailbox imapsync checks
|
||||
a message exist before copying it, but it takes time and
|
||||
cpu on the host1 server.
|
||||
|
||||
|
||||
Notes about --useuid
|
||||
|
||||
Case where building the cache first is necessary (to avoid multiples transfers)
|
||||
|
||||
If you run again imapsync with --useuid on a transfer already done without
|
||||
--useuid then, to avoid messages be copied again, first run imapsync
|
||||
with --usecache but without --useuid, example scenario:
|
||||
|
||||
A] Running with the default options, I began without --useuid
|
||||
|
||||
1) First run with default options
|
||||
|
||||
imapsync ...
|
||||
|
||||
Too slow, I want to speed up!
|
||||
|
||||
2) Build the cache
|
||||
|
||||
imapsync ... --usecache
|
||||
|
||||
3) Speed up now
|
||||
|
||||
imapsync ... --useuid
|
||||
|
||||
B] I began with --useuid from the first time
|
||||
|
||||
1) First run and next runs with --useuid
|
||||
|
||||
imapsync ... --useuid
|
||||
|
||||
|
||||
Inodes number issue.
|
||||
|
||||
The cache is simple, it uses the file-system natively,
|
||||
it's just an empty file per message transfered.
|
||||
When mailboxes are huge the cache can exhaust the number of inodes
|
||||
allowed in the filesystem, that's a limitation like limitation
|
||||
size but it's less often encountered.
|
||||
|
||||
On Unix, to predict whether your tmpdir filesystem used by imapsync
|
||||
will support the whole cache, just run the command "df -i /var/tmp",
|
||||
if /var/tmp is the --tmpdir argument.
|
||||
|
||||
On windows, search and drop me a note about how to count the number
|
||||
of files allowed in the filesystem.
|
||||
It seems FAT32 supports 268 435 445 clusters.
|
||||
|
||||
Choosing the number of inodes allowed by a filesystem can be done
|
||||
at the creation of it with "mkfs -N number-of-inodes ..."
|
||||
|
||||
imapsync can predict how many messages have to be synced with the
|
||||
option --justfoldersizes (no transfer will be done)
|
||||
|
||||
imapsync ... --justfoldersizes
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. I see warning messages like the following:
|
||||
"Host1 Sent/15 size 1428 ignored (no header so we ignore this message.
|
||||
To solve this: use --addheader)".
|
||||
|
||||
What can I do to transfer those messages?
|
||||
|
||||
|
||||
R1. Like suggested inline, use --addheader option.
|
||||
Option --addheader will add an header line like
|
||||
Message-Id: <15@imapsync>
|
||||
where 15 is the message UID number on host1.
|
||||
Then imapsync will transfer the changed message on host2.
|
||||
Duplicates won't happen on next runs.
|
||||
|
||||
imapsync ... --addheader
|
||||
|
||||
R2. Other solution.
|
||||
Use --useuid then imapsync will avoid dealing with headers.
|
||||
|
||||
imapsync ... --useuid
|
||||
|
||||
=======================================================================
|
||||
Q. On Windows, with --useuid or --usecache a problem occurs with long
|
||||
nested folder names. The error message is:
|
||||
"No such file or directory; The filename or extension is too long"
|
||||
|
||||
R. This comes from a Windows limitation on pathnames.
|
||||
No more than 260 characters are allowed for pathnames.
|
||||
See more details on page
|
||||
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx#maxpath
|
||||
The workaround solution given at the previous link,
|
||||
ie using \\?\D:", does not work for imapsync.
|
||||
So this imapsync Windows bug is still pending and needs a fix using
|
||||
a different technique to cache, like a database file for example.
|
||||
|
||||
A solution to fix the issue is to use a Linux virtual host on a
|
||||
Windows box, with VirtualBox or VmWare etc. There is no bug this way,
|
||||
pathnames can be several thousands characters long.
|
||||
Better said that done but not so difficult nor expensive these days,
|
||||
VirtualBox is free and VmWare Player is free for personal or test use.
|
||||
|
||||
If you have to stick on Windows, there are two good workarounds
|
||||
to reduce the cache directory name:
|
||||
|
||||
1) Use --tmpdir "D:\\temp" or simply --tmpdir "D:" and imapsync
|
||||
will build and use the cache in the sub directory
|
||||
D:\imapsync_cache\
|
||||
|
||||
2) add two equivalent entries in the etc/hosts for host1 imap.truc.org
|
||||
and host2 imap.trac.org.
|
||||
If you map the ip of imap.truc.org just with the letter a
|
||||
and same thing for imap.trac.org then you gain characters
|
||||
|
||||
etc/hosts
|
||||
|
||||
192.168.12.1 a
|
||||
192.168.55.3 b
|
||||
|
||||
Then use:
|
||||
|
||||
imapsync --host1 a --host2 b ...
|
||||
|
||||
You can get the ip of a host with the ping command line
|
||||
C:\> ping imap.truc.org
|
||||
|
||||
Fixing the long path problem directly in imapsync is in the TODO file.
|
||||
|
||||
=======================================================================
|
||||
Q. How can I try imapsync with latest Mail::IMAPClient 3.xx perl module?
|
||||
|
||||
Three solutions at least.
|
||||
|
||||
R1 - Look at the script named "i3" in the tarball, it can be used to
|
||||
run imapsync with the included Mail-IMAPClient-3.38/ wherever you
|
||||
unpacked the imapsync tarball
|
||||
|
||||
R2 Run:
|
||||
|
||||
cpanm Mail::IMAPClient # this uses cpanminus
|
||||
|
||||
or
|
||||
|
||||
cpan -i Mail::IMAPClient
|
||||
|
||||
or
|
||||
|
||||
perl -MCPAN -e "install Mail::IMAPClient"
|
||||
|
||||
|
||||
R3 If you want to install the Perl module locally in a directory
|
||||
|
||||
- Download latest Mail::IMAPClient 3.xx at
|
||||
http://search.cpan.org/dist/Mail-IMAPClient/
|
||||
|
||||
- untar it anywhere:
|
||||
tar xzvf Mail-IMAPClient-3.xx.tar.gz
|
||||
|
||||
- Get any imapsync (latest is better).
|
||||
|
||||
- run imapsync with perl and -I option tailing to use the perl
|
||||
module Mail-IMAPClient-3.xx. Example:
|
||||
|
||||
perl -I./Mail-IMAPClient-3.38/lib ./imapsync ...
|
||||
|
||||
or if imapsync is in directory /path/
|
||||
perl -I./Mail-IMAPClient-3.38/lib /path/imapsync ...
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. How can I use imapsync with Mail::IMAPClient 2.2.9 perl module?
|
||||
|
||||
R. Mail::IMAPClient 2.2.9 is no longer supported.
|
||||
|
||||
=======================================================================
|
||||
Q. Can I use imapsync to migrate emails from pop3 server to imap server?
|
||||
|
||||
R1. No.
|
||||
You can migrate emails from pop server to imap server with pop2imap:
|
||||
http://www.linux-france.org/prj/pop2imap/
|
||||
|
||||
R2. Yes
|
||||
Many pop3 servers runs in parallel with an imap server on exactly
|
||||
the same mailboxes. They serve the same INBOX
|
||||
(imap serves INBOX and several other folders, pop3 serves only INBOX)
|
||||
So have a try with imapsync on the same host1.
|
||||
|
||||
=======================================================================
|
||||
Q. Folders are not created on host2. What happens?
|
||||
|
||||
R. Do you use IMAP or POP3 with your client software?
|
||||
It looks like you use POP3 instead of IMAP, POP3 sees only INBOX.
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. I am interested in creating a local clone of the IMAP on a LAN
|
||||
server for faster synchronizations, email will always be delivered
|
||||
to the remote server and so the synchronization will be one way - from
|
||||
remote to local. How suited is imapsync for continuous one-way
|
||||
synchronization of mailboxes? Is there a better solution?
|
||||
|
||||
R. If messages are delivered remotely and you play locally with the
|
||||
copy, in order to have fast access, then the synchronization can't
|
||||
be one way. You may change flags, you may move messages in
|
||||
different folders etc. The issue described is clearly
|
||||
two-ways sync.
|
||||
|
||||
A better tool with this scenario is offlineimap,
|
||||
designed for this issue, and faster than imapsync.
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. I need to log every output on a file named log.txt
|
||||
|
||||
R1. imapsync logs on a file by default, its name is given at the
|
||||
beginning and the end of each run. This name is unique since
|
||||
it is compound of the current date and time and user2 value.
|
||||
|
||||
R2. To change this default name, use --logfile log.txt
|
||||
|
||||
imapsync ... --logfile log.txt
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. Quantifier in {,} bigger than 32766 in regex; marked by <-- HERE in
|
||||
m/(.{ <-- HERE 1,49947})(?:,|$)/ at Mail/IMAPClient.pm line 2121.
|
||||
|
||||
R. Do not use a bigger value than 3276 with --split1 or --split2
|
||||
|
||||
=======================================================================
|
||||
Q. Couldn't create [INBOX.Ops/foo/bar]: NO Invalid mailbox name:
|
||||
INBOX.Ops/foo/bar
|
||||
|
||||
Let begin by an explanation.
|
||||
|
||||
Example:
|
||||
sep1 = /
|
||||
sep2 = .
|
||||
|
||||
imapsync reverts each separator automatically.
|
||||
|
||||
a) All / character coming from host1 are converted to . (convert the separator)
|
||||
b) All . character coming from host1 are converted to / (to avoid
|
||||
intermediate unwanted folder creation).
|
||||
|
||||
So
|
||||
INBOX/Ops.foo.bar (Ops.foo.bar is just one folder name) will be translated to
|
||||
INBOX.Ops/foo/bar
|
||||
|
||||
Sometimes the sep1 character is not valid on host2 (character "/" usually)
|
||||
|
||||
R. Try :
|
||||
|
||||
--regextrans2 "s,/,X,g"
|
||||
|
||||
It'll convert / character to X
|
||||
Choose X as you wish: _ or SEP or
|
||||
any string (including the empty string).
|
||||
|
||||
This issue is automatically fixed by default since imapsync
|
||||
release 1.513, use --nofixslash2 to suppress the fix.
|
||||
|
||||
=======================================================================
|
||||
Q. Is it possible to sync also the UIDL of the POP3 server?
|
||||
|
||||
R. imapsync does not POP3 but I think you mean UID in IMAP.
|
||||
See next question.
|
||||
|
||||
=======================================================================
|
||||
Q. Is it possible to sync also the UIDs of the IMAP server?
|
||||
|
||||
UIDs in IMAP are chosen and created by the servers, not by the clients,
|
||||
imapsync is a client. So UIDs cannot be synced by any imap method.
|
||||
UIDs might be synced via a rsync command on the server part.
|
||||
|
||||
=======================================================================
|
||||
Q. The option --subscribe does not seem to work
|
||||
|
||||
R1. Use it with --subscribed
|
||||
|
||||
R2. There is also the --subscribe_all option that subscribe
|
||||
to all folders on host2.
|
||||
|
||||
=======================================================================
|
||||
Q. On Unix, some passwords contain * and " characters. Login fails.
|
||||
R. Use a backslash to escape the characters:
|
||||
|
||||
imapsync ... --password1 \"password\"
|
||||
|
||||
It works for the star * character,
|
||||
I don't know if it works for the " character.
|
||||
|
||||
=======================================================================
|
||||
Q. With huge account (many messages) when it comes to reading the
|
||||
destination server it comes out this error:
|
||||
"To Folder [INBOX.foobar] Not connected"
|
||||
What can I do?
|
||||
|
||||
R. May be spending too much time on the source server, the connection
|
||||
timed out on the destination server.
|
||||
Try options --nofoldersizes
|
||||
|
||||
======================================================================
|
||||
Q. Can Imapsync filter Spam during the sync?
|
||||
|
||||
R. No, imapsync doesn't detect Spam by itself and currently it can't
|
||||
delegate this job during its IMAP syncs. But I've seen blogs and
|
||||
Spamassassin documentation explaining solutions to apply Spamassassin
|
||||
to a imap mailbox. So you can apply one of these solutions on the host1
|
||||
source mailbox before the imapsync run or on the destination host2
|
||||
mailbox after the imapsync transfer.
|
||||
|
||||
http://www.stearns.org/doc/spamassassin-setup.current.html#isbg
|
||||
http://euer.krebsco.de/using-spamassassin-on-a-remote-imap-host.html
|
||||
https://github.com/ook/isbg
|
||||
|
||||
======================================================================
|
||||
Q. How to migrate from uw-imap with an admin/authuser account?
|
||||
|
||||
R. Use the following syntax:
|
||||
|
||||
imapsync ... --user1="loginuser*admin_user" --password1 "admin_user_password"
|
||||
|
||||
|
||||
======================================================================
|
||||
Q. How to migrate from cyrus with an admin account?
|
||||
|
||||
R. Use:
|
||||
|
||||
imapsync ... \
|
||||
--authuser1 admin_user ----password1 admin_user_password \
|
||||
--user1 foo_user --ssl1
|
||||
|
||||
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 or --tls1 since PLAIN auth is only
|
||||
supported with ssl encryption most of the time. But it can
|
||||
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
|
||||
being migrated from, "joe" here.
|
||||
|
||||
|
||||
Here is an example:
|
||||
imapsync \
|
||||
--host1 server1 \
|
||||
--user1 joe \
|
||||
--authuser1 AdminAccount \
|
||||
--password1 AdminAccountPassword \
|
||||
--ssl1 \
|
||||
--host2 server2 \
|
||||
--user2 joe \
|
||||
--password2 joespassonserver2 \
|
||||
--exclude "^user\."
|
||||
|
||||
======================================================================
|
||||
Q: How to migrate from Sun Java Enterprise System / Sun One / iPlanet /
|
||||
Netscape servers with an admin account?
|
||||
|
||||
R: Those imap servers don't allow the typical use of --authuser1 to use an
|
||||
administrative account. They expect the use of an IMAP command called
|
||||
proxyauth that is issued after login in as an administrative account.
|
||||
|
||||
For example, consider the administrative account 'administrator' and your
|
||||
real user 'real_user'. The IMAP sequence would be:
|
||||
|
||||
OK [CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ NAMESPACE UIDPLUS
|
||||
CHILDREN BINARY UNSELECT LANGUAGE STARTTLS XSENDER X-NETSCAPE XSERVERINFO
|
||||
AUTH=PLAIN] imap.server IMAP4 service (Sun Java(tm) System Messaging
|
||||
Server ...))
|
||||
1 LOGIN administrator password
|
||||
1 OK User logged in
|
||||
2 PROXYAUTH real_user
|
||||
2 OK Completed
|
||||
|
||||
In imapsync, you can achieve this by using the following options:
|
||||
|
||||
--host1 source.imap.server \
|
||||
--user1 real_user \
|
||||
--authuser1 administrator \
|
||||
--proxyauth1 \
|
||||
--passfile admin.txt
|
||||
|
||||
======================================================================
|
||||
Q. Is there anyway of making imapsync purge the destination folder
|
||||
when the source folder is deleted?
|
||||
|
||||
R. Yes, use --delete2folders
|
||||
|
||||
--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 <regex>: Deleted only folders matching regex.
|
||||
Example: --delete2foldersonly "/^Junk$|^INBOX.Junk$/"
|
||||
--delete2foldersbutnot <regex>: Do not delete folders matching regex.
|
||||
Example: --delete2foldersbutnot "/Tasks$|Contacts$|Foo$/"
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. I want to play with headers line and --regexmess but I want to leave
|
||||
the body as is.
|
||||
|
||||
R. The header/body separation is a blank line so an example:
|
||||
--regexmess 's{\A(.*?(?! ^$))^Date:(.*?)$}{$1Date:$2\nX-Date:$2}gxms'
|
||||
|
||||
Will replace the next three lines
|
||||
|
||||
Message-ID: <499EF800.4030002@blabla.fr>
|
||||
Date: Fri, 20 Feb 2009 19:35:44 +0100
|
||||
From: Gilles LAMIRAL <lamiral@linux-france.org>
|
||||
|
||||
by the next four lines
|
||||
|
||||
Message-ID: <499EF800.4030002@blabla.fr>
|
||||
Date: Fri, 20 Feb 2009 19:35:44 +0100
|
||||
X-Date: Fri, 20 Feb 2009 19:35:44 +0100
|
||||
From: Gilles LAMIRAL <lamiral@linux-france.org>
|
||||
|
||||
|
||||
This example just add an header line "X-Date:" based on "Date:" line.
|
||||
|
||||
=======================================================================
|
||||
Q. My imap server does not accept a message and warns
|
||||
"Invalid header". What is the problem?
|
||||
|
||||
R. You fall in the classical mbox versus Maildir/ format
|
||||
problem. May be you use a misconfigured procmail rule.
|
||||
|
||||
A header beginning like the following one is in the mbox
|
||||
format, header line 1 has no colon behind "From", header
|
||||
lines 2 through N do have a colon :
|
||||
|
||||
From foo@yoyo.org Sat Jun 22 01:10:21 2002
|
||||
Return-Path: <foo@yoyo.org>
|
||||
Received: ...
|
||||
|
||||
Any Maildir/ configured imap server may refuse this message since its
|
||||
header is invalid. The first "From " line is not valid. It lacks a
|
||||
colon character ":". To solve this issue you have several solutions
|
||||
|
||||
a) Remove manually this first "From " line for each message before
|
||||
using imapsync.
|
||||
|
||||
b) Replace manually the whitespace by a colon in string "From " but you
|
||||
might end with two "From:" lines (just have a look at the other
|
||||
header lines of the message)
|
||||
|
||||
c) Run imapsync with the following option (this replaces "From "by "From:"):
|
||||
--regexmess 's/\AFrom /From: /'
|
||||
|
||||
or may be better (no other "From:" collision):
|
||||
|
||||
d) Run imapsync with the following option (this replaces "From "by "X-om:"):
|
||||
--regexmess 's/\AFrom /X-From: /'
|
||||
|
||||
e) Run imapsync with the following option (this removes the whole "From " line):
|
||||
--regexmess 's{\AFrom\ [^\n]*(\n)?}{}gxms'
|
||||
|
||||
Solution e) is solution a) made by imapsync itself.
|
||||
Solutions c) and d) keep "From " lines information
|
||||
(normally it's useless to keep them)
|
||||
|
||||
Best solutions are e) or d).
|
||||
|
||||
=======================================================================
|
||||
Q. The contact folder isn't well copied.
|
||||
How to copy the contact folder?
|
||||
|
||||
R. Forget the destination server (choose the same)
|
||||
Change the script around line 1426
|
||||
# ITSD
|
||||
$new_id = $from->copy($t_fold,$f_msg);
|
||||
#$new_id = $to->append_string($t_fold,$string, $flags_f, $d);
|
||||
|
||||
and tried a copy of the mail instead an append_string. Because we are
|
||||
using the same server, we can use $from->copy Therefore we seem to not
|
||||
download and upload the message and therefore we do not have any
|
||||
format issues. And now it works fine. (Thanks to Hansjoerg.Maurer)
|
||||
|
||||
|
||||
======================================================================
|
||||
Q: How can I write an .rpm with imapsync
|
||||
|
||||
R. You'll find an RPM imapsync.spec file in the directory learn/rpm/
|
||||
It has been downloaded from
|
||||
https://svn.fysik.dtu.dk/projects/rpmbuild/trunk/SPECS/imapsync.spec
|
||||
It has been tested with imapsync 1.434 (May 2011) on CentOS5
|
||||
and RedHat RHEL5 Linux. (Thanks to Ole Holm Nielsen).
|
||||
This imapsync.spec is coming from Neil Brown work in 2007.
|
||||
|
||||
=======================================================================
|
||||
Q. Where I can read up on the various IMAP RFCs?
|
||||
|
||||
R. Here:
|
||||
|
||||
RFC 3501 - INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1
|
||||
http://www.faqs.org/rfcs/rfc3501.html
|
||||
|
||||
RFC2683 - IMAP4 Implementation Recommendations
|
||||
http://www.faqs.org/rfcs/rfc2683.html
|
||||
|
||||
RFC 2595 - Using TLS with IMAP, POP3 and ACAP
|
||||
http://www.faqs.org/rfcs/rfc2595.html
|
||||
|
||||
RFC 2822 - Internet Message Format
|
||||
http://www.faqs.org/rfcs/rfc2822.html
|
||||
|
||||
RFC 2342 - IMAP4 Namespace
|
||||
http://www.faqs.org/rfcs/rfc2342.html
|
||||
|
||||
RFC2180 - IMAP4 Multi-Accessed Mailbox Practice
|
||||
http://www.faqs.org/rfcs/rfc2180.html
|
||||
|
||||
RFC 4549 - Synchronization Operations for Disconnected IMAP4 Clients
|
||||
http://www.faqs.org/rfcs/rfc4549.html
|
||||
|
||||
|
32
FAQ.d/FAQ.Admin_Authentication.txt
Normal file
32
FAQ.d/FAQ.Admin_Authentication.txt
Normal file
@ -0,0 +1,32 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Admin_Authentication.txt,v 1.2 2017/01/06 14:11:13 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
==============================================
|
||||
Imapsync tips about admin authentication.
|
||||
==============================================
|
||||
|
||||
It can be useful to authenticate without knowing each user password.
|
||||
Using an admin account to authenticate is not a standard feature
|
||||
supported by all imap servers. Sometimes it is implemented via --authuser1
|
||||
sometimes not. It depends on the server software and its configuration.
|
||||
You have to figure out what is the imap software server,
|
||||
find out if it supports an admin account and how,
|
||||
if an admin account is actually configured and
|
||||
finally check an authentication via this admin account for
|
||||
a standard user.
|
||||
|
||||
Known imap server software supporting admin authentication:
|
||||
|
||||
* Exchange 2003/2007/2010/2013. See the file FAQ.Exchange.txt
|
||||
* Office365. See the file FAQ.Exchange.txt
|
||||
* Gmail. See the file FAQ.XOAUTH2.txt
|
||||
* Dovecot. See the file FAQ.Dovecot.txt
|
||||
* UW-imap. See the file FAQ.General.txt
|
||||
* Cyrus-imap. See the file FAQ.General.txt
|
||||
* Sun Java Enterprise System/SunOne/iPlanet. See the file FAQ.General.txt
|
||||
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
@ -1,5 +1,5 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Archiving.txt,v 1.2 2016/05/09 13:03:14 gilles Exp gilles $
|
||||
$Id: FAQ.Archiving.txt,v 1.6 2017/07/13 14:44:07 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
@ -7,6 +7,30 @@ This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
Imapsync tips about archiving messages.
|
||||
============================================
|
||||
|
||||
=======================================================================
|
||||
Q. Can I archive different accounts on the same destination account,
|
||||
each account on a separate folder?
|
||||
|
||||
R. Yes. Use --subfolder2
|
||||
|
||||
--subfolder2 str : Move whole host1 folders hierarchy under the
|
||||
host2 folder str.
|
||||
It is done it by adding two --regextrans2 options before
|
||||
all others. Add --debug to see what's really going on.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
imapsync ... --user1 foo --subfolder2 foo
|
||||
|
||||
imapsync ... --user1 bar --subfolder2 bar
|
||||
|
||||
In case you need a strict sync, add --delete2 --delete2foldersonly "foo"
|
||||
(or "bar"), il will delete on account2 what is not on account1 but only
|
||||
in the right place, ie, the subfolder "foo".
|
||||
|
||||
imapsync ... --user1 foo --subfolder2 foo --delete2 --delete2foldersonly "foo"
|
||||
|
||||
=======================================================================
|
||||
Q. How to move emails from one IMAP folder to another either on the
|
||||
same IMAP server or a different one?
|
||||
@ -21,3 +45,5 @@ Add option --delete if you want to move messages, instead of just copy/sync them
|
||||
|
||||
R2. See also file FAQ.Folders_Mapping.txt
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
54
FAQ.d/FAQ.Authentication_failure.txt
Normal file
54
FAQ.d/FAQ.Authentication_failure.txt
Normal file
@ -0,0 +1,54 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Authentication_failure.txt,v 1.5 2017/09/04 11:03:57 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
=======================================================================
|
||||
Imapsync authentication issues
|
||||
=======================================================================
|
||||
|
||||
|
||||
Host1 failure: Error login on [imap.example.com] with user [foo] auth [LOGIN]: 2 NO [AUTHENTICATIONFAILED] Authentication failed
|
||||
|
||||
|
||||
One over four imapsync syncs ends up quickly with the error message
|
||||
"Authentication failed" or "NO LOGIN failed" or similar.
|
||||
Authentication failure is the primary failure with imapsync
|
||||
and since nothing tangible can be done without authentication,
|
||||
this stage must succeed to go further.
|
||||
|
||||
Here are some advices to get you pass this difficult stage of authentication:
|
||||
|
||||
* Triple check each credendial parameter, there are three parameters at each side:
|
||||
* triple check --host1
|
||||
* triple check --user1
|
||||
* triple check --password1
|
||||
* triple check --host2
|
||||
* triple check --user2
|
||||
* triple check --password2
|
||||
|
||||
* If you can authenticate successfully with an other imap client software
|
||||
like Thunderbird or Outlook or Sparrow then it is a very good sign to
|
||||
authenticate successfully with imapsync. Examine the parameters of
|
||||
this other imap client and copy them as is for imapsync.
|
||||
|
||||
* Use option --showpasswords
|
||||
At the beginning of the output, imapsync dumps all its command
|
||||
line parameters; it's the line after "Command line used:".
|
||||
With --showpasswords, imapsync prints the passwords received
|
||||
instead of the string MASKED. It helps for debugging quoting issues.
|
||||
Option --showpasswords shows passwords again when the IMAP dialog
|
||||
is dumped by --debugimap option. Search for a line like
|
||||
"Sending: 2 LOGIN test1 secret1" (secret1 is the password here)
|
||||
|
||||
|
||||
* It is sometimes very hard to quote correctly unusual characters,
|
||||
especially on Windows. See
|
||||
https://imapsync.lamiral.info/FAQ.d/FAQ.Passwords_on_Windows.txt
|
||||
https://imapsync.lamiral.info/FAQ.d/FAQ.Passwords_on_Unix.txt
|
||||
The quicker trick might be to change the password temporarilly
|
||||
with easy characters like the classical alphabet, a long
|
||||
string will still ensure strong security.
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Contacts_Calendars.txt,v 1.3 2016/05/09 13:37:21 gilles Exp gilles $
|
||||
$Id: FAQ.Contacts_Calendars.txt,v 1.5 2017/01/06 14:11:13 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
@ -7,6 +7,11 @@ This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
Imapsync issues about syncing Contacts & Calendars.
|
||||
=========================================================
|
||||
|
||||
Questions anwswered in this FAQ are:
|
||||
|
||||
Q. Can I copy or sync Calendar or Contacts with imapsync?
|
||||
Q. How can I avoid copying Calendar or Contacts folders?
|
||||
Q. How can I copy or synchronize Calendars or Contacts?
|
||||
|
||||
=======================================================================
|
||||
Q. Can I copy or sync Calendar or Contacts with imapsync?
|
||||
@ -16,15 +21,29 @@ R. No, Imapsync can't migrate Contacts and Calendars.
|
||||
events via IMAP. In other words, messages synced by imapsync from
|
||||
Calendars or Contacts folders are not used by email servers to set
|
||||
or get the contacts or calendars.
|
||||
No way via IMAP, no way via imapsync.
|
||||
No way via IMAP, no way via imapsync.
|
||||
So it's a good idea to avoid syncing contacts and calendars.
|
||||
But see next question.
|
||||
|
||||
=======================================================================
|
||||
Q. How can I avoid copying Calendar or Contacts folders?
|
||||
|
||||
R1. You can avoid synchronizing Calendar or Contacts folders with
|
||||
the --exclude option. First you have to search what is their
|
||||
exact name. The folders listing printed by imapsync at the
|
||||
beginning of a run will surely help to find their names.
|
||||
Assuming their names are "Calendars" and "Contacts" use then:
|
||||
|
||||
imapsync ... --exclude "Calendar" --exclude "Contacts"
|
||||
|
||||
=======================================================================
|
||||
Q. How can I copy or synchronize Calendars or Contacts?
|
||||
|
||||
R1. It can't be done with imapsync. See previous question for explanations.
|
||||
R1. Synchronizing Calendars or Contacts can't be done with imapsync.
|
||||
See the first question for detailed explanations.
|
||||
|
||||
R2. It can be done, depending on the email server softwares used.
|
||||
R2. Synchronizing Calendars or Contacts can be done, not
|
||||
with imapsync, depending on the email server softwares used.
|
||||
|
||||
a) From Exchange to Exchange, export contacts and calendar to
|
||||
PST format files on host1 and import them on host2.
|
||||
@ -46,4 +65,6 @@ d) I plan to make tools for that but so far nothing has began
|
||||
http://www.linux-france.org/prj/imapsync_list/msg01797.html
|
||||
http://www.linux-france.org/prj/imapsync_list/msg01811.html
|
||||
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Dates.txt,v 1.3 2016/07/27 13:14:30 gilles Exp gilles $
|
||||
$Id: FAQ.Dates.txt,v 1.6 2017/08/29 05:34:55 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
@ -7,10 +7,19 @@ This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
Imapsync tips about dates.
|
||||
===============================
|
||||
|
||||
Questions anwswered in this FAQ are:
|
||||
|
||||
Q. We have found that the time and date displayed have been changed to
|
||||
the time at which the file was synchronized. What happened? Any fix?
|
||||
|
||||
Q. Is there a way to set any message with
|
||||
"Date: (Invalid)" to a valid one like
|
||||
"Date: Thu, 1 Jun 2017 23:59:59 +0000"?
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. We have found that the time and date displayed have been changed to
|
||||
the time at which the file was synchronized.
|
||||
the time at which the file was synchronized. What happened? Any fix?
|
||||
|
||||
R. This is the case by default with some email readers like:
|
||||
- Outlook 2003
|
||||
@ -70,7 +79,30 @@ by sent date, the "Date:" header line.
|
||||
b) Use a imap server that respects the imap RFC and accepts
|
||||
the internal date set by imapsync.
|
||||
|
||||
c) Try to understand why the reader shows another date than the "Date:" line.
|
||||
c) Try to understand why the email client software shows another date
|
||||
than the "Date:" header line.
|
||||
|
||||
=======================================================================
|
||||
Q. Is there a way to set any message with
|
||||
"Date: (Invalid)" to a valid one like
|
||||
"Date: Thu, 1 Jun 2017 23:59:59 +0000"?
|
||||
|
||||
R. Yes, there is a way with option --regexmess
|
||||
|
||||
First, let's select only messages with a buggy Date header:
|
||||
|
||||
--search "HEADER Date Invalid"
|
||||
|
||||
Second, let's change this line by a valid one,
|
||||
|
||||
on windows:
|
||||
|
||||
--regexmess "s{\A(.*?(?! ^$))^Date:\ \(Invalid\)(.*?)$}{$1Date: Thu, 1 Jun 2017 23:59:59 +0000}xms"
|
||||
|
||||
on Unix (replaced enclosing double-quotes " by single quotes ' ):
|
||||
|
||||
--regexmess 's{\A(.*?(?! ^$))^Date:\ \(Invalid\)(.*?)$}{$1Date: Thu, 1 Jun 2017 23:59:59 +0000}xms'
|
||||
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/cat
|
||||
# $Id: FAQ.Domino.txt,v 1.6 2016/01/28 14:34:15 gilles Exp gilles $
|
||||
# $Id: FAQ.Domino.txt,v 1.8 2017/03/02 12:54:15 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
@ -8,44 +8,44 @@ This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
=============================
|
||||
|
||||
|
||||
======================================================================
|
||||
Q. From Domino Notes to xxx
|
||||
=======================================================================
|
||||
Q. From Domino Notes to XXX
|
||||
|
||||
On Windows use:
|
||||
|
||||
imapsync.exe ... --sep1 "\\" --prefix1 ""
|
||||
imapsync.exe ... --sep1 "\\" --prefix1 "" --messageidnodomain
|
||||
|
||||
On Unix use:
|
||||
|
||||
imapsync ... --sep1 '\' --prefix1 ''
|
||||
imapsync ... --sep1 '\' --prefix1 '' --messageidnodomain
|
||||
|
||||
======================================================================
|
||||
Q. From xxx to Domino Notes
|
||||
=======================================================================
|
||||
Q. From XXX to Domino Notes
|
||||
|
||||
Domino doesn't accept INBOX subfolders.
|
||||
|
||||
On Windows:
|
||||
|
||||
imapsync.exe ... ^
|
||||
--sep2 "\\" --prefix2 "" ^
|
||||
--sep2 "\\" --prefix2 "" --messageidnodomain ^
|
||||
--regextrans2 "s,^Inbox\\(.*),$1,i"
|
||||
|
||||
On Unix:
|
||||
|
||||
imapsync ... \
|
||||
--sep2 '\' --prefix2 '' \
|
||||
--sep2 '\' --prefix2 '' --messageidnodomain \
|
||||
--regextrans2 's,^Inbox\\(.*),$1,i'
|
||||
|
||||
If you want to sync the complete host1 mailbox in a subfolder called OLDBOX use:
|
||||
|
||||
On Windows:
|
||||
imapsync.exe ... ^
|
||||
--sep2 "\\" --prefix2 "" ^
|
||||
--sep2 "\\" --prefix2 "" --messageidnodomain ^
|
||||
--subfolder2 "OLDBOX" --justfolders --dry
|
||||
|
||||
On Unix:
|
||||
imapsync ... \
|
||||
--sep2 '\' --prefix2 '' \
|
||||
--sep2 '\' --prefix2 '' --messageidnodomain \
|
||||
--subfolder2 'OLDBOX' --justfolders --dry
|
||||
|
||||
If the output is correct for you then remove --dry and have a run.
|
||||
@ -69,8 +69,10 @@ For Domino 853FP6 on Linux, we used this command on Unix:
|
||||
--host2 hhh2 --user2 uuu2 --password2 ppp2 \
|
||||
--exclude "^INBOX/Trash" --exclude 'Junk|Drafts' \
|
||||
--regextrans2 's#^INBOX/Sent$#^Sent#' \
|
||||
--prefix2 "" --sep2 "\/" \
|
||||
--prefix2 "" --sep2 "\/" --messageidnodomain \
|
||||
--regexmess 's{\A(.*?(?! ^$))^Date:(.*?)$}{$1Migratedbyus:$2\nx-MailDate:$2}gxms'
|
||||
|
||||
|
||||
======================================================================
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Dovecot.txt,v 1.4 2016/01/28 14:34:15 gilles Exp gilles $
|
||||
$Id: FAQ.Dovecot.txt,v 1.5 2017/01/06 14:21:06 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Duplicates.txt,v 1.10 2016/04/17 19:06:39 gilles Exp gilles $
|
||||
$Id: FAQ.Duplicates.txt,v 1.12 2017/08/31 03:06:45 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
======================================================================
|
||||
=======================================================================
|
||||
Imapsync tips about duplicated messages issues.
|
||||
======================================================================
|
||||
=======================================================================
|
||||
|
||||
=======================================================================
|
||||
Q. How can I remove duplicates in an lone account?
|
||||
@ -13,6 +13,27 @@ Q. How can I remove duplicates in an lone account?
|
||||
R. Just run imapsync on the same account with option --delete2duplicates,
|
||||
ie, with host1 == host2 and user1 == user2
|
||||
|
||||
=======================================================================
|
||||
Q. How can I know if imapsync will generate duplicates on a second run?
|
||||
|
||||
R. To see if imapsync will generate duplicates on a second run, start
|
||||
a second run with --dry option added. imapsync will then show if it
|
||||
would mistakenly copy messages again, but without really copying them
|
||||
|
||||
imapsync ... --dry
|
||||
|
||||
The final stats should also show a positive value for the line
|
||||
"Messages skipped:" since most of the skipped messages are skipped
|
||||
because they are already on host2. Example of final stats:
|
||||
|
||||
++++ Statistics
|
||||
Transfer started on : Thu Aug 31 04:28:32 2017
|
||||
Transfer ended on : Thu Aug 31 04:28:44 2017
|
||||
Transfer time : 11.7 sec
|
||||
Folders synced : 1/1 synced
|
||||
Messages transferred : 0
|
||||
Messages skipped : 1555
|
||||
|
||||
=======================================================================
|
||||
Q: Multiple copies, duplicates, when I run imapsync twice ore more.
|
||||
|
||||
@ -140,5 +161,4 @@ R2. With option --useuid imapsync doesn't use headers to identify
|
||||
In that case duplicates on host1 are also transferred on host2.
|
||||
|
||||
=======================================================================
|
||||
|
||||
|
||||
=======================================================================
|
||||
|
@ -1,11 +1,11 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Emptying.txt,v 1.4 2016/04/24 00:07:47 gilles Exp gilles $
|
||||
$Id: FAQ.Emptying.txt,v 1.5 2017/01/06 14:11:13 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
============================================
|
||||
=======================================================================
|
||||
Imapsync tip to empty an account.
|
||||
============================================
|
||||
=======================================================================
|
||||
|
||||
=======================================================================
|
||||
Q. How to delete all emails of all folders of an account with imapsync?
|
||||
@ -33,3 +33,4 @@ Example:
|
||||
./imapsync ... --delete2folders --foldersizes
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Exchange.txt,v 1.23 2016/08/10 01:29:37 gilles Exp gilles $
|
||||
|
||||
$Id: FAQ.Exchange.txt,v 1.34 2017/07/18 21:27:18 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
@ -11,13 +11,16 @@ Questions anwswered in this FAQ are:
|
||||
|
||||
Q. Can I use imapsync to transfer from or to Exchange or Office365 accounts?
|
||||
|
||||
Q. How to sync from XXX to Exchange 2010/2013
|
||||
Q. How to sync from XXX to Exchange 2010/2013/2016
|
||||
|
||||
Q. How to sync from XXX to Office365
|
||||
|
||||
Q. For Office365 I have double and triple checked the username and
|
||||
password spelling but I still get a "LOGIN failed". Any clue?
|
||||
|
||||
Q. I see "NO Maximum size of appendable message has been exceeded"
|
||||
What can I do with that?
|
||||
|
||||
Q. Exchange fails with "User is authenticated but not connected".
|
||||
|
||||
Q. Exchange fails with "BAD Command received in Invalid state".
|
||||
@ -25,6 +28,9 @@ Q. Exchange fails with "BAD Command received in Invalid state".
|
||||
Q. From XXX to Exchange 2013 or Office365, read receipts are all
|
||||
resent again after a sync. Even for old messages. How can I fix that?
|
||||
|
||||
Q. DEBUG: IO/Socket/SSL.pm:1043: local error: SSL read error
|
||||
DEBUG: IO/Socket/SSL.pm:1043: local error: SSL read error
|
||||
|
||||
Q. From XXX to Exchange 2010/2013 or Office365 I get this error message
|
||||
sometimes: "BAD Command Argument Error 11". What does it mean?
|
||||
|
||||
@ -60,12 +66,14 @@ R. Yes. But IMAP access to a Exchange or Office365 account is not always
|
||||
part:
|
||||
|
||||
=======================================================================
|
||||
Q. How to sync from XXX to Exchange 2010/2013
|
||||
Q. How to sync from XXX to Exchange 2010/2013/2016
|
||||
|
||||
R. Here is a command line resume that solves most encountered issues when
|
||||
migrating to Exchange. To understand or change the details you have
|
||||
to read next Q/R sections.
|
||||
R0. IMAP is not enable by default on Exchange, see how to enable it:
|
||||
https://technet.microsoft.com/en-us/library/bb124489(v=exchg.150).aspx
|
||||
|
||||
R1. Following is a command line resume that solves most encountered
|
||||
issues when migrating to Exchange. To fully understand or change
|
||||
the details you have to read the next Q/R sections.
|
||||
|
||||
On Windows:
|
||||
|
||||
@ -155,13 +163,39 @@ R2. Miguel Alameda reported understanding and solving this issue
|
||||
like this, the context was admin/authuser:
|
||||
"The admin user had not permission in the target mailbox."
|
||||
|
||||
=======================================================================
|
||||
Q. I see "NO Maximum size of appendable message has been exceeded"
|
||||
What can I do with that?
|
||||
|
||||
R. Office 365 supports send/receive max message sizes of up to 150MB
|
||||
but you need to make changes in your tenant(s) to support it.
|
||||
|
||||
The following PowerShell command will increase the message sizes that
|
||||
can be sent/received. The trick in getting IMAPSync to work is to
|
||||
apply these settings to the accounts performing the migration,
|
||||
NOT the accounts associated with the target mailbox (assuming you're
|
||||
using service accounts to perform transfers on behalf of users).
|
||||
|
||||
Set-mailbox -Identity $UPN -MaxReceiveSize 150mb -MaxSendSize 150mb
|
||||
|
||||
e.g.
|
||||
|
||||
Set-mailbox -Identity "migrationaccount@testtenant.onmicrosoft.com" -MaxReceiveSize 150mb -MaxSendSize 150mb
|
||||
|
||||
We're transferring data between Office 365 tenants so we set these
|
||||
values on the migration acounts in the source and target tenants.
|
||||
|
||||
Thanks to Sean McDougall, Ian Thomas & Matt Wilks from Toronto
|
||||
for this FAQ item.
|
||||
|
||||
=======================================================================
|
||||
Q. Exchange fails with "BAD Command received in Invalid state".
|
||||
|
||||
R. This message might happens when authentication without ssl nor tls.
|
||||
R. This message might happens when authenticating without ssl nor tls.
|
||||
Add --tls1 or --ssl1 if this error message comes from host1.
|
||||
Add --tls2 or --ssl2 if this error message comes from host1.
|
||||
Add --tls2 or --ssl2 if this error message comes from host2.
|
||||
|
||||
(Never add --tlsX and --sslX on the same side X (1 or 2), it won't work)
|
||||
=======================================================================
|
||||
Q. From XXX to Exchange 2013 or Office365, read receipts are all
|
||||
resent again after a sync. Even for old messages. How can I fix that?
|
||||
@ -196,6 +230,19 @@ X-Disposition-Notification-To: blabla
|
||||
|
||||
Thanks to David Karnowski for pointing and solving this issue.
|
||||
|
||||
=======================================================================
|
||||
Q. DEBUG: IO/Socket/SSL.pm:1043: local error: SSL read error
|
||||
DEBUG: IO/Socket/SSL.pm:1043: local error: SSL read error
|
||||
|
||||
R1. "SSL read or write error" happens sometimes, it isn't related to
|
||||
imapsync directly but to the ssl underlying library when communicating
|
||||
with Exchange in TLS/SSL encrypted mode.
|
||||
Next runs should put the sync further, so rerun the syncs
|
||||
until it is well completed.
|
||||
|
||||
R2. Another solution is to remove --tls or --ssl options for Exchange
|
||||
and accept a clear text sync.
|
||||
|
||||
=======================================================================
|
||||
Q. From XXX to Exchange 2010/2013 or Office365 I get this error message
|
||||
sometimes: "BAD Command Argument Error 11". What does it mean?
|
||||
@ -273,11 +320,19 @@ Q. Exchange and Office365 have throttle mechanisms to limit any huge
|
||||
usage. Sometimes imapsync transfers are too stressful for servers.
|
||||
How to deal with that?
|
||||
|
||||
R. It looks like limiting 4 messages per second is enough to never
|
||||
reach any throttle limit.
|
||||
R. It looks like limiting 4 messages per second is enough to avoid
|
||||
the throttle limits.
|
||||
|
||||
imapsync ... --maxmessagespersecond 4
|
||||
|
||||
In case throttle appears anyway, fix them with:
|
||||
https://technet.microsoft.com/en-us/library/jj863577(v=exchg.150).aspx
|
||||
See also:
|
||||
http://www.linux-france.org/prj/imapsync_list/msg02072.html
|
||||
|
||||
Sometimes restarting the Exchange server is needed to take
|
||||
into account the change in the configuration.
|
||||
|
||||
======================================================================
|
||||
Q. How to migrate from or to Exchange 2007/2010/2013 with an
|
||||
admin/authuser account?
|
||||
@ -347,6 +402,12 @@ So don't use --authmech1 SOMETHING with --authuser1 admin_user,
|
||||
it will not work.
|
||||
Same behavior with the --authuser2 option.
|
||||
|
||||
Note from Martin Paulucci:
|
||||
I had to remove the domain part for the user
|
||||
but not for the admin. Example:
|
||||
|
||||
imapsync ... --authuser2 user_admin@domain.com --user2 user_to_be_migrated
|
||||
|
||||
See also:
|
||||
http://www.linux-france.org/prj/imapsync_list/msg02203.html
|
||||
|
||||
@ -458,3 +519,4 @@ R. imapsync ... --prefix1 "INBOX."
|
||||
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
@ -1,11 +1,11 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Flags.txt,v 1.7 2016/01/28 14:34:15 gilles Exp gilles $
|
||||
$Id: FAQ.Flags.txt,v 1.17 2017/07/27 15:39:57 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
===============================
|
||||
=======================================================================
|
||||
Imapsync tips about flags.
|
||||
===============================
|
||||
=======================================================================
|
||||
|
||||
Questions answered here are:
|
||||
|
||||
@ -15,7 +15,11 @@ Q. Is there a way to only sync messages with a specific flag set,
|
||||
for example, the \Seen flag?
|
||||
|
||||
Q. How to convert flags?
|
||||
|
||||
|
||||
Q. Exchange sends an email to any sender whose email is deleted
|
||||
without reading. It's called "unread notifications".
|
||||
How to set the \Seen flag on host1 (source system) before syncing?
|
||||
|
||||
Q. Does imapsync retain the \Answered and $Forwarded flags?
|
||||
|
||||
Q. How to fix this error: BAD Invalid system flag \FORWARDED
|
||||
@ -25,9 +29,16 @@ Q. How to convert flags with $ to \ character?
|
||||
Q. imapsync fails with the following error:
|
||||
flags from : [\Seen NonJunk]
|
||||
Error trying to append string: 58 NO APPEND Invalid flag list
|
||||
|
||||
|
||||
Q. Flags are not well synchronized. Is it a bug?
|
||||
|
||||
Q. Flags are resynced at each run for already synced/copied messages,
|
||||
how can I avoid this feature?
|
||||
|
||||
Q. Is it possible to sync labels and stars made by Thunderbird to
|
||||
Exchange categories? Or a way in Outlook to show labels created by
|
||||
Thunderbird?
|
||||
|
||||
=======================================================================
|
||||
Q. How to debug flag issues?
|
||||
|
||||
@ -50,35 +61,15 @@ or
|
||||
|
||||
or ...
|
||||
|
||||
The complete list of search things are listed below
|
||||
The complete list of search things related to flags are listed below
|
||||
|
||||
http://www.faqs.org/rfcs/rfc3501.html
|
||||
|
||||
6.4.4. SEARCH Command
|
||||
...
|
||||
ALL
|
||||
All messages in the mailbox; the default initial key for
|
||||
ANDing.
|
||||
|
||||
ANSWERED
|
||||
Messages with the \Answered flag set.
|
||||
|
||||
BCC <string>
|
||||
Messages that contain the specified string in the envelope
|
||||
structure's BCC field.
|
||||
|
||||
BEFORE <date>
|
||||
Messages whose internal date (disregarding time and timezone)
|
||||
is earlier than the specified date.
|
||||
|
||||
BODY <string>
|
||||
Messages that contain the specified string in the body of the
|
||||
message.
|
||||
|
||||
CC <string>
|
||||
Messages that contain the specified string in the envelope
|
||||
structure's CC field.
|
||||
|
||||
DELETED
|
||||
Messages with the \Deleted flag set.
|
||||
|
||||
@ -88,25 +79,9 @@ http://www.faqs.org/rfcs/rfc3501.html
|
||||
FLAGGED
|
||||
Messages with the \Flagged flag set.
|
||||
|
||||
FROM <string>
|
||||
Messages that contain the specified string in the envelope
|
||||
structure's FROM field.
|
||||
|
||||
HEADER <field-name> <string>
|
||||
Messages that have a header with the specified field-name (as
|
||||
defined in [RFC-2822]) and that contains the specified string
|
||||
in the text of the header (what comes after the colon). If the
|
||||
string to search is zero-length, this matches all messages that
|
||||
have a header line with the specified field-name regardless of
|
||||
the contents.
|
||||
|
||||
KEYWORD <flag>
|
||||
Messages with the specified keyword flag set.
|
||||
|
||||
LARGER <n>
|
||||
Messages with an [RFC-2822] size larger than the specified
|
||||
number of octets.
|
||||
|
||||
NEW
|
||||
Messages that have the \Recent flag set but not the \Seen flag.
|
||||
This is functionally equivalent to "(RECENT UNSEEN)".
|
||||
@ -119,10 +94,6 @@ http://www.faqs.org/rfcs/rfc3501.html
|
||||
functionally equivalent to "NOT RECENT" (as opposed to "NOT
|
||||
NEW").
|
||||
|
||||
ON <date>
|
||||
Messages whose internal date (disregarding time and timezone)
|
||||
is within the specified date.
|
||||
|
||||
OR <search-key1> <search-key2>
|
||||
Messages that match either search key.
|
||||
|
||||
@ -132,42 +103,6 @@ http://www.faqs.org/rfcs/rfc3501.html
|
||||
SEEN
|
||||
Messages that have the \Seen flag set.
|
||||
|
||||
SENTBEFORE <date>
|
||||
Messages whose [RFC-2822] Date: header (disregarding time and
|
||||
timezone) is earlier than the specified date.
|
||||
|
||||
SENTON <date>
|
||||
Messages whose [RFC-2822] Date: header (disregarding time and
|
||||
timezone) is within the specified date.
|
||||
|
||||
SENTSINCE <date>
|
||||
Messages whose [RFC-2822] Date: header (disregarding time and
|
||||
timezone) is within or later than the specified date.
|
||||
|
||||
SINCE <date>
|
||||
Messages whose internal date (disregarding time and timezone)
|
||||
is within or later than the specified date.
|
||||
|
||||
SMALLER <n>
|
||||
Messages with an [RFC-2822] size smaller than the specified
|
||||
number of octets.
|
||||
|
||||
SUBJECT <string>
|
||||
Messages that contain the specified string in the envelope
|
||||
structure's SUBJECT field.
|
||||
|
||||
TEXT <string>
|
||||
Messages that contain the specified string in the header or
|
||||
body of the message.
|
||||
|
||||
TO <string>
|
||||
Messages that contain the specified string in the envelope
|
||||
structure's TO field.
|
||||
|
||||
UID <sequence set>
|
||||
Messages with unique identifiers corresponding to the specified
|
||||
unique identifier set. Sequence set ranges are permitted.
|
||||
|
||||
UNANSWERED
|
||||
Messages that do not have the \Answered flag set.
|
||||
|
||||
@ -197,6 +132,44 @@ For example to convert flag IMPORTANT to flag CANWAIT
|
||||
option --debugflags is usefull to see in details what imapsync
|
||||
does with flags.
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. Exchange sends an email to any sender whose email is deleted
|
||||
without reading. It's called "unread notifications".
|
||||
How to set the \Seen flag on host1 (source system) before syncing?
|
||||
|
||||
R. You can add \Seen (if missing) to the host1 account by applying a
|
||||
first sync to the same account, same at source and destination,
|
||||
and the help of option --regexflag. It can also be done on the fly
|
||||
from account1 to account2 in case account1 has to stay as it is.
|
||||
|
||||
Add the \Seen flag to all messages like this:
|
||||
|
||||
On Winwows:
|
||||
|
||||
imapsync.exe ... --regexflag "s,^((?!\\Seen)).*$,$1 \\Seen,"
|
||||
|
||||
On Unix:
|
||||
|
||||
imapsync ... --regexflag 's,^((?!\\Seen)).*$,$1 \\Seen,'
|
||||
|
||||
R2. You can also filter with --search1 UNSEEN and use a simpler
|
||||
regex:
|
||||
|
||||
On Winwows:
|
||||
|
||||
imapsync.exe ... --search1 UNSEEN --regexflag "s/(.*)/$1 \\Seen/"
|
||||
|
||||
On Unix:
|
||||
|
||||
imapsync ... --search1 UNSEEN --regexflag 's/(.*)/$1 \\Seen/'
|
||||
|
||||
R3. Fix it on the server Exchange:
|
||||
Google translate:
|
||||
https://translate.google.com/translate?sl=auto&tl=en&u=https%3A%2F%2Fwww.ci-solution.com%2Fblog%2Fartikel%2Fungelesen-geloescht-verhindern.html
|
||||
German original:
|
||||
https://www.ci-solution.com/blog/artikel/ungelesen-geloescht-verhindern.html
|
||||
(Link from Oliver B.)
|
||||
=======================================================================
|
||||
Q. Does imapsync retain the \Answered and $Forwarded flags?
|
||||
|
||||
@ -224,7 +197,7 @@ R. Filter flag \FORWARDED with --regexflag like this:
|
||||
|
||||
On Windows:
|
||||
|
||||
imapsync ... --regexflag "s/\\FORWARDED//gi"
|
||||
imapsync.exe ... --regexflag "s/\\FORWARDED//gi"
|
||||
|
||||
On Unix:
|
||||
|
||||
@ -234,6 +207,19 @@ or
|
||||
|
||||
imapsync ... --regexflag "s/\\\\FORWARDED//gi"
|
||||
|
||||
Other related flags to remove are \Indexed and \ATTACHED
|
||||
|
||||
Windows: imapsync.exe ... --regexflag "s/\\Indexed//gi"
|
||||
Unix: imapsync ... --regexflag 's/\\Indexed//gi'
|
||||
|
||||
Windows: imapsync.exe ... --regexflag "s/\\ATTACHED//gi"
|
||||
Unix: imapsync ... --regexflag 's/\\ATTACHED//gi'
|
||||
|
||||
All usually problematic flags in one line:
|
||||
|
||||
Windows: imapsync.exe ... --regexflag "s/\\FORWARDED|\\Indexed|\\ATTACHED//gi"
|
||||
Unix: imapsync ... --regexflag 's/\\FORWARDED|\\Indexed|\\ATTACHED//gi'
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. How to convert flags with $ to \ character?
|
||||
@ -280,5 +266,37 @@ Two solutions:
|
||||
option --syncflagsaftercopy does it again using the imap STORE
|
||||
command.
|
||||
|
||||
=======================================================================
|
||||
Q. Flags are resynced at each run for already synced/copied messages,
|
||||
how can I avoid this feature?
|
||||
|
||||
R. It is not possible to avoid this feature by an option for now.
|
||||
If you really need this then ask for it and I might code it.
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. Is it possible to sync labels and stars made by Thunderbird to
|
||||
Exchange categories? Or a way in Outlook to show labels created by
|
||||
Thunderbird?
|
||||
|
||||
R. Imapsync syncs all flags possible by default, so if it doesn't do
|
||||
that it might means there are not on the server but stay only on the
|
||||
client or that the host2 server claims to accept only a given set
|
||||
of flags.
|
||||
|
||||
Check those claims by accessing the same mailbox on the same server
|
||||
from another thunderbird on another host, you should not retrieve
|
||||
those labels. If you do find them it then might mean that host2
|
||||
server don't want them, try --nofilterflags
|
||||
|
||||
imapsync ... --nofilterflags
|
||||
|
||||
You can try --nofilterflags straightaway without the
|
||||
"other thunderbird" proposal.
|
||||
|
||||
There is also the possibility to map flags across servers
|
||||
with --regexflags
|
||||
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
@ -1,11 +1,11 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Folders_Mapping.txt,v 1.10 2016/01/28 14:34:15 gilles Exp gilles $
|
||||
$Id: FAQ.Folders_Mapping.txt,v 1.13 2017/05/24 19:18:41 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
===============================================
|
||||
=======================================================================
|
||||
Imapsync tips about changing folders names.
|
||||
===============================================
|
||||
=======================================================================
|
||||
|
||||
Folders names are by default reproduced identical except for
|
||||
the prefix and the separator which are automatically adapted
|
||||
@ -46,22 +46,22 @@ Here
|
||||
|
||||
*) Good method to elaborate any --regextrans2 string
|
||||
|
||||
First elaborate the --regextrans2 string with --dry --justfolders
|
||||
--nofoldersizes options.
|
||||
With --dry imapsync shows the transformations it will do without
|
||||
really doing them.
|
||||
With --justfolders imapsync will work only with folders,
|
||||
messages won't be taken into account.
|
||||
With --nofoldersizes imapsync won't spend time useless time on
|
||||
evaluating folders sizes.
|
||||
First, elaborate the --regextrans2 string with --dry --justfolders options.
|
||||
|
||||
When the output shows what you escape imapsync to do with folders
|
||||
imapsync ... --dry --justfolders
|
||||
|
||||
With --dry imapsync shows the transformations it will do without
|
||||
really doing them, --dry is the "do nothing" mode.
|
||||
With --justfolders imapsync will work only with folders,
|
||||
messages won't be taken into account, so it will be fast.
|
||||
|
||||
When the output shows what you expect imapsync to do with folders
|
||||
names, you can remove the --dry option. Keep the --justfolders
|
||||
option in order to see if the destination server host2 accepts
|
||||
to create the folders.
|
||||
|
||||
When everything is ok with folders you can remove --justfolders
|
||||
and --nofoldersizes imapsync will also transfer messages.
|
||||
When everything is ok with folders you might remove --justfolders,
|
||||
imapsync will also transfer messages.
|
||||
Showing folders sizes is good then transferring messages, it allows
|
||||
ETA calculation and it's a supplementary check on folders.
|
||||
|
||||
@ -183,7 +183,7 @@ to folder INBOX only on host2:
|
||||
|
||||
1) First try (safe mode):
|
||||
|
||||
--regextrans2 "s/(.*)/INBOX/" --dry --justfolders
|
||||
--regextrans2 "s/.*/INBOX/" --dry --justfolders
|
||||
|
||||
2) See if the output says everything you want imapsync to do,
|
||||
--dry option is safe and does nothing real.
|
||||
@ -247,5 +247,4 @@ imapsync ... \
|
||||
--folder INBOX
|
||||
|
||||
=======================================================================
|
||||
|
||||
|
||||
=======================================================================
|
||||
|
@ -1,11 +1,11 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Folders_Selection.txt,v 1.4 2016/06/07 22:19:04 gilles Exp gilles $
|
||||
$Id: FAQ.Folders_Selection.txt,v 1.6 2017/07/20 11:02:11 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
=====================================
|
||||
=======================================================================
|
||||
Imapsync tips to select folders.
|
||||
=====================================
|
||||
=======================================================================
|
||||
|
||||
By default, Imapsync syncs all folders, one by one, in alphanumeric order.
|
||||
|
||||
@ -19,7 +19,7 @@ square brackets, the right column is the human utf8 view.
|
||||
|
||||
|
||||
|
||||
======================================================================
|
||||
=======================================================================
|
||||
Q. How can I sync only one folder?
|
||||
|
||||
R. Use --folder option.
|
||||
@ -31,25 +31,24 @@ If you have more specific folders to sync just add several --folder
|
||||
imapsync ... --folder MyFolder --folder ThisFolder --folder ThatFolder
|
||||
|
||||
|
||||
======================================================================
|
||||
=======================================================================
|
||||
Q. What are --subscribe and --subscribed for, and how can they be used?
|
||||
|
||||
R. In the IMAP protocol each user can subscribe to one or more folders.
|
||||
Then one can configure his email software to just see his subscribed
|
||||
folders. That's an IMAP feature.
|
||||
|
||||
Knowing that, the imapsync help mentions:
|
||||
Imapsync can use this imap feature to select subscribed folders
|
||||
and also subscribe to folders on host2. Here are the options:
|
||||
|
||||
imapsync --help
|
||||
...
|
||||
--subscribed : transfers subscribed folders.
|
||||
--subscribe : subscribe to the folders transferred on the
|
||||
host2 that are subscribed on host1.
|
||||
--subscribe_all : subscribe to the folders transferred on the
|
||||
host2 even if they are not subscribed on host1.
|
||||
--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.
|
||||
|
||||
|
||||
======================================================================
|
||||
=======================================================================
|
||||
Q. I want to exclude a folder hierarchy like "public"
|
||||
|
||||
R. Use:
|
||||
@ -65,7 +64,7 @@ output line :
|
||||
From folders list : [INBOX] [public.dreams] [etc.]
|
||||
|
||||
|
||||
======================================================================
|
||||
=======================================================================
|
||||
Q. I want to exclude only INBOX
|
||||
|
||||
R. Use:
|
||||
@ -76,7 +75,7 @@ A good way to see what will be done is to first use:
|
||||
|
||||
imapsync ... --exclude "^INBOX$" --justfolders --nofoldersizes --dry
|
||||
|
||||
======================================================================
|
||||
=======================================================================
|
||||
Q. I want to exclude folders matching SPAM no matter the case,
|
||||
aka how to be case insensitive
|
||||
|
||||
@ -89,7 +88,7 @@ A good way to see what will be done is to first use:
|
||||
imapsync ... --exclude "(?i)spam" --justfolders --nofoldersizes --dry
|
||||
|
||||
|
||||
======================================================================
|
||||
=======================================================================
|
||||
Q. I want the --folder "MyFolder" option be recursive.
|
||||
|
||||
Two solutions:
|
||||
@ -102,5 +101,5 @@ R2. Use --include "^MyFolder"
|
||||
Then the folder "MyFolder" and all its subfolders will be handled
|
||||
and only them.
|
||||
|
||||
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
797
FAQ.d/FAQ.General.txt
Normal file
797
FAQ.d/FAQ.General.txt
Normal file
@ -0,0 +1,797 @@
|
||||
#!/bin/cat
|
||||
# $Id: FAQ.General.txt,v 1.233 2017/09/07 22:08:42 gilles Exp gilles $
|
||||
|
||||
=======================================================================
|
||||
General FAQ for imapsync
|
||||
=======================================================================
|
||||
|
||||
This document is also available at
|
||||
https://imapsync.lamiral.info/#doc
|
||||
https://imapsync.lamiral.info/FAQ.d/FAQ.General.txt
|
||||
|
||||
Questions anwswered in this FAQ are:
|
||||
|
||||
Q. Do I need to create IMAP mailboxes at the destination platform?
|
||||
|
||||
Q. Am I forced to publish the IMAP service on internet since the two
|
||||
environment are not in the same location or same LAN?
|
||||
|
||||
Q. What are the most important differences between the Unix shell syntax
|
||||
and the Windows batch syntax.
|
||||
|
||||
Q. How to install imapsync?
|
||||
|
||||
Q. How to use imapsync?
|
||||
|
||||
Q. Can you give some configuration examples?
|
||||
|
||||
Q. How can I have commercial support?
|
||||
|
||||
Q. How can I have gratis support?
|
||||
|
||||
Q. Where I can find old imapsync releases?
|
||||
|
||||
Q. Where I can find free open and gratis imapsync releases?
|
||||
|
||||
Q. Is is legal to find imapsync gratis (or not) elsewhere?
|
||||
|
||||
Q. How "Facts and figures" are known
|
||||
https://imapsync.lamiral.info/#NUMBERS
|
||||
|
||||
Q. I use --useuid which uses a cache in /tmp or --tmpdir, the hostnames
|
||||
host1 or host2 has changed but mailboxes are the same. Will imapsync
|
||||
generate duplicate messages on next runs?
|
||||
|
||||
Q. How can I speed up transfers?
|
||||
|
||||
Q. I see warning messages like the following:
|
||||
"Host1 Sent/15 size 1428 ignored (no header so we ignore this message.
|
||||
To solve this: use --addheader)".
|
||||
What can I do to transfer those messages?
|
||||
|
||||
Q. How can I try imapsync with latest Mail::IMAPClient 3.xx perl module?
|
||||
|
||||
Q. How can I use imapsync with Mail::IMAPClient 2.2.9 perl module?
|
||||
|
||||
Q. How to verify imapsync.exe I got is the right file bit per bit?
|
||||
|
||||
Q. Can I use imapsync to migrate emails from pop3 server to imap server?
|
||||
|
||||
Q. Folders are not created on host2. What happens?
|
||||
|
||||
Q. I am interested in creating a local clone of the IMAP on a LAN
|
||||
server for faster synchronizations, email will always be delivered
|
||||
to the remote server and so the synchronization will be one way - from
|
||||
remote to local. How suited is imapsync for continuous one-way
|
||||
synchronization of mailboxes? Is there a better solution?
|
||||
|
||||
Q. I need to log every output on a file named log.txt
|
||||
|
||||
Q. Quantifier in {,} bigger than 32766 in regex; marked by <-- HERE in
|
||||
m/(.{ <-- HERE 1,49947})(?:,|$)/ at Mail/IMAPClient.pm line 2121.
|
||||
|
||||
Q. Couldn't create [INBOX.Ops/foo/bar]: NO Invalid mailbox name:
|
||||
INBOX.Ops/foo/bar
|
||||
|
||||
Q. Is it possible to sync also the UIDL of the POP3 server?
|
||||
|
||||
Q. Is it possible to sync also the UIDs of the IMAP server?
|
||||
|
||||
Q. The option --subscribe does not seem to work
|
||||
|
||||
Q. With huge account (many messages) when it comes to reading the
|
||||
destination server it comes out this error:
|
||||
"To Folder [INBOX.foobar] Not connected"
|
||||
What can I do?
|
||||
|
||||
Q. Can Imapsync filter Spam during the sync?
|
||||
|
||||
Q. How to migrate from uw-imap with an admin/authuser account?
|
||||
|
||||
Q. How to migrate from cyrus with an admin account?
|
||||
|
||||
Q: How to migrate from Sun Java Enterprise System / Sun One / iPlanet /
|
||||
Netscape servers with an admin account?
|
||||
|
||||
Q. Is there a way to delete the destination folder when the source
|
||||
folder is no longer there?
|
||||
|
||||
Q. I would love to have a function to inject lines in the header.
|
||||
Things like "X-migrated-from-foo: 20100617"
|
||||
|
||||
Q. I want to play with headers line and --regexmess but I want to leave
|
||||
the body as is.
|
||||
|
||||
Q. My imap server does not accept a message and warns
|
||||
"Invalid header". What is the problem?
|
||||
|
||||
Q. The contact folder isn't well copied.
|
||||
How to copy the contact folder?
|
||||
|
||||
Q: How can I write an .rpm with imapsync
|
||||
|
||||
Q. Where I can read up on the various IMAP RFCs?
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. Do I need to create IMAP mailboxes at the destination platform?
|
||||
|
||||
R. Yes!
|
||||
Imapsync does only IMAP and there is no way to create an account
|
||||
with the standard IMAP protocol. So you have to create them first.
|
||||
|
||||
=======================================================================
|
||||
Q. Am I forced to publish the IMAP service on internet since the two
|
||||
environment are not in the same location or same LAN?
|
||||
|
||||
R. The host where you run imapsync has to contact both servers via imap.
|
||||
You are not obliged to publish the imap service on internet if the host
|
||||
where you run imapsync can contact both imap servers via imap.
|
||||
Use their names or their IP addresses.
|
||||
|
||||
=======================================================================
|
||||
Q. What are the most important differences between the Unix shell syntax
|
||||
and the Windows batch syntax.
|
||||
|
||||
R. There are several differences between Unix and Windows
|
||||
in the command line syntax.
|
||||
- Character \ on Unix versus ^ on Windows
|
||||
- Character ' on Unix versus " on Windows
|
||||
|
||||
Details:
|
||||
|
||||
A) \ versus ^
|
||||
|
||||
On Unix shells you can write a single command on multiple lines
|
||||
by using the escape character \ at the end of each line
|
||||
(except the last one). On Windows this character is ^
|
||||
|
||||
Unix example:
|
||||
|
||||
./imapsync \
|
||||
--host1 imap.truc.org --user1 foo --password1 secret1 \
|
||||
--host2 imap.trac.org --user2 bar --password2 secret2
|
||||
|
||||
|
||||
Windows example:
|
||||
|
||||
imapsync ^
|
||||
--host1 imap.truc.org --user1 foo --password1 secret1 ^
|
||||
--host2 imap.trac.org --user2 bar --password2 secret2
|
||||
|
||||
|
||||
Of course you can write the command on a single line without
|
||||
characters \ nor ^. I use them because the output is
|
||||
better, no truncation, pretty print. It's just sugar!
|
||||
|
||||
In this FAQ I use \ for examples. Transcript to ^ if
|
||||
you're on a Windows system.
|
||||
|
||||
B) Quote vs Double-quote, ie ' versus "
|
||||
|
||||
On Windows the single quote character ' doesn't work
|
||||
like on Unix so in the examples of this FAQ the
|
||||
command containing single quotes ' will fail on Windows.
|
||||
To fix this, just replace single quotes ' by double quotes "
|
||||
|
||||
Also on Windows, in examples with \$1, replace
|
||||
any \$1 by $1 (remove the \ before $).
|
||||
|
||||
=======================================================================
|
||||
Q. How to install imapsync?
|
||||
|
||||
R. Read the INSTALL files in the tarball. also available at
|
||||
https://imapsync.lamiral.info/#doc
|
||||
https://imapsync.lamiral.info/INSTALL.d/
|
||||
|
||||
=======================================================================
|
||||
Q. How to use imapsync?
|
||||
|
||||
R. Read the TUTORIAL_Unix.txt file, maybe the README and, if you
|
||||
encounter problems, the FAQ.d/* files in the tarball.
|
||||
All are also available and updated at:
|
||||
https://imapsync.lamiral.info/#doc
|
||||
|
||||
=======================================================================
|
||||
Q. Can you give some configuration examples?
|
||||
|
||||
R1. Basic usage is described there:
|
||||
https://imapsync.lamiral.info/#DOC_BASIC
|
||||
|
||||
It is:
|
||||
|
||||
imapsync --host1 test1.lamiral.info --user1 test1 --password1 secret1 \
|
||||
--host2 test2.lamiral.info --user2 test2 --password2 secret2
|
||||
|
||||
R2. Some FAQ files contains many examples for several scenarios
|
||||
https://imapsync.lamiral.info/#doc
|
||||
(Gmail, Office365, Exchange, Darwin, etc.)
|
||||
|
||||
=======================================================================
|
||||
Q. How can I have commercial support?
|
||||
|
||||
R. Buy support from imapsync author: Gilles LAMIRAL
|
||||
https://imapsync.lamiral.info/#buy_all
|
||||
|
||||
=======================================================================
|
||||
Q. How can I have gratis support?
|
||||
|
||||
R. Write to the imapsync author: Gilles LAMIRAL
|
||||
https://imapsync.lamiral.info/#AUTHOR
|
||||
|
||||
I help all users as long as I have time to help them all,
|
||||
users who bought the support get my help first.
|
||||
|
||||
=======================================================================
|
||||
Q. Where I can find old imapsync releases?
|
||||
|
||||
R. https://imapsync.lamiral.info/dist/old_releases/
|
||||
|
||||
=======================================================================
|
||||
Q. Where I can find free open and gratis imapsync releases?
|
||||
|
||||
R. https://imapsync.lamiral.info/dist/
|
||||
Github has a copy at
|
||||
https://github.com/imapsync/imapsync
|
||||
|
||||
Q. Is is legal to find imapsync gratis (or not) elsewhere?
|
||||
|
||||
R. Yes, the license permits it
|
||||
https://imapsync.lamiral.info/NOLIMIT
|
||||
|
||||
=======================================================================
|
||||
Q. How "Facts and figures" are known
|
||||
https://imapsync.lamiral.info/#NUMBERS
|
||||
|
||||
R. To know wether a newer imapsync exists or not, imapsync does a http
|
||||
GET to http://imapsync.lamiral.info/VERSION
|
||||
Via the User-agent parameter it also send:
|
||||
|
||||
* imapsync release
|
||||
* Perl version
|
||||
* Mail::IMAPClient version
|
||||
* Operating System
|
||||
|
||||
You can remove this behavior by adding option --noreleasecheck on the
|
||||
command line (or by setting $releasecheck = 0 in the source code)
|
||||
or by using the github release.
|
||||
|
||||
=======================================================================
|
||||
Q. I use --useuid which uses a cache in /tmp or --tmpdir, the hostnames
|
||||
host1 or host2 has changed but mailboxes are the same. Will imapsync
|
||||
generate duplicate messages on next runs?
|
||||
|
||||
R. Yes
|
||||
|
||||
Q. How can I fix this?
|
||||
|
||||
R. The cache path reflects exactly hostnames or ip addresses given via
|
||||
--host1 and --host2 values. So just change the directory names
|
||||
of host1 or host2. Use --dry to see if next runs will generate
|
||||
duplicates.
|
||||
By default on Unix the cache is like
|
||||
|
||||
/tmp/imapsync_cache/host1/user1/host2/user2/...
|
||||
|
||||
=======================================================================
|
||||
Q. How can I speed up transfers?
|
||||
|
||||
R. By using --useuid imapsync avoid getting messages headers and build
|
||||
a cache. On Unix a good thing is to add also --tmpdir /var/tmp
|
||||
to keep the cache since /tmp is often cleared on reboot.
|
||||
|
||||
imapsync ... --useuid
|
||||
|
||||
On Unix:
|
||||
|
||||
imapsync ... --useuid --tmpdir /var/tmp/
|
||||
|
||||
R. Add also --nofoldersizes since the default behavior is to compute
|
||||
folder sizes. Folder sizes are useless for the transfer, just
|
||||
useful to see what has to be done on each folder and guess when
|
||||
the transfer will end (ETA).
|
||||
|
||||
R. Add also --noexpungeaftereach if you use --delete.
|
||||
But be warn that an interrupted transfer can loose messages
|
||||
on host2 in a second run if you use a (silly) combination like
|
||||
|
||||
imapsync ... --delete --noexpunge --noexpungeaftereach --expunge2
|
||||
|
||||
R. Add also --nocheckmessageexists
|
||||
--nocheckmessageexists is on by default since release 1.520.
|
||||
Since transfer can be long on a huge mailbox imapsync checks
|
||||
a message exist before copying it, but it takes time and
|
||||
cpu on the host1 server.
|
||||
|
||||
Notes about --useuid
|
||||
|
||||
Case where building the cache first is necessary (to avoid multiples transfers)
|
||||
|
||||
If you run again imapsync with --useuid on a transfer already done without
|
||||
--useuid then, to avoid messages be copied again, first run imapsync
|
||||
with --usecache but without --useuid, example scenario:
|
||||
|
||||
A] Running with the default options, I began without --useuid
|
||||
|
||||
1) First run with default options
|
||||
|
||||
imapsync ...
|
||||
|
||||
Too slow, I want to speed up!
|
||||
|
||||
2) Build the cache
|
||||
|
||||
imapsync ... --usecache
|
||||
|
||||
3) Speed up now
|
||||
|
||||
imapsync ... --useuid
|
||||
|
||||
B] I began with --useuid from the first time
|
||||
|
||||
1) First run and next runs with --useuid
|
||||
|
||||
imapsync ... --useuid
|
||||
|
||||
|
||||
Inodes number issue.
|
||||
|
||||
The cache is simple, it uses the file-system natively,
|
||||
it's just an empty file per message transfered.
|
||||
When mailboxes are huge the cache can exhaust the number of inodes
|
||||
allowed in the filesystem, that's a limitation like limitation
|
||||
size but it's less often encountered.
|
||||
|
||||
On Unix, to predict whether your tmpdir filesystem used by imapsync
|
||||
will support the whole cache, just run the command "df -i /var/tmp",
|
||||
if /var/tmp is the --tmpdir argument.
|
||||
|
||||
On windows, search and drop me a note about how to count the number
|
||||
of files allowed in the filesystem.
|
||||
It seems FAT32 supports 268 435 445 clusters.
|
||||
|
||||
Choosing the number of inodes allowed by a filesystem can be done
|
||||
at the creation of it with "mkfs -N number-of-inodes ..."
|
||||
|
||||
imapsync can predict how many messages have to be synced with the
|
||||
option --justfoldersizes (no transfer will be done)
|
||||
|
||||
imapsync ... --justfoldersizes
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. I see warning messages like the following:
|
||||
"Host1 Sent/15 size 1428 ignored (no header so we ignore this message.
|
||||
To solve this: use --addheader)".
|
||||
What can I do to transfer those messages?
|
||||
|
||||
|
||||
R1. Like suggested inline, use --addheader option.
|
||||
Option --addheader will add an header line like
|
||||
Message-Id: <15@imapsync>
|
||||
where 15 is the message UID number on host1.
|
||||
Then imapsync will transfer the changed message on host2.
|
||||
Duplicates won't happen on next runs.
|
||||
|
||||
imapsync ... --addheader
|
||||
|
||||
R2. Other solution.
|
||||
Use --useuid then imapsync will avoid dealing with headers.
|
||||
|
||||
imapsync ... --useuid
|
||||
|
||||
=======================================================================
|
||||
Q. How can I try imapsync with latest Mail::IMAPClient 3.xx perl module?
|
||||
|
||||
Three solutions at least.
|
||||
|
||||
R1 - Look at the script named "i3" in the tarball, it can be used to
|
||||
run imapsync with the included Mail-IMAPClient-3.39/ wherever you
|
||||
unpacked the imapsync tarball
|
||||
|
||||
R2 Run:
|
||||
|
||||
cpanm Mail::IMAPClient # this uses cpanminus
|
||||
|
||||
or
|
||||
|
||||
cpan -i Mail::IMAPClient
|
||||
|
||||
or
|
||||
|
||||
perl -MCPAN -e "install Mail::IMAPClient"
|
||||
|
||||
|
||||
R3 If you want to install the Perl module locally in a directory
|
||||
|
||||
- Download latest Mail::IMAPClient 3.xx at
|
||||
http://search.cpan.org/dist/Mail-IMAPClient/
|
||||
|
||||
- untar it anywhere:
|
||||
tar xzvf Mail-IMAPClient-3.xx.tar.gz
|
||||
|
||||
- Get any imapsync (latest is better).
|
||||
|
||||
- run imapsync with perl and -I option tailing to use the perl
|
||||
module Mail-IMAPClient-3.xx. Example:
|
||||
|
||||
perl -I./Mail-IMAPClient-3.39/lib ./imapsync ...
|
||||
|
||||
or if imapsync is in directory /path/
|
||||
perl -I./Mail-IMAPClient-3.39/lib /path/imapsync ...
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. How can I use imapsync with Mail::IMAPClient 2.2.9 perl module?
|
||||
|
||||
R. Mail::IMAPClient 2.2.9 is no longer supported.
|
||||
|
||||
=======================================================================
|
||||
Q. How to verify imapsync.exe I got is the right file bit per bit?
|
||||
|
||||
R. Use md5sum to check integrity of the file.
|
||||
Get md5sum.exe at http://etree.org/md5com.html
|
||||
|
||||
md5sum imapsync.exe
|
||||
|
||||
Then compare the checksum with the one given by the author.
|
||||
|
||||
=======================================================================
|
||||
Q. Can I use imapsync to migrate emails from pop3 server to imap server?
|
||||
|
||||
R1. No, but you can migrate emails from a pop3 server to an imap server
|
||||
with the command line tool pop2imap:
|
||||
http://www.linux-france.org/prj/pop2imap/
|
||||
|
||||
R2. Yes, sometimes, because many pop3 servers runs in parallel
|
||||
with an imap server on exactly the same mailboxes. They serve
|
||||
the same INBOX (imap serves INBOX and several other folders,
|
||||
pop3 serves only INBOX).
|
||||
So have a try with imapsync on the same host1.
|
||||
|
||||
=======================================================================
|
||||
Q. Folders are not created on host2. What happens?
|
||||
|
||||
R. Do you use IMAP or POP3 with your client software?
|
||||
It looks like you use POP3 instead of IMAP, POP3 sees only INBOX.
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. I am interested in creating a local clone of the IMAP on a LAN
|
||||
server for faster synchronizations, email will always be delivered
|
||||
to the remote server and so the synchronization will be one way - from
|
||||
remote to local. How suited is imapsync for continuous one-way
|
||||
synchronization of mailboxes? Is there a better solution?
|
||||
|
||||
R. If messages are delivered remotely and you play locally with the
|
||||
copy, in order to have fast access, then the synchronization can't
|
||||
be one way. You may change flags, you may move messages in
|
||||
different folders etc. The issue described is clearly
|
||||
two-ways sync.
|
||||
|
||||
A better tool with this scenario is offlineimap,
|
||||
designed for this issue, and faster than imapsync.
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. I need to log every output on a file named log.txt
|
||||
|
||||
R1. imapsync logs on a file by default, its name is given at the
|
||||
beginning and the end of each run. This name is unique since
|
||||
it is compound of the current date and time and user2 value.
|
||||
|
||||
R2. To change this default name, use --logfile log.txt
|
||||
|
||||
imapsync ... --logfile log.txt
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. Quantifier in {,} bigger than 32766 in regex; marked by <-- HERE in
|
||||
m/(.{ <-- HERE 1,49947})(?:,|$)/ at Mail/IMAPClient.pm line 2121.
|
||||
|
||||
R. Do not use a bigger value than 3276 with --split1 or --split2
|
||||
|
||||
=======================================================================
|
||||
Q. Couldn't create [INBOX.Ops/foo/bar]: NO Invalid mailbox name:
|
||||
INBOX.Ops/foo/bar
|
||||
|
||||
Let begin by an explanation.
|
||||
|
||||
Example:
|
||||
sep1 = /
|
||||
sep2 = .
|
||||
|
||||
imapsync reverts each separator automatically.
|
||||
|
||||
a) All / character coming from host1 are converted to . (convert the separator)
|
||||
b) All . character coming from host1 are converted to / (to avoid
|
||||
intermediate unwanted folder creation).
|
||||
|
||||
So
|
||||
INBOX/Ops.foo.bar (Ops.foo.bar is just one folder name) will be translated to
|
||||
INBOX.Ops/foo/bar
|
||||
|
||||
Sometimes the sep1 character is not valid on host2 (character "/" usually)
|
||||
|
||||
R. Try :
|
||||
|
||||
--regextrans2 "s,/,X,g"
|
||||
|
||||
It'll convert / character to X
|
||||
Choose X as you wish: _ or SEP or
|
||||
any string (including the empty string).
|
||||
|
||||
This issue is automatically fixed by default since imapsync
|
||||
release 1.513, use --nofixslash2 to suppress the fix.
|
||||
|
||||
=======================================================================
|
||||
Q. Is it possible to sync also the UIDL of the POP3 server?
|
||||
|
||||
R. imapsync doesn't talk POP3 but I think you mean UID in IMAP.
|
||||
See next question.
|
||||
|
||||
=======================================================================
|
||||
Q. Is it possible to sync also the UIDs of the IMAP server?
|
||||
|
||||
R. UIDs in IMAP are chosen and created by the server, not by the
|
||||
client software. imapsync is a client software. So UIDs cannot
|
||||
be synced by any imap method.
|
||||
|
||||
UIDs may be synced via a rsync command between the imap servers but
|
||||
it implies they are the same software, among other constraints.
|
||||
|
||||
=======================================================================
|
||||
Q. The option --subscribe does not seem to work
|
||||
|
||||
R1. Use it with --subscribed
|
||||
|
||||
R2. There is also the --subscribe_all option that subscribe
|
||||
to all folders on host2.
|
||||
|
||||
=======================================================================
|
||||
Q. With huge account (many messages) when it comes to reading the
|
||||
destination server it comes out this error:
|
||||
"To Folder [INBOX.foobar] Not connected"
|
||||
What can I do?
|
||||
|
||||
R. May be spending too much time on the source server, the connection
|
||||
timed out on the destination server.
|
||||
Try options --nofoldersizes
|
||||
|
||||
======================================================================
|
||||
Q. Can Imapsync filter Spam during the sync?
|
||||
|
||||
R. No, imapsync doesn't detect Spam by itself. But I've seen blogs and
|
||||
Spamassassin documentation explaining solutions to apply Spamassassin
|
||||
to a imap mailbox. So you can apply one of these solutions on the host1
|
||||
source mailbox before the imapsync run or on the destination host2
|
||||
mailbox after the imapsync transfer.
|
||||
|
||||
http://www.stearns.org/doc/spamassassin-setup.current.html#isbg
|
||||
http://euer.krebsco.de/using-spamassassin-on-a-remote-imap-host.html
|
||||
https://github.com/ook/isbg
|
||||
|
||||
Imapsync can delegate this job during its IMAP syncs via the
|
||||
--pipemess option but the underlying spam tool has to be written.
|
||||
|
||||
======================================================================
|
||||
Q. How to migrate from uw-imap with an admin/authuser account?
|
||||
|
||||
R. Use the following syntax:
|
||||
|
||||
imapsync ... --user1="loginuser*admin_user" --password1 "admin_user_password"
|
||||
|
||||
|
||||
======================================================================
|
||||
Q. How to migrate from cyrus with an admin account?
|
||||
|
||||
R. Use:
|
||||
|
||||
imapsync ... \
|
||||
--authuser1 admin_user ----password1 admin_user_password \
|
||||
--user1 foo_user --ssl1
|
||||
|
||||
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 or --tls1 since PLAIN auth is only
|
||||
supported with ssl encryption most of the time. But it can
|
||||
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
|
||||
being migrated from, "joe" here.
|
||||
|
||||
|
||||
Here is an example:
|
||||
imapsync \
|
||||
--host1 server1 \
|
||||
--user1 joe \
|
||||
--authuser1 AdminAccount \
|
||||
--password1 AdminAccountPassword \
|
||||
--ssl1 \
|
||||
--host2 server2 \
|
||||
--user2 joe \
|
||||
--password2 joespassonserver2 \
|
||||
--exclude "^user\."
|
||||
|
||||
======================================================================
|
||||
Q: How to migrate from Sun Java Enterprise System / Sun One / iPlanet /
|
||||
Netscape servers with an admin account?
|
||||
|
||||
R: Those imap servers don't allow the typical use of --authuser1 to use an
|
||||
administrative account. They expect the use of an IMAP command called
|
||||
proxyauth that is issued after login in as an administrative account.
|
||||
|
||||
For example, consider the administrative account 'administrator' and your
|
||||
real user 'real_user'. The IMAP sequence would be:
|
||||
|
||||
OK [CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ NAMESPACE UIDPLUS
|
||||
CHILDREN BINARY UNSELECT LANGUAGE STARTTLS XSENDER X-NETSCAPE XSERVERINFO
|
||||
AUTH=PLAIN] imap.server IMAP4 service (Sun Java(tm) System Messaging
|
||||
Server ...))
|
||||
1 LOGIN administrator password
|
||||
1 OK User logged in
|
||||
2 PROXYAUTH real_user
|
||||
2 OK Completed
|
||||
|
||||
In imapsync, you can achieve this by using the following options:
|
||||
|
||||
--host1 source.imap.server \
|
||||
--user1 real_user \
|
||||
--authuser1 administrator \
|
||||
--proxyauth1 \
|
||||
--passfile admin.txt
|
||||
|
||||
======================================================================
|
||||
Q. Is there a way to delete the destination folder when the source
|
||||
folder is no longer there?
|
||||
|
||||
R. Yes, use --delete2folders
|
||||
|
||||
--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 <regex>: Deleted only folders matching regex.
|
||||
Example: --delete2foldersonly "/^Junk$|^INBOX.Junk$/"
|
||||
--delete2foldersbutnot <regex>: Do not delete folders matching regex.
|
||||
Example: --delete2foldersbutnot "/Tasks$|Contacts$|Foo$/"
|
||||
|
||||
=======================================================================
|
||||
Q. I would love to have a function to inject lines in the header.
|
||||
Things like "X-migrated-from-foo: 20100617"
|
||||
|
||||
R. You can do that with:
|
||||
|
||||
imapsync ... --regexmess 's/\A/X-migrated-from-foo: 20100617\n/'
|
||||
|
||||
It will insert a first header line containing "X-migrated-from-foo: 20100617"
|
||||
|
||||
=======================================================================
|
||||
Q. I want to play with headers line and --regexmess but I want to leave
|
||||
the body as is.
|
||||
|
||||
R. The header/body separation is a blank line so an example:
|
||||
--regexmess 's{\A(.*?(?! ^$))^Date:(.*?)$}{$1Date:$2\nX-Date:$2}gxms'
|
||||
|
||||
Will replace the next three lines
|
||||
|
||||
Message-ID: <499EF800.4030002@blabla.fr>
|
||||
Date: Fri, 20 Feb 2009 19:35:44 +0100
|
||||
From: Gilles LAMIRAL <lamiral@linux-france.org>
|
||||
|
||||
by the next four lines
|
||||
|
||||
Message-ID: <499EF800.4030002@blabla.fr>
|
||||
Date: Fri, 20 Feb 2009 19:35:44 +0100
|
||||
X-Date: Fri, 20 Feb 2009 19:35:44 +0100
|
||||
From: Gilles LAMIRAL <lamiral@linux-france.org>
|
||||
|
||||
|
||||
This example just add an header line "X-Date:" based on "Date:" line.
|
||||
|
||||
=======================================================================
|
||||
Q. My imap server does not accept a message and warns
|
||||
"Invalid header". What is the problem?
|
||||
|
||||
R. You fall in the classical mbox versus Maildir/ format
|
||||
problem. May be you use a misconfigured procmail rule.
|
||||
|
||||
A header beginning like the following one is in the mbox
|
||||
format, header line 1 has no colon behind "From", header
|
||||
lines 2 through N do have a colon :
|
||||
|
||||
From foo@yoyo.org Sat Jun 22 01:10:21 2002
|
||||
Return-Path: <foo@yoyo.org>
|
||||
Received: ...
|
||||
|
||||
Any Maildir/ configured imap server may refuse this message since its
|
||||
header is invalid. The first "From " line is not valid. It lacks a
|
||||
colon character ":". To solve this issue you have several solutions
|
||||
|
||||
a) Remove manually this first "From " line for each message before
|
||||
using imapsync.
|
||||
|
||||
b) Replace manually the whitespace by a colon in string "From " but you
|
||||
might end with two "From:" lines (just have a look at the other
|
||||
header lines of the message)
|
||||
|
||||
c) Run imapsync with the following option (this replaces "From "by "From:"):
|
||||
--regexmess 's/\AFrom /From: /'
|
||||
|
||||
or may be better (no other "From:" collision):
|
||||
|
||||
d) Run imapsync with the following option (this replaces "From "by "X-om:"):
|
||||
--regexmess 's/\AFrom /X-From: /'
|
||||
|
||||
e) Run imapsync with the following option (this removes the whole "From " line):
|
||||
--regexmess 's{\AFrom\ [^\n]*(\n)?}{}gxms'
|
||||
|
||||
Solution e) is solution a) made by imapsync itself.
|
||||
Solutions c) and d) keep "From " lines information
|
||||
(normally it's useless to keep them)
|
||||
|
||||
Best solutions are e) or d).
|
||||
|
||||
=======================================================================
|
||||
Q. The contact folder isn't well copied.
|
||||
How to copy the contact folder?
|
||||
|
||||
R. Forget the destination server (choose the same)
|
||||
Change the script around line 1426
|
||||
# ITSD
|
||||
$new_id = $from->copy($t_fold,$f_msg);
|
||||
#$new_id = $to->append_string($t_fold,$string, $flags_f, $d);
|
||||
|
||||
and tried a copy of the mail instead an append_string. Because we are
|
||||
using the same server, we can use $from->copy Therefore we seem to not
|
||||
download and upload the message and therefore we do not have any
|
||||
format issues. And now it works fine. (Thanks to Hansjoerg.Maurer)
|
||||
|
||||
|
||||
======================================================================
|
||||
Q: How can I write an .rpm with imapsync
|
||||
|
||||
R. You'll find an RPM imapsync.spec file in the directory learn/rpm/
|
||||
It has been downloaded from
|
||||
https://svn.fysik.dtu.dk/projects/rpmbuild/trunk/SPECS/imapsync.spec
|
||||
It has been tested with imapsync 1.434 (May 2011) on CentOS5
|
||||
and RedHat RHEL5 Linux. (Thanks to Ole Holm Nielsen).
|
||||
This imapsync.spec is coming from Neil Brown work in 2007.
|
||||
|
||||
=======================================================================
|
||||
Q. Where I can read up on the various IMAP RFCs?
|
||||
|
||||
R. Here:
|
||||
|
||||
RFC 3501 - INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1
|
||||
http://www.faqs.org/rfcs/rfc3501.html
|
||||
|
||||
RFC2683 - IMAP4 Implementation Recommendations
|
||||
http://www.faqs.org/rfcs/rfc2683.html
|
||||
|
||||
RFC 2595 - Using TLS with IMAP, POP3 and ACAP
|
||||
http://www.faqs.org/rfcs/rfc2595.html
|
||||
|
||||
RFC 2822 - Internet Message Format
|
||||
http://www.faqs.org/rfcs/rfc2822.html
|
||||
|
||||
RFC 2342 - IMAP4 Namespace
|
||||
http://www.faqs.org/rfcs/rfc2342.html
|
||||
|
||||
RFC2180 - IMAP4 Multi-Accessed Mailbox Practice
|
||||
http://www.faqs.org/rfcs/rfc2180.html
|
||||
|
||||
RFC 4549 - Synchronization Operations for Disconnected IMAP4 Clients
|
||||
http://www.faqs.org/rfcs/rfc4549.html
|
||||
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
@ -1,11 +1,11 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Gmail.txt,v 1.25 2016/07/22 00:18:35 gilles Exp gilles $
|
||||
$Id: FAQ.Gmail.txt,v 1.33 2017/09/05 15:11:20 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
=====================================
|
||||
Imapsync tips for Gmail accounts.
|
||||
=====================================
|
||||
=======================================================================
|
||||
Imapsync tips for Gmail accounts.
|
||||
=======================================================================
|
||||
|
||||
Questions anwswered in this FAQ are:
|
||||
|
||||
@ -19,17 +19,22 @@ Q. How to synchronize from XXX to Gmail?
|
||||
|
||||
Q. How to synchronize from Gmail to XXX?
|
||||
|
||||
Q. Can I use the Extension of the SEARCH command: X-GM-RAW described at
|
||||
https://support.google.com/mail/answer/7190?hl=en
|
||||
|
||||
Q. How to avoid the [IMAP] prefix on Gmail side?
|
||||
|
||||
Q. I can't authenticate with Gmail via IMAP
|
||||
and Gmail says "Please log in via your web browser"
|
||||
|
||||
Q. Can not open imap connection on [imap.gmail.com]
|
||||
Unable to connect to imap.gmail.com
|
||||
|
||||
Q. Can I safely use --useuid for Gmail transfers?
|
||||
|
||||
Q. Gmail does not really delete messages in folder [Gmail]/All Mail
|
||||
What happens? What can I do?
|
||||
|
||||
Q. Can I use the Extension of the SEARCH command: X-GM-RAW described at
|
||||
https://support.google.com/mail/answer/7190?hl=en
|
||||
https://developers.google.com/gmail/imap_extensions#extension_of_the_search_command_x-gm-raw
|
||||
|
||||
Q. How to avoid the [IMAP] prefix on Gmail side?
|
||||
|
||||
Q. Does imapsync have the capability to do 2 stage authentication?
|
||||
|
||||
@ -55,13 +60,25 @@ it has to be allowed in the Gmail configuration part:
|
||||
Q. How many days does it take to transfer X GB?
|
||||
|
||||
R. Basically it takes X days to transfer X GB per account.
|
||||
Gmail has usage limits per day
|
||||
Gmail has usage limits per day and use throttlers when
|
||||
they are overtaken
|
||||
http://support.google.com/a/bin/answer.py?hl=en&answer=1071518
|
||||
From the previous link,
|
||||
it's 2X days to upload X GB to Gmail
|
||||
it's X/2 days to download X BG from Gmail
|
||||
but that's the theory.
|
||||
From the previous link:
|
||||
|
||||
* it's 2X days to upload X GB to Gmail, it's why I suggest to add
|
||||
--maxbytespersecond 10000
|
||||
for uploading messages to Gmail
|
||||
* it's X/2 days to download X BG from Gmail, it's why I suggest to add
|
||||
--maxbytespersecond 20000
|
||||
for downloading messages from Gmail
|
||||
|
||||
That's theoretical values that always work in practice. Try
|
||||
upper values and see if they still work.
|
||||
|
||||
How Gmail says limits are reached?
|
||||
This is either a disconnection with
|
||||
"BYE Session expired, please login again"
|
||||
or a very small rate, less than 1 Kib/s
|
||||
=======================================================================
|
||||
Q. How to synchronize from Gmail to Gmail?
|
||||
|
||||
@ -275,6 +292,8 @@ label CanWait and only it.
|
||||
--skipcrossduplicates, will only put in "[Gmail]/All Mail"
|
||||
the messages that are not labeled at all.
|
||||
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. I can't authenticate with Gmail via IMAP
|
||||
and Gmail says "Please log in via your web browser"
|
||||
@ -310,10 +329,16 @@ R0. It looks like this issue is related to ipv6. Both ipv4 and ipv6
|
||||
protocols should work with gmail and imapsync, I test that regularly,
|
||||
imapsync works fine for both ipv4 and ipv6.
|
||||
If you disable ipv6 then disable also ipv6 resolution!
|
||||
Or at least, make ipv4 answers be taken before ipv6 since the default
|
||||
names resolution order is to present ipv6 name resolutions first.
|
||||
|
||||
R1. A first simple solution is to use directly gmail ipv4 ip address:
|
||||
The default names resolution order is to present ipv6 name resolutions
|
||||
first. If you know how to make ipv4 answers be taken before ipv6
|
||||
then tell me.
|
||||
|
||||
R1. First solution, run imapsync with the option --inet4:
|
||||
|
||||
imapsync ... --inet4
|
||||
|
||||
R2. A second solution is to use directly gmail ipv4 ip address:
|
||||
|
||||
imapsync ... --host1 64.233.184.108
|
||||
|
||||
@ -326,12 +351,23 @@ name resolution, try one of those:
|
||||
|
||||
Or go to http://ping.eu/nslookup/ to get the resolution.
|
||||
|
||||
R2. Second solution. Fix imapsync with the line:
|
||||
|
||||
use IO::Socket::SSL 'inet4' ;
|
||||
|
||||
Thanks to Chris Nolan to report, understand and fix this issue!
|
||||
|
||||
=======================================================================
|
||||
Q. Can I safely use --useuid for Gmail transfers?
|
||||
|
||||
R. Yes, but I suggest to not use --useuid for Gmail transfers.
|
||||
|
||||
Using UIDs is useless with Gmail in the case of global duplicates
|
||||
(duplicates across different folders). Gmail always accept a global
|
||||
duplicate message as a new message, giving imapsync a new UID for this
|
||||
message, and throw it away because it already has it. Gmail
|
||||
will do this at each run so imapsync will always try to copy the
|
||||
message, and Gmail will always accept and throw away the new copy. It
|
||||
ends up with no duplicates on Gmail but a waste of bandwith and time,
|
||||
which is the opposite goal of --usecache implied by --useuid.
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. Gmail does not really delete messages in folder [Gmail]/All Mail
|
||||
What happens? What can I do?
|
||||
@ -407,6 +443,8 @@ Q. How to migrate email from gmail to google apps?
|
||||
R. Take a look at:
|
||||
http://www.linux-france.org/prj/imapsync_list/msg00639.html
|
||||
|
||||
http://biasecurities.com/blog/2009/migrate-email-from-gmail-to-google-apps/
|
||||
http://biasecurities.com/2009/02/migrate-email-from-gmail-to-google-apps/
|
||||
http://www.thamtech.com/blog/2008/03/29/gmail-to-google-apps-email-migration/
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
@ -1,11 +1,11 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.ISP.txt,v 1.4 2016/01/28 14:34:15 gilles Exp gilles $
|
||||
$Id: FAQ.ISP.txt,v 1.8 2017/06/21 18:09:00 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
=========================================================
|
||||
Imapsync tips for ISP. Specific issues and solutions.
|
||||
=========================================================
|
||||
=======================================================================
|
||||
Imapsync tips for ISP. Specific issues and solutions.
|
||||
=======================================================================
|
||||
|
||||
* IMAPSync - usage scenario with ISP - by Flávio Zarur Lucarelli.
|
||||
|
||||
@ -18,12 +18,43 @@ Lamiral for all his help and hard work.
|
||||
First of all, remember to use --dry to test things first always and
|
||||
check the log file to see what would actually happen.
|
||||
|
||||
Initially, I used a method where I'd do an exact sync of source to
|
||||
destination, deleting messages which were in destination, but not
|
||||
source. I call this "Method 2", below. In this cenario, customer
|
||||
shouldn't be using the destination account yet. Then, after I switch MX,
|
||||
I'd do a final sync based on date. The big advantage of this is, you
|
||||
get an exact sync.
|
||||
|
||||
Easier, however, is method 1, where I sync based on message ID, this
|
||||
way, I can use the same syntax before and after MX change, with no
|
||||
worries. Only disadvantage, you might not get an exact sync, there
|
||||
might be some difference in terms of total emails in folders, due to
|
||||
duplicates, emails that had same message ID in source server.
|
||||
|
||||
* Method 1 - sync based on message ID, can use same syntax before and
|
||||
after MX change
|
||||
|
||||
imapsync --host1 imap.myisp.com --user1 user@domain.com --password1 pwd \
|
||||
--host2 imap.myisp.com --user2 user@domain.com --password2 pwd \
|
||||
--addheader
|
||||
|
||||
Note: add header adds message ID when it doesn't exist.
|
||||
|
||||
This syntax can also be used to sync different source accounts to one
|
||||
same destination account, simply execute it as many times as desired,
|
||||
switching source user (user1).
|
||||
|
||||
* Method 2 - exact sync source do destination, then sync based on date
|
||||
after MX change
|
||||
|
||||
My first goal is to have an exact sync of an account from
|
||||
current/source host to the new/destination host and be able to sync
|
||||
several times. The --useuid parameter is very important for that
|
||||
purpose. This is what I use:
|
||||
|
||||
imapsync --host1 imap.gmail.com --user1 user@domain.com --password1 pwd --ssl1 --host2 imap.myisp.com --user2 user@domain.com --password2 pwd --ssl2 --useuid --delete2 --delete2folders
|
||||
imapsync --host1 imap.gmail.com --user1 user@domain.com --password1 pwd --ssl1 \
|
||||
--host2 imap.myisp.com --user2 user@domain.com --password2 pwd --ssl2 \
|
||||
--useuid --delete2 --delete2folders
|
||||
|
||||
This makes it so imap.myisp.com (destination) is an exact copy of the
|
||||
account at imap.gmail.com (source). This is not a problem, since the
|
||||
@ -51,7 +82,9 @@ cache) and delete such emails from source server. This way, customer's
|
||||
mailbox is still intact on the source server, except new emails, which
|
||||
get synced to new server and deleted from source.
|
||||
|
||||
imapsync --host1 imap.gmail.com --user1 user@domain.com --password1 pwd --ssl2 --folder INBOX --useuid --noexpungeaftereach --skipemptyfolders --maxage 1 --delete1
|
||||
imapsync --host1 imap.gmail.com --user1 user@domain.com --password1 pwd --ssl1 \
|
||||
--host2 imap.myisp.com --user2 user@domain.com --password2 pwd --ssl2 \
|
||||
--folder INBOX --useuid --noexpungeaftereach --skipemptyfolders --maxage 1 --delete1
|
||||
|
||||
I personally prefer to keep a copy of users box intact in source, but
|
||||
if that's not an issue for you, you can remove --folder INBOX and even
|
||||
@ -70,5 +103,22 @@ lixeira (trash) and rascunhos (drafts).
|
||||
|
||||
So this was added:
|
||||
|
||||
--regextrans2 "s,\[Gmail\].,," --regextrans2 "s,E-mails enviados,Sent," --regextrans2 "s,/Lixeira,Trash," --regextrans2 "s,/Rascunhos,Drafts,"
|
||||
--regextrans2 "s,\[Gmail\].,," \
|
||||
--regextrans2 "s,E-mails enviados,Sent," \
|
||||
--regextrans2 "s,Lixeira,Trash," \
|
||||
--regextrans2 "s,Rascunhos,Drafts,"
|
||||
|
||||
*** Other cenarios
|
||||
|
||||
- Sync entire account into 1 folder of another account
|
||||
|
||||
imapsync --host1 xxx --user1 user1@domain.com --password1 secret1 --ssl1 \
|
||||
--host2 yyy --user2 user2@domain.com --password2 secret2 --ssl2 \
|
||||
--useuid --subfolder2 otheraccountfolder --delete2 --delete2foldersonly /otheraccountfolder/
|
||||
|
||||
Above is based on message UID, advantage of no dupes, however, user
|
||||
must not be using such destination folder in destination account until
|
||||
you finish syncing.
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
@ -1,20 +1,20 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Massive.txt,v 1.9 2016/03/25 19:59:45 gilles Exp gilles $
|
||||
$Id: FAQ.Massive.txt,v 1.15 2017/06/17 13:45:15 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
==============================================
|
||||
Imapsync tips for massive/bulk migrations.
|
||||
==============================================
|
||||
=======================================================================
|
||||
Imapsync tips for massive/bulk migrations.
|
||||
=======================================================================
|
||||
|
||||
Questions answered here are:
|
||||
|
||||
Q. I need to migrate hundred accounts, how can I do?
|
||||
|
||||
Q. I have to migrate 500k users using 400 TB of disk space.
|
||||
How do I proceed?
|
||||
How do I proceed? How about speed?
|
||||
|
||||
Q. How to determine what is the bottleneck in my current imapsync process?
|
||||
Q. How to determine where is the bottleneck in an imapsync process?
|
||||
|
||||
Q. Can I run more instances of imapsync in parallel on a Windows host?
|
||||
|
||||
@ -29,7 +29,7 @@ Q. I need to migrate hundred accounts, how can I do?
|
||||
|
||||
R. If you have many mailboxes to migrate think about a little
|
||||
script program. Write a file called file.txt (for example)
|
||||
containing hosts users and passwords on both sides.
|
||||
containing hosts, users and passwords on both sides.
|
||||
The separator used in this example is ";"
|
||||
|
||||
The file.txt file contains for example:
|
||||
@ -40,16 +40,23 @@ host003_1;user003_1;password003_1;host003_2;user003_2;password003_2;
|
||||
host004_1;user004_1;password004_1;host004_2;user004_2;password004_2;
|
||||
etc.
|
||||
|
||||
Most of the times, the first column (host001_1, host002_1 ...) will
|
||||
contains the same value, the value of --host1 parameter. Same
|
||||
thing for the third column (host001_2, host002_2).
|
||||
|
||||
On Unix the shell script can be:
|
||||
|
||||
#!/bin/sh
|
||||
{ while IFS=';' read h1 u1 p1 h2 u2 p2 fake
|
||||
do
|
||||
imapsync --host1 "$h1" --user1 "$u1" --password1 "$p1" \
|
||||
--host2 "$h2" --user2 "$u2" --password2 "$p2"
|
||||
--host2 "$h2" --user2 "$u2" --password2 "$p2" "$@"
|
||||
done
|
||||
} < file.txt
|
||||
|
||||
You can add extra options inside this script, just after the variable "$@".
|
||||
You can also pass extra options via the parameters of this script
|
||||
since they will go in "$@"
|
||||
|
||||
Here is a complete Unix example ready to use:
|
||||
http://imapsync.lamiral.info/examples/sync_loop_unix.sh
|
||||
@ -59,54 +66,142 @@ On Windows the batch script can be:
|
||||
|
||||
CD /D %~dp0
|
||||
SET csvfile=file.txt
|
||||
FOR /F "tokens=1,2,3,4,5,6 delims=; eol=#" %%G IN (%csvfile%) DO (
|
||||
FOR /F "tokens=1,2,3,4,5,6,7 delims=; eol=#" %%G IN (%csvfile%) DO (
|
||||
imapsync ^
|
||||
--host1 %%G --user1 %%H --password1 %%I ^
|
||||
--host2 %%J --user2 %%K --password2 %%L ...
|
||||
--host2 %%J --user2 %%K --password2 %%L %%M ...
|
||||
)
|
||||
|
||||
The final ... can be replaced by nothing or any supplementary imapsync option.
|
||||
You can add extra options inside this script, just after the variable %%M.
|
||||
You can add extra options inside the file.txt, in the last column. Add
|
||||
an extra semicolon at the end (optional)
|
||||
Example:
|
||||
host001_1;user001_1;password001_1;host001_2;user001_2;password001_2;
|
||||
host002_1;user002_1;password002_1;host002_2;user002_2;password002_2;
|
||||
becomes
|
||||
host001_1;user001_1;password001_1;host001_2;user001_2;password001_2; --automap --addheader
|
||||
host002_1;user002_1;password002_1;host002_2;user002_2;password002_2; --automap --addheader
|
||||
|
||||
Here is a complete Windows example nearly ready to use:
|
||||
With this solution, options can be added, changed or removed per account.
|
||||
Technically those options will go in %%M in the loop body
|
||||
|
||||
Here is a complete Windows example ready to use:
|
||||
http://imapsync.lamiral.info/examples/sync_loop_windows.bat
|
||||
|
||||
Another solution to add extra arguments is to write another .bat that
|
||||
calls sync_loop_windows.bat with the extra arguments, like this
|
||||
for example:
|
||||
|
||||
sync_loop_windows.bat --automap --addheader --maxmessagespersecond 4
|
||||
|
||||
Technically those options will go in %arguments% in the loop body
|
||||
of sync_loop_windows.bat
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. I have to migrate 500k users using 400 TB of disk space.
|
||||
How do I proceed?
|
||||
How do I proceed? How about speed?
|
||||
|
||||
R. Solution to this issue is two words: parallelism and measurements.
|
||||
Since all 500k mailboxes are independent against each other,
|
||||
they can be processed independently.
|
||||
|
||||
500k on 400TB is 800 MB per account on average.
|
||||
Since all mailboxes are functionnaly independent, they can be processed
|
||||
independently, here comes parallelism, lunching several imapsync
|
||||
processes in parallel.
|
||||
|
||||
On any process involving several mechanisms there is always a
|
||||
bottleneck among all elements taking part on the process. No one knows
|
||||
in advance what is the first bottleneck. The first bottleneck has to
|
||||
be determined, by measurements, not by guesses. Once this first
|
||||
Meanwhile, mailboxes usually belong to the same server and syncs
|
||||
share the same imapsync host via the same bandwidth, here come
|
||||
some limitations and bottlenecks.
|
||||
|
||||
How many syncs can we run in parallel? here comes measurements.
|
||||
|
||||
1) Measure the total transfer rate by adding each one printed in each run.
|
||||
Since adding this way is not so easy, just look at the overall
|
||||
network rate of the imapsync host.
|
||||
|
||||
On Linux, nload is good candidate to measure this overall
|
||||
network rate, every 6 seconds, on eth0 interface, values in Kbytes:
|
||||
|
||||
nload -t 6000 eth0 -u K
|
||||
|
||||
Another excellent network tool is dstat:
|
||||
|
||||
dstat -n -N eth0 6
|
||||
|
||||
On Windows, get the overall network rate with the classical
|
||||
task manager (Ctrl-Alt-Sup), there is a network tab in it.
|
||||
Don't hesitate to send me free good tools to measure the
|
||||
overall transfer rate (the best would be one to sum up only
|
||||
imap traffic but that's not mandatory at all).
|
||||
|
||||
2) Launch new parallel runs, one by one, as long as the total
|
||||
transfer rate increase.
|
||||
|
||||
3) When the total transfer rate starts to diminish, stop new launches.
|
||||
Note N as the number of parallel runs you got until then.
|
||||
|
||||
4) Only keep N-2 parallel runs for the future.
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. How to determine where is the bottleneck in an imapsync process?
|
||||
|
||||
R1. Divide and conquer.
|
||||
|
||||
In order to detect whether host1/link1 is the bottleneck or
|
||||
host2/link2, we have several tests to explore:
|
||||
|
||||
1) run a sync from host1 to host1, with a host1 test account as destination.
|
||||
This way, only host1+link1 are tested, host2 is not directly concerned.
|
||||
If performances increase a lot then host2/link2 is the bottleneck.
|
||||
|
||||
2) run a sync from host2 to host2, with a host2 test account as destination.
|
||||
This way, only host2+link2 are tested, host1 is not concerned.
|
||||
If performances increase a lot then host1/link1 is the bottleneck.
|
||||
|
||||
If performances increase on both tests 1) and 2), I have no clue to explain that.
|
||||
Same thing if they both decrease!
|
||||
|
||||
R2. Isolating and overcoming bottlenecks
|
||||
|
||||
On any process involving several mechanisms, among all elements taking
|
||||
part on the process there is always a bottleneck. No one knows in
|
||||
advance what is the first bottleneck. The first bottleneck has to be
|
||||
determined, by measurements, not by guesses. Once this first
|
||||
bottleneck is known and overcome then the next bottleneck has to be
|
||||
determined and overcome too, if needed. Repeat the process of looking
|
||||
for the next bottleneck and its resolution until you estimate the
|
||||
for the next bottleneck and its elimination until you estimate the
|
||||
transfer rates, money costs and final dates are good enough to proceed
|
||||
the whole 500k/400TB migration.
|
||||
the whole huge migration.
|
||||
|
||||
Possible bottlenecks:
|
||||
|
||||
- IMAP servers have artificial limits. For example Gmail and Office365
|
||||
have throttle limits.
|
||||
- Throttles.
|
||||
IMAP servers have artificial limits.
|
||||
For example Gmail, Office365, Exchange have throttle limits.
|
||||
|
||||
- Bandwidth, on any side, especially on small Internet connexions. But
|
||||
usually bandwidth is not a bottleneck.
|
||||
- Bandwidth.
|
||||
Usually available bandwidth is not a bottleneck.
|
||||
Meanwhile, it can be a bottleneck on small Internet connexions.
|
||||
Imapsync downloads messages from host1 and upload messages to host2,
|
||||
consider this in case the connexion are asymetric.
|
||||
|
||||
- I/O on disks.
|
||||
I/O are a classical bottleneck, almost always forgotten.
|
||||
Unlike CPU and RAM, Input/Output performances don't improve
|
||||
very much as time goes on so it's often a bottleneck.
|
||||
|
||||
- Memory, on any side. Monitor your system doesn't swap on disk.
|
||||
- RAM memory.
|
||||
On all sides, monitor that your systems don't swap on disk,
|
||||
because swapping memory on disks decreases performance by
|
||||
a factor of 20, at least.
|
||||
|
||||
- CPU, on any side. When measuring that CPU is always 100% during a
|
||||
transfer then it's useless to add imapsync processus on that host.
|
||||
|
||||
- I/O on disks. A classical one always forgotten. Unlike CPU and RAM
|
||||
Input/Output performances don't improve very much as time goes on.
|
||||
- CPU.
|
||||
100% CPU during a whole transfer means the system is busy.
|
||||
Usually CPU is not a problem with imapsync but it can be a problem
|
||||
with one of the imap servers.
|
||||
Most often CPU is not the real bottleneck, I/O are.
|
||||
|
||||
Other possible bottlenecks:
|
||||
- Number of hosts available to run imapsync processes.
|
||||
- Imapsync itself.
|
||||
- Errors management.
|
||||
@ -116,25 +211,6 @@ Possible bottlenecks:
|
||||
- Bad luck.
|
||||
- ...
|
||||
|
||||
=======================================================================
|
||||
Q. How to determine what is the bottleneck in my current imapsync process?
|
||||
|
||||
R. Divide and conquer.
|
||||
|
||||
In order to detect whether host1/link1 is the bottleneck or
|
||||
host2/link2, we have several tests to explore:
|
||||
|
||||
1) run a sync from host1 to host1, with a host1 test account as destination.
|
||||
This way, only host1+link1 are tested. host2 is not concerned.
|
||||
If performances increase a lot then host2/link2 is the bottleneck.
|
||||
|
||||
2) run a sync from host2 to host2, with a host2 test account as destination.
|
||||
This way, only host2+link2 are tested. host1 is not concerned.
|
||||
If performances increase a lot then host1/link1 is the bottleneck.
|
||||
|
||||
If performances increase on both tests 1) and 2), I have no clue to explain that.
|
||||
Same thing if they both decrease!
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. Can I run more instances of imapsync in parallel on a Windows host?
|
||||
@ -181,4 +257,5 @@ This file is removed at the end of a normal run.
|
||||
You can safely ignore the warning if you don't use imapsync.pid file
|
||||
to manage imapsync processes.
|
||||
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
@ -1,11 +1,11 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Memory.txt,v 1.3 2016/05/09 13:01:22 gilles Exp gilles $
|
||||
$Id: FAQ.Memory.txt,v 1.4 2017/01/06 14:11:13 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
============================================
|
||||
Imapsync tips about memory issues.
|
||||
============================================
|
||||
=======================================================================
|
||||
Imapsync tips about memory issues.
|
||||
=======================================================================
|
||||
|
||||
|
||||
=======================================================================
|
||||
@ -27,4 +27,5 @@ R2. Usually "Out of memory" errors are related to old days,
|
||||
Look at imapsync output first lines to get the Mail::IMAPClient
|
||||
release used. Then upgrade Mail::IMAPClient Perl module if needed.
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
@ -1,22 +1,55 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Messages_Selection.txt,v 1.6 2016/04/18 12:45:20 gilles Exp gilles $
|
||||
$Id: FAQ.Messages_Selection.txt,v 1.12 2017/09/05 15:11:20 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
=====================================
|
||||
Imapsync tips to select messages.
|
||||
=====================================
|
||||
=======================================================================
|
||||
Imapsync tips to select messages.
|
||||
=======================================================================
|
||||
|
||||
By default, Imapsync syncs all messages, avoiding duplicates.
|
||||
Questions anwswered in this FAQ are:
|
||||
|
||||
Q. What messages imapsync syncs by default?
|
||||
|
||||
Q. Is there a way we can specify a date range to sync emails?
|
||||
If yes, can you please share an example?
|
||||
|
||||
Q. Is there a way we can specify an age to sync emails?
|
||||
If yes, can you please share some examples?
|
||||
|
||||
Q. I want to sync messages based on their UID.
|
||||
|
||||
Q. Can I migrate only mails with attachments?
|
||||
|
||||
Q. How can I move messages marked \Deleted from all folders to
|
||||
a dedicated folder?
|
||||
|
||||
Q. What are the selection criteria available with --search option?
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. What messages imapsync syncs by default?
|
||||
|
||||
R. By default, Imapsync syncs all messages, except duplicates.
|
||||
|
||||
=======================================================================
|
||||
Q. Is there a way we can specify a date range to sync emails?
|
||||
If yes, can you please share an example?
|
||||
|
||||
R. Yes, with the --search option.
|
||||
R. Yes, a date range is possible with the --search option.
|
||||
|
||||
imapsync ... --search "SENTSINCE 1-Jan-2010"
|
||||
|
||||
or
|
||||
|
||||
imapsync ... --search "SENTBEFORE 31-Dec-2010"
|
||||
|
||||
or
|
||||
|
||||
imapsync ... --search "SENTSINCE 1-Jan-2010 SENTBEFORE 31-Dec-2010"
|
||||
|
||||
Months are specified like this:
|
||||
|
||||
Jan
|
||||
Feb
|
||||
Mar
|
||||
@ -80,7 +113,8 @@ timezone) is earlier than the specified date.
|
||||
If --noabletosearch is on then --minage and --maxage deal
|
||||
with the internal dates given by a FETCH imap command but
|
||||
not the Date: header. Internal date is the arrival date
|
||||
in the mailbox.
|
||||
in the mailbox. Same remark for --noabletosearch1 and
|
||||
--noabletosearch2 but only for one side then.
|
||||
|
||||
=======================================================================
|
||||
Q. I want to sync messages based on their UID.
|
||||
@ -109,9 +143,29 @@ UIDs 20000 20002 20004:
|
||||
If you search n UIDs then you have to put n-1 OR in the search line,
|
||||
that's IMAP.
|
||||
|
||||
=======================================================================
|
||||
Q. Can I migrate only mails with attachments?
|
||||
|
||||
R. Use:
|
||||
|
||||
imapsync ... --search "HEADER Content-Type multipart/mixed"
|
||||
|
||||
or more generally:
|
||||
|
||||
imapsync ... --search "OR HEADER Content-Disposition attachment HEADER Content-Type multipart/mixed"
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. What is the selection criteria available with --search option?
|
||||
Q. How can I move messages marked \Deleted from all folders to
|
||||
a dedicated folder?
|
||||
|
||||
R. To move \Deleted messages from all folders to a specific folder,
|
||||
let's call it Trash, use:
|
||||
|
||||
imapsync ... --search DELETED --regextrans2 "s/.*/Trash/"
|
||||
|
||||
=======================================================================
|
||||
Q. What are the selection criteria available with --search option?
|
||||
|
||||
R. The list of search criteria are listed below, an excerpt from RFC3501.
|
||||
|
||||
@ -250,4 +304,5 @@ http://www.faqs.org/rfcs/rfc3501.html
|
||||
Messages that do not have the \Seen flag set.
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
||||
|
36
FAQ.d/FAQ.OnlineUI.txt
Normal file
36
FAQ.d/FAQ.OnlineUI.txt
Normal file
@ -0,0 +1,36 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.OnlineUI.txt,v 1.1 2017/05/04 23:24:55 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
=====================================================================
|
||||
Imapsync tips about the online visual user interface
|
||||
https://imapsync.lamiral.info/X/
|
||||
=====================================================================
|
||||
|
||||
Q .Will I have any issues with browser timing out? What happens
|
||||
if the connection is closed for whatever reason?
|
||||
|
||||
R. It should be ok
|
||||
|
||||
With the /X interface there is two connections (three connections in
|
||||
fact but let simplify the picture), 1 is the Browser-WebServer
|
||||
connection, 2 is the WebServer-ImapServers connections (imapsync
|
||||
stuff).
|
||||
|
||||
If the Browser-WebServer connection is timeout (but it shouldn't
|
||||
because of the log refresh), the imapsync sync might continue
|
||||
anyway. To see if it continues or not, just do a sync again and the
|
||||
interface will tell you that a sync is already going on, if the
|
||||
"Sync!" button is grey/inactive then just reload the page (F5 or
|
||||
similar).
|
||||
|
||||
Anyway, on the /X you can try to do several parallel runs on the same
|
||||
mailbox even if there is no timeout, open a new tab/windows with /X
|
||||
and start a same sync, it's safe, the /X will say, if any, that there
|
||||
is already a current sync.
|
||||
|
||||
You can stop this sync with the "Abort!" button from any /X
|
||||
tab/window, even from another browser or place. To doing this with
|
||||
success, you have to give the same account parameters, same
|
||||
credentials, or imapsync will ignore the demand.
|
@ -1,11 +1,11 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Oracle-UCS.txt,v 1.3 2016/01/28 14:34:15 gilles Exp gilles $
|
||||
$Id: FAQ.Oracle-UCS.txt,v 1.4 2017/01/06 14:11:13 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
==================================================
|
||||
Imapsync tips for Oracle-UCS. Specific issues.
|
||||
==================================================
|
||||
=======================================================================
|
||||
Imapsync tips for Oracle-UCS. Specific issues.
|
||||
=======================================================================
|
||||
|
||||
Oracle-UCS was previously Sun JES, IPlanet, etc.
|
||||
|
||||
@ -16,3 +16,5 @@ Oracle-UCS was previously Sun JES, IPlanet, etc.
|
||||
--skipmess 'm/[\x80-\xff]/'
|
||||
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
21
FAQ.d/FAQ.Passwords_on_Unix.txt
Normal file
21
FAQ.d/FAQ.Passwords_on_Unix.txt
Normal file
@ -0,0 +1,21 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Passwords_on_Unix.txt,v 1.1 2017/01/06 14:11:13 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
=======================================================================
|
||||
Imapsync issues with passwords on Unix.
|
||||
=======================================================================
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. On Unix, some passwords contain some *(),;& characters. Login fails.
|
||||
|
||||
R. Use double-quotes within single-quotes in order to enclose the
|
||||
password within double-quotes in the imap LOGIN command:
|
||||
|
||||
imapsync ... --password1 '"passw*(),;&rd"'
|
||||
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
@ -1,16 +1,18 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Passwords_on_Windows.txt,v 1.2 2016/05/10 19:19:16 gilles Exp gilles $
|
||||
$Id: FAQ.Passwords_on_Windows.txt,v 1.3 2017/01/06 14:11:13 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
======================================================
|
||||
Imapsync issues with passwords on Windows.
|
||||
======================================================
|
||||
=======================================================================
|
||||
Imapsync issues with passwords on Windows.
|
||||
=======================================================================
|
||||
|
||||
|
||||
http://www.robvanderwoude.com/escapechars.php
|
||||
http://stackoverflow.com/questions/3288552/how-can-i-escape-an-exclamation-mark-in-cmd-scripts
|
||||
|
||||
In case you're brave and relentless, understand and try this:
|
||||
http://www.dostips.com/forum/viewtopic.php?f=3&t=1733
|
||||
|
||||
=======================================================================
|
||||
Q. On Windows, some passwords contain $ characters. Login fails.
|
||||
@ -42,3 +44,5 @@ or even
|
||||
|
||||
imapsync ... --password1 "==secret"
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
22
FAQ.d/FAQ.Release_Checklist.txt
Normal file
22
FAQ.d/FAQ.Release_Checklist.txt
Normal file
@ -0,0 +1,22 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Release_Checklist.txt,v 1.5 2017/09/07 12:38:45 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
===================================
|
||||
Imapsync developper notes
|
||||
===================================
|
||||
|
||||
|
||||
Checklist before release a new release:
|
||||
|
||||
- Generate the README
|
||||
- Run a spell checker on the README
|
||||
- Read the README again slowly. Fix all issues, all
|
||||
- Read the OPTIONS section of README and read it very slowly
|
||||
- Read slowly README_Windows.txt
|
||||
- Read slowly the TUTORIAL_Unix file in html
|
||||
- Review the newsletter by running:
|
||||
m4 -P W/ml_announce.in
|
||||
|
||||
- Review the general FAQ.d/FAQ.General.txt
|
29
FAQ.d/FAQ.Reporting_Bugs.txt
Normal file
29
FAQ.d/FAQ.Reporting_Bugs.txt
Normal file
@ -0,0 +1,29 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Reporting_Bugs.txt,v 1.2 2017/09/07 12:10:49 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
===================================================
|
||||
Imapsync bugs reports
|
||||
===================================================
|
||||
|
||||
=======================================================================
|
||||
Q. How can I report bugs or problems I encountered with Imapsync?
|
||||
|
||||
R. Help me to help you: follow the following guidelines.
|
||||
|
||||
Report any bug or feature request directly to the author by
|
||||
email at <gilles.lamiral@laposte.net>
|
||||
|
||||
Put a useful title with word "imapsync" in it: my spam filters
|
||||
won't filter it.
|
||||
|
||||
Provide me any useful information. The simplest way is to attach
|
||||
the complete log file, in case it is not too big, let say less
|
||||
than 1MB. Don't zip it, it will slow my response.
|
||||
|
||||
Thanks!
|
||||
|
||||
=======================================================================
|
||||
|
||||
|
56
FAQ.d/FAQ.SSL_errors.txt
Normal file
56
FAQ.d/FAQ.SSL_errors.txt
Normal file
@ -0,0 +1,56 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.SSL_errors.txt,v 1.1 2017/05/24 19:16:40 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
=====================================================
|
||||
Imapsync SSL errors
|
||||
=====================================================
|
||||
|
||||
Questions anwswered in this FAQ are:
|
||||
|
||||
Q. What are the errors
|
||||
DEBUG: .../IO/Socket/SSL.pm:1165: local error: SSL write error
|
||||
or
|
||||
DEBUG: .../IO/Socket/SSL.pm:1088: local error: SSL read error
|
||||
|
||||
|
||||
Q. What can I do to avoid those "SSL read/write errors"?
|
||||
|
||||
=======================================================================
|
||||
Q. What are the errors
|
||||
DEBUG: .../IO/Socket/SSL.pm:1165: local error: SSL write error
|
||||
or
|
||||
DEBUG: .../IO/Socket/SSL.pm:1088: local error: SSL read error
|
||||
|
||||
R. Like they claim, those errors are SSL errors. SSL is not directly
|
||||
done by imapsync but by an underlying Perl module called
|
||||
IO::Socket::SSL. Those errors arise sometimes and sometimes
|
||||
they form a serie that ends with imapsync auto-abortion.
|
||||
Those errors happen with some hosts but not with others,
|
||||
it's often Exchange or Office365. I don't know what exactly happens.
|
||||
Those errors happen more often on Windows than on Linux.
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. What can I do to avoid those "SSL read/write errors"?
|
||||
|
||||
R1. Remove all ssl/tls encryption
|
||||
|
||||
imapsync ... --nossl1 --notls1 --nossl2 --notls2
|
||||
|
||||
R2. If you don't want to quit encryption, rerun imapsync until the
|
||||
complete sync is over. Those errors are not at the same place
|
||||
each time, so imapsync will sync remaining messages at each run
|
||||
until none remains.
|
||||
|
||||
R3. Run imapsync on a Linux machine, a VM is ok, there are less
|
||||
SSL errors on Unix.
|
||||
|
||||
R4. Use https://imapsync.lamiral.info/X/
|
||||
It's a Linux host so R3 applies there.
|
||||
|
||||
R5. Set up a ssltunnel proxy to the host.
|
||||
Read the file FAQ.Security.txt
|
||||
|
||||
=======================================================================
|
@ -1,44 +1,108 @@
|
||||
#!/bin/cat
|
||||
# $Id: FAQ.Security.txt,v 1.9 2016/08/19 17:53:21 gilles Exp gilles $
|
||||
# $Id: FAQ.Security.txt,v 1.16 2017/04/26 21:50:00 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
=======================================================
|
||||
Imapsync tips about security. Issues and solutions.
|
||||
=======================================================
|
||||
=======================================================================
|
||||
Imapsync tips about security. Issues and solutions.
|
||||
=======================================================================
|
||||
|
||||
SSL: going to encryption before the imap session start.
|
||||
It is on port 993.
|
||||
|
||||
TLS: going to encryption after the imap session start but before
|
||||
the credential are sent. It is on port 143.
|
||||
|
||||
=======================================================================
|
||||
Q. Is running this program a secure method of transferring emails?
|
||||
Are there any security concerns?
|
||||
|
||||
R. Well, it depends. Use encryption, secure the access to the host running
|
||||
imapsync and everything shall be safe.
|
||||
|
||||
=======================================================================
|
||||
Q. I noticed that the online UI has no option for TLS/SSL
|
||||
Is this secure? Is this more secure that using the .bat file
|
||||
on my computer?
|
||||
|
||||
R1. The online UI does TLS/SSL imap connections if the imap
|
||||
servers support TLS/SSL. If you are concerned by security then
|
||||
using the .bat file or .sh on your computer should be more secure
|
||||
since you can examine and secure it by yourself, no matter high is
|
||||
your paranoïd spirit. The online UI security is mine, I am
|
||||
concerned by security, not to the upmost high level possible
|
||||
but I won't give you direct access to the host to discover my level.
|
||||
With a good guy spirit, feel free to try to break the online UI
|
||||
security and report me any security issue you encounter, I'll do my
|
||||
best to fix them as soon as possible. Drop me a note before
|
||||
starting because I may detect a sort of abuse and ban
|
||||
definitively your IPs.
|
||||
|
||||
=======================================================================
|
||||
Q. Are transferred emails/attachments stored on any other
|
||||
server/location aside from my originating/destination server(s)?
|
||||
|
||||
R. No!
|
||||
|
||||
=======================================================================
|
||||
Q. Other than changing passwords on the originating/destination email
|
||||
accounts once the relevant emails have been moved,
|
||||
are there any other security tips I should know?
|
||||
|
||||
R. Secure the host where imapsync is running since credentials are
|
||||
on it.
|
||||
|
||||
=======================================================================
|
||||
Q. I need to transfer mail from an imap server to an other imap server.
|
||||
Which ports need to be open on the firewall to make this possible?
|
||||
|
||||
R. It depends. Open either:
|
||||
* port 143 in basic (no special option) or tls mode (--tls1 or --tls2)
|
||||
* port 993 in ssl mode (--ssl1 or --ssl2)
|
||||
|
||||
=======================================================================
|
||||
Q. Does imapsync support IMAP TLS?
|
||||
|
||||
R. Use --tls1 and/or --tls2 options
|
||||
R1. Yes.
|
||||
Use --tls1 and/or --tls2 options:
|
||||
|
||||
--tls1 tells imapsync to use tls on host1.
|
||||
--tls2 tells imapsync to use tls on host2.
|
||||
--tls1 tells imapsync to use tls on host1.
|
||||
--tls2 tells imapsync to use tls on host2.
|
||||
|
||||
R2. Since imapsync release 1.755 TLS mode is activated automatically
|
||||
if the server announce it supports it, STARTTLS inside the response
|
||||
to CAPABILITY, and if neither --notls nor --ssl is explicitely
|
||||
mentioned on the command line options.
|
||||
|
||||
=======================================================================
|
||||
Q. Does imapsync support IMAP over SSL (IMAPS)?
|
||||
|
||||
R. Yes natively since release 1.161.
|
||||
still, 2 ways, at least to use ssl:
|
||||
Still, there are 2 ways, at least, to use ssl:
|
||||
|
||||
a) Use native --ssl1 and/or --ssl2 options
|
||||
|
||||
--ssl1 tells imapsync to use ssl on host1.
|
||||
--ssl2 tells imapsync to use ssl on host2.
|
||||
--ssl1 tells imapsync to use ssl on host1.
|
||||
--ssl2 tells imapsync to use ssl on host2.
|
||||
|
||||
|
||||
b) Use stunnel
|
||||
http://www.stunnel.org/
|
||||
Assuming there is an imaps (993) server on imap.foo.org,
|
||||
on your localhost machine (or bar machine) run :
|
||||
stunnel -c -d imap -r imap.foo.org:imaps
|
||||
or using names instead of numbers
|
||||
stunnel -c -d 143 -r imap.foo.org:993
|
||||
then use imapsync on localhost (or bar machine) imap (143) port.
|
||||
If the local port 143 is already taken then use a free one, 10143.
|
||||
on your localhost machine (or bar machine), run:
|
||||
|
||||
c) Other example for gmail with no root access to open port 143
|
||||
stunnel -c -d imap -r imap.foo.org:imaps
|
||||
|
||||
or using numbers instead of names:
|
||||
|
||||
stunnel -c -d 143 -r imap.foo.org:993
|
||||
|
||||
then use imapsync on localhost (or bar machine) imap (143) port.
|
||||
If the local port 143 is already taken then use a free one,
|
||||
like 10143 for example.
|
||||
|
||||
c) Other example for accessing gmail with no local root access
|
||||
to open port 143
|
||||
|
||||
stunnel -f -P '' -c -d 9993 -r imap.gmail.com:993
|
||||
|
||||
@ -47,12 +111,36 @@ Then, to access gmail as host2 use:
|
||||
imapsync ... --host2 localhost --port2 9993 --nossl2
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q.How can I test an ssl imap connection without imapsync?
|
||||
|
||||
R1. Use either ncat or telnet-ssl or openssl commands like in the
|
||||
following examples with imap.gmail.com server:
|
||||
|
||||
ncat --ssl -C imap.gmail.com 993
|
||||
|
||||
telnet-ssl -z ssl imap.gmail.com 993
|
||||
|
||||
openssl s_client -crlf -connect imap.gmail.com:993
|
||||
|
||||
The previous commands are interactive, hit ctrl-c
|
||||
to finish them. If you want to finish automatically, then use:
|
||||
|
||||
{ sleep 2; echo "a logout"; sleep 1; } | ncat --ssl -C imap.gmail.com 993
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. How can I manually test a login via ssl?
|
||||
|
||||
R. Use ncat or telnet-ssl like in this example:
|
||||
R. Use either ncat or telnet-ssl or openssl commands like in the
|
||||
following examples with imap.gmail.com server:
|
||||
|
||||
ncat --ssl -C imap.gmail.com 993
|
||||
ncat --ssl -C imap.gmail.com 993
|
||||
telnet-ssl -z ssl imap.gmail.com 993
|
||||
openssl s_client -crlf -connect imap.gmail.com:993
|
||||
|
||||
Tipical dialog for an imap LOGIN command:
|
||||
|
||||
* OK Gimap ready for requests from 78.196.254.58 q1mb175739668wix
|
||||
a LOGIN "gilles.lamiral@gmail.com" "secret"
|
||||
* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE ... ESEARCH
|
||||
@ -61,21 +149,27 @@ b LOGOUT
|
||||
* BYE LOGOUT Requested
|
||||
b OK 73 good day (Success)
|
||||
|
||||
The client part to type is "a LOGIN ..." and "b LOGOUT" without
|
||||
the double-quotes.
|
||||
The client part you have to type is
|
||||
a LOGIN ...
|
||||
b LOGOUT
|
||||
while replacing ... by your credentials values.
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q.How to test a ssl imap connection without imapsync?
|
||||
Q.How can I test an tls imap connection without imapsync?
|
||||
|
||||
R1.Use openssl command like the following,
|
||||
an example with imap.gmail.com server:
|
||||
R1. Use openssl command like the following example with
|
||||
an outlook.office365.com server:
|
||||
|
||||
openssl s_client -crlf -connect imap.gmail.com:993
|
||||
openssl s_client -crlf -starttls imap -connect outlook.office365.com:143
|
||||
|
||||
The previous command is an interactive connection, hit ctrl-c
|
||||
to finish it. If you want to finish it gently, then use:
|
||||
The previous commands are interactive, hit ctrl-c
|
||||
to finish them. If you want to finish automatically, then use:
|
||||
|
||||
{ sleep 2; echo "a logout"; sleep 1; } | openssl s_client -crlf -starttls imap -connect outlook.office365.com:143
|
||||
|
||||
Replace outlook.office365.com with your imap server name.
|
||||
|
||||
{ sleep 2; echo "a logout"; sleep 1; } | openssl s_client -crlf -connect imap.gmail.com:993
|
||||
|
||||
======================================================================
|
||||
Q. Imapsync used to use SSL_VERIFY_PEER now it uses SSL_VERIFY_NONE.
|
||||
@ -130,3 +224,5 @@ b) or use stunnel :
|
||||
c) or use stunnel on inetd
|
||||
imaps stream tcp nowait cyrus /usr/sbin/stunnel -s cyrus -p /etc/ssl/certs/imapd.pem -r localhost:imap2
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
@ -1,11 +1,11 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.SmarterMail.txt,v 1.8 2016/01/28 14:34:15 gilles Exp gilles $
|
||||
$Id: FAQ.SmarterMail.txt,v 1.11 2017/09/05 15:11:20 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
=================================================================
|
||||
Imapsync tips for SmarterMail. Specific issues and solutions.
|
||||
=================================================================
|
||||
=======================================================================
|
||||
Imapsync tips for SmarterMail. Specific issues and solutions.
|
||||
=======================================================================
|
||||
|
||||
|
||||
=======================================================================
|
||||
@ -14,7 +14,7 @@ Q. Synchronizing from SmarterMail to XXX
|
||||
On Unix:
|
||||
imapsync --host1 imap.d1.org --user1 joe --password1 secret1 \
|
||||
--host2 imap.d2.org --user2 joe --password2 secret2 \
|
||||
--sep1 "/" --prefix1 "" --useheader Message-Id \
|
||||
--sep1 "/" --prefix1 "" --useheader Message-Id --noabletosearch1 \
|
||||
--regextrans2 "s,Deleted Items,Trash," \
|
||||
--regextrans2 "s,Junk E-Mail,Junk," \
|
||||
--regextrans2 "s,Sent Items,Sent,"
|
||||
@ -22,7 +22,7 @@ imapsync --host1 imap.d1.org --user1 joe --password1 secret1 \
|
||||
On Windows:
|
||||
imapsync.exe --host1 imap.d1.org --user1 joe --password1 secret1 ^
|
||||
--host2 imap.d2.org --user2 joe --password2 secret2 ^
|
||||
--sep1 "/" --prefix1 "" --useheader Message-Id ^
|
||||
--sep1 "/" --prefix1 "" --useheader Message-Id --noabletosearch1 ^
|
||||
--regextrans2 "s,Deleted Items,Trash," ^
|
||||
--regextrans2 "s,Junk E-Mail,Junk," ^
|
||||
--regextrans2 "s,Sent Items,Sent,"
|
||||
@ -36,13 +36,14 @@ Q. Synchronizing from XXX to SmarterMail
|
||||
On Unix:
|
||||
imapsync --host1 imap.d1.org --user1 joe --password1 secret1 \
|
||||
--host2 imap.d2.org --user2 joe --password2 secret2 \
|
||||
--sep2 "/" --prefix2 "" --useheader Message-Id
|
||||
--sep2 "/" --prefix2 "" --useheader Message-Id --noabletosearch2
|
||||
|
||||
On Windows:
|
||||
imapsync.exe --host1 imap.d1.org --user1 joe --password1 secret1 ^
|
||||
--host2 imap.d2.org --user2 joe --password2 secret2 ^
|
||||
--sep2 "/" --prefix2 "" --useheader Message-Id
|
||||
--sep2 "/" --prefix2 "" --useheader Message-Id --noabletosearch2
|
||||
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
||||
|
32
FAQ.d/FAQ.TTL.txt
Normal file
32
FAQ.d/FAQ.TTL.txt
Normal file
@ -0,0 +1,32 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.TTL.txt,v 1.1 2017/05/03 22:27:45 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
=====================================================================
|
||||
Imapsync tips about TTL when changing name resolution of hosts
|
||||
=====================================================================
|
||||
|
||||
Why decrease the TTL (Time To Live) delay in DNS configuration, down
|
||||
to 5 minutes?
|
||||
|
||||
A small TTL is not mandatory, it's safer and more easy to work with when
|
||||
migrating.
|
||||
|
||||
It's about how long it takes to be sure the users are using the new
|
||||
imap host, and how long it takes to be sure all new incoming messages
|
||||
are going right now at the right place. Will you shut down the old
|
||||
server just after the resolution change? I guess you won't and you'll
|
||||
be right.
|
||||
|
||||
The TTL is just a value, very well supported by machines, with a
|
||||
little name resolution supplementary work for them when it is set to a
|
||||
small value like 5 minutes, but it's a tremendous comfort for migrator
|
||||
people like us.
|
||||
|
||||
Be sure to wait 24h after this TTL change before changing any
|
||||
resolution since the TTL change has to be propagated as well. After
|
||||
the migration done, no problem to set back the TTL to 24h or more. If
|
||||
you can't decrease TTL under 4h or even 24h, it's ok anyway, imapsync
|
||||
can sync the new messages dropped in the old server.
|
||||
|
@ -1,11 +1,11 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Use_addheader.txt,v 1.1 2016/06/01 12:25:56 gilles Exp gilles $
|
||||
$Id: FAQ.Use_addheader.txt,v 1.4 2017/01/25 23:54:02 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
============================================
|
||||
Imapsync --addheader suggestion.
|
||||
============================================
|
||||
=======================================================================
|
||||
Imapsync --addheader suggestion.
|
||||
=======================================================================
|
||||
|
||||
=======================================================================
|
||||
Q. What means this log message:
|
||||
@ -22,9 +22,12 @@ R. In order to sync messages from one account to another Imapsync has
|
||||
messages except for special folders like Sent or Draft where
|
||||
messages in those folders don't have "Message-Id:" nor
|
||||
"Received:" headers.
|
||||
Here comes -addheader option. Option --addheader adds
|
||||
a "Message-Id" header consisting of the imap UID of the message
|
||||
on the host1 folder, like "Message-Id: 12345@imapsync".
|
||||
This way, messages are well identified on both sides.
|
||||
Here comes --addheader option. When a message has no "Message-Id:"
|
||||
nor "Received:", option --addheader adds a "Message-Id" header
|
||||
consisting of the imap UID of the message on the host1 folder,
|
||||
like "Message-Id: 12345@imapsync".
|
||||
This way, messages are well identified on both sides,
|
||||
transferred, and only once.
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
99
FAQ.d/FAQ.Use_cache.txt
Normal file
99
FAQ.d/FAQ.Use_cache.txt
Normal file
@ -0,0 +1,99 @@
|
||||
|
||||
$Id: FAQ.Use_cache.txt,v 1.4 2017/02/14 17:35:22 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
============================================
|
||||
Imapsync --usecache option
|
||||
============================================
|
||||
|
||||
Questions anwswered in this FAQ are:
|
||||
|
||||
Q. On Windows, with --useuid or --usecache a problem occurs with long
|
||||
nested folder names. The error message is:
|
||||
"No such file or directory; The filename or extension is too long"
|
||||
|
||||
Q. Inode problem with --usecache on Linux
|
||||
|
||||
|
||||
Questions and their answers:
|
||||
|
||||
=======================================================================
|
||||
Q. On Windows, with --useuid or --usecache a problem occurs with long
|
||||
nested folder names. The error message is:
|
||||
"No such file or directory; The filename or extension is too long"
|
||||
|
||||
R. This comes from a Windows limitation on pathnames.
|
||||
No more than 260 characters are allowed for pathnames.
|
||||
See more details on page
|
||||
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx#maxpath
|
||||
The workaround solution given at the previous link,
|
||||
ie using \\?\D:", does not work for imapsync.
|
||||
So this imapsync Windows bug is still pending and needs a fix using
|
||||
a different technique to cache, like a database file for example.
|
||||
|
||||
A solution to fix the issue is to use a Linux virtual host on a
|
||||
Windows box, with VirtualBox or VmWare etc. There is no bug this way,
|
||||
pathnames can be several thousands characters long.
|
||||
Better said that done but not so difficult nor expensive these days,
|
||||
VirtualBox is free and VmWare Player is free for personal or test use.
|
||||
|
||||
If you have to stick on Windows, there are two good workarounds
|
||||
to reduce the cache directory name:
|
||||
|
||||
1) Use --tmpdir "D:\\temp" or simply --tmpdir "D:" and imapsync
|
||||
will build and use the cache in the sub directory
|
||||
D:\imapsync_cache\
|
||||
|
||||
2) add two equivalent entries in the etc/hosts for host1 imap.truc.org
|
||||
and host2 imap.trac.org.
|
||||
If you map the ip of imap.truc.org just with the letter a
|
||||
and same thing for imap.trac.org then you gain characters
|
||||
|
||||
etc/hosts
|
||||
|
||||
192.168.12.1 a
|
||||
192.168.55.3 b
|
||||
|
||||
Then use:
|
||||
|
||||
imapsync --host1 a --host2 b ...
|
||||
|
||||
You can get the ip of a host with the ping command line
|
||||
C:\> ping imap.truc.org
|
||||
|
||||
3) A third solution is to not use options --useuid nor --usecache
|
||||
|
||||
Fixing this long path problem directly in imapsync is in the TODO file
|
||||
for a very long time.
|
||||
|
||||
=======================================================================
|
||||
Q. Inode problem with --usecache on Linux
|
||||
|
||||
R. You may run out of inodes using --usecache, especially with large
|
||||
migration. Option --usecache creates a empty file per email message
|
||||
in order to keep the UIDs mapping between account1 and account2.
|
||||
|
||||
So, if you plan to sync regularly 10 millions messages over a period
|
||||
of migration then the filesystem of --tmpdir needs 10 millions of free
|
||||
inodes. If it hasn't those free inodes then create a new special
|
||||
filesystem devoted to the imapsync cache.
|
||||
|
||||
# Create a file of 10 GB (10 millions*1024):
|
||||
|
||||
dd if=/dev/zero of=/var/tmp/fscache bs=1M count=10000
|
||||
|
||||
# Create a filesystem where each file is only 1024 bytes per inode:
|
||||
|
||||
mkfs.ext2 -F -i 1024 /var/tmp/fscache
|
||||
|
||||
# Mount this brand new filesystem
|
||||
|
||||
mount -o loop /var/tmp/fscache /var/tmp/cachedir
|
||||
|
||||
# Tell imapsync to use it
|
||||
|
||||
imapsync ... --tmpdir /var/tmp/cachedir/
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
@ -1,11 +1,11 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.User_Concurrent_Access.txt,v 1.1 2016/07/22 00:00:08 gilles Exp gilles $
|
||||
$Id: FAQ.User_Concurrent_Access.txt,v 1.2 2017/01/06 14:11:13 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
=======================================
|
||||
Imapsync and user concurrent access.
|
||||
=======================================
|
||||
=======================================================================
|
||||
Imapsync and user concurrent access.
|
||||
=======================================================================
|
||||
|
||||
=======================================================================
|
||||
Q. What happens if a user access the mailbox during the transfer process?
|
||||
@ -33,3 +33,4 @@ on what he does, where he does and when:
|
||||
* message flag change => might be canceled by the sync
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
@ -1,11 +1,11 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.Various_Server_Softwares.txt,v 1.4 2016/01/28 14:34:15 gilles Exp gilles $
|
||||
$Id: FAQ.Various_Server_Softwares.txt,v 1.8 2017/09/05 15:11:20 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
====================================================
|
||||
Imapsync tips for various imap server softwares.
|
||||
====================================================
|
||||
=======================================================================
|
||||
Imapsync tips for various imap server softwares.
|
||||
=======================================================================
|
||||
|
||||
|
||||
|
||||
@ -43,22 +43,6 @@ http://www.safetynet-it.com/it-support/mac-kerio-server-to-microsoft-exchange-20
|
||||
http://www.safetynet-it.com/it-support/mac-kerio-server-to-microsoft-exchange-2010-migration-2/
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. Synchronizing from Yahoo to XXX
|
||||
|
||||
R. Use --host1 imap.mail.yahoo.com --ssl1
|
||||
|
||||
./imapsync \
|
||||
--host1 imap.mail.yahoo.com \
|
||||
--user1 billy \
|
||||
--password1 secret \
|
||||
--ssl1 \
|
||||
--host2 XXX \
|
||||
--user2 billy \
|
||||
--password2 secret
|
||||
|
||||
SSL is mandatory for yahoo since november 2011.
|
||||
|
||||
=======================================================================
|
||||
Q. from Microsoft's Exchange 2007 to Google Apps for your Domain
|
||||
(GAFYD)
|
||||
@ -228,14 +212,14 @@ R. Old Softalk releases don't support the IMAP SEARCH command.
|
||||
Here are the options to get it working.
|
||||
|
||||
imapsync ... --sep1 '.' --prefix1 '' \
|
||||
--noabletosearch --nocheckmessageexists --addheader
|
||||
--noabletosearch1 --nocheckmessageexists --addheader
|
||||
|
||||
(Thanks to Andrew Tucker)
|
||||
|
||||
======================================================================
|
||||
Q. From or to QQMail IMAP4Server
|
||||
|
||||
R. imapsync ... --noabletosearch
|
||||
R. imapsync ... --noabletosearch1
|
||||
|
||||
======================================================================
|
||||
Q. From FirstClass to XXX
|
||||
@ -264,8 +248,20 @@ Here is a command line used to migrate from FirtClass release 12:
|
||||
--regextrans2 "s,&AC8-,-,g" \
|
||||
--regextrans2 "s,&APg-,oe,g"
|
||||
|
||||
On Windows, in the previous example containing \$1 you have to
|
||||
replace the two \$1 by $1 (remove the \ before $).
|
||||
On Windows:
|
||||
imapsync.exe ... ^
|
||||
--automap ^
|
||||
--usecache ^
|
||||
--useheader Message-ID ^
|
||||
--idatefromheader ^
|
||||
--addheader ^
|
||||
--regextrans2 "s,(/|^) +,$1,g" ^
|
||||
--regextrans2 "s, +(/|$),$1,g" ^
|
||||
--regextrans2 "s/[\^]/_/g" ^
|
||||
--regextrans2 "s/['\\]/_/g" ^
|
||||
--regextrans2 "s,^&AC8-,-,g" ^
|
||||
--regextrans2 "s,^&APg-,oe,g"
|
||||
|
||||
|
||||
Special thanks to Kristian Wind and Joey Alexander for helping me
|
||||
writing this FAQ item.
|
||||
@ -283,3 +279,5 @@ R. Do NOT use --usecache since new UIDs are not given by FTGate and also
|
||||
--sep2 / --prefix2 "" \
|
||||
--useheader Message-Id \
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
34
FAQ.d/FAQ.Virus.txt
Normal file
34
FAQ.d/FAQ.Virus.txt
Normal file
@ -0,0 +1,34 @@
|
||||
|
||||
$Id: FAQ.Virus.txt,v 1.2 2017/07/03 19:30:19 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
=======================================================================
|
||||
Imapsync and virus scanners
|
||||
=======================================================================
|
||||
|
||||
=======================================================================
|
||||
Q. My virus scanner claims imapsync.exe is a virus/malware/trojan etc.
|
||||
What the hell?
|
||||
|
||||
R. Yes, I found the same. Two antivirus, Baidu and Jiangmin, report that
|
||||
imapsync might have a trojan in it.
|
||||
All others virus scanner say imapsync.exe is ok.
|
||||
I've done this test on imapsync.exe release 1.727 on the two following
|
||||
meta-virus-scanners:
|
||||
https://www.virustotal.com/
|
||||
https://www.metadefender.com/
|
||||
|
||||
R2. Explanation:
|
||||
It may come from the fact that imapsync checks whether there is a
|
||||
new realease available at http://imapsync.lamiral.info/VERSION
|
||||
It's explained here:
|
||||
https://imapsync.lamiral.info/#NUMBERS
|
||||
|
||||
Any other explanation is welcome!
|
||||
|
||||
R3. There is no virus alerts reported for the Perl script imapsync
|
||||
itself. The binary imapsync.exe is just a compiled version of
|
||||
the script imapsync, with perl interpreter itself and all modules
|
||||
needed by imapsync in order to make imapsync.exe a standalone software.
|
||||
|
@ -1,11 +1,11 @@
|
||||
#!/bin/cat
|
||||
$Id: FAQ.XOAUTH2.txt,v 1.11 2016/07/27 23:08:19 gilles Exp gilles $
|
||||
$Id: FAQ.XOAUTH2.txt,v 1.12 2017/01/06 14:11:13 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
======================================================================
|
||||
=======================================================================
|
||||
Imapsync tips to use XOAUTH2 authentication (Gmail) and old XOAUTH
|
||||
======================================================================
|
||||
=======================================================================
|
||||
|
||||
|
||||
=======================================================================
|
||||
@ -187,4 +187,6 @@ Some notes about configuring the Google Apps XOAUTH:
|
||||
"https://mail.google.com/" configured
|
||||
(https://support.google.com/a/bin/answer.py?answer=162106).
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
||||
|
54
FAQ.d/FAQ.Yahoo.txt
Normal file
54
FAQ.d/FAQ.Yahoo.txt
Normal file
@ -0,0 +1,54 @@
|
||||
|
||||
$Id: FAQ.Yahoo.txt,v 1.6 2017/06/17 14:42:01 gilles Exp gilles $
|
||||
|
||||
This documentation is also at http://imapsync.lamiral.info/#doc
|
||||
|
||||
=======================================================================
|
||||
Imapsync tips for Yahoo.
|
||||
=======================================================================
|
||||
|
||||
|
||||
=======================================================================
|
||||
Q. Synchronizing from Yahoo to XXX
|
||||
|
||||
R. Use --host1 imap.mail.yahoo.com --ssl1
|
||||
|
||||
./imapsync \
|
||||
--host1 imap.mail.yahoo.com \
|
||||
--user1 billy \
|
||||
--password1 secret \
|
||||
--ssl1 \
|
||||
--host2 XXX \
|
||||
--user2 billy \
|
||||
--password2 secret
|
||||
|
||||
SSL is mandatory for yahoo since November 2011.
|
||||
|
||||
You also need to go to Yahoo, security and enable
|
||||
"Allow less secure apps to login",
|
||||
otherwise the login will not work.
|
||||
|
||||
To enable less secure apps to login:
|
||||
* Login to the Yahoo mail account,
|
||||
* click on the account name or the avatar and select "Account Info",
|
||||
* click on "Account security",
|
||||
* turn off "Two steps verification"
|
||||
* turn on "Allow apps that use less secure authentication".
|
||||
|
||||
Thanks to Eugen Mayer for this last point.
|
||||
|
||||
Another solution:
|
||||
|
||||
* Login to the Yahoo mail account,
|
||||
* click on the account name or the avatar and select "Account Info",
|
||||
* click on "Account security",
|
||||
* Turn on "Two-step verification"
|
||||
* Click on "Manage app passwords" and
|
||||
generate a specific password for imapsync,
|
||||
choose "Other app" at the bottom and type imapsync
|
||||
since it is not in the predefined apps.
|
||||
* Use this password with imapsync.
|
||||
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
@ -1,31 +1,40 @@
|
||||
|
||||
# $Id: htaccess.txt,v 1.10 2016/07/22 00:20:13 gilles Exp gilles $
|
||||
# $Id: htaccess.txt,v 1.18 2017/09/03 03:14:48 gilles Exp gilles $
|
||||
|
||||
AddDescription "<b>Back to Imapsync main page</b>." ..
|
||||
AddDescription "<b>Archiving tips</b>." FAQ.Archiving.txt
|
||||
AddDescription "<b>Connection issues</b>." FAQ.Connection.txt
|
||||
AddDescription "<b>Contacts & Calendars issues</b>." FAQ.Contacts_Calendars.txt
|
||||
AddDescription "<b>Dates issues</b>." FAQ.Dates.txt
|
||||
AddDescription "<b>Domino</b>." FAQ.Domino.txt
|
||||
AddDescription "<b>Dovecot</b>." FAQ.Dovecot.txt
|
||||
AddDescription "<b>Duplicated</b> messages issues." FAQ.Duplicates.txt
|
||||
AddDescription "<b>Emptying</b> an account." FAQ.Emptying.txt
|
||||
AddDescription "<b>Exchange 20xx</b> and <b>Office365</b>." FAQ.Exchange.txt
|
||||
AddDescription "<b>Changing folders names</b>." FAQ.Folders_Mapping.txt
|
||||
AddDescription "<b>Selecting folders</b>." FAQ.Folders_Selection.txt
|
||||
AddDescription "<b>Flags</b>." FAQ.Flags.txt
|
||||
AddDescription "<b>Gmail</b> accounts." FAQ.Gmail.txt
|
||||
AddDescription "<b>ISP tips</b>." FAQ.ISP.txt
|
||||
AddDescription "<b>Massive/bulk migrations</b>." FAQ.Massive.txt
|
||||
|
||||
AddDescription "<b>Back to Imapsync main page</b>." ..
|
||||
AddDescription "<b>Authenticate via an admin account</b>." FAQ.Admin_Authentication.txt
|
||||
AddDescription "<b>Authentication failures</b>." FAQ.Authentication_failure.txt
|
||||
AddDescription "<b>Archiving tips</b>." FAQ.Archiving.txt
|
||||
AddDescription "<b>Connection issues</b>." FAQ.Connection.txt
|
||||
AddDescription "<b>Contacts & Calendars issues</b>." FAQ.Contacts_Calendars.txt
|
||||
AddDescription "<b>Dates issues</b>." FAQ.Dates.txt
|
||||
AddDescription "<b>Domino</b>." FAQ.Domino.txt
|
||||
AddDescription "<b>Dovecot</b>." FAQ.Dovecot.txt
|
||||
AddDescription "<b>Duplicated</b> messages issues." FAQ.Duplicates.txt
|
||||
AddDescription "<b>Emptying</b> an account." FAQ.Emptying.txt
|
||||
AddDescription "<b>Exchange 20xx</b> and <b>Office365</b>." FAQ.Exchange.txt
|
||||
AddDescription "<b>Changing folders names</b>." FAQ.Folders_Mapping.txt
|
||||
AddDescription "<b>Selecting folders</b>." FAQ.Folders_Selection.txt
|
||||
AddDescription "<b>Flags</b>." FAQ.Flags.txt
|
||||
AddDescription "<b>General</b> and <b>pot-pourri</b> issues" FAQ.General.txt
|
||||
AddDescription "<b>Gmail</b> accounts." FAQ.Gmail.txt
|
||||
AddDescription "<b>ISP tips</b>." FAQ.ISP.txt
|
||||
AddDescription "<b>Massive/bulk migrations</b>." FAQ.Massive.txt
|
||||
AddDescription "<b>Memory issues</b>." FAQ.Memory.txt
|
||||
AddDescription "<b>Password & special characters on Windows</b>." FAQ.Passwords_on_Windows.txt
|
||||
AddDescription "<b>Password & special characters on Unix</b>." FAQ.Passwords_on_Unix.txt
|
||||
AddDescription "<b>Selecting messages</b>." FAQ.Messages_Selection.txt
|
||||
AddDescription "<b>Oracle-UCS</b>." FAQ.Oracle-UCS.txt
|
||||
AddDescription "<b>Security</b>." FAQ.Security.txt
|
||||
AddDescription "<b>SmarterMail</b>." FAQ.SmarterMail.txt
|
||||
AddDescription "<b>User concurrent access</b>." FAQ.User_Concurrent_Access.txt
|
||||
AddDescription "<b>Why use --addheader?</b>." FAQ.Use_addheader.txt
|
||||
AddDescription "<b>Various imap server</b> softwares." FAQ.Various_Server_Softwares.txt
|
||||
AddDescription "<b>XOAUTH2</b> (<b>Gmail</b>)." FAQ.XOAUTH2.txt
|
||||
AddDescription "<b>Oracle-UCS</b>." FAQ.Oracle-UCS.txt
|
||||
AddDescription "<b>Guidelines to report bugs</b>." FAQ.Reporting_Bugs.txt
|
||||
AddDescription "<b>Security</b>." FAQ.Security.txt
|
||||
AddDescription "<b>SSL errors</b>." FAQ.SSL_errors.txt
|
||||
AddDescription "<b>SmarterMail</b>." FAQ.SmarterMail.txt
|
||||
AddDescription "<b>Option --usecache and inodes</b>." FAQ.Use_cache.txt
|
||||
AddDescription "<b>User concurrent access</b>." FAQ.User_Concurrent_Access.txt
|
||||
AddDescription "<b>Why use --addheader?</b>." FAQ.Use_addheader.txt
|
||||
AddDescription "<b>Various imap server</b> softwares." FAQ.Various_Server_Softwares.txt
|
||||
AddDescription "<b>XOAUTH2</b> (<b>Gmail</b>)." FAQ.XOAUTH2.txt
|
||||
AddDescription "<b>Yahoo</b>." FAQ.Yahoo.txt
|
||||
AddDescription "<b>Where this Description column comes from</b>." htaccess.txt
|
||||
|
||||
|
171
INSTALL
171
INSTALL
@ -1,171 +0,0 @@
|
||||
# $Id: INSTALL,v 1.50 2016/01/21 15:06:34 gilles Exp gilles $
|
||||
#
|
||||
# This is the main INSTALL file for imapsync.
|
||||
# imapsync : IMAP sync and migrate tool.
|
||||
|
||||
INTRODUCTION
|
||||
============
|
||||
|
||||
imapsync works fine under any operating system with Perl and Perl modules (listed below).
|
||||
imapsync.exe works fine standalone under Windows XP, Vista, Seven, 20XX, either 32 or 64bit.
|
||||
|
||||
====================================
|
||||
== Installing imapsync on WINDOWS ==
|
||||
====================================
|
||||
|
||||
Read the file README_Windows.txt
|
||||
Also available at
|
||||
http://imapsync.lamiral.info/README_Windows.txt
|
||||
|
||||
|
||||
=================================
|
||||
== Installing imapsync on Unix ==
|
||||
=================================
|
||||
|
||||
There are specific INSTALL files in the imapsync directory INSTALL.d/
|
||||
also available at http://imapsync.lamiral.info/INSTALL.d/
|
||||
|
||||
- Mac OS X
|
||||
- FreeBSD
|
||||
- CentOS
|
||||
- CPanel
|
||||
- Debian
|
||||
- Ubuntu
|
||||
|
||||
If you are not on one of these systems then read the section
|
||||
below called "Installing imapsync on other Unixes".
|
||||
|
||||
=====================================
|
||||
== Installing imapsync on Mac OS X ==
|
||||
=====================================
|
||||
|
||||
Easy.
|
||||
Read the file INSTALL.d/INSTALL.Darwin.txt
|
||||
Also available at
|
||||
http://imapsync.lamiral.info/INSTALL.d/INSTALL.Darwin.txt
|
||||
|
||||
=====================================
|
||||
== Installing imapsync on FreeBSD ==
|
||||
=====================================
|
||||
|
||||
Easy.
|
||||
Read the file INSTALL.d/INSTALL.FreeBSD.txt
|
||||
Also available at
|
||||
http://imapsync.lamiral.info/INSTALL.d/INSTALL.FreeBSD.txt
|
||||
|
||||
|
||||
===================================
|
||||
== Installing imapsync on CentOS ==
|
||||
===================================
|
||||
|
||||
Easy.
|
||||
Read the file INSTALL.d/INSTALL.Centos.txt
|
||||
Also available at
|
||||
http://imapsync.lamiral.info/INSTALL.d/INSTALL.Centos.txt
|
||||
|
||||
|
||||
===================================
|
||||
== Installing imapsync on CPanel ==
|
||||
===================================
|
||||
|
||||
Easy.
|
||||
Read the file INSTALL.d/INSTALL.CPanel.txt
|
||||
Also available at
|
||||
http://imapsync.lamiral.info/INSTALL.d/INSTALL.CPanel.txt
|
||||
|
||||
|
||||
==========================================
|
||||
== Installing imapsync on Debian 6 or 7 ==
|
||||
==========================================
|
||||
|
||||
Not so easy.
|
||||
See the file INSTALL.d/INSTALL.Debian.txt
|
||||
Also available at
|
||||
http://imapsync.lamiral.info/INSTALL.d/INSTALL.Debian.txt
|
||||
|
||||
============================================
|
||||
== Installing imapsync on Ubuntu 12 or 14 ==
|
||||
============================================
|
||||
|
||||
Not so easy.
|
||||
See the file INSTALL.d/INSTALL.Ubuntu.txt
|
||||
Also available at
|
||||
http://imapsync.lamiral.info/INSTALL.d/INSTALL.Ubuntu.txt
|
||||
|
||||
|
||||
=========================================
|
||||
== Installing imapsync on other Unixes ==
|
||||
=========================================
|
||||
|
||||
|
||||
Purchase imapsync at
|
||||
http://imapsync.lamiral.info/
|
||||
or get it anywhere.
|
||||
|
||||
You have access to a compressed tarball called imapsync-1.xxx.tgz
|
||||
where 1.xxx is the version number. Untar the tarball where
|
||||
you want:
|
||||
|
||||
cd
|
||||
tar xzvf imapsync-1.xxx.tgz
|
||||
|
||||
Go into the directory imapsync-1.xxx
|
||||
|
||||
cd imapsync-1.xxx
|
||||
|
||||
You can easily detect any missing Perl modules via the
|
||||
script prerequisites_imapsync located in the INSTALL.d directory:
|
||||
|
||||
sh INSTALL.d/prerequisites_imapsync
|
||||
|
||||
or
|
||||
|
||||
cd INSTALL.d/
|
||||
sh prerequisites_imapsync
|
||||
|
||||
You don't need to be root to run the previous command. You have
|
||||
to be root if you want the Perl modules to be available for the
|
||||
whole system, for all users.
|
||||
|
||||
You may be in one of following cases:
|
||||
- you are not root.
|
||||
- you are in a environment where modifying system Perl
|
||||
modules can break other things or where you're not allowed to
|
||||
change the whole system.
|
||||
|
||||
In the previous cases, you have to reinit cpan in order to use
|
||||
your local account:
|
||||
|
||||
FIX. The following commands can be replaced by what is described in
|
||||
"Installing imapsync script on Darwin / Mac OS X"
|
||||
at http://imapsync.lamiral.info/INSTALL.d/INSTALL.Darwin.txt
|
||||
|
||||
|
||||
perl -MCPAN -e shell
|
||||
# then inside the cpan shell type "o conf init"
|
||||
cpan> o conf init
|
||||
cpan> exit
|
||||
# finally source your modified local bashrc
|
||||
. $HOME/.bashrc
|
||||
|
||||
Run again prerequisites_imapsync
|
||||
|
||||
sh INSTALL.d/prerequisites_imapsync
|
||||
|
||||
Run the "cpan -i" command with the missing Perl modules as arguments.
|
||||
For example it can be:
|
||||
|
||||
cpan -i Authen::NTLM Data::Uniqid File::Copy::Recursive IO::Tee Mail::IMAPClient Unicode::String
|
||||
|
||||
Once you've run the "cpan -i" command, you can rerun "sh prerequisites_imapsync"
|
||||
to verify everything is ok:
|
||||
|
||||
sh prerequisites_imapsync
|
||||
|
||||
When everything is ok the script execution ends with this sentence
|
||||
"All needed modules are already installed"
|
||||
|
||||
Now imapsync should work on your system.
|
||||
|
||||
|
||||
|
165
INSTALL.d/INSTALL.ANY.txt
Normal file
165
INSTALL.d/INSTALL.ANY.txt
Normal file
@ -0,0 +1,165 @@
|
||||
# $Id: INSTALL.ANY.txt,v 1.55 2017/04/18 15:11:29 gilles Exp gilles $
|
||||
#
|
||||
# This is the main INSTALL file for imapsync.
|
||||
# imapsync : IMAP sync and migrate tool.
|
||||
|
||||
INTRODUCTION
|
||||
============
|
||||
|
||||
imapsync works fine under any operating system with Perl and Perl modules (listed below).
|
||||
imapsync.exe works fine standalone under Windows XP, Vista, Seven, 20XX, either 32 or 64bit.
|
||||
|
||||
====================================
|
||||
== Installing imapsync on WINDOWS ==
|
||||
====================================
|
||||
|
||||
Read the file README_Windows.txt
|
||||
Also available at
|
||||
https://imapsync.lamiral.info/README_Windows.txt
|
||||
|
||||
|
||||
=================================
|
||||
== Installing imapsync on Unix ==
|
||||
=================================
|
||||
|
||||
There are specific INSTALL files in the imapsync directory INSTALL.d/
|
||||
also available at https://imapsync.lamiral.info/INSTALL.d/
|
||||
|
||||
- Mac OS X
|
||||
- FreeBSD
|
||||
- CentOS
|
||||
- CPanel
|
||||
- Debian
|
||||
- Ubuntu
|
||||
- AWS EC2
|
||||
|
||||
If you are not on one of these systems then read the section
|
||||
below called "Installing imapsync on other Unixes".
|
||||
|
||||
=====================================
|
||||
== Installing imapsync on Mac OS X ==
|
||||
=====================================
|
||||
|
||||
Easy.
|
||||
Read the file INSTALL.d/INSTALL.Darwin.txt
|
||||
Also available at
|
||||
https://imapsync.lamiral.info/INSTALL.d/INSTALL.Darwin.txt
|
||||
|
||||
=====================================
|
||||
== Installing imapsync on FreeBSD ==
|
||||
=====================================
|
||||
|
||||
Easy.
|
||||
Read the file INSTALL.d/INSTALL.FreeBSD.txt
|
||||
Also available at
|
||||
https://imapsync.lamiral.info/INSTALL.d/INSTALL.FreeBSD.txt
|
||||
|
||||
|
||||
===================================
|
||||
== Installing imapsync on CentOS ==
|
||||
===================================
|
||||
|
||||
Easy.
|
||||
Read the file INSTALL.d/INSTALL.Centos.txt
|
||||
Also available at
|
||||
https://imapsync.lamiral.info/INSTALL.d/INSTALL.Centos.txt
|
||||
|
||||
|
||||
===================================
|
||||
== Installing imapsync on CPanel ==
|
||||
===================================
|
||||
|
||||
Easy.
|
||||
Read the file INSTALL.d/INSTALL.CPanel.txt
|
||||
Also available at
|
||||
https://imapsync.lamiral.info/INSTALL.d/INSTALL.CPanel.txt
|
||||
|
||||
|
||||
==========================================
|
||||
== Installing imapsync on Debian 6 or 7 ==
|
||||
==========================================
|
||||
|
||||
Not so easy.
|
||||
See the file INSTALL.d/INSTALL.Debian.txt
|
||||
Also available at
|
||||
https://imapsync.lamiral.info/INSTALL.d/INSTALL.Debian.txt
|
||||
|
||||
============================================
|
||||
== Installing imapsync on Ubuntu 12 or 14 ==
|
||||
============================================
|
||||
|
||||
Not so easy.
|
||||
See the file INSTALL.d/INSTALL.Ubuntu.txt
|
||||
Also available at
|
||||
https://imapsync.lamiral.info/INSTALL.d/INSTALL.Ubuntu.txt
|
||||
|
||||
==================================
|
||||
= Installing imapsync on AWS EC2 =
|
||||
==================================
|
||||
|
||||
Not so easy.
|
||||
See the file INSTALL.d/INSTALL.AWS_EC2.txt
|
||||
Also available at
|
||||
https://imapsync.lamiral.info/INSTALL.d/INSTALL.AWS_EC2.txt
|
||||
|
||||
|
||||
=========================================
|
||||
== Installing imapsync on other Unixes ==
|
||||
=========================================
|
||||
|
||||
|
||||
Purchase imapsync at
|
||||
https://imapsync.lamiral.info/
|
||||
or get it anywhere.
|
||||
|
||||
You have access to a compressed tarball called imapsync-1.xxx.tgz
|
||||
where 1.xxx is the version number. Untar the tarball where
|
||||
you want:
|
||||
|
||||
cd
|
||||
tar xzvf imapsync-1.xxx.tgz
|
||||
|
||||
Go into the directory imapsync-1.xxx
|
||||
|
||||
cd imapsync-1.xxx
|
||||
|
||||
You can easily detect any missing Perl modules via the
|
||||
script prerequisites_imapsync located in the INSTALL.d directory:
|
||||
|
||||
sh INSTALL.d/prerequisites_imapsync
|
||||
|
||||
or
|
||||
|
||||
cd INSTALL.d/
|
||||
sh prerequisites_imapsync
|
||||
|
||||
You don't need to be root to run the previous command. You have
|
||||
to be root if you want the Perl modules to be available for the
|
||||
whole system, for all users.
|
||||
|
||||
You may be in one of following cases:
|
||||
- you are not root.
|
||||
- you are in a environment where modifying system Perl
|
||||
modules can break other things or where you're not allowed to
|
||||
change the whole system.
|
||||
|
||||
The "make" command is a prerequisite to build some Perl modules.
|
||||
Install make in case it is not already installed.
|
||||
|
||||
Run the "cpanm" command with the missing Perl modules as arguments.
|
||||
For example it can be:
|
||||
|
||||
cpanm Authen::NTLM Data::Uniqid File::Copy::Recursive IO::Tee Mail::IMAPClient Unicode::String
|
||||
|
||||
Once you've run the "cpanm" command, you can rerun "sh prerequisites_imapsync"
|
||||
to verify everything is ok:
|
||||
|
||||
sh prerequisites_imapsync
|
||||
|
||||
When everything is ok the script execution ends with this sentence
|
||||
"All needed modules are already installed"
|
||||
|
||||
Now imapsync should work on your system. To check it run:
|
||||
|
||||
./imapsync --testslive
|
||||
|
57
INSTALL.d/INSTALL.AWS_EC2.txt
Normal file
57
INSTALL.d/INSTALL.AWS_EC2.txt
Normal file
@ -0,0 +1,57 @@
|
||||
#!/bin/cat
|
||||
# $Id: INSTALL.AWS_EC2.txt,v 1.3 2017/04/18 15:06:35 gilles Exp gilles $
|
||||
|
||||
==================================
|
||||
= Installing imapsync on AWS EC2 =
|
||||
==================================
|
||||
|
||||
AWS: Amazon Web Service
|
||||
|
||||
cat /etc/system-release
|
||||
Amazon Linux AMI release 2017.03
|
||||
|
||||
|
||||
sudo yum install \
|
||||
perl-Class-Load-0.20-3.6.amzn1.noarch \
|
||||
perl-IO-Compress-2.061-2.12.amzn1.noarch \
|
||||
perl-Crypt-OpenSSL-RSA-0.28-7.8.amzn1.x86_64 \
|
||||
perl-Data-Dumper-2.145-3.5.amzn1.x86_64 \
|
||||
perl-Dist-CheckConflicts-0.06-2.5.amzn1.noarch \
|
||||
perl-File-Copy-Recursive-0.38-14.8.amzn1.noarch \
|
||||
perl-IO-Socket-INET6-2.69-5.8.amzn1.noarch \
|
||||
perl-IO-Socket-SSL-1.94-3.13.amzn1.noarch \
|
||||
perl-JSON-2.59-2.8.amzn1.noarch \
|
||||
perl-HTML-Parser-3.71-4.7.amzn1.x86_64 \
|
||||
perl-libwww-perl-6.05-2.17.amzn1.noarch \
|
||||
perl-Mail-IMAPClient-3.34-1.2.amzn1.noarch \
|
||||
perl-Module-Implementation-0.06-6.6.amzn1.noarch \
|
||||
perl-Module-Runtime-0.013-4.5.amzn1.noarch \
|
||||
perl-Module-ScanDeps-1.10-3.7.amzn1.noarch \
|
||||
perl-Net-SSLeay-1.65-2.10.amzn1.x86_64 \
|
||||
perl-Package-Stash-0.34-2.6.amzn1.noarch \
|
||||
perl-Package-Stash-XS-0.26-3.7.amzn1.x86_64 \
|
||||
perl-Parse-RecDescent-1.967009-5.13.amzn1.noarch \
|
||||
perl-Readonly-1.03-22.8.amzn1.noarch \
|
||||
perl-Sys-MemInfo-0.91-7.5.amzn1.x86_64 \
|
||||
perl-TermReadKey-2.30-20.9.amzn1.x86_64 \
|
||||
perl-Test-Fatal-0.010-5.5.amzn1.noarch \
|
||||
perl-Test-MockObject-1.20120301-3.8.amzn1.noarch \
|
||||
perl-Test-Simple-0.98-243.6.amzn1.noarch \
|
||||
perl-Test-Pod-1.48-3.9.amzn1.noarch \
|
||||
perl-Test-Requires-0.06-10.6.amzn1.noarch \
|
||||
perl-Try-Tiny-0.12-2.5.amzn1.noarch \
|
||||
perl-Unicode-String-2.09-29.7.amzn1.x86_64 \
|
||||
perl-URI-1.60-9.8.amzn1.noarch \
|
||||
perl-ExtUtils-Embed-1.30-286.38.amzn1.noarch \
|
||||
cpanminus
|
||||
|
||||
sudo cpanm Authen::NTLM Data::Uniqid IO::Tee JSON::WebToken JSON::WebToken::Crypt::RSA Test::Mock::Guard
|
||||
|
||||
wget -N https://imapsync.lamiral.info/imapsync
|
||||
|
||||
chmod +x imapsync
|
||||
|
||||
./imapsync
|
||||
|
||||
./imapsync --testslive
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/cat
|
||||
# $Id: INSTALL.CPanel.txt,v 1.4 2015/09/19 08:55:25 gilles Exp gilles $
|
||||
# $Id: INSTALL.CPanel.txt,v 1.5 2016/11/07 10:40:53 gilles Exp gilles $
|
||||
|
||||
=================================
|
||||
= Installing imapsync on CPanel =
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/cat
|
||||
# $Id: INSTALL.Centos.txt,v 1.5 2016/01/14 20:25:32 gilles Exp gilles $
|
||||
# $Id: INSTALL.Centos.txt,v 1.6 2016/11/07 10:40:53 gilles Exp gilles $
|
||||
|
||||
=================================
|
||||
= Installing imapsync on CentOS =
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/cat
|
||||
# $Id: INSTALL.Darwin.txt,v 1.14 2016/06/22 19:57:00 gilles Exp gilles $
|
||||
# $Id: INSTALL.Darwin.txt,v 1.16 2016/11/07 05:06:34 gilles Exp gilles $
|
||||
|
||||
===================================================
|
||||
= Installing imapsync binary on Darwin / Mac OS X =
|
||||
@ -57,32 +57,49 @@ you have to use:
|
||||
= Installing imapsync script on Darwin / Mac OS X =
|
||||
===================================================
|
||||
|
||||
This part is only for advanced Unix users, or brave ones.
|
||||
This part is only for advanced Unix users, or brave users.
|
||||
|
||||
wget --no-check-certificate -O- http://cpanmin.us | perl - -l ~/perl5 App::cpanminus local::lib
|
||||
eval `perl -I ~/perl5/lib/perl5 -Mlocal::lib`
|
||||
perl -I ~/perl5/lib/perl5 -Mlocal::lib
|
||||
The "make" command is a prerequisite to build some Perl modules.
|
||||
Install make in case it is not already installed.
|
||||
|
||||
echo 'eval `perl -I ~/perl5/lib/perl5 -Mlocal::lib`' >> ~/.profile
|
||||
echo 'export MANPATH=$HOME/perl5/man:$MANPATH' >> ~/.profile
|
||||
cat ~/.profile
|
||||
cpanm CPAN
|
||||
First let us install cpanminus locally in ~/perl5
|
||||
|
||||
curl -L http://imapsync.lamiral.info/INSTALL.d/prerequisites_imapsync > prerequisites_imapsync
|
||||
sh prerequisites_imapsync
|
||||
wget --no-check-certificate -O- http://cpanmin.us | perl - -l ~/perl5 App::cpanminus local::lib
|
||||
|
||||
cpanm Authen::NTLM
|
||||
cpanm File::Copy::Recursive IO::Tee
|
||||
cpanm Mail::IMAPClient
|
||||
cpanm Readonly
|
||||
cpanm Unicode::String
|
||||
Then take this install into account in the current environment
|
||||
|
||||
wget -c http://imapsync.lamiral.info/imapsync
|
||||
./imapsync
|
||||
perl ./imapsync
|
||||
perl ./imapsync --modules
|
||||
cpanm Data::Uniqid
|
||||
cpanm JSON::WebToken
|
||||
eval `perl -I ~/perl5/lib/perl5 -Mlocal::lib`
|
||||
perl -I ~/perl5/lib/perl5 -Mlocal::lib
|
||||
|
||||
If you want to have always this setting in your environment then run the commands
|
||||
|
||||
echo 'eval `perl -I ~/perl5/lib/perl5 -Mlocal::lib`' >> ~/.profile
|
||||
echo 'export MANPATH=$HOME/perl5/man:$MANPATH' >> ~/.profile
|
||||
cat ~/.profile
|
||||
|
||||
Now let's update the standard CPAN Perl module
|
||||
|
||||
cpanm CPAN
|
||||
|
||||
The specific install part for imapsync begins, the script "prerequisites_imapsync"
|
||||
helps to verify what is needed to install on your system
|
||||
|
||||
curl -L http://imapsync.lamiral.info/INSTALL.d/prerequisites_imapsync > prerequisites_imapsync
|
||||
sh prerequisites_imapsync
|
||||
|
||||
cpanm Authen::NTLM
|
||||
cpanm File::Copy::Recursive IO::Tee
|
||||
cpanm Mail::IMAPClient
|
||||
cpanm Readonly
|
||||
cpanm Unicode::String
|
||||
cpanm Data::Uniqid
|
||||
cpanm JSON::WebToken
|
||||
|
||||
We're ready to install and test the latest imapsync
|
||||
|
||||
wget -c http://imapsync.lamiral.info/imapsync
|
||||
./imapsync
|
||||
./imapsync --modules
|
||||
|
||||
You can rerun "sh prerequisites_imapsync"
|
||||
to verify everything is ok:
|
||||
@ -94,6 +111,8 @@ When everything is ok the script execution ends with this sentence
|
||||
|
||||
Now imapsync should work on your system.
|
||||
|
||||
./imapsync --testslive
|
||||
|
||||
=================================================
|
||||
= Building imapsync binary on Darwin / Mac OS X =
|
||||
=================================================
|
||||
|
@ -1,7 +1,110 @@
|
||||
#!/bin/cat
|
||||
# $Id: INSTALL.Debian.txt,v 1.7 2016/06/22 19:58:32 gilles Exp gilles $
|
||||
# $Id: INSTALL.Debian.txt,v 1.15 2017/04/05 02:03:04 gilles Exp gilles $
|
||||
|
||||
There is three install sections in this document,
|
||||
one for Debian 9 Stretch
|
||||
one for Debian 8 Jessie
|
||||
one for Debian 7 Wheezy
|
||||
|
||||
First a call to Debian packagers
|
||||
Why imapsync is not in Debian as a package?
|
||||
Imapsync used to be in Debian from 2005-04-25 (release 1.125) to 2011-01-25 (release 1.315).
|
||||
It could be in Debian nowadays, as always, my last words on this discussion were
|
||||
"Do what you want, I promise I won't complain anymore about the fact imapsync is on Debian or not."
|
||||
https://lists.debian.org/debian-legal/2011/01/msg00058.html
|
||||
The license is now "No limits to do anything with this work and this license".
|
||||
and full dist/ is back to https://imapsync.lamiral.info/dist/
|
||||
Feel free.
|
||||
See also a more detailed story at
|
||||
https://lists.debian.org/debian-user/2016/11/msg00849.html
|
||||
|
||||
|
||||
===========================================
|
||||
= Installing imapsync on Debian 9 Stretch =
|
||||
===========================================
|
||||
|
||||
Here is the command to install imapsync dependencies.
|
||||
You need root priviledge to run it.
|
||||
|
||||
apt install -y \
|
||||
libjson-webtoken-perl \
|
||||
libauthen-ntlm-perl \
|
||||
libcgi-pm-perl \
|
||||
libcrypt-openssl-rsa-perl \
|
||||
libdata-uniqid-perl \
|
||||
libfile-copy-recursive-perl \
|
||||
libio-socket-ssl-perl \
|
||||
libio-tee-perl \
|
||||
libhtml-parser-perl \
|
||||
libjson-webtoken-perl \
|
||||
libmail-imapclient-perl \
|
||||
libparse-recdescent-perl \
|
||||
libmodule-scandeps-perl \
|
||||
libreadonly-perl \
|
||||
libsys-meminfo-perl \
|
||||
libterm-readkey-perl \
|
||||
libtest-mockobject-perl \
|
||||
libtest-pod-perl \
|
||||
libunicode-string-perl \
|
||||
liburi-perl \
|
||||
libwww-perl
|
||||
|
||||
After installing the dependencies, imapsync should be working,
|
||||
go to the section "After installing the dependencies" below.
|
||||
|
||||
|
||||
==========================================
|
||||
= Installing imapsync on Debian 8 Jessie =
|
||||
==========================================
|
||||
|
||||
Here are the commands to install imapsync dependencies.
|
||||
You need root priviledge to run them.
|
||||
|
||||
The first command installs standard Debian packages:
|
||||
apt install \
|
||||
libauthen-ntlm-perl \
|
||||
libcgi-pm-perl \
|
||||
libcrypt-openssl-rsa-perl \
|
||||
libdata-uniqid-perl \
|
||||
libfile-copy-recursive-perl \
|
||||
libio-socket-inet6-perl \
|
||||
libio-socket-ssl-perl \
|
||||
libio-tee-perl \
|
||||
libhtml-parser-perl \
|
||||
libmail-imapclient-perl \
|
||||
libparse-recdescent-perl \
|
||||
libmodule-scandeps-perl \
|
||||
libreadonly-perl \
|
||||
libterm-readkey-perl \
|
||||
libtest-mockobject-perl \
|
||||
libtest-pod-perl \
|
||||
libunicode-string-perl \
|
||||
liburi-perl \
|
||||
libwww-perl \
|
||||
make \
|
||||
cpanminus
|
||||
|
||||
|
||||
The following second command installs "manually" the Perl module Sys::MemInfo
|
||||
because Debian hasn't made it available via a package yet.
|
||||
|
||||
cpanm Sys::MemInfo
|
||||
|
||||
The following optional cpanm command updates Perl module Mail::IMAPClient
|
||||
because it is good to be up to date with that imapsync dependency,
|
||||
but it is not mandatory since Mail::IMAPClient is installed by
|
||||
the Debian package libmail-imapclient-perl:
|
||||
|
||||
cpanm Mail::IMAPClient
|
||||
|
||||
Last, in case you need to use XOAUTH2 authentication you have to install
|
||||
the module JSON::WebToken with the command:
|
||||
|
||||
cpanm JSON::WebToken
|
||||
|
||||
After installing the dependencies, imapsync should be working,
|
||||
go to the section "After installing the dependencies" below.
|
||||
|
||||
There is one section for Debian 7 and one for Debian 6.
|
||||
|
||||
==========================================
|
||||
= Installing imapsync on Debian 7 Wheezy =
|
||||
@ -12,125 +115,92 @@ You need root priviledge to run them.
|
||||
|
||||
The first command installs standard Debian packages:
|
||||
|
||||
apt-get install \
|
||||
libauthen-ntlm-perl \
|
||||
libcrypt-ssleay-perl \
|
||||
apt-get install \
|
||||
libauthen-ntlm-perl \
|
||||
libclass-load-perl \
|
||||
libcrypt-openssl-rsa-perl \
|
||||
libdigest-hmac-perl \
|
||||
libfile-copy-recursive-perl \
|
||||
libio-compress-perl \
|
||||
libio-compress-perl \
|
||||
libio-socket-inet6-perl \
|
||||
libio-socket-ssl-perl \
|
||||
libio-tee-perl \
|
||||
libmail-imapclient-perl \
|
||||
libmodule-implementation-perl \
|
||||
libmodule-runtime-perl \
|
||||
libmodule-scandeps-perl \
|
||||
libnet-ssleay-perl \
|
||||
libpackage-stash-perl \
|
||||
libpackage-stash-xs-perl \
|
||||
libpar-packer-perl \
|
||||
libreadonly-perl \
|
||||
libterm-readkey-perl \
|
||||
libtest-fatal-perl \
|
||||
libtest-pod-perl \
|
||||
libtest-requires-perl \
|
||||
libtest-simple-perl \
|
||||
libunicode-string-perl \
|
||||
liburi-perl \
|
||||
make \
|
||||
cpanminus
|
||||
|
||||
|
||||
The second command installs "manually" the Perl module Data::Uniqid
|
||||
because Debian hasn't made it available via a package yet.
|
||||
It also install manually Perl module Mail::IMAPClient because
|
||||
it is good to be up to date:
|
||||
The following second command installs "manually" the Perl modules
|
||||
Data::Uniqid
|
||||
Sys::MemInfo
|
||||
because Debian hasn't made them available via a package yet.
|
||||
This cpanm command also installs manually Perl module Mail::IMAPClient
|
||||
because it is good to be up to date with that imapsync dependency,
|
||||
but it is not mandatory since Mail::IMAPClient is installed by
|
||||
the Debian package libmail-imapclient-perl:
|
||||
|
||||
cpanm Data::Uniqid Sys::MemInfo
|
||||
|
||||
In case you want to update the Perl module Mail::IMAPClient,
|
||||
a major module for imapsync, but an old March 2012 release 3.31 in Wheezy,
|
||||
the following command updates it "manually":
|
||||
|
||||
cpanm Mail::IMAPClient
|
||||
|
||||
Last, in case you need to use XOAUTH2 authentication you have to install
|
||||
the module JSON::WebToken with the command:
|
||||
|
||||
cpanm JSON::WebToken
|
||||
|
||||
cpanm Data::Uniqid Mail::IMAPClient
|
||||
|
||||
After installing the dependencies, imapsync should be working.
|
||||
|
||||
=====================================
|
||||
= After installing the dependencies =
|
||||
======================================
|
||||
|
||||
You don't have to be root to test and use imapsync.
|
||||
Take the compressed tarball called imapsync-1.xxx.tgz
|
||||
where 1.xxx is the version number.
|
||||
Untar the tarball where you want:
|
||||
|
||||
cd
|
||||
tar xzvf imapsync-1.xxx.tgz
|
||||
Take imapsync either on github or at the upstream site:
|
||||
|
||||
Go into the directory imapsync-1.xxx
|
||||
wget -N https://imapsync.lamiral.info/dist/imapsync
|
||||
|
||||
cd imapsync-1.xxx
|
||||
Add execution permission to the downloaded script:
|
||||
|
||||
A dependencies test that shows also the basic example:
|
||||
chmod +x imapsync
|
||||
|
||||
Check the dependencies and print also the basic example:
|
||||
|
||||
./imapsync
|
||||
|
||||
A live test showing imapsync job:
|
||||
Perform a live test showing imapsync job:
|
||||
|
||||
./imapsync --testslive
|
||||
|
||||
Now the install command (need root priviledges again):
|
||||
Now install imapsync on the system (need root priviledges again):
|
||||
|
||||
cp imapsync /usr/bin/
|
||||
|
||||
That's finished for the installation part.
|
||||
You can use imapsync.
|
||||
You can now use imapsync without knowing where it is located
|
||||
on the system:
|
||||
|
||||
imapsync
|
||||
|
||||
Now go to read http://imapsync.lamiral.info/#doc
|
||||
start with the tutorial.
|
||||
|
||||
===========================================
|
||||
= Installing imapsync on Debian 6 Squeeze =
|
||||
===========================================
|
||||
|
||||
|
||||
apt-get install \
|
||||
libcrypt-ssleay-perl \
|
||||
libdigest-hmac-perl \
|
||||
libfile-copy-recursive-perl \
|
||||
libio-compress-perl \
|
||||
libio-socket-inet6-perl \
|
||||
libio-socket-ssl-perl \
|
||||
libio-tee-perl \
|
||||
libmodule-scandeps-perl \
|
||||
libnet-ssleay-perl \
|
||||
libpar-packer-perl \
|
||||
libreadonly-perl \
|
||||
libterm-readkey-perl \
|
||||
libtest-pod-perl \
|
||||
libtest-simple-perl \
|
||||
libunicode-string-perl \
|
||||
liburi-perl
|
||||
|
||||
|
||||
perl -MCPAN -e "install Data::Uniqid"
|
||||
perl -MCPAN -e "install Authen::NTLM"
|
||||
perl -MCPAN -e "install Mail::IMAPClient"
|
||||
|
||||
The Perl module Mail::IMAPClient is good to be recent
|
||||
and installed manually.
|
||||
|
||||
After installing the dependencies, imapsync should be working.
|
||||
|
||||
You don't have to be root to test and use imapsync.
|
||||
Take the compressed tarball called imapsync-1.xxx.tgz
|
||||
where 1.xxx is the version number.
|
||||
Untar the tarball where you want:
|
||||
|
||||
cd
|
||||
tar xzvf imapsync-1.xxx.tgz
|
||||
|
||||
Go into the directory imapsync-1.xxx
|
||||
|
||||
cd imapsync-1.xxx
|
||||
|
||||
A dependencies test that shows also the basic example:
|
||||
|
||||
./imapsync
|
||||
|
||||
A live test showing imapsync job:
|
||||
|
||||
./imapsync --testslive
|
||||
|
||||
Now the install command (need root priviledges again):
|
||||
|
||||
cp imapsync /usr/bin/
|
||||
|
||||
That's finished for the installation part.
|
||||
You can use imapsync.
|
||||
|
||||
Now go to read http://imapsync.lamiral.info/#doc
|
||||
start with the tutorial.
|
||||
|
17
INSTALL.d/INSTALL.Docker.txt
Normal file
17
INSTALL.d/INSTALL.Docker.txt
Normal file
@ -0,0 +1,17 @@
|
||||
#!/bin/cat
|
||||
# $Id: INSTALL.Docker.txt,v 1.1 2017/09/03 03:23:54 gilles Exp gilles $
|
||||
|
||||
=======================================
|
||||
= Installing imapsync docker image
|
||||
=======================================
|
||||
|
||||
== Installation ==
|
||||
|
||||
docker pull gilleslamiral/imapsync
|
||||
|
||||
== Usage ==
|
||||
|
||||
docker run gilleslamiral/imapsync imapsync <usual imapsync arguments>
|
||||
|
||||
|
||||
|
51
INSTALL.d/INSTALL.Docker_build.txt
Normal file
51
INSTALL.d/INSTALL.Docker_build.txt
Normal file
@ -0,0 +1,51 @@
|
||||
#!/bin/cat
|
||||
# $Id: INSTALL.Docker_build.txt,v 1.5 2017/04/07 08:45:20 gilles Exp gilles $
|
||||
|
||||
=================================================
|
||||
= Building an imapsync docker image from Debian =
|
||||
=================================================
|
||||
|
||||
|
||||
# Dockerfile for building a docker imapsync image
|
||||
|
||||
FROM debian:stretch
|
||||
|
||||
LABEL maintainer "gilles.lamiral@laposte.net"
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y \
|
||||
libjson-webtoken-perl \
|
||||
libauthen-ntlm-perl \
|
||||
libcgi-pm-perl \
|
||||
libcrypt-openssl-rsa-perl \
|
||||
libdata-uniqid-perl \
|
||||
libfile-copy-recursive-perl \
|
||||
libio-socket-ssl-perl \
|
||||
libio-tee-perl \
|
||||
libhtml-parser-perl \
|
||||
libjson-webtoken-perl \
|
||||
libmail-imapclient-perl \
|
||||
libparse-recdescent-perl \
|
||||
libmodule-scandeps-perl \
|
||||
libpar-packer-perl \
|
||||
libreadonly-perl \
|
||||
libsys-meminfo-perl \
|
||||
libterm-readkey-perl \
|
||||
libtest-mockobject-perl \
|
||||
libtest-pod-perl \
|
||||
libunicode-string-perl \
|
||||
liburi-perl \
|
||||
libwww-perl \
|
||||
procps \
|
||||
wget \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN wget -N https://imapsync.lamiral.info/imapsync \
|
||||
&& cp imapsync /usr/bin/imapsync \
|
||||
&& chmod +x /usr/bin/imapsync
|
||||
|
||||
USER nobody
|
||||
|
||||
CMD ["/usr/bin/imapsync"]
|
||||
|
||||
# End of Dockerfile
|
@ -1,5 +1,5 @@
|
||||
#!/bin/cat
|
||||
# $Id: INSTALL.FreeBSD.txt,v 1.6 2015/09/19 08:55:25 gilles Exp gilles $
|
||||
# $Id: INSTALL.FreeBSD.txt,v 1.7 2016/11/07 10:40:53 gilles Exp gilles $
|
||||
|
||||
==================================
|
||||
= Installing imapsync on FreeBSD =
|
||||
|
70
INSTALL.d/INSTALL.OnlineUI.txt
Normal file
70
INSTALL.d/INSTALL.OnlineUI.txt
Normal file
@ -0,0 +1,70 @@
|
||||
#!/bin/cat
|
||||
# $Id: INSTALL.OnlineUI.txt,v 1.8 2017/09/01 22:50:06 gilles Exp gilles $
|
||||
|
||||
==============================
|
||||
= Installing imapsync online =
|
||||
==============================
|
||||
|
||||
Please consider this as relatively new and experimental.
|
||||
I add I'm begining to be confident with /X since the /X service
|
||||
is up and running quite well since january 2017.
|
||||
|
||||
You have to be a little familiar with what is a CGI script
|
||||
and how to activate it on an Apache (or any other) HTTP server.
|
||||
|
||||
The web visual user interface frontend is the file
|
||||
https://imapsync.lamiral.info/X/imapsync_form.html
|
||||
You can do a "view source" to see it as it is written,
|
||||
and a "save" to get it locally.
|
||||
|
||||
This imapsync_form.html file in action calls the CGI location
|
||||
/cgi-bin/imapsync
|
||||
which has to be imapsync itself.
|
||||
|
||||
The very latest and relatively stable imapsync is at
|
||||
https://imapsync.lamiral.info/imapsync
|
||||
It is the program file used verbatim for the service given at
|
||||
https://imapsync.lamiral.info/X/
|
||||
|
||||
So copy both imapsync_form.html and imapsync on a HTTP server
|
||||
allowing CGIs and you'll have your own imapsync visual interface.
|
||||
|
||||
|
||||
Example on a Debian server with Apache:
|
||||
|
||||
Imapsync place on the server disk:
|
||||
/usr/lib/cgi-bin/imapsync
|
||||
|
||||
This classical /cgi-bin directory is configured in Apache
|
||||
configuration file
|
||||
/etc/apache2/sites-available/default-ssl
|
||||
or
|
||||
/etc/apache2/sites-available/default
|
||||
|
||||
It contains somewhere (maybe in comments for now,
|
||||
with some # characters to make them ignored):
|
||||
|
||||
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
|
||||
<Directory "/usr/lib/cgi-bin">
|
||||
AllowOverride None
|
||||
Options +ExecCGI -MultiViews
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
</Directory>
|
||||
|
||||
The UI frontend file place on the server disk is
|
||||
/var/www/X/imapsync_form.html
|
||||
but it can be placed it anywhere on disk, the important
|
||||
thing is that it has to be served by the web server.
|
||||
|
||||
The imapsync working directory in cgi mode is
|
||||
/var/tmp/imapsync_cgi/
|
||||
it is not configurable unless changing it in
|
||||
imapsync directly, it is hardcoded in imapsync.
|
||||
In this directory will go the log files and
|
||||
the pid files.
|
||||
|
||||
Use at least CGI.pm release 4.08 (2014-10-18)
|
||||
to avoid the bug "Undefined subroutine CGI::multi_param"
|
||||
|
||||
|
@ -1,43 +1,54 @@
|
||||
#!/bin/cat
|
||||
# $Id: INSTALL.Ubuntu.txt,v 1.7 2016/06/22 19:58:32 gilles Exp gilles $
|
||||
# $Id: INSTALL.Ubuntu.txt,v 1.10 2017/03/30 11:23:37 gilles Exp gilles $
|
||||
|
||||
=================================================
|
||||
= Installing imapsync on Ubuntu 12.04 or higher =
|
||||
= Installing imapsync on Ubuntu 16.04 or higher =
|
||||
=================================================
|
||||
|
||||
Here are the two commands to install imapsync dependencies.
|
||||
You need root priviledge to run them.
|
||||
|
||||
The first command installs standard Ubuntu packages:
|
||||
Here is the command to install imapsync dependencies,
|
||||
you need root privilege to run them.
|
||||
|
||||
This command installs standard Ubuntu packages:
|
||||
|
||||
sudo apt-get install \
|
||||
libauthen-ntlm-perl \
|
||||
libcrypt-ssleay-perl \
|
||||
libdigest-hmac-perl \
|
||||
libauthen-ntlm-perl \
|
||||
libclass-load-perl \
|
||||
libcrypt-ssleay-perl \
|
||||
libdata-uniqid-perl \
|
||||
libdigest-hmac-perl \
|
||||
libdist-checkconflicts-perl \
|
||||
libfile-copy-recursive-perl \
|
||||
libio-compress-perl \
|
||||
libio-compress-perl \
|
||||
libio-socket-inet6-perl \
|
||||
libio-socket-ssl-perl \
|
||||
libio-tee-perl \
|
||||
libio-socket-ssl-perl \
|
||||
libio-tee-perl \
|
||||
libmail-imapclient-perl \
|
||||
libmodule-scandeps-perl \
|
||||
libnet-ssleay-perl \
|
||||
libpar-packer-perl \
|
||||
libreadonly-perl \
|
||||
libterm-readkey-perl \
|
||||
libtest-pod-perl \
|
||||
libpar-packer-perl \
|
||||
libreadonly-perl \
|
||||
libsys-meminfo-perl \
|
||||
libterm-readkey-perl \
|
||||
libtest-fatal-perl \
|
||||
libtest-mock-guard-perl \
|
||||
libtest-pod-perl \
|
||||
libtest-requires-perl \
|
||||
libtest-simple-perl \
|
||||
libunicode-string-perl \
|
||||
liburi-perl \
|
||||
libtest-mockobject-perl \
|
||||
libunicode-string-perl \
|
||||
liburi-perl \
|
||||
make \
|
||||
cpanminus
|
||||
|
||||
The second command installs "manually" the Perl module Data::Uniqid
|
||||
because Debian hasn't made it available via a package yet.
|
||||
It also install manually Perl module Mail::IMAPClient because
|
||||
it is good to be up to date:
|
||||
In case you want to update the Perl module
|
||||
Mail::IMAPClient, a major module for imapsync,
|
||||
the following command installs it "manually":
|
||||
|
||||
sudo cpanm Data::Uniqid Mail::IMAPClient
|
||||
sudo cpanm Mail::IMAPClient
|
||||
|
||||
In case you need to use XOAUTH2 authentication you have to install
|
||||
the module JSON::WebToken with the command:
|
||||
|
||||
sudo cpanm JSON::WebToken
|
||||
|
||||
After installing the dependencies, imapsync should be working.
|
||||
|
||||
|
@ -1,36 +1,54 @@
|
||||
#!/bin/sh
|
||||
|
||||
# $Id: prerequisites_imapsync,v 1.16 2016/08/16 16:25:01 gilles Exp gilles $
|
||||
# $Id: prerequisites_imapsync,v 1.21 2017/08/31 02:12:36 gilles Exp gilles $
|
||||
|
||||
MODULES_MANDATORY='
|
||||
Authen::NTLM
|
||||
Class::Load
|
||||
Compress::Zlib
|
||||
Crypt::OpenSSL::RSA
|
||||
Data::Dumper
|
||||
Data::Uniqid
|
||||
Digest::HMAC_MD5
|
||||
Digest::HMAC
|
||||
Digest::HMAC_MD5
|
||||
Digest::MD5
|
||||
Dist::CheckConflicts
|
||||
Encode::Byte
|
||||
File::Copy::Recursive
|
||||
IO::Socket::INET
|
||||
IO::Socket::INET6
|
||||
IO::Socket::SSL
|
||||
IO::Tee
|
||||
JSON
|
||||
JSON::WebToken
|
||||
JSON::WebToken::Crypt::RSA
|
||||
HTML::Entities
|
||||
LWP::UserAgent
|
||||
Mail::IMAPClient
|
||||
Module::Implementation
|
||||
Module::Runtime
|
||||
Module::ScanDeps
|
||||
Net::Ping
|
||||
Net::SSLeay
|
||||
Package::Stash
|
||||
Package::Stash::XS
|
||||
PAR::Packer
|
||||
Parse::RecDescent
|
||||
Pod::Usage
|
||||
Readonly
|
||||
Sys::MemInfo
|
||||
Term::ReadKey
|
||||
Test::Fatal
|
||||
Test::Mock::Guard
|
||||
Test::MockObject
|
||||
Test::More
|
||||
Test::Pod
|
||||
Test::Requires
|
||||
Try::Tiny
|
||||
Unicode::String
|
||||
URI::Escape
|
||||
'
|
||||
|
||||
MODULES_DEVEL='
|
||||
Module::ScanDeps
|
||||
PAR::Packer
|
||||
'
|
||||
|
||||
test_perl() {
|
||||
# First we need perl
|
||||
@ -45,6 +63,21 @@ test_perl() {
|
||||
fi
|
||||
}
|
||||
|
||||
test_make() {
|
||||
# Second we need make to build some Perl modules
|
||||
|
||||
if make -v > /dev/null 2>&1 ; then
|
||||
make_version=`make -v |head -1`
|
||||
echo Ok: Found make $make_version
|
||||
return 0
|
||||
else
|
||||
echo Failure: make is not here. You have to install the make command.
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
test_module() {
|
||||
test -n $1 || return
|
||||
@ -102,7 +135,7 @@ search_modules_yum() {
|
||||
for M in "$@" ; do
|
||||
echo "==== Searching rpm package name for $M"
|
||||
F=`echo $M|tr -s ":" "/"`.pm
|
||||
#echo yum -q whatprovides "*/$F"
|
||||
echo yum -q whatprovides "*/$F"
|
||||
echo
|
||||
yum -q whatprovides "*/$F"
|
||||
echo
|
||||
@ -147,6 +180,7 @@ test_unix() {
|
||||
test_unix
|
||||
#exit
|
||||
test_perl || exit
|
||||
test_make || exit
|
||||
test_mandatory_modules
|
||||
list_to_install
|
||||
EXIT=$?
|
||||
|
174
Makefile
174
Makefile
@ -1,5 +1,5 @@
|
||||
|
||||
# $Id: Makefile,v 1.239 2016/08/19 14:17:26 gilles Exp gilles $
|
||||
# $Id: Makefile,v 1.257 2017/09/11 11:11:18 gilles Exp gilles $
|
||||
|
||||
.PHONY: help usage all doc
|
||||
|
||||
@ -17,10 +17,12 @@ usage:
|
||||
@echo "make test_quick # few tests verbosely"
|
||||
@echo "make W/test.bat # run --tests and W/test.bat on win32"
|
||||
@echo "make W/test_tests.bat # run --tests on win32"
|
||||
@echo "make W/test_testsdebug.bat # run --testsdebug 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_reg.bat # run W/test_reg.bat on win32"
|
||||
@echo "make W/test_exe.bat # run W/test_exe.bat on win32"
|
||||
@echo "make W/test_exe_tests.bat # run W/test_exe_tests.bat on win32"
|
||||
@echo "make W/test_exe_2.bat # run W/test_exe_2.bat on win32"
|
||||
@echo "make examples/sync_loop_windows.bat # run examples/sync_loop_windows.bat on win32"
|
||||
|
||||
@ -30,7 +32,9 @@ usage:
|
||||
@echo "make upload_tests # upload tests.sh"
|
||||
@echo "make upload_index"
|
||||
@echo "make upload_FAQ # upload FAQs and documentation"
|
||||
@echo "make upload_X # upload online UI"
|
||||
@echo "make upload_latest # upload latest imapsync and binaries (dev)"
|
||||
@echo "make upload_cgi # upload latest imapsync"
|
||||
@echo "make valid_index # check index.shtml for good syntax"
|
||||
@echo "make upload_ks"
|
||||
@echo "make imapsync.exe"
|
||||
@ -39,10 +43,14 @@ usage:
|
||||
@echo "make win # build win binary"
|
||||
@echo "make lin # build linux binary"
|
||||
@echo "make publish"
|
||||
@echo "make perlcritic"
|
||||
@echo "make crit # run perlcritic on imapsync"
|
||||
@echo "make prereq # Generates W/prereq.*"
|
||||
@echo "make cl # Check links of index.shtml"
|
||||
@echo "make cle # Check links of S/*.shtml"
|
||||
@echo "make cle # Check links of S/*.shtml"
|
||||
@echo "make mactestsdebug # run ./imapsync --testsdebug on Mac"
|
||||
@echo "make mactests # run ./imapsync --tests on Mac"
|
||||
@echo "make ks2testsdebug # run ./imapsync --testsdebug on ks2"
|
||||
@echo "make ks2tests # run ./imapsync --tests on ks2"
|
||||
|
||||
|
||||
PREFIX ?= /usr
|
||||
@ -55,13 +63,17 @@ VERSION_PREVIOUS=$(shell perl -I$(IMAPClient) ./dist/imapsync --version 2>/dev/n
|
||||
VERSION_EXE=$(shell cat ./VERSION_EXE)
|
||||
|
||||
HELLO=$(shell date;uname -a)
|
||||
IMAPClient_3xx=./W/Mail-IMAPClient-3.38/lib
|
||||
IMAPClient_3xx=./W/Mail-IMAPClient-3.39/lib
|
||||
IMAPClient=$(IMAPClient_3xx)
|
||||
|
||||
HOSTNAME = $(shell hostname -s)
|
||||
ARCH = $(shell uname -m)
|
||||
KERNEL = $(shell uname -s)
|
||||
BIN_NAME = imapsync_bin_$(KERNEL)_$(ARCH)
|
||||
DISTRO_NAME = $(shell lsb_release -i -s || echo Unknown)
|
||||
DISTRO_RELEASE = $(shell lsb_release -r -s || echo 0.0)
|
||||
DISTRO_CODE = $(shell lsb_release -c -s || echo Unknown)
|
||||
DISTRO = $(DISTRO_NAME)_$(DISTRO_RELEASE)_$(DISTRO_CODE)
|
||||
|
||||
hello:
|
||||
@echo "$(VERSION)"
|
||||
@ -70,6 +82,7 @@ hello:
|
||||
@echo "$(ARCH)"
|
||||
@echo "$(KERNEL)"
|
||||
@echo "$(BIN_NAME)"
|
||||
@echo "$(DISTRO)"
|
||||
|
||||
|
||||
all: doc VERSION biz prereq allcritic bin VERSION_EXE
|
||||
@ -82,12 +95,10 @@ ChangeLog: imapsync
|
||||
rlog imapsync > ChangeLog
|
||||
|
||||
README: imapsync
|
||||
perldoc -t imapsync > README
|
||||
|
||||
OPTIONS: imapsync
|
||||
perl -I./$(IMAPClient) ./imapsync --help > ./OPTIONS
|
||||
pod2text --loose imapsync > README
|
||||
|
||||
VERSION: imapsync
|
||||
rcsdiff imapsync
|
||||
perl -I./$(IMAPClient) ./imapsync --version > ./VERSION
|
||||
touch -r ./imapsync ./VERSION
|
||||
|
||||
@ -99,21 +110,34 @@ VERSION_EXE: imapsync
|
||||
|
||||
doc/GOOD_PRACTICES.html: doc/GOOD_PRACTICES.t2t
|
||||
txt2tags -i doc/GOOD_PRACTICES.t2t -t html --toc -o doc/GOOD_PRACTICES.html
|
||||
./W/tools/validate_html4 doc/GOOD_PRACTICES.html
|
||||
./W/tools/validate doc/GOOD_PRACTICES.html
|
||||
|
||||
|
||||
doc/TUTORIAL_Unix.html: doc/TUTORIAL_Unix.t2t
|
||||
txt2tags -i doc/TUTORIAL_Unix.t2t -t html --toc -o doc/TUTORIAL_Unix.html
|
||||
./W/tools/validate_html4 doc/TUTORIAL_Unix.html
|
||||
./W/tools/validate doc/TUTORIAL_Unix.html
|
||||
|
||||
doc: README OPTIONS ChangeLog doc/TUTORIAL_Unix.html doc/GOOD_PRACTICES.html W/imapsync.1
|
||||
|
||||
.PHONY: clean clean_tilde clean_test doc clean_log clean_bak
|
||||
doc: README ChangeLog doc/TUTORIAL_Unix.html doc/GOOD_PRACTICES.html W/imapsync.1
|
||||
|
||||
clean: clean_tilde clean_man clean_log clean_bak
|
||||
.PHONY: clean clean_tilde clean_test doc clean_log clean_bak clean_permissions
|
||||
|
||||
clean: clean_tilde clean_man clean_log clean_bak clean_permissions
|
||||
|
||||
clean_permissions:
|
||||
chmod a-x Makefile FAQ.d/FAQ.*.txt README_Windows.txt
|
||||
chmod a-x INSTALL.d/INSTALL.*.txt
|
||||
chmod a-x X/progress.html X/imapsync_form.html
|
||||
chmod a-x S/*.shtml S/*.html
|
||||
chmod a-x doc/*.t2t dist/*.txt
|
||||
|
||||
clean_test:
|
||||
rm -f .test_3xx
|
||||
|
||||
clean_tilde:
|
||||
rm -f *~ W/*~ FAQ.d/*~ S/*~ INSTALL.d/*~
|
||||
rm -f *~ W/*~ FAQ.d/*~ S/*~ INSTALL.d/*~ examples/*~
|
||||
|
||||
clean_log:
|
||||
rm -f LOG_imapsync/*.txt
|
||||
@ -130,7 +154,6 @@ clean_man:
|
||||
rm -f imapsync.1
|
||||
|
||||
W/imapsync.1: imapsync
|
||||
# pod2man < /dev/null
|
||||
pod2man imapsync > W/imapsync.1
|
||||
|
||||
install: testp W/imapsync.1
|
||||
@ -149,18 +172,24 @@ ci: cidone
|
||||
|
||||
cidone:
|
||||
rcsdiff W/*.bat W/*.sh W/*.out W/*.txt W/*.htaccess
|
||||
rcsdiff S/*.txt S/*.shtml S/*.html
|
||||
rcsdiff doc/*.t2t
|
||||
rcsdiff INSTALL.d/*.txt INSTALL.d/prerequisites_imapsync
|
||||
rcsdiff FAQ.d/*.txt
|
||||
rcsdiff examples/*.sh examples/*.bat examples/*.txt
|
||||
rcsdiff RCS/*
|
||||
rcsdiff W/tools/backup_old_dist W/tools/gen_README_dist W/tools/validate_html4 W/tools/validate_xml_html5 W/tools/fix_email_for_exchange.py
|
||||
rcsdiff S/*.txt S/*.shtml S/*.html
|
||||
|
||||
###############
|
||||
# Local goals
|
||||
###############
|
||||
|
||||
.PHONY: prereq test tests testp testf test3xx testv3 perlcritic allcritic compok
|
||||
.PHONY: prereq test tests unitests testp testf test3xx testv3 perlcritic allcritic crit compok dev
|
||||
|
||||
dev: test crit bin
|
||||
|
||||
docker:
|
||||
ssh ks3 'cd docker/imapsync && . memo'
|
||||
|
||||
compok: W/.compok
|
||||
|
||||
@ -169,33 +198,38 @@ W/.compok: imapsync
|
||||
perl -c imapsync
|
||||
touch W/.compok
|
||||
|
||||
prereq: W/prereq.scandeps
|
||||
prereq: W/prereq.scandeps.$(DISTRO).txt
|
||||
|
||||
W/prereq.scandeps: INSTALL.d/prerequisites_imapsync imapsync
|
||||
scandeps -c -x imapsync | tee W/prereq.scandeps
|
||||
rcsdiff W/prereq.scandeps || { echo 'rcsdiff detected a diff' | ci -l W/prereq.scandeps ; }
|
||||
./INSTALL.d/prerequisites_imapsync | tee W/prereq.`lsb_release -i -s || echo Unknown`
|
||||
W/prereq.scandeps.$(DISTRO).txt: INSTALL.d/prerequisites_imapsync imapsync
|
||||
scandeps -c -x imapsync | tee W/prereq.scandeps.$(DISTRO).txt
|
||||
rcsdiff W/prereq.scandeps.$(DISTRO).txt || { echo 'rcsdiff detected a diff' | ci -l W/prereq.scandeps.$(DISTRO).txt ; }
|
||||
./INSTALL.d/prerequisites_imapsync | tee W/prereq.$(DISTRO).txt
|
||||
|
||||
|
||||
crit: allcritic
|
||||
|
||||
perlcritic: W/perlcritic_3.out W/perlcritic_2.out
|
||||
|
||||
allcritic: W/perlcritic_4.out W/perlcritic_3.out W/perlcritic_2.out W/perlcritic_1.out
|
||||
|
||||
W/perlcritic_1.out: imapsync W/.compok
|
||||
perlcritic --statistics -1 imapsync > W/perlcritic_1.out || :
|
||||
perlcritic --statistics -1 imapsync > W/perlcritic_1.out.tmp || :
|
||||
mv W/perlcritic_1.out.tmp W/perlcritic_1.out
|
||||
echo | ci -l W/perlcritic_1.out
|
||||
|
||||
W/perlcritic_2.out: imapsync W/.compok
|
||||
perlcritic --statistics -2 imapsync > W/perlcritic_2.out || :
|
||||
perlcritic --statistics -2 imapsync > W/perlcritic_2.out.tmp || :
|
||||
mv W/perlcritic_2.out.tmp W/perlcritic_2.out
|
||||
echo | ci -l W/perlcritic_2.out
|
||||
|
||||
W/perlcritic_3.out: imapsync W/.compok
|
||||
perlcritic --statistics -3 imapsync > W/perlcritic_3.out || :
|
||||
perlcritic --statistics -3 imapsync > W/perlcritic_3.out.tmp || :
|
||||
mv W/perlcritic_3.out.tmp W/perlcritic_3.out
|
||||
echo | ci -l W/perlcritic_3.out
|
||||
|
||||
W/perlcritic_4.out: imapsync W/.compok
|
||||
perlcritic --statistics -4 imapsync > W/perlcritic_4.out || :
|
||||
perlcritic --statistics -4 imapsync > W/perlcritic_4.out.tmp || :
|
||||
mv W/perlcritic_4.out.tmp W/perlcritic_4.out
|
||||
echo | ci -l W/perlcritic_4.out
|
||||
|
||||
|
||||
@ -215,6 +249,9 @@ test: .test_3xx
|
||||
|
||||
tests: test
|
||||
|
||||
unitests:
|
||||
perl -I./$(IMAPClient_3xx) ./imapsync --tests
|
||||
|
||||
# .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
|
||||
@ -302,6 +339,12 @@ W/test_exe.bat:
|
||||
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/test_exe.bat'
|
||||
./W/check_winerr test_exe.bat
|
||||
|
||||
W/test_exe_tests.bat:
|
||||
unix2dos W/test_exe_tests.bat
|
||||
scp W/test_exe_tests.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/'
|
||||
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/test_exe_tests.bat'
|
||||
./W/check_winerr test_exe_tests.bat
|
||||
|
||||
W/build_exe.bat:
|
||||
unix2dos W/build_exe.bat
|
||||
scp W/build_exe.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/'
|
||||
@ -333,6 +376,11 @@ W/install_module_one.bat:
|
||||
scp W/install_module_one.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/'
|
||||
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/install_module_one.bat'
|
||||
|
||||
W/uninstall_module_one.bat:
|
||||
unix2dos W/uninstall_module_one.bat
|
||||
scp W/uninstall_module_one.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/'
|
||||
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/uninstall_module_one.bat'
|
||||
|
||||
imapsync.exe: imapsync
|
||||
rcsdiff imapsync
|
||||
ssh Admin@c 'perl -V'
|
||||
@ -365,7 +413,7 @@ zip: dosify_bat
|
||||
mkdir -p ../prepa_zip/imapsync_$(VERSION_EXE)/FAQ.d/ ../prepa_zip/imapsync_$(VERSION_EXE)/Cook/
|
||||
cp -av examples/imapsync_example.bat examples/sync_loop_windows.bat examples/file.txt ../prepa_zip/imapsync_$(VERSION_EXE)/
|
||||
cp -av W/build_exe.bat W/install_modules.bat W/test_cook_exe.bat W/test_cook_src.bat imapsync ../prepa_zip/imapsync_$(VERSION_EXE)/Cook/
|
||||
for f in FAQ README ; do cp -av $$f ../prepa_zip/imapsync_$(VERSION_EXE)/$$f.txt ; done
|
||||
for f in README ; do cp -av $$f ../prepa_zip/imapsync_$(VERSION_EXE)/$$f.txt ; done
|
||||
cp -av FAQ.d/*.txt ../prepa_zip/imapsync_$(VERSION_EXE)/FAQ.d/
|
||||
cp -av imapsync.exe README_Windows.txt ../prepa_zip/imapsync_$(VERSION_EXE)/
|
||||
unix2dos ../prepa_zip/imapsync_$(VERSION_EXE)/*.txt
|
||||
@ -386,32 +434,43 @@ imapsync_bin_Darwin: imapsync W/build_mac.sh INSTALL.d/prerequisites_imapsync
|
||||
ssh -p 995 gilleslamira@gate.polarhome.com 'sh build_mac.sh'
|
||||
rsync -P -e 'ssh -p 995' gilleslamira@gate.polarhome.com:imapsync_bin_Darwin .
|
||||
|
||||
mactests:
|
||||
rsync -p -e 'ssh -p 995' imapsync gilleslamira@gate.polarhome.com:
|
||||
ssh -p 995 gilleslamira@gate.polarhome.com '. .bash_profile; perl imapsync --tests'
|
||||
|
||||
mactestsdebug:
|
||||
rsync -p -e 'ssh -p 995' imapsync gilleslamira@gate.polarhome.com:
|
||||
ssh -p 995 gilleslamira@gate.polarhome.com '. .bash_profile; perl imapsync --testsdebug --debug'
|
||||
|
||||
bin: lin mac win
|
||||
|
||||
lin: $(BIN_NAME)
|
||||
|
||||
win: imapsync.exe
|
||||
|
||||
|
||||
|
||||
$(BIN_NAME): imapsync
|
||||
rcsdiff imapsync
|
||||
{ pp -o $(BIN_NAME) -I $(IMAPClient_3xx) \
|
||||
-M Mail::IMAPClient -M IO::Socket -M IO::Socket::SSL \
|
||||
-M Mail::IMAPClient \
|
||||
-M Net::SSLeay -M IO::Socket -M IO::Socket::INET6 -M IO::Socket::SSL \
|
||||
-M Digest::MD5 -M Digest::HMAC_MD5 -M Term::ReadKey \
|
||||
-M Authen::NTLM \
|
||||
-M Authen::NTLM -M HTML::Entities -M JSON::WebToken \
|
||||
imapsync ; \
|
||||
} || :
|
||||
./$(BIN_NAME)
|
||||
./$(BIN_NAME) --tests
|
||||
./$(BIN_NAME) --testslive
|
||||
./$(BIN_NAME) --justbanner
|
||||
|
||||
|
||||
|
||||
lfo: upload_lfo
|
||||
|
||||
.PHONY: tarball
|
||||
|
||||
tarball: ../prepa_dist/$(DIST_FILE)
|
||||
|
||||
|
||||
|
||||
../prepa_dist/$(DIST_FILE): imapsync
|
||||
tarball:
|
||||
echo making tarball ../prepa_dist/$(DIST_FILE)
|
||||
rcsdiff RCS/*
|
||||
cd W && rcsdiff RCS/*
|
||||
@ -428,7 +487,7 @@ tarball: ../prepa_dist/$(DIST_FILE)
|
||||
|
||||
DIST_PATH := ./dist/
|
||||
|
||||
dist: cidone test clean all perlcritic dist_prepa dist_zip README_dist.txt
|
||||
dist: cidone test clean all perlcritic dist_prepa dist_zip README_dist
|
||||
|
||||
|
||||
md5:
|
||||
@ -437,17 +496,17 @@ md5:
|
||||
sha:
|
||||
cd $(DIST_PATH)/ && sha512sum *
|
||||
|
||||
.PHONY: moveoldrelease
|
||||
.PHONY: moveoldrelease ks2testsdebug ks2tests README_dist
|
||||
|
||||
moveoldrelease:
|
||||
ls -dl dist/imapsync dist/imapsync-$(VERSION_PREVIOUS).tgz dist/imapsync_$(VERSION_PREVIOUS).zip
|
||||
test -d dist/old_releases/$(VERSION_PREVIOUS) || mkdir dist/old_releases/$(VERSION_PREVIOUS) && cd dist/old_releases/$(VERSION_PREVIOUS)
|
||||
mv -vf dist/imapsync dist/imapsync-$(VERSION_PREVIOUS).tgz dist/imapsync_$(VERSION_PREVIOUS).zip dist/old_releases/$(VERSION_PREVIOUS)
|
||||
./W/tools/backup_old_dist
|
||||
|
||||
|
||||
dist_prepa: tarball moveoldrelease
|
||||
ln -f ../prepa_dist/$(DIST_FILE) $(DIST_PATH)/
|
||||
rcsdiff imapsync
|
||||
cp -a ../prepa_dist/$(DIST_NAME)/imapsync $(DIST_PATH)/
|
||||
cp -a ../prepa_dist/$(DIST_NAME)/imapsync_bin_Darwin $(DIST_PATH)/
|
||||
#cd $(DIST_PATH)/ && md5sum $(DIST_FILE) > $(DIST_FILE).md5.txt
|
||||
#cd $(DIST_PATH)/ && md5sum -c $(DIST_FILE).md5.txt
|
||||
ls -l $(DIST_PATH)/
|
||||
@ -456,9 +515,9 @@ dist_prepa: tarball moveoldrelease
|
||||
dist_zip: zip
|
||||
cp -a ../prepa_zip/imapsync_$(VERSION_EXE).zip $(DIST_PATH)/
|
||||
|
||||
README_dist.txt:
|
||||
sh W/tools/gen_README_dist > $(DIST_PATH)/README_dist.txt
|
||||
unix2dos $(DIST_PATH)/README_dist.txt
|
||||
README_dist:
|
||||
sh W/tools/gen_README_dist > $(DIST_PATH)/README.txt
|
||||
unix2dos $(DIST_PATH)/README.txt
|
||||
|
||||
.PHONY: publish upload_ks ks valid_index biz
|
||||
|
||||
@ -476,6 +535,9 @@ ksa:
|
||||
rsync -avHz --delete -P \
|
||||
. gilles@ks.lamiral.info:public_html/imapsync/
|
||||
|
||||
ks3:
|
||||
rsync -avHz --delete -P \
|
||||
. gilles@ks3.lamiral.info:public_html/imapsync/
|
||||
|
||||
upload_tests: tests.sh
|
||||
rsync -avHz --delete -P \
|
||||
@ -483,7 +545,13 @@ upload_tests: tests.sh
|
||||
gilles@ks.lamiral.info:public_html/imapsync/
|
||||
|
||||
|
||||
ks2testsdebug:
|
||||
rsync -aP imapsync gilles@ks.lamiral.info:public_html/imapsync/imapsync
|
||||
ssh gilles@ks.lamiral.info 'public_html/imapsync/imapsync --testsdebug'
|
||||
|
||||
ks2tests:
|
||||
rsync -aP imapsync gilles@ks.lamiral.info:public_html/imapsync/imapsync
|
||||
ssh gilles@ks.lamiral.info 'public_html/imapsync/imapsync --tests'
|
||||
|
||||
publish: dist upload_ks ksa
|
||||
echo Now ou can do make ml
|
||||
@ -491,7 +559,7 @@ publish: dist upload_ks ksa
|
||||
PUBLIC = ./ChangeLog ./NOLIMIT ./LICENSE ./CREDITS ./FAQ \
|
||||
./index.shtml ./INSTALL ./README_Windows.txt \
|
||||
./VERSION ./VERSION_EXE ./imapsync \
|
||||
./README ./OPTIONS ./TODO
|
||||
./README ./TODO
|
||||
|
||||
|
||||
|
||||
@ -542,9 +610,10 @@ upload_bin:
|
||||
rsync -aHvz --delete ../imapsync_website/ root@ks.lamiral.info:/var/www/imapsync/
|
||||
|
||||
upload_index: W/.valid.index.shtml
|
||||
rcsdiff index.shtml S/*.shtml FAQ FAQ.d/*.txt INSTALL LICENSE CREDITS TODO W/*.bat examples/*.bat index.shtml INSTALL.d/*.txt
|
||||
rsync -avH index.shtml FAQ INSTALL OPTIONS NOLIMIT LICENSE CREDITS TODO ../imapsync_website/
|
||||
rsync -avH S/ ../imapsync_website/S/
|
||||
rcsdiff index.shtml S/style.css S/*.shtml FAQ.d/*.txt LICENSE CREDITS TODO examples/*.bat index.shtml INSTALL.d/*.txt
|
||||
rsync -avH index.shtml FAQ INSTALL NOLIMIT LICENSE CREDITS TODO S/robots.txt S/favicon.ico ../imapsync_website/
|
||||
rsync -aHv --delete ./W/ks.htaccess ../imapsync_website/.htaccess
|
||||
rsync -aHv --delete S/ ../imapsync_website/S/
|
||||
rsync -aHv --delete ./examples/ ../imapsync_website/examples/
|
||||
rsync -aHv --delete ./INSTALL.d/ ../imapsync_website/INSTALL.d/
|
||||
rsync -aHv --delete ./FAQ.d/ ../imapsync_website/FAQ.d/
|
||||
@ -555,13 +624,24 @@ upload_index: W/.valid.index.shtml
|
||||
ci_imapsync:
|
||||
rcsdiff imapsync
|
||||
|
||||
upload_latest: ci_imapsync bin
|
||||
upload_latest: unitests ci_imapsync bin
|
||||
rsync -a imapsync imapsync_bin_Linux_i686 imapsync_bin_Darwin imapsync.exe ../imapsync_website/
|
||||
rsync -aHvz --delete ../imapsync_website/ root@ks.lamiral.info:/var/www/imapsync/
|
||||
|
||||
upload_cgi: unitests ks2tests ci_imapsync
|
||||
rsync -a imapsync ../imapsync_website/
|
||||
rsync -aHvz --delete ../imapsync_website/ root@ks.lamiral.info:/var/www/imapsync/
|
||||
|
||||
|
||||
upload_X:
|
||||
./W/tools/validate_xml_html5 X/imapsync_form.html
|
||||
rcsdiff X/imapsync_form.html
|
||||
rsync -av --delete X/ ../imapsync_website/X/
|
||||
rsync -aHvz --delete ../imapsync_website/ root@ks.lamiral.info:/var/www/imapsync/
|
||||
|
||||
upload_FAQ:
|
||||
rcsdiff FAQ FAQ.d/*.txt INSTALL LICENSE CREDITS TODO INSTALL.d/*.txt
|
||||
rsync -avH FAQ INSTALL OPTIONS CREDITS TODO ../imapsync_website/
|
||||
rcsdiff FAQ.d/*.txt LICENSE CREDITS TODO INSTALL.d/*.txt
|
||||
rsync -avH FAQ INSTALL CREDITS TODO ../imapsync_website/
|
||||
rsync -aHv --delete ./INSTALL.d/ ../imapsync_website/INSTALL.d/
|
||||
rsync -aHv --delete ./FAQ.d/ ../imapsync_website/FAQ.d/
|
||||
rsync -avH --delete ./doc/ ../imapsync_website/doc/
|
||||
|
281
OPTIONS
281
OPTIONS
@ -1,283 +1,4 @@
|
||||
|
||||
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.
|
||||
|
||||
--delete : Deletes messages on host1 server after a successful
|
||||
transfer. Option --delete has the following behavior:
|
||||
it marks messages as deleted with the IMAP flag
|
||||
\Deleted, then messages are really deleted with an
|
||||
EXPUNGE IMAP command.
|
||||
|
||||
--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$/"
|
||||
--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.
|
||||
|
||||
--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 : 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.
|
||||
--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 [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.38
|
||||
$Id: imapsync,v 1.727 2016/08/19 10:30:36 gilles Exp gilles $
|
||||
This imapsync is up to date
|
||||
|
||||
Homepage: http://imapsync.lamiral.info/
|
||||
Options are in the README file now. (since August 2017)
|
||||
|
||||
|
578
README
578
README
@ -1,14 +1,14 @@
|
||||
NAME
|
||||
|
||||
imapsync - Email IMAP tool for syncing, copying and migrating email
|
||||
mailboxes.
|
||||
mailboxes between two imap servers, one way, and without duplicates.
|
||||
|
||||
The imapsync command synchronises mailboxes between two imap servers.
|
||||
More than 69 different IMAP server softwares supported with success, few
|
||||
failures.
|
||||
VERSION
|
||||
|
||||
$Revision: 1.727 $
|
||||
This documentation refers to Imapsync $Revision: 1.4 $
|
||||
|
||||
USAGE
|
||||
|
||||
SYNOPSIS
|
||||
To synchronize the source imap account
|
||||
"test1" on server "test1.lamiral.info" with password "secret1"
|
||||
to the destination imap account
|
||||
@ -19,78 +19,94 @@ SYNOPSIS
|
||||
--host1 test1.lamiral.info --user1 test1 --password1 secret1 \
|
||||
--host2 test2.lamiral.info --user2 test2 --password2 secret2
|
||||
|
||||
REQUIRED ARGUMENTS
|
||||
The required argmuments are the six values, three on each sides, needed
|
||||
to login into the IMAP servers, a host, a username, and a password, two
|
||||
DESCRIPTION
|
||||
|
||||
We sometimes need to transfer mailboxes from one imap server to another.
|
||||
|
||||
Imapsync command is a tool allowing incremental and recursive imap
|
||||
transfers from one mailbox to another.
|
||||
|
||||
By default all folders are transferred, recursively, meaning the whole
|
||||
folder hierarchy is taken, all messages in them, and all messages flags
|
||||
(\Seen \Answered \Flagged etc.) are synced too.
|
||||
|
||||
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 "Message-Id:" and
|
||||
"Received:" lines but it can be changed with --useheader option).
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
A different scenario is synchronizing a mailbox B from another mailbox A
|
||||
in case you just want to keep a "live" 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).
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
INSTALL
|
||||
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.
|
||||
Conventions used:
|
||||
|
||||
Purchase latest imapsync at
|
||||
http://imapsync.lamiral.info/
|
||||
|
||||
You'll 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/
|
||||
|
||||
CONFIGURATION
|
||||
There is no specific configuration file for imapsync, everything is
|
||||
specified by the command line parameteres and the default behavior.
|
||||
|
||||
USAGE
|
||||
To get a description of each option just run imapsync with no argument,
|
||||
like this:
|
||||
|
||||
imapsync
|
||||
|
||||
This description of options is also available at
|
||||
http://imapsync.lamiral.info/OPTIONS and is reproduced here:
|
||||
|
||||
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.
|
||||
--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.
|
||||
--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'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.
|
||||
|
||||
--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.
|
||||
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
|
||||
@ -104,6 +120,8 @@ USAGE
|
||||
--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
|
||||
@ -116,11 +134,12 @@ USAGE
|
||||
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).
|
||||
|
||||
OPTIONS/folders
|
||||
|
||||
--folder str : Sync this folder.
|
||||
--folder str : and this one, etc.
|
||||
@ -132,17 +151,16 @@ USAGE
|
||||
--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 'fold1|fold2|f3' skips fold1, fold2 and f3.
|
||||
@ -153,37 +171,69 @@ USAGE
|
||||
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.
|
||||
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
|
||||
it's 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.
|
||||
|
||||
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
|
||||
--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.
|
||||
OPTIONS/messages
|
||||
|
||||
--skipmess reg : Skips messages maching the regex.
|
||||
--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.
|
||||
@ -198,15 +248,30 @@ USAGE
|
||||
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 : and this one, etc.
|
||||
--regexflag reg : then this one, etc.
|
||||
|
||||
--delete : Deletes messages on host1 server after a successful
|
||||
transfer. Option --delete has the following behavior:
|
||||
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.
|
||||
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.
|
||||
@ -221,19 +286,12 @@ USAGE
|
||||
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.
|
||||
|
||||
OPTIONS/dates
|
||||
|
||||
--syncinternaldates : Sets the internal dates on host2 same as host1.
|
||||
Turned on by default. Internal date is the date
|
||||
@ -241,6 +299,8 @@ USAGE
|
||||
--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.
|
||||
@ -260,44 +320,32 @@ USAGE
|
||||
--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.
|
||||
|
||||
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 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.
|
||||
@ -309,6 +357,38 @@ USAGE
|
||||
--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).
|
||||
@ -322,89 +402,17 @@ USAGE
|
||||
|
||||
--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 \
|
||||
--host1 test1.lamiral.info --user1 test1 --password1 secret1 \
|
||||
--host2 test2.lamiral.info --user2 test2 --password2 secret2
|
||||
|
||||
DESCRIPTION
|
||||
Imapsync command is a tool allowing incremental and recursive imap
|
||||
transfers from one mailbox to another.
|
||||
|
||||
By default all folders are transferred, recursively, all possible flags
|
||||
(\Seen \Answered \Flagged etc.) are synced too.
|
||||
|
||||
We sometimes need to transfer mailboxes from one imap server to another.
|
||||
This is called migration.
|
||||
|
||||
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.
|
||||
|
||||
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).
|
||||
|
||||
A different scenario is synchronizing a mailbox B from another mailbox A
|
||||
in case you just want to keep a "live" 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).
|
||||
|
||||
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.
|
||||
|
||||
OPTIONS
|
||||
To get a description of each option just invoke:
|
||||
|
||||
imapsync
|
||||
|
||||
or read the previous section named USAGE,
|
||||
|
||||
or read http://imapsync.lamiral.info/OPTIONS
|
||||
|
||||
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).
|
||||
|
||||
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.
|
||||
|
||||
To synchronize the imap account "buddy" (with password "secret1") on
|
||||
host "imap.src.fr" to the imap account "max" (with password "secret2")
|
||||
on host "imap.dest.fr":
|
||||
|
||||
imapsync --host1 imap.src.fr --user1 buddy --password1 secret1 \
|
||||
--host2 imap.dest.fr --user2 max --password2 secret2
|
||||
|
||||
Then you will have max's mailbox updated from buddy's mailbox.
|
||||
|
||||
SECURITY
|
||||
|
||||
You can use --passfile1 instead of --password1 to give the password
|
||||
since it is safer. With --password1 option any user on your host can see
|
||||
the password by using the 'ps auxwwww' command. Using a variable (like
|
||||
@ -412,150 +420,62 @@ SECURITY
|
||||
saving the password in a well protected file (600 or rw-------) is the
|
||||
best solution.
|
||||
|
||||
imasync is not totally protected against sniffers on the network since
|
||||
passwords may be transferred in plain text if CRAM-MD5 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 "if possible"? 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 TLS support in the CAPABILITY list of the servers. If TLS
|
||||
is supported then imapsync goes to encryption.
|
||||
|
||||
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 "adminuser" to enable this
|
||||
on host1. 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 "adminuser", 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.
|
||||
|
||||
When working on Sun/iPlanet/Netscape IMAP servers you must use
|
||||
--proxyauth1 to enable administrative user to masquerade as another
|
||||
user. Can also be used on destination server with --proxyauth2
|
||||
|
||||
You can authenticate with OAUTH 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 FAQ.Security.txt in the FAQ.d/ directory or at
|
||||
https://imapsync.lamiral.info/FAQ.d/FAQ.Security.txt
|
||||
|
||||
EXIT STATUS
|
||||
imapsync will exit with a 0 status (return code) if everything went
|
||||
|
||||
Imapsync will exit with a 0 status (return code) if everything went
|
||||
good. Otherwise, it exits with a non-zero status.
|
||||
|
||||
So if you have an unreliable internet connection, you can use this loop
|
||||
in a Bourne shell:
|
||||
|
||||
while ! imapsync ...; do
|
||||
echo imapsync not complete
|
||||
done
|
||||
|
||||
LICENSE AND COPYRIGHT
|
||||
imapsync is free, open, public but not always gratis software cover by
|
||||
|
||||
Imapsync is free, open, public but not always gratis software cover by
|
||||
the NOLIMIT Public License. See the LICENSE file included in the
|
||||
distribution or just read this simple sentence as it is the licence
|
||||
distribution or just read this simple sentence as it IS the licence
|
||||
text:
|
||||
|
||||
"No limit to do anything with this work and this license."
|
||||
|
||||
In case it is not long enough I repeat:
|
||||
In case it is not long enough, I repeat:
|
||||
|
||||
"No limit to do anything with this work and this license."
|
||||
|
||||
MAILING-LIST
|
||||
The public mailing-list may be the best way to get free support.
|
||||
|
||||
To write on the mailing-list, the address is:
|
||||
<imapsync@linux-france.org>
|
||||
|
||||
To subscribe, send any message (even empty) to:
|
||||
<imapsync-subscribe@listes.linux-france.org> then just reply to the
|
||||
confirmation message.
|
||||
|
||||
To unsubscribe, send a message to:
|
||||
<imapsync-unsubscribe@listes.linux-france.org>
|
||||
|
||||
To contact the person in charge for the list:
|
||||
<imapsync-request@listes.linux-france.org>
|
||||
|
||||
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.
|
||||
|
||||
Thank you for your participation.
|
||||
https://imapsync.lamiral.info/LICENSE
|
||||
|
||||
AUTHOR
|
||||
|
||||
Gilles LAMIRAL <gilles.lamiral@laposte.net>
|
||||
|
||||
Feedback good or bad is very often welcome.
|
||||
|
||||
Gilles LAMIRAL earns his living by writing, installing, configuring and
|
||||
teaching free, open and often gratis softwares. It used to be "always
|
||||
gratis" but now it is "often" because imapsync is sold by its author, a
|
||||
good way to stay maintening and supporting free open public softwares
|
||||
(see the license) over decades.
|
||||
teaching free, open and often gratis software. Imapsync used to be
|
||||
"always gratis" but now it is only "often gratis" because imapsync is
|
||||
sold by its author, a good way to maintain and support free open public
|
||||
software over decades.
|
||||
|
||||
BUGS AND LIMITATIONS
|
||||
Help me to help you: follow the following guidelines.
|
||||
|
||||
Report any bugs or feature requests to the public mailing-list or to the
|
||||
author.
|
||||
See https://imapsync.lamiral.info/FAQ.d/FAQ.Reporting_Bugs.txt
|
||||
|
||||
Before reporting bugs, read the FAQs, the README and the TODO files.
|
||||
http://imapsync.lamiral.info/
|
||||
IMAP SERVERS supported
|
||||
|
||||
Upgrade to last imapsync release, maybe the bug is already fixed.
|
||||
|
||||
Upgrade to last Mail-IMAPClient Perl module.
|
||||
http://search.cpan.org/dist/Mail-IMAPClient/ maybe the bug is already
|
||||
fixed there.
|
||||
|
||||
Make a good title with word "imapsync" in it (my spam filters won't
|
||||
filter it), Try to write an email title with more words than just
|
||||
"imapsync" or "problem", a good title is made of keywords summary, but
|
||||
not too long (one visible line).
|
||||
|
||||
Help us to help you: in your report, please include:
|
||||
|
||||
- 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 'BUG' and use
|
||||
|
||||
imapsync ... --folder 'BUG' --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.
|
||||
|
||||
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.
|
||||
|
||||
One time in your life, read the paper "How To Ask Questions The Smart
|
||||
Way" http://www.catb.org/~esr/faqs/smart-questions.html and then forget
|
||||
it.
|
||||
|
||||
IMAP SERVERS
|
||||
See http://imapsync.lamiral.info/S/imapservers.shtml
|
||||
See https://imapsync.lamiral.info/S/imapservers.shtml
|
||||
|
||||
HUGE MIGRATION
|
||||
Pay special attention to options --subscribed --subscribe --delete
|
||||
|
||||
Pay special attention to options --subscribed --subscribe --delete1
|
||||
--delete2 --delete2folders --maxage --minage --maxsize --useuid
|
||||
--usecache
|
||||
|
||||
@ -585,20 +505,46 @@ HUGE MIGRATION
|
||||
--host2 imap.side2.org --user2 %%I --password2 %%J ...
|
||||
|
||||
The ... have to be replaced by nothing or any imapsync option. Welcome
|
||||
in shell programming !
|
||||
in shell or batch programming !
|
||||
|
||||
You will find already written scripts at
|
||||
http://imapsync.lamiral.info/examples/
|
||||
|
||||
INSTALL
|
||||
|
||||
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'll 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/
|
||||
|
||||
CONFIGURATION
|
||||
|
||||
There is no specific configuration file for imapsync, everything is
|
||||
specified by the command line parameters and the default behavior.
|
||||
|
||||
HACKING
|
||||
|
||||
Feel free to hack imapsync as the NOLIMIT license permits it.
|
||||
|
||||
LINKS
|
||||
Entries for imapsync:
|
||||
https://web.archive.org/web/20070202005121/http://www.imap.org/products/
|
||||
showall.php
|
||||
|
||||
SIMILAR SOFTWARES
|
||||
|
||||
imap_tools : http://www.athensfbc.com/imap_tools
|
||||
offlineimap : https://github.com/nicolas33/offlineimap
|
||||
mbsync : http://isync.sourceforge.net/
|
||||
@ -617,5 +563,15 @@ SIMILAR SOFTWARES
|
||||
|
||||
Feedback (good or bad) will often be welcome.
|
||||
|
||||
$Id: imapsync,v 1.727 2016/08/19 10:30:36 gilles Exp gilles $
|
||||
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).
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
# $Id: README_Windows.txt,v 1.5 2015/03/26 04:27:39 gilles Exp gilles $
|
||||
# $Id: README_Windows.txt,v 1.9 2017/09/11 02:57:38 gilles Exp gilles $
|
||||
#
|
||||
# README_Windows.txt file for imapsync
|
||||
# This is the README_Windows.txt file for imapsync
|
||||
# imapsync : IMAP sync and migrate tool.
|
||||
|
||||
WINDOWS
|
||||
=======
|
||||
|
||||
Two ways to install and use imapsync on Windows systems: A) or B).
|
||||
There is two ways to install and use imapsync on Windows systems: A) or B).
|
||||
|
||||
Standard users should only take the A) way.
|
||||
|
||||
Developers, users that want to build their own imapsync.exe
|
||||
Developers, or powerful users that want to build their own imapsync.exe
|
||||
or modify it, have to consider the B) way.
|
||||
|
||||
A) Simplest way
|
||||
@ -18,7 +18,7 @@ A) Simplest way
|
||||
|
||||
A.1) Get imapsync.
|
||||
|
||||
Buy imapsync at http://imapsync.lamiral.info/
|
||||
Get imapsync at https://imapsync.lamiral.info/dist/
|
||||
You'll then have access to a zip archive file named imapsync_1.xxx.zip
|
||||
where 1.xxx is the imapsync release number.
|
||||
|
||||
@ -33,12 +33,11 @@ A.3) Check the folder
|
||||
In the folder extracted imapsync_1.xxx you see 6 files and 2 directories:
|
||||
|
||||
* README_Windows.txt is the current file you are reading
|
||||
* README.txt is the imapsync general document.
|
||||
* FAQ.d/* FAQs are a must read when something goes wrong.
|
||||
* imapsync_example.bat is a batch file example you will copy and edit
|
||||
* sync_loop_windows.bat is a batch file example for syncing many accounts
|
||||
* FAQ.txt contains many useful tips, too many so I started
|
||||
* FAQ.d/* to split them in FAQ.d/ folder.
|
||||
FAQs are a must read when something goes wrong.
|
||||
* README.txt imapsync general documentation.
|
||||
* file.txt is an input file example for syncing many accounts
|
||||
* imapsync.exe is the imapsync binary. You don't have to run it directly.
|
||||
* Cook/ is the directory to build imapsync.exe from its source.
|
||||
|
||||
@ -47,8 +46,8 @@ its extension remains ".bat". On Windows systems .bat extension
|
||||
means "I'm a batch script". Same thing for sync_loop_windows.bat.
|
||||
The batch scripts have to stay with imapsync.exe because
|
||||
of the way they call it, they use ".\imapsync.exe", so
|
||||
let them be in the same directory (or change the path if you
|
||||
understand what you're doing).
|
||||
let them be in the same directory (or change the path .\
|
||||
to whatever you want if you understand what you're doing).
|
||||
|
||||
For the rest of this documentation I assume you copied
|
||||
imapsync_example.bat to a file named imapsync_stuff.bat
|
||||
@ -58,12 +57,13 @@ A.4) Edit the batch file
|
||||
Edit imapsync_stuff.bat and change the values with yours.
|
||||
In order to edit it you have do a right click on it and select "modify"
|
||||
in the list presented in the small window menu.
|
||||
Notepad is a good editor to modify it,
|
||||
Office Word is not good for that job.
|
||||
Notepad or Notepadd++ are good editors to modify it.
|
||||
Office Word is not good for that job, don't use it!
|
||||
|
||||
Files FAQ.txt and FAQ.d/* contain many tips and special options sometimes
|
||||
needed by specific imap server softwares like Exchange or Gmail.
|
||||
|
||||
|
||||
A.5) Run the batch file
|
||||
|
||||
To run imapsync with your values just double-clic on
|
||||
@ -76,14 +76,16 @@ A.6) Loop on A.5) A.6)
|
||||
Loop the process of editing and running imapsync until
|
||||
you solve all issues and all values suit your needs.
|
||||
|
||||
A.7) Look the sync running. You can abort it at any time with a ctrl-c.
|
||||
A.7) Look the sync running. You can abort it at any time with a
|
||||
quick double ctrl-c, hit ctrl-c twice within one second.
|
||||
(a single ctrl-c will reconnect to both imap servers)
|
||||
|
||||
A.8) When the sync is finished you can find the whole log of the output
|
||||
in the folder named "LOG_imapsync", the logfile name is based
|
||||
on the launching date, hour, minute, second and the user2 parameter,
|
||||
one logfile per run.
|
||||
on the launching date, hour, minute, second, miliseconds and the
|
||||
user2 parameter. There is one logfile per run.
|
||||
The logfile name is printed at the end of the imapsync run.
|
||||
If you do not want logging in a file use option --nolog
|
||||
If you do not want logging to a file then use option --nolog
|
||||
|
||||
|
||||
B) Hard way. It is the hard way because it installs all software
|
||||
@ -92,7 +94,8 @@ B) Hard way. It is the hard way because it installs all software
|
||||
B.1) Install Perl if it isn't already installed.
|
||||
Strawberry Perl is a very good candidate
|
||||
http://strawberryperl.com/
|
||||
I use 5.16 (March 2015) but later releases should work (5.18 and 5.20 do)
|
||||
I use 5.26.0.1 (31 may 2017) but previous and later releases
|
||||
should work (5.18 and 5.20 do) as well.
|
||||
|
||||
B.2) Go into the Cook/ directory
|
||||
B.3) Double-clic build_exe.bat
|
||||
|
@ -1,13 +1,13 @@
|
||||
|
||||
<!-- $Id: bc-payment.html,v 1.4 2016/07/27 21:51:57 gilles Exp gilles $ -->
|
||||
<!-- $Id: bc-payment.html,v 1.11 2017/09/11 03:04:46 gilles Exp gilles $ -->
|
||||
|
||||
<a
|
||||
class="coinbase-button"
|
||||
data-code="5c8544cfe2d17f92401e60fd9299760f"
|
||||
href="https://www.coinbase.com/checkouts/5c8544cfe2d17f92401e60fd9299760f">Pay with bitcoins</a>
|
||||
class="coinbase-button"
|
||||
href="https://www.coinbase.com/checkouts/5c8544cfe2d17f92401e60fd9299760f"
|
||||
data-code="5c8544cfe2d17f92401e60fd9299760f">Pay with bitcoins</a>
|
||||
<script
|
||||
src="https://www.coinbase.com/assets/button.js"
|
||||
type="text/javascript">
|
||||
</script>
|
||||
|
||||
|
||||
<!-- data-code="5c8544cfe2d17f92401e60fd9299760f" -->
|
||||
|
@ -18,21 +18,24 @@
|
||||
<link rel="icon" type="image/png" href="../S/images/logo_imapsync_s.png" />
|
||||
<link href="../S/style.css" rel="stylesheet" type="text/css"/>
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<!--
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
|
||||
-->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>Similar softwares <a id="similar" href="../#TOP"><small>(back to menu)</small></a>
|
||||
<h1>Similar software <a id="similar" href="../#TOP"><small>(back to menu)</small></a>
|
||||
</h1>
|
||||
|
||||
|
||||
<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> davmail: <a href="http://davmail.sourceforge.net/">http://davmail.sourceforge.net/</a></li>
|
||||
|
||||
<li> <b>imapsync</b>: <a href="https://github.com/imapsync/imapsync">https://github.com/imapsync/imapsync</a> (this is an imapsync copy, sometimes delayed)</li>
|
||||
<li> imap_tools: <a href="https://web-beta.archive.org/web/20160927133511/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> Doveadm-Sync: <a href="http://wiki2.dovecot.org/Tools/Doveadm/Sync">http://wiki2.dovecot.org/Tools/Doveadm/Sync</a> ( Dovecot sync tool )</li>
|
||||
<li> davmail: <a href="http://davmail.sourceforge.net/">http://davmail.sourceforge.net/</a></li>
|
||||
<li> <b>offlineimap</b>: <a href="http://offlineimap.org/">http://offlineimap.org/</a></li>
|
||||
<li> <b>mbsync</b>: <a href="http://isync.sourceforge.net/">http://isync.sourceforge.net/</a></li>
|
||||
<li> mailsync: <a href="http://mailsync.sourceforge.net/">http://mailsync.sourceforge.net/</a></li>
|
||||
@ -50,7 +53,7 @@
|
||||
<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>
|
||||
<li> SyncBackPro <a href="http://www.2brightsparks.com/syncback/sbpro.html">http://www.2brightsparks.com/syncback/sbpro.html</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
@ -62,11 +65,13 @@ I don't think they use Imapsync.
|
||||
Prices are given par mailbox and may be outdated (December 2011).</p>
|
||||
|
||||
<ul>
|
||||
<li> French Ovh imapcopy <b>0 EUR</b>: <a href="https://ssl0.ovh.net/fr/imapcopy/">https://ssl0.ovh.net/fr/imapcopy/</a></li>
|
||||
<li> Imapsync.love <b>0 EUR</b>: <a href="http://imapsync.love/">http://imapsync.love/</a></li>
|
||||
<li> French Ovh imapcopy <b>0 EUR</b>: <a href="https://mail.ovh.net/fr/imapcopy/">https://mail.ovh.net/fr/imapcopy/</a></li>
|
||||
<li> Turkish imapcopy.net <b>0 TRY</b>: <a href="http://imapcopy.net/">http://imapcopy.net/</a></li>
|
||||
<li> Rackspace migration <b>0 USD</b>: <a href="http://www.rackspace.com/email-hosting/migrations">http://www.rackspace.com/email-hosting/migrations</a></li>
|
||||
<li> Movemymail free for the first and 5 USD thereafter: <a href="https://movemymail.net">https://movemymail.net</a> .</li>
|
||||
<li> Migrationwiz 10 USD: <a href="https://www.bittitan.com/products/migrationwiz/">https://www.bittitan.com/products/migrationwiz/</a></li>
|
||||
<li> Rackspace migration 5 USD: <a href="http://www.rackspace.com/email-hosting/migrations">http://www.rackspace.com/email-hosting/migrations</a></li>
|
||||
<li> Migrationwiz 10 USD: <a href="https://www.bittitan.com/products/migrationwiz/">https://www.bittitan.com/products/migrationwiz/</a>
|
||||
(See this remarkable comparaison <a href="https://blog.bittitan.com/imapsync-vs-migrationwiz/">Imapsync vs Migrationwiz</a>!)</li>
|
||||
<li> Audriga Gmbh 9.99 EUR: <a href="https://www.email-umzug.de/en.html">https://www.email-umzug.de/</a></li>
|
||||
<li> Yippiemove 15 USD: <a href="http://www.yippiemove.com">http://www.yippiemove.com/</a></li>
|
||||
<li> Dell ondemand-migration-for-email (price unknown): <a href="http://software.dell.com/products/ondemand-migration-for-email/">http://software.dell.com/products/ondemand-migration-for-email/</a></li>
|
||||
@ -100,7 +105,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: external.shtml,v 1.7 2016/03/19 22:05:24 gilles Exp gilles $)<br/>
|
||||
($Id: external.shtml,v 1.20 2017/09/11 03:04:46 gilles Exp gilles $)<br/>
|
||||
<a href="#TOP">Top of the page</a>
|
||||
</p>
|
||||
|
||||
|
BIN
S/favicon.ico
Normal file
BIN
S/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.3 KiB |
57
S/guestbook.shtml
Executable file
57
S/guestbook.shtml
Executable file
@ -0,0 +1,57 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en" id="TOP">
|
||||
<!-- $Id: guestbook.shtml,v 1.17 2017/09/11 03:04:46 gilles Exp gilles $ -->
|
||||
<head>
|
||||
<meta charset="utf-8" >
|
||||
<title>Imapsync Guestbook</title>
|
||||
<meta name="author" content="Gilles LAMIRAL" >
|
||||
<meta name="copyright" content="None">
|
||||
|
||||
<link rel="icon" type="image/png" href="../S/images/logo_imapsync_s.png" >
|
||||
<link href="../S/style.css" rel="stylesheet" type="text/css">
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<!--
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
|
||||
-->
|
||||
|
||||
|
||||
<!--
|
||||
The link to the HTML5Shiv must be placed in the <head> element, after any stylesheets
|
||||
http://www.w3schools.com/html/html5_browsers.asp
|
||||
-->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<section>
|
||||
<h1>Imapsync Guestbook</h1>
|
||||
<p>
|
||||
Your name is mandatory to post but don't hesitate to use a pseudonym!
|
||||
Email address is optional, only needed if you want a personnal reply.
|
||||
Have fun!
|
||||
</p>
|
||||
|
||||
|
||||
Feedback can also be done via:
|
||||
<div class="email">An email to the author <a href="mailto:gilles.lamiral@laposte.net?subject=Imapsync_feedback" class="email">gilles.lamiral@laposte.net</a></div>
|
||||
<div class="twitter">A tweet to the author <a href="https://twitter.com/imapsync" class="website">@imapsync</a></div>
|
||||
|
||||
|
||||
<!-- Bravenet Embedded Service Code -->
|
||||
<script src="http://apps.bravenet.com/go.js?service=guestbook;id=1;usernum=2854376880" type="text/javascript" charset="utf-8">
|
||||
</script>
|
||||
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
BIN
S/images/logo_imapsync_Xn.png
Normal file
BIN
S/images/logo_imapsync_Xn.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
BIN
S/images/logo_paypal.png
Normal file
BIN
S/images/logo_paypal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.0 KiB |
3
S/images/memo
Normal file
3
S/images/memo
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
convert logo_imapsync.png -gravity center -resize 190x60 -extent 190x60 logo_paypal.png
|
||||
|
BIN
S/imap_tools.V1.333/IMAP_Tools_User_Guide.pdf
Normal file
BIN
S/imap_tools.V1.333/IMAP_Tools_User_Guide.pdf
Normal file
Binary file not shown.
959
S/imap_tools.V1.333/IMAPtoMbox.pl
Executable file
959
S/imap_tools.V1.333/IMAPtoMbox.pl
Executable file
@ -0,0 +1,959 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# $Header: /mhub4/sources/imap-tools/IMAPtoMbox.pl,v 1.13 2015/04/30 12:22:21 rick Exp $
|
||||
|
||||
#######################################################################
|
||||
# Program name IMAPtoMbox.pl #
|
||||
# Written by Rick Sanders #
|
||||
# #
|
||||
# Description #
|
||||
# #
|
||||
# IMAPtoMbox.pl is a utility for extracting all of the mailboxes #
|
||||
# in an IMAP user's account and writing them to files in the #
|
||||
# Unix mbx format. #
|
||||
# #
|
||||
# The user supplies host/user/password information and the name #
|
||||
# of a directory on the local system. IMAPtoMbox.pl connects to #
|
||||
# the IMAP server and extracts each message in the user's IMAP #
|
||||
# mailboxes. Those messages are written to a file with the same #
|
||||
# name as the IMAP mailbox into the specified directory. #
|
||||
# #
|
||||
# For example: #
|
||||
# ./IMAPtoMbox.pl -i localhost/rfs/mypass -m /var/rfs #
|
||||
# #
|
||||
# Optional arguments: #
|
||||
# -d debug #
|
||||
# -L logfile #
|
||||
# -M IMAP mailbox list (dumps the specified mailboxes, see #
|
||||
# the usage notes for syntax) #
|
||||
#######################################################################
|
||||
|
||||
use Socket;
|
||||
use FileHandle;
|
||||
use Fcntl;
|
||||
use Getopt::Std;
|
||||
use MIME::Base64 qw(encode_base64 decode_base64);
|
||||
use POSIX qw(strftime);
|
||||
|
||||
#################################################################
|
||||
# Main program. #
|
||||
#################################################################
|
||||
|
||||
$dir = init();
|
||||
|
||||
# Get list of all messages on the source host by Message-Id
|
||||
#
|
||||
connectToHost($sourceHost, \$dst);
|
||||
login($sourceUser,$sourcePwd, $dst);
|
||||
namespace($dst, \$prefix, \$delim );
|
||||
|
||||
@mbxs = getMailboxList( $prefix, $dst );
|
||||
$number = $#mbxs + 1;
|
||||
|
||||
foreach $mbx ( @mbxs ) {
|
||||
my $mbxname = $mbx;
|
||||
$mbxname =~ s/^$prefix// if $prefix;
|
||||
@msgs = ();
|
||||
Log(" $mbxname");
|
||||
getMsgList( $mbx, \@msgs, $dst );
|
||||
|
||||
$mbxname =~ s/\//-/g; # Don't allow slashes in filename
|
||||
$mbxfn = "$dir/$mbxname";
|
||||
if ( !open (M, ">>$mbxfn") ) {
|
||||
Log("Error opening $mbxfn: $!");
|
||||
print STDERR "Error opening $mbxfn\n";
|
||||
next;
|
||||
}
|
||||
$summary{"$mbx"} = 0;
|
||||
next if $#msgs == -1;
|
||||
existingMboxMsgs( $mbxfn, \%mbox ) if $no_duplicates;
|
||||
$copied=0;
|
||||
next unless @msgs;
|
||||
foreach $msg ( @msgs ) {
|
||||
fetchMsg( $msg, $mbx, $dst, \$message, \$msgid );
|
||||
if ( $no_duplicates and ($mbox{"$msgid"}) ) {
|
||||
Log(" message $msgid already exists") if $debug;
|
||||
next;
|
||||
}
|
||||
print M $message;
|
||||
print M "\n";
|
||||
$copied++;
|
||||
|
||||
if ( $msgs_per_folder ) {
|
||||
# opt_F allows us to limit number of messages copied per folder
|
||||
last if $copied == $msgs_per_folder;
|
||||
}
|
||||
}
|
||||
close M;
|
||||
|
||||
`chown $opt_o "$mbxfn"` if $opt_o; # Set ownership
|
||||
|
||||
$summary{"$mbx"} = $copied++;
|
||||
}
|
||||
|
||||
logout( $dst );
|
||||
|
||||
Log("\nSummary of results");
|
||||
while (($x,$y) = each(%summary)) {
|
||||
$x =~ s/^$prefix// if $prefix;
|
||||
$line = pack("A50 A10\n", $x, $y);
|
||||
push( @summary, $line );
|
||||
}
|
||||
@summary = sort @summary;
|
||||
foreach $line ( @summary ) {
|
||||
Log("$line");
|
||||
}
|
||||
|
||||
exit;
|
||||
|
||||
|
||||
sub init {
|
||||
|
||||
$os = $ENV{'OS'};
|
||||
|
||||
$dir = processArgs();
|
||||
|
||||
$timeout = 60 if !$timeout;
|
||||
|
||||
# Open the logFile
|
||||
#
|
||||
if ( $logfile ) {
|
||||
if ( !open(LOG, ">> $logfile")) {
|
||||
print STDOUT "Can't open $logfile: $!\n";
|
||||
}
|
||||
select(LOG); $| = 1;
|
||||
}
|
||||
Log("\n$0 starting");
|
||||
Log("arguments i = $opt_i m = $opt_m");
|
||||
Log("Mailfiles will be written to $dir");
|
||||
# Determine whether we have SSL support via openSSL and IO::Socket::SSL
|
||||
$ssl_installed = 1;
|
||||
eval 'use IO::Socket::SSL';
|
||||
if ( $@ ) {
|
||||
$ssl_installed = 0;
|
||||
}
|
||||
|
||||
$installed = 1;
|
||||
@date_modules = qw( DateTime Date::Parse POSIX);
|
||||
foreach $module ( @date_modules ) {
|
||||
eval "use $module";
|
||||
if ( $@ ) {
|
||||
print STDERR "The Perl module $module is not installed. Please install it before proceeding.\n";
|
||||
$installed = 0;
|
||||
}
|
||||
}
|
||||
exit if $installed == 0;
|
||||
|
||||
return $dir;
|
||||
}
|
||||
|
||||
#
|
||||
# sendCommand
|
||||
#
|
||||
# This subroutine formats and sends an IMAP protocol command to an
|
||||
# IMAP server on a specified connection.
|
||||
#
|
||||
|
||||
sub sendCommand
|
||||
{
|
||||
local($fd) = shift @_;
|
||||
local($cmd) = shift @_;
|
||||
|
||||
print $fd "$cmd\r\n";
|
||||
|
||||
if ($showIMAP) { Log (">> $cmd",2); }
|
||||
}
|
||||
|
||||
#
|
||||
# readResponse
|
||||
#
|
||||
# This subroutine reads and formats an IMAP protocol response from an
|
||||
# IMAP server on a specified connection.
|
||||
#
|
||||
|
||||
sub readResponse {
|
||||
|
||||
local($fd) = shift @_;
|
||||
|
||||
$response = <$fd>;
|
||||
chop $response;
|
||||
$response =~ s/\r//g;
|
||||
push (@response,$response);
|
||||
if ($showIMAP) { Log ("<< $response",2); }
|
||||
}
|
||||
|
||||
#
|
||||
# Log
|
||||
#
|
||||
# This subroutine formats and writes a log message to STDERR.
|
||||
#
|
||||
|
||||
sub Log {
|
||||
|
||||
my $str = shift;
|
||||
|
||||
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
|
||||
if ($year < 99) { $yr = 2000; }
|
||||
else { $yr = 1900; }
|
||||
$line = sprintf ("%.2d-%.2d-%d.%.2d:%.2d:%.2d %s %s\n",
|
||||
$mon + 1, $mday, $year + $yr, $hour, $min, $sec,$$,$str);
|
||||
print LOG "$line";
|
||||
print STDERR "$str\n";
|
||||
|
||||
}
|
||||
|
||||
# connectToHost
|
||||
#
|
||||
# Make a connection to a host
|
||||
#
|
||||
sub connectToHost {
|
||||
|
||||
my $host = shift;
|
||||
my $conn = shift;
|
||||
|
||||
Log("Connecting to $host") if $debug;
|
||||
|
||||
($host,$port) = split(/:/, $host);
|
||||
$port = 143 unless $port;
|
||||
|
||||
# We know whether to use SSL for ports 143 and 993. For any
|
||||
# other ones we'll have to figure it out.
|
||||
$mode = sslmode( $host, $port );
|
||||
|
||||
if ( $mode eq 'SSL' ) {
|
||||
unless( $ssl_installed == 1 ) {
|
||||
warn("You must have openSSL and IO::Socket::SSL installed to use an SSL connection");
|
||||
Log("You must have openSSL and IO::Socket::SSL installed to use an SSL connection");
|
||||
exit;
|
||||
}
|
||||
Log("Attempting an SSL connection") if $debug;
|
||||
$$conn = IO::Socket::SSL->new(
|
||||
Proto => "tcp",
|
||||
SSL_verify_mode => 0x00,
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
Domain => AF_INET,
|
||||
);
|
||||
|
||||
unless ( $$conn ) {
|
||||
$error = IO::Socket::SSL::errstr();
|
||||
Log("Error connecting to $host: $error");
|
||||
warn("Error connecting to $host: $error");
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
# Non-SSL connection
|
||||
Log("Attempting a non-SSL connection") if $debug;
|
||||
$$conn = IO::Socket::INET->new(
|
||||
Proto => "tcp",
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
);
|
||||
|
||||
unless ( $$conn ) {
|
||||
Log("Error connecting to $host:$port: $@");
|
||||
warn "Error connecting to $host:$port: $@";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
Log("Connected to $host on port $port");
|
||||
|
||||
select( $$conn ); $| = 1;
|
||||
while (1) {
|
||||
readResponse ( $$conn );
|
||||
if ( $response =~ /^\* OK/i ) {
|
||||
last;
|
||||
}
|
||||
else {
|
||||
Log ("Bad response from host on port $port: $response");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Log ("connected to $host") if $debug;
|
||||
|
||||
select( $$conn ); $| = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub sslmode {
|
||||
|
||||
my $host = shift;
|
||||
my $port = shift;
|
||||
my $mode;
|
||||
|
||||
# Determine whether to make an SSL connection
|
||||
# to the host. Return 'SSL' if so.
|
||||
|
||||
if ( $port == 143 ) {
|
||||
# Standard non-SSL port
|
||||
return '';
|
||||
} elsif ( $port == 993 ) {
|
||||
# Standard SSL port
|
||||
return 'SSL';
|
||||
}
|
||||
|
||||
unless ( $ssl_installed ) {
|
||||
# We don't have SSL installed on this machine
|
||||
return '';
|
||||
}
|
||||
|
||||
# For any other port we need to determine whether it supports SSL
|
||||
|
||||
my $conn = IO::Socket::SSL->new(
|
||||
Proto => "tcp",
|
||||
SSL_verify_mode => 0x00,
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
);
|
||||
|
||||
if ( $conn ) {
|
||||
close( $conn );
|
||||
$mode = 'SSL';
|
||||
} else {
|
||||
$mode = '';
|
||||
}
|
||||
|
||||
return $mode;
|
||||
}
|
||||
|
||||
|
||||
# trim
|
||||
#
|
||||
# remove leading and trailing spaces from a string
|
||||
sub trim {
|
||||
|
||||
local (*string) = @_;
|
||||
|
||||
$string =~ s/^\s+//;
|
||||
$string =~ s/\s+$//;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
# login
|
||||
#
|
||||
# login in at the IMAP host with the user's name and password
|
||||
#
|
||||
sub login {
|
||||
|
||||
my $user = shift;
|
||||
my $pwd = shift;
|
||||
my $conn = shift;
|
||||
|
||||
if ( $admin_user ) {
|
||||
# An AUTHENTICATE = PLAIN login has been requested
|
||||
($authuser,$authpwd) = split(/:/, $admin_user );
|
||||
login_plain( $user, $authuser, $authpwd, $conn ) or exit;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( $pwd =~ /^oauth2:(.+)/i ) {
|
||||
$token = $1;
|
||||
Log("password is an OAUTH2 token") if $debug;
|
||||
login_xoauth2( $user, $token, $conn );
|
||||
return 1;
|
||||
}
|
||||
|
||||
sendCommand ($conn, "1 LOGIN $user \"$pwd\"");
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
if ($response =~ /^1 OK/i) {
|
||||
last;
|
||||
}
|
||||
elsif ($response =~ /NO/) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
Log("Logged in as $user") if $debug;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# login_plain
|
||||
#
|
||||
# login in at the source host with the user's name and password. If provided
|
||||
# with administrator credential, use them as this eliminates the need for the
|
||||
# user's password.
|
||||
#
|
||||
sub login_plain {
|
||||
|
||||
my $user = shift;
|
||||
my $admin = shift;
|
||||
my $pwd = shift;
|
||||
my $conn = shift;
|
||||
|
||||
# Do an AUTHENTICATE = PLAIN. If an admin user has been provided then use it.
|
||||
|
||||
if ( !$admin ) {
|
||||
# Log in as the user
|
||||
$admin = $user
|
||||
}
|
||||
|
||||
$login_str = sprintf("%s\x00%s\x00%s", $user,$admin,$pwd);
|
||||
$login_str = encode_base64("$login_str", "");
|
||||
$len = length( $login_str );
|
||||
|
||||
sendCommand ($conn, "1 AUTHENTICATE PLAIN" );
|
||||
|
||||
my $loops;
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
last if $response =~ /\+/;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
exit;
|
||||
}
|
||||
$last if $loops++ > 5;
|
||||
}
|
||||
|
||||
sendCommand ($conn, "$login_str" );
|
||||
my $loops;
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
|
||||
if ( $response =~ /Microsoft Exchange/i and $conn eq $dst ) {
|
||||
# The destination is an Exchange server
|
||||
$exchange = 1;
|
||||
Log("The destination is an Exchange server");
|
||||
}
|
||||
|
||||
last if $response =~ /^1 OK/i;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
exit;
|
||||
}
|
||||
$last if $loops++ > 5;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
# logout
|
||||
#
|
||||
# log out from the host
|
||||
#
|
||||
sub logout {
|
||||
|
||||
my $conn = shift;
|
||||
|
||||
++$lsn;
|
||||
undef @response;
|
||||
sendCommand ($conn, "$lsn LOGOUT");
|
||||
while ( 1 ) {
|
||||
readResponse ($conn);
|
||||
if ( $response =~ /^$lsn OK/i ) {
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
Log ("unexpected LOGOUT response: $response");
|
||||
last;
|
||||
}
|
||||
}
|
||||
close $conn;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
# getMailboxList
|
||||
#
|
||||
# get a list of the user's mailboxes from the source host
|
||||
#
|
||||
sub getMailboxList {
|
||||
|
||||
my $prefix = shift;
|
||||
my $conn = shift;
|
||||
my @mbxs;
|
||||
|
||||
# Get a list of the user's mailboxes
|
||||
#
|
||||
|
||||
Log("Get list of user's mailboxes",2) if $debugMode;
|
||||
|
||||
if ( $mbxList ) {
|
||||
foreach $mbx ( split(/,/, $mbxList) ) {
|
||||
$mbx = $prefix . $mbx if $prefix;
|
||||
if ( $opt_r ) {
|
||||
# Get all submailboxes under the ones specified
|
||||
$mbx .= '*';
|
||||
@mailboxes = listMailboxes( $mbx, $conn);
|
||||
push( @mbxs, @mailboxes );
|
||||
} else {
|
||||
push( @mbxs, $mbx );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
# Get all mailboxes
|
||||
@mbxs = listMailboxes( '*', $conn);
|
||||
}
|
||||
|
||||
return @mbxs;
|
||||
}
|
||||
|
||||
# listMailboxes
|
||||
#
|
||||
sub listMailboxes {
|
||||
|
||||
my $mbx = shift;
|
||||
my $conn = shift;
|
||||
|
||||
sendCommand ($conn, "1 LIST \"\" \"$mbx\"");
|
||||
undef @response;
|
||||
while ( 1 ) {
|
||||
readResponse ($conn);
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
Log ("unexpected response: $response");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
%nosel_mbxs = ();
|
||||
@mbxs = ();
|
||||
for $i (0 .. $#response) {
|
||||
$response[$i] =~ s/\s+/ /;
|
||||
if ( $response[$i] =~ /"$/ ) {
|
||||
$response[$i] =~ /\* LIST \((.*)\) "(.+)" "(.+)"/i;
|
||||
$mbx = $3;
|
||||
} else {
|
||||
$response[$i] =~ /\* LIST \((.*)\) "(.+)" (.+)/i;
|
||||
$mbx = $3;
|
||||
}
|
||||
$mbx =~ s/^\s+//; $mbx =~ s/\s+$//;
|
||||
|
||||
next if $response[$i] =~ /NOSELECT/i;
|
||||
|
||||
if (($mbx =~ /^\#/) && ($user ne 'anonymous')) {
|
||||
# Skip public mbxs unless we are migrating them
|
||||
next;
|
||||
}
|
||||
if ($mbx =~ /^\./) {
|
||||
# Skip mailboxes starting with a dot
|
||||
next;
|
||||
}
|
||||
push ( @mbxs, $mbx ) if $mbx ne '';
|
||||
}
|
||||
|
||||
return @mbxs;
|
||||
}
|
||||
|
||||
# getMsgList
|
||||
#
|
||||
# Get a list of the user's messages in the indicated mailbox on
|
||||
# the source host
|
||||
#
|
||||
sub getMsgList {
|
||||
|
||||
my $mailbox = shift;
|
||||
my $msgs = shift;
|
||||
my $conn = shift;
|
||||
my $seen;
|
||||
my $empty;
|
||||
my $msgnum;
|
||||
my $from;
|
||||
|
||||
trim( *mailbox );
|
||||
sendCommand ($conn, "1 EXAMINE \"$mailbox\"");
|
||||
undef @response;
|
||||
$empty=0;
|
||||
select($conn);
|
||||
while ( 1 ) {
|
||||
readResponse ( $conn );
|
||||
if ( $response =~ / 0 EXISTS/i ) { $empty=1; }
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
# print STDERR "response $response\n";
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
Log ("unexpected response: $response");
|
||||
# print STDERR "Error: $response\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return if $empty;
|
||||
|
||||
Log("Fetch the header info") if $debug;
|
||||
|
||||
sendCommand ( $conn, "1 FETCH 1:* (uid flags internaldate body[header.fields (From Date)])");
|
||||
undef @response;
|
||||
while ( 1 ) {
|
||||
readResponse ( $conn );
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
# print STDERR "response $response\n";
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
undef @msgs;
|
||||
undef $flags;
|
||||
for $i (0 .. $#response) {
|
||||
$seen=0;
|
||||
$_ = $response[$i];
|
||||
|
||||
last if /OK FETCH complete/;
|
||||
|
||||
if ( $response[$i] =~ /^From:\s*(.+)/i ) {
|
||||
$from = $1 if !$from;
|
||||
}
|
||||
|
||||
if ( $response[$i] =~ /^Date: (.+)/ ) {
|
||||
# Firstly assume that the date is formatted correctly and split accordingly.
|
||||
$origdate = $1;
|
||||
$date = $origdate;
|
||||
$date =~ s/,//g;
|
||||
($date) = split(/-/, $date);
|
||||
($wkday,$mday,$mon,$yr,$time) = split(/\s+/, $date);
|
||||
$mday = '0' . $mday if length($mday) == 1;
|
||||
$date = "$wkday $mon $mday $time $yr";
|
||||
|
||||
# Now actually parse the date to check that it is formatted correctly.
|
||||
# Assume GMT if timezone is omitted.
|
||||
my @parseddate = strptime ($origdate, "GMT");
|
||||
# If the number of seconds were omitted then assume 0.
|
||||
if ( !defined $parseddate[0] ) {
|
||||
$parseddate[0] = 0;
|
||||
}
|
||||
# If the year was given as 2 digits, assume it can't be less than the UNIX epoch of 1970.
|
||||
if ( $parseddate[5] < 70 ) {
|
||||
$parseddate[5] += 100;
|
||||
}
|
||||
# strptime returns the timezone as an offset in seconds. Convert back to +/-HHMM format.
|
||||
if ( $parseddate[6] < 0 ) {
|
||||
$parseddate[6] = sprintf ("-%02d%02d", int (-$parseddate[6] / 3600), int ((-$parseddate[6] % 3600) / 60));
|
||||
} else {
|
||||
$parseddate[6] = sprintf ("+%02d%02d", int ($parseddate[6] / 3600), int (($parseddate[6] % 3600) / 60));
|
||||
}
|
||||
eval '
|
||||
$dt = DateTime->new (second => $parseddate[0],
|
||||
minute => $parseddate[1],
|
||||
hour => $parseddate[2],
|
||||
day => $parseddate[3],
|
||||
month => $parseddate[4] + 1, # needs to be 1-12 and not 0-11.
|
||||
year => $parseddate[5] + 1900, # needs to be an absolute year.
|
||||
time_zone => $parseddate[6]);
|
||||
';
|
||||
|
||||
if ( length( $@ ) != 0 ) {
|
||||
# The date is too badly formatted to fix. Use today's date instead.
|
||||
Log("The date $date is badly formatted, using today's date instead");
|
||||
$date = strftime("%a, %d %b %Y %H:%M:%S %z", localtime(time()));
|
||||
} else {
|
||||
$newdate = $dt->strftime ("%a %b %d %H:%M:%S %Y");
|
||||
|
||||
# Compare the parsed date with that formed by assuming the date was correctly formatted.
|
||||
# Let the user know if they differ so they can judge if the calculated date is correct.
|
||||
if ( $date ne $newdate ) {
|
||||
Log ("badly formatted date in message: " . $origdate);
|
||||
Log (" calculated replacement date as: " . $newdate);
|
||||
$date = $newdate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $response[$i] =~ /\* (.+) FETCH/ ) {
|
||||
($msgnum) = split(/\s+/, $1);
|
||||
}
|
||||
|
||||
if ( $response[$i] =~ /^\)/ or ( $response[$i] =~ /\)\)$/ ) ) {
|
||||
push (@$msgs,"$msgnum|$from|$date");
|
||||
$msgnum = $date = '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
## Fetch a message from the IMAP server
|
||||
#
|
||||
|
||||
sub fetchMsg {
|
||||
|
||||
my $msg = shift;
|
||||
my $mbx = shift;
|
||||
my $conn = shift;
|
||||
my $message = shift;
|
||||
my $msgid = shift;
|
||||
|
||||
my ($msgnum,$from,$date) = split(/\|/, $msg);
|
||||
Log(" Fetching msg $msgnum...") if $debug;
|
||||
sendCommand ($conn, "1 EXAMINE \"$mbx\"");
|
||||
while (1) {
|
||||
readResponse ($conn);
|
||||
last if ( $response =~ /^1 OK/i );
|
||||
}
|
||||
|
||||
sendCommand( $conn, "1 FETCH $msgnum (rfc822)");
|
||||
while (1) {
|
||||
readResponse ($conn);
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
$size = length($message);
|
||||
last;
|
||||
}
|
||||
elsif ( $response =~ /^1 NO|^1 BAD/ ) {
|
||||
last;
|
||||
}
|
||||
elsif ($response =~ /message number out of range/i) {
|
||||
Log ("Error fetching uid $uid: out of range",2);
|
||||
$stat=0;
|
||||
last;
|
||||
}
|
||||
elsif ($response =~ /Bogus sequence in FETCH/i) {
|
||||
Log ("Error fetching uid $uid: Bogus sequence in FETCH",2);
|
||||
$stat=0;
|
||||
last;
|
||||
}
|
||||
elsif ( $response =~ /message could not be processed/i ) {
|
||||
Log("Message could not be processed, skipping it ($user,msgnum $msgnum,$destMbx)");
|
||||
push(@errors,"Message could not be processed, skipping it ($user,msgnum $msgnum,$destMbx)");
|
||||
$stat=0;
|
||||
last;
|
||||
}
|
||||
elsif
|
||||
($response =~ /^\*\s+$msgnum\s+FETCH\s+\(.*RFC822\s+\{[0-9]+\}/i) {
|
||||
($len) = ($response =~ /^\*\s+$msgnum\s+FETCH\s+\(.*RFC822\s+\{([0-9]+)\}/i);
|
||||
$cc = 0;
|
||||
$$message = "";
|
||||
while ( $cc < $len ) {
|
||||
$n = 0;
|
||||
$n = read ($conn, $segment, $len - $cc);
|
||||
if ( $n == 0 ) {
|
||||
Log ("unable to read $len bytes");
|
||||
return 0;
|
||||
}
|
||||
$$message .= $segment;
|
||||
$cc += $n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$$message =~ s/\r//g;
|
||||
if ( $$message !~ /^From / ) {
|
||||
$$message = "From $from $date\n$$message";
|
||||
}
|
||||
|
||||
# Some servers don't like single-digit days in the timestamp
|
||||
# in the "From " line
|
||||
for $i (0 .. 9 ) {
|
||||
$$message =~ s/ $i / 0$i /;
|
||||
}
|
||||
|
||||
$$message =~ /Message-ID:\s*\<(.+)\>/i;
|
||||
$$msgid = $1 if $1;
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
## Display the usage message
|
||||
#
|
||||
|
||||
sub usage {
|
||||
|
||||
print STDOUT "\nusage:";
|
||||
print STDOUT "IMAPtoMbox.pl -i Host/User/Password -m <dir> [-M] [-d] [-I] [-o <user>] \n";
|
||||
print STDOUT "\n Optional arguments:\n";
|
||||
print STDOUT " -M IMAP mailbox list (eg \"Inbox, Drafts, Notes\". Default all mailboxes)\n";
|
||||
print STDOUT " -o <user> sets ownership of mailfile\n";
|
||||
print STDOUT " -A <admin_user:admin_pwd>\n";
|
||||
print STDOUT " -L logfile\n";
|
||||
print STDOUT " -d debug\n";
|
||||
print STDOUT " -I show IMAP protocal exchanges\n";
|
||||
print STDOUT " -n don't copy if message already exists in mbox file\n";
|
||||
print STDOUT " -r include submailboxes when used with -M\n\n";
|
||||
exit;
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
## Get command-line arguments
|
||||
#
|
||||
sub processArgs {
|
||||
|
||||
if ( !getopts( "di:L:m:hM:Io:nrF:A:" ) ) {
|
||||
usage();
|
||||
}
|
||||
|
||||
($sourceHost,$sourceUser,$sourcePwd) = split(/\//, $opt_i);
|
||||
$mbxList = $opt_M;
|
||||
$logfile = $opt_L;
|
||||
$dir = $opt_m;
|
||||
$owner = $opt_o;
|
||||
$no_duplicates = 1 if $opt_n;
|
||||
$submbxs = 1 if $opt_r;
|
||||
$debug = 1 if $opt_d;
|
||||
$showIMAP = 1 if $opt_I;
|
||||
$msgs_per_folder = $opt_F;
|
||||
$admin_user = $opt_A;
|
||||
|
||||
if ( !$dir ) {
|
||||
print "You must specify the file directory where messages will\n";
|
||||
print "be written using the -m argument.\n\n";
|
||||
usage();
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( !-d $dir ) {
|
||||
print "Fatal Error: $dir does not exist\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
usage() if $opt_h;
|
||||
|
||||
return $dir;
|
||||
|
||||
}
|
||||
|
||||
sub existingMboxMsgs {
|
||||
|
||||
my $mbx = shift;
|
||||
my $msgs = shift;
|
||||
|
||||
|
||||
# Build an index of messages in an mbox by messageID.
|
||||
|
||||
%$msgs = ();
|
||||
unless ( open(F, "<$mbx") ) {
|
||||
Log("Error opening mbox file $mbox: $!");
|
||||
return;
|
||||
}
|
||||
|
||||
while ( <F> ) {
|
||||
if ( /^Message-ID:\s*\<(.+)\>/i ) {
|
||||
$$msgs{"$1"} = 1;
|
||||
}
|
||||
}
|
||||
close F;
|
||||
|
||||
}
|
||||
|
||||
sub namespace {
|
||||
|
||||
my $conn = shift;
|
||||
my $prefix = shift;
|
||||
my $delimiter = shift;
|
||||
|
||||
# Query the server with NAMESPACE so we can determine its
|
||||
# mailbox prefix (if any) and hierachy delimiter.
|
||||
|
||||
@response = ();
|
||||
sendCommand( $conn, "1 NAMESPACE");
|
||||
while ( 1 ) {
|
||||
readResponse( $conn );
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
last;
|
||||
} elsif ( $response =~ /NO|BAD/i ) {
|
||||
Log("Unexpected response to NAMESPACE command: $response");
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
foreach $_ ( @response ) {
|
||||
if ( /NAMESPACE/i ) {
|
||||
my $i = index( $_, '((' );
|
||||
my $j = index( $_, '))' );
|
||||
my $val = substr($_,$i+2,$j-$i-3);
|
||||
($val) = split(/\)/, $val);
|
||||
($$prefix,$$delimiter) = split( / /, $val );
|
||||
$$prefix =~ s/"//g;
|
||||
$$delimiter =~ s/"//g;
|
||||
last;
|
||||
}
|
||||
last if /^NO|^BAD/;
|
||||
}
|
||||
|
||||
if ( $debug ) {
|
||||
Log("prefix $$prefix");
|
||||
Log("delim $$delimiter");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub mailboxName {
|
||||
|
||||
my $mbx = shift;
|
||||
my $prefix = shift;
|
||||
my $delim = shift;
|
||||
|
||||
# Adjust the mailbox name if necessary using the mailbox hierarchy
|
||||
# prefix and delimiter.
|
||||
|
||||
$mbx =~ s#^$srcPrefix##;
|
||||
$mbx = $srcmbx;
|
||||
|
||||
if ( $srcDelim ne $dstDelim ) {
|
||||
# Need to substitute the dst's hierarchy delimiter for the src's one
|
||||
$srcDelim = '\\' . $srcDelim if $srcDelim eq '.';
|
||||
$dstDelim = "\\" . $dstDelim if $dstDelim eq '.';
|
||||
$dstmbx =~ s#$srcDelim#$dstDelim#g;
|
||||
$dstmbx =~ s/\\//g;
|
||||
}
|
||||
if ( $srcPrefix ne $dstPrefix ) {
|
||||
# Replace the source prefix with the dest prefix
|
||||
$dstmbx =~ s#^$srcPrefix## if $srcPrefix;
|
||||
if ( $dstPrefix ) {
|
||||
$dstmbx = "$dstPrefix$dstmbx" unless uc($srcmbx) eq 'INBOX';
|
||||
}
|
||||
$dstDelim = "\\$dstDelim" if $dstDelim eq '.';
|
||||
$dstmbx =~ s#^$dstDelim##;
|
||||
}
|
||||
|
||||
if ( $root_mbx ) {
|
||||
# Put folders under a 'root' folder on the dst
|
||||
$dstDelim =~ s/\./\\./g;
|
||||
$dstmbx =~ s/^$dstPrefix//;
|
||||
$dstmbx =~ s/^$dstDelim//;
|
||||
$dstmbx = $dstPrefix . $root_mbx . $dstDelim . $dstmbx;
|
||||
if ( uc($srcmbx) eq 'INBOX' ) {
|
||||
# Special case for the INBOX
|
||||
$dstmbx =~ s/INBOX$//i;
|
||||
$dstmbx =~ s/$dstDelim$//;
|
||||
}
|
||||
$dstmbx =~ s/\\//g;
|
||||
}
|
||||
|
||||
return $dstmbx;
|
||||
}
|
||||
|
||||
# login_xoauth2
|
||||
#
|
||||
# login in at the source host with the user's name and an XOAUTH2 token.
|
||||
#
|
||||
sub login_xoauth2 {
|
||||
|
||||
my $user = shift;
|
||||
my $token = shift;
|
||||
my $conn = shift;
|
||||
|
||||
# Do an AUTHENTICATE = XOAUTH2 login
|
||||
|
||||
$login_str = encode_base64("user=". $user ."\x01auth=Bearer ". $token ."\x01\x01", '');
|
||||
sendCommand ($conn, "1 AUTHENTICATE XOAUTH2 $login_str" );
|
||||
|
||||
my $loops;
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
if ( $response =~ /^\+ (.+)/ ) {
|
||||
$error = decode_base64( $1 );
|
||||
Log("XOAUTH authentication as $user failed: $error");
|
||||
exit;
|
||||
}
|
||||
last if $response =~ /^1 OK/;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE|failed/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
exit;
|
||||
}
|
||||
$last if $loops++ > 5;
|
||||
}
|
||||
|
||||
Log("login complete") if $debug;
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
1189
S/imap_tools.V1.333/MboxtoIMAP.pl
Executable file
1189
S/imap_tools.V1.333/MboxtoIMAP.pl
Executable file
File diff suppressed because it is too large
Load Diff
1238
S/imap_tools.V1.333/delIMAPdups.pl
Executable file
1238
S/imap_tools.V1.333/delIMAPdups.pl
Executable file
File diff suppressed because it is too large
Load Diff
1251
S/imap_tools.V1.333/delIMAPdups.pl.files
Normal file
1251
S/imap_tools.V1.333/delIMAPdups.pl.files
Normal file
File diff suppressed because it is too large
Load Diff
1304
S/imap_tools.V1.333/delete_imap_mailboxes.pl
Executable file
1304
S/imap_tools.V1.333/delete_imap_mailboxes.pl
Executable file
File diff suppressed because it is too large
Load Diff
924
S/imap_tools.V1.333/dumptoIMAP.pl
Executable file
924
S/imap_tools.V1.333/dumptoIMAP.pl
Executable file
@ -0,0 +1,924 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# $Header: /mhub4/sources/imap-tools/dumptoIMAP.pl,v 1.14 2014/11/10 12:55:43 rick Exp $
|
||||
|
||||
#######################################################################
|
||||
# dumptoIMAP.pl is used to load the mailboxes and messages exported #
|
||||
# from an IMAP server by the imapdump.pl script. See usage() notes #
|
||||
# for a list of the arguments used to run it. #
|
||||
# #
|
||||
# If you ran imapdump.pl -S host/user/pwd -f /tmp/BACKUP #
|
||||
# then you could restore all of the mailboxes & messages with the #
|
||||
# following command: #
|
||||
# #
|
||||
# ./dumptoIMAP.pl -i host/user/pwd -D /tmp/BACKUP #
|
||||
# #
|
||||
# If you wanted to restore just the INBOX and the Sent mailboxes you #
|
||||
# would add -m "INBOX,Sent" #
|
||||
#######################################################################
|
||||
|
||||
use Socket;
|
||||
use IO::Socket;
|
||||
use FileHandle;
|
||||
use File::Find;
|
||||
use Fcntl;
|
||||
use Getopt::Std;
|
||||
use MIME::Base64 qw(decode_base64 encode_base64);
|
||||
|
||||
init();
|
||||
|
||||
connectToHost($imapHost, \$conn);
|
||||
|
||||
if ( $imapUser =~ /(.+):(.+)/ ) {
|
||||
# An AUTHENTICATE = PLAIN login has been requested
|
||||
$imapUser = $1;
|
||||
$authuser = $2;
|
||||
login_plain( $imapUser, $authuser, $imapPwd, $conn ) or exit;
|
||||
} else {
|
||||
if ( !login($imapUser,$imapPwd, $conn) ) {
|
||||
Log("Check your username and password");
|
||||
print STDOUT "Login failed: Check your username and password\n";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $opt_y ) {
|
||||
# User-supplied mbx delimiter and prefix
|
||||
($mbx_delim,$prefix) = split(/\s+/, $opt_y );
|
||||
} else {
|
||||
namespace( $conn, \$prefix, \$mbx_delim );
|
||||
}
|
||||
|
||||
get_mbx_list( $dir, \@mbxs );
|
||||
|
||||
foreach $mbx ( @mbxs ) {
|
||||
$copied=0;
|
||||
Log("mbx = >$mbx<") if $debug;
|
||||
Log("Full path to $mbx is >$dir/$mbx<") if $debug;
|
||||
|
||||
Log("Copying messages from $dir/$mbx to $mbx folder on the IMAP server");
|
||||
get_messages( "$dir/$mbx", \@msgs );
|
||||
$n = scalar @msgs;
|
||||
Log("$mbx has $n messages");
|
||||
|
||||
$mbx =~ s/\//$mbx_delim/g unless $mbx_delim eq '/';
|
||||
if ( $prefix ) {
|
||||
$mbx = $prefix . $mbx unless $mbx =~ /^INBOX/i;
|
||||
}
|
||||
|
||||
foreach $_ ( @msgs ) {
|
||||
next unless $_;
|
||||
my $msg; my $date; my $seen;
|
||||
|
||||
$flags = '';
|
||||
if ( /,S$/ ) {
|
||||
$flags = '\\SEEN';
|
||||
}
|
||||
|
||||
Log("Opening $_") if $debug;
|
||||
unless ( open(F, "<$_") ) {
|
||||
Log("Error opening $_: $!");
|
||||
next;
|
||||
}
|
||||
Log("Opened $_ successfully") if $debug;
|
||||
while( <F> ) {
|
||||
# Log("Reading line $_") if $debug;
|
||||
if ( /^Date: (.+)/ ) {
|
||||
$date = $1 unless $date;
|
||||
$date =~ s/\r|\m//g;
|
||||
chomp $date;
|
||||
}
|
||||
s/\r+$//g;
|
||||
$msg .= $_;
|
||||
chomp $msg;
|
||||
$msg .= "\r\n";
|
||||
|
||||
}
|
||||
close F;
|
||||
|
||||
$size = length( $msg );
|
||||
Log("The message is $size bytes") if $debug;
|
||||
# Log("$msg") if $debug;
|
||||
|
||||
if ( $size == 0 ) {
|
||||
Log("The message file is empty") if $debug;
|
||||
next;
|
||||
}
|
||||
|
||||
$copied++ if insertMsg($mbx, \$msg, $flags, $date, $conn);
|
||||
|
||||
if ( $msgs_per_folder ) {
|
||||
# opt_F allows us to limit number of messages copied per folder
|
||||
last if $copied == $msgs_per_folder;
|
||||
}
|
||||
|
||||
if ( $copied/100 == int($copied/100)) { Log("$copied messages copied "); }
|
||||
}
|
||||
$total += $copied;
|
||||
|
||||
}
|
||||
|
||||
logout( $conn );
|
||||
|
||||
Log("Done. $total messages were copied.");
|
||||
exit;
|
||||
|
||||
|
||||
sub init {
|
||||
|
||||
if ( !getopts('m:L:i:dD:Ix:XRA:F:y:') ) {
|
||||
usage();
|
||||
}
|
||||
|
||||
$mbx_list = $opt_m;
|
||||
$dir = $opt_D;
|
||||
$logfile = $opt_L;
|
||||
$extension = $opt_x;
|
||||
$debug = 1 if $opt_d;
|
||||
$showIMAP = 1 if $opt_I;
|
||||
$admin_user = $opt_A;
|
||||
$msgs_per_folder = $opt_F;
|
||||
($imapHost,$imapUser,$imapPwd) = split(/\//, $opt_i);
|
||||
|
||||
if ( $logfile ) {
|
||||
if ( ! open (LOG, ">> $logfile") ) {
|
||||
print "Can't open logfile $logfile: $!\n";
|
||||
$logfile = '';
|
||||
}
|
||||
}
|
||||
Log("Starting");
|
||||
|
||||
# Determine whether we have SSL support via openSSL and IO::Socket::SSL
|
||||
$ssl_installed = 1;
|
||||
eval 'use IO::Socket::SSL';
|
||||
if ( $@ ) {
|
||||
$ssl_installed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub usage {
|
||||
|
||||
print "Usage: dumptoIMAP.pl\n";
|
||||
print " -D <path to the mailboxes>\n";
|
||||
print " -i <server/username/password>\n";
|
||||
print " (if the password is an OAUTH2 token then prefix it with 'oauth2:'\n";
|
||||
print " [-A <admin_user:admin_pwd>\n";
|
||||
print " [-m <mbx1,mbx2,..,mbxn> copy only the listed mailboxes]\n";
|
||||
print " [-x <extension> Import only files with this extension\n";
|
||||
print " [-L <logfile>]\n";
|
||||
print " [-d debug]\n";
|
||||
print " [-I log IMAP protocol exchanges]\n";
|
||||
|
||||
}
|
||||
|
||||
sub get_messages {
|
||||
|
||||
my $dir = shift;
|
||||
my $msgs = shift;
|
||||
|
||||
# Get a list of the message files
|
||||
|
||||
if ( $debug ) {
|
||||
Log("Get list of messages in $dir");
|
||||
}
|
||||
|
||||
opendir D, $dir;
|
||||
my @files = readdir( D );
|
||||
closedir D;
|
||||
foreach $_ ( @files ) {
|
||||
next if /^\./;
|
||||
if ( $extension ) {
|
||||
next unless /$extension$/;
|
||||
}
|
||||
Log(" $dir/$_") if $debug;
|
||||
push( @$msgs, "$dir/$_");
|
||||
}
|
||||
}
|
||||
|
||||
# Print a message to STDOUT and to the logfile if
|
||||
# the opt_L option is present.
|
||||
#
|
||||
|
||||
sub Log {
|
||||
|
||||
my $line = shift;
|
||||
my $msg;
|
||||
|
||||
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime (time);
|
||||
$msg = sprintf ("%.2d-%.2d-%.4d.%.2d:%.2d:%.2d %s",
|
||||
$mon + 1, $mday, $year + 1900, $hour, $min, $sec, $line);
|
||||
|
||||
if ( $logfile ) {
|
||||
print LOG "$msg\n";
|
||||
}
|
||||
print STDOUT "$line\n";
|
||||
|
||||
}
|
||||
|
||||
# connectToHost
|
||||
#
|
||||
# Make an IMAP connection to a host
|
||||
#
|
||||
sub connectToHost {
|
||||
|
||||
my $host = shift;
|
||||
my $conn = shift;
|
||||
|
||||
Log("Connecting to $host") if $debug;
|
||||
|
||||
$sockaddr = 'S n a4 x8';
|
||||
($name, $aliases, $proto) = getprotobyname('tcp');
|
||||
($host,$port) = split(/:/, $host);
|
||||
$port = 143 unless $port;
|
||||
|
||||
if ($host eq "") {
|
||||
Log ("no remote host defined");
|
||||
close LOG;
|
||||
exit (1);
|
||||
}
|
||||
|
||||
# We know whether to use SSL for ports 143 and 993. For any
|
||||
# other ones we'll have to figure it out.
|
||||
$mode = sslmode( $host, $port );
|
||||
|
||||
if ( $mode eq 'SSL' ) {
|
||||
unless( $ssl_installed == 1 ) {
|
||||
warn("You must have openSSL and IO::Socket::SSL installed to use an SSL connection");
|
||||
Log("You must have openSSL and IO::Socket::SSL installed to use an SSL connection");
|
||||
exit;
|
||||
}
|
||||
Log("Attempting an SSL connection") if $debug;
|
||||
$$conn = IO::Socket::SSL->new(
|
||||
Proto => "tcp",
|
||||
SSL_verify_mode => 0x00,
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
Domain => AF_INET,
|
||||
);
|
||||
|
||||
unless ( $$conn ) {
|
||||
$error = IO::Socket::SSL::errstr();
|
||||
Log("Error connecting to $host: $error");
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
# Non-SSL connection
|
||||
Log("Attempting a non-SSL connection") if $debug;
|
||||
$$conn = IO::Socket::INET->new(
|
||||
Proto => "tcp",
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
);
|
||||
|
||||
unless ( $$conn ) {
|
||||
Log("Error connecting to $host:$port: $@");
|
||||
warn "Error connecting to $host:$port: $@";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
select( $$conn ); $| = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#
|
||||
# login in at the IMAP host with the user's name and password
|
||||
#
|
||||
sub login {
|
||||
|
||||
my $user = shift;
|
||||
my $pwd = shift;
|
||||
my $conn = shift;
|
||||
|
||||
if ( $admin_user ) {
|
||||
# An AUTHENTICATE = PLAIN login has been requested
|
||||
($authuser,$authpwd) = split(/:/, $admin_user );
|
||||
login_plain( $user, $authuser, $authpwd, $conn ) or exit;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( $pwd =~ /^oauth2:(.+)/i ) {
|
||||
$token = $1;
|
||||
Log("password is an OAUTH2 token");
|
||||
login_xoauth2( $user, $token, $conn );
|
||||
return 1;
|
||||
}
|
||||
|
||||
Log("Logging in as $user") if $debug;
|
||||
$rsn = 1;
|
||||
sendCommand ($conn, "$rsn LOGIN $user $pwd");
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
if ($response =~ /^$rsn OK/i) {
|
||||
last;
|
||||
}
|
||||
elsif ($response =~ /NO/) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Log("Logged in as $user") if $debug;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# login_plain
|
||||
#
|
||||
# login in at the source host with the user's name and password. If provided
|
||||
# with administrator credential, use them as this eliminates the need for the
|
||||
# user's password.
|
||||
#
|
||||
sub login_plain {
|
||||
|
||||
my $user = shift;
|
||||
my $admin = shift;
|
||||
my $pwd = shift;
|
||||
my $conn = shift;
|
||||
|
||||
# Do an AUTHENTICATE = PLAIN. If an admin user has been provided then use it.
|
||||
|
||||
if ( !$admin ) {
|
||||
# Log in as the user
|
||||
$admin = $user
|
||||
}
|
||||
|
||||
$login_str = sprintf("%s\x00%s\x00%s", $user,$admin,$pwd);
|
||||
$login_str = encode_base64("$login_str", "");
|
||||
$len = length( $login_str );
|
||||
|
||||
# sendCommand ($conn, "1 AUTHENTICATE \"PLAIN\" {$len}" );
|
||||
sendCommand ($conn, "1 AUTHENTICATE PLAIN $login_str" );
|
||||
|
||||
my $loops;
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
last if $response =~ /^1 OK/;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
exit;
|
||||
}
|
||||
$last if $loops++ > 5;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
# login_xoauth2
|
||||
#
|
||||
# login in at the source host with the user's name and an XOAUTH2 token.
|
||||
#
|
||||
sub login_xoauth2 {
|
||||
|
||||
my $user = shift;
|
||||
my $token = shift;
|
||||
my $conn = shift;
|
||||
|
||||
# Do an AUTHENTICATE = XOAUTH2 login
|
||||
|
||||
$login_str = encode_base64("user=". $user ."\x01auth=Bearer ". $token ."\x01\x01", '');
|
||||
sendCommand ($conn, "1 AUTHENTICATE XOAUTH2 $login_str" );
|
||||
|
||||
my $loops;
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
if ( $response =~ /^\+ (.+)/ ) {
|
||||
$error = decode_base64( $1 );
|
||||
Log("XOAUTH authentication as $user failed: $error");
|
||||
exit;
|
||||
}
|
||||
last if $response =~ /^1 OK/;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE|failed/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
exit;
|
||||
}
|
||||
$last if $loops++ > 5;
|
||||
}
|
||||
|
||||
Log("login complete") if $debug;
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
# logout
|
||||
#
|
||||
# log out from the host
|
||||
#
|
||||
sub logout {
|
||||
|
||||
my $conn = shift;
|
||||
|
||||
++$lsn;
|
||||
undef @response;
|
||||
sendCommand ($conn, "$lsn LOGOUT");
|
||||
while ( 1 ) {
|
||||
readResponse ($conn);
|
||||
if ( $response =~ /^$lsn OK/i ) {
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
Log ("unexpected LOGOUT response: $response");
|
||||
last;
|
||||
}
|
||||
}
|
||||
close $conn;
|
||||
return;
|
||||
}
|
||||
|
||||
# readResponse
|
||||
#
|
||||
# This subroutine reads and formats an IMAP protocol response from an
|
||||
# IMAP server on a specified connection.
|
||||
#
|
||||
|
||||
sub readResponse {
|
||||
|
||||
my $fd = shift;
|
||||
|
||||
$response = <$fd>;
|
||||
chop $response;
|
||||
$response =~ s/\r//g;
|
||||
push (@response,$response);
|
||||
Log(">>$response") if $showIMAP;
|
||||
}
|
||||
|
||||
#
|
||||
# sendCommand
|
||||
#
|
||||
# This subroutine formats and sends an IMAP protocol command to an
|
||||
# IMAP server on a specified connection.
|
||||
#
|
||||
|
||||
sub sendCommand {
|
||||
|
||||
my $fd = shift;
|
||||
my $cmd = shift;
|
||||
|
||||
print $fd "$cmd\r\n";
|
||||
Log(">>$cmd") if $showIMAP;
|
||||
}
|
||||
|
||||
#
|
||||
# insertMsg
|
||||
#
|
||||
# Append a message to an IMAP mailbox
|
||||
#
|
||||
|
||||
sub insertMsg {
|
||||
|
||||
my $mbx = shift;
|
||||
my $message = shift;
|
||||
my $flags = shift;
|
||||
my $date = shift;
|
||||
my $conn = shift;
|
||||
my ($lsn,$lenx);
|
||||
|
||||
Log(" Inserting message") if $debug;
|
||||
$lenx = length($$message);
|
||||
|
||||
# Log("$$message");
|
||||
|
||||
($date) = split(/\s*\(/, $date);
|
||||
if ( $date =~ /,/ ) {
|
||||
$date =~ /(.+),\s+(.+)\s+(.+)\s+(.+)\s+(.+)\s+(.+)/;
|
||||
$date = "$2-$3-$4 $5 $6";
|
||||
} else {
|
||||
$date =~ s/\s/-/;
|
||||
$date =~ s/\s/-/;
|
||||
}
|
||||
|
||||
# Create the mailbox unless we have already done so
|
||||
++$lsn;
|
||||
if ($destMbxs{"$mbx"} eq '') {
|
||||
sendCommand ($conn, "$lsn CREATE \"$mbx\"");
|
||||
while ( 1 ) {
|
||||
readResponse ($conn);
|
||||
if ( $response =~ /^$rsn OK/i ) {
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
if (!($response =~ /already exists|reserved mailbox name/i)) {
|
||||
Log ("WARNING: $response");
|
||||
}
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
$destMbxs{"$mbx"} = '1';
|
||||
|
||||
$flags =~ s/\\Recent//i;
|
||||
|
||||
if ( $date ) {
|
||||
sendCommand ($conn, "1 APPEND \"$mbx\" ($flags) \"$date\" \{$lenx\}");
|
||||
} else {
|
||||
sendCommand ($conn, "1 APPEND \"$mbx\" ($flags) \{$lenx\}");
|
||||
}
|
||||
readResponse ($conn);
|
||||
if ( $response !~ /^\+/ ) {
|
||||
Log ("unexpected APPEND response to $cmd");
|
||||
push(@errors,"Error appending message to $mbx for $user");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( $opt_X ) {
|
||||
print $conn "$$message\n";
|
||||
} else {
|
||||
print $conn "$$message\r\n";
|
||||
}
|
||||
|
||||
undef @response;
|
||||
while ( 1 ) {
|
||||
readResponse ($conn);
|
||||
if ( $response =~ /^$lsn OK/i ) {
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
Log ("unexpected APPEND response: $response");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# getMsgList
|
||||
#
|
||||
# Get a list of the user's messages in the indicated mailbox on
|
||||
# the IMAP host
|
||||
#
|
||||
sub getMsgList {
|
||||
|
||||
my $mailbox = shift;
|
||||
my $msgs = shift;
|
||||
my $conn = shift;
|
||||
my $seen;
|
||||
my $empty;
|
||||
my $msgnum;
|
||||
|
||||
Log("Getting list of msgs in $mailbox") if $debug;
|
||||
trim( *mailbox );
|
||||
sendCommand ($conn, "$rsn EXAMINE \"$mailbox\"");
|
||||
undef @response;
|
||||
$empty=0;
|
||||
while ( 1 ) {
|
||||
readResponse ( $conn );
|
||||
if ( $response =~ / 0 EXISTS/i ) { $empty=1; }
|
||||
if ( $response =~ /^$rsn OK/i ) {
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
Log ("unexpected response: $response");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
sendCommand ( $conn, "$rsn FETCH 1:* (uid flags internaldate body[header.fields (Message-Id)])");
|
||||
undef @response;
|
||||
while ( 1 ) {
|
||||
readResponse ( $conn );
|
||||
if ( $response =~ /^$rsn OK/i ) {
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
# Get a list of the msgs in the mailbox
|
||||
#
|
||||
undef @msgs;
|
||||
undef $flags;
|
||||
for $i (0 .. $#response) {
|
||||
$seen=0;
|
||||
$_ = $response[$i];
|
||||
|
||||
last if /OK FETCH complete/;
|
||||
|
||||
if ( $response[$i] =~ /FETCH \(UID / ) {
|
||||
$response[$i] =~ /\* ([^FETCH \(UID]*)/;
|
||||
$msgnum = $1;
|
||||
}
|
||||
|
||||
if ($response[$i] =~ /FLAGS/) {
|
||||
# Get the list of flags
|
||||
$response[$i] =~ /FLAGS \(([^\)]*)/;
|
||||
$flags = $1;
|
||||
$flags =~ s/\\Recent//i;
|
||||
}
|
||||
if ( $response[$i] =~ /INTERNALDATE ([^\)]*)/ ) {
|
||||
### $response[$i] =~ /INTERNALDATE (.+) ([^BODY]*)/i;
|
||||
$response[$i] =~ /INTERNALDATE (.+) BODY/i;
|
||||
$date = $1;
|
||||
$date =~ s/"//g;
|
||||
}
|
||||
if ( $response[$i] =~ /^Message-Id:/i ) {
|
||||
($label,$msgid) = split(/: /, $response[$i]);
|
||||
push (@$msgs,$msgid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# trim
|
||||
#
|
||||
# remove leading and trailing spaces from a string
|
||||
sub trim {
|
||||
|
||||
local (*string) = @_;
|
||||
|
||||
$string =~ s/^\s+//;
|
||||
$string =~ s/\s+$//;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sub sslmode {
|
||||
|
||||
my $host = shift;
|
||||
my $port = shift;
|
||||
my $mode;
|
||||
|
||||
# Determine whether to make an SSL connection
|
||||
# to the host. Return 'SSL' if so.
|
||||
|
||||
if ( $port == 143 ) {
|
||||
# Standard non-SSL port
|
||||
return '';
|
||||
} elsif ( $port == 993 ) {
|
||||
# Standard SSL port
|
||||
return 'SSL';
|
||||
}
|
||||
|
||||
unless ( $ssl_installed ) {
|
||||
# We don't have SSL installed on this machine
|
||||
return '';
|
||||
}
|
||||
|
||||
# For any other port we need to determine whether it supports SSL
|
||||
|
||||
my $conn = IO::Socket::SSL->new(
|
||||
Proto => "tcp",
|
||||
SSL_verify_mode => 0x00,
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
);
|
||||
|
||||
if ( $conn ) {
|
||||
close( $conn );
|
||||
$mode = 'SSL';
|
||||
} else {
|
||||
$mode = '';
|
||||
}
|
||||
|
||||
return $mode;
|
||||
}
|
||||
|
||||
sub get_mbx_list {
|
||||
|
||||
my $dir = shift;
|
||||
my $mbxs = shift;
|
||||
my %MBXS;
|
||||
|
||||
if ( $mbx_list ) {
|
||||
# The user has supplied a list of mailboxes.
|
||||
@$mbxs = split(/,/, $mbx_list );
|
||||
return;
|
||||
}
|
||||
|
||||
@dirs = ();
|
||||
push( @dirs, $dir );
|
||||
@messages = ();
|
||||
find( \&findMsgs, @dirs ); # Returns @messages
|
||||
foreach $fn ( @messages ) {
|
||||
Log("fn = $fn") if $debug;
|
||||
$fn =~ s/$dir//;
|
||||
Log("fn = $fn") if $debug;
|
||||
$i = rindex($fn,'/');
|
||||
Log("find rightmost slash, i = $i") if $debug;
|
||||
if ( $fn =~ /^\// ) {
|
||||
$mbx = substr($fn,1,$i);
|
||||
} else {
|
||||
$mbx = substr($fn,0,$i);
|
||||
}
|
||||
Log("mbx = $mbx") if $debug;
|
||||
$mbx =~ s/\/$//;
|
||||
Log("mbx = >$mbx<") if $debug;
|
||||
push( @$mbxs, $mbx ) if !$MBXS{"$mbx"};
|
||||
Log("Add >$mbx< to the list of mailboxes") if $debug;
|
||||
$MBXS{"$mbx"} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
sub findMsgs {
|
||||
|
||||
return if not -f;
|
||||
|
||||
my $fn = $File::Find::name;
|
||||
push( @messages, $fn );
|
||||
|
||||
}
|
||||
|
||||
sub namespace {
|
||||
|
||||
my $conn = shift;
|
||||
my $prefix = shift;
|
||||
my $delimiter = shift;
|
||||
|
||||
# Query the server with NAMESPACE so we can determine its
|
||||
# mailbox prefix (if any) and hierachy delimiter.
|
||||
|
||||
@response = ();
|
||||
sendCommand( $conn, "1 NAMESPACE");
|
||||
while ( 1 ) {
|
||||
readResponse( $conn );
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
last;
|
||||
} elsif ( $response =~ /^1 NO|^1 BAD|^\* BYE/i ) {
|
||||
Log("Unexpected response to NAMESPACE command: $response");
|
||||
Log("Cannot determine the mailbox delimiter and prefix. Use -y '<delimiter prefix>' to supply it");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
foreach $_ ( @response ) {
|
||||
if ( /NAMESPACE/i ) {
|
||||
my $i = index( $_, '((' );
|
||||
my $j = index( $_, '))' );
|
||||
my $val = substr($_,$i+2,$j-$i-3);
|
||||
($val) = split(/\)/, $val);
|
||||
($$prefix,$$delimiter) = split( / /, $val );
|
||||
$$prefix =~ s/"//g;
|
||||
$$delimiter =~ s/"//g;
|
||||
|
||||
# Experimental
|
||||
if ( $public_mbxs ) {
|
||||
# Figure out the public mailbox settings
|
||||
/\(\((.+)\)\)\s+\(\((.+)\s+\(\((.+)\)\)/;
|
||||
$public = $3;
|
||||
$public =~ /"(.+)"\s+"(.+)"/;
|
||||
$src_public_prefix = $1 if $conn eq $src;
|
||||
$src_public_delim = $2 if $conn eq $src;
|
||||
$dst_public_prefix = $1 if $conn eq $dst;
|
||||
$dst_public_delim = $2 if $conn eq $dst;
|
||||
}
|
||||
last;
|
||||
}
|
||||
last if /^1 NO|^1 BAD|^\* BYE/;
|
||||
}
|
||||
|
||||
unless ( $$delimiter ) {
|
||||
# NAMESPACE command is not supported by the server
|
||||
# so we will have to figure it out another way.
|
||||
$delim = getDelimiter( $conn );
|
||||
$$delimiter = $delim;
|
||||
$$prefix = '';
|
||||
}
|
||||
|
||||
if ( $debug ) {
|
||||
Log("prefix >$$prefix<");
|
||||
Log("delim >$$delimiter<");
|
||||
}
|
||||
}
|
||||
|
||||
sub mailboxName {
|
||||
|
||||
my $srcmbx = shift;
|
||||
my $srcPrefix = shift;
|
||||
my $srcDelim = shift;
|
||||
my $dstPrefix = shift;
|
||||
my $dstDelim = shift;
|
||||
my $dstmbx;
|
||||
my $substChar = '_';
|
||||
|
||||
if ( $public_mbxs ) {
|
||||
my ($public_src,$public_dst) = split(/:/, $public_mbxs );
|
||||
# If the mailbox starts with the public mailbox prefix then
|
||||
# map it to the public mailbox destination prefix
|
||||
|
||||
if ( $srcmbx =~ /^$public_src/ ) {
|
||||
Log("src: $srcmbx is a public mailbox") if $debug;
|
||||
$dstmbx = $srcmbx;
|
||||
$dstmbx =~ s/$public_src/$public_dst/;
|
||||
Log("dst: $dstmbx") if $debug;
|
||||
return $dstmbx;
|
||||
}
|
||||
}
|
||||
|
||||
# Change the mailbox name if the user has supplied mapping rules.
|
||||
|
||||
if ( $mbx_map{"$srcmbx"} ) {
|
||||
$srcmbx = $mbx_map{"$srcmbx"}
|
||||
}
|
||||
|
||||
# Adjust the mailbox name if the source and destination server
|
||||
# have different mailbox prefixes or hierarchy delimiters.
|
||||
|
||||
if ( ($srcmbx =~ /[$dstDelim]/) and ($dstDelim ne $srcDelim) ) {
|
||||
# The mailbox name has a character that is used on the destination
|
||||
# as a mailbox hierarchy delimiter. We have to replace it.
|
||||
$srcmbx =~ s^[$dstDelim]^$substChar^g;
|
||||
}
|
||||
|
||||
if ( $debug ) {
|
||||
Log("src mbx $srcmbx");
|
||||
Log("src prefix $srcPrefix");
|
||||
Log("src delim $srcDelim");
|
||||
Log("dst prefix $dstPrefix");
|
||||
Log("dst delim $dstDelim");
|
||||
}
|
||||
|
||||
$srcmbx =~ s/^$srcPrefix//;
|
||||
$srcmbx =~ s/\\$srcDelim/\//g;
|
||||
|
||||
if ( ($srcPrefix eq $dstPrefix) and ($srcDelim eq $dstDelim) ) {
|
||||
# No adjustments necessary
|
||||
# $dstmbx = $srcmbx;
|
||||
if ( lc( $srcmbx ) eq 'inbox' ) {
|
||||
$dstmbx = $srcmbx;
|
||||
} else {
|
||||
$dstmbx = $srcPrefix . $srcmbx;
|
||||
}
|
||||
if ( $root_mbx ) {
|
||||
# Put folders under a 'root' folder on the dst
|
||||
$dstmbx =~ s/^$dstPrefix//;
|
||||
$dstDelim =~ s/\./\\./g;
|
||||
$dstmbx =~ s/^$dstDelim//;
|
||||
$dstmbx = $dstPrefix . $root_mbx . $dstDelim . $dstmbx;
|
||||
if ( uc($srcmbx) eq 'INBOX' ) {
|
||||
# Special case for the INBOX
|
||||
$dstmbx =~ s/INBOX$//i;
|
||||
$dstmbx =~ s/$dstDelim$//;
|
||||
}
|
||||
$dstmbx =~ s/\\//g;
|
||||
}
|
||||
return $dstmbx;
|
||||
}
|
||||
|
||||
$srcmbx =~ s#^$srcPrefix##;
|
||||
$dstmbx = $srcmbx;
|
||||
|
||||
if ( $srcDelim ne $dstDelim ) {
|
||||
# Need to substitute the dst's hierarchy delimiter for the src's one
|
||||
$srcDelim = '\\' . $srcDelim if $srcDelim eq '.';
|
||||
$dstDelim = "\\" . $dstDelim if $dstDelim eq '.';
|
||||
$dstmbx =~ s#$srcDelim#$dstDelim#g;
|
||||
$dstmbx =~ s/\\//g;
|
||||
}
|
||||
if ( $srcPrefix ne $dstPrefix ) {
|
||||
# Replace the source prefix with the dest prefix
|
||||
$dstmbx =~ s#^$srcPrefix## if $srcPrefix;
|
||||
if ( $dstPrefix ) {
|
||||
$dstmbx = "$dstPrefix$dstmbx" unless uc($srcmbx) eq 'INBOX';
|
||||
}
|
||||
$dstDelim = "\\$dstDelim" if $dstDelim eq '.';
|
||||
$dstmbx =~ s#^$dstDelim##;
|
||||
}
|
||||
|
||||
if ( $root_mbx ) {
|
||||
# Put folders under a 'root' folder on the dst
|
||||
$dstDelim =~ s/\./\\./g;
|
||||
$dstmbx =~ s/^$dstPrefix//;
|
||||
$dstmbx =~ s/^$dstDelim//;
|
||||
$dstmbx = $dstPrefix . $root_mbx . $dstDelim . $dstmbx;
|
||||
if ( uc($srcmbx) eq 'INBOX' ) {
|
||||
# Special case for the INBOX
|
||||
$dstmbx =~ s/INBOX$//i;
|
||||
$dstmbx =~ s/$dstDelim$//;
|
||||
}
|
||||
$dstmbx =~ s/\\//g;
|
||||
}
|
||||
|
||||
return $dstmbx;
|
||||
}
|
||||
|
||||
sub getDelimiter {
|
||||
|
||||
my $conn = shift;
|
||||
my $delimiter;
|
||||
|
||||
# Issue a 'LIST "" ""' command to find out what the
|
||||
# mailbox hierarchy delimiter is.
|
||||
|
||||
sendCommand ($conn, '1 LIST "" ""');
|
||||
@response = '';
|
||||
while ( 1 ) {
|
||||
readResponse ($conn);
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
Log ("unexpected response: $response");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for $i (0 .. $#response) {
|
||||
$response[$i] =~ s/\s+/ /;
|
||||
if ( $response[$i] =~ /\* LIST \((.*)\) "(.*)" "(.*)"/i ) {
|
||||
$delimiter = $2;
|
||||
}
|
||||
}
|
||||
|
||||
return $delimiter;
|
||||
}
|
||||
|
BIN
S/imap_tools.V1.333/flag_de.gif
Normal file
BIN
S/imap_tools.V1.333/flag_de.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 953 B |
BIN
S/imap_tools.V1.333/flag_en.gif
Normal file
BIN
S/imap_tools.V1.333/flag_en.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 884 B |
502
S/imap_tools.V1.333/imapCapability.pl
Executable file
502
S/imap_tools.V1.333/imapCapability.pl
Executable file
@ -0,0 +1,502 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# $Header: /mhub4/sources/imap-tools/imapCapability.pl,v 1.9 2014/10/15 21:42:58 rick Exp $
|
||||
|
||||
###########################################################################
|
||||
# Program name imapCapability.pl #
|
||||
# Written by Rick Sanders #
|
||||
# Date 23 December 2007 #
|
||||
# #
|
||||
# Description #
|
||||
# #
|
||||
# imapCapability.pl is a simple program for querying an IMAP #
|
||||
# server for a list of the IMAP features it supports. #
|
||||
# #
|
||||
# Description #
|
||||
# #
|
||||
# imapCapability is used to discover what services an IMAP #
|
||||
# server supports. #
|
||||
# #
|
||||
# Usage: imapCapability.pl -h <host> -u <user> -p <password> #
|
||||
# Optional arguments: -d (debug) -m (list folders) #
|
||||
# #
|
||||
# Sample output: #
|
||||
# The server supports the following IMAP capabilities: #
|
||||
# #
|
||||
# IMAP4 IMAP4REV1 ACL NAMESPACE UIDPLUS IDLE LITERAL+ QUOTA #
|
||||
# ID MULTIAPPEND LISTEXT CHILDREN BINARY LOGIN-REFERRALS #
|
||||
# UNSELECT STARTTLS AUTH=LOGIN AUTH=PLAIN AUTH=CRAM-MD5 #
|
||||
# AUTH=DIGEST-MD5 AUTH=GSSAPI AUTH=MSN AUTH=NTLM #
|
||||
###########################################################################
|
||||
|
||||
############################################################################
|
||||
# Copyright (c) 2012 Rick Sanders <rfs9999@earthlink.net> #
|
||||
# #
|
||||
# Permission to use, copy, modify, and distribute this software for any #
|
||||
# purpose with or without fee is hereby granted, provided that the above #
|
||||
# copyright notice and this permission notice appear in all copies. #
|
||||
# #
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES #
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF #
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR #
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES #
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN #
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF #
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #
|
||||
############################################################################
|
||||
|
||||
use Socket;
|
||||
use FileHandle;
|
||||
use Fcntl;
|
||||
use Getopt::Std;
|
||||
use IO::Socket;
|
||||
eval 'use Encode qw/encode decode/';
|
||||
eval 'use Encode::IMAPUTF7 qw/encode decode/';
|
||||
use MIME::Base64 qw(encode_base64 decode_base64);
|
||||
|
||||
#################################################################
|
||||
# Main program. #
|
||||
#################################################################
|
||||
|
||||
($host,$user,$pwd) = getArgs();
|
||||
|
||||
unless ( $host and $user and $pwd ) {
|
||||
print "Host:Port > ";
|
||||
chomp($host = <>);
|
||||
print "Username > ";
|
||||
chomp($user = <>);
|
||||
print "Password > ";
|
||||
chomp($pwd = <>);
|
||||
}
|
||||
|
||||
unless ( $host and $user and $pwd ) {
|
||||
print "Please supply host, username, and password\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
connectToHost($host, \$conn) or exit;
|
||||
login($user,$pwd, $conn) or exit;
|
||||
capability( $conn );
|
||||
|
||||
if ( $list_mbxs ) {
|
||||
print STDOUT "\nList of mailboxes for $user:\n\n";
|
||||
@mbxs = listMailboxes( $conn );
|
||||
|
||||
foreach $mbx ( @mbxs ) {
|
||||
$mbx1 = decode( 'IMAP-UTF-7', $mbx );
|
||||
if ( $mbx eq $mbx1 ) {
|
||||
print STDOUT " $mbx\n";
|
||||
} elsif( $utf7_installed ) {
|
||||
print STDOUT " $mbx ($mbx1)\n";
|
||||
} else {
|
||||
print STDOUT " $mbx\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
logout( $conn );
|
||||
|
||||
sub init {
|
||||
|
||||
# Determine whether we have SSL support via openSSL and IO::Socket::SSL
|
||||
$ssl_installed = 1;
|
||||
eval 'use IO::Socket::SSL';
|
||||
if ( $@ ) {
|
||||
$ssl_installed = 0;
|
||||
}
|
||||
|
||||
$utf7_installed = 1;
|
||||
eval 'use Encode::IMAPUTF7 qw/decode/';
|
||||
if ( $@ ) {
|
||||
$utf7_installed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
sub getArgs {
|
||||
|
||||
getopts( "h:u:p:dmA:I" );
|
||||
$host = $opt_h;
|
||||
$user = $opt_u;
|
||||
$pwd = $opt_p;
|
||||
$debug = $opt_d;
|
||||
$admin_user = $opt_A;
|
||||
$list_mbxs = 1 if $opt_m;
|
||||
$showIMAP = 1 if $opt_I;
|
||||
|
||||
if ( $admin_user ) {
|
||||
# Don't need user password
|
||||
$pwd = 'XXXX';
|
||||
}
|
||||
|
||||
if ( $opt_H ) {
|
||||
usage();
|
||||
}
|
||||
|
||||
if ( !$host or !$user or !$pwd ) {
|
||||
usage();
|
||||
}
|
||||
|
||||
return ($host,$user,$pwd);
|
||||
|
||||
}
|
||||
|
||||
sub usage {
|
||||
|
||||
print STDOUT "usage: imapCapability.pl -h <host> -u <user> -p <password>\n";
|
||||
print STDOUT " Option argument: -m (list mailboxes)\n";
|
||||
exit;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub connectToHost {
|
||||
|
||||
my $host = shift;
|
||||
my $conn = shift;
|
||||
|
||||
($host,$port) = split(/:/, $host);
|
||||
$port = 143 unless $port;
|
||||
|
||||
# We know whether to use SSL for ports 143 and 993. For any
|
||||
# other ones we'll have to figure it out.
|
||||
$mode = sslmode( $host, $port );
|
||||
|
||||
if ( $mode eq 'SSL' ) {
|
||||
unless( $ssl_installed == 1 ) {
|
||||
warn("You must have openSSL and IO::Socket::SSL installed to use an SSL connection");
|
||||
exit;
|
||||
}
|
||||
print "Attempting an SSL connection\n" if $debug;
|
||||
$$conn = IO::Socket::SSL->new(
|
||||
Proto => "tcp",
|
||||
SSL_verify_mode => 0x00,
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
Domain => AF_INET,
|
||||
);
|
||||
|
||||
unless ( $$conn ) {
|
||||
$error = IO::Socket::SSL::errstr();
|
||||
print "Error connecting to $host: $error\n";
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
# Non-SSL connection
|
||||
print "Attempting a non-SSL connection\n" if $debug;
|
||||
$$conn = IO::Socket::INET->new(
|
||||
Proto => "tcp",
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
);
|
||||
|
||||
unless ( $$conn ) {
|
||||
print "Error connecting to $host:$port: $@\n";
|
||||
warn "Error connecting to $host:$port: $@";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
print "Connected to $host on port $port\n";
|
||||
|
||||
}
|
||||
|
||||
sub sslmode {
|
||||
|
||||
my $host = shift;
|
||||
my $port = shift;
|
||||
my $mode;
|
||||
|
||||
# Determine whether to make an SSL connection
|
||||
# to the host. Return 'SSL' if so.
|
||||
|
||||
if ( $port == 143 ) {
|
||||
# Standard non-SSL port
|
||||
return '';
|
||||
} elsif ( $port == 993 ) {
|
||||
# Standard SSL port
|
||||
return 'SSL';
|
||||
}
|
||||
|
||||
unless ( $ssl_installed ) {
|
||||
# We don't have SSL installed on this machine
|
||||
return '';
|
||||
}
|
||||
|
||||
# For any other port we need to determine whether it supports SSL
|
||||
|
||||
my $conn = IO::Socket::SSL->new(
|
||||
Proto => "tcp",
|
||||
SSL_verify_mode => 0x00,
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
);
|
||||
|
||||
if ( $conn ) {
|
||||
close( $conn );
|
||||
$mode = 'SSL';
|
||||
} else {
|
||||
$mode = '';
|
||||
}
|
||||
|
||||
return $mode;
|
||||
}
|
||||
|
||||
|
||||
sub login {
|
||||
|
||||
my $user = shift;
|
||||
my $pwd = shift;
|
||||
my $conn = shift;
|
||||
|
||||
if ( $admin_user ) {
|
||||
# An AUTHENTICATE = PLAIN login has been requested
|
||||
($authuser,$authpwd) = split(/:/, $admin_user );
|
||||
login_plain( $user, $authuser, $authpwd, $conn ) or exit;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( $pwd =~ /^oauth2:(.+)/i ) {
|
||||
$token = $1;
|
||||
Log("password is an OAUTH2 token");
|
||||
login_xoauth2( $user, $token, $conn );
|
||||
return 1;
|
||||
}
|
||||
|
||||
sendCommand ($conn, "1 LOGIN $user $pwd");
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
last if $response =~ /^1 OK/i;
|
||||
if ($response =~ /^1 NO|^1 BAD/i) {
|
||||
print "Unexpected LOGIN response: $response\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
print "Logged in as $user\n" if $debug;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# login_plain
|
||||
#
|
||||
# login in at the source host with the user's name and password. If provided
|
||||
# with administrator credential, use them as this eliminates the need for the
|
||||
# user's password.
|
||||
#
|
||||
sub login_plain {
|
||||
|
||||
my $user = shift;
|
||||
my $admin = shift;
|
||||
my $pwd = shift;
|
||||
my $conn = shift;
|
||||
|
||||
# Do an AUTHENTICATE = PLAIN. If an admin user has been provided then use it.
|
||||
|
||||
if ( !$admin ) {
|
||||
# Log in as the user
|
||||
$admin = $user
|
||||
}
|
||||
|
||||
$login_str = sprintf("%s\x00%s\x00%s", $user,$admin,$pwd);
|
||||
$login_str = encode_base64("$login_str", "");
|
||||
$len = length( $login_str );
|
||||
|
||||
# sendCommand ($conn, "1 AUTHENTICATE \"PLAIN\" {$len}" );
|
||||
sendCommand ($conn, "1 AUTHENTICATE PLAIN" );
|
||||
|
||||
my $loops;
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
last if $response =~ /\+/;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
exit;
|
||||
}
|
||||
$last if $loops++ > 5;
|
||||
}
|
||||
|
||||
sendCommand ($conn, "$login_str" );
|
||||
my $loops;
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
|
||||
if ( $response =~ /Microsoft Exchange/i and $conn eq $dst ) {
|
||||
# The destination is an Exchange server
|
||||
$exchange = 1;
|
||||
Log("The destination is an Exchange server");
|
||||
}
|
||||
|
||||
last if $response =~ /^1 OK/i;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
exit;
|
||||
}
|
||||
$last if $loops++ > 5;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
# login_xoauth2
|
||||
#
|
||||
# login in at the source host with the user's name and an XOAUTH2 token.
|
||||
#
|
||||
sub login_xoauth2 {
|
||||
|
||||
my $user = shift;
|
||||
my $token = shift;
|
||||
my $conn = shift;
|
||||
|
||||
# Do an AUTHENTICATE = XOAUTH2 login
|
||||
|
||||
$login_str = encode_base64("user=". $user ."\x01auth=Bearer ". $token ."\x01\x01", '');
|
||||
sendCommand ($conn, "1 AUTHENTICATE XOAUTH2 $login_str" );
|
||||
|
||||
my $loops;
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
if ( $response =~ /^\+ (.+)/ ) {
|
||||
$error = decode_base64( $1 );
|
||||
Log("XOAUTH authentication as $user failed: $error");
|
||||
return 0;
|
||||
}
|
||||
last if $response =~ /^1 OK/;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE|failed/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
return 0;
|
||||
}
|
||||
$last if $loops++ > 5;
|
||||
}
|
||||
|
||||
Log("login complete") if $debug;
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
sub capability {
|
||||
|
||||
my $conn = shift;
|
||||
my @response;
|
||||
my $capability;
|
||||
|
||||
sendCommand ($conn, "1 CAPABILITY");
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
$capability = $response if $response =~ /\* CAPABILITY/i;
|
||||
last if $response =~ /^1 OK/i;
|
||||
if ($response =~ /^1 NO|^1 BAD/i) {
|
||||
print "Unexpected response: $response\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
print STDOUT "\nThe server supports the following IMAP capabilities:\n\n";
|
||||
$capability =~ s/^\* CAPABILITY //;
|
||||
print "$capability\n";
|
||||
|
||||
}
|
||||
|
||||
sub logout {
|
||||
|
||||
my $conn = shift;
|
||||
|
||||
undef @response;
|
||||
sendCommand ($conn, "1 LOGOUT");
|
||||
while ( 1 ) {
|
||||
readResponse ($conn);
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
print "Unexpected LOGOUT response: $response\n";
|
||||
last;
|
||||
}
|
||||
}
|
||||
close $conn;
|
||||
return;
|
||||
}
|
||||
|
||||
sub sendCommand {
|
||||
|
||||
my $fd = shift;
|
||||
my $cmd = shift;
|
||||
|
||||
print $fd "$cmd\r\n";
|
||||
print STDOUT "$cmd\n" if $showIMAP;
|
||||
}
|
||||
|
||||
sub readResponse {
|
||||
|
||||
my $fd = shift;
|
||||
|
||||
$response = <$fd>;
|
||||
chop $response;
|
||||
$response =~ s/\r//g;
|
||||
push (@response,$response);
|
||||
print STDOUT "$response\n" if $showIMAP;
|
||||
}
|
||||
|
||||
|
||||
# listMailboxes
|
||||
#
|
||||
# Get a list of the user's mailboxes
|
||||
#
|
||||
sub listMailboxes {
|
||||
|
||||
my $conn = shift;
|
||||
|
||||
sendCommand ($conn, "1 LIST \"\" *");
|
||||
undef @response;
|
||||
while ( 1 ) {
|
||||
&readResponse ($conn);
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
&Log ("unexpected response: $response");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@mbxs = ();
|
||||
for $i (0 .. $#response) {
|
||||
$response[$i] =~ s/\s+/ /;
|
||||
if ( $response[$i] =~ /"$/ ) {
|
||||
$response[$i] =~ /\* LIST \((.*)\) "(.+)" "(.+)"/i;
|
||||
$mbx = $3;
|
||||
} elsif ( $response[$i] =~ /\* LIST \((.*)\) NIL (.+)/i ) {
|
||||
$mbx = $2;
|
||||
} else {
|
||||
$response[$i] =~ /\* LIST \((.*)\) "(.+)" (.+)/i;
|
||||
$mbx = $3;
|
||||
}
|
||||
$mbx =~ s/^\s+//; $mbx =~ s/\s+$//;
|
||||
push ( @mbxs, $mbx ) if $mbx ne '';
|
||||
}
|
||||
|
||||
return @mbxs;
|
||||
}
|
||||
|
||||
sub isAscii {
|
||||
|
||||
my $str = shift;
|
||||
my $ascii = 1;
|
||||
|
||||
# Determine whether a string contains non-ASCII characters
|
||||
|
||||
my $test = $str;
|
||||
$test=~s/\P{IsASCII}/?/g;
|
||||
$ascii = 0 unless $test eq $str;
|
||||
|
||||
return $ascii;
|
||||
|
||||
}
|
||||
|
||||
sub Log {
|
||||
|
||||
my $str = shift;
|
||||
|
||||
print STDERR "$str\n";
|
||||
|
||||
}
|
488
S/imap_tools.V1.333/imapPing.pl
Executable file
488
S/imap_tools.V1.333/imapPing.pl
Executable file
@ -0,0 +1,488 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# $Header: /mhub4/sources/imap-tools/imapPing.pl,v 1.3 2013/09/30 14:27:38 rick Exp $
|
||||
|
||||
############################################################################
|
||||
# Program imapPing.pl #
|
||||
# Date 20 January 2008 #
|
||||
# #
|
||||
# Description #
|
||||
# #
|
||||
# This script performs some basic IMAP operations on a user's #
|
||||
# account and displays the time as each one is executed. The #
|
||||
# operations are: #
|
||||
# 1. Connect to the IMAP server #
|
||||
# 2. Log in with the user's name and password #
|
||||
# 3. Get a list of mailboxes in the user's account #
|
||||
# 4. Select the INBOX #
|
||||
# 5. Get a list of messages in the INBOX #
|
||||
# 6. Log off the server #
|
||||
# #
|
||||
# Usage: imapPing.pl -h <host> -u <user> -p <password> #
|
||||
# #
|
||||
############################################################################
|
||||
# Copyright (c) 2008 Rick Sanders <rfs9999@earthlink.net> #
|
||||
# #
|
||||
# Permission to use, copy, modify, and distribute this software for any #
|
||||
# purpose with or without fee is hereby granted, provided that the above #
|
||||
# copyright notice and this permission notice appear in all copies. #
|
||||
# #
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES #
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF #
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR #
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES #
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN #
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF #
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #
|
||||
############################################################################
|
||||
|
||||
use Getopt::Std;
|
||||
use Socket;
|
||||
use FileHandle;
|
||||
use Fcntl;
|
||||
use IO::Socket;
|
||||
use MIME::Base64 qw(encode_base64);
|
||||
|
||||
init();
|
||||
($host,$user,$pwd) = getArgs();
|
||||
|
||||
print STDOUT pack( "A35 A10", "Connecting to $host", getTime() );
|
||||
connectToHost( $host, \$conn );
|
||||
|
||||
print STDOUT pack( "A35 A10","Logging in as $user", getTime() );
|
||||
login( $user,$pwd, $conn );
|
||||
|
||||
print STDOUT pack( "A35 A10","Get list of mailboxes", getTime() );
|
||||
getMailboxList( $conn );
|
||||
|
||||
print STDOUT pack( "A35 A10","Selecting the INBOX", getTime() );
|
||||
selectMbx( 'INBOX', $conn ) if $rc;
|
||||
|
||||
print STDOUT pack( "A35 A10","Get list of msgs in INBOX", getTime() );
|
||||
getMsgList( 'INBOX', $conn );
|
||||
|
||||
print STDOUT pack( "A35 A10","Logging out", getTime() );
|
||||
logout( $conn );
|
||||
|
||||
print STDOUT pack( "A35 A10","Done", getTime() );
|
||||
|
||||
exit;
|
||||
|
||||
exit 1;
|
||||
|
||||
|
||||
sub init {
|
||||
|
||||
# Determine whether we have SSL support via openSSL and IO::Socket::SSL
|
||||
$ssl_installed = 1;
|
||||
eval 'use IO::Socket::SSL';
|
||||
if ( $@ ) {
|
||||
$ssl_installed = 0;
|
||||
}
|
||||
|
||||
getTime();
|
||||
$debug = 1;
|
||||
}
|
||||
|
||||
sub getTime {
|
||||
|
||||
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
|
||||
if ($year < 99) { $yr = 2000; }
|
||||
else { $yr = 1900; }
|
||||
$date = sprintf ("%.2d-%.2d-%d.%.2d:%.2d:%.2d \n",
|
||||
$mon+1,$mday,$year+$yr,$hour,$min,$sec);
|
||||
$time = sprintf ("%.2d:%.2d:%.2d \n",$hour,$min,$sec);
|
||||
|
||||
return $time;
|
||||
}
|
||||
|
||||
sub getArgs {
|
||||
|
||||
getopts( "h:u:p:A:" );
|
||||
$host = $opt_h;
|
||||
$user = $opt_u;
|
||||
$pwd = $opt_p;
|
||||
$admin_user = $opt_A;
|
||||
$showIMAP = 1 if $opt_I;
|
||||
|
||||
if ( $opt_H ) {
|
||||
usage();
|
||||
}
|
||||
|
||||
if ( $admin_user ) {
|
||||
$pwd = 'XXX'; # Don't need the user's password
|
||||
}
|
||||
|
||||
unless ( $host and $user and $pwd ) {
|
||||
usage();
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
return ($host,$user,$pwd);
|
||||
|
||||
}
|
||||
|
||||
# sendCommand
|
||||
#
|
||||
# This subroutine formats and sends an IMAP protocol command to an
|
||||
# IMAP server on a specified connection.
|
||||
#
|
||||
|
||||
sub sendCommand
|
||||
{
|
||||
local($fd) = shift @_;
|
||||
local($cmd) = shift @_;
|
||||
|
||||
print $fd "$cmd\r\n";
|
||||
print STDOUT ">> $cmd\n" if $showIMAP;
|
||||
}
|
||||
|
||||
#
|
||||
# readResponse
|
||||
#
|
||||
# This subroutine reads and formats an IMAP protocol response from an
|
||||
# IMAP server on a specified connection.
|
||||
#
|
||||
|
||||
sub readResponse
|
||||
{
|
||||
local($fd) = shift @_;
|
||||
|
||||
$response = <$fd>;
|
||||
chop $response;
|
||||
$response =~ s/\r//g;
|
||||
push (@response,$response);
|
||||
print STDOUT "<< $response\n" if $showIMAP;
|
||||
}
|
||||
|
||||
# Make a connection to an IMAP host
|
||||
|
||||
sub connectToHost {
|
||||
|
||||
my $host = shift;
|
||||
my $conn = shift;
|
||||
|
||||
($host,$port) = split(/:/, $host);
|
||||
$port = 143 unless $port;
|
||||
|
||||
# We know whether to use SSL for ports 143 and 993. For any
|
||||
# other ones we'll have to figure it out.
|
||||
$mode = sslmode( $host, $port );
|
||||
|
||||
if ( $mode eq 'SSL' ) {
|
||||
unless( $ssl_installed == 1 ) {
|
||||
warn("You must have openSSL and IO::Socket::SSL installed to use an SSL connection");
|
||||
exit;
|
||||
}
|
||||
$$conn = IO::Socket::SSL->new(
|
||||
Proto => "tcp",
|
||||
SSL_verify_mode => 0x00,
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
Domain => AF_INET,
|
||||
);
|
||||
|
||||
unless ( $$conn ) {
|
||||
$error = IO::Socket::SSL::errstr();
|
||||
warn("Error connecting to $host: $error");
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
# Non-SSL connection
|
||||
$$conn = IO::Socket::INET->new(
|
||||
Proto => "tcp",
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
);
|
||||
|
||||
unless ( $$conn ) {
|
||||
warn "Error connecting to $host:$port: $@";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub sslmode {
|
||||
|
||||
my $host = shift;
|
||||
my $port = shift;
|
||||
my $mode;
|
||||
|
||||
# Determine whether to make an SSL connection
|
||||
# to the host. Return 'SSL' if so.
|
||||
|
||||
if ( $port == 143 ) {
|
||||
# Standard non-SSL port
|
||||
return '';
|
||||
} elsif ( $port == 993 ) {
|
||||
# Standard SSL port
|
||||
return 'SSL';
|
||||
}
|
||||
|
||||
unless ( $ssl_installed ) {
|
||||
# We don't have SSL installed on this machine
|
||||
return '';
|
||||
}
|
||||
|
||||
# For any other port we need to determine whether it supports SSL
|
||||
|
||||
my $conn = IO::Socket::SSL->new(
|
||||
Proto => "tcp",
|
||||
SSL_verify_mode => 0x00,
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
);
|
||||
|
||||
if ( $conn ) {
|
||||
close( $conn );
|
||||
$mode = 'SSL';
|
||||
} else {
|
||||
$mode = '';
|
||||
}
|
||||
|
||||
return $mode;
|
||||
}
|
||||
|
||||
|
||||
# login
|
||||
#
|
||||
# login in at the source host with the user's name and password
|
||||
#
|
||||
sub login {
|
||||
|
||||
my $user = shift;
|
||||
my $pwd = shift;
|
||||
my $conn = shift;
|
||||
|
||||
if ( $admin_user ) {
|
||||
# An AUTHENTICATE = PLAIN login has been requested
|
||||
($authuser,$authpwd) = split(/:/, $admin_user );
|
||||
login_plain( $user, $authuser, $authpwd, $conn ) or exit;
|
||||
return 1;
|
||||
}
|
||||
|
||||
sendCommand ($conn, "1 LOGIN $user $pwd");
|
||||
while (1) {
|
||||
readResponse ($conn);
|
||||
if ($response =~ /^1 OK/i) {
|
||||
last;
|
||||
}
|
||||
elsif ($response !~ /^\*/) {
|
||||
print STDOUT "Unexpected login response $response\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# login_plain
|
||||
#
|
||||
# login in at the source host with the user's name and password. If provided
|
||||
# with administrator credential, use them as this eliminates the need for the
|
||||
# user's password.
|
||||
#
|
||||
sub login_plain {
|
||||
|
||||
my $user = shift;
|
||||
my $admin = shift;
|
||||
my $pwd = shift;
|
||||
my $conn = shift;
|
||||
|
||||
# Do an AUTHENTICATE = PLAIN. If an admin user has been provided then use it.
|
||||
|
||||
if ( !$admin ) {
|
||||
# Log in as the user
|
||||
$admin = $user
|
||||
}
|
||||
|
||||
$login_str = sprintf("%s\x00%s\x00%s", $user,$admin,$pwd);
|
||||
$login_str = encode_base64("$login_str", "");
|
||||
$len = length( $login_str );
|
||||
|
||||
# sendCommand ($conn, "1 AUTHENTICATE \"PLAIN\" {$len}" );
|
||||
sendCommand ($conn, "1 AUTHENTICATE PLAIN" );
|
||||
|
||||
my $loops;
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
last if $response =~ /\+/;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
exit;
|
||||
}
|
||||
$last if $loops++ > 5;
|
||||
}
|
||||
|
||||
sendCommand ($conn, "$login_str" );
|
||||
my $loops;
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
|
||||
if ( $response =~ /Microsoft Exchange/i and $conn eq $dst ) {
|
||||
# The destination is an Exchange server
|
||||
$exchange = 1;
|
||||
Log("The destination is an Exchange server");
|
||||
}
|
||||
|
||||
last if $response =~ /^1 OK/i;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
exit;
|
||||
}
|
||||
$last if $loops++ > 5;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
# logout
|
||||
#
|
||||
# log out from the source host
|
||||
#
|
||||
sub logout {
|
||||
|
||||
my $conn = shift;
|
||||
|
||||
# print STDOUT "Logging out\n" if $debug;
|
||||
sendCommand ($conn, "1 LOGOUT");
|
||||
while ( 1 ) {
|
||||
readResponse ($conn);
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
print STDOUT "unexpected LOGOUT response: $response\n";
|
||||
last;
|
||||
}
|
||||
}
|
||||
close $conn;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub usage {
|
||||
|
||||
print STDOUT "\nUsage: imapPing.pl <args> \n\n";
|
||||
print STDOUT " -h <hostname>\n";
|
||||
print STDOUT " -u <user>\n";
|
||||
print STDOUT " -p <password>\n";
|
||||
|
||||
exit;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub selectInbox {
|
||||
|
||||
my $mbx = shift;
|
||||
my $conn = shift;
|
||||
|
||||
# Select a mailbox
|
||||
|
||||
sendCommand ($conn, "1 SELECT $mbx");
|
||||
while (1) {
|
||||
readResponse ($conn);
|
||||
if ($response =~ /^1 OK/i) {
|
||||
last;
|
||||
}
|
||||
elsif ($response !~ /^\*/) {
|
||||
print STDOUT "Unexpected SELECT INBOX response: $response\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub getMailboxList {
|
||||
|
||||
my $conn = shift;
|
||||
|
||||
# Get a list of the user's mailboxes
|
||||
|
||||
sendCommand ($conn, "1 LIST \"\" *");
|
||||
@response = ();
|
||||
while ( 1 ) {
|
||||
readResponse ($conn);
|
||||
last if $response =~ /^1 OK/i;
|
||||
|
||||
if ( $response !~ /^\*/ ) {
|
||||
print STDOUT "unexpected response: $response\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@mbxs = ();
|
||||
for $i (0 .. $#response) {
|
||||
# print STDERR "$response[$i]\n";
|
||||
$response[$i] =~ s/\s+/ /;
|
||||
($dmy,$mbx) = split(/"\/"/,$response[$i]);
|
||||
$mbx =~ s/^\s+//; $mbx =~ s/\s+$//;
|
||||
$mbx =~ s/"//g;
|
||||
|
||||
if ($mbx =~ /^\#/) {
|
||||
# Skip public mbxs
|
||||
next;
|
||||
}
|
||||
|
||||
if ($mbx ne '') {
|
||||
push(@mbxs,$mbx);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub getMsgList {
|
||||
|
||||
my $mailbox = shift;
|
||||
my $conn = shift;
|
||||
|
||||
# Select the mailbox in read-only mode
|
||||
|
||||
sendCommand ($conn, "1 EXAMINE \"$mailbox\"");
|
||||
undef @response;
|
||||
$empty=0;
|
||||
while ( 1 ) {
|
||||
readResponse ($conn);
|
||||
|
||||
last if $response =~ /^1 OK/i;
|
||||
|
||||
if ( $response !~ /^\*/ ) {
|
||||
print STDOUT "Error: $response\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
sendCommand ($conn, "1 FETCH 1:* (UID FLAGS)");
|
||||
undef @response;
|
||||
while ( 1 ) {
|
||||
readResponse ($conn);
|
||||
last if $response =~ /^1 OK/i;
|
||||
if ( $response !~ /^\*/ ) {
|
||||
print STDOUT "Unexpected response: $response\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
# Get a list of the msgs in the mailbox
|
||||
#
|
||||
undef @msgs;
|
||||
for $i (0 .. $#response) {
|
||||
$_ = $response[$i];
|
||||
$_ =~ /\* ([^FETCH]*)/;
|
||||
$uid = $1;
|
||||
$uid =~ s/\s+$//;
|
||||
if ($response[$i] =~ /\\Seen/) { $seen = 1; }
|
||||
if (($uid ne 'OK') && ($uid ne '')) {
|
||||
push (@msgs,"$uid $seen");
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
1913
S/imap_tools.V1.333/imap_audit.pl
Executable file
1913
S/imap_tools.V1.333/imap_audit.pl
Executable file
File diff suppressed because it is too large
Load Diff
1940
S/imap_tools.V1.333/imap_search.pl
Executable file
1940
S/imap_tools.V1.333/imap_search.pl
Executable file
File diff suppressed because it is too large
Load Diff
1118
S/imap_tools.V1.333/imap_to_maildir.pl
Executable file
1118
S/imap_tools.V1.333/imap_to_maildir.pl
Executable file
File diff suppressed because it is too large
Load Diff
5
S/imap_tools.V1.333/imapcopy.cf
Normal file
5
S/imap_tools.V1.333/imapcopy.cf
Normal file
@ -0,0 +1,5 @@
|
||||
LOGFILE: imapcopy.log
|
||||
IMAPCOPY: imapcopy.pl
|
||||
PROCESS_LIMIT: 8
|
||||
DEBUG: 0
|
||||
SHOWIMAP: 0
|
598
S/imap_tools.V1.333/imapcopy.cgi
Normal file
598
S/imap_tools.V1.333/imapcopy.cgi
Normal file
@ -0,0 +1,598 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# $Header: /mhub4/sources/imap-tools/imapcopy.cgi,v 1.9 2014/08/18 15:17:22 rick Exp $
|
||||
|
||||
#######################################################################
|
||||
# Program name imapcopy.cgi #
|
||||
# Written by Rick Sanders #
|
||||
# #
|
||||
# Description #
|
||||
# #
|
||||
# imapcopy.cgi is used to manage the imapcopy.pl script in CGI #
|
||||
# mode. #
|
||||
#######################################################################
|
||||
|
||||
use Socket;
|
||||
use FileHandle;
|
||||
use Fcntl;
|
||||
use Getopt::Std;
|
||||
use CGI;
|
||||
use CGI::Carp qw(fatalsToBrowser);
|
||||
use IO::Socket;
|
||||
use POSIX 'setsid';
|
||||
use Cwd;
|
||||
|
||||
init();
|
||||
get_html();
|
||||
|
||||
# Check the source and dest logins in case the user has provided
|
||||
# invalid credentials or host names
|
||||
|
||||
test_logins();
|
||||
|
||||
# To prevent someone from seeing the passwords in ps pass them
|
||||
# as ENV variables.
|
||||
|
||||
$ENV{SOURCEPWD} = $sourcePwd;
|
||||
$ENV{DESTPWD} = $destPwd;
|
||||
|
||||
my $cmd = "$imapcopy ";
|
||||
$cmd .= "-S $sourceHost/$sourceUser/SOURCEPWD ";
|
||||
$cmd .= "-D $destHost/$destUser/DESTPWD ";
|
||||
$cmd .= "-I " if $DEFAULTS{'SHOWIMAP'} == 1;
|
||||
$cmd .= "-d " if $DEFAULTS{'DEBUG'} == 1;
|
||||
$cmd .= "-L $logfile " if $logfile;
|
||||
$cmd .= "-m \"$mbxList\" " if $mbxList;
|
||||
$cmd .= "-e \"$excludeMbxs\" " if $excludeMbxs;
|
||||
$cmd .= "-a $sent_after " if $sent_after;
|
||||
$cmd .= "-b $sent_before " if $sent_before;
|
||||
$cmd .= "-U " if $update;
|
||||
$cmd .= "$DEFAULTS{ARGUMENTS} " if $DEFAULTS{ARGUMENTS};
|
||||
|
||||
launch_daemon( $cmd );
|
||||
|
||||
print STDOUT "<b><br>Your copy job has been started. You will be notified when it has completed</b><br>";
|
||||
|
||||
exit;
|
||||
|
||||
|
||||
sub init {
|
||||
|
||||
$os = $ENV{'OS'};
|
||||
|
||||
print "Content-type: text/html\n\n<html>\n";
|
||||
print '<meta equiv="refresh" content="5">';
|
||||
print '</head>';
|
||||
print '<title>IMAP Copy</title>';
|
||||
print '<body style="background-color:#FFF8C6" bgproperties="fixed" bgcolor="#FFFFFF" text="#000000"
|
||||
link="#050473" vlink="#6B6AF5" alink="#840000">';
|
||||
|
||||
if ( -e "imapcopy.cf" ) {
|
||||
open(CF, "<imapcopy.cf") or print "Can't open imapcopy.cf: $!";
|
||||
}
|
||||
while( <CF> ) {
|
||||
chomp;
|
||||
($kw,$value) = split(/\s*:\s*/, $_, 2);
|
||||
$DEFAULTS{$kw} = $value;
|
||||
}
|
||||
close CF;
|
||||
|
||||
if ( $DEFAULTS{'IMAPCOPY'} ) {
|
||||
$imapcopy = $DEFAULTS{'IMAPCOPY'};
|
||||
} else {
|
||||
my $here = getcwd;
|
||||
$imapcopy = "$here/imapcopy.pl";
|
||||
}
|
||||
|
||||
$logfile = $DEFAULTS{'LOGFILE'};
|
||||
if ( $logfile ) {
|
||||
if ( !open(LOG, ">> $logfile")) {
|
||||
print STDOUT "Can't open $logfile: $!\n";
|
||||
exit;
|
||||
}
|
||||
select(LOG); $| = 1;
|
||||
}
|
||||
Log("$0 starting");
|
||||
|
||||
$count = count_imapcopy_processes();
|
||||
if ( $DEFAULTS{PROCESS_LIMIT} ) {
|
||||
exit if $count > $DEFAULTS{PROCESS_LIMIT};
|
||||
}
|
||||
|
||||
# Determine whether we have SSL support via openSSL and IO::Socket::SSL
|
||||
$ssl_installed = 1;
|
||||
eval 'use IO::Socket::SSL';
|
||||
if ( $@ ) {
|
||||
$ssl_installed = 0;
|
||||
}
|
||||
|
||||
# Set up signal handling
|
||||
$SIG{'ALRM'} = 'signalHandler';
|
||||
$SIG{'HUP'} = 'signalHandler';
|
||||
$SIG{'INT'} = 'signalHandler';
|
||||
$SIG{'TERM'} = 'signalHandler';
|
||||
$SIG{'URG'} = 'signalHandler';
|
||||
|
||||
}
|
||||
|
||||
sub launch_daemon {
|
||||
|
||||
my $cmd = shift;
|
||||
my $parent = $$;
|
||||
use POSIX 'setsid';
|
||||
|
||||
# The purpose of this routine is to launch imapcopy as a grandkid which detaches
|
||||
# it from the Apache process so that it will not die if the user closes his browser.
|
||||
|
||||
print STDOUT "Your copy job has been started. You will be notified when it has completed.";
|
||||
|
||||
if ( !defined (my $kid = fork) ) {
|
||||
print STDOUT "Cannot fork a child process: $!<br>";
|
||||
Log("Cannot fork: $!");
|
||||
exit;
|
||||
}
|
||||
if ( $kid ) {
|
||||
exit(0);
|
||||
} else {
|
||||
close STDIN;
|
||||
close STDOUT;
|
||||
close STDERR;
|
||||
if ( !setsid ) {
|
||||
Log("Cannot execute 'setsid', exiting");
|
||||
exit;
|
||||
}
|
||||
|
||||
umask(0027); # create files with perms -rw-r-----
|
||||
if ( !chdir '/' ) {
|
||||
Log("Can't chdir to /: $!");
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( !(open STDIN, '<', '/dev/null') ) {
|
||||
Log("Cannot redirect STDIN: $!");
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( !(open STDOUT, '>', '/dev/null') ) {
|
||||
Log("Cannot redirect STDOUT: $!");
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( !(open STDERR, '>>', $logfile) ) {
|
||||
Log("Cannot redirect STDERR to $logfile: $!");
|
||||
Log("Check the path and permissions on $logfile");
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( !defined (my $grandkid = fork) ) {
|
||||
exit;
|
||||
} else {
|
||||
if ( $grandkid != 0 and $$ != $parent ) {
|
||||
Log("Execute $cmd");
|
||||
$rc = `$cmd`;
|
||||
Log("rc = $rc");
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub get_html {
|
||||
|
||||
my $fields = shift;
|
||||
my $formData=0;
|
||||
|
||||
# Get the HTML form values
|
||||
#
|
||||
my $query = new CGI;
|
||||
|
||||
$sourceHost = $query->param('sourceHost');
|
||||
$sourceUser = $query->param('sourceUser');
|
||||
$sourcePwd = $query->param('sourcePwd');
|
||||
|
||||
$destHost = $query->param('destHost');
|
||||
$destUser = $query->param('destUser');
|
||||
$destPwd = $query->param('destPwd');
|
||||
|
||||
$mbxList = $query->param('mbxList');
|
||||
$excludeMbxs = $query->param('excludeMbxList');
|
||||
$sent_after = $query->param('sent_after');
|
||||
$sent_before = $query->param('sent_before');
|
||||
$update = $query->param('update');
|
||||
|
||||
$update = 1 if $update eq 'on';
|
||||
|
||||
}
|
||||
|
||||
sub Log {
|
||||
|
||||
my $str = shift;
|
||||
|
||||
if ( $logfile ) {
|
||||
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
|
||||
if ($year < 99) { $yr = 2000; }
|
||||
else { $yr = 1900; }
|
||||
$line = sprintf ("%.2d-%.2d-%d.%.2d:%.2d:%.2d %s\n",
|
||||
$mon + 1, $mday, $year + $yr, $hour, $min, $sec,$str);
|
||||
print LOG "$line";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
# login
|
||||
#
|
||||
# login in at the source host with the user's name and password
|
||||
#
|
||||
sub login {
|
||||
|
||||
my $user = shift;
|
||||
my $pwd = shift;
|
||||
my $host = shift;
|
||||
my $conn = shift;
|
||||
my $method = shift;
|
||||
|
||||
Log("method $method") if $debug;
|
||||
|
||||
return 1 if $method eq 'PREAUTH'; # Server pre-authenticates users
|
||||
|
||||
Log("Authenticating to $host as $user");
|
||||
if ( uc( $method ) eq 'CRAM-MD5' ) {
|
||||
# A CRAM-MD5 login is requested
|
||||
Log("login method $method");
|
||||
my $rc = login_cram_md5( $user, $pwd, $conn );
|
||||
return $rc;
|
||||
}
|
||||
|
||||
if ( $user =~ /(.+):(.+)/ ) {
|
||||
# An AUTHENTICATE = PLAIN login has been requested
|
||||
$sourceUser = $1;
|
||||
$authuser = $2;
|
||||
login_plain( $sourceUser, $authuser, $pwd, $conn ) or exit;
|
||||
return 1;
|
||||
}
|
||||
|
||||
# Otherwise do an ordinary login
|
||||
|
||||
sendCommand ($conn, "1 LOGIN $user \"$pwd\"");
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
|
||||
if ( $response =~ /Cyrus/i and $conn eq $dst ) {
|
||||
Log("Destination is a Cyrus server");
|
||||
$cyrus = 1;
|
||||
}
|
||||
|
||||
if ( $response =~ /Microsoft Exchange/i and $conn eq $dst ) {
|
||||
# The destination is an Exchange server
|
||||
unless ( $exchange_override ) {
|
||||
$exchange = 1;
|
||||
Log("The destination is an Exchange server");
|
||||
}
|
||||
}
|
||||
last if $response =~ /^1 OK/i;
|
||||
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Log("Logged in as $user") if $debug;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
sub login_cram_md5 {
|
||||
|
||||
my $user = shift;
|
||||
my $pwd = shift;
|
||||
my $conn = shift;
|
||||
|
||||
sendCommand ($conn, "1 AUTHENTICATE CRAM-MD5");
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
last if $response =~ /^\+/;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
my ($challenge) = $response =~ /^\+ (.+)/;
|
||||
|
||||
Log("challenge $challenge") if $debug;
|
||||
$response = cram_md5( $challenge, $user, $pwd );
|
||||
Log("response $response") if $debug;
|
||||
|
||||
sendCommand ($conn, $response);
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
|
||||
if ( $response =~ /Microsoft Exchange/i and $conn eq $dst ) {
|
||||
# The destination is an Exchange server
|
||||
$exchange = 1;
|
||||
Log("The destination is an Exchange server");
|
||||
}
|
||||
|
||||
last if $response =~ /^1 OK/i;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Log("Logged in as $user") if $debug;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# login_plain
|
||||
#
|
||||
# login in at the source host with the user's name and password. If provided
|
||||
# with administrator credential, use them as this eliminates the need for the
|
||||
# user's password.
|
||||
#
|
||||
sub login_plain {
|
||||
|
||||
my $user = shift;
|
||||
my $admin = shift;
|
||||
my $pwd = shift;
|
||||
my $conn = shift;
|
||||
|
||||
# Do an AUTHENTICATE = PLAIN. If an admin user has been provided then use it.
|
||||
|
||||
if ( !$admin ) {
|
||||
# Log in as the user
|
||||
$admin = $user
|
||||
}
|
||||
|
||||
$login_str = sprintf("%s\x00%s\x00%s", $user,$admin,$pwd);
|
||||
$login_str = encode_base64("$login_str", "");
|
||||
$len = length( $login_str );
|
||||
|
||||
# sendCommand ($conn, "1 AUTHENTICATE \"PLAIN\" {$len}" );
|
||||
sendCommand ($conn, "1 AUTHENTICATE PLAIN" );
|
||||
|
||||
my $loops;
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
last if $response =~ /\+/;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
exit;
|
||||
}
|
||||
$last if $loops++ > 5;
|
||||
}
|
||||
|
||||
sendCommand ($conn, "$login_str" );
|
||||
my $loops;
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
|
||||
if ( $response =~ /Cyrus/i and $conn eq $dst ) {
|
||||
Log("Destination is a Cyrus server");
|
||||
$cyrus = 1;
|
||||
}
|
||||
|
||||
if ( $response =~ /Microsoft Exchange/i and $conn eq $dst ) {
|
||||
# The destination is an Exchange server
|
||||
$exchange = 1;
|
||||
Log("The destination is an Exchange server");
|
||||
}
|
||||
|
||||
last if $response =~ /^1 OK/i;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
exit;
|
||||
}
|
||||
$last if $loops++ > 5;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
# logout
|
||||
#
|
||||
# log out from the host
|
||||
#
|
||||
sub logout {
|
||||
|
||||
my $conn = shift;
|
||||
|
||||
undef @response;
|
||||
sendCommand ($conn, "1 LOGOUT");
|
||||
while ( 1 ) {
|
||||
readResponse ($conn);
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
Log ("unexpected LOGOUT response: $response");
|
||||
last;
|
||||
}
|
||||
}
|
||||
close $conn;
|
||||
return;
|
||||
}
|
||||
|
||||
# Make a connection to a IMAP host
|
||||
|
||||
sub connectToHost {
|
||||
|
||||
my $host = shift;
|
||||
my $conn = shift;
|
||||
|
||||
Log("Connecting to $host") if $debug;
|
||||
|
||||
($host,$port) = split(/:/, $host);
|
||||
$port = 143 unless $port;
|
||||
|
||||
# We know whether to use SSL for ports 143 and 993. For any
|
||||
# other ones we'll have to figure it out.
|
||||
$mode = sslmode( $host, $port );
|
||||
|
||||
if ( $mode eq 'SSL' ) {
|
||||
unless( $ssl_installed == 1 ) {
|
||||
warn("You must have openSSL and IO::Socket::SSL installed to use an SSL connection");
|
||||
Log("You must have openSSL and IO::Socket::SSL installed to use an SSL connection");
|
||||
exit;
|
||||
}
|
||||
Log("Attempting an SSL connection") if $debug;
|
||||
$$conn = IO::Socket::SSL->new(
|
||||
Proto => "tcp",
|
||||
SSL_verify_mode => 0x00,
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
Domain => AF_INET,
|
||||
Timeout => 10,
|
||||
);
|
||||
|
||||
unless ( $$conn ) {
|
||||
$error = IO::Socket::SSL::errstr();
|
||||
Log("Error connecting to $host: $error");
|
||||
print STDOUT "<font color=red><b>Error: Can't connect to $host.<br>";
|
||||
print STDOUT "Hit the Back button on your browser, correct the info, and try again.";
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
# Non-SSL connection
|
||||
Log("Attempting a non-SSL connection") if $debug;
|
||||
$$conn = IO::Socket::INET->new(
|
||||
Proto => "tcp",
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
Timeout => 10,
|
||||
);
|
||||
|
||||
unless ( $$conn ) {
|
||||
Log("Error connecting to $host:$port: $@");
|
||||
print STDOUT "<font color=red><b>Error: Can't connect to $host.<br>";
|
||||
print STDOUT "Hit the Back button on your browser, correct the info, and try again.";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
Log("Connected to $host on port $port");
|
||||
|
||||
}
|
||||
|
||||
sub sslmode {
|
||||
|
||||
my $host = shift;
|
||||
my $port = shift;
|
||||
my $mode;
|
||||
|
||||
# Determine whether to make an SSL connection
|
||||
# to the host. Return 'SSL' if so.
|
||||
|
||||
if ( $port == 143 ) {
|
||||
# Standard non-SSL port
|
||||
return '';
|
||||
} elsif ( $port == 993 ) {
|
||||
# Standard SSL port
|
||||
return 'SSL';
|
||||
}
|
||||
|
||||
unless ( $ssl_installed ) {
|
||||
# We don't have SSL installed on this machine
|
||||
return '';
|
||||
}
|
||||
|
||||
# For any other port we need to determine whether it supports SSL
|
||||
|
||||
my $conn = IO::Socket::SSL->new(
|
||||
Proto => "tcp",
|
||||
SSL_verify_mode => 0x00,
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
);
|
||||
|
||||
if ( $conn ) {
|
||||
close( $conn );
|
||||
$mode = 'SSL';
|
||||
} else {
|
||||
$mode = '';
|
||||
}
|
||||
|
||||
return $mode;
|
||||
}
|
||||
|
||||
sub test_logins {
|
||||
|
||||
# Verify that we can log in at the source and destination before launching
|
||||
# the copy job.
|
||||
|
||||
print "<br><br>";
|
||||
if ( !connectToHost($sourceHost, \$src) ) {
|
||||
print STDOUT "<font color=red> <b>Error: Can't connect to $sourceHost. Check that $sourceHost is correct.<br>";
|
||||
print STDOUT "Hit the Back button on your browser, correct the info, and try again.";
|
||||
exit;
|
||||
}
|
||||
if ( !login($sourceUser,$sourcePwd, $sourceHost, $src, $srcMethod) ) {
|
||||
print STDOUT "<font color=red><b>Error: Can't login as $sourceUser. Check your username and password<br>";
|
||||
print STDOUT "Hit the Back button on your browser, correct the info, and try again.";
|
||||
exit;
|
||||
}
|
||||
if ( !connectToHost($destHost, \$dst) ) {
|
||||
print STDOUT "<font color=red><b>Error: Can't connect to $destHost. Check that $destHost is correct.\n";
|
||||
print STDOUT "Hit the Back button on your browser, correct the info, and try again.";
|
||||
exit;
|
||||
}
|
||||
if ( !login($destUser,$destPwd, $destHost, $dst, $dstMethod) ) {
|
||||
print STDOUT "<font color=red><b>Error: Can't login as $destUser. Check your username and password<br>";
|
||||
print STDOUT "Hit the Back button on your browser, correct the info, and try again.";
|
||||
exit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub sendCommand {
|
||||
|
||||
my $fd = shift;
|
||||
my $cmd = shift;
|
||||
|
||||
print $fd "$cmd\r\n";
|
||||
|
||||
Log (">> $cmd") if $showIMAP;
|
||||
}
|
||||
|
||||
#
|
||||
# readResponse
|
||||
#
|
||||
# This subroutine reads and formats an IMAP protocol response from an
|
||||
# IMAP server on a specified connection.
|
||||
#
|
||||
|
||||
sub readResponse {
|
||||
|
||||
my $fd = shift;
|
||||
|
||||
$response = <$fd>;
|
||||
chop $response;
|
||||
$response =~ s/\r//g;
|
||||
push (@response,$response);
|
||||
Log ("<< $response") if $showIMAP;
|
||||
}
|
||||
|
||||
sub count_imapcopy_processes {
|
||||
|
||||
my $count;
|
||||
|
||||
# Count how many imapcopy processes are currently running
|
||||
# and exit if the max has been reached.
|
||||
|
||||
foreach $_ ( `ps -ef | grep imapcopy.pl` ) {
|
||||
next unless /imapcopy.pl/;
|
||||
next if /grep/;
|
||||
$count++;
|
||||
}
|
||||
|
||||
$process_limit = $DEFAULTS{PROCESS_LIMIT};
|
||||
if ( $process_limit > 0 and $count > $process_limit ) {
|
||||
print STDOUT "<br><br><b>The maximum number of IMAP copies is already running. Please try again later.<br>";
|
||||
}
|
||||
return $count;
|
||||
|
||||
}
|
||||
|
86
S/imap_tools.V1.333/imapcopy.html
Normal file
86
S/imap_tools.V1.333/imapcopy.html
Normal file
@ -0,0 +1,86 @@
|
||||
|
||||
<html>
|
||||
<title>IMAPCOPY</title>
|
||||
<head>
|
||||
|
||||
<FORM name="imapcopy" method=post action="../cgi-bin/imapcopy.cgi" ENCTYPE="multipart/form-data">
|
||||
|
||||
<script language="javascript">
|
||||
var pageLoaded = false;
|
||||
function validate() {
|
||||
if ( !document.imapcopy.sourceHost.value ||
|
||||
!document.imapcopy.sourceUser.value ||
|
||||
!document.imapcopy.sourcePwd.value ||
|
||||
!document.imapcopy.destHost.value ||
|
||||
!document.imapcopy.destUser.value ||
|
||||
!document.imapcopy.destPwd.value
|
||||
) {
|
||||
alert("Please enter values for source & destination servers, source & destination usernames, and source & destination passwords");
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body style="background-color:#FFF8C6" bgproperties="fixed" bgcolor="#FFFFFF" text="#000000"
|
||||
link="#050473" vlink="#6B6AF5" alink="#840000">
|
||||
|
||||
<H3><font size=6 color="#0000ff"> IMAPCOPY</font></H3>
|
||||
|
||||
<br>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Source server
|
||||
<td><input type=text name=sourceHost value=SOURCEHOST>
|
||||
|
||||
<tr>
|
||||
<td>Destination server
|
||||
<td><input type=text name=destHost value=DESTHOST>
|
||||
<tr>
|
||||
<td>Source username <td><input type=text name=sourceUser>
|
||||
<td>Source password <td><input type=password name=sourcePwd>
|
||||
|
||||
<tr>
|
||||
<td>Destination username <td><input type=text name=destUser>
|
||||
<td>Destination password <td><input type=password name=destPwd>
|
||||
</table>
|
||||
|
||||
<br><br>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Copy only these folders
|
||||
<td><input type=text name="mbxList" size=35> folder1,folder2,...
|
||||
|
||||
<tr>
|
||||
<td>Exclude these folders
|
||||
<td><input type=text name="excludeMbxList" size=35> folder1,folder2,...
|
||||
|
||||
<tr>
|
||||
<td>After date
|
||||
<td><input type=text name=sent_after> DD-MMM-YYYY
|
||||
|
||||
<tr>
|
||||
<td>Before Date
|
||||
<td><input type=text name=sent_before> DD-MMM-YYYY
|
||||
|
||||
<tr>
|
||||
<td>Update Mode
|
||||
<td><input type=checkbox name=update><br>
|
||||
</table>
|
||||
|
||||
<br><br>
|
||||
<input type=submit value="Submit" onclick="return validate()">
|
||||
<input type=reset value="Clear form">
|
||||
|
||||
<br><br>
|
||||
After clicking on Submit the copy process will start.
|
||||
Depending on the size of your
|
||||
account it will take a few minutes or more to copy everything over.
|
||||
When it finishes you will receive an e-mail notifying of the results.
|
||||
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
3133
S/imap_tools.V1.333/imapcopy.pl
Executable file
3133
S/imap_tools.V1.333/imapcopy.pl
Executable file
File diff suppressed because it is too large
Load Diff
86
S/imap_tools.V1.333/imapcopy_de.html
Normal file
86
S/imap_tools.V1.333/imapcopy_de.html
Normal file
@ -0,0 +1,86 @@
|
||||
<html>
|
||||
<title>IMAPCOPY</title>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<FORM name="imapcopy" method=post action="imapcopy.cgi" ENCTYPE="multipart/form-data">
|
||||
|
||||
<script language="javascript">
|
||||
var pageLoaded = false;
|
||||
function validate() {
|
||||
if ( !document.imapcopy.sourceHost.value ||
|
||||
!document.imapcopy.sourceUser.value ||
|
||||
!document.imapcopy.sourcePwd.value ||
|
||||
!document.imapcopy.destHost.value ||
|
||||
!document.imapcopy.destUser.value ||
|
||||
!document.imapcopy.destPwd.value
|
||||
) {
|
||||
alert("Please enter values for source & destination servers, source & destination usernames, and source & destination passwords");
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body style="background-color:#FFF8C6" bgproperties="fixed" bgcolor="#FFFFFF" text="#000000"
|
||||
link="#050473" vlink="#6B6AF5" alink="#840000">
|
||||
|
||||
<H3><font size=6 color="#0000ff"> IMAPCOPY</font></H3>
|
||||
|
||||
<p>
|
||||
<a href="imapcopy_en.html"><img src="flag_en.gif" width="50" height="38" border="0" alt="EN"></a>
|
||||
<a href="imapcopy_de.html"><img src="flag_de.gif" width="50" height="38" border="0" alt="DE"></a>
|
||||
</p>
|
||||
|
||||
<br>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Quellserver:
|
||||
<td><input type=text name=sourceHost value=imap.quellserver.de>
|
||||
|
||||
<tr>
|
||||
<td>Zielserver:
|
||||
<td><input type=text name=destHost value=imap.zielserver.de>
|
||||
<tr>
|
||||
<td>Benutzername Quellserver:<td><input type=text name=sourceUser>
|
||||
<td>Passwort Quellserver:<td><input type=password name=sourcePwd>
|
||||
|
||||
<tr>
|
||||
<td>Benutzername Zielserver:<td><input type=text name=destUser>
|
||||
<td>Passwort Zielserver:<td><input type=password name=destPwd>
|
||||
</table>
|
||||
|
||||
<br><br>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Nur diese Ordner kopieren:
|
||||
<td><input type=text name="mbxList" size=35> Ordner1,Ordner2, ...
|
||||
|
||||
<tr>
|
||||
<td>Diese Ordner nicht kopieren:
|
||||
<td><input type=text name="excludeMbxList" size=35> Ordner1,Ordner2, ...
|
||||
|
||||
<tr>
|
||||
<td>Nachrichten kopieren nach Datum
|
||||
<td><input type=text name=sent_after> TT-MMM-JJJJ
|
||||
|
||||
<tr>
|
||||
<td>Nachrichten kopieren vor Datum
|
||||
<td><input type=text name=sent_before> TT-MMM-JJJJ
|
||||
|
||||
<tr>
|
||||
<td>Update Mode <br> (nur noch nicht kopierte Nachrichten)
|
||||
<td><input type=checkbox name=update><br>
|
||||
</table>
|
||||
|
||||
<br><br>
|
||||
<input type=submit value="Start imapcopy" onclick="return validate()">
|
||||
<input type=reset value="Formular löschen">
|
||||
|
||||
<br><br>
|
||||
Nach Start imapcopy wird der Kopierprozess gestartet. Abhängig von der Größe der zu kopierenden Accounts kann es einige Minuten oder länger dauern bis alle Nachrichten kopiert sind. Am Ende des Kopierprozesses erhalten Sie eine Nachricht per E-Mail.
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
91
S/imap_tools.V1.333/imapcopy_en.html
Normal file
91
S/imap_tools.V1.333/imapcopy_en.html
Normal file
@ -0,0 +1,91 @@
|
||||
|
||||
<html>
|
||||
<title>IMAPCOPY</title>
|
||||
<head>
|
||||
|
||||
<FORM name="imapcopy" method=post action="../cgi-bin/imapcopy.cgi" ENCTYPE="multipart/form-data">
|
||||
|
||||
<script language="javascript">
|
||||
var pageLoaded = false;
|
||||
function validate() {
|
||||
if ( !document.imapcopy.sourceHost.value ||
|
||||
!document.imapcopy.sourceUser.value ||
|
||||
!document.imapcopy.sourcePwd.value ||
|
||||
!document.imapcopy.destHost.value ||
|
||||
!document.imapcopy.destUser.value ||
|
||||
!document.imapcopy.destPwd.value
|
||||
) {
|
||||
alert("Please enter values for source & destination servers, source & destination usernames, and source & destination passwords");
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body style="background-color:#FFF8C6" bgproperties="fixed" bgcolor="#FFFFFF" text="#000000"
|
||||
link="#050473" vlink="#6B6AF5" alink="#840000">
|
||||
|
||||
<H3><font size=6 color="#0000ff"> IMAPCOPY</font></H3>
|
||||
|
||||
<p>
|
||||
<a href="imapcopy_en.html"><img src="flag_en.gif" width="50" height="38" border="0" alt="EN"></a>
|
||||
<a href="imapcopy_de.html"><img src="flag_de.gif" width="50" height="38" border="0" alt="DE"></a>
|
||||
</p>
|
||||
|
||||
<br>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Source server
|
||||
<td><input type=text name=sourceHost value=SOURCEHOST>
|
||||
|
||||
<tr>
|
||||
<td>Destination server
|
||||
<td><input type=text name=destHost value=DESTHOST>
|
||||
<tr>
|
||||
<td>Source username <td><input type=text name=sourceUser>
|
||||
<td>Source password <td><input type=password name=sourcePwd>
|
||||
|
||||
<tr>
|
||||
<td>Destination username <td><input type=text name=destUser>
|
||||
<td>Destination password <td><input type=password name=destPwd>
|
||||
</table>
|
||||
|
||||
<br><br>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Copy only these folders
|
||||
<td><input type=text name="mbxList" size=35> folder1,folder2,...
|
||||
|
||||
<tr>
|
||||
<td>Exclude these folders
|
||||
<td><input type=text name="excludeMbxList" size=35> folder1,folder2,...
|
||||
|
||||
<tr>
|
||||
<td>After date
|
||||
<td><input type=text name=sent_after> DD-MMM-YYYY
|
||||
|
||||
<tr>
|
||||
<td>Before Date
|
||||
<td><input type=text name=sent_before> DD-MMM-YYYY
|
||||
|
||||
<tr>
|
||||
<td>Update Mode
|
||||
<td><input type=checkbox name=update><br>
|
||||
</table>
|
||||
|
||||
<br><br>
|
||||
<input type=submit value="Submit" onclick="return validate()">
|
||||
<input type=reset value="Clear form">
|
||||
|
||||
<br><br>
|
||||
After clicking on Submit the copy process will start.
|
||||
Depending on the size of your
|
||||
account it will take a few minutes or more to copy everything over.
|
||||
When it finishes you will receive an e-mail notifying of the results.
|
||||
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
1697
S/imap_tools.V1.333/imapdump.pl
Executable file
1697
S/imap_tools.V1.333/imapdump.pl
Executable file
File diff suppressed because it is too large
Load Diff
2151
S/imap_tools.V1.333/imapfilter.pl
Normal file
2151
S/imap_tools.V1.333/imapfilter.pl
Normal file
File diff suppressed because it is too large
Load Diff
2348
S/imap_tools.V1.333/imapsync.pl
Executable file
2348
S/imap_tools.V1.333/imapsync.pl
Executable file
File diff suppressed because it is too large
Load Diff
21
S/imap_tools.V1.333/license.txt
Normal file
21
S/imap_tools.V1.333/license.txt
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
############################################################################
|
||||
# Copyright (c) 2012 Rick Sanders <rfs9999@earthlink.net> #
|
||||
# #
|
||||
# Permission to use, copy, and modify this software for any purpose #
|
||||
# is hereby granted, provided that the above copyright notice and this #
|
||||
# permission notice appear in all copies. #
|
||||
# #
|
||||
# This software is not assignable and may not be resold without the #
|
||||
# express written permission of the author. The sofware can be hosted #
|
||||
# on any or all of the license holder's servers and sites. #
|
||||
# #
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES #
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF #
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR #
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES #
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN #
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF #
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #
|
||||
############################################################################
|
||||
|
1183
S/imap_tools.V1.333/list_account_sizes.pl
Executable file
1183
S/imap_tools.V1.333/list_account_sizes.pl
Executable file
File diff suppressed because it is too large
Load Diff
1150
S/imap_tools.V1.333/list_imap_folders.pl
Executable file
1150
S/imap_tools.V1.333/list_imap_folders.pl
Executable file
File diff suppressed because it is too large
Load Diff
1221
S/imap_tools.V1.333/load_msgs.pl
Normal file
1221
S/imap_tools.V1.333/load_msgs.pl
Normal file
File diff suppressed because it is too large
Load Diff
1328
S/imap_tools.V1.333/maildir_to_imap.pl
Executable file
1328
S/imap_tools.V1.333/maildir_to_imap.pl
Executable file
File diff suppressed because it is too large
Load Diff
749
S/imap_tools.V1.333/mbxIMAPsync.pl
Executable file
749
S/imap_tools.V1.333/mbxIMAPsync.pl
Executable file
@ -0,0 +1,749 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use Socket;
|
||||
use FileHandle;
|
||||
use Fcntl;
|
||||
use Getopt::Std;
|
||||
use MIME::Base64 qw(encode_base64 decode_base64);
|
||||
|
||||
######################################################################
|
||||
# Program name mbxIMAPsync.pl #
|
||||
# Written by Rick Sanders #
|
||||
# Date 12 Feb 2004 #
|
||||
# #
|
||||
# Description #
|
||||
# #
|
||||
# mbxIMAPsync is used to synchronize the contents of a Unix #
|
||||
# mailfiles with an IMAP mailbox. The user supplies the location #
|
||||
# & name of the Unix mailbox (eg /var/mail/rfs) and the hostname, #
|
||||
# username, & password of the IMAP account along with the name #
|
||||
# of the IMAP mailbox. For example: #
|
||||
# #
|
||||
# ./mbxIMAPsync.pl -f /var/mail/rfs -i imapsrv/rfs/mypass -m INBOX #
|
||||
# #
|
||||
# mbxIMAPsync compares the messages in the mailfile with those in #
|
||||
# the IMAP mailbox by Message-Id and adds the ones in the mailfile #
|
||||
# which are not in the IMAP mailbox. Then it looks for messages #
|
||||
# in the IMAP mailbox which are not in the mailfile and removes #
|
||||
# them from the IMAP mailbox. #
|
||||
# #
|
||||
# See the Usage() for available options. #
|
||||
######################################################################
|
||||
|
||||
init();
|
||||
|
||||
connectToHost($imapHost, \$conn );
|
||||
login($imapUser,$imapPwd, $conn );
|
||||
|
||||
# Get list of msgs in the mailfile by Message-Id
|
||||
|
||||
$added=$purged=0;
|
||||
print STDOUT "Processing $mailfile\n";
|
||||
print STDOUT "Checking for messages to add\n";
|
||||
@msgs = readMbox( $mailfile );
|
||||
foreach $msg ( @msgs ) {
|
||||
@msgid = grep( /^Message-ID:/i, @$msg );
|
||||
($label,$msgid) = split(/:/, $msgid[0]);
|
||||
chomp $msgid;
|
||||
trim( *msgid );
|
||||
$mailfileMsgs{"$msgid"} = '1';
|
||||
push( @sourceMsgs, $msgid );
|
||||
|
||||
if ( !findMsg( $msgid, $mbx, $conn ) ) {
|
||||
# print STDOUT "Need to add msgid >$msgid<\n";
|
||||
my $message;
|
||||
|
||||
foreach $_ ( @$msg ) { chop $_; $message .= "$_\r\n"; }
|
||||
|
||||
if ( insertMsg($mbx, \$message, $flags, $date, $conn ) ) {
|
||||
$added++;
|
||||
print STDOUT " Added $msgid\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Remove any messages from the IMAP mailbox that no longer
|
||||
# exist in the mailfile
|
||||
|
||||
print STDOUT "Checking for messages to purge\n";
|
||||
getMsgList( $mbx, \@imapMsgs, $conn );
|
||||
foreach $msgid ( @imapMsgs ) {
|
||||
if ( $mailfileMsgs{"$msgid"} eq '' ) {
|
||||
if ( deleteMsg($msgid, $mbx, $conn ) ) {
|
||||
Log(" Marked $msgid for deletion");
|
||||
print STDOUT " Marked msgid $msgid for deletion\n";
|
||||
$deleted++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $deleted ) {
|
||||
# Need to purge the deleted messages
|
||||
$purged = expungeMbx( $mbx, $conn );
|
||||
}
|
||||
|
||||
Log("Done");
|
||||
Log("Added $added messages to IMAP mailbox $mbx");
|
||||
Log("Purged $purged messages from IMAP mailbox $mbx");
|
||||
|
||||
print STDOUT "\nAdded $added messages to IMAP mailbox $mbx\n";
|
||||
print STDOUT "Purged $purged messages from IMAP mailbox $mbx\n";
|
||||
|
||||
exit;
|
||||
|
||||
|
||||
sub init {
|
||||
|
||||
if ( ! getopts('f:m:i:L:dxA:F:I') ) {
|
||||
usage();
|
||||
exit;
|
||||
}
|
||||
|
||||
($imapHost,$imapUser,$imapPwd) = split(/\//, $opt_i);
|
||||
$mailfile = $opt_f;
|
||||
$mbx = $opt_m;
|
||||
$logfile = $opt_L;
|
||||
$admin_user = $opt_A;
|
||||
$msgs_per_folder = $opt_F;
|
||||
$debug = 1 if $opt_d;
|
||||
$showIMAP = 1;
|
||||
|
||||
if ( $logfile ) {
|
||||
if ( ! open (LOG, ">> $logfile") ) {
|
||||
print "Can't open logfile $logfile: $!\n";
|
||||
$logfile = '';
|
||||
}
|
||||
}
|
||||
Log("\nThis is mbxIMAPsync\n");
|
||||
|
||||
if ( !-e $mailfile ) {
|
||||
Log("$mailfile does not exist");
|
||||
exit;
|
||||
}
|
||||
|
||||
# Determine whether we have SSL support via openSSL and IO::Socket::SSL
|
||||
$ssl_installed = 1;
|
||||
eval 'use IO::Socket::SSL';
|
||||
if ( $@ ) {
|
||||
$ssl_installed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
sub usage {
|
||||
|
||||
print "Usage: mbxIMAPsync.pl\n";
|
||||
print " -f <location of mailfiles>\n";
|
||||
print " -i imapHost/imapUser/imapPassword\n";
|
||||
print " -m <IMAP mailbox>\n";
|
||||
print " [-L <logfile>]\n";
|
||||
print " [-d debug]\n";
|
||||
|
||||
}
|
||||
|
||||
sub readMbox {
|
||||
|
||||
my $file = shift;
|
||||
my @mail = ();
|
||||
my $mail = [];
|
||||
my $blank = 1;
|
||||
local *FH;
|
||||
local $_;
|
||||
|
||||
Log("Reading the mailfile") if $debug;
|
||||
open(FH,"< $file") or die "Can't open $file";
|
||||
|
||||
while(<FH>) {
|
||||
if($blank && /\AFrom .*\d{4}/) {
|
||||
push(@mail, $mail) if scalar(@{$mail});
|
||||
$mail = [ $_ ];
|
||||
$blank = 0;
|
||||
}
|
||||
else {
|
||||
$blank = m#\A\Z#o ? 1 : 0;
|
||||
push(@{$mail}, $_);
|
||||
}
|
||||
}
|
||||
|
||||
push(@mail, $mail) if scalar(@{$mail});
|
||||
close(FH);
|
||||
|
||||
return wantarray ? @mail : \@mail;
|
||||
}
|
||||
|
||||
sub Log {
|
||||
|
||||
my $line = shift;
|
||||
my $msg;
|
||||
|
||||
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime (time);
|
||||
$msg = sprintf ("%.2d-%.2d-%.4d.%.2d:%.2d:%.2d %s",
|
||||
$mon + 1, $mday, $year + 1900, $hour, $min, $sec, $line);
|
||||
|
||||
if ( $logfile ) {
|
||||
print LOG "$msg\n";
|
||||
}
|
||||
print STDERR "$line\n";
|
||||
|
||||
}
|
||||
|
||||
# Make a connection to a IMAP host
|
||||
|
||||
sub connectToHost {
|
||||
|
||||
my $host = shift;
|
||||
my $conn = shift;
|
||||
|
||||
Log("Connecting to $host") if $debug;
|
||||
|
||||
($host,$port) = split(/:/, $host);
|
||||
$port = 143 unless $port;
|
||||
|
||||
# We know whether to use SSL for ports 143 and 993. For any
|
||||
# other ones we'll have to figure it out.
|
||||
$mode = sslmode( $host, $port );
|
||||
|
||||
if ( $mode eq 'SSL' ) {
|
||||
unless( $ssl_installed == 1 ) {
|
||||
warn("You must have openSSL and IO::Socket::SSL installed to use an SSL connection");
|
||||
Log("You must have openSSL and IO::Socket::SSL installed to use an SSL connection");
|
||||
exit;
|
||||
}
|
||||
Log("Attempting an SSL connection") if $debug;
|
||||
$$conn = IO::Socket::SSL->new(
|
||||
Proto => "tcp",
|
||||
SSL_verify_mode => 0x00,
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
Domain => AF_INET,
|
||||
);
|
||||
|
||||
unless ( $$conn ) {
|
||||
$error = IO::Socket::SSL::errstr();
|
||||
Log("Error connecting to $host: $error");
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
# Non-SSL connection
|
||||
Log("Attempting a non-SSL connection") if $debug;
|
||||
$$conn = IO::Socket::INET->new(
|
||||
Proto => "tcp",
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
);
|
||||
|
||||
unless ( $$conn ) {
|
||||
Log("Error connecting to $host:$port: $@");
|
||||
warn "Error connecting to $host:$port: $@";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
# Log("Connected to $host on port $port");
|
||||
|
||||
}
|
||||
|
||||
sub sslmode {
|
||||
|
||||
my $host = shift;
|
||||
my $port = shift;
|
||||
my $mode;
|
||||
|
||||
# Determine whether to make an SSL connection
|
||||
# to the host. Return 'SSL' if so.
|
||||
|
||||
if ( $port == 143 ) {
|
||||
# Standard non-SSL port
|
||||
return '';
|
||||
} elsif ( $port == 993 ) {
|
||||
# Standard SSL port
|
||||
return 'SSL';
|
||||
}
|
||||
|
||||
unless ( $ssl_installed ) {
|
||||
# We don't have SSL installed on this machine
|
||||
return '';
|
||||
}
|
||||
|
||||
# For any other port we need to determine whether it supports SSL
|
||||
|
||||
my $conn = IO::Socket::SSL->new(
|
||||
Proto => "tcp",
|
||||
SSL_verify_mode => 0x00,
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
);
|
||||
|
||||
if ( $conn ) {
|
||||
close( $conn );
|
||||
$mode = 'SSL';
|
||||
} else {
|
||||
$mode = '';
|
||||
}
|
||||
|
||||
return $mode;
|
||||
}
|
||||
|
||||
#
|
||||
# login in at the source host with the user's name and password
|
||||
#
|
||||
sub login {
|
||||
|
||||
my $user = shift;
|
||||
my $pwd = shift;
|
||||
my $conn = shift;
|
||||
|
||||
if ( $admin_user ) {
|
||||
($admin_user,$admin_pwd) = split(/:/, $admin_user);
|
||||
login_plain( $user, $admin_user, $admin_pwd, $conn ) or exit;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( $pwd =~ /^oauth2:(.+)/i ) {
|
||||
$token = $1;
|
||||
Log("password is an OAUTH2 token");
|
||||
login_xoauth2( $user, $token, $conn );
|
||||
return 1;
|
||||
}
|
||||
|
||||
Log("Logging in as $user") if $debug;
|
||||
sendCommand ($conn, "1 LOGIN $user $pwd");
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
if ($response =~ /^1 OK/i) {
|
||||
last;
|
||||
}
|
||||
elsif ($response =~ /NO/) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Log("Logged in as $user") if $debug;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# login_plain
|
||||
#
|
||||
# login in at the source host with the user's name and password. If provided
|
||||
# with administrator credential, use them as this eliminates the need for the
|
||||
# user's password.
|
||||
#
|
||||
sub login_plain {
|
||||
|
||||
my $user = shift;
|
||||
my $admin = shift;
|
||||
my $pwd = shift;
|
||||
my $conn = shift;
|
||||
|
||||
# Do an AUTHENTICATE = PLAIN. If an admin user has been provided then use it.
|
||||
|
||||
if ( !$admin ) {
|
||||
# Log in as the user
|
||||
$admin = $user
|
||||
}
|
||||
|
||||
$login_str = sprintf("%s\x00%s\x00%s", $user,$admin,$pwd);
|
||||
$login_str = encode_base64("$login_str", "");
|
||||
$len = length( $login_str );
|
||||
|
||||
# sendCommand ($conn, "1 AUTHENTICATE \"PLAIN\" {$len}" );
|
||||
sendCommand ($conn, "1 AUTHENTICATE PLAIN" );
|
||||
|
||||
my $loops;
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
last if $response =~ /\+/;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
exit;
|
||||
}
|
||||
$last if $loops++ > 5;
|
||||
}
|
||||
|
||||
sendCommand ($conn, "$login_str" );
|
||||
my $loops;
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
|
||||
if ( $response =~ /Microsoft Exchange/i and $conn eq $dst ) {
|
||||
# The destination is an Exchange server
|
||||
$exchange = 1;
|
||||
Log("The destination is an Exchange server");
|
||||
}
|
||||
|
||||
last if $response =~ /^1 OK/i;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
exit;
|
||||
}
|
||||
$last if $loops++ > 5;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
# login_xoauth2
|
||||
#
|
||||
# login in at the source host with the user's name and an XOAUTH2 token.
|
||||
#
|
||||
sub login_xoauth2 {
|
||||
|
||||
my $user = shift;
|
||||
my $token = shift;
|
||||
my $conn = shift;
|
||||
|
||||
# Do an AUTHENTICATE = XOAUTH2 login
|
||||
|
||||
$login_str = encode_base64("user=". $user ."\x01auth=Bearer ". $token ."\x01\x01", '');
|
||||
sendCommand ($conn, "1 AUTHENTICATE XOAUTH2 $login_str" );
|
||||
|
||||
my $loops;
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
if ( $response =~ /^\+ (.+)/ ) {
|
||||
$error = decode_base64( $1 );
|
||||
Log("XOAUTH authentication as $user failed: $error");
|
||||
return 0;
|
||||
}
|
||||
last if $response =~ /^1 OK/;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE|failed/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
return 0;
|
||||
}
|
||||
$last if $loops++ > 5;
|
||||
}
|
||||
|
||||
Log("login complete") if $debug;
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
# logout
|
||||
#
|
||||
# log out from the host
|
||||
#
|
||||
sub logout {
|
||||
|
||||
my $conn = shift;
|
||||
|
||||
++$lsn;
|
||||
undef @response;
|
||||
sendCommand ($conn, "$lsn LOGOUT");
|
||||
while ( 1 ) {
|
||||
readResponse ($conn);
|
||||
if ( $response =~ /^$lsn OK/i ) {
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
Log ("unexpected LOGOUT response: $response");
|
||||
last;
|
||||
}
|
||||
}
|
||||
close $conn;
|
||||
return;
|
||||
}
|
||||
|
||||
# readResponse
|
||||
#
|
||||
# This subroutine reads and formats an IMAP protocol response from an
|
||||
# IMAP server on a specified connection.
|
||||
#
|
||||
|
||||
sub readResponse
|
||||
{
|
||||
local($fd) = shift @_;
|
||||
|
||||
$response = <$fd>;
|
||||
chop $response;
|
||||
$response =~ s/\r//g;
|
||||
push (@response,$response);
|
||||
Log ("<< $response",2) if $showIMAP;
|
||||
}
|
||||
|
||||
#
|
||||
# sendCommand
|
||||
#
|
||||
# This subroutine formats and sends an IMAP protocol command to an
|
||||
# IMAP server on a specified connection.
|
||||
#
|
||||
|
||||
sub sendCommand
|
||||
{
|
||||
local($fd) = shift @_;
|
||||
local($cmd) = shift @_;
|
||||
|
||||
print $fd "$cmd\r\n";
|
||||
|
||||
if ($showIMAP) { Log (">> $cmd",2); }
|
||||
}
|
||||
|
||||
#
|
||||
sub insertMsg {
|
||||
|
||||
my $mbx = shift;
|
||||
my $message = shift;
|
||||
my $flags = shift;
|
||||
my $date = shift;
|
||||
my $conn = shift;
|
||||
my ($lsn,$lenx);
|
||||
|
||||
Log(" Inserting message into mailbox $mbx") if $debug;
|
||||
$lenx = length($$message);
|
||||
|
||||
# Create the mailbox unless we have already done so
|
||||
++$lsn;
|
||||
if ($destMbxs{"$mbx"} eq '') {
|
||||
Log("creating mailbox $mbx") if $debug;
|
||||
sendCommand (IMAP, "$lsn CREATE \"$mbx\"");
|
||||
while ( 1 ) {
|
||||
readResponse (IMAP);
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
if (!($response =~ /already exists|reserved mailbox name/i)) {
|
||||
Log ("WARNING: $response");
|
||||
}
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$destMbxs{"$mbx"} = '1';
|
||||
|
||||
++$lsn;
|
||||
$flags =~ s/\\Recent//i;
|
||||
|
||||
# &sendCommand (IMAP, "$lsn APPEND \"$mbx\" ($flags) \"$date\" \{$lenx\}");
|
||||
sendCommand (IMAP, "$lsn APPEND \"$mbx\" \{$lenx\}");
|
||||
readResponse (IMAP);
|
||||
if ( $response !~ /^\+/ ) {
|
||||
Log ("unexpected APPEND response: $response");
|
||||
# next;
|
||||
push(@errors,"Error appending message to $mbx for $user");
|
||||
return 0;
|
||||
}
|
||||
|
||||
print IMAP "$$message\r\n";
|
||||
|
||||
undef @response;
|
||||
while ( 1 ) {
|
||||
readResponse (IMAP);
|
||||
if ( $response =~ /^$lsn OK/i ) {
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
Log ("unexpected APPEND response: $response");
|
||||
# next;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# getMsgList
|
||||
#
|
||||
# Get a list of the user's messages in the indicated mailbox on
|
||||
# the IMAP host
|
||||
#
|
||||
sub getMsgList {
|
||||
|
||||
my $mailbox = shift;
|
||||
my $msgs = shift;
|
||||
my $conn = shift;
|
||||
my $seen;
|
||||
my $empty;
|
||||
my $msgnum;
|
||||
|
||||
Log("Getting list of msgs in $mailbox") if $debug;
|
||||
trim( *mailbox );
|
||||
sendCommand ($conn, "1 EXAMINE \"$mailbox\"");
|
||||
undef @response;
|
||||
$empty=0;
|
||||
while ( 1 ) {
|
||||
readResponse ( $conn );
|
||||
if ( $response =~ / 0 EXISTS/i ) { $empty=1; }
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
# print STDERR "response $response\n";
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
Log ("unexpected response: $response");
|
||||
# print STDERR "Error: $response\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
sendCommand ( $conn, "1 FETCH 1:* (uid flags internaldate body[header.fields (Message-Id)])");
|
||||
undef @response;
|
||||
while ( 1 ) {
|
||||
readResponse ( $conn );
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
# print STDERR "response $response\n";
|
||||
last;
|
||||
}
|
||||
elsif ( $XDXDXD ) {
|
||||
Log ("unexpected response: $response");
|
||||
Log ("Unable to get list of messages in this mailbox");
|
||||
push(@errors,"Error getting list of $user's msgs");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
# Get a list of the msgs in the mailbox
|
||||
#
|
||||
undef @msgs;
|
||||
undef $flags;
|
||||
for $i (0 .. $#response) {
|
||||
$seen=0;
|
||||
$_ = $response[$i];
|
||||
|
||||
last if /OK FETCH complete/;
|
||||
|
||||
if ( $response[$i] =~ /FETCH \(UID / ) {
|
||||
$response[$i] =~ /\* ([^FETCH \(UID]*)/;
|
||||
$msgnum = $1;
|
||||
}
|
||||
|
||||
if ($response[$i] =~ /FLAGS/) {
|
||||
# Get the list of flags
|
||||
$response[$i] =~ /FLAGS \(([^\)]*)/;
|
||||
$flags = $1;
|
||||
$flags =~ s/\\Recent//i;
|
||||
}
|
||||
if ( $response[$i] =~ /INTERNALDATE ([^\)]*)/ ) {
|
||||
### $response[$i] =~ /INTERNALDATE (.+) ([^BODY]*)/i;
|
||||
$response[$i] =~ /INTERNALDATE (.+) BODY/i;
|
||||
$date = $1;
|
||||
$date =~ s/"//g;
|
||||
}
|
||||
if ( $response[$i] =~ /^Message-Id:/i ) {
|
||||
($label,$msgid) = split(/: /, $response[$i]);
|
||||
push (@$msgs,$msgid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# trim
|
||||
#
|
||||
# remove leading and trailing spaces from a string
|
||||
sub trim {
|
||||
|
||||
local (*string) = @_;
|
||||
|
||||
$string =~ s/^\s+//;
|
||||
$string =~ s/\s+$//;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
sub findMsg {
|
||||
|
||||
my $msgid = shift;
|
||||
my $mbx = shift;
|
||||
my $conn = shift;
|
||||
my $msgnum;
|
||||
my $noSuchMbx;
|
||||
|
||||
Log("Searching for $msgid in $mbx") if $debug;
|
||||
sendCommand ( $conn, "1 SELECT \"$mbx\"");
|
||||
while (1) {
|
||||
readResponse ($conn);
|
||||
if ( $response =~ /^1 NO/ ) {
|
||||
$noSuchMbx = 1;
|
||||
last;
|
||||
}
|
||||
last if $response =~ /^1 OK/;
|
||||
}
|
||||
return '' if $noSuchMbx;
|
||||
|
||||
Log("Search for $msgid") if $debug;
|
||||
sendCommand ( $conn, "1 SEARCH header Message-Id \"$msgid\"");
|
||||
while (1) {
|
||||
readResponse ($conn);
|
||||
if ( $response =~ /\* SEARCH /i ) {
|
||||
($dmy, $msgnum) = split(/\* SEARCH /i, $response);
|
||||
($msgnum) = split(/ /, $msgnum);
|
||||
}
|
||||
|
||||
last if $response =~ /^1 OK/;
|
||||
last if $response =~ /complete/i;
|
||||
}
|
||||
|
||||
if ( $msgnum ) {
|
||||
Log("Message exists") if $debug;
|
||||
} else {
|
||||
Log("Message does not exist") if $debug;
|
||||
}
|
||||
|
||||
return $msgnum;
|
||||
}
|
||||
|
||||
sub deleteMsg {
|
||||
|
||||
my $msgid = shift;
|
||||
my $mbx = shift;
|
||||
my $conn = shift;
|
||||
my $rc;
|
||||
|
||||
Log("Deleting message $msgid") if $debug;
|
||||
$msgnum = findMsg( $msgid, $mbx, $conn );
|
||||
|
||||
sendCommand ( $conn, "1 STORE $msgnum +FLAGS (\\Deleted)");
|
||||
while (1) {
|
||||
readResponse ($conn);
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
$rc = 1;
|
||||
Log(" Marked $msgid for delete");
|
||||
last;
|
||||
}
|
||||
|
||||
if ( $response =~ /^1 BAD|^1 NO/i ) {
|
||||
Log("Error setting \Deleted flag for msg $msgnum: $response");
|
||||
$rc = 0;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
return $rc;
|
||||
|
||||
}
|
||||
|
||||
sub expungeMbx {
|
||||
|
||||
my $mbx = shift;
|
||||
my $conn = shift;
|
||||
my $purged=0;
|
||||
|
||||
Log("Purging $mbx") if $debug;
|
||||
sendCommand ( $conn, "1 SELECT \"$mbx\"");
|
||||
while (1) {
|
||||
readResponse ($conn);
|
||||
last if $response =~ /^1 OK/;
|
||||
|
||||
if ( $response =~ /^1 NO|^1 BAD/i ) {
|
||||
Log("Error selecting mailbox $mbx: $response");
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
sendCommand ( $conn, "1 EXPUNGE");
|
||||
while (1) {
|
||||
readResponse ($conn);
|
||||
last if $response =~ /^1 OK/;
|
||||
$purged++ if $response =~ /EXPUNGE/i;
|
||||
|
||||
if ( $response =~ /^1 BAD|^1 NO/i ) {
|
||||
print STDOUT "Error expunging messages: $response\n";
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
return $purged;
|
||||
|
||||
}
|
||||
|
2467
S/imap_tools.V1.333/migrateIMAP.pl
Normal file
2467
S/imap_tools.V1.333/migrateIMAP.pl
Normal file
File diff suppressed because it is too large
Load Diff
1080
S/imap_tools.V1.333/pop3toimap.pl
Executable file
1080
S/imap_tools.V1.333/pop3toimap.pl
Executable file
File diff suppressed because it is too large
Load Diff
797
S/imap_tools.V1.333/purgeMbx.pl
Executable file
797
S/imap_tools.V1.333/purgeMbx.pl
Executable file
@ -0,0 +1,797 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# $Header: /mhub4/sources/imap-tools/purgeMbx.pl,v 1.7 2015/06/05 11:32:25 rick Exp $
|
||||
|
||||
############################################################################
|
||||
# Program name purgeMbx.pl #
|
||||
# Written by Rick Sanders #
|
||||
# Date 5/24/2008 #
|
||||
# #
|
||||
# Description #
|
||||
# #
|
||||
# This script deletes all of the messages in a user's IMAP #
|
||||
# mailbox. #
|
||||
# #
|
||||
# purgeMbx.pl is called like this: #
|
||||
# ./purgeMbx.pl -s host/user/password -m <mailbox> #
|
||||
# #
|
||||
# Note that the mailbox name is case-sensitive. #
|
||||
# #
|
||||
# Optional arguments: #
|
||||
# -d debug #
|
||||
# -L <logfile> #
|
||||
############################################################################
|
||||
|
||||
############################################################################
|
||||
# Copyright (c) 2008 Rick Sanders <rfs9999@earthlink.net> #
|
||||
# #
|
||||
# Permission to use, copy, modify, and distribute this software for any #
|
||||
# purpose with or without fee is hereby granted, provided that the above #
|
||||
# copyright notice and this permission notice appear in all copies. #
|
||||
# #
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES #
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF #
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR #
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES #
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN #
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF #
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #
|
||||
############################################################################
|
||||
|
||||
use Socket;
|
||||
use FileHandle;
|
||||
use Fcntl;
|
||||
use Getopt::Std;
|
||||
use IO::Socket;
|
||||
use MIME::Base64 qw(encode_base64 decode_base64 );
|
||||
|
||||
#################################################################
|
||||
# Main program. #
|
||||
#################################################################
|
||||
|
||||
init();
|
||||
|
||||
sigprc();
|
||||
|
||||
# Get list of all messages on the source host by Message-Id
|
||||
#
|
||||
connectToHost($host, \$conn);
|
||||
login($user,$pwd, $conn) or exit;
|
||||
|
||||
if ( $mbx eq '*' ) {
|
||||
@mailboxes = listMailboxes( '*', $conn);
|
||||
} else {
|
||||
push( @mailboxes, $mbx );
|
||||
}
|
||||
|
||||
foreach $mbx ( @mailboxes ) {
|
||||
Log("Purging the \"$mbx\" mailbox");
|
||||
@sourceMsgs = ();
|
||||
getMsgList( $mbx, \@msgs, $conn );
|
||||
Log("$mbx mailbox is empty") unless @msgs;
|
||||
foreach $msgnum ( @msgs ) {
|
||||
$total++;
|
||||
deleteMsg( $msgnum, $conn );
|
||||
}
|
||||
expungeMbx( $mbx, $conn ) if @msgs;
|
||||
|
||||
Log("$total messages were deleted from \"$mbx\" mailbox");
|
||||
}
|
||||
|
||||
logout( $conn );
|
||||
|
||||
exit;
|
||||
|
||||
|
||||
sub init {
|
||||
|
||||
$version = 'V1.0.1';
|
||||
$os = $ENV{'OS'};
|
||||
|
||||
processArgs();
|
||||
|
||||
# Determine whether we have SSL support via openSSL and IO::Socket::SSL
|
||||
$ssl_installed = 1;
|
||||
eval 'use IO::Socket::SSL';
|
||||
if ( $@ ) {
|
||||
$ssl_installed = 0;
|
||||
}
|
||||
|
||||
$timeout = 60 unless $timeout;
|
||||
|
||||
# Open the logFile
|
||||
#
|
||||
if ( $logfile ) {
|
||||
if ( !open(LOG, ">> $logfile")) {
|
||||
print STDOUT "Can't open $logfile: $!\n";
|
||||
}
|
||||
select(LOG); $| = 1;
|
||||
}
|
||||
Log("\n$0 starting");
|
||||
$total=0;
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# sendCommand
|
||||
#
|
||||
# This subroutine formats and sends an IMAP protocol command to an
|
||||
# IMAP server on a specified connection.
|
||||
#
|
||||
|
||||
sub sendCommand
|
||||
{
|
||||
local($fd) = shift @_;
|
||||
local($cmd) = shift @_;
|
||||
|
||||
print $fd "$cmd\r\n";
|
||||
|
||||
if ($showIMAP) { Log (">> $cmd",2); }
|
||||
}
|
||||
|
||||
#
|
||||
# readResponse
|
||||
#
|
||||
# This subroutine reads and formats an IMAP protocol response from an
|
||||
# IMAP server on a specified connection.
|
||||
#
|
||||
|
||||
sub readResponse
|
||||
{
|
||||
local($fd) = shift @_;
|
||||
|
||||
$response = <$fd>;
|
||||
chop $response;
|
||||
$response =~ s/\r//g;
|
||||
push (@response,$response);
|
||||
if ($showIMAP) { Log ("<< $response",2); }
|
||||
}
|
||||
|
||||
#
|
||||
# Log
|
||||
#
|
||||
# This subroutine formats and writes a log message to STDERR.
|
||||
#
|
||||
|
||||
sub Log {
|
||||
|
||||
my $str = shift;
|
||||
|
||||
# If a logile has been specified then write the output to it
|
||||
# Otherwise write it to STDOUT
|
||||
|
||||
if ( $logfile ) {
|
||||
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
|
||||
if ($year < 99) { $yr = 2000; }
|
||||
else { $yr = 1900; }
|
||||
$line = sprintf ("%.2d-%.2d-%d.%.2d:%.2d:%.2d %s %s\n",
|
||||
$mon + 1, $mday, $year + $yr, $hour, $min, $sec,$$,$str);
|
||||
print LOG "$line";
|
||||
}
|
||||
print STDOUT "$str\n";
|
||||
|
||||
}
|
||||
|
||||
# Make a connection to an IMAP host
|
||||
|
||||
sub connectToHost {
|
||||
|
||||
my $host = shift;
|
||||
my $conn = shift;
|
||||
|
||||
Log("Connecting to $host") if $debug;
|
||||
|
||||
($host,$port) = split(/:/, $host);
|
||||
$port = 143 unless $port;
|
||||
|
||||
# We know whether to use SSL for ports 143 and 993. For any
|
||||
# other ones we'll have to figure it out.
|
||||
$mode = sslmode( $host, $port );
|
||||
|
||||
if ( $mode eq 'SSL' ) {
|
||||
unless( $ssl_installed == 1 ) {
|
||||
warn("You must have openSSL and IO::Socket::SSL installed to use an SSL connection");
|
||||
Log("You must have openSSL and IO::Socket::SSL installed to use an SSL connection");
|
||||
exit;
|
||||
}
|
||||
Log("Attempting an SSL connection") if $debug;
|
||||
$$conn = IO::Socket::SSL->new(
|
||||
Proto => "tcp",
|
||||
SSL_verify_mode => 0x00,
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
Domain => AF_INET,
|
||||
);
|
||||
|
||||
unless ( $$conn ) {
|
||||
$error = IO::Socket::SSL::errstr();
|
||||
Log("Error connecting to $host: $error");
|
||||
warn("Error connecting to $host: $error");
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
# Non-SSL connection
|
||||
Log("Attempting a non-SSL connection") if $debug;
|
||||
$$conn = IO::Socket::INET->new(
|
||||
Proto => "tcp",
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
);
|
||||
|
||||
unless ( $$conn ) {
|
||||
Log("Error connecting to $host:$port: $@");
|
||||
warn "Error connecting to $host:$port: $@";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
Log("Connected to $host on port $port");
|
||||
|
||||
}
|
||||
|
||||
sub sslmode {
|
||||
|
||||
my $host = shift;
|
||||
my $port = shift;
|
||||
my $mode;
|
||||
|
||||
# Determine whether to make an SSL connection
|
||||
# to the host. Return 'SSL' if so.
|
||||
|
||||
if ( $port == 143 ) {
|
||||
# Standard non-SSL port
|
||||
return '';
|
||||
} elsif ( $port == 993 ) {
|
||||
# Standard SSL port
|
||||
return 'SSL';
|
||||
}
|
||||
|
||||
unless ( $ssl_installed ) {
|
||||
# We don't have SSL installed on this machine
|
||||
return '';
|
||||
}
|
||||
|
||||
# For any other port we need to determine whether it supports SSL
|
||||
|
||||
my $conn = IO::Socket::SSL->new(
|
||||
Proto => "tcp",
|
||||
SSL_verify_mode => 0x00,
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port,
|
||||
);
|
||||
|
||||
if ( $conn ) {
|
||||
close( $conn );
|
||||
$mode = 'SSL';
|
||||
} else {
|
||||
$mode = '';
|
||||
}
|
||||
|
||||
return $mode;
|
||||
}
|
||||
|
||||
|
||||
# trim
|
||||
#
|
||||
# remove leading and trailing spaces from a string
|
||||
sub trim {
|
||||
|
||||
local (*string) = @_;
|
||||
|
||||
$string =~ s/^\s+//;
|
||||
$string =~ s/\s+$//;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
# login
|
||||
#
|
||||
# login in at the source host with the user's name and password
|
||||
#
|
||||
sub login {
|
||||
|
||||
my $user = shift;
|
||||
my $pwd = shift;
|
||||
my $conn = shift;
|
||||
|
||||
if ( $admin_user ) {
|
||||
($admin_user,$admin_pwd) = split(/:/, $admin_user);
|
||||
login_plain( $user, $admin_user, $admin_pwd, $conn ) or exit;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( $pwd =~ /^oauth2:(.+)/i ) {
|
||||
$token = $1;
|
||||
Log("password is an OAUTH2 token");
|
||||
login_xoauth2( $user, $token, $conn );
|
||||
return 1;
|
||||
}
|
||||
|
||||
sendCommand ($conn, "1 LOGIN $user $pwd");
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
if ($response =~ /1 OK/i) {
|
||||
last;
|
||||
}
|
||||
if ($response =~ /^(.+) NO|^(.+) BAD/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Log("Logged in as $user") if $debug;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# login_plain
|
||||
#
|
||||
# login in at the source host with the user's name and password. If provided
|
||||
# with administrator credential, use them as this eliminates the need for the
|
||||
# user's password.
|
||||
#
|
||||
sub login_plain {
|
||||
|
||||
my $user = shift;
|
||||
my $admin = shift;
|
||||
my $pwd = shift;
|
||||
my $conn = shift;
|
||||
|
||||
# Do an AUTHENTICATE = PLAIN. If an admin user has been provided then use it.
|
||||
|
||||
if ( !$admin ) {
|
||||
# Log in as the user
|
||||
$admin = $user
|
||||
}
|
||||
|
||||
$login_str = sprintf("%s\x00%s\x00%s", $user,$admin,$pwd);
|
||||
$login_str = encode_base64("$login_str", "");
|
||||
$len = length( $login_str );
|
||||
|
||||
# sendCommand ($conn, "1 AUTHENTICATE \"PLAIN\" {$len}" );
|
||||
sendCommand ($conn, "1 AUTHENTICATE PLAIN" );
|
||||
|
||||
my $loops;
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
last if $response =~ /\+/;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
exit;
|
||||
}
|
||||
$last if $loops++ > 5;
|
||||
}
|
||||
|
||||
sendCommand ($conn, "$login_str" );
|
||||
my $loops;
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
|
||||
if ( $response =~ /Microsoft Exchange/i and $conn eq $dst ) {
|
||||
# The destination is an Exchange server
|
||||
$exchange = 1;
|
||||
Log("The destination is an Exchange server");
|
||||
}
|
||||
|
||||
last if $response =~ /^1 OK/i;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
exit;
|
||||
}
|
||||
$last if $loops++ > 5;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
# login_xoauth2
|
||||
#
|
||||
# login in at the source host with the user's name and an XOAUTH2 token.
|
||||
#
|
||||
sub login_xoauth2 {
|
||||
|
||||
my $user = shift;
|
||||
my $token = shift;
|
||||
my $conn = shift;
|
||||
|
||||
# Do an AUTHENTICATE = XOAUTH2 login
|
||||
|
||||
$login_str = encode_base64("user=". $user ."\x01auth=Bearer ". $token ."\x01\x01", '');
|
||||
sendCommand ($conn, "1 AUTHENTICATE XOAUTH2 $login_str" );
|
||||
|
||||
my $loops;
|
||||
while (1) {
|
||||
readResponse ( $conn );
|
||||
if ( $response =~ /^\+ (.+)/ ) {
|
||||
$error = decode_base64( $1 );
|
||||
Log("XOAUTH authentication as $user failed: $error");
|
||||
return 0;
|
||||
}
|
||||
last if $response =~ /^1 OK/;
|
||||
if ($response =~ /^1 NO|^1 BAD|^\* BYE|failed/i) {
|
||||
Log ("unexpected LOGIN response: $response");
|
||||
return 0;
|
||||
}
|
||||
$last if $loops++ > 5;
|
||||
}
|
||||
|
||||
Log("login complete") if $debug;
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
# logout
|
||||
#
|
||||
# log out from the host
|
||||
#
|
||||
sub logout {
|
||||
|
||||
my $conn = shift;
|
||||
|
||||
++$lsn;
|
||||
undef @response;
|
||||
sendCommand ($conn, "$lsn LOGOUT");
|
||||
while ( 1 ) {
|
||||
readResponse ($conn);
|
||||
if ( $response =~ /^$lsn OK/i ) {
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
Log ("unexpected LOGOUT response: $response");
|
||||
last;
|
||||
}
|
||||
}
|
||||
close $conn;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
# getMsgList
|
||||
#
|
||||
# Get a list of messages in a mailbox
|
||||
#
|
||||
sub getMsgList {
|
||||
|
||||
my $mailbox = shift;
|
||||
my $msgs = shift;
|
||||
my $conn = shift;
|
||||
my $seen;
|
||||
my $empty;
|
||||
my $msgnum;
|
||||
my $from;
|
||||
my $flags;
|
||||
|
||||
trim( *mailbox );
|
||||
sendCommand ($conn, "1 SELECT \"$mailbox\"");
|
||||
undef @response;
|
||||
$empty=0;
|
||||
while ( 1 ) {
|
||||
readResponse ( $conn );
|
||||
if ( $response =~ / 0 EXISTS/i ) { $empty=1; }
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
# print STDERR "response $response\n";
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
Log ("unexpected response: $response");
|
||||
# print STDERR "Error: $response\n";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
sendCommand ( $conn, "1 FETCH 1:* (uid flags internaldate body[header.fields (From Date)])");
|
||||
undef @response;
|
||||
while ( 1 ) {
|
||||
readResponse ( $conn );
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
# print STDERR "response $response\n";
|
||||
last;
|
||||
}
|
||||
last if $response =~ /^1 NO|^1 BAD/;
|
||||
}
|
||||
|
||||
@msgs = ();
|
||||
$flags = '';
|
||||
for $i (0 .. $#response) {
|
||||
last if $response[$i] =~ /^1 OK FETCH complete/i;
|
||||
|
||||
if ($response[$i] =~ /FLAGS/) {
|
||||
# Get the list of flags
|
||||
$response[$i] =~ /FLAGS \(([^\)]*)/;
|
||||
$flags = $1;
|
||||
$flags =~ s/\\Recent//;
|
||||
}
|
||||
|
||||
if ( $response[$i] =~ /INTERNALDATE/) {
|
||||
$response[$i] =~ /INTERNALDATE (.+) BODY/;
|
||||
# $response[$i] =~ /INTERNALDATE "(.+)" BODY/;
|
||||
$date = $1;
|
||||
|
||||
$date =~ /"(.+)"/;
|
||||
$date = $1;
|
||||
$date =~ s/"//g;
|
||||
}
|
||||
|
||||
# if ( $response[$i] =~ /\* (.+) [^FETCH]/ ) {
|
||||
if ( $response[$i] =~ /\* (.+) FETCH/ ) {
|
||||
($msgnum) = split(/\s+/, $1);
|
||||
}
|
||||
|
||||
if ( $msgnum && $date ) {
|
||||
push (@$msgs, $msgnum);
|
||||
$msgnum = $date = '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
sub fetchMsg {
|
||||
|
||||
my $msgnum = shift;
|
||||
my $mbx = shift;
|
||||
my $conn = shift;
|
||||
my $message;
|
||||
|
||||
Log(" Fetching msg $msgnum...") if $debug;
|
||||
sendCommand ($conn, "1 SELECT \"$mbx\"");
|
||||
while (1) {
|
||||
readResponse ($conn);
|
||||
last if ( $response =~ /1 OK/i );
|
||||
}
|
||||
|
||||
sendCommand( $conn, "1 FETCH $msgnum (rfc822)");
|
||||
while (1) {
|
||||
readResponse ($conn);
|
||||
if ( $response =~ /1 OK/i ) {
|
||||
$size = length($message);
|
||||
last;
|
||||
}
|
||||
elsif ($response =~ /message number out of range/i) {
|
||||
Log ("Error fetching uid $uid: out of range",2);
|
||||
$stat=0;
|
||||
last;
|
||||
}
|
||||
elsif ($response =~ /Bogus sequence in FETCH/i) {
|
||||
Log ("Error fetching uid $uid: Bogus sequence in FETCH",2);
|
||||
$stat=0;
|
||||
last;
|
||||
}
|
||||
elsif ( $response =~ /message could not be processed/i ) {
|
||||
Log("Message could not be processed, skipping it ($user,msgnum $msgnum,$destMbx)");
|
||||
push(@errors,"Message could not be processed, skipping it ($user,msgnum $msgnum,$destMbx)");
|
||||
$stat=0;
|
||||
last;
|
||||
}
|
||||
elsif
|
||||
($response =~ /^\*\s+$msgnum\s+FETCH\s+\(.*RFC822\s+\{[0-9]+\}/i) {
|
||||
($len) = ($response =~ /^\*\s+$msgnum\s+FETCH\s+\(.*RFC822\s+\{([0-9]+)\}/i);
|
||||
$cc = 0;
|
||||
$message = "";
|
||||
while ( $cc < $len ) {
|
||||
$n = 0;
|
||||
$n = read ($conn, $segment, $len - $cc);
|
||||
if ( $n == 0 ) {
|
||||
Log ("unable to read $len bytes");
|
||||
return 0;
|
||||
}
|
||||
$message .= $segment;
|
||||
$cc += $n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $message;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub usage {
|
||||
|
||||
print STDOUT "usage:\n";
|
||||
print STDOUT " purgeMbx.pl -S host/user/pwd -m <mbx>\n";
|
||||
print STDOUT " Optional arguments:\n";
|
||||
print STDOUT " -d debug\n";
|
||||
print STDOUT " -L <logfile>\n";
|
||||
print STDOUT " -A <admin_user:admin_password>\n";
|
||||
exit;
|
||||
|
||||
}
|
||||
|
||||
sub processArgs {
|
||||
|
||||
if ( !getopts( "dIs:L:m:hA:" ) ) {
|
||||
usage();
|
||||
}
|
||||
|
||||
($host,$user,$pwd) = split(/\//, $opt_s);
|
||||
|
||||
$mbx = $opt_m;
|
||||
$admin_user = $opt_A;
|
||||
$logfile = $opt_L;
|
||||
$debug = $showIMAP = 1 if $opt_d;
|
||||
$showIMAP = 1 if $opt_I;
|
||||
usage() if $opt_h;
|
||||
|
||||
}
|
||||
|
||||
sub deleteMsg {
|
||||
|
||||
my $msgnum = shift;
|
||||
my $conn = shift;
|
||||
my $rc;
|
||||
|
||||
sendCommand ( $conn, "1 STORE $msgnum +FLAGS (\\Deleted)");
|
||||
while (1) {
|
||||
readResponse ($conn);
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
$rc = 1;
|
||||
Log(" Marked msg number $msgnum for delete") if $debug;
|
||||
last;
|
||||
}
|
||||
|
||||
if ( $response =~ /^1 BAD|^1 NO/i ) {
|
||||
Log("Error setting \Deleted flag for msg $msgnum: $response");
|
||||
$rc = 0;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
return $rc;
|
||||
|
||||
}
|
||||
|
||||
sub expungeMbx {
|
||||
|
||||
my $mbx = shift;
|
||||
my $conn = shift;
|
||||
|
||||
print STDOUT "Purging mailbox $mbx..." if $debug;
|
||||
|
||||
sendCommand ($conn, "1 SELECT \"$mbx\"");
|
||||
while (1) {
|
||||
readResponse ($conn);
|
||||
last if ( $response =~ /1 OK/i );
|
||||
}
|
||||
|
||||
sendCommand ( $conn, "1 EXPUNGE");
|
||||
$expunged=0;
|
||||
while (1) {
|
||||
readResponse ($conn);
|
||||
$expunged++ if $response =~ /\* (.+) Expunge/i;
|
||||
last if $response =~ /^1 OK/;
|
||||
|
||||
if ( $response =~ /^1 BAD|^1 NO/i ) {
|
||||
print STDOUT "Error purging messages: $response\n";
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
$totalExpunged += $expunged;
|
||||
|
||||
# print STDOUT "$expunged messages purged\n" if $debug;
|
||||
|
||||
}
|
||||
|
||||
sub dieright {
|
||||
local($sig) = @_;
|
||||
print STDOUT "caught signal $sig\n";
|
||||
logout( $conn );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
sub sigprc {
|
||||
|
||||
$SIG{'HUP'} = 'dieright';
|
||||
$SIG{'INT'} = 'dieright';
|
||||
$SIG{'QUIT'} = 'dieright';
|
||||
$SIG{'ILL'} = 'dieright';
|
||||
$SIG{'TRAP'} = 'dieright';
|
||||
$SIG{'IOT'} = 'dieright';
|
||||
$SIG{'EMT'} = 'dieright';
|
||||
$SIG{'FPE'} = 'dieright';
|
||||
$SIG{'BUS'} = 'dieright';
|
||||
$SIG{'SEGV'} = 'dieright';
|
||||
$SIG{'SYS'} = 'dieright';
|
||||
$SIG{'PIPE'} = 'dieright';
|
||||
$SIG{'ALRM'} = 'dieright';
|
||||
$SIG{'TERM'} = 'dieright';
|
||||
$SIG{'URG'} = 'dieright';
|
||||
}
|
||||
|
||||
# getMailboxList
|
||||
#
|
||||
# get a list of the user's mailboxes
|
||||
#
|
||||
sub getMailboxList {
|
||||
|
||||
my $conn = shift;
|
||||
my @mbxs;
|
||||
my $mbx;
|
||||
|
||||
# Get a list of the user's mailboxes
|
||||
#
|
||||
Log("Get list of user's mailboxes") if $debug;
|
||||
|
||||
sendCommand ($conn, "1 LIST \"\" *");
|
||||
undef @response;
|
||||
while ( 1 ) {
|
||||
readResponse ($conn);
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
Log ("unexpected response: $response");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
undef @mbxs;
|
||||
for $i (0 .. $#response) {
|
||||
$response[$i] =~ s/\s+/ /;
|
||||
($dmy,$mbx) = split(/"\/"/,$response[$i]);
|
||||
$mbx =~ s/^\s+//; $mbx =~ s/\s+$//;
|
||||
$mbx =~ s/"//g;
|
||||
|
||||
if ($response[$i] =~ /NOSELECT/i) {
|
||||
if ($debugMode) { Log("$mbx is set NOSELECT,skip it",2); }
|
||||
next;
|
||||
}
|
||||
if ($mbx =~ /^\./) {
|
||||
# Skip mailboxes starting with a dot
|
||||
next;
|
||||
}
|
||||
push ( @mbxs, $mbx ) if $mbx ne '';
|
||||
}
|
||||
|
||||
return @mbxs;
|
||||
}
|
||||
|
||||
# listMailboxes
|
||||
#
|
||||
# Get a list of the user's mailboxes
|
||||
#
|
||||
sub listMailboxes {
|
||||
|
||||
my $mbx = shift;
|
||||
my $conn = shift;
|
||||
my @mbxs;
|
||||
|
||||
sendCommand ($conn, "1 LIST \"\" \"$mbx\"");
|
||||
undef @response;
|
||||
while ( 1 ) {
|
||||
&readResponse ($conn);
|
||||
if ( $response =~ /^1 OK/i ) {
|
||||
last;
|
||||
}
|
||||
elsif ( $response !~ /^\*/ ) {
|
||||
&Log ("unexpected response: $response");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@mbxs = ();
|
||||
for $i (0 .. $#response) {
|
||||
$response[$i] =~ s/\s+/ /;
|
||||
if ( $response[$i] =~ /"$/ ) {
|
||||
$response[$i] =~ /\* LIST \((.*)\) "(.+)" "(.+)"/i;
|
||||
$mbx = $3;
|
||||
} elsif ( $response[$i] =~ /\* LIST \((.*)\) NIL (.+)/i ) {
|
||||
$mbx = $2;
|
||||
} else {
|
||||
$response[$i] =~ /\* LIST \((.*)\) "(.+)" (.+)/i;
|
||||
$mbx = $3;
|
||||
}
|
||||
$mbx =~ s/^\s+//; $mbx =~ s/\s+$//;
|
||||
|
||||
if ($response[$i] =~ /NOSELECT/i) {
|
||||
$nosel_mbxs{"$mbx"} = 1;
|
||||
}
|
||||
push ( @mbxs, $mbx ) if $mbx ne '';
|
||||
}
|
||||
|
||||
return @mbxs;
|
||||
}
|
||||
|
76
S/imap_tools.V1.333/release_notes_1.291.txt
Normal file
76
S/imap_tools.V1.333/release_notes_1.291.txt
Normal file
@ -0,0 +1,76 @@
|
||||
Release notes for IMAP-Tools version 1.291.
|
||||
Changes since 2014/06/12:
|
||||
|
||||
dumptoIMAP.pl 1.12 2014/06/21
|
||||
Fix handling of delimter and prefix when server does not supply NAMESPACE via -y argument.
|
||||
|
||||
dumptoIMAP.pl 1.11 2014/06/20
|
||||
Fix problem in get_mbx_list caused by the path not being as expected and causing the filespec to not have a leading '/'
|
||||
|
||||
imap_audit.pl 1.6 2014/07/24
|
||||
Added support for "before date" and "after date" audits. Also added building of "dummy" msgids for messages lacking them.
|
||||
|
||||
imapcopy.pl 1.138 2014/07/21
|
||||
Added -O argument to tell imapcopy that both servers are Dovecot using the brain-dead mbox format where mailboxes can have messages or submailboxes but not both.
|
||||
|
||||
imapcopy.pl 1.136 2014/07/21
|
||||
Added -o <destination mailbox> to permit all messages to be copied to a single "archive" mailbox on the destination (and not to the regular mailboxes.)
|
||||
Prompt the user for source/dest user password if the password = PROMPT
|
||||
|
||||
imapcopy.pl 1.129 2014/07/02
|
||||
When building dummy msgids use the Date in the header rather than the INTERNALDATE. It seems that a server may adjust the internaldate according to its timezone.
|
||||
|
||||
imapcopy.pl 1.128 2014/07/02
|
||||
Tweak detection of message size because gmail doesn't send it the way most servers do.
|
||||
|
||||
imapcopy.pl 1.127 2014/06/27
|
||||
Two changes: If a message does not have a Message-ID then build one for it from the Sender, Subject, and INTERNALDATE fields. So the same for the source and destination servers. If -l is set (dont_copy_source_dups) then duplicates on the source will not be copied.
|
||||
|
||||
imapcopy.pl 1.126 2014/06/16
|
||||
Add a 'special date' search function for a customer whose SEARCH command seems to be unreliable. This routine manually compares the INTERNALDATES with the value of -J 'SINCE|BEFORE <date>' argument.
|
||||
|
||||
imapcopy.pl 1.125 2014/06/13
|
||||
Notify msg to dest user with Subject of messages excluded because they exceed the maximum size argument
|
||||
|
||||
imapcopy.pl 1.123 2014/06/13
|
||||
Removed 'from the dest' from sub expunge() since the -r option can be used to purge messages on the source that have been copied.
|
||||
|
||||
imapsync.pl 1.62 2014/07/19
|
||||
Add support for backslash as delimiter for -S and -D host/user/pwd
|
||||
|
||||
imapsync.pl 1.60 2014/07/05
|
||||
Fix the getDatedMsg subroutine for built msgids.
|
||||
|
||||
imapsync.pl 1.58 2014/07/05
|
||||
Include the subject in the constructed msgid.
|
||||
|
||||
imapsync.pl 1.56 2014/07/05
|
||||
Build msgid from date,subject,sender if msgid is missing.
|
||||
|
||||
migrateIMAP.pl 1.54 2014/07/11
|
||||
Use from+header_date+subject for msgid if message lacks one.
|
||||
|
||||
pop3toimap.pl 1.8 2014/07/06
|
||||
Fix problem reading users file on Windows (last character was chopped off).
|
||||
|
||||
thunderbird_to_imap.pl 1.12 2014/07/09
|
||||
Added a range selector to deal with out-of-memory errors
|
||||
|
||||
thunderbird_to_imap.pl 1.11 2014/07/09
|
||||
Fix the way Tbird status codes are interpreted
|
||||
|
||||
thunderbird_to_imap.pl 1.10 2014/07/07
|
||||
Fixed problem with CRLF on some Windows boxes, added complete set of Thunderbird Mozilla status flags.
|
||||
|
||||
thunderbird_to_imap.pl 1.9 2014/07/01
|
||||
Don't print 'running in update mode' unless -U is set.
|
||||
|
||||
thunderbird_to_imap.pl 1.8 2014/07/01
|
||||
Tweak the end-of-message check because some Thunderbird folders have just "From " instead of "From xxxxxxxx"
|
||||
|
||||
thunderbird_to_imap.pl 1.6 2014/06/29
|
||||
Enhance the date-formatting code.
|
||||
|
||||
thunderbird_to_imap.pl 1.5 2014/06/28
|
||||
Fix opt_x which was used for two purposes; add opt_X (CRLF control) in its place.
|
||||
|
30
S/imap_tools.V1.333/release_notes_1.298.txt
Normal file
30
S/imap_tools.V1.333/release_notes_1.298.txt
Normal file
@ -0,0 +1,30 @@
|
||||
Release notes for IMAP-Tools version 1.298.
|
||||
Changes since 2014/07/25:
|
||||
|
||||
The release notes for earlier versions can be found at http://www.athensfbc.com/release_notes
|
||||
|
||||
imap_audit.pl 1.15 2014/08/25
|
||||
Added -n argument to compare only the message counts on src and dest.
|
||||
Add more loop detection code
|
||||
Open mbxs in RO mode
|
||||
|
||||
imap_audit.pl 1.12 2014/07/27
|
||||
Strip off timezone offset when building dummy msgid
|
||||
|
||||
imap_audit.pl 1.11 2014/07/26
|
||||
Added -g argument to force use of dummy msgids for all messages
|
||||
|
||||
imap_audit.pl 1.10 2014/07/26
|
||||
If Message-ID line is wrapped get it from following line
|
||||
|
||||
imapcopy.cgi 1.9 2014/08/18
|
||||
Make the 'Cannot redirect to STDERR' error message more informative.
|
||||
|
||||
imapfilter.pl 1.46 2014/09/01
|
||||
Fixed 'test' mode counters.
|
||||
Add support for numeric date offsets instead of fixed dates in ISEARCH rules
|
||||
Fix issue with chunking of messages. Add -X <Trash> argument for emptying the Trash folder at the end of the run.
|
||||
|
||||
imapsync.pl 1.63 2014/08/26
|
||||
Added -t (dry run) feature.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user