1
0
mirror of https://github.com/imapsync/imapsync.git synced 2024-11-16 15:52:47 +01:00
This commit is contained in:
Nick Bebout 2017-09-23 16:54:48 -05:00
parent 3afeea4a16
commit 8d76e44c5e
243 changed files with 57452 additions and 10330 deletions

View File

@ -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
View File

@ -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
View File

@ -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

1
FAQ Symbolic link
View File

@ -0,0 +1 @@
FAQ.d/FAQ.General.txt

View 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
=======================================================================
=======================================================================

View File

@ -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
=======================================================================
=======================================================================

View 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.

View File

@ -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
=======================================================================
=======================================================================

View File

@ -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'
=======================================================================
=======================================================================

View File

@ -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'
======================================================================
=======================================================================
=======================================================================

View File

@ -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

View File

@ -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.
=======================================================================
=======================================================================

View File

@ -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
=======================================================================
=======================================================================

View File

@ -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."
=======================================================================
=======================================================================

View File

@ -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
=======================================================================
=======================================================================

View File

@ -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
=======================================================================
=======================================================================

View File

@ -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
View 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
=======================================================================
=======================================================================

View File

@ -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/
=======================================================================
=======================================================================

View File

@ -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.
=======================================================================
=======================================================================

View File

@ -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.
=======================================================================
=======================================================================

View File

@ -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.
=======================================================================
=======================================================================
=======================================================================

View File

@ -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
View 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.

View File

@ -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]/'
=======================================================================
=======================================================================

View 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"'
=======================================================================
=======================================================================

View File

@ -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"
=======================================================================
=======================================================================

View 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

View 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
View 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
=======================================================================

View File

@ -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
=======================================================================
=======================================================================

View File

@ -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
View 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.

View File

@ -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
View 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/
=======================================================================
=======================================================================

View File

@ -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
=======================================================================
=======================================================================

View File

@ -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
View 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.

View File

@ -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
View 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.
=======================================================================
=======================================================================

View File

@ -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
View File

@ -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.

1
INSTALL Symbolic link
View File

@ -0,0 +1 @@
INSTALL.d/INSTALL.ANY.txt

165
INSTALL.d/INSTALL.ANY.txt Normal file
View 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

View 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

View File

@ -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 =

View File

@ -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 =

View File

@ -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 =
=================================================

View File

@ -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.

View 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>

View 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

View File

@ -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 =

View 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"

View File

@ -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.

View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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).

View File

@ -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

View File

@ -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" -->

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

57
S/guestbook.shtml Executable file
View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

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
View File

@ -0,0 +1,3 @@
convert logo_imapsync.png -gravity center -resize 190x60 -extent 190x60 logo_paypal.png

Binary file not shown.

959
S/imap_tools.V1.333/IMAPtoMbox.pl Executable file
View 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

File diff suppressed because it is too large Load Diff

1238
S/imap_tools.V1.333/delIMAPdups.pl Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

924
S/imap_tools.V1.333/dumptoIMAP.pl Executable file
View 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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 953 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 884 B

View 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
View 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

File diff suppressed because it is too large Load Diff

1940
S/imap_tools.V1.333/imap_search.pl Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
LOGFILE: imapcopy.log
IMAPCOPY: imapcopy.pl
PROCESS_LIMIT: 8
DEBUG: 0
SHOWIMAP: 0

View 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;
}

View 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

File diff suppressed because it is too large Load Diff

View 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>

View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2348
S/imap_tools.V1.333/imapsync.pl Executable file

File diff suppressed because it is too large Load Diff

View 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. #
############################################################################

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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;
}

File diff suppressed because it is too large Load Diff

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
View 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;
}

View 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.

View 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