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 2011-06-14 06:04:24 -05:00
parent 54b0fc1d9d
commit 091ae4a2e5
17 changed files with 740 additions and 251 deletions

View File

@ -1,5 +1,5 @@
#!/bin/cat
# $Id: CREDITS,v 1.157 2011/05/07 02:30:05 gilles Exp gilles $
# $Id: CREDITS,v 1.159 2011/05/30 21:58:46 gilles Exp gilles $
If you want to make a donation to the author, Gilles LAMIRAL,
use any of the following ways:
@ -30,6 +30,13 @@ 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.
Dex Kelson.
Contributed by his patch for a better good_date() with --idatefromheader over 100000 messages.
Unknow (@baccari.it)
Contributed by giving the book
32.65 "Metamagical Themas: Questing For The Essence Of Mind And Pattern"
Unknow
Contributed by giving the book
20.31 "Fluid Concepts And Creative Analogies: Computer Models Of The Fundamental Mechanisms Of Thought"

View File

@ -1,17 +1,67 @@
RCS file: RCS/imapsync,v
Working file: imapsync
head: 1.434
head: 1.446
branch:
locks: strict
gilles: 1.434
gilles: 1.446
access list:
symbolic names:
keyword substitution: kv
total revisions: 434; selected revisions: 434
total revisions: 446; selected revisions: 446
description:
----------------------------
revision 1.434 locked by: gilles;
revision 1.446 locked by: gilles;
date: 2011/05/31 09:11:18; author: gilles; state: Exp; lines: +17 -17
Bugfix. Try to handle Markus bug in foldersizes() when select_msgs() returns a list of undef.
----------------------------
revision 1.445
date: 2011/05/31 08:00:45; author: gilles; state: Exp; lines: +53 -46
Check if uidexpunge is supported at the beginning of execution, not when needed.
Set --uidexpunge2 if --delete2 or --expunge2 if uidexpunge not supported.
Changed all warn() calls (STDERR) to print calls (STDOUT)
----------------------------
revision 1.444
date: 2011/05/30 15:16:46; author: gilles; state: Exp; lines: +10 -7
good_date() "24 Aug 77" -> "24-Aug-1977"
----------------------------
revision 1.443
date: 2011/05/28 16:50:27; author: gilles; state: Exp; lines: +125 -41
Patched tests_good_date() and good_date() with Dax Kelson patches.
----------------------------
revision 1.442
date: 2011/05/28 16:14:31; author: gilles; state: Exp; lines: +28 -8
Started code to deal with epoch of messages.
----------------------------
revision 1.441
date: 2011/05/26 01:01:25; author: gilles; state: Exp; lines: +14 -11
Handle better folder creation, not a failure when folder "already exists" during its creation.
----------------------------
revision 1.440
date: 2011/05/26 00:40:51; author: gilles; state: Exp; lines: +28 -28
Replaced default setting. Now --delete2 sets --uidexpunge2 instead of --expunge2 (unless --nouidexpunge2 is set)
----------------------------
revision 1.439
date: 2011/05/25 03:11:41; author: gilles; state: Exp; lines: +65 -9
Added epoch() routine to prepare the safe bidirectional sync (maybe...)
----------------------------
revision 1.438
date: 2011/05/25 00:47:27; author: gilles; state: Exp; lines: +9 -8
Adapted the usage output multiline character to Unix or Win, \ or ^
----------------------------
revision 1.437
date: 2011/05/25 00:29:04; author: gilles; state: Exp; lines: +8 -7
Bugfix. Avoid a "no number" warning when size is null.
----------------------------
revision 1.436
date: 2011/05/23 23:30:20; author: gilles; state: Exp; lines: +8 -12
Added "Date" in the default --useheader list. ("Message-Id", "Message-ID", "Date")
----------------------------
revision 1.435
date: 2011/05/23 23:06:31; author: gilles; state: Exp; lines: +29 -12
Bugfix. Bad header beginning with a blank character.
----------------------------
revision 1.434
date: 2011/05/16 07:16:19; author: gilles; state: Exp; lines: +142 -57
Bugfix. Made --usecache work with --maxage or --maxsize or --min*
----------------------------

41
FAQ
View File

@ -1,10 +1,34 @@
#!/bin/cat
# $Id: FAQ,v 1.86 2011/05/16 16:43:12 gilles Exp gilles $
# $Id: FAQ,v 1.88 2011/05/26 00:53:26 gilles Exp gilles $
+------------------+
| FAQ for imapsync |
+------------------+
Unix versus Windows syntax.
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).
./imapsync \
--host1 imap.truc.org --user1 foo --password1 secret1 \
--host2 imap.trac.org --user2 bar --password2 secret2
On Windows this character is ^
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.
=======================================================================
Q. How to install imapsync?
@ -519,12 +543,11 @@ Q. I want the --folder 'MyFolder' option be recursive.
Two solutions:
R. Use
R1. Use
--folderrec 'MyFolder'
R. Do not use the --folder option.
Instead, use --include '^MyFolder'
R2. Use --include '^MyFolder'
Then the folder "MyFolder" and all its subfolders will be handled
and only them.
@ -1192,6 +1215,10 @@ R. imapsync ... \
======================================================================
Q: How can I write an .rpm with imapsync
R: I don't know but Neil Brown wrote one rpm package and you'll find
his .spec file here :
http://www.linux-france.org/prj/imapsync/learn/rpm/
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 derivated from Neil Brown work in 2007.

View File

@ -1,5 +1,5 @@
# $Id: Makefile,v 1.74 2011/05/16 17:25:22 gilles Exp gilles $
# $Id: Makefile,v 1.79 2011/05/31 21:32:16 gilles Exp gilles $
.PHONY: help usage all
@ -25,6 +25,12 @@ DIST_NAME=imapsync-$(VERSION)
DIST_FILE=$(DIST_NAME).tgz
DEB_FILE=$(DIST_NAME).deb
VERSION=$(shell perl -I./Mail-IMAPClient-2.2.9 ./imapsync --version)
VERSION_EXE=$(shell cat ./VERSION_EXE)
HELLO=$(shell date;uname -a)
hello:
echo "$(HELLO)"
all: ChangeLog README VERSION
@ -48,7 +54,7 @@ VERSION: imapsync
clean: clean_tilde clean_man
clean_test:
rm -f .test .test_3xx .test_229
rm -f .test_3xx .test_229
clean_tilde:
rm -f *~
@ -93,8 +99,9 @@ test_quick_229: imapsync tests.sh
test_quick_3xx: imapsync tests.sh
CMD_PERL='perl -I./Mail-IMAPClient-3.28/lib' /usr/bin/time sh -x tests.sh locallocal
testv:
sh -x tests.sh
testv2:
CMD_PERL='perl -I./Mail-IMAPClient-2.2.9' /usr/bin/time sh tests.sh
touch .test_229
testv3:
CMD_PERL='perl -I./Mail-IMAPClient-3.28/lib' sh -x tests.sh
@ -155,6 +162,7 @@ imapsync.exe: imapsync build_exe.bat test_exe.bat .dosify_bat
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/test_exe.bat'
scp Admin@c:'C:/msys/1.0/home/Admin/imapsync/imapsync.exe' .
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/imapsync.exe --version' > VERSION_EXE
dos2unix VERSION_EXE
(date "+%s"| tr "\n" " "; echo -n "END " $(VERSION) ": "; date) >> .BUILD_EXE_TIME
@ -191,7 +199,7 @@ imapsync_elf_x86.bin: imapsync
lfo: cidone niouze_lfo upload_lfo
dist: cidone test clean all INSTALL tarball
dist: cidone test clean all INSTALL dist_prepa dist_prepa_exe
tarball: cidone all
echo making tarball $(DIST_FILE)
@ -205,6 +213,36 @@ tarball: cidone all
cd ../prepa_dist && md5sum -c $(DIST_FILE).md5.txt
ls -l ../prepa_dist/$(DIST_FILE)
DO_IT := $(shell test -f ./dist/path_$(VERSION).txt || makepasswd --chars 4 > ./dist/path_$(VERSION).txt)
DIST_SECRET := $(shell cat ./dist/path_$(VERSION).txt)
DIST_PATH := ./dist/$(DIST_SECRET)
lalala:
echo $(DIST_SECRET)
dist_prepa: tarball dist_dir
ln -f ../prepa_dist/$(DIST_FILE) $(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)/
dist_dir:
@echo $(DIST_SECRET)
@echo $(DIST_PATH)
mkdir -p $(DIST_PATH)
ln -f ./dist/path_$(VERSION).txt ./dist/path_last.txt
dist_prepa_exe: imapsync.exe
mkdir -p $(DIST_PATH)
ln -f ./imapsync.exe $(DIST_PATH)/
#cd $(DIST_PATH)/ && md5sum ./imapsync.exe > ./imapsync.exe.md5.txt
#cd $(DIST_PATH)/ && md5sum -c ./imapsync.exe.md5.txt
ks:
rsync -avz --delete . imapsync@ks.lamiral.info:public_html/imapsync
{ cd /g/var/paypal_reply/ &&\
@ -221,7 +259,7 @@ PUBLIC_FILES = ./ChangeLog ./COPYING ./CREDITS ./FAQ \
upload_ks:
rsync -lptvHz $(PUBLIC_FILES) \
root@ks.lamiral.info:/var/www/imapsync/
rsync -lptvHz ./dist/index.shtml \
rsync -lptvHzr ./dist/ \
root@ks.lamiral.info:/var/www/imapsync/dist/
upload_lfo:

4
README
View File

@ -3,7 +3,7 @@ NAME
Synchronise mailboxes between two imap servers. Good at IMAP migration.
More than 36 different IMAP server softwares supported with success.
$Revision: 1.434 $
$Revision: 1.446 $
SYNOPSIS
To synchronise imap account "foo" on "imap.truc.org" to imap account
@ -424,5 +424,5 @@ SIMILAR SOFTWARES
Feedback (good or bad) will often be welcome.
$Id: imapsync,v 1.434 2011/05/16 07:16:19 gilles Exp gilles $
$Id: imapsync,v 1.446 2011/05/31 09:11:18 gilles Exp gilles $

2
TIME
View File

@ -1,3 +1,5 @@
30 Patched tests_good_date() and good_date() with Dax Kelson patches.
120 Added a good reply for buying support.
540 (1.434) (1.433) (1.432)
180 Tests of mkpath very long path > 300 char. Win32 fails on them. (1.431)
Added special case for Inbox vs INBOX bug creation. (1.430)

4
TODO
View File

@ -1,5 +1,5 @@
#!/bin/cat
# $Id: TODO,v 1.97 2011/05/16 16:39:38 gilles Exp gilles $
# $Id: TODO,v 1.98 2011/05/30 21:59:06 gilles Exp gilles $
TODO file for imapsync
----------------------
@ -23,6 +23,8 @@ Evaluate
http://www.rackspace.com/apps/email_hosting/migrations
http://www.yippiemove.com/
Find a way to avoid passwords in --debugimap unless needed.
Fix long path over than 256 character on Win32.
Think about Digest::SHA or Digest::SHA::PurePerl.

View File

@ -1 +1 @@
1.434
1.446

View File

@ -1 +1 @@
1.434
1.446

View File

@ -1,10 +1,19 @@
REM $Id: build_exe.bat,v 1.8 2010/11/09 01:22:29 gilles Exp gilles $
REM $Id: build_exe.bat,v 1.9 2011/05/31 08:28:29 gilles Exp gilles $
echo Building imapsync.exe
cd C:\msys\1.0\home\Admin\imapsync
perl -mMail::IMAPClient -mDigest::MD5 -mTerm::ReadKey -mIO::Socket::SSL -mFile::Spec -mDigest::HMAC_MD5 -mAuthen::NTLM -e ''
perl -mMail::IMAPClient -mIO::Socket -mIO::Socket::SSL ^
-mDigest::MD5 -mDigest::HMAC_MD5 ^
-mTerm::ReadKey -mFile::Spec -mAuthen::NTLM ^
-mTime::Local ^
-e ''
pp -o imapsync.exe --link libeay32_.dll --link libssl32_.dll -M Mail::IMAPClient -M IO::Socket -M IO::Socket::SSL -M Digest::MD5 -M Digest::HMAC_MD5 -M Term::ReadKey -M Authen::NTLM imapsync
pp -o imapsync.exe --link libeay32_.dll --link libssl32_.dll ^
-M Mail::IMAPClient -M IO::Socket -M IO::Socket::SSL ^
-M Digest::MD5 -M Digest::HMAC_MD5 ^
-M Term::ReadKey -M Authen::NTLM ^
-M Time::Local ^
imapsync
echo Done building imapsync.exe

456
imapsync
View File

@ -20,7 +20,7 @@ Synchronise mailboxes between two imap servers.
Good at IMAP migration. More than 36 different IMAP server softwares
supported with success.
$Revision: 1.434 $
$Revision: 1.446 $
=head1 SYNOPSIS
@ -498,7 +498,7 @@ Entries for imapsync:
Feedback (good or bad) will often be welcome.
$Id: imapsync,v 1.434 2011/05/16 07:16:19 gilles Exp gilles $
$Id: imapsync,v 1.446 2011/05/31 09:11:18 gilles Exp gilles $
=cut
@ -525,6 +525,7 @@ use IO::Socket qw(:crlf SOL_SOCKET SO_KEEPALIVE);
use Errno qw(EAGAIN EPIPE ECONNRESET);
use File::Glob qw( :glob ) ;
use IO::File;
use Time::Local ;
use Test::More 'no_plan';
@ -610,7 +611,7 @@ my(
# global variables initialisation
$rcs = '$Id: imapsync,v 1.434 2011/05/16 07:16:19 gilles Exp gilles $ ';
$rcs = '$Id: imapsync,v 1.446 2011/05/31 09:11:18 gilles Exp gilles $ ';
$total_bytes_transferred = 0;
$total_bytes_skipped = 0;
@ -625,11 +626,28 @@ $h1_total_bytes_duplicate = $h2_total_bytes_duplicate = 0;
$nb_errors = 0;
$max_msg_size_in_bytes = 0;
my %month_abrev = (
Jan => 0,
Feb => 1,
Mar => 2,
Apr => 3,
May => 4,
Jun => 5,
Jul => 6,
Aug => 7,
Sep => 8,
Oct => 9,
Nov => 10,
Dec => 11,
);
unless(defined(&_SYSEXITS_H)) {
# 64 on my linux box.
eval 'sub EX_USAGE () {64;}' unless defined(&EX_USAGE);
}
# @ARGV will be eat by get_options()
my @argv_copy = @ARGV;
@ -731,15 +749,24 @@ if ($delete) {
}
}
if ( $delete2 ) {
if ( ! defined( $expunge2 ) ) {
$expunge2 = 1 ;
}
if ( $uidexpunge2 and ! Mail::IMAPClient->can( 'uidexpunge' ) ) {
print "Failure: uidexpunge not supported (IMAPClient release < 3.17), use --expunge2 instead\n" ;
exit_clean( 3 ) ;
}
if ( $delete2 and ! defined( $uidexpunge2 ) ) {
if ( Mail::IMAPClient->can( 'uidexpunge' ) ) {
print "Info: will act as --uidexpunge2\n" ;
$uidexpunge2 = 1 ;
}elsif ( ! defined( $expunge2 ) ) {
print "Info: will act as --expunge2 (no uidexpunge support)\n" ;
$expunge2 = 1 ;
}
}
if ( $delete and $delete2 ) {
print "Warning: using --delete and --delete2 is almost always a bad idea, exiting imapsync\n" ;
exit_clean( 0 ) ;
exit_clean( 4 ) ;
}
if ($idatefromheader) {
@ -749,10 +776,10 @@ if ($idatefromheader) {
}
if ($syncinternaldates) {
print "Turned ON syncinternaldates, ",
print "Info: turned ON syncinternaldates, ",
"will set the internal dates (arrival dates) on host2 same as host1.\n";
}else{
print "Turned OFF syncinternaldates\n";
print "Info: turned OFF syncinternaldates\n";
}
if (defined($authmd5) and ($authmd5)) {
@ -788,8 +815,8 @@ if (defined $proxyauth2 && !$authuser2) {
$authuser1 ||= $user1;
$authuser2 ||= $user2;
print "Will try to use $authmech1 authentication on host1\n";
print "Will try to use $authmech2 authentication on host2\n";
print "Info: will try to use $authmech1 authentication on host1\n";
print "Info: will try to use $authmech2 authentication on host2\n";
$syncacls = (defined($syncacls)) ? $syncacls : 0;
$foldersizes = (defined($foldersizes)) ? $foldersizes : 1;
@ -800,16 +827,13 @@ $fastio2 = (defined($fastio2)) ? $fastio2 : 0;
$reconnectretry1 = (defined($reconnectretry1)) ? $reconnectretry1 : 3;
$reconnectretry2 = (defined($reconnectretry2)) ? $reconnectretry2 : 3;
@useheader = ( "Message-Id", "Message-ID" ) unless ( @useheader ) ;
@useheader = ( "Message-Id", "Message-ID", "Date" ) unless ( @useheader ) ;
my %useheader ;
# Make a hash %useheader of each --useheader 'key' in uppercase
@useheader{ map( { uc( $_ ) } @useheader ) } = ( ) ;
my %useheaderclassic ;
@useheaderclassic{ qw(MESSAGE-ID DATE) } = ( ) ;
#require Data::Dumper ;
#print Data::Dumper->Dump( [ \%useheader ] ) ;
@ -1084,7 +1108,6 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
$debug and print '[',
map ( { "$_->$cache_1_2_ref->{$_} " } keys %$cache_1_2_ref ), " ]\n";
}
#sleep 4 ;
my %h1_hash = ();
my %h2_hash = ();
@ -1096,33 +1119,33 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
my @h1_msgs_in_cache = sort { $a <=> $b } keys %$cache_1_2_ref ;
my @h2_msgs_in_cache = keys %$cache_2_1_ref ;
my ( %h1_msgs_no_cache, %h2_msgs_no_cache ) ;
%h1_msgs_no_cache = %h1_msgs ;
%h2_msgs_no_cache = %h2_msgs ;
delete @h1_msgs_no_cache{ @h1_msgs_in_cache } ;
delete @h2_msgs_no_cache{ @h2_msgs_in_cache } ;
my ( %h1_msgs_not_in_cache, %h2_msgs_not_in_cache ) ;
%h1_msgs_not_in_cache = %h1_msgs ;
%h2_msgs_not_in_cache = %h2_msgs ;
delete @h1_msgs_not_in_cache{ @h1_msgs_in_cache } ;
delete @h2_msgs_not_in_cache{ @h2_msgs_in_cache } ;
my @h1_msgs_no_cache = keys %h1_msgs_no_cache ;
#print "h1_msgs_no_cache: [@h1_msgs_no_cache]\n" ;
my @h2_msgs_no_cache = keys %h2_msgs_no_cache ;
my @h1_msgs_not_in_cache = keys %h1_msgs_not_in_cache ;
#print "h1_msgs_not_in_cache: [@h1_msgs_not_in_cache]\n" ;
my @h2_msgs_not_in_cache = keys %h2_msgs_not_in_cache ;
my @h2_msgs_delete2_no_cache = () ;
my @h2_msgs_delete2_not_in_cache = () ;
%h1_msgs_copy_by_uid = ( ) ;
if ( $useuid ) {
# use uid so we have to avoid getting header
@h1_msgs_copy_by_uid{ @h1_msgs_no_cache } = ( ) ;
@h2_msgs_delete2_no_cache = @h2_msgs_no_cache if $usecache ;
@h1_msgs_no_cache = ( ) ;
@h2_msgs_no_cache = ( ) ;
@h1_msgs_copy_by_uid{ @h1_msgs_not_in_cache } = ( ) ;
@h2_msgs_delete2_not_in_cache = @h2_msgs_not_in_cache if $usecache ;
@h1_msgs_not_in_cache = ( ) ;
@h2_msgs_not_in_cache = ( ) ;
#print "delete2: @h2_msgs_delete2_no_cache\n";
#print "delete2: @h2_msgs_delete2_not_in_cache\n";
}
$debug and print "Host1 parsing headers of folder [$h1_fold]\n";
my ($h1_heads_ref, $h1_fir_ref) = ({}, {});
$h1_heads_ref = $imap1->parse_headers([@h1_msgs_no_cache], @useheader) if (@h1_msgs_no_cache);
$h1_heads_ref = $imap1->parse_headers([@h1_msgs_not_in_cache], @useheader) if (@h1_msgs_not_in_cache);
$debug and print "Host1 parsing headers of folder [$h1_fold] took ", timenext(), " s\n";
@$h1_fir_ref{@h1_msgs} = (undef);
@ -1132,7 +1155,7 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
if (@h1_msgs);
$debug and print "Host1 getting flags idate and sizes of folder [$h1_fold] took ", timenext(), " s\n";
unless ($h1_fir_ref) {
warn
print
"Host1 folder $h1_fold: Could not fetch_hash_2 ",
scalar(@h1_msgs), " msgs: ", $imap1->LastError, "\n";
$nb_errors++;
@ -1140,7 +1163,7 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
}
my @h1_msgs_duplicate;
foreach my $m (@h1_msgs_no_cache) {
foreach my $m (@h1_msgs_not_in_cache) {
my $rc = parse_header_msg($imap1, $m, $h1_heads_ref, $h1_fir_ref, 'Host1', \%h1_hash);
if (! defined($rc)) {
my $h1_size = $h1_fir_ref->{$m}->{"RFC822.SIZE"} || 0;
@ -1164,7 +1187,7 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
$debug and print "Host2 parsing headers of folder [$h2_fold]\n";
my ($h2_heads_ref, $h2_fir_ref) = ( {}, {} );
$h2_heads_ref = $imap2->parse_headers([@h2_msgs_no_cache], @useheader) if (@h2_msgs_no_cache);
$h2_heads_ref = $imap2->parse_headers([@h2_msgs_not_in_cache], @useheader) if (@h2_msgs_not_in_cache);
$debug and print "Host2 parsing headers of folder [$h2_fold] took ", timenext(), " s\n" ;
$debug and print "Host2 getting flags idate and sizes of folder [$h2_fold]\n" ;
@ -1174,7 +1197,7 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
$debug and print "Host2 getting flags idate and sizes of folder [$h2_fold] took ", timenext(), " s\n" ;
my @h2_msgs_duplicate;
foreach my $m (@h2_msgs_no_cache) {
foreach my $m (@h2_msgs_not_in_cache) {
my $rc = parse_header_msg($imap2, $m, $h2_heads_ref, $h2_fir_ref, 'Host2', \%h2_hash);
my $h2_size = $h2_fir_ref->{$m}->{"RFC822.SIZE"} || 0;
if (! defined($rc)) {
@ -1200,7 +1223,19 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
my @h2_hash_keys_sorted_by_uid
= sort {$h2_hash{$a}{'m'} <=> $h2_hash{$b}{'m'}} keys(%h2_hash);
if ( 0 ) {
# hashes, keys are uid, values are the internaldates in epoch (best format to compare dates)
my %h1_epoch ;
my %h2_epoch ;
@h1_epoch{ @h1_msgs } = map( { epoch( $h1_fir_ref->{ $_ }->{ 'INTERNALDATE' } ) } @h1_msgs ) ;
@h2_epoch{ @h2_msgs } = map( { epoch( $h2_fir_ref->{ $_ }->{ 'INTERNALDATE' } ) } @h2_msgs ) ;
#print keyval( %h1_epoch ) ;
#print keyval( %h2_epoch ) ;
my $h1_greatest_epoch = max( values %h1_epoch ) ;
print "h1_greatest_epoch $h1_greatest_epoch\n" ;
}
#next FOLDER ;
if($delete2) {
my @h2_expunge;
foreach my $m_id (@h2_hash_keys_sorted_by_uid) {
@ -1226,24 +1261,22 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
$h2_nb_msg_deleted += 1;
}
}
foreach my $h2_msg ( @h2_msgs_delete2_no_cache ) {
foreach my $h2_msg ( @h2_msgs_delete2_not_in_cache ) {
print "msg $h2_fold/$h2_msg marked \\Deleted [not in cache] on host2\n";
push(@h2_expunge, $h2_msg) if $uidexpunge2;
unless ($dry) {
$imap2->delete_message($h2_msg);
$h2_nb_msg_deleted += 1;
}
}
my $cnt = scalar @h2_expunge;
if(@h2_expunge and !$imap2->can("uidexpunge")) {
warn "uidexpunge not supported (< IMAPClient 3.17)\n";
}
elsif(@h2_expunge) {
print "uidexpunge $cnt message(s)\n";
$imap2->uidexpunge(\@h2_expunge) if !$dry;
my $cnt = scalar @h2_expunge ;
if( @h2_expunge ) {
print "uidexpunge $cnt message(s)\n" ;
$imap2->uidexpunge( \@h2_expunge ) if ! $dry ;
}
if ($expunge2){
print "Expunging host2 folder $h2_fold\n";
unless($dry) { $imap2->expunge() };
print "Expunging host2 folder $h2_fold\n" ;
$imap2->expunge( ) if ! $dry ;
}
}
@ -1319,7 +1352,7 @@ $debug and print "Time: ", timenext(), " s\n";
}
sub size_filtered_flag {
my( $h1_size ) = @_ ;
my $h1_size = shift ;
if (defined $maxsize and $h1_size >= $maxsize) {
return( 1 ) ;
@ -1362,7 +1395,7 @@ sub sync_flags {
# we need most of the time.
if ( ! $dry and $diff and ! $imap2->store( $h2_msg, "FLAGS.SILENT (@h1_flags)" ) ) {
warn "- msg $h2_fold/$h2_msg could not add flags [@h1_flags]: ",
print "- msg $h2_fold/$h2_msg could not add flags [@h1_flags]: ",
$imap2->LastError, "\n";
#$nb_errors++;
}
@ -1403,6 +1436,13 @@ sub tests_max {
#ok(100 == max(100, "haha", 1), "max 100 42 1");
}
sub keyval {
my %hash = @_ ;
return( join( " ", map( { "$_ => " . $hash{ $_ } } keys %hash ) ) . "\n" ) ;
}
sub check_lib_version {
$debug and print "IMAPClient $Mail::IMAPClient::VERSION\n";
if ($Mail::IMAPClient::VERSION eq '2.2.9') {
@ -1681,22 +1721,22 @@ sub login_imap {
#$imap->connect()
myconnect($imap)
or die_clean("Can not open imap connection on [$host] with user [$user]: $@\n");
or die_clean("Failure: can not open imap connection on [$host] with user [$user]: $@\n");
print "Banner: ", server_banner($imap);
if ($imap->has_capability("AUTH=$authmech")
or $imap->has_capability($authmech)
) {
printf("Host %s says it has CAPABILITY for AUTHENTICATE %s\n",
printf("Info: host %s says it has CAPABILITY for AUTHENTICATE %s\n",
$imap->Server, $authmech);
}
else {
printf("Host %s says it has NO CAPABILITY for AUTHENTICATE %s\n",
printf("Info: host %s says it has NO CAPABILITY for AUTHENTICATE %s\n",
$imap->Server, $authmech);
if ($authmech eq 'PLAIN') {
print "Frequently PLAIN is only supported with SSL, ",
"try --ssl1 or --ssl2 option\n";
print "Info: frequently PLAIN is only supported with SSL, ",
"try --ssl or --tls options\n";
}
}
@ -1722,13 +1762,13 @@ sub login_imap {
}
unless ($imap->login()) {
my $info = "Error login: [$host] with user [$user] auth";
my $info = "Failure: error login [$host] with user [$user] auth";
my $einfo = $imap->LastError || @{$imap->History}[-1];
chomp($einfo);
my $error = "$info [$authmech]: $einfo\n";
print $error; # note: duplicating error on stdout/stderr
die_clean($error) if ($authmech eq 'LOGIN' or $imap->IsUnconnected() or $authuser);
print "Trying LOGIN Auth mechanism on [$host] with user [$user]\n";
print "Info: trying LOGIN Auth mechanism on [$host] with user [$user]\n";
$imap->Authmechanism("");
$imap->login() or
die_clean("$info [LOGIN]: ", $imap->LastError, "\n");
@ -1736,7 +1776,7 @@ sub login_imap {
$proxyauth && $imap->proxyauth($user);
$split and $imap->Split( $split ) ;
print "Success login on [$host] with user [$user] auth [$authmech]\n";
print "Info: success login on [$host] with user [$user] auth [$authmech]\n";
return($imap);
}
@ -1763,8 +1803,8 @@ sub banner_imapsync {
my @argv_copy = @_;
my $banner_imapsync = join("",
'$RCSfile: imapsync,v $ ',
'$Revision: 1.434 $ ',
'$Date: 2011/05/16 07:16:19 $ ',
'$Revision: 1.446 $ ',
'$Date: 2011/05/31 09:11:18 $ ',
"\n",localhost_info(), "\n",
"Command line used:\n",
"$0 ", command_line_nopassword(@argv_copy), "\n",
@ -1786,10 +1826,10 @@ sub write_pidfile {
print "PID file is $pidfile\n";
if (-e $pidfile) {
warn "$pidfile already exists, overwriting it\n";
print "$pidfile already exists, overwriting it\n";
}
open(PIDFILE, ">$pidfile") or do {
warn "Could not open $pidfile for writing";
print "Could not open $pidfile for writing";
return undef;
};
@ -1820,7 +1860,7 @@ sub missing_option {
sub select_folder {
my ($imap, $folder, $hostside) = @_;
if ( ! $imap->select($folder)) {
warn
print
"$hostside folder $folder: Could not select: ",
$imap->LastError, "\n";
$nb_errors++;
@ -1842,18 +1882,21 @@ sub create_folder {
return( 1 ) ;
}
if ( ! $dry ){
if ( ! $imap2->create($h2_fold)){
warn( "Couldn't create folder [$h2_fold] from [$h1_fold]: ",
$imap2->LastError(), "\n" );
if ( ! $imap2->create( $h2_fold ) ) {
print( "Couldn't create folder [$h2_fold] from [$h1_fold]: ",
$imap2->LastError( ), "\n" );
$nb_errors++;
return(0);
# success if folder exists ("already exists" error)
return( 1 ) if $imap2->exists( $h2_fold ) ;
# failure since create failed
return( 0 );
}else{
#create succeeded
return(1);
return( 1 );
}
}else{
# dry mode, no folder so many imap will fail, assuming failure
return(0);
return( 0 );
}
}
@ -2149,14 +2192,14 @@ sub imap2_folder_name {
sub foldersizes {
my ($side, $imap, @folders) = @_;
my $tot = 0;
my $tmess = 0;
my $total_size = 0;
my $total_nb = 0;
my $biggest = 0 ;
print "++++ Calculating sizes\n";
foreach my $folder (@folders) {
my $stot = 0;
my $smess = 0;
my $nb_msgs = 0;
printf("$side folder %-35s", "[$folder]");
if ( 'Host2' eq $side and ! exists( $h2_folders_all{ $folder } ) ) {
print(" does not exist yet\n") ;
@ -2168,7 +2211,7 @@ sub foldersizes {
}
unless ($imap->examine($folder)) {
warn
print
"$side Folder $folder: Could not examine: ",
$imap->LastError, "\n";
$nb_errors++;
@ -2177,10 +2220,10 @@ sub foldersizes {
my $hash_ref = {};
my @msgs = select_msgs($imap);
$smess = scalar(@msgs);
$nb_msgs = scalar(@msgs);
my $smax = 0 ;
@$hash_ref{@msgs} = (undef);
unless ($smess == 0) {
@$hash_ref{@msgs} = (undef) if @msgs ;
if ( $nb_msgs > 0 and @msgs ) {
$imap->fetch_hash_2("RFC822.SIZE",$hash_ref) or die_clean("$@");
#print map {$hash_ref->{$_}->{"RFC822.SIZE"}, " "} keys %$hash_ref;
map {$stot += $hash_ref->{$_}->{"RFC822.SIZE"}} keys %$hash_ref ;
@ -2189,13 +2232,13 @@ sub foldersizes {
}
printf(" Size: %9s", $stot);
printf(" Messages: %5s", $smess);
printf(" Messages: %5s", $nb_msgs);
printf(" Biggest: %9s\n", $smax);
$tot += $stot;
$tmess += $smess;
$total_size += $stot;
$total_nb += $nb_msgs;
}
printf ("Nb messages: %11s\n", $tmess ) ;
printf ("Total size: %11s bytes\n", $tot ) ;
printf ("Nb messages: %11s\n", $total_nb ) ;
printf ("Total size: %11s bytes\n", $total_size ) ;
printf ("Biggest message: %11s bytes\n", $biggest ) ;
printf ("Time: %11s secondes\n", timenext( ) ) ;
}
@ -2328,9 +2371,9 @@ sub acls_sync {
my($h1_fold, $h2_fold) = @_;
if ($syncacls) {
my $h1_hash = $imap1->getacl($h1_fold)
or warn "Could not getacl for $h1_fold: $@\n";
or print "Could not getacl for $h1_fold: $@\n";
my $h2_hash = $imap2->getacl($h2_fold)
or warn "Could not getacl for $h2_fold: $@\n";
or print "Could not getacl for $h2_fold: $@\n";
my %users = map({ ($_, 1) } (keys(%$h1_hash), keys(%$h2_hash)));
foreach my $user (sort(keys(%users))) {
my $acl = $h1_hash->{$user} || "none";
@ -2340,7 +2383,7 @@ sub acls_sync {
unless ($dry) {
print "setting acl $h2_fold $user $acl\n";
$imap2->setacl($h2_fold, $user, $acl)
or warn "Could not set acl: $@\n";
or print "Could not set acl: $@\n";
}
}
}
@ -2520,6 +2563,7 @@ sub lastuid {
sub size_filtered {
my( $h1_size, $h1_msg, $h1_fold, $h2_fold ) = @_ ;
$h1_size = 0 if ( ! $h1_size ) ; # null if empty or undef
if (defined $maxsize and $h1_size >= $maxsize) {
print "msg $h1_fold/$h1_msg skipped ($h1_size exceeds maxsize limit $maxsize bytes)\n";
$total_bytes_skipped += $h1_size;
@ -2558,7 +2602,7 @@ sub copy_message {
my $string_len = defined( $string ) ? length( $string ) : '' ; # length or undef
#print "- msg $h1_fold/$h1_msg {$string_len}\n" ;
unless ( defined( $string ) and $string_len ) { # undef or 0 length
warn
print
"- msg $h1_fold/$h1_msg {$string_len} S[$h1_size] F[$h1_flags] I[$h1_idate] could not be fetched: ",
$imap1->LastError, "\n" ;
$nb_errors++ ;
@ -2607,7 +2651,7 @@ sub copy_message {
$new_id = $imap2->append_string($h2_fold, $string, $h1_flags, $h1_date);
unless($new_id){
no warnings 'uninitialized';
warn "- msg $h1_fold/$h1_msg {$string_len} couldn't append (Subject:[".
print "- msg $h1_fold/$h1_msg {$string_len} couldn't append (Subject:[".
$imap1->subject($h1_msg)."]) to folder $h2_fold: ",
$imap2->LastError, "\n";
$nb_errors++;
@ -2900,7 +2944,7 @@ sub clean_cache {
or ( ! exists( $h2_msgs_all_hash_ref->{ $uid2 } ) )
) {
$debugcache and print "remove $file\n" ;
unlink( $file ) or warn "$!" ;
unlink( $file ) or print "$!" ;
}
}
@ -3057,6 +3101,8 @@ sub cache_folder {
my $h2_fold_slash = convert_sep_to_slash( $h2_fold, $sep2 );
return( "$cache_dir/$h1_fold_slash/$h2_fold_slash" ) ;
}
sub convert_sep_to_slash {
@ -3393,8 +3439,7 @@ sub parse_header_msg {
foreach my $h (sort keys(%$head)){
next if ( ! exists( $useheader{ uc( $h ) } )
and ! exists( $useheader{ 'ALL' } )
and ! exists( $useheaderclassic{ uc( $h ) } )
and ! exists( $useheader{ 'ALL' } )
) ;
foreach my $val (sort @{$head->{$h}}) {
# no 8-bit data in headers !
@ -3506,7 +3551,7 @@ sub check_last_release {
}
sub imapsync_version {
my $rcs = '$Id: imapsync,v 1.434 2011/05/16 07:16:19 gilles Exp gilles $ ';
my $rcs = '$Id: imapsync,v 1.446 2011/05/31 09:11:18 gilles Exp gilles $ ';
$rcs =~ m/,v (\d+\.\d+)/;
my $VERSION = ($1) ? $1: "UNKNOWN";
return($VERSION);
@ -3562,7 +3607,7 @@ sub not_long {
POSIX::sigaction(SIGALRM,
POSIX::SigAction->new(sub { die "alarm" }))
or warn "Error setting SIGALRM handler: $!\n";
or print "Error setting SIGALRM handler: $!\n";
}
eval {
@ -3613,6 +3658,7 @@ sub usage {
my $thank = thank_author();
my $warn_release ='';
$warn_release = check_last_release() if (not defined($releasecheck));
my $escape_char = ( 'MSWin32' eq $OSNAME ) ? '^' : '\\';
print <<EOF;
usage: $0 [options]
@ -3781,8 +3827,8 @@ Example: to synchronise imap account "foo" on "imap.truc.org"
with foo password "secret1"
and bar password "secret2"
$0 \\
--host1 imap.truc.org --user1 foo --password1 secret1 \\
$0 $escape_char
--host1 imap.truc.org --user1 foo --password1 secret1 $escape_char
--host2 imap.trac.org --user2 bar --password2 secret2
$localhost_info
@ -3794,41 +3840,6 @@ EOF
}
sub good_date {
# two incoming formats:
# header Tue, 24 Aug 2010 16:00:00 +0200
# internal 24-Aug-2010 16:00:00 +0200
# outgoing format: internal date format
# 24-Aug-2010 16:00:00 +0200
my ($d) = @_;
return ('') if not defined($d);
if ( $d =~ m{(\d?)(\d-...-\d{4})( \d{2}:\d{2}:\d{2})( (?:\+|-)\d{4})?}o ) {
#print "internal: [$1][$2][$3][$4]\n";
my ($day_1, $date_rest, $hour, $zone) = ($1,$2,$3,$4);
$day_1 = '0' if ($day_1 eq '');
$zone = ' +0000' if not defined($zone);
$d = $day_1 . $date_rest . $hour . $zone;
}elsif ($d =~ m{(?:.{3}, )(\d?)(\d) (...) (\d{4})( \d{2}:\d{2}:\d{2})( (?:\+|-)\d{4})?}o ) {
#print "header: [$1][$2][$3][$4][$5][$6]\n";
my ($day_1, $day_rest, $month, $year, $hour, $zone) = ($1,$2,$3,$4,$5,$6);
$day_1 = '0' if ($day_1 eq '');
$zone = ' +0000' if not defined($zone);
$d = $day_1 . "$day_rest-$month-$year" . $hour . $zone;
}else{
# unknown/unmatch => return same string
return($d);
}
$d = qq("$d");
return($d);
}
sub memory_consumption {
# memory consumed by imapsync until now in bytes
return((memory_consumption_of_pids())[0]);
@ -3938,6 +3949,109 @@ sub tests_memory_consumption {
ok(print memory_consumption(), "\n");
}
sub good_date {
# two incoming formats:
# header Tue, 24 Aug 2010 16:00:00 +0200
# internal 24-Aug-2010 16:00:00 +0200
# outgoing format: internal date format
# 24-Aug-2010 16:00:00 +0200
my $d = shift ;
return ('') if not defined($d);
if ( $d =~ m{(\d?)(\d-...-\d{4})( \d{2}:\d{2}:\d{2})( (?:\+|-)\d{4})?}o ) {
#print "internal: [$1][$2][$3][$4]\n";
my ($day_1, $date_rest, $hour, $zone) = ($1,$2,$3,$4);
$day_1 = '0' if ($day_1 eq '');
$zone = ' +0000' if not defined($zone);
$d = $day_1 . $date_rest . $hour . $zone;
}elsif ($d =~ m{(?:\w{3,}, )?(\d{1,2}),?\s+(\w{3,})\s+(\d{2,4})\s+(\d{1,2})(?::|\.)(\d{1,2})(?:(?::|\.)(\d{1,2}))?\s*((?:\+|-)\d{4})?}o ) {
# Handles any combination of following formats
# Tue, 24 Aug 2010 16:00:00 +0200 -- Standard
# 24 Aug 2010 16:00:00 +0200 -- Missing Day of Week
# Tue, 24 Aug 97 16:00:00 +0200 -- Two digit year
# Tue, 24 Aug 1997 16.00.00 +0200 -- Periods instead of colons
# Tue, 24 Aug 1997 16:00:00 +0200 -- Extra whitespace between year and hour
# Tue, 24 Aug 1997 6:5:2 +0200 -- Single digit hour, min, or second
# Tue, 24, Aug 1997 16:00:00 +0200 -- Extra comma
#print "header: [$1][$2][$3][$4][$5][$6][$7][$8]\n";
my ($day, $month, $year, $hour, $min, $sec, $zone) = ($1,$2,$3,$4,$5,$6,$7,$8);
$year = '19' . $year if length($year) == 2 && $year =~ /^[789]/;
$year = '20' . $year if length($year) == 2;
$month = substr $month, 0, 3 if length($month) > 4;
$day = sprintf("%02d", $day);
$hour = sprintf("%02d", $hour);
$min = sprintf("%02d", $min);
$sec = '00' if not defined($sec);
$sec = sprintf("%02d", $sec);
$zone = '+0000' if not defined($zone);
$d = "$day-$month-$year $hour:$min:$sec $zone";
}elsif ($d =~ m{(?:.{3}) (...)\s+(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2}) (?:\w{3})?\s?(\d{4})}o ) {
# Handles any combination of following formats
# Sun Aug 20 11:55:09 2006
# Wed Jan 24 11:58:38 MST 2007
# Wed Jan 2 08:40:57 2008
#print "header: [$1][$2][$3][$4][$5][$6]\n";
my ($month, $day, $hour, $min, $sec, $year) = ($1,$2,$3,$4,$5,$6);
$day = sprintf("%02d", $day);
$hour = sprintf("%02d", $hour);
$min = sprintf("%02d", $min);
$sec = sprintf("%02d", $sec);
$d = "$day-$month-$year $hour:$min:$sec +0000";
}elsif ($d =~ m{(\d{2})/(\d{2})/(\d{2}) (\d{2}):(\d{2}):(\d{2})}o ) {
# Handles the following format
# 02/06/09 22:18:08 -- Generated by AVTECH TemPageR devices
#print "header: [$1][$2][$3][$4][$5][$6]\n";
my ($month, $day, $year, $hour, $min, $sec) = ($1,$2,$3,$4,$5,$6);
$year = '20' . $year;
my %num2mon = qw(01 Jan 02 Feb 03 Mar 04 Apr 05 May 06 Jun 07 Jul 08 Aug 09 Sep 10 Oct 11 Nov 12 Dec);
$month = $num2mon{$month};
$d = "$day-$month-$year $hour:$min:$sec +0000";
}elsif ($d =~ m{\w{6,}, (\w{3})\w+\s+(\d{1,2}), (\d{4}) (\d{2}):(\d{2}) (AM|PM)}o ) {
# Handles the following format
# Saturday, December 14, 2002 05:00 PM - KBtoys.com order confirmations
my ($month, $day, $year, $hour, $min, $apm) = ($1,$2,$3,$4,$5,$6);
$hour += 12 if $apm eq 'PM';
$day = sprintf("%02d", $day);
$d = "$day-$month-$year $hour:$min:00 +0000";
}elsif ($d =~ m{(\w{3}) (\d{1,2}) (\d{4}) (\d{2}):(\d{2}):(\d{2}) ((?:\+|-)\d{4})}o ) {
# Handles the following format
# Saturday, December 14, 2002 05:00 PM - jr.com order confirmations
my ($month, $day, $year, $hour, $min, $sec, $zone) = ($1,$2,$3,$4,$5,$6,$7);
$day = sprintf("%02d", $day);
$d = "$day-$month-$year $hour:$min:$sec $zone";
}elsif ($d =~ m{(\d{1,2})-(\w{3})-(\d{4})}o ) {
# Handles the following format
# 21-Jun-2001 - register.com domain transfer email circa 2001
my ($day, $month, $year) = ($1,$2,$3);
$day = sprintf("%02d", $day);
$d = "$day-$month-$year 11:11:11 +0000";
}else{
# unknown/unmatch => return same string
return($d);
}
$d = qq("$d");
return($d);
}
sub tests_good_date {
ok('' eq good_date(), 'good_date no arg');
@ -3948,6 +4062,25 @@ sub tests_good_date {
ok('"01-Sep-2010 16:00:00 +0000"' eq good_date('Wed, 1 Sep 2010 16:00:00'), 'good_date header SP 1digit zone');
ok('"01-Sep-2010 16:00:00 +0200"' eq good_date('Wed, 1 Sep 2010 16:00:00 +0200'), 'good_date header SP 1digit zone');
ok('"01-Sep-2010 16:00:00 +0200"' eq good_date('Wed, 1 Sep 2010 16:00:00 +0200 (CEST)'), 'good_date header SP 1digit zone');
ok('"06-Feb-2009 22:18:08 +0000"' eq good_date('02/06/09 22:18:08'), 'good_date header TemPageR');
ok('"02-Jan-2008 08:40:57 +0000"' eq good_date('Wed Jan 2 08:40:57 2008'), 'good_date header dice.com support 1digit day');
ok('"20-Aug-2006 11:55:09 +0000"' eq good_date('Sun Aug 20 11:55:09 2006'), 'good_date header dice.com support 2digit day');
ok('"24-Jan-2007 11:58:38 +0000"' eq good_date('Wed Jan 24 11:58:38 MST 2007'), 'good_date header status-now.com');
ok('"24-Aug-2010 16:00:00 +0200"' eq good_date('24 Aug 2010 16:00:00 +0200'), 'good_date header missing date of week');
ok('"24-Aug-2067 16:00:00 +0200"' eq good_date('Tue, 24 Aug 67 16:00:00 +0200'), 'good_date header 2digit year');
ok('"24-Aug-1977 16:00:00 +0200"' eq good_date('Tue, 24 Aug 77 16:00:00 +0200'), 'good_date header 2digit year');
ok('"24-Aug-1987 16:00:00 +0200"' eq good_date('Tue, 24 Aug 87 16:00:00 +0200'), 'good_date header 2digit year');
ok('"24-Aug-1997 16:00:00 +0200"' eq good_date('Tue, 24 Aug 97 16:00:00 +0200'), 'good_date header 2digit year');
ok('"24-Aug-2004 16:00:00 +0200"' eq good_date('Tue, 24 Aug 04 16:00:00 +0200'), 'good_date header 2digit year');
ok('"24-Aug-1997 16:00:00 +0200"' eq good_date('Tue, 24 Aug 1997 16.00.00 +0200'), 'good_date header period time sep');
ok('"24-Aug-1997 16:00:00 +0200"' eq good_date('Tue, 24 Aug 1997 16:00:00 +0200'), 'good_date header extra white space type1');
ok('"24-Aug-1997 05:06:02 +0200"' eq good_date('Tue, 24 Aug 1997 5:6:2 +0200'), 'good_date header 1digit time vals');
ok('"24-Aug-1997 05:06:02 +0200"' eq good_date('Tue, 24, Aug 1997 05:06:02 +0200'), 'good_date header extra commas');
ok('"01-Oct-2003 12:45:24 +0000"' eq good_date('Wednesday, 01 October 2003 12:45:24 CDT'), 'good_date header no abbrev');
ok('"11-Jan-2005 17:58:27 -0500"' eq good_date('Tue, 11 Jan 2005 17:58:27 -0500'), 'good_date extra white space');
ok('"18-Dec-2002 15:07:00 +0000"' eq good_date('Wednesday, December 18, 2002 03:07 PM'), 'good_date kbtoys.com orders');
ok('"16-Dec-2004 02:01:49 -0500"' eq good_date('Dec 16 2004 02:01:49 -0500'), 'good_date jr.com orders');
ok('"21-Jun-2001 11:11:11 +0000"' eq good_date('21-Jun-2001'), 'good_date register.com domain transfer');
}
@ -4054,7 +4187,7 @@ sub decompose_header{
}elsif( $line =~ m/^(\s+)(.*)/ ) {
$val = $2 ;
#print "DDD only [$val]\n" ;
@{ $header->{ $key } }[ -1 ] .= " $val" ;
@{ $header->{ $key } }[ -1 ] .= " $val" if $key ;
}else{
next ;
}
@ -4126,18 +4259,72 @@ Received: from plume [192.168.68.7]
ok(
'from plume [192.168.68.7] by plume with POP3 (fetchmail-6.3.6) for <gilles@localhost> (single-drop); Mon, 26 Nov 2007 10:39:06 +0100 (CET)'
eq $header_dec->{ 'Received' }[1], 'decompose_header: 3' ) ;
# Bad header beginning with a blank character
$header_dec = decompose_header(
' KEY_1: VAL_1
KEY_2: VAL_2
VAL_2_+
VAL_2_++
KEY_3: VAL_3
KEY_1: VAL_1_other
'
) ;
ok( 'VAL_3'
eq $header_dec->{ 'KEY_3' }[0], 'decompose_header: Bad header VAL_3' ) ;
ok( 'VAL_1_other'
eq $header_dec->{ 'KEY_1' }[0], 'decompose_header: Bad header VAL_1_other' ) ;
ok( 'VAL_2 VAL_2_+ VAL_2_++'
eq $header_dec->{ 'KEY_2' }[0], 'decompose_header: Bad header VAL_2 VAL_2_+ VAL_2_++' ) ;
}
sub epoch {
# incoming format:
# internal date 24-Aug-2010 16:00:00 +0200
# outgoing format: epoch
my $d = shift ;
return ('') if not defined($d);
my ( $mday, $month, $year, $hour, $min, $sec, $sign, $zone_h, $zone_m ) ;
my $time ;
if ( $d =~ m{(\d{2})-([A-Z][a-z]{2})-(\d{4}) (\d{2}):(\d{2}):(\d{2}) ((?:\+|-))(\d{2})(\d{2})}o ) {
#print "internal: [$1][$2][$3][$4][$5][$6][$7][$8][$9]\n" ;
( $mday, $month, $year, $hour, $min, $sec, $sign, $zone_h, $zone_m )
= ( $1, $2, $3, $4, $5, $6, $7, $8, $9 ) ;
#print "( $mday, $month, $year, $hour, $min, $sec, $sign, $zone_h, $zone_m )\n" ;
$sign = +1 if ( '+' eq $sign ) ;
$sign = -1 if ( '-' eq $sign ) ;
$time = timegm( $sec, $min, $hour, $mday, $month_abrev{$month}, $year )
- $sign * ( 3600 * $zone_h + 60 * $zone_m ) ;
#print( "$time ", scalar(localtime($time)), "\n");
}
return( $time ) ;
}
sub tests_epoch {
ok( '1282658400' eq epoch( '24-Aug-2010 16:00:00 +0200' ), 'epoch 24-Aug-2010 16:00:00 +0200 -> 1282658400' ) ;
ok( '1282658400' eq epoch( '24-Aug-2010 14:00:00 +0000' ), 'epoch 24-Aug-2010 14:00:00 +0000 -> 1282658400' ) ;
ok( '1282658400' eq epoch( '24-Aug-2010 12:00:00 -0200' ), 'epoch 24-Aug-2010 12:00:00 -0200 -> 1282658400' ) ;
ok( '1282658400' eq epoch( '24-Aug-2010 16:01:00 +0201' ), 'epoch 24-Aug-2010 16:01:00 +0201 -> 1282658400' ) ;
ok( '1282658400' eq epoch( '24-Aug-2010 14:01:00 +0001' ), 'epoch 24-Aug-2010 14:01:00 +0001 -> 1282658400' ) ;
}
sub tests_debug {
SKIP: {
skip "No test in normal run" if ( not $tests_debug );
tests_match_a_cache_file( ) ;
tests_cache_map( ) ;
tests_get_cache( ) ;
tests_clean_cache( ) ;
tests_clean_cache_2( ) ;
tests_good_date();
tests_epoch( ) ;
}
}
@ -4172,6 +4359,7 @@ sub tests {
tests_mkpath( ) ;
tests_extract_header( ) ;
tests_decompose_header( ) ;
tests_epoch( ) ;
}
}
@ -4617,7 +4805,7 @@ use constant NonFolderArg => 1; # Value to pass to Massage to
if (! $self->Ignoresizeerrors ) {
if ( length($string) != $expected_size ) {
warn "message_string: " .
print "message_string: " .
"expected $expected_size bytes but received " .
length($string) . "\n";
$self->LastError("message_string: expected ".

View File

@ -5,7 +5,7 @@
<title>Imapsync: an IMAP migration tool ( release <!--#exec cmd="cat VERSION"--> )</title>
<meta name="generator" content="Bluefish 1.0.7"/>
<meta name="author" content="Gilles LAMIRAL"/>
<meta name="date" content="2011-05-16T19:09:12+0200"/>
<meta name="date" content="2011-05-31T18:38:11+0200"/>
<meta name="copyright" content="None"/>
<meta name="keywords" content="imap, transfert, migration"/>
<meta name="description" content="imap migration tool"/>
@ -68,9 +68,17 @@ where the user plays independently on both sides. Use <b>offlineimap</b>
<p>See <b><a href="ChangeLog">ChangeLog</a></b> to know what's new in details since 2001.</p>
<p>New features or bugfixes since previous release 1.411:</p>
<p>New features or bugfixes since previous releases:</p>
<ul>
<li><b>1.446</b></li>
<li><b>Bugfix</b>: Better --idatefromheader behavior (thank to Dax Kelson patches).</li>
<li><b>Usability</b>: Now --delete2 sets --uidexpunge2 instead of --expunge2 if possible.</li>
<li><b>Usability</b>: Adapted the usage output multiline character to Unix or Win, \ or ^</li>
<li><b>Bugfix</b>: Avoid a "not a number" warning when size is null.</li>
<li><b>Bugfix</b>: Added "Date" in the default --useheader list. It is ("Message-Id", "Message-ID", "Date")</li>
<li><b>Bugfix</b>: allows bad header beginning with a blank character.</li>
<li><b>1.434</b></li>
<li><b>Bugfix</b>: Changed the way imapsync knows <b>whether a folder exists</b> or not. <b>Exchange</b> might be happy and <b>stop deconnecting</b> for this reason.</li>
<li><b>Bugfix</b>: <b>Reconnections</b> are well done in <b>TLS mode</b> now.</li>
@ -84,17 +92,6 @@ where the user plays independently on both sides. Use <b>offlineimap</b>
</ul>
</li>
<li><b>1.422</b></li>
<li><b>Better default behavior</b>: Option --delete2 implies --expunge2 now (unless --noexpunge2 is given.)</li>
<li><b>Better default behavior</b>: Correct flags case to be RFC compliant on host2 if host1 is not (\SEEN -> \Seen)</li>
<li><b>Better debug</b>: Added --debugcontent option to avoid debugging content (can be big) with --debug option.</li>
<li><b>Better debug</b>: Added --debugflags to permit flag debugging only.</li>
<li><b>Bugfix</b>: The APPEND error then the FETCH 0 byte error is fixed</li>
<li><b>Bugfix</b>: Options --maxsize --minsize now work with --useuid</li>
<li><b>Bugfix</b>: Flag sync of already transfered messages now take care of --maxsize --minsize options</li>
<li><b>Bugfix</b>: Added 0 length message tracking when fetching host1 (to avoid frequently "APPEND {0}" recent issues).</li>
<li><b>Bugfix</b>: Avoid Inbox vs INBOX case problem ("already exists").</li>
<li><b>Bugfix</b>: --proxyauth2 was setting proxyauth1 instead of proxyauth2</li>
</ul>
<!--
@ -438,7 +435,7 @@ alt="Viewable With Any Browser" />
<!--#config timefmt="%D" -->
<!--#config timefmt="%A %B %d, %Y" -->
<b>This document last modified on <!--#echo var="LAST_MODIFIED" --></b>
($Id: index.shtml,v 1.69 2011/05/16 17:10:13 gilles Exp gilles $)
($Id: index.shtml,v 1.70 2011/05/31 16:43:38 gilles Exp gilles $)
</p>
</body>

View File

@ -1,52 +1,133 @@
Summary: imapsync a tool to migrate across IMAP servers
URL: http://freshmeat.net/projects/imapsync/
Name: imapsync
Version: 1.217
Release: 1
License: GPL
Group: DICE/Utils
Source: http://www.linux-france.org/prj/imapsync/dist/imapsync-1.217.tgz
Source99: filter-requires-imapsync.sh
BuildArch: noarch
BuildRoot: /var/tmp/%{name}-build
Packager: Neil Brown <neilb@inf.ed.ac.uk>
Requires: perl(Mail::IMAPClient), perl(Net::SSLeay), perl(IO::Socket::SSL)
# Working around perl dependency problem, its wrongly matching
# on "use --prefix" in the docs embeded in the code
%define __perl_requires %{SOURCE99}
%description
imapsync is a tool for facilitating incremental recursive IMAP
transfers from one mailbox to another. It is useful for mailbox
migration, and reduces the amount of data transferred by only copying
messages that are not present on both servers. Read, unread, and
deleted flags are preserved, and the process can be stopped and
resumed. The original messages can optionally be deleted after a
successful transfer.
%prep
%setup
%build
%install
make DESTDIR=$RPM_BUILD_ROOT install
%files
%defattr(-,root,root)
%doc ChangeLog README INSTALL FAQ CREDITS TODO GPL
/usr/bin/imapsync
/usr/share/man
%clean
rm -rf $RPM_BUILD_ROOT
%changelog
* Mon Mar 19 2007 Neil Brown <neilb@inf.ed.ac.uk>
- Packaged up source tarball into the RPM. Had to add a fix
- to stop the perl_requires script wrongly matching on "use --prefix"
- in the docs as a genuine perl "use module;"
# The source cannot be distributed:
%{!?nosrc: %define nosrc 1}
# to include the source use:
# rpm -bs --define 'nosrc 0'
%{?!imapsyncver: %define imapsyncver 1.434}
Summary: Tool to migrate across IMAP servers
Name: imapsync
Version: %{imapsyncver}
Release: 1%{?dist}
License: WTFPL
Group: Applications/Internet
URL: http://www.linux-france.org/prj/imapsync/
Source: http://www.linux-france.org/prj/imapsync/dist/imapsync-%{version}.tgz
# The source cannot be distributed:
%if %{nosrc}
NoSource: 0
%endif
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
BuildArch: noarch
BuildRequires: make
BuildRequires: perl(Mail::IMAPClient) >= 3.19
BuildRequires: perl(Test::More)
Requires: perl(Date::Manip)
Requires: perl(Digest::MD5)
Requires: perl(IO::Socket::SSL)
Requires: perl(Mail::IMAPClient) >= 3.19
Requires: perl(Term::ReadKey)
Requires: perl(Digest::HMAC_MD5)
#Requires: perl(Digest::MD5::M4p)
#Requires: perl(Net::SSLeay)
# http://fedoraproject.org/wiki/Packaging:AutoProvidesAndRequiresFiltering
%{?filter_setup:
%filter_from_requires /^perl(--prefix2)/d
%filter_setup
}
%{!?filter_setup:
# filter_setup undefined
%define __perl_requires %{_builddir}/%{buildsubdir}/filter-requires-imapsync.sh
}
%description
imapsync is a tool for facilitating incremental recursive IMAP
transfers from one mailbox to another. It is useful for mailbox
migration, and reduces the amount of data transferred by only copying
messages that are not present on both servers. Read, unread, and
deleted flags are preserved, and the process can be stopped and
resumed. The original messages can optionally be deleted after a
successful transfer.
%prep
%setup -q
%{!?filter_setup:
%{__cat} <<'EOF' >filter-requires-imapsync.sh
#!/bin/sh
/usr/lib/rpm/perl.req $* | sed -e '/perl(--prefix2)/d'
EOF
%{__chmod} a+x filter-requires-imapsync.sh
}
%build
%install
%{__rm} -rf %{buildroot}
%{__make} install DESTDIR="%{buildroot}"
%files
%defattr(-, root, root, 0755)
%doc ChangeLog COPYING CREDITS FAQ INSTALL README TODO
%doc %{_mandir}/man1/imapsync.1*
%{_bindir}/imapsync
%clean
%{__rm} -rf %{buildroot}
%changelog
* Fri Mar 25 2011 Marcin Dulak <Marcin.Dulak@gmail.com> - 1.440-1
- Updated to release 1.440.
- introduced nosrc variable: source must not be distributed
- license is WTFPL: see ChangeLog
- use filter-requires-imapsync.sh when filter_setup undefined
- removed Authority: dag
* Tue Sep 07 2010 Dag Wieers <dag@wieers.com> - 1.350-1
- Updated to release 1.350.
* Wed Jan 13 2010 Steve Huff <shuff@vecna.org> - 1.293-1
- Updated to version 1.293.
* Sun Dec 20 2009 Steve Huff <shuff@vecna.org> - 1.286-2
- Added missing Perl dependencies (reported by John Thomas).
* Thu Sep 10 2009 Dag Wieers <dag@wieers.com> - 1.286-1
- Updated to release 1.286.
* Thu Jul 09 2009 Christoph Maser <cmr@financial.com> - 1.285-1
- Updated to release 1.285.
* Mon Jun 30 2008 Dag Wieers <dag@wieers.com> - 1.255-1
- Updated to release 1.255.
* Fri May 09 2008 Dag Wieers <dag@wieers.com> - 1.252-1
- Updated to release 1.252.
* Sun Apr 27 2008 Dag Wieers <dag@wieers.com> - 1.250-1
- Updated to release 1.250.
* Wed Mar 26 2008 Dag Wieers <dag@wieers.com> - 1.249-1
- Updated to release 1.249.
* Mon Feb 11 2008 Dag Wieers <dag@wieers.com> - 1.241-1
- Updated to release 1.241.
* Thu Nov 22 2007 Dag Wieers <dag@wieers.com> - 1.233-1
- Updated to release 1.233.
* Thu Sep 13 2007 Dag Wieers <dag@wieers.com> - 1.223-1
- Updated to release 1.223.
* Thu Aug 16 2007 Fabian Arrotin <fabian.arrotin@arrfab.net> - 1.219-1
- Update to 1.219.
- Cosmetic changes for Requires: specific to RHEL/CentOS.
* Mon Mar 19 2007 Neil Brown <neilb@inf.ed.ac.uk>
- Packaged up source tarball into the RPM. Had to add a fix
to stop the perl_requires script wrongly matching on "use --prefix"
in the docs as a genuine perl "use module;"

View File

@ -5,7 +5,7 @@
<title>imapsync download</title>
<meta name="generator" content="Bluefish 1.0.7"/>
<meta name="author" content="Gilles LAMIRAL"/>
<meta name="date" content="2011-05-16T19:22:54+0200"/>
<meta name="date" content="2011-05-31T08:34:56+0200"/>
<meta name="copyright" content=""/>
<meta name="keywords" content=""/>
<meta name="description" content=""/>
@ -42,12 +42,9 @@ You may log into your account at <a href="http://www.paypal.com/">www.paypal.com
to view details of this transaction.
</p>
<p>You will find the latest <b>imapsync source code</b> release 1.422 at the following link:<br/>
<a href="http://www.linux-france.org/depot/2011_05_09/EocZFt/">http://www.linux-france.org/depot/2011_05_09/EocZFt/</a>
</p>
<p>You will find the latest <b>imapsync.exe binary</b> release 1.422 at the following link:<br/>
<a href="http://www.linux-france.org/depot/2011_05_09/XhVbYj/">http://www.linux-france.org/depot/2011_05_09/XhVbYj/</a>
<p>You will find the latest <b>imapsync.exe binary</b> release <!--#exec cmd="cat VERSION_EXE" --><br/>
and the latest <b>imapsync source code</b> release <!--#exec cmd="cat VERSION" --> at this
<a href="./dist/<!--#exec cmd="cat dist/path_last.txt" -->/"><b>download page</b></a>.
</p>
<p>You will receive an invoice soon.</p>
@ -55,15 +52,16 @@ to view details of this transaction.
<p>Next imapsync releases will be available for one year without extra payment.<br/>
I will send you a message explaining how to get them</p>
<p>To <b>avoid loosing time</b>, explain your specific needs, find <b>best solutions</b><br/>
and then <b>succeed your migration</b> you can buy professionnal support at the link<br/>
<a href="http://www.linux-france.org/prj/imapsync/#buy_support"><b>http://www.linux-france.org/prj/imapsync/#buy_support</b></a>
<p>To explain your <b>specific needs</b>, find <b>best solutions</b> for them, <b>avoid loosing time</b>, <br/>
and then <b>succeed your migration</b> quickly you can buy
<a href="./#buy_support"><b>professionnal support</b></a>.
</p>
<p><b>I thank you</b> again for buying and using imapsync,<br/>
<b>I wish you successful imap transfers!</b></p>
<p><a href="./">imapsync homepage</a></p>
<p>Back to <a href="./">imapsync homepage</a>.
</p>
<p><b>Gilles LAMIRAL</b><br/>
gilles.lamiral@laposte.net</p>
@ -83,7 +81,7 @@ gilles.lamiral@laposte.net</p>
<!--#config timefmt="%D" -->
<!--#config timefmt="%A %B %d, %Y" -->
<b>This document last modified on <!--#echo var="LAST_MODIFIED" --></b><br/>
($Id: paypal_return.shtml,v 1.7 2011/05/16 17:23:12 gilles Exp gilles $)
($Id: paypal_return.shtml,v 1.9 2011/05/31 08:28:00 gilles Exp gilles $)
</p>
<!-- Google Code for Achat imapsync Conversion Page -->

View File

@ -51,7 +51,7 @@ to view details of this transaction.
<p>Now you can contact me (Gilles LAMIRAL) by email or phone</p>
<ul>
<li>Email address: <b>gilles.lamiral@laposte.net</b>.</li>
<li>Professionnal phone number: <b>+33 9 51 84 42 42</b> (in France) I can <b>call you back</b> for free in many countries.</li>
<li>Professionnal phone number: <b>+33 951 84 42 42</b> (in France) I can <b>call you back</b> for free in many countries.</li>
<li>Mobile phone number: <b>+33 620 79 76 06</b> (in France).</li>
</ul>
@ -78,7 +78,7 @@ gilles.lamiral@laposte.net</p>
<!--#config timefmt="%D" -->
<!--#config timefmt="%A %B %d, %Y" -->
<b>This document last modified on <!--#echo var="LAST_MODIFIED" --></b><br/>
($Id: paypal_return_support.shtml,v 1.2 2011/04/19 13:09:12 gilles Exp gilles $)
($Id: paypal_return_support.shtml,v 1.3 2011/05/20 12:32:25 gilles Exp gilles $)
</p>
<!-- Google Code for Achat imapsync Conversion Page -->

View File

@ -1,5 +1,5 @@
REM $Id: test2.bat,v 1.2 2011/05/16 16:41:47 gilles Exp gilles $
REM $Id: test2.bat,v 1.3 2011/05/30 21:58:08 gilles Exp gilles $
cd C:\msys\1.0\home\Admin\imapsync
REM perl ./imapsync --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi --delete2 --expunge2 --folder INBOX
@ -14,8 +14,9 @@ REM imapsync --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 ti
REM perl imapsync --version
REM perl imapsync --tests_debug
imapsync.exe ^
--host1 p --user1 big1 --passfile1 secret.big1 ^
--host2 p --user2 big2 --passfile2 secret.big2 ^
--folder INBOX.bigmail
REM imapsync.exe ^
REM --host1 p --user1 big1 --passfile1 secret.big1 ^
REM --host2 p --user2 big2 --passfile2 secret.big2 ^
REM --folder INBOX.bigmail
perl imapsync

101
tests.sh
View File

@ -1,6 +1,6 @@
#!/bin/sh
# $Id: tests.sh,v 1.165 2011/05/16 16:41:11 gilles Exp gilles $
# $Id: tests.sh,v 1.168 2011/05/31 16:42:38 gilles Exp gilles $
# Example 1:
# CMD_PERL='perl -I./Mail-IMAPClient-3.25/lib' sh -x tests.sh
@ -297,6 +297,24 @@ ll_few_emails() {
--folder INBOX.few_emails
}
ll_few_emails_dev() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--folder INBOX.few_emails --nofoldersizes
}
ll_size_null() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--folder INBOX.size_null
}
ll_noheader() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
@ -336,9 +354,20 @@ ll_folderrec() {
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--folderrec INBOX.yop
--folderrec INBOX.yop --debugimap --justfolders
}
ll_folderrec_star() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--folderrec 'INBOX.yop.*' --justfolders
}
ll_folderrec_blank_bug() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
@ -712,6 +741,19 @@ ll_maxage()
--maxage 1
}
ll_maxage_nonew()
{
can_send && sendtestmessage
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--maxage 1 --nofoldersizes \
--folder INBOX.few_emails
}
ll_newmessage()
{
can_send && sendtestmessage
@ -1274,9 +1316,7 @@ ll_authmech_CRAMMD5() {
}
ll_delete2() {
if can_send; then
sendtestmessage titi
fi
can_send && sendtestmessage titi
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
@ -1286,6 +1326,55 @@ ll_delete2() {
--delete2 --expunge2
}
ll_delete2_minage() {
can_send && sendtestmessage titi
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--folder INBOX \
--delete2 --expunge2 --minage 1
}
ll_delete2_minage_useuid() {
can_send && sendtestmessage titi
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--folder INBOX \
--delete2 --uidexpunge2 --minage 1 --useuid
}
ll_delete2_uidexpunge2_implicit() {
can_send && sendtestmessage titi
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--folder INBOX \
--delete2 --useuid
}
ll_delete2_dev() {
can_send && sendtestmessage titi
can_send && sendtestmessage
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--folder INBOX --nofoldersizes \
--delete2
}
ll_delete() {
if can_send; then
sendtestmessage titi
@ -1301,7 +1390,7 @@ ll_delete() {
ll_delete_delete2() {
$CMD_PERL ./imapsync \
! $CMD_PERL ./imapsync \
--host1 $HOST1 --user1 titi \
--passfile1 ../../var/pass/secret.titi \
--host2 $HOST2 --user2 tata \