mirror of
https://github.com/imapsync/imapsync.git
synced 2025-06-09 06:04:31 +02:00
1.508
This commit is contained in:
parent
c08a56e486
commit
1e03db551f
58 changed files with 790 additions and 435 deletions
24
ChangeLog
24
ChangeLog
|
@ -1,17 +1,33 @@
|
||||||
|
|
||||||
RCS file: RCS/imapsync,v
|
RCS file: RCS/imapsync,v
|
||||||
Working file: imapsync
|
Working file: imapsync
|
||||||
head: 1.504
|
head: 1.508
|
||||||
branch:
|
branch:
|
||||||
locks: strict
|
locks: strict
|
||||||
gilles: 1.504
|
gilles: 1.508
|
||||||
access list:
|
access list:
|
||||||
symbolic names:
|
symbolic names:
|
||||||
keyword substitution: kv
|
keyword substitution: kv
|
||||||
total revisions: 504; selected revisions: 504
|
total revisions: 508; selected revisions: 508
|
||||||
description:
|
description:
|
||||||
----------------------------
|
----------------------------
|
||||||
revision 1.504 locked by: gilles;
|
revision 1.508 locked by: gilles;
|
||||||
|
date: 2012/09/10 21:10:13; author: gilles; state: Exp; lines: +81 -17
|
||||||
|
Added ETA after each copy. Estimated Time of Arrival.
|
||||||
|
----------------------------
|
||||||
|
revision 1.507
|
||||||
|
date: 2012/09/09 12:57:44; author: gilles; state: Exp; lines: +20 -12
|
||||||
|
Bugfix. Previous fix about characters *|?:"<> in cache path was not complete.
|
||||||
|
----------------------------
|
||||||
|
revision 1.506
|
||||||
|
date: 2012/09/07 14:51:00; author: gilles; state: Exp; lines: +10 -7
|
||||||
|
Option. Added --noexpungeaftereach to speedup --delete --expunge from Gmail.
|
||||||
|
----------------------------
|
||||||
|
revision 1.505
|
||||||
|
date: 2012/09/07 10:40:55; author: gilles; state: Exp; lines: +10 -10
|
||||||
|
Usability. Added Host1 or Host2 before "Nb messages" "Total size" with --foldersiszes
|
||||||
|
----------------------------
|
||||||
|
revision 1.504
|
||||||
date: 2012/08/28 13:10:26; author: gilles; state: Exp; lines: +10 -9
|
date: 2012/08/28 13:10:26; author: gilles; state: Exp; lines: +10 -9
|
||||||
Bugfix. sentsince sentbefore in int seconds.
|
Bugfix. sentsince sentbefore in int seconds.
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
22
FAQ
22
FAQ
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/cat
|
#!/bin/cat
|
||||||
# $Id: FAQ,v 1.114 2012/07/19 09:42:13 gilles Exp gilles $
|
# $Id: FAQ,v 1.116 2012/09/11 21:00:06 gilles Exp gilles $
|
||||||
|
|
||||||
+------------------+
|
+------------------+
|
||||||
| FAQ for imapsync |
|
| FAQ for imapsync |
|
||||||
|
@ -262,13 +262,13 @@ R. - Download latest Mail::IMAPClient 3.xx at
|
||||||
- run imapsync with perl and -I option tailing to use the perl
|
- run imapsync with perl and -I option tailing to use the perl
|
||||||
module Mail-IMAPClient-3.xx. Example:
|
module Mail-IMAPClient-3.xx. Example:
|
||||||
|
|
||||||
perl -I./Mail-IMAPClient-3.31/lib ./imapsync ...
|
perl -I./Mail-IMAPClient-3.32/lib ./imapsync ...
|
||||||
|
|
||||||
or if imapsync is in directory /path/
|
or if imapsync is in directory /path/
|
||||||
perl -I./Mail-IMAPClient-3.31/lib /path/imapsync ...
|
perl -I./Mail-IMAPClient-3.32/lib /path/imapsync ...
|
||||||
|
|
||||||
- Look at the script named i3 in the tarball, it can be used to
|
- Look at the script named i3 in the tarball, it can be used to
|
||||||
run imapsync with included Mail-IMAPClient-3.31/ wherever you
|
run imapsync with included Mail-IMAPClient-3.32/ wherever you
|
||||||
unpacked the imapsync tarball
|
unpacked the imapsync tarball
|
||||||
|
|
||||||
=======================================================================
|
=======================================================================
|
||||||
|
@ -1369,16 +1369,17 @@ R. GroupWise 7 seems buggy. Apply GroupWise 7 support pack 1
|
||||||
=======================================================================
|
=======================================================================
|
||||||
Q. Migrating from David Tobit V10
|
Q. Migrating from David Tobit V10
|
||||||
|
|
||||||
R. Use the following options :
|
R. Use the following options:
|
||||||
imapsync ... --prefix1 "" --sep1 / --idatefromheader ^
|
|
||||||
--nofoldersizes --useuid
|
|
||||||
|
|
||||||
|
imapsync ... --prefix1 "" --sep1 / --idatefromheader ^
|
||||||
=======================================================================
|
--nofoldersizes --useuid --nocheckmessageexists
|
||||||
|
|
||||||
=======================================================================
|
=======================================================================
|
||||||
Q. Migrating from David Tobit V8
|
Q. Migrating from David Tobit V8
|
||||||
|
|
||||||
|
First try above V10 solution since improvments have been made
|
||||||
|
to support Tobit.
|
||||||
|
|
||||||
R. Use the following options :
|
R. Use the following options :
|
||||||
imapsync ... --prefix1 INBOX. --sep1 / --subscribe --subscribed
|
imapsync ... --prefix1 INBOX. --sep1 / --subscribe --subscribed
|
||||||
|
|
||||||
|
@ -1386,6 +1387,9 @@ imapsync ... --prefix1 INBOX. --sep1 / --subscribe --subscribed
|
||||||
Q. Migrating from Tobit David Server 6
|
Q. Migrating from Tobit David Server 6
|
||||||
("DvISE Mail Access Server MA-6.60a (0118)")
|
("DvISE Mail Access Server MA-6.60a (0118)")
|
||||||
|
|
||||||
|
First try above V10 solution since improvments have been made
|
||||||
|
to support Tobit.
|
||||||
|
|
||||||
R. Look at the discussion:
|
R. Look at the discussion:
|
||||||
http://www.linux-france.org/prj/imapsync_list/msg00582.html
|
http://www.linux-france.org/prj/imapsync_list/msg00582.html
|
||||||
http://www.linux-france.org/prj/imapsync_list/threads.html#00582
|
http://www.linux-france.org/prj/imapsync_list/threads.html#00582
|
||||||
|
|
30
INSTALL
30
INSTALL
|
@ -1,4 +1,4 @@
|
||||||
# $Id: INSTALL,v 1.25 2012/07/19 05:57:14 gilles Exp gilles $
|
# $Id: INSTALL,v 1.26 2012/09/11 21:00:06 gilles Exp gilles $
|
||||||
#
|
#
|
||||||
# INSTALL file for imapsync
|
# INSTALL file for imapsync
|
||||||
# imapsync : IMAP sync or copy tool.
|
# imapsync : IMAP sync or copy tool.
|
||||||
|
@ -76,19 +76,20 @@ Here is some individual module help:
|
||||||
perl -mMail::IMAPClient -e 'print $Mail::IMAPClient::VERSION, "\n"'
|
perl -mMail::IMAPClient -e 'print $Mail::IMAPClient::VERSION, "\n"'
|
||||||
|
|
||||||
New Mail-IMAPClient-3.xx works now very well with imapsync,
|
New Mail-IMAPClient-3.xx works now very well with imapsync,
|
||||||
better than Mail-IMAPClient-2.2.9 with memory and other things,
|
better than old Mail-IMAPClient-2.2.9, with memory and other things.
|
||||||
at least with Mail-IMAPClient-3.25 (previous may bug).
|
Use at least Mail-IMAPClient-3.25 (previous may bug).
|
||||||
Don't hesitate to use latest Mail-IMAPClient-3.xx
|
Don't hesitate to use latest Mail-IMAPClient-3.xx (3.xx >= 3.32 at the time
|
||||||
|
of this writing)
|
||||||
|
|
||||||
Look at the script named i3 in the tarball, it can be used to
|
Look at the script named i3 in the tarball, it can be used to
|
||||||
run imapsync with included Mail-IMAPClient-3.31/ wherever you
|
run imapsync with included Mail-IMAPClient-3.32/ wherever you
|
||||||
unpacked the imapsync tarball.
|
unpacked the imapsync tarball.
|
||||||
|
|
||||||
|
|
||||||
- Perl Digest::MD5 module.
|
- Perl Digest::MD5 module.
|
||||||
try:
|
try:
|
||||||
|
|
||||||
perl -mDigest::MD5
|
perl -mDigest::MD5 -e ""
|
||||||
|
|
||||||
http://search.cpan.org/
|
http://search.cpan.org/
|
||||||
http://search.cpan.org/~gaas/Digest-MD5-2.52/
|
http://search.cpan.org/~gaas/Digest-MD5-2.52/
|
||||||
|
@ -97,27 +98,31 @@ Here is some individual module help:
|
||||||
I use 2.39 (Ubuntu package)
|
I use 2.39 (Ubuntu package)
|
||||||
|
|
||||||
- Term::ReadKey
|
- Term::ReadKey
|
||||||
perl -mTerm::ReadKey -e ''
|
perl -mTerm::ReadKey -e ""
|
||||||
|
|
||||||
- IO::Socket::SSL
|
- IO::Socket::SSL
|
||||||
perl -mIO::Socket::SSL -e ''
|
perl -mIO::Socket::SSL -e ""
|
||||||
|
|
||||||
- File::Spec
|
- File::Spec
|
||||||
perl -mFile::Spec -e ''
|
perl -mFile::Spec -e ""
|
||||||
|
|
||||||
- File::Path
|
- File::Path
|
||||||
perl -mFile::Path -e ''
|
perl -mFile::Path -e ""
|
||||||
|
|
||||||
- Perl Digest::HMAC_MD5 module
|
- Perl Digest::HMAC_MD5 module
|
||||||
Good for non plain text password over network.
|
Good for non plain text password over network.
|
||||||
|
perl -mDigest::HMAC_MD5 -e ""
|
||||||
|
|
||||||
- Perl Authen::NTLM
|
- Perl Authen::NTLM
|
||||||
perl -mAuthen::NTLM -e ''
|
perl -mAuthen::NTLM -e ""
|
||||||
|
|
||||||
|
- Perl Time::HiRes
|
||||||
|
perl -mTime::HiRes -e ""
|
||||||
|
|
||||||
Test everything in one command:
|
Test everything in one command:
|
||||||
|
|
||||||
perl -mMail::IMAPClient -mDigest::MD5 -mTerm::ReadKey -mIO::Socket::SSL \
|
perl -mMail::IMAPClient -mDigest::MD5 -mTerm::ReadKey -mIO::Socket::SSL \
|
||||||
-mFile::Spec -mDigest::HMAC_MD5 -mAuthen::NTLM -e ''
|
-mFile::Spec -mDigest::HMAC_MD5 -mAuthen::NTLM -e -mTime::HiRes ''
|
||||||
|
|
||||||
You can install easily those Perl modules in latest release via the
|
You can install easily those Perl modules in latest release via the
|
||||||
following commands (with root permissions)
|
following commands (with root permissions)
|
||||||
|
@ -129,6 +134,7 @@ following commands (with root permissions)
|
||||||
perl -MCPAN -e 'install File::Spec'
|
perl -MCPAN -e 'install File::Spec'
|
||||||
perl -MCPAN -e 'install Digest::HMAC_MD5'
|
perl -MCPAN -e 'install Digest::HMAC_MD5'
|
||||||
perl -MCPAN -e 'install Authen::NTLM'
|
perl -MCPAN -e 'install Authen::NTLM'
|
||||||
|
perl -MCPAN -e 'install Time::HiRes'
|
||||||
|
|
||||||
You can install them easily too by using the standard install
|
You can install them easily too by using the standard install
|
||||||
command on your system if the packages have been made on it
|
command on your system if the packages have been made on it
|
||||||
|
|
25
Makefile
25
Makefile
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
# $Id: Makefile,v 1.103 2012/08/29 10:24:17 gilles Exp gilles $
|
# $Id: Makefile,v 1.107 2012/09/11 21:00:06 gilles Exp gilles $
|
||||||
|
|
||||||
.PHONY: help usage all
|
.PHONY: help usage all
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ VERSION_EXE=$(shell cat ./VERSION_EXE)
|
||||||
|
|
||||||
HELLO=$(shell date;uname -a)
|
HELLO=$(shell date;uname -a)
|
||||||
IMAPClient_2xx=./W/Mail-IMAPClient-2.2.9
|
IMAPClient_2xx=./W/Mail-IMAPClient-2.2.9
|
||||||
IMAPClient_3xx=./W/Mail-IMAPClient-3.31/lib
|
IMAPClient_3xx=./W/Mail-IMAPClient-3.32/lib
|
||||||
IMAPClient=$(IMAPClient_3xx)
|
IMAPClient=$(IMAPClient_3xx)
|
||||||
|
|
||||||
hello:
|
hello:
|
||||||
|
@ -264,20 +264,24 @@ ksa:
|
||||||
rsync -avHz --delete \
|
rsync -avHz --delete \
|
||||||
. imapsync@ks.lamiral.info:public_html/imapsync/
|
. imapsync@ks.lamiral.info:public_html/imapsync/
|
||||||
|
|
||||||
publish: upload_ks ks
|
publish: upload_ks ks ml
|
||||||
|
|
||||||
PUBLIC_FILES = ./ChangeLog ./COPYING ./CREDITS ./FAQ \
|
PUBLIC_FILES = ./ChangeLog ./COPYING ./CREDITS ./FAQ \
|
||||||
./index.shtml ./INSTALL \
|
./index.shtml ./INSTALL \
|
||||||
|
./VERSION ./VERSION_EXE \
|
||||||
./README ./TODO
|
./README ./TODO
|
||||||
|
|
||||||
PUBLIC_FILES_W = ./W/style.css \
|
PUBLIC_FILES_W = ./W/style.css \
|
||||||
./TIME \
|
./W/TIME \
|
||||||
./VERSION ./VERSION_EXE \
|
|
||||||
./W/paypal.shtml ./W/paypal_return.shtml ./W/paypal_return_support.shtml
|
./W/paypal.shtml ./W/paypal_return.shtml ./W/paypal_return_support.shtml
|
||||||
|
|
||||||
|
|
||||||
PUBLIC_FILES_IMAGES = ./W/images/logo_imapsync.png ./W/images/logo_imapsync_s.png
|
PUBLIC_FILES_IMAGES = ./W/images/logo_imapsync.png ./W/images/logo_imapsync_s.png
|
||||||
|
|
||||||
|
ml:
|
||||||
|
m4 -P W/ml_announce.in | mutt -H-
|
||||||
|
mailq
|
||||||
|
|
||||||
|
|
||||||
upload_ks: ci
|
upload_ks: ci
|
||||||
rsync -lptvHzP $(PUBLIC_FILES) \
|
rsync -lptvHzP $(PUBLIC_FILES) \
|
||||||
|
@ -303,13 +307,10 @@ upload_lfo:
|
||||||
/home/gilles/public_html/www.linux-france.org/html/prj/imapsync/.htaccess
|
/home/gilles/public_html/www.linux-france.org/html/prj/imapsync/.htaccess
|
||||||
sh ~/memo/lfo-rsync
|
sh ~/memo/lfo-rsync
|
||||||
|
|
||||||
upload_index: index.shtml FAQ paypal.shtml
|
upload_index: index.shtml FAQ
|
||||||
validate --verbose index.shtml paypal.shtml
|
validate --verbose index.shtml
|
||||||
rcsdiff index.shtml paypal.shtml FAQ COPYING
|
rcsdiff index.shtml FAQ COPYING
|
||||||
rsync -avH index.shtml FAQ paypal.shtml COPYING root@ks.lamiral.info:/var/www/imapsync/
|
rsync -avH index.shtml FAQ COPYING root@ks.lamiral.info:/var/www/imapsync/
|
||||||
rsync -avH index.shtml FAQ paypal.shtml COPYING \
|
|
||||||
../../public_html/www.linux-france.org/html/prj/imapsync/
|
|
||||||
sh $(HOME)/memo/lfo-rsync
|
|
||||||
|
|
||||||
niouze_lfo :
|
niouze_lfo :
|
||||||
echo "CORRECT ME: . ./memo && lfo_announce"
|
echo "CORRECT ME: . ./memo && lfo_announce"
|
||||||
|
|
4
README
4
README
|
@ -3,7 +3,7 @@ NAME
|
||||||
Synchronise mailboxes between two imap servers. Good at IMAP migration.
|
Synchronise mailboxes between two imap servers. Good at IMAP migration.
|
||||||
More than 44 different IMAP server softwares supported with success.
|
More than 44 different IMAP server softwares supported with success.
|
||||||
|
|
||||||
$Revision: 1.504 $
|
$Revision: 1.508 $
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
To synchronise imap account "foo" on "imap.truc.org" to imap account
|
To synchronise imap account "foo" on "imap.truc.org" to imap account
|
||||||
|
@ -440,5 +440,5 @@ SIMILAR SOFTWARES
|
||||||
|
|
||||||
Feedback (good or bad) will often be welcome.
|
Feedback (good or bad) will often be welcome.
|
||||||
|
|
||||||
$Id: imapsync,v 1.504 2012/08/28 13:10:26 gilles Exp gilles $
|
$Id: imapsync,v 1.508 2012/09/10 21:10:13 gilles Exp gilles $
|
||||||
|
|
||||||
|
|
54
TODO
54
TODO
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/cat
|
#!/bin/cat
|
||||||
# $Id: TODO,v 1.112 2012/07/19 09:41:54 gilles Exp gilles $
|
# $Id: TODO,v 1.113 2012/09/11 20:58:32 gilles Exp gilles $
|
||||||
|
|
||||||
TODO file for imapsync
|
TODO file for imapsync
|
||||||
----------------------
|
----------------------
|
||||||
|
@ -31,14 +31,7 @@ Add a FAQ entry about long path over than 260 character on Win32.
|
||||||
|
|
||||||
Fix long path over than 260 character on Win32.
|
Fix long path over than 260 character on Win32.
|
||||||
Think about Digest::SHA or Digest::SHA::PurePerl.
|
Think about Digest::SHA or Digest::SHA::PurePerl.
|
||||||
|
Think about a file database like DBM instead.
|
||||||
Try to use imapsync with cygwin.
|
|
||||||
|
|
||||||
Add an option to solve syncing Sent folder when no good header
|
|
||||||
are available:
|
|
||||||
http://www.linux-france.org/prj/imapsync_list/msg01151.html
|
|
||||||
http://www.linux-france.org/prj/imapsync_list/msg01158.html
|
|
||||||
|
|
||||||
|
|
||||||
Find a way to avoid passwords in --debugimap unless needed.
|
Find a way to avoid passwords in --debugimap unless needed.
|
||||||
|
|
||||||
|
@ -101,19 +94,6 @@ Fix bug "not possible to use space in the imap password"
|
||||||
|
|
||||||
Add kerberos authentification
|
Add kerberos authentification
|
||||||
|
|
||||||
Add a --skipheaderinfolder option
|
|
||||||
|
|
||||||
Fix this:
|
|
||||||
> - Erreur avec la traditionnelle différence entre Windows
|
|
||||||
> et Linux sur les retour-chariots : le calcul de la
|
|
||||||
> longueur du message ou des entêtes à envoyer au serveur
|
|
||||||
> cible n'est pas bon sur une machine Windows.
|
|
||||||
> Ci-dessous la modif :
|
|
||||||
>
|
|
||||||
> # No NL Count on Windows my $length = ( -s $file ) + $bare_nl_count;
|
|
||||||
> my $length = ( -s $file );
|
|
||||||
I wonder if it is Windows or the imap server used.
|
|
||||||
|
|
||||||
|
|
||||||
Add stdin/stdout filter before transfer:
|
Add stdin/stdout filter before transfer:
|
||||||
"Now i asked me, how to modify your perl program to work with
|
"Now i asked me, how to modify your perl program to work with
|
||||||
|
@ -152,9 +132,6 @@ Add --verbose from Kjetil jumbo patch.
|
||||||
|
|
||||||
Read the IMAP RFC http://www.faqs.org/rfcs/rfc3501.html
|
Read the IMAP RFC http://www.faqs.org/rfcs/rfc3501.html
|
||||||
|
|
||||||
Add debian packaging in the Makefile.
|
|
||||||
Write to the debian maintener about that.
|
|
||||||
|
|
||||||
Interface with external software like procmail
|
Interface with external software like procmail
|
||||||
|
|
||||||
Read:
|
Read:
|
||||||
|
@ -165,6 +142,33 @@ http://asg.web.cmu.edu/cyrus/download/imapd/altnamespace.html
|
||||||
|
|
||||||
===========================================================================
|
===========================================================================
|
||||||
|
|
||||||
|
|
||||||
|
DONE. Not donse since useless now (--useuid)
|
||||||
|
Add a --skipheaderinfolder option
|
||||||
|
|
||||||
|
DONE. Not fixed since only reported once a long time ago.
|
||||||
|
Fix this:
|
||||||
|
> - Erreur avec la traditionnelle différence entre Windows
|
||||||
|
> et Linux sur les retour-chariots : le calcul de la
|
||||||
|
> longueur du message ou des entêtes à envoyer au serveur
|
||||||
|
> cible n'est pas bon sur une machine Windows.
|
||||||
|
> Ci-dessous la modif :
|
||||||
|
>
|
||||||
|
> # No NL Count on Windows my $length = ( -s $file ) + $bare_nl_count;
|
||||||
|
> my $length = ( -s $file );
|
||||||
|
I wonder if it is Windows or the imap server used.
|
||||||
|
|
||||||
|
|
||||||
|
DONE. No Debian package anymore.
|
||||||
|
Add debian packaging in the Makefile.
|
||||||
|
Write to the debian maintener about that.
|
||||||
|
|
||||||
|
DONE with --addheader
|
||||||
|
Add an option to solve syncing Sent folder when no good header
|
||||||
|
are available:
|
||||||
|
http://www.linux-france.org/prj/imapsync_list/msg01151.html
|
||||||
|
http://www.linux-france.org/prj/imapsync_list/msg01158.html
|
||||||
|
|
||||||
DONE. Add a note about
|
DONE. Add a note about
|
||||||
"One other thing: You might want to warn idiots like me, that if your
|
"One other thing: You might want to warn idiots like me, that if your
|
||||||
cache resides on a filesystem with a limited number of inodes such as
|
cache resides on a filesystem with a limited number of inodes such as
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
1.504
|
1.508
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
1.504
|
1.508
|
||||||
|
|
|
@ -152,3 +152,7 @@
|
||||||
1346160945 END 1.504 : mardi 28 août 2012, 15:35:45 (UTC+0200)
|
1346160945 END 1.504 : mardi 28 août 2012, 15:35:45 (UTC+0200)
|
||||||
1346241775 BEGIN 1.504 : mercredi 29 août 2012, 14:02:55 (UTC+0200)
|
1346241775 BEGIN 1.504 : mercredi 29 août 2012, 14:02:55 (UTC+0200)
|
||||||
1346242932 END 1.504 : mercredi 29 août 2012, 14:22:12 (UTC+0200)
|
1346242932 END 1.504 : mercredi 29 août 2012, 14:22:12 (UTC+0200)
|
||||||
|
1347195553 BEGIN 1.507 : dimanche 9 septembre 2012, 14:59:13 (UTC+0200)
|
||||||
|
1347196697 END 1.507 : dimanche 9 septembre 2012, 15:18:17 (UTC+0200)
|
||||||
|
1347392501 BEGIN 1.508 : mardi 11 septembre 2012, 21:41:41 (UTC+0200)
|
||||||
|
1347393591 END 1.508 : mardi 11 septembre 2012, 21:59:51 (UTC+0200)
|
||||||
|
|
|
@ -5,6 +5,27 @@ Changes from 2.99_01 to 3.16 made by Mark Overmeer
|
||||||
Changes from 0.09 to 2.99_01 made by David Kernen
|
Changes from 0.09 to 2.99_01 made by David Kernen
|
||||||
- Potential compatibility issues from 3.17+ highlighted with '*'
|
- Potential compatibility issues from 3.17+ highlighted with '*'
|
||||||
|
|
||||||
|
version 3.32: Fri, Aug 10, 2012 4:43:24 PM
|
||||||
|
- document RFC2087 quota related calls
|
||||||
|
[Mathias Reitinger] documentation request
|
||||||
|
- rt.cpan.org#78474: idle/idle_data documentation error
|
||||||
|
[Dima Kogan]
|
||||||
|
- Quote()/Massage() now uses literals for non ascii data
|
||||||
|
[Mathias Reitinger] reported issues with utf8 data in password
|
||||||
|
- use Quote()/Massage() consistently now in:
|
||||||
|
login() proxyauth() deleteacl() setacl() listrights() rename()
|
||||||
|
- documented deleteacl() and other minor pod cleanup
|
||||||
|
- ran Mail::IMAPClient::BodyStructure through perltidy
|
||||||
|
- update year in README/pod to 2012
|
||||||
|
- rt.cpan.org#74733: Fails with Parse::RecDescent >= 1.966_002
|
||||||
|
rt.cpan.org#74593: Recent changes break Module::ExtractUse and ...
|
||||||
|
[ANDK, TEAM, SREZIC, NBEBOUT at CPAN and nine from detonation]
|
||||||
|
- Makefile.PL avoid buggy Parse::RecDescent 1.966_002 until 1.967_009
|
||||||
|
- rt.cpan.org#76989: Mail::IMAPClient::BodyStructure usage/docs
|
||||||
|
[Pierluigi Frullani]
|
||||||
|
- fix incorrect documentation on new()
|
||||||
|
- lots of doc verbiage updates
|
||||||
|
|
||||||
version 3.31: Mon, Mar 19, 2012 11:11:11 AM
|
version 3.31: Mon, Mar 19, 2012 11:11:11 AM
|
||||||
- rt.cpan.org#74799: Support for partial data responses in fetch_hash
|
- rt.cpan.org#74799: Support for partial data responses in fetch_hash
|
||||||
[Philip Garrett]
|
[Philip Garrett]
|
|
@ -1,6 +1,6 @@
|
||||||
--- #YAML:1.0
|
--- #YAML:1.0
|
||||||
name: Mail-IMAPClient
|
name: Mail-IMAPClient
|
||||||
version: 3.31
|
version: 3.32
|
||||||
abstract: IMAP4 client library
|
abstract: IMAP4 client library
|
||||||
author:
|
author:
|
||||||
- Phil Pearl (Lobbes) <phil@zimbra.com>
|
- Phil Pearl (Lobbes) <phil@zimbra.com>
|
||||||
|
@ -28,7 +28,7 @@ no_index:
|
||||||
directory:
|
directory:
|
||||||
- t
|
- t
|
||||||
- inc
|
- inc
|
||||||
generated_by: ExtUtils::MakeMaker version 6.55_02
|
generated_by: ExtUtils::MakeMaker version 6.57_05
|
||||||
meta-spec:
|
meta-spec:
|
||||||
url: http://module-build.sourceforge.net/META-spec-v1.4.html
|
url: http://module-build.sourceforge.net/META-spec-v1.4.html
|
||||||
version: 1.4
|
version: 1.4
|
|
@ -37,6 +37,22 @@ MSG
|
||||||
sleep 3;
|
sleep 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# HACK: die on broken Parse::RecDescent 1.966002 through 1.967009
|
||||||
|
# - rt.cpan.org#74593: Recent changes break Module::ExtractUse and ...
|
||||||
|
# - rt.cpan.org#74733: Fails with Parse::RecDescent >= 1.966_002
|
||||||
|
do {
|
||||||
|
eval { require version; require Parse::RecDescent; };
|
||||||
|
unless ($@) {
|
||||||
|
my $found = version->parse( Parse::RecDescent->VERSION() );
|
||||||
|
my $broke = version->parse("1.966002");
|
||||||
|
my $fixed = version->parse("1.967009");
|
||||||
|
if ( $found < $fixed and $found >= $broke ) {
|
||||||
|
die("Found broken Parse::RecDescent $found in your environment.\n",
|
||||||
|
"Please upgrade to version $fixed or greater.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
WriteMakefile(
|
WriteMakefile(
|
||||||
NAME => 'Mail::IMAPClient',
|
NAME => 'Mail::IMAPClient',
|
||||||
AUTHOR => 'Phil Pearl (Lobbes) <phil@zimbra.com>',
|
AUTHOR => 'Phil Pearl (Lobbes) <phil@zimbra.com>',
|
|
@ -64,7 +64,7 @@ COPYRIGHT AND LICENSE
|
||||||
=====================
|
=====================
|
||||||
Copyright (C) 1999-2003 The Kernen Group, Inc.
|
Copyright (C) 1999-2003 The Kernen Group, Inc.
|
||||||
Copyright (C) 2007-2009 Mark Overmeer
|
Copyright (C) 2007-2009 Mark Overmeer
|
||||||
Copyright (C) 2010-2011 Phil Pearl (Lobbes)
|
Copyright (C) 2010-2012 Phil Pearl (Lobbes)
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or modify
|
This library is free software; you can redistribute it and/or modify
|
|
@ -7,7 +7,7 @@ use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
package Mail::IMAPClient;
|
package Mail::IMAPClient;
|
||||||
our $VERSION = '3.31';
|
our $VERSION = '3.32';
|
||||||
|
|
||||||
use Mail::IMAPClient::MessageSet;
|
use Mail::IMAPClient::MessageSet;
|
||||||
|
|
||||||
|
@ -546,20 +546,15 @@ sub login {
|
||||||
or return undef;
|
or return undef;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
my $user = $self->User;
|
||||||
my $passwd = $self->Password;
|
my $passwd = $self->Password;
|
||||||
my $id = $self->User;
|
|
||||||
|
|
||||||
return undef unless ( defined($passwd) and defined($id) );
|
return undef unless ( defined($passwd) and defined($user) );
|
||||||
|
|
||||||
# BUG: should use Quote() with $passwd and $id
|
$user = ( $user eq "" ) ? qq("") : $self->Quote($user);
|
||||||
if ( $passwd eq "" or $passwd =~ m/\W/ ) {
|
$passwd = ( $passwd eq "" ) ? qq("") : $self->Quote($passwd);
|
||||||
$passwd =~ s/(["\\])/\\$1/g;
|
|
||||||
$passwd = qq("$passwd");
|
|
||||||
}
|
|
||||||
|
|
||||||
$id = qq("$id") if $id !~ /^".*"$/;
|
$self->_imap_command("LOGIN $user $passwd")
|
||||||
|
|
||||||
$self->_imap_command("LOGIN $id $passwd")
|
|
||||||
or return undef;
|
or return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,6 +572,7 @@ sub noop {
|
||||||
|
|
||||||
sub proxyauth {
|
sub proxyauth {
|
||||||
my ( $self, $user ) = @_;
|
my ( $self, $user ) = @_;
|
||||||
|
$user = ( $user eq "" ) ? qq("") : $self->Quote($user);
|
||||||
$self->_imap_command("PROXYAUTH $user") ? $self->Results : undef;
|
$self->_imap_command("PROXYAUTH $user") ? $self->Results : undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,33 +737,27 @@ sub subscribed {
|
||||||
return wantarray ? @folders : \@folders;
|
return wantarray ? @folders : \@folders;
|
||||||
}
|
}
|
||||||
|
|
||||||
# BUG? cleanup escaping/quoting
|
|
||||||
sub deleteacl {
|
sub deleteacl {
|
||||||
my ( $self, $target, $user ) = @_;
|
my ( $self, $target, $user ) = @_;
|
||||||
$target = $self->Massage($target);
|
$target = $self->Massage($target);
|
||||||
$user =~ s/^"(.*)"$/$1/;
|
$user = ( $user eq "" ) ? qq("") : $self->Quote($user);
|
||||||
$user =~ s/"/\\"/g;
|
|
||||||
|
|
||||||
$self->_imap_command(qq(DELETEACL $target "$user"))
|
$self->_imap_command(qq(DELETEACL $target $user))
|
||||||
or return undef;
|
or return undef;
|
||||||
|
|
||||||
return wantarray ? $self->History : $self->Results;
|
return wantarray ? $self->History : $self->Results;
|
||||||
}
|
}
|
||||||
|
|
||||||
# BUG? cleanup escaping/quoting
|
|
||||||
sub setacl {
|
sub setacl {
|
||||||
my ( $self, $target, $user, $acl ) = @_;
|
my ( $self, $target, $user, $acl ) = @_;
|
||||||
$target ||= $self->Folder;
|
$target ||= $self->Folder;
|
||||||
$target = $self->Massage($target);
|
$target = $self->Massage($target);
|
||||||
|
|
||||||
$user ||= $self->User;
|
$user ||= $self->User;
|
||||||
$user =~ s/^"(.*)"$/$1/;
|
$user = ( $user eq "" ) ? qq("") : $self->Quote($user);
|
||||||
$user =~ s/"/\\"/g;
|
$acl = ( $acl eq "" ) ? qq("") : $self->Quote($acl);
|
||||||
|
|
||||||
$acl =~ s/^"(.*)"$/$1/;
|
$self->_imap_command(qq(SETACL $target $user $acl))
|
||||||
$acl =~ s/"/\\"/g;
|
|
||||||
|
|
||||||
$self->_imap_command(qq(SETACL $target "$user" "$acl"))
|
|
||||||
or return undef;
|
or return undef;
|
||||||
|
|
||||||
return wantarray ? $self->History : $self->Results;
|
return wantarray ? $self->History : $self->Results;
|
||||||
|
@ -809,10 +799,9 @@ sub listrights {
|
||||||
$target = $self->Massage($target);
|
$target = $self->Massage($target);
|
||||||
|
|
||||||
$user ||= $self->User;
|
$user ||= $self->User;
|
||||||
$user =~ s/^"(.*)"$/$1/;
|
$user = ( $user eq "" ) ? qq("") : $self->Quote($user);
|
||||||
$user =~ s/"/\\"/g;
|
|
||||||
|
|
||||||
$self->_imap_command(qq(LISTRIGHTS $target "$user"))
|
$self->_imap_command(qq(LISTRIGHTS $target $user))
|
||||||
or return undef;
|
or return undef;
|
||||||
|
|
||||||
my $resp = first { /^\* LISTRIGHTS/ } $self->History;
|
my $resp = first { /^\* LISTRIGHTS/ } $self->History;
|
||||||
|
@ -2352,21 +2341,13 @@ sub uidexpunge {
|
||||||
return wantarray ? $self->History : $self->Results;
|
return wantarray ? $self->History : $self->Results;
|
||||||
}
|
}
|
||||||
|
|
||||||
# BUG? cleanup escaping/quoting
|
|
||||||
sub rename {
|
sub rename {
|
||||||
my ( $self, $from, $to ) = @_;
|
my ( $self, $from, $to ) = @_;
|
||||||
|
|
||||||
if ( $from =~ /^"(.*)"$/ ) {
|
$from = ( $from eq "" ) ? qq("") : $self->Massage($from);
|
||||||
$from = $1 unless $self->exists($from);
|
$to = ( $to eq "" ) ? qq("") : $self->Massage($to);
|
||||||
$from =~ s/"/\\"/g;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $to =~ /^"(.*)"$/ ) {
|
$self->_imap_command(qq(RENAME $from $to)) ? $self : undef;
|
||||||
$to = $1 unless $self->exists($from) && $from =~ /^".*"$/;
|
|
||||||
$to =~ s/"/\\"/g;
|
|
||||||
}
|
|
||||||
|
|
||||||
$self->_imap_command(qq(RENAME "$from" "$to")) ? $self : undef;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub status {
|
sub status {
|
||||||
|
@ -3352,37 +3333,38 @@ sub getquotaroot {
|
||||||
return $self->_imap_command("GETQUOTAROOT $who") ? $self->Results : undef;
|
return $self->_imap_command("GETQUOTAROOT $who") ? $self->Results : undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# BUG? using user/$User here and INBOX in quota/quota_usage
|
||||||
sub getquota {
|
sub getquota {
|
||||||
my ( $self, $what ) = @_;
|
my ( $self, $what ) = @_;
|
||||||
my $who = $what ? $self->Massage($what) : "user/$self->{User}";
|
my $who = $what ? $self->Massage($what) : "user/" . $self->User;
|
||||||
return $self->_imap_command("GETQUOTA $who") ? $self->Results : undef;
|
return $self->_imap_command("GETQUOTA $who") ? $self->Results : undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
# usage: $self->setquota($folder, storage => 512)
|
# usage: $self->setquota($quotaroot, storage => 512, ...)
|
||||||
sub setquota(@) {
|
sub setquota(@) {
|
||||||
my ( $self, $what ) = ( shift, shift );
|
my ( $self, $what ) = ( shift, shift );
|
||||||
my $who = $what ? $self->Massage($what) : "user/$self->{User}";
|
my $who = $what ? $self->Massage($what) : "user/" . $self->User;
|
||||||
my @limits;
|
my @limits;
|
||||||
while (@_) {
|
while (@_) {
|
||||||
my $key = uc shift @_;
|
my ( $k, $v ) = ( $self->Quote( uc( shift @_ ) ), shift @_ );
|
||||||
push @limits, $key => shift @_;
|
push( @limits, "($k $v)" );
|
||||||
}
|
}
|
||||||
local $" = ' ';
|
my $limits = join( ' ', @limits );
|
||||||
$self->_imap_command("SETQUOTA $who (@limits)") ? $self->Results : undef;
|
$self->_imap_command("SETQUOTA $who $limits") ? $self->Results : undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub quota {
|
sub quota {
|
||||||
my $self = shift;
|
my ( $self, $what ) = ( shift, shift || "INBOX" );
|
||||||
my $what = shift || "INBOX";
|
my $tref = $self->getquota($what) or return undef;
|
||||||
$self->_imap_command("GETQUOTA $what") or $self->getquotaroot($what);
|
shift @$tref; # pop off command
|
||||||
( map { /.*STORAGE\s+\d+\s+(\d+).*\n$/ ? $1 : () } $self->Results )[0];
|
return ( map { /.*STORAGE\s+\d+\s+(\d+).*\n$/ ? $1 : () } @$tref )[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
sub quota_usage {
|
sub quota_usage {
|
||||||
my $self = shift;
|
my ( $self, $what ) = ( shift, shift || "INBOX" );
|
||||||
my $what = shift || "INBOX";
|
my $tref = $self->getquota($what) or return undef;
|
||||||
$self->_imap_command("GETQUOTA $what") || $self->getquotaroot($what);
|
shift @$tref; # pop off command
|
||||||
( map { /.*STORAGE\s+(\d+)\s+\d+.*\n$/ ? $1 : () } $self->Results )[0];
|
return ( map { /.*STORAGE\s+(\d+)\s+\d+.*\n$/ ? $1 : () } @$tref )[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Quote($) { $_[0]->Massage( $_[1], NonFolderArg ) }
|
sub Quote($) { $_[0]->Massage( $_[1], NonFolderArg ) }
|
||||||
|
@ -3395,15 +3377,16 @@ sub Quote($) { $_[0]->Massage( $_[1], NonFolderArg ) }
|
||||||
# resp-specials = "]"
|
# resp-specials = "]"
|
||||||
# rfc2060:
|
# rfc2060:
|
||||||
# CTL ::= <any ASCII control character and DEL, 0x00 - 0x1f, 0x7f>
|
# CTL ::= <any ASCII control character and DEL, 0x00 - 0x1f, 0x7f>
|
||||||
# Additionally, we encode strings with } and [, be less than minimal
|
# Paranoia/safety:
|
||||||
|
# encode strings with "}" / "[" / "]" / non-ascii chars
|
||||||
sub Massage($;$) {
|
sub Massage($;$) {
|
||||||
my ( $self, $name, $notFolder ) = @_;
|
my ( $self, $name, $notFolder ) = @_;
|
||||||
$name =~ s/^\"(.*)\"$/$1/ unless $notFolder;
|
$name =~ s/^\"(.*)\"$/$1/s unless $notFolder;
|
||||||
|
|
||||||
if ( $name =~ /["\\]/ ) {
|
if ( $name =~ /["\\[:^ascii:][:cntrl:]]/s ) {
|
||||||
return "{" . length($name) . "}" . $CRLF . $name;
|
return "{" . length($name) . "}" . $CRLF . $name;
|
||||||
}
|
}
|
||||||
elsif ( $name =~ /[(){}\s[:cntrl:]%*\[\]]/ ) {
|
elsif ( $name =~ /[(){}\s%*\[\]]/s ) {
|
||||||
return qq("$name");
|
return qq("$name");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
|
@ -230,7 +230,7 @@ Example:
|
||||||
The B<Quote> method accepts a value as an argument and returns its
|
The B<Quote> method accepts a value as an argument and returns its
|
||||||
argument as a correctly quoted string or a literal string. Since
|
argument as a correctly quoted string or a literal string. Since
|
||||||
version 3.17 Mail::IMAPClient automatically quotes search arguments we
|
version 3.17 Mail::IMAPClient automatically quotes search arguments we
|
||||||
use a SCALARREF so search will not modify or re-quite the valaue
|
use a SCALARREF so search will not modify or re-quote the value
|
||||||
returned by B<Quote>.
|
returned by B<Quote>.
|
||||||
|
|
||||||
Note this method should not be used on folder names for
|
Note this method should not be used on folder names for
|
||||||
|
@ -783,6 +783,18 @@ The B<delete> method accepts a single argument, the name of a folder
|
||||||
to delete. It returns a true value on success and C<undef> on
|
to delete. It returns a true value on success and C<undef> on
|
||||||
failure.
|
failure.
|
||||||
|
|
||||||
|
=head2 deleteacl
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
$imap->deleteacl( $folder, $userid )
|
||||||
|
or die "Could not delete acl: $@\n";
|
||||||
|
|
||||||
|
The B<deleteacl> method accepts two input arguments, a folder name, a
|
||||||
|
user id (or authentication identifier, to use the terminology of
|
||||||
|
RFC2086). See RFC2086 for more information. (This is somewhat
|
||||||
|
experimental and its implementation may change.)
|
||||||
|
|
||||||
=head2 delete_message
|
=head2 delete_message
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
@ -945,7 +957,7 @@ server will likely respond with an error like I<* BAD Invalid tag>.
|
||||||
|
|
||||||
On failure <undef> is returned and L</LastError> is set.
|
On failure <undef> is returned and L</LastError> is set.
|
||||||
|
|
||||||
See also L</idle>, L</imap_data> and L</Results>.
|
See also L</idle>, L</idle_data> and L</Results>.
|
||||||
|
|
||||||
=head2 examine
|
=head2 examine
|
||||||
|
|
||||||
|
@ -1277,10 +1289,15 @@ has been terminated by calling L</done>. Failure to do so will result
|
||||||
in an error and the idle command will typically be terminated by the
|
in an error and the idle command will typically be terminated by the
|
||||||
server.
|
server.
|
||||||
|
|
||||||
See also L</imap_data> and L</done>.
|
See also L</idle_data> and L</done>.
|
||||||
|
|
||||||
=head2 idle_data
|
=head2 idle_data
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
# an optional timeout in seconds may be specified
|
||||||
|
$imap->idle_data( [$timeout] )
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
my $tag = $imap->idle or warn "idle failed: $@\n";
|
my $tag = $imap->idle or warn "idle failed: $@\n";
|
||||||
|
@ -1292,12 +1309,12 @@ Example:
|
||||||
The B<idle_data> method can be used to accept any unsolicited mailbox
|
The B<idle_data> method can be used to accept any unsolicited mailbox
|
||||||
update messages that have been sent by the server during an L</idle>
|
update messages that have been sent by the server during an L</idle>
|
||||||
command. This method does not send any commands to the server, it
|
command. This method does not send any commands to the server, it
|
||||||
simply waits for data from the server and returns that data to the
|
simply looks for and optionally waits for data from the server and
|
||||||
caller.
|
returns that data to the caller.
|
||||||
|
|
||||||
The B<idle> method accepts an optional $timeout argument and returns
|
The B<idle_data> method accepts an optional $timeout argument and
|
||||||
an array (or an array reference if called in scalar context) with the
|
returns an array (or an array reference if called in scalar context)
|
||||||
messages from the server.
|
with the messages from the server.
|
||||||
|
|
||||||
By default a timeout of 0 seconds is used (do not block). Internally
|
By default a timeout of 0 seconds is used (do not block). Internally
|
||||||
the timeout is passed to L<perlfunc/select>. The timeout controls how
|
the timeout is passed to L<perlfunc/select>. The timeout controls how
|
||||||
|
@ -1399,6 +1416,87 @@ The B<get_header> method is a short-cut for:
|
||||||
|
|
||||||
my $messageId = $imap->parse_headers($msg,"Subject")->{"Subject"}[0];
|
my $messageId = $imap->parse_headers($msg,"Subject")->{"Subject"}[0];
|
||||||
|
|
||||||
|
=head2 getquotaroot
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
my $results = $imap->getquotaroot($mailboxname)
|
||||||
|
or die "Could not getquotaroot for $mailboxname: $@\n";
|
||||||
|
|
||||||
|
The B<getquotaroot> method implements the RFC2087 GETQUOTAROOT
|
||||||
|
command. The "$mailboxname" defaults to "INBOX" if no argument is
|
||||||
|
provided.
|
||||||
|
|
||||||
|
On error C<undef> is returned, otherwise L</Results> are returned.
|
||||||
|
The results should have the untagged QUOTAROOT response from the
|
||||||
|
server along with the QUOTAROOT's resource usage and limits in an
|
||||||
|
untagged QUOTA response.
|
||||||
|
|
||||||
|
See also B<RFC2087>, L</getquota>, L</setquota>, L</quota> and L</quota_usage>.
|
||||||
|
|
||||||
|
=head2 getquota
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
my $results = $imap->getquota($quotaroot)
|
||||||
|
or die "Could not getquota for $quotaroot: $@\n";
|
||||||
|
|
||||||
|
The B<getquota> method implements the RFC2087 GETQUOTA command. The
|
||||||
|
"$quotaroot" defaults to "user/I<User>" if no argument is provided.
|
||||||
|
|
||||||
|
On error C<undef> is returned, otherwise L</Results> are returned.
|
||||||
|
The results from the server should have the untagged QUOTA response
|
||||||
|
from the server.
|
||||||
|
|
||||||
|
See also B<RFC2087>, L</getquotaroot>, L</quota> and L</quota_usage>.
|
||||||
|
|
||||||
|
=head2 quota
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
my $limit = $imap->quota($quotaroot)
|
||||||
|
or die "Could not get quota limit for $quotaroot: $@\n";
|
||||||
|
|
||||||
|
The B<quota> method takes the L</Results> from L<getquota> and parses
|
||||||
|
out the "STORAGE" limit returned by the server. The "$quotaroot"
|
||||||
|
defaults to "INBOX" if no argument is provided.
|
||||||
|
|
||||||
|
On error C<undef> is returned, otherwise the integer "STORAGE" limit
|
||||||
|
provided by the server is returned.
|
||||||
|
|
||||||
|
See also B<RFC2087>, L</getquotaroot>, L</getquota> and L</quota_usage>.
|
||||||
|
|
||||||
|
=head2 quota_usage
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
my $usage = $imap->quota_usage($quotaroot)
|
||||||
|
or die "Could not get quota usage for $quotaroot: $@\n";
|
||||||
|
|
||||||
|
The B<quota_usage> method takes the L</Results> from L<getquota> and
|
||||||
|
parses out the "STORAGE" usage returned by the server. The
|
||||||
|
"$quotaroot" defaults to "INBOX" if no argument is provided.
|
||||||
|
|
||||||
|
On error C<undef> is returned, otherwise the integer "STORAGE" usage
|
||||||
|
provided by the server is returned.
|
||||||
|
|
||||||
|
See also B<RFC2087>, L</getquotaroot>, L</getquota> and L</quota>.
|
||||||
|
|
||||||
|
=head2 setquota
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
my $results = $imap->setquota( $quotaroot, $resource, $limit )
|
||||||
|
or die "Could not setquota for $quotaroot: $@\n";
|
||||||
|
|
||||||
|
The B<setquota> method implements the RFC2087 SETQUOTA command. It
|
||||||
|
accepts multiple pairs of $resource and $limit arguments. The
|
||||||
|
"$quotaroot" defaults to "user/I<User>" if not defined.
|
||||||
|
|
||||||
|
On error C<undef> is returned, otherwise L</Results> are returned.
|
||||||
|
|
||||||
|
See also B<RFC2087>, L</getquotaroot> and L</getquota>.
|
||||||
|
|
||||||
=head2 is_parent
|
=head2 is_parent
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
@ -1477,7 +1575,8 @@ and $@ is set. The methods L</new>, L</connect>, and L</Socket> may
|
||||||
automatically invoke B<login> see the documentation of each method for
|
automatically invoke B<login> see the documentation of each method for
|
||||||
details.
|
details.
|
||||||
|
|
||||||
If the L</Compress> parameter is set, the L</compress> method will automatically be called after successful authentication.
|
If the L</Compress> parameter is set, the L</compress> method will
|
||||||
|
automatically be called after successful authentication.
|
||||||
|
|
||||||
See also L</proxyauth> and L</Proxy> for additional information
|
See also L</proxyauth> and L</Proxy> for additional information
|
||||||
regarding ways of authenticating with a server via SASL and/or
|
regarding ways of authenticating with a server via SASL and/or
|
||||||
|
@ -2275,7 +2374,7 @@ contain both subfolders and mail messages; other servers allow this.)
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
$imap->set_flag("Seen",@msgs)
|
$imap->set_flag( "Seen", @msgs )
|
||||||
or die "Could not set flag: $@\n";
|
or die "Could not set flag: $@\n";
|
||||||
|
|
||||||
The B<set_flag> method accepts the name of a flag as its first
|
The B<set_flag> method accepts the name of a flag as its first
|
||||||
|
@ -2298,7 +2397,7 @@ which is why you don't have to worry about it overly much.)
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
$imap->setacl($folder,$userid,$authstring)
|
$imap->setacl( $folder, $userid, $aclstring )
|
||||||
or die "Could not set acl: $@\n";
|
or die "Could not set acl: $@\n";
|
||||||
|
|
||||||
The B<setacl> method accepts three input arguments, a folder name, a
|
The B<setacl> method accepts three input arguments, a folder name, a
|
||||||
|
@ -2429,7 +2528,7 @@ Version note: method added in Mail::IMAPClient 3.22
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
my @rawdata = $imap->status($folder,qw/(Messages)/)
|
my @rawdata = $imap->status( $folder, qw/(Messages)/ )
|
||||||
or die "Error obtaining status: $@\n";
|
or die "Error obtaining status: $@\n";
|
||||||
|
|
||||||
The B<status> method accepts one argument, the name of a folder (or
|
The B<status> method accepts one argument, the name of a folder (or
|
||||||
|
@ -2646,7 +2745,7 @@ messages in the currently selected Folder.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
$imap->unset_flag("\Seen",@msgs)
|
$imap->unset_flag( "\Seen", @msgs )
|
||||||
or die "Could not unset_flag: $@\n";
|
or die "Could not unset_flag: $@\n";
|
||||||
|
|
||||||
The B<unset_flag> method accepts the name of a flag as its first
|
The B<unset_flag> method accepts the name of a flag as its first
|
||||||
|
@ -3740,7 +3839,7 @@ exchange. After the L</authenticate> method sends "<tag> AUTHENTICATE
|
||||||
challenge. The L</authenticate> method then invokes the code whose
|
challenge. The L</authenticate> method then invokes the code whose
|
||||||
reference is stored in the B<Authcallback> parameter as follows:
|
reference is stored in the B<Authcallback> parameter as follows:
|
||||||
|
|
||||||
$Authcallback->($challenge, $imap)
|
$Authcallback->( $challenge, $imap )
|
||||||
|
|
||||||
where C<$Authcallback> is the code reference stored in the
|
where C<$Authcallback> is the code reference stored in the
|
||||||
B<Authcallback> parameter, C<$challenge> is the challenge received
|
B<Authcallback> parameter, C<$challenge> is the challenge received
|
||||||
|
@ -3771,7 +3870,7 @@ http://rt.cpan.org/Public/Dist/Display.html?Name=Mail-IMAPClient
|
||||||
|
|
||||||
Copyright (C) 1999-2003 The Kernen Group, Inc.
|
Copyright (C) 1999-2003 The Kernen Group, Inc.
|
||||||
Copyright (C) 2007-2009 Mark Overmeer
|
Copyright (C) 2007-2009 Mark Overmeer
|
||||||
Copyright (C) 2010-2011 Phil Pearl (Lobbes)
|
Copyright (C) 2010-2012 Phil Pearl (Lobbes)
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or modify
|
This library is free software; you can redistribute it and/or modify
|
|
@ -9,94 +9,98 @@ my $HEAD = "HEAD";
|
||||||
|
|
||||||
# my has file scope, not limited to package!
|
# my has file scope, not limited to package!
|
||||||
my $parser = Mail::IMAPClient::BodyStructure::Parse->new
|
my $parser = Mail::IMAPClient::BodyStructure::Parse->new
|
||||||
or die "Cannot parse rules: $@\n"
|
or die "Cannot parse rules: $@\n"
|
||||||
. "Try remaking Mail::IMAPClient::BodyStructure::Parse.\n";
|
. "Try remaking Mail::IMAPClient::BodyStructure::Parse.\n";
|
||||||
|
|
||||||
sub new
|
sub new {
|
||||||
{ my $class = shift;
|
my $class = shift;
|
||||||
my $bodystructure = shift;
|
my $bodystructure = shift;
|
||||||
|
|
||||||
my $self = $parser->start($bodystructure)
|
my $self = $parser->start($bodystructure)
|
||||||
or return undef;
|
or return undef;
|
||||||
|
|
||||||
$self->{_prefix} = "";
|
$self->{_prefix} = "";
|
||||||
$self->{_id} = exists $self->{bodystructure} ? $HEAD : 1;
|
$self->{_id} = exists $self->{bodystructure} ? $HEAD : 1;
|
||||||
$self->{_top} = 1;
|
$self->{_top} = 1;
|
||||||
|
|
||||||
bless $self, ref($class)||$class;
|
bless $self, ref($class) || $class;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub _get_thingy
|
sub _get_thingy {
|
||||||
{ my $thingy = shift;
|
my $thingy = shift;
|
||||||
my $object = shift || (ref $thingy ? $thingy : undef);
|
my $object = shift || ( ref $thingy ? $thingy : undef );
|
||||||
|
|
||||||
unless ($object && ref $object)
|
unless ( $object && ref $object ) {
|
||||||
{ warn $@ = "No argument passed to $thingy method.";
|
warn $@ = "No argument passed to $thingy method.";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
unless(UNIVERSAL::isa($object, 'HASH') && exists $object->{$thingy})
|
unless ( UNIVERSAL::isa( $object, 'HASH' ) && exists $object->{$thingy} ) {
|
||||||
{ my $a = $thingy =~ /^[aeiou]/i ? 'an' : 'a';
|
my $a = $thingy =~ /^[aeiou]/i ? 'an' : 'a';
|
||||||
my $has = ref $object eq 'HASH' ? join(", ",keys %$object) : '';
|
my $has = ref $object eq 'HASH' ? join( ", ", keys %$object ) : '';
|
||||||
warn $@ = ref($object)." $object does not have $a $thingy. "
|
warn $@ =
|
||||||
. ($has ? "It has $has" : '');
|
ref($object)
|
||||||
|
. " $object does not have $a $thingy. "
|
||||||
|
. ( $has ? "It has $has" : '' );
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $value = $object->{$thingy};
|
my $value = $object->{$thingy};
|
||||||
$value =~ s/\\ ( [\\\(\)"\x0d\x0a] )/$1/gx;
|
$value =~ s/\\ ( [\\\(\)"\x0d\x0a] )/$1/gx;
|
||||||
$value =~ s/^"(.*)"$/$1/;
|
$value =~ s/^"(.*)"$/$1/;
|
||||||
$value;
|
$value;
|
||||||
}
|
}
|
||||||
|
|
||||||
BEGIN
|
BEGIN {
|
||||||
{ no strict 'refs';
|
no strict 'refs';
|
||||||
foreach my $datum (
|
foreach my $datum (
|
||||||
qw/ bodytype bodysubtype bodyparms bodydisp bodyid bodydesc bodyenc
|
qw/ bodytype bodysubtype bodyparms bodydisp bodyid bodydesc bodyenc
|
||||||
bodysize bodylang envelopestruct textlines / )
|
bodysize bodylang envelopestruct textlines /
|
||||||
{ *$datum = sub { _get_thingy($datum, @_) };
|
)
|
||||||
|
{
|
||||||
|
*$datum = sub { _get_thingy( $datum, @_ ) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub parts
|
sub parts {
|
||||||
{ my $self = shift;
|
my $self = shift;
|
||||||
return wantarray ? @{$self->{PartsList}} : $self->{PartsList}
|
return wantarray ? @{ $self->{PartsList} } : $self->{PartsList}
|
||||||
if exists $self->{PartsList};
|
if exists $self->{PartsList};
|
||||||
|
|
||||||
my @parts;
|
my @parts;
|
||||||
$self->{PartsList} = \@parts;
|
$self->{PartsList} = \@parts;
|
||||||
|
|
||||||
# BUG?: should this default to ($HEAD, TEXT)
|
# BUG?: should this default to ($HEAD, TEXT)
|
||||||
unless(exists $self->{bodystructure})
|
unless ( exists $self->{bodystructure} ) {
|
||||||
{ $self->{PartsIndex}{1} = $self;
|
$self->{PartsIndex}{1} = $self;
|
||||||
@parts = ($HEAD, 1);
|
@parts = ( $HEAD, 1 );
|
||||||
return wantarray ? @parts : \@parts;
|
return wantarray ? @parts : \@parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach my $p ($self->bodystructure)
|
foreach my $p ( $self->bodystructure ) {
|
||||||
{ my $id = $p->id;
|
my $id = $p->id;
|
||||||
push @parts, $id;
|
push @parts, $id;
|
||||||
$self->{PartsIndex}{$id} = $p ;
|
$self->{PartsIndex}{$id} = $p;
|
||||||
my $type = uc $p->bodytype || '';
|
my $type = uc $p->bodytype || '';
|
||||||
|
|
||||||
push @parts, "$id.$HEAD"
|
push @parts, "$id.$HEAD"
|
||||||
if $type eq 'MESSAGE';
|
if $type eq 'MESSAGE';
|
||||||
}
|
}
|
||||||
|
|
||||||
wantarray ? @parts : \@parts;
|
wantarray ? @parts : \@parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub bodystructure
|
sub bodystructure {
|
||||||
{ my $self = shift;
|
my $self = shift;
|
||||||
my $partno = 0;
|
my $partno = 0;
|
||||||
my @parts;
|
my @parts;
|
||||||
|
|
||||||
if($self->{_top})
|
if ( $self->{_top} ) {
|
||||||
{ $self->{_id} ||= $HEAD;
|
$self->{_id} ||= $HEAD;
|
||||||
$self->{_prefix} ||= $HEAD;
|
$self->{_prefix} ||= $HEAD;
|
||||||
$partno = 0;
|
$partno = 0;
|
||||||
foreach my $b ( @{$self->{bodystructure}} )
|
foreach my $b ( @{ $self->{bodystructure} } ) {
|
||||||
{ $b->{_id} = ++$partno;
|
$b->{_id} = ++$partno;
|
||||||
$b->{_prefix} = $partno;
|
$b->{_prefix} = $partno;
|
||||||
push @parts, $b, $b->bodystructure;
|
push @parts, $b, $b->bodystructure;
|
||||||
}
|
}
|
||||||
|
@ -104,10 +108,10 @@ sub bodystructure
|
||||||
}
|
}
|
||||||
|
|
||||||
my $prefix = $self->{_prefix} || "";
|
my $prefix = $self->{_prefix} || "";
|
||||||
$prefix =~ s/\.?$/./;
|
$prefix =~ s/\.?$/./;
|
||||||
|
|
||||||
foreach my $p ( @{$self->{bodystructure}} )
|
foreach my $p ( @{ $self->{bodystructure} } ) {
|
||||||
{ $partno++;
|
$partno++;
|
||||||
|
|
||||||
# BUG?: old code didn't add .TEXT sections, should we skip these?
|
# BUG?: old code didn't add .TEXT sections, should we skip these?
|
||||||
# - This code needs to be generalised (maybe it belongs in parts()?)
|
# - This code needs to be generalised (maybe it belongs in parts()?)
|
||||||
|
@ -119,14 +123,14 @@ sub bodystructure
|
||||||
my $ptype = $p->{bodytype} || "";
|
my $ptype = $p->{bodytype} || "";
|
||||||
|
|
||||||
# a message and the multipart inside of it "collapse together"
|
# a message and the multipart inside of it "collapse together"
|
||||||
if ($partno == 1 and $stype eq 'MESSAGE' and $ptype eq 'MULTIPART') {
|
if ( $partno == 1 and $stype eq 'MESSAGE' and $ptype eq 'MULTIPART' ) {
|
||||||
$pno = "TEXT";
|
$pno = "TEXT";
|
||||||
$p->{_prefix} = "$prefix";
|
$p->{_prefix} = "$prefix";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$p->{_prefix} = "$prefix$partno";
|
$p->{_prefix} = "$prefix$partno";
|
||||||
}
|
}
|
||||||
$p->{_id} ||= "$prefix$pno";
|
$p->{_id} ||= "$prefix$pno";
|
||||||
|
|
||||||
push @parts, $p, $p->{bodystructure} ? $p->bodystructure : ();
|
push @parts, $p, $p->{bodystructure} ? $p->bodystructure : ();
|
||||||
}
|
}
|
||||||
|
@ -134,22 +138,22 @@ sub bodystructure
|
||||||
wantarray ? @parts : \@parts;
|
wantarray ? @parts : \@parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub id
|
sub id {
|
||||||
{ my $self = shift;
|
my $self = shift;
|
||||||
return $self->{_id}
|
return $self->{_id}
|
||||||
if exists $self->{_id};
|
if exists $self->{_id};
|
||||||
|
|
||||||
return $HEAD
|
return $HEAD
|
||||||
if $self->{_top};
|
if $self->{_top};
|
||||||
|
|
||||||
# BUG?: can this be removed? ... seems wrong
|
# BUG?: can this be removed? ... seems wrong
|
||||||
if ($self->{bodytype} eq 'MULTIPART')
|
if ( $self->{bodytype} eq 'MULTIPART' ) {
|
||||||
{ my $p = $self->{_id} || $self->{_prefix};
|
my $p = $self->{_id} || $self->{_prefix};
|
||||||
$p =~ s/\.$//;
|
$p =~ s/\.$//;
|
||||||
return $p;
|
return $p;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{ return $self->{_id} ||= 1;
|
return $self->{_id} ||= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,55 +163,57 @@ our @ISA = qw/Mail::IMAPClient::BodyStructure/;
|
||||||
package Mail::IMAPClient::BodyStructure::Envelope;
|
package Mail::IMAPClient::BodyStructure::Envelope;
|
||||||
our @ISA = qw/Mail::IMAPClient::BodyStructure/;
|
our @ISA = qw/Mail::IMAPClient::BodyStructure/;
|
||||||
|
|
||||||
sub new
|
sub new {
|
||||||
{ my ($class, $envelope) = @_;
|
my ( $class, $envelope ) = @_;
|
||||||
$parser->envelope($envelope);
|
$parser->envelope($envelope);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub parse_string
|
sub parse_string {
|
||||||
{ my ($class, $envelope) = @_;
|
my ( $class, $envelope ) = @_;
|
||||||
$envelope = "(" . $envelope . ")" unless ( $envelope =~ /^\(/ );
|
$envelope = "(" . $envelope . ")" unless ( $envelope =~ /^\(/ );
|
||||||
$parser->envelopestruct($envelope);
|
$parser->envelopestruct($envelope);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub from_addresses { shift->_addresses(from => 1) }
|
sub from_addresses { shift->_addresses( from => 1 ) }
|
||||||
sub sender_addresses { shift->_addresses(sender => 1) }
|
sub sender_addresses { shift->_addresses( sender => 1 ) }
|
||||||
sub replyto_addresses { shift->_addresses(replyto => 1) }
|
sub replyto_addresses { shift->_addresses( replyto => 1 ) }
|
||||||
sub to_addresses { shift->_addresses(to => 0) }
|
sub to_addresses { shift->_addresses( to => 0 ) }
|
||||||
sub cc_addresses { shift->_addresses(cc => 0) }
|
sub cc_addresses { shift->_addresses( cc => 0 ) }
|
||||||
sub bcc_addresses { shift->_addresses(bcc => 0) }
|
sub bcc_addresses { shift->_addresses( bcc => 0 ) }
|
||||||
|
|
||||||
sub _addresses($$$)
|
sub _addresses($$$) {
|
||||||
{ my ($self, $name, $isSender) = @_;
|
my ( $self, $name, $isSender ) = @_;
|
||||||
ref $self->{$name} eq 'ARRAY'
|
ref $self->{$name} eq 'ARRAY'
|
||||||
or return ();
|
or return ();
|
||||||
|
|
||||||
my @list;
|
my @list;
|
||||||
foreach ( @{$self->{$name}} )
|
foreach ( @{ $self->{$name} } ) {
|
||||||
{ my $pn = $_->personalname;
|
my $pn = $_->personalname;
|
||||||
my $name = $pn && $pn ne 'NIL' ? "$pn " : '';
|
my $name = $pn && $pn ne 'NIL' ? "$pn " : '';
|
||||||
push @list, $name . '<' . $_->mailboxname . '@' . $_->hostname . '>';
|
push @list, $name . '<' . $_->mailboxname . '@' . $_->hostname . '>';
|
||||||
}
|
}
|
||||||
|
|
||||||
wantarray ? @list
|
wantarray ? @list
|
||||||
: $isSender ? $list[0]
|
: $isSender ? $list[0]
|
||||||
: \@list;
|
: \@list;
|
||||||
}
|
}
|
||||||
|
|
||||||
BEGIN
|
BEGIN {
|
||||||
{ no strict 'refs';
|
no strict 'refs';
|
||||||
for my $datum ( qw(subject inreplyto from messageid bcc date
|
for my $datum (
|
||||||
replyto to sender cc))
|
qw(subject inreplyto from messageid bcc date
|
||||||
{ *$datum = sub { @_ > 1 ? $_[0]->{$datum} = $_[1] : $_[0]->{$datum} }
|
replyto to sender cc)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
*$datum = sub { @_ > 1 ? $_[0]->{$datum} = $_[1] : $_[0]->{$datum} }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
package Mail::IMAPClient::BodyStructure::Address;
|
package Mail::IMAPClient::BodyStructure::Address;
|
||||||
our @ISA = qw/Mail::IMAPClient::BodyStructure/;
|
our @ISA = qw/Mail::IMAPClient::BodyStructure/;
|
||||||
|
|
||||||
for my $datum ( qw(personalname mailboxname hostname sourcename) )
|
for my $datum (qw(personalname mailboxname hostname sourcename)) {
|
||||||
{ no strict 'refs';
|
no strict 'refs';
|
||||||
*$datum = sub { shift->{$datum}; };
|
*$datum = sub { shift->{$datum}; };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,38 +227,32 @@ Mail::IMAPClient::BodyStructure - parse fetched results
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
use Mail::IMAPClient::BodyStructure;
|
|
||||||
use Mail::IMAPClient;
|
use Mail::IMAPClient;
|
||||||
|
use Mail::IMAPClient::BodyStructure;
|
||||||
|
|
||||||
my $imap = Mail::IMAPClient->new(Server=>$serv,User=>$usr,Password=>$pwd);
|
my $imap = Mail::IMAPClient->new(
|
||||||
$imap->select("INBOX") or die "cannot select the inbox for $usr: $@\n";
|
Server => $server, User => $login, Password => $pass
|
||||||
|
);
|
||||||
|
|
||||||
my @recent = $imap->search("recent");
|
$imap->select("INBOX") or die "Could not select INBOX: $@\n";
|
||||||
|
|
||||||
foreach my $id (@recent)
|
my @recent = $imap->search("recent") or die "No recent msgs in INBOX\n";
|
||||||
{ my $fetched = $imap->fetch($id, "bodystructure");
|
|
||||||
my $struct = Mail::IMAPClient::BodyStructure->new($fetched);
|
|
||||||
|
|
||||||
my $mime = $struct->bodytype."/".$struct->bodysubtype;
|
foreach my $id (@recent) {
|
||||||
my $parts =join "\n\t", $struct->parts;
|
my $bsdat = $imap->fetch( $id, "bodystructure" );
|
||||||
print "Msg $id (Content-type: $mime) contains these parts:\n\t$parts\n";
|
my $bso = Mail::IMAPClient::BodyStructure->new($bsdat);
|
||||||
|
my $mime = $bso->bodytype . "/" . $bso->bodysubtype;
|
||||||
|
my $parts = map( "\n\t" . $_, $bso->parts );
|
||||||
|
print "Msg $id (Content-type: $mime) contains these parts:$parts\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
This extension will parse the result of an IMAP FETCH BODYSTRUCTURE
|
This extension will parse the result of an IMAP FETCH BODYSTRUCTURE
|
||||||
command into a perl data structure. It also provides helper methods that
|
command into a perl data structure. It also provides helper methods
|
||||||
will help you pull information out of the data structure.
|
to help pull information out of the data structure.
|
||||||
|
|
||||||
Use of this extension requires Parse::RecDescent. If you don't have
|
This module requires Parse::RecDescent.
|
||||||
Parse::RecDescent then you must either get it or refrain from using
|
|
||||||
this module.
|
|
||||||
|
|
||||||
=head2 EXPORT
|
|
||||||
|
|
||||||
Nothing is exported by default. C<$parser> is exported upon
|
|
||||||
request. C<$parser> is the BodyStucture object's Parse::RecDescent object,
|
|
||||||
which you'll probably only need for debugging purposes.
|
|
||||||
|
|
||||||
=head1 Class Methods
|
=head1 Class Methods
|
||||||
|
|
||||||
|
@ -261,21 +261,13 @@ The following class method is available:
|
||||||
=head2 new
|
=head2 new
|
||||||
|
|
||||||
This class method is the constructor method for instantiating new
|
This class method is the constructor method for instantiating new
|
||||||
Mail::IMAPClient::BodyStructure objects. The B<new> method accepts one
|
Mail::IMAPClient::BodyStructure objects. The B<new> method accepts
|
||||||
argument, a string containing a server response to a FETCH BODYSTRUCTURE
|
one argument, a string containing a server response to a FETCH
|
||||||
directive. Only one message's body structure should be described in this
|
BODYSTRUCTURE directive.
|
||||||
string, although that message may contain an arbitrary number of parts.
|
|
||||||
|
|
||||||
If you know the messages sequence number or unique ID (UID)
|
The module B<Mail::IMAPClient> provides the B<get_bodystructure>
|
||||||
but haven't got its body structure, and you want to get the body
|
conveniece method to simplify use of this module when starting with
|
||||||
structure and parse it into a B<Mail::IMAPClient::BodyStructure>
|
just a messages sequence number or unique ID (UID).
|
||||||
object, then you might as well save yourself some work and use
|
|
||||||
B<Mail::IMAPClient>'s B<get_bodystructure> method, which accepts
|
|
||||||
a message sequence number (or UID if I<Uid> is true) and returns a
|
|
||||||
B<Mail::IMAPClient::BodyStructure> object. It's functionally equivalent
|
|
||||||
to issuing the FETCH BODYSTRUCTURE IMAP client command and then passing
|
|
||||||
the results to B<Mail::IMAPClient::BodyStructure>'s B<new> method but
|
|
||||||
it does those things in one simple method call.
|
|
||||||
|
|
||||||
=head1 Object Methods
|
=head1 Object Methods
|
||||||
|
|
||||||
|
@ -344,10 +336,8 @@ calling B<Mail::IMAPClient::Bodystructure> object.
|
||||||
=head2 envelopestruct
|
=head2 envelopestruct
|
||||||
|
|
||||||
The B<envelopestruct> object method requires no arguments. It returns
|
The B<envelopestruct> object method requires no arguments. It returns
|
||||||
the envelopestruct for the message whose structure is described by the
|
a B<Mail::IMAPClient::BodyStructure::Envelope> object for the message
|
||||||
calling B<Mail::IMAPClient::Bodystructure> object. This envelope structure
|
from the calling B<Mail::IMAPClient::Bodystructure> object.
|
||||||
is blessed into the B<Mail::IMAPClient::BodyStructure::Envelope> subclass,
|
|
||||||
which is explained more fully below.
|
|
||||||
|
|
||||||
=head2 textlines
|
=head2 textlines
|
||||||
|
|
||||||
|
@ -355,37 +345,38 @@ The B<textlines> object method requires no arguments. It returns the
|
||||||
textlines for the message whose structure is described by the calling
|
textlines for the message whose structure is described by the calling
|
||||||
B<Mail::IMAPClient::Bodystructure> object.
|
B<Mail::IMAPClient::Bodystructure> object.
|
||||||
|
|
||||||
=head1 Envelopes and the Mail::IMAPClient::BodyStructure::Envelope Subclass
|
=head1 Mail::IMAPClient::BodyStructure::Envelope
|
||||||
|
|
||||||
The IMAP standard specifies that output from the IMAP B<FETCH
|
The IMAP standard specifies that output from the IMAP B<FETCH
|
||||||
ENVELOPE> command will be an RFC2060 envelope structure. It further
|
ENVELOPE> command will be an RFC2060 envelope structure. It further
|
||||||
specifies that output from the B<FETCH BODYSTRUCTURE> command may also
|
specifies that output from the B<FETCH BODYSTRUCTURE> command may also
|
||||||
contain embedded envelope structures (if, for example, a message's
|
contain embedded envelope structures (if, for example, a message's
|
||||||
subparts contain one or more included messages). Objects belonging to
|
subparts contain one or more included messages). Objects belonging to
|
||||||
B<Mail::IMAPClient::BodyStructure::Envelope> are Perl representations
|
B<Mail::IMAPClient::BodyStructure::Envelope> are Perl representations
|
||||||
of these envelope structures, which is to say the nested parenthetical
|
of these envelope structures, which is to say the nested parenthetical
|
||||||
lists of RFC2060 translated into a Perl datastructure.
|
lists of RFC2060 translated into a Perl datastructure.
|
||||||
|
|
||||||
Note that all of the fields relate to the specific part to which they
|
Note that all of the fields relate to the specific part to which they
|
||||||
belong. In other words, output from a FETCH nnnn ENVELOPE command (or,
|
belong. In other words, output from a FETCH nnnn ENVELOPE command
|
||||||
in B<Mail::IMAPClient>, C<$imap->fetch($msgid,"ENVELOPE")> or C<my $env =
|
(or, in B<Mail::IMAPClient>, C<$imap->fetch($msgid,"ENVELOPE")> or
|
||||||
$imap->get_envelope($msgid)>) are for the message, but fields from within
|
C<my $env = $imap->get_envelope($msgid)>) are for the message, but
|
||||||
a bodystructure relate to the message subpart and not the parent message.
|
fields from within a bodystructure relate to the message subpart and
|
||||||
|
not the parent message.
|
||||||
|
|
||||||
An envelope structure's B<Mail::IMAPClient::BodyStructure::Envelope>
|
An envelope structure's B<Mail::IMAPClient::BodyStructure::Envelope>
|
||||||
representation is a hash of thingies that looks like this:
|
representation is a hash of thingies that looks like this:
|
||||||
|
|
||||||
{
|
{
|
||||||
subject => "subject",
|
subject => "subject",
|
||||||
inreplyto => "reference_message_id",
|
inreplyto => "reference_message_id",
|
||||||
from => [ addressStruct1 ],
|
from => [ addressStruct1 ],
|
||||||
messageid => "message_id",
|
messageid => "message_id",
|
||||||
bcc => [ addressStruct1, addressStruct2 ],
|
bcc => [ addressStruct1, addressStruct2 ],
|
||||||
date => "Tue, 09 Jul 2002 14:15:53 -0400",
|
date => "Tue, 09 Jul 2002 14:15:53 -0400",
|
||||||
replyto => [ adressStruct1, addressStruct2 ],
|
replyto => [ adressStruct1, addressStruct2 ],
|
||||||
to => [ adressStruct1, addressStruct2 ],
|
to => [ adressStruct1, addressStruct2 ],
|
||||||
sender => [ adressStruct1 ],
|
sender => [ adressStruct1 ],
|
||||||
cc => [ adressStruct1, addressStruct2 ],
|
cc => [ adressStruct1, addressStruct2 ],
|
||||||
}
|
}
|
||||||
|
|
||||||
The B<...::Envelope> object also has methods for accessing data in the
|
The B<...::Envelope> object also has methods for accessing data in the
|
||||||
|
@ -411,17 +402,17 @@ Returns the message id of the message.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
You can also use the following methods to get addressing
|
You can also use the following methods to get addressing information.
|
||||||
information. Each of these methods returns an array of
|
Each of these methods returns an array of
|
||||||
B<Mail::IMAPClient::BodyStructure::Address> objects, which are perl
|
B<Mail::IMAPClient::BodyStructure::Address> objects, which are perl
|
||||||
data structures representing RFC2060 address structures. Some of these
|
data structures representing RFC2060 address structures. Some of
|
||||||
arrays would naturally contain one element (such as B<from>, which
|
these arrays would naturally contain one element (such as B<from>,
|
||||||
normally contains a single "From:" address); others will often contain
|
which normally contains a single "From:" address); others will often
|
||||||
more than one address. However, because RFC2060 defines all of these as
|
contain more than one address. However, because RFC2060 defines all
|
||||||
"lists of address structures", they are all translated into arrays of
|
of these as "lists of address structures", they are all translated
|
||||||
B<...::Address> objects.
|
into arrays of B<...::Address> objects.
|
||||||
|
|
||||||
See the section on B<Mail::IMAPClient::BodyStructure::Address>", below,
|
See the section on B<Mail::IMAPClient::BodyStructure::Address>, below,
|
||||||
for alternate (and preferred) ways of accessing these data.
|
for alternate (and preferred) ways of accessing these data.
|
||||||
|
|
||||||
The methods available are:
|
The methods available are:
|
||||||
|
@ -430,9 +421,9 @@ The methods available are:
|
||||||
|
|
||||||
=item bcc
|
=item bcc
|
||||||
|
|
||||||
Returns an array of blind cc'ed recipients' address structures. (Don't
|
Returns an array of blind cc'ed recipients' address structures.
|
||||||
expect much in here unless the message was sent from the mailbox you're
|
(Don't expect much in here unless the message was sent from the
|
||||||
poking around in, by the way.)
|
mailbox you're poking around in, by the way.)
|
||||||
|
|
||||||
=item cc
|
=item cc
|
||||||
|
|
||||||
|
@ -444,8 +435,8 @@ Returns an array of "From:" address structures--usually just one.
|
||||||
|
|
||||||
=item replyto
|
=item replyto
|
||||||
|
|
||||||
Returns an array of "Reply-to:" address structures. Once again there is
|
Returns an array of "Reply-to:" address structures. Once again there
|
||||||
usually just one address in the list.
|
is usually just one address in the list.
|
||||||
|
|
||||||
=item sender
|
=item sender
|
||||||
|
|
||||||
|
@ -459,12 +450,12 @@ Returns an array of recipients' address structures.
|
||||||
=back
|
=back
|
||||||
|
|
||||||
Each of the methods that returns a list of address structures (i.e. a
|
Each of the methods that returns a list of address structures (i.e. a
|
||||||
list of B<Mail::IMAPClient::BodyStructure::Address> arrays) also has an
|
list of B<Mail::IMAPClient::BodyStructure::Address> arrays) also has
|
||||||
analagous method that will return a list of E-Mail addresses instead. The
|
an analagous method that will return a list of E-Mail addresses
|
||||||
addresses are in the format C<personalname E<lt>mailboxname@hostnameE<gt>>
|
instead. The addresses are in the format C<personalname
|
||||||
(see the section on B<Mail::IMAPClient::BodyStructure::Address>,
|
E<lt>mailboxname@hostnameE<gt>> (see the section on
|
||||||
below) However, if the personal name is 'NIL' then it is omitted from
|
B<Mail::IMAPClient::BodyStructure::Address>, below) However, if the
|
||||||
the address.
|
personal name is 'NIL' then it is omitted from the address.
|
||||||
|
|
||||||
These methods are:
|
These methods are:
|
||||||
|
|
||||||
|
@ -472,65 +463,66 @@ These methods are:
|
||||||
|
|
||||||
=item bcc_addresses
|
=item bcc_addresses
|
||||||
|
|
||||||
Returns a list (or an array reference if called in scalar context)
|
Returns a list (or an array reference if called in scalar context) of
|
||||||
of blind cc'ed recipients' email addresses. (Don't expect much in here
|
blind cc'ed recipients' email addresses. (Don't expect much in here
|
||||||
unless the message was sent from the mailbox you're poking around in,
|
unless the message was sent from the mailbox you're poking around in,
|
||||||
by the way.)
|
by the way.)
|
||||||
|
|
||||||
=item cc_addresses
|
=item cc_addresses
|
||||||
|
|
||||||
Returns a list of cc'ed recipients' email addresses. If called in a scalar
|
Returns a list of cc'ed recipients' email addresses. If called in a
|
||||||
context it returns a reference to an array of email addresses.
|
scalar context it returns a reference to an array of email addresses.
|
||||||
|
|
||||||
=item from_addresses
|
=item from_addresses
|
||||||
|
|
||||||
Returns a list of "From:" email addresses. If called in a scalar context
|
Returns a list of "From:" email addresses. If called in a scalar
|
||||||
it returns the first email address in the list. (It's usually a list of just
|
context it returns the first email address in the list. (It's usually
|
||||||
one anyway.)
|
a list of just one anyway.)
|
||||||
|
|
||||||
=item replyto_addresses
|
=item replyto_addresses
|
||||||
|
|
||||||
Returns a list of "Reply-to:" email addresses. If called in a scalar context
|
Returns a list of "Reply-to:" email addresses. If called in a scalar
|
||||||
it returns the first email address in the list.
|
context it returns the first email address in the list.
|
||||||
|
|
||||||
=item sender_addresses
|
=item sender_addresses
|
||||||
|
|
||||||
Returns a list of senders' email addresses. If called in a scalar context
|
Returns a list of senders' email addresses. If called in a scalar
|
||||||
it returns the first email address in the list.
|
context it returns the first email address in the list.
|
||||||
|
|
||||||
=item to_addresses
|
=item to_addresses
|
||||||
|
|
||||||
Returns a list of recipients' email addresses. If called in a scalar context
|
Returns a list of recipients' email addresses. If called in a scalar
|
||||||
it returns a reference to an array of email addresses.
|
context it returns a reference to an array of email addresses.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
Note that context affects the behavior of all of the above methods.
|
Note that context affects the behavior of all of the above methods.
|
||||||
|
|
||||||
Those fields that will commonly contain multiple entries (i.e. they are
|
Those fields that will commonly contain multiple entries (i.e. they
|
||||||
recipients) will return an array reference when called in scalar context.
|
are recipients) will return an array reference when called in scalar
|
||||||
You can use this behavior to optimize performance.
|
context. You can use this behavior to optimize performance.
|
||||||
|
|
||||||
Those fields that will commonly contain just one address (the sender's) will
|
Those fields that will commonly contain just one address (the
|
||||||
return the first (and usually only) address. You can use this behavior to
|
sender's) will return the first (and usually only) address. You can
|
||||||
optimize your development time.
|
use this behavior to optimize your development time.
|
||||||
|
|
||||||
=head1 Addresses and the Mail::IMAPClient::BodyStructure::Address
|
=head1 Addresses and the Mail::IMAPClient::BodyStructure::Address
|
||||||
|
|
||||||
Several components of an envelope structure are address
|
Several components of an envelope structure are address structures.
|
||||||
structures. They are each parsed into their own object,
|
They are each parsed into their own object,
|
||||||
B<Mail::IMAPClient::BodyStructure::Address>, which looks like this:
|
B<Mail::IMAPClient::BodyStructure::Address>, which looks like this:
|
||||||
|
|
||||||
{ mailboxname => 'somebody.special'
|
{
|
||||||
, hostname => 'somplace.weird.com'
|
mailboxname => 'somebody.special',
|
||||||
, personalname => 'Somebody Special
|
hostname => 'somplace.weird.com'
|
||||||
, sourceroute => 'NIL'
|
personalname => 'Somebody Special
|
||||||
|
sourceroute => 'NIL'
|
||||||
}
|
}
|
||||||
|
|
||||||
RFC2060 specifies that each address component of a bodystructure is a
|
RFC2060 specifies that each address component of a bodystructure is a
|
||||||
list of address structures, so B<Mail::IMAPClient::BodyStructure> parses
|
list of address structures, so B<Mail::IMAPClient::BodyStructure>
|
||||||
each of these into an array of B<Mail::IMAPClient::BodyStructure::Address>
|
parses each of these into an array of
|
||||||
objects.
|
B<Mail::IMAPClient::BodyStructure::Address> objects.
|
||||||
|
|
||||||
Each of these objects has the following methods available to it:
|
Each of these objects has the following methods available to it:
|
||||||
|
|
||||||
|
@ -543,13 +535,13 @@ the left of the '@' sign.
|
||||||
|
|
||||||
=item hostname
|
=item hostname
|
||||||
|
|
||||||
Returns the "hostname" portion of the address, which is the part to the
|
Returns the "hostname" portion of the address, which is the part to
|
||||||
right of the '@' sign.
|
the right of the '@' sign.
|
||||||
|
|
||||||
=item personalname
|
=item personalname
|
||||||
|
|
||||||
Returns the "personalname" portion of the address, which is the part of
|
Returns the "personalname" portion of the address, which is the part
|
||||||
the address that's treated like a comment.
|
of the address that's treated like a comment.
|
||||||
|
|
||||||
=item sourceroute
|
=item sourceroute
|
||||||
|
|
||||||
|
@ -557,30 +549,28 @@ Returns the "sourceroute" portion of the address, which is typically "NIL".
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
Taken together, the parts of an address structure form an address that will
|
Taken together, the parts of an address structure form an address that
|
||||||
look something like this:
|
will look something like this:
|
||||||
|
|
||||||
C<personalname E<lt>mailboxname@hostnameE<gt>>
|
C<personalname E<lt>mailboxname@hostnameE<gt>>
|
||||||
|
|
||||||
Note that because the B<Mail::IMAPClient::BodyStructure::Address>
|
Note that because the B<Mail::IMAPClient::BodyStructure::Address>
|
||||||
objects come in arrays, it's generally easier to use the methods
|
objects come in arrays, it's generally easier to use the methods
|
||||||
available to B<Mail::IMAPClient::BodyStructure::Envelope> to obtain
|
available to B<Mail::IMAPClient::BodyStructure::Envelope> to obtain
|
||||||
all of the addresses in a particular array in one operation. These
|
all of the addresses in a particular array in one operation. These
|
||||||
methods are provided, however, in case you'd rather do things
|
methods are provided, however, in case you'd rather do things the hard
|
||||||
the hard way. (And also because the aforementioned methods from
|
way. (And also because the aforementioned methods from
|
||||||
B<Mail::IMAPClient::BodyStructure::Envelope> need them anyway.)
|
B<Mail::IMAPClient::BodyStructure::Envelope> need them anyway.)
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
=head1 AUTHOR
|
=head1 AUTHOR
|
||||||
|
|
||||||
David J. Kernen
|
Original author: David J. Kernen; Reworked by: Mark Overmeer;
|
||||||
|
Maintained by Phil Pearl.
|
||||||
Reworked and maintained by Mark Overmeer.
|
|
||||||
|
|
||||||
=head1 SEE ALSO
|
=head1 SEE ALSO
|
||||||
|
|
||||||
perl(1), Mail::IMAPClient, and RFC2060. See also Parse::RecDescent if you
|
perl(1), Mail::IMAPClient, Parse::RecDescent, and RFC2060.
|
||||||
want to understand the internals of this module.
|
|
||||||
|
|
||||||
=cut
|
=cut
|
|
@ -413,11 +413,14 @@ ok( $imap->reconnect, "reconnect" );
|
||||||
|
|
||||||
ok_relaxed_logout($imap);
|
ok_relaxed_logout($imap);
|
||||||
|
|
||||||
# Test STARTTLS - an optional feature so tests always succeed
|
# STARTTLS - an optional feature
|
||||||
{
|
if ( $imap->_load_module("SSL") ) {
|
||||||
$imap->connect( Starttls => 1 );
|
$imap->connect( Ssl => 0, Starttls => 1 );
|
||||||
ok( 1, "OPTIONAL connect(Starttls=>1)" . ( $@ ? ": (error) $@ " : "" ) );
|
ok( 1, "OPTIONAL connect(Starttls=>1)" . ( $@ ? ": (error) $@ " : "" ) );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
ok( 1, "skipping optional STARTTLS test" );
|
||||||
|
}
|
||||||
|
|
||||||
# LOGOUT
|
# LOGOUT
|
||||||
# - on successful LOGOUT $code is OK (not BYE!) see RFC 3501 sect 7.1.5
|
# - on successful LOGOUT $code is OK (not BYE!) see RFC 3501 sect 7.1.5
|
30
W/learn/data_utf7
Normal file
30
W/learn/data_utf7
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
[&ZTZO9nux-]
|
||||||
|
[&ZTZO9nux-/263&cO1+vw-]
|
||||||
|
[&ZTZO9nux-/&kK57sZXumJg-]
|
||||||
|
[&ZTZO9nux-/&fwFb+G3u-]
|
||||||
|
[&ZTZO9nux-/11111]
|
||||||
|
[&XfJT0ZAB-]
|
||||||
|
[&XfJT0ZAB-/321]
|
||||||
|
[&XfJSIJZk-]
|
||||||
|
[&XfJSIJZk-/&fwFb+G3u-]
|
||||||
|
[&g0l6Pw-]
|
||||||
|
[&Tg1mDpCuTvZZOQ-]
|
||||||
|
[&XfJfUmhj-]
|
||||||
|
[&XfJfUmhj-/&VGhfi14I-]
|
||||||
|
[&XfJfUmhj-/&Ti1W,U4Hf1E-]
|
||||||
|
[&XfJfUmhj-/&f1F62Q-]
|
||||||
|
[&XfJfUmhj-/&UWh0Aw-]
|
||||||
|
[&XfJfUmhj-/&UWh0Aw-/11]
|
||||||
|
[&XfJfUmhj-/&fwFb+G3u-]
|
||||||
|
[&XfJfUmhj-/&X66Pbw-eip]
|
||||||
|
[&XfJfUmhj-/China Tax Service]
|
||||||
|
[&XfJfUmhj-/IT&ZXR0Bg-]
|
||||||
|
[&XfJfUmhj-/&cGuPZnlo-]
|
||||||
|
[&XfJfUmhj-/&UWhl9g-]
|
||||||
|
[&XfJfUmhj-/&dTWL3U8ai64-]
|
||||||
|
[&XfJfUmhj-/&V,mLrQ-]
|
||||||
|
[&XfJfUmhj-/&cO1wuU,hYG+QH5AS-]
|
||||||
|
[Sent Messages]
|
||||||
|
[Deleted Messages]
|
||||||
|
[&V4NXPpCuTvY-]
|
||||||
|
[&XfJSIJZkkK5O9g-]
|
13
W/learn/imap_utf7
Executable file
13
W/learn/imap_utf7
Executable file
|
@ -0,0 +1,13 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
|
||||||
|
use Unicode::IMAPUtf7;
|
||||||
|
|
||||||
|
my $t = Unicode::IMAPUtf7->new();
|
||||||
|
|
||||||
|
while (<>) {
|
||||||
|
chomp ;
|
||||||
|
push( @result, sprintf( "%33s %s\n", $_, $t->decode($_) ) ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
print @result ;
|
41
W/ml_announce.in
Normal file
41
W/ml_announce.in
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
m4_dnl $Id: ml_announce.in,v 1.3 2012/09/11 21:01:53 gilles Exp gilles $
|
||||||
|
m4_dnl
|
||||||
|
m4_define(`M4_imapsync_VERSION',m4_esyscmd(cat VERSION|tr -d '\n'))m4_dnl
|
||||||
|
m4_define(`M4_SECRET_PATH',m4_esyscmd(cat dist/path_last.txt|tr -d '\n'))m4_dnl
|
||||||
|
m4_dnl
|
||||||
|
From: Gilles LAMIRAL <gilles.lamiral@laposte.net>
|
||||||
|
Bcc: gilles@lamiral.info
|
||||||
|
Subject: [imapsync update] new imapsync release M4_imapsync_VERSION available
|
||||||
|
To: imapsync_update@lists.lamiral.info
|
||||||
|
|
||||||
|
Hello imapsync user,
|
||||||
|
|
||||||
|
You're subscribed to the newsletter announcing imapsync new releases
|
||||||
|
(very few traffic) and the way to get them. Send me a note if you
|
||||||
|
don't want to receive those announces anymore.
|
||||||
|
|
||||||
|
You will find the latest imapsync.exe binary (release M4_imapsync_VERSION)
|
||||||
|
and the latest imapsync source code (release M4_imapsync_VERSION) at the following link:
|
||||||
|
|
||||||
|
http://imapsync.lamiral.info/dist/M4_SECRET_PATH/
|
||||||
|
|
||||||
|
Three files are there:
|
||||||
|
- imapsync is directly the perl script (also found in the tarball) for a fast upgrade.
|
||||||
|
- imapsync-M4_imapsync_VERSION.tgz is the tarball containing everything of the project (maybe too much)
|
||||||
|
- imapsync.exe is the win32 standalone binary.
|
||||||
|
|
||||||
|
What's new in this M4_imapsync_VERSION release can be found at
|
||||||
|
http://imapsync.lamiral.info/#latest
|
||||||
|
|
||||||
|
I thank you again for buying and using imapsync,
|
||||||
|
I wish you successful imap transfers!
|
||||||
|
|
||||||
|
Feedback is welcome!
|
||||||
|
|
||||||
|
Web site: http://imapsync.lamiral.info/
|
||||||
|
|
||||||
|
--
|
||||||
|
Au revoir.
|
||||||
|
Gilles Lamiral, La Billais, 35580 Baulon, France
|
||||||
|
tel +33 951 84 42 42
|
||||||
|
mob +33 620 79 76 06
|
|
@ -1,13 +1,13 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# $Id: paypal_run_dev,v 1.5 2011/05/20 10:50:05 gilles Exp gilles $
|
# $Id: paypal_run_dev,v 1.7 2012/09/10 11:53:37 gilles Exp gilles $
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
#set -x
|
#set -x
|
||||||
|
|
||||||
# Add path to commands at home
|
# Add path to commands at home
|
||||||
PATH=$PATH:/g/public_html/imapsync/W/paypal_reply
|
PATH=$PATH:/g/public_html/imapsync/W/paypal_reply
|
||||||
PERL5LIB=/g/public_html/imapsync/Mail-IMAPClient-3.30/lib
|
PERL5LIB=/g/public_html/imapsync/Mail-IMAPClient-3.32/lib
|
||||||
export PERL5LIB
|
export PERL5LIB
|
||||||
|
|
||||||
test -f /g/public_html/imapsync/W/paypal_reply/paypal_functions \
|
test -f /g/public_html/imapsync/W/paypal_reply/paypal_functions \
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# $Id: paypal_run_laposte,v 1.5 2012/08/24 14:18:02 gilles Exp gilles $
|
# $Id: paypal_run_laposte,v 1.6 2012/09/10 11:54:33 gilles Exp gilles $
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
#set -x
|
#set -x
|
||||||
|
@ -8,7 +8,7 @@ set -e
|
||||||
|
|
||||||
# Add path to commands at home
|
# Add path to commands at home
|
||||||
PATH=$PATH:/g/public_html/imapsync/W/paypal_reply
|
PATH=$PATH:/g/public_html/imapsync/W/paypal_reply
|
||||||
PERL5LIB=/g/public_html/imapsync/Mail-IMAPClient-3.30/lib
|
PERL5LIB=/g/public_html/imapsync/Mail-IMAPClient-3.32/lib
|
||||||
export PERL5LIB
|
export PERL5LIB
|
||||||
|
|
||||||
test -f /g/public_html/imapsync/W/paypal_reply/paypal_functions \
|
test -f /g/public_html/imapsync/W/paypal_reply/paypal_functions \
|
||||||
|
|
|
@ -1,2 +1,6 @@
|
||||||
imapsync \ --host1 p --user1 toto --passfile1 secret.toto \ --host2 p --user2 titi --passfile2 secret.titi
|
REM
|
||||||
imapsync \ --host1 p --user1 tata --passfile1 secret.tata \ --host2 p --user2 titi --passfile2 secret.titi
|
|
||||||
|
cd C:\msys\1.0\home\Admin\imapsync
|
||||||
|
|
||||||
|
REM imapsync.exe \ --host1 p --user1 toto --passfile1 secret.toto \ --host2 p --user2 titi --passfile2 secret.titi
|
||||||
|
.\imapsync.exe \ --host1 p --user1 tata --passfile1 secret.tata \ --host2 p --user2 titi --passfile2 secret.titi
|
||||||
|
|
4
i3
4
i3
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# $Id: i3,v 1.10 2012/08/12 23:15:15 gilles Exp gilles $
|
# $Id: i3,v 1.11 2012/09/11 21:00:06 gilles Exp gilles $
|
||||||
|
|
||||||
BASE=`dirname $0`
|
BASE=`dirname $0`
|
||||||
perl -I${BASE}/W/Mail-IMAPClient-3.31/lib ${BASE}/imapsync "$@"
|
perl -I${BASE}/W/Mail-IMAPClient-3.32/lib ${BASE}/imapsync "$@"
|
||||||
|
|
||||||
|
|
129
imapsync
129
imapsync
|
@ -20,7 +20,7 @@ Synchronise mailboxes between two imap servers.
|
||||||
Good at IMAP migration. More than 44 different IMAP server softwares
|
Good at IMAP migration. More than 44 different IMAP server softwares
|
||||||
supported with success.
|
supported with success.
|
||||||
|
|
||||||
$Revision: 1.504 $
|
$Revision: 1.508 $
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
@ -515,7 +515,7 @@ Entries for imapsync:
|
||||||
|
|
||||||
Feedback (good or bad) will often be welcome.
|
Feedback (good or bad) will often be welcome.
|
||||||
|
|
||||||
$Id: imapsync,v 1.504 2012/08/28 13:10:26 gilles Exp gilles $
|
$Id: imapsync,v 1.508 2012/09/10 21:10:13 gilles Exp gilles $
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
@ -589,6 +589,7 @@ my(
|
||||||
$version, $help,
|
$version, $help,
|
||||||
$justconnect, $justfolders, $justbanner,
|
$justconnect, $justfolders, $justbanner,
|
||||||
$fast,
|
$fast,
|
||||||
|
|
||||||
$total_bytes_transferred,
|
$total_bytes_transferred,
|
||||||
$total_bytes_skipped,
|
$total_bytes_skipped,
|
||||||
$total_bytes_error,
|
$total_bytes_error,
|
||||||
|
@ -603,6 +604,12 @@ my(
|
||||||
$h2_total_bytes_duplicate,
|
$h2_total_bytes_duplicate,
|
||||||
$h1_nb_msg_deleted,
|
$h1_nb_msg_deleted,
|
||||||
$h2_nb_msg_deleted,
|
$h2_nb_msg_deleted,
|
||||||
|
|
||||||
|
$h1_bytes_processed,
|
||||||
|
$h1_nb_msg_processed,
|
||||||
|
$h1_nb_msg_start, $h1_bytes_start,
|
||||||
|
$h2_nb_msg_start, $h2_bytes_start,
|
||||||
|
|
||||||
$timeout,
|
$timeout,
|
||||||
$timestart, $timestart_int, $timeend, $timediff,
|
$timestart, $timestart_int, $timeend, $timediff,
|
||||||
$timesize, $timebefore,
|
$timesize, $timebefore,
|
||||||
|
@ -627,13 +634,14 @@ my(
|
||||||
$addheader,
|
$addheader,
|
||||||
%h1, %h2,
|
%h1, %h2,
|
||||||
$checkselectable, $checkmessageexists,
|
$checkselectable, $checkmessageexists,
|
||||||
|
$expungeaftereach,
|
||||||
);
|
);
|
||||||
|
|
||||||
# main program
|
# main program
|
||||||
|
|
||||||
# global variables initialisation
|
# global variables initialisation
|
||||||
|
|
||||||
$rcs = '$Id: imapsync,v 1.504 2012/08/28 13:10:26 gilles Exp gilles $ ';
|
$rcs = '$Id: imapsync,v 1.508 2012/09/10 21:10:13 gilles Exp gilles $ ';
|
||||||
|
|
||||||
$total_bytes_transferred = 0;
|
$total_bytes_transferred = 0;
|
||||||
$total_bytes_skipped = 0;
|
$total_bytes_skipped = 0;
|
||||||
|
@ -645,6 +653,11 @@ $h1_nb_msg_duplicate = $h2_nb_msg_duplicate = 0;
|
||||||
$h1_nb_msg_noheader = $h2_nb_msg_noheader = 0;
|
$h1_nb_msg_noheader = $h2_nb_msg_noheader = 0;
|
||||||
$h1_total_bytes_duplicate = $h2_total_bytes_duplicate = 0;
|
$h1_total_bytes_duplicate = $h2_total_bytes_duplicate = 0;
|
||||||
|
|
||||||
|
|
||||||
|
$h1_nb_msg_start = $h1_bytes_start = 0 ;
|
||||||
|
$h2_nb_msg_start = $h2_bytes_start = 0 ;
|
||||||
|
$h1_nb_msg_processed = $h1_bytes_processed = 0 ;
|
||||||
|
|
||||||
$nb_errors = 0;
|
$nb_errors = 0;
|
||||||
$max_msg_size_in_bytes = 0;
|
$max_msg_size_in_bytes = 0;
|
||||||
|
|
||||||
|
@ -715,6 +728,7 @@ $cacheaftercopy = 1 if ( $usecache and ( ! defined( $cacheaftercopy ) ) ) ;
|
||||||
|
|
||||||
$checkselectable = defined( $checkselectable ) ? $checkselectable : 1 ;
|
$checkselectable = defined( $checkselectable ) ? $checkselectable : 1 ;
|
||||||
$checkmessageexists = defined( $checkmessageexists ) ? $checkmessageexists : 1 ;
|
$checkmessageexists = defined( $checkmessageexists ) ? $checkmessageexists : 1 ;
|
||||||
|
$expungeaftereach = defined( $expungeaftereach ) ? $expungeaftereach : 1 ;
|
||||||
|
|
||||||
print banner_imapsync(@argv_copy);
|
print banner_imapsync(@argv_copy);
|
||||||
|
|
||||||
|
@ -1043,9 +1057,9 @@ foreach my $h1_fold (@h1_folders_all) {
|
||||||
#@h2_folders_from_1_all = sort keys(%h2_folders_from_1_all);
|
#@h2_folders_from_1_all = sort keys(%h2_folders_from_1_all);
|
||||||
|
|
||||||
|
|
||||||
if ($foldersizes) {
|
if ( $foldersizes ) {
|
||||||
foldersizes( "Host1", $imap1, @h1_folders_wanted ) ;
|
( $h1_nb_msg_start, $h1_bytes_start ) = foldersizes( "Host1", $imap1, @h1_folders_wanted ) ;
|
||||||
foldersizes( "Host2", $imap2, @h2_folders_from_1_wanted ) ;
|
( $h2_nb_msg_start, $h2_bytes_start ) = foldersizes( "Host2", $imap2, @h2_folders_from_1_wanted ) ;
|
||||||
sleep( 2 ) ;
|
sleep( 2 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1221,6 +1235,7 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
|
||||||
$total_bytes_skipped += $h1_size;
|
$total_bytes_skipped += $h1_size;
|
||||||
$nb_msg_skipped += 1;
|
$nb_msg_skipped += 1;
|
||||||
$h1_nb_msg_noheader +=1;
|
$h1_nb_msg_noheader +=1;
|
||||||
|
$h1_nb_msg_processed +=1 ;
|
||||||
} elsif(0 == $rc) {
|
} elsif(0 == $rc) {
|
||||||
# duplicate
|
# duplicate
|
||||||
push(@h1_msgs_duplicate, $m);
|
push(@h1_msgs_duplicate, $m);
|
||||||
|
@ -1229,6 +1244,7 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
|
||||||
$nb_msg_skipped += 1;
|
$nb_msg_skipped += 1;
|
||||||
$h1_total_bytes_duplicate += $h1_size;
|
$h1_total_bytes_duplicate += $h1_size;
|
||||||
$h1_nb_msg_duplicate += 1;
|
$h1_nb_msg_duplicate += 1;
|
||||||
|
$h1_nb_msg_processed +=1 ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
my $h1_msgs_duplicate_nb = scalar( @h1_msgs_duplicate ) ;
|
my $h1_msgs_duplicate_nb = scalar( @h1_msgs_duplicate ) ;
|
||||||
|
@ -1281,6 +1297,7 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
|
||||||
= sort {$h2_hash{$a}{'m'} <=> $h2_hash{$b}{'m'}} keys(%h2_hash);
|
= sort {$h2_hash{$a}{'m'} <=> $h2_hash{$b}{'m'}} keys(%h2_hash);
|
||||||
|
|
||||||
if ( 0 ) {
|
if ( 0 ) {
|
||||||
|
# What the hell was this code written for?
|
||||||
# hashes, keys are uid, values are the internaldates in epoch (best format to compare dates)
|
# hashes, keys are uid, values are the internaldates in epoch (best format to compare dates)
|
||||||
my %h1_epoch ;
|
my %h1_epoch ;
|
||||||
my %h2_epoch ;
|
my %h2_epoch ;
|
||||||
|
@ -1341,7 +1358,7 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
|
||||||
$debug and print "Host2 uidnext: $h2_uidnext\n" ;
|
$debug and print "Host2 uidnext: $h2_uidnext\n" ;
|
||||||
$h2_uidguess = $h2_uidnext ;
|
$h2_uidguess = $h2_uidnext ;
|
||||||
MESS: foreach my $m_id (@h1_hash_keys_sorted_by_uid) {
|
MESS: foreach my $m_id (@h1_hash_keys_sorted_by_uid) {
|
||||||
|
#print "h1_nb_msg_processed: $h1_nb_msg_processed\n" ;
|
||||||
my $h1_size = $h1_hash{$m_id}{'s'};
|
my $h1_size = $h1_hash{$m_id}{'s'};
|
||||||
my $h1_msg = $h1_hash{$m_id}{'m'};
|
my $h1_msg = $h1_hash{$m_id}{'m'};
|
||||||
my $h1_idate = $h1_hash{$m_id}{'D'};
|
my $h1_idate = $h1_hash{$m_id}{'D'};
|
||||||
|
@ -1360,6 +1377,8 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
|
||||||
$debug and print "Host1 found msg $h1_fold/$h1_msg equals Host2 $h2_fold/$h2_msg\n" ;
|
$debug and print "Host1 found msg $h1_fold/$h1_msg equals Host2 $h2_fold/$h2_msg\n" ;
|
||||||
$total_bytes_skipped += $h1_size ;
|
$total_bytes_skipped += $h1_size ;
|
||||||
$nb_msg_skipped += 1 ;
|
$nb_msg_skipped += 1 ;
|
||||||
|
$h1_nb_msg_processed +=1 ;
|
||||||
|
|
||||||
if ( $usecache ) {
|
if ( $usecache ) {
|
||||||
$debugcache and print "touch $cache_dir/${h1_msg}_$h2_msg\n" ;
|
$debugcache and print "touch $cache_dir/${h1_msg}_$h2_msg\n" ;
|
||||||
touch( "$cache_dir/${h1_msg}_$h2_msg" )
|
touch( "$cache_dir/${h1_msg}_$h2_msg" )
|
||||||
|
@ -1378,12 +1397,12 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
|
||||||
"Host1 size msg $h1_fold/$h1_msg = $h1_size <> $h2_size = Host2 $h2_fold/$h2_msg\n";
|
"Host1 size msg $h1_fold/$h1_msg = $h1_size <> $h2_size = Host2 $h2_fold/$h2_msg\n";
|
||||||
if( $delete ) {
|
if( $delete ) {
|
||||||
my $expunge_message = '' ;
|
my $expunge_message = '' ;
|
||||||
$expunge_message = "and expunged" if ( $expunge or $expunge1 ) ;
|
$expunge_message = "and expunged" if ( $expungeaftereach and ( $expunge or $expunge1 ) ) ;
|
||||||
print "Host1 msg $h1_fold/$h1_msg marked deleted $expunge_message $dry_message\n" ;
|
print "Host1 msg $h1_fold/$h1_msg marked deleted $expunge_message $dry_message\n" ;
|
||||||
unless( $dry ) {
|
unless( $dry ) {
|
||||||
$imap1->delete_message( $h1_msg ) ;
|
$imap1->delete_message( $h1_msg ) ;
|
||||||
$h1_nb_msg_deleted += 1 ;
|
$h1_nb_msg_deleted += 1 ;
|
||||||
$imap1->expunge() if ( $expunge or $expunge1 ) ;
|
$imap1->expunge() if ( $expungeaftereach and ( $expunge or $expunge1 ) ) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1398,6 +1417,7 @@ FOLDER: foreach my $h1_fold (@h1_folders_wanted) {
|
||||||
my $h1_size = $h1_fir_ref->{ $h1_msg }->{ 'RFC822.SIZE' } || 0 ;
|
my $h1_size = $h1_fir_ref->{ $h1_msg }->{ 'RFC822.SIZE' } || 0 ;
|
||||||
$total_bytes_skipped += $h1_size;
|
$total_bytes_skipped += $h1_size;
|
||||||
$nb_msg_skipped += 1;
|
$nb_msg_skipped += 1;
|
||||||
|
$h1_nb_msg_processed +=1 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
#print "Messages by uid: ", map { "$_ " } keys %h1_msgs_copy_by_uid, "\n" ;
|
#print "Messages by uid: ", map { "$_ " } keys %h1_msgs_copy_by_uid, "\n" ;
|
||||||
|
@ -1903,8 +1923,8 @@ sub banner_imapsync {
|
||||||
my @argv_copy = @_;
|
my @argv_copy = @_;
|
||||||
my $banner_imapsync = join("",
|
my $banner_imapsync = join("",
|
||||||
'$RCSfile: imapsync,v $ ',
|
'$RCSfile: imapsync,v $ ',
|
||||||
'$Revision: 1.504 $ ',
|
'$Revision: 1.508 $ ',
|
||||||
'$Date: 2012/08/28 13:10:26 $ ',
|
'$Date: 2012/09/10 21:10:13 $ ',
|
||||||
"\n",localhost_info(), "\n",
|
"\n",localhost_info(), "\n",
|
||||||
"Command line used:\n",
|
"Command line used:\n",
|
||||||
"$0 ", command_line_nopassword(@argv_copy), "\n",
|
"$0 ", command_line_nopassword(@argv_copy), "\n",
|
||||||
|
@ -2352,10 +2372,11 @@ sub foldersizes {
|
||||||
$total_size += $stot ;
|
$total_size += $stot ;
|
||||||
$total_nb += $nb_msgs ;
|
$total_nb += $nb_msgs ;
|
||||||
}
|
}
|
||||||
printf ( "Nb messages: %11s messages\n", $total_nb ) ;
|
printf ( "%s Nb messages: %11s messages\n", $side, $total_nb ) ;
|
||||||
printf ( "Total size: %11s bytes (%s)\n", $total_size, bytes_display_string( $total_size ) ) ;
|
printf ( "%s Total size: %11s bytes (%s)\n", $side, $total_size, bytes_display_string( $total_size ) ) ;
|
||||||
printf ( "Biggest message: %11s bytes (%s)\n", $biggest, bytes_display_string( $biggest ) ) ;
|
printf ( "%s Biggest message: %11s bytes (%s)\n", $side, $biggest, bytes_display_string( $biggest ) ) ;
|
||||||
printf ( "Time spent: %11.1f seconds\n", timenext( ) ) ;
|
printf ( "%s Time spent: %11.1f seconds\n", $side, timenext( ) ) ;
|
||||||
|
return( $total_nb, $total_size ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub timenext {
|
sub timenext {
|
||||||
|
@ -2735,13 +2756,22 @@ sub copy_message {
|
||||||
my $h1_flags = $h1_fir_ref->{$h1_msg}->{"FLAGS"} || '' ;
|
my $h1_flags = $h1_fir_ref->{$h1_msg}->{"FLAGS"} || '' ;
|
||||||
my $h1_idate = $h1_fir_ref->{$h1_msg}->{"INTERNALDATE"} || '' ;
|
my $h1_idate = $h1_fir_ref->{$h1_msg}->{"INTERNALDATE"} || '' ;
|
||||||
|
|
||||||
return() if size_filtered( $h1_size, $h1_msg, $h1_fold, $h2_fold ) ;
|
|
||||||
|
if (size_filtered( $h1_size, $h1_msg, $h1_fold, $h2_fold ) ) {
|
||||||
|
$h1_nb_msg_processed +=1 ;
|
||||||
|
return( ) ;
|
||||||
|
}
|
||||||
|
|
||||||
my $string;
|
my $string;
|
||||||
do { print "SLEEP 5\n" and sleep 5 ; } if ( $debugsleep ) ;
|
do { print "SLEEP 5\n" and sleep 5 ; } if ( $debugsleep ) ;
|
||||||
print "- msg $h1_fold/$h1_msg S[$h1_size] F[$h1_flags] I[$h1_idate] has RFC822.SIZE null!\n" if ( ! $h1_size ) ;
|
print "- msg $h1_fold/$h1_msg S[$h1_size] F[$h1_flags] I[$h1_idate] has RFC822.SIZE null!\n" if ( ! $h1_size ) ;
|
||||||
|
|
||||||
return( ) if ( $checkmessageexists and not message_exists( $imap1, $h1_msg ) ) ;
|
|
||||||
|
if ( $checkmessageexists and not message_exists( $imap1, $h1_msg ) ) {
|
||||||
|
$h1_nb_msg_processed +=1 ;
|
||||||
|
return( ) ;
|
||||||
|
}
|
||||||
|
|
||||||
$string = $imap1->message_string($h1_msg);
|
$string = $imap1->message_string($h1_msg);
|
||||||
|
|
||||||
|
|
||||||
|
@ -2754,6 +2784,7 @@ sub copy_message {
|
||||||
$nb_errors++ ;
|
$nb_errors++ ;
|
||||||
$total_bytes_error += $h1_size if ( $h1_size ) ;
|
$total_bytes_error += $h1_size if ( $h1_size ) ;
|
||||||
#relogin1( ) if ( $relogin1 ) ;
|
#relogin1( ) if ( $relogin1 ) ;
|
||||||
|
$h1_nb_msg_processed +=1 ;
|
||||||
return( ) ;
|
return( ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2807,6 +2838,7 @@ sub copy_message {
|
||||||
$imap2->LastError, "\n";
|
$imap2->LastError, "\n";
|
||||||
$nb_errors++;
|
$nb_errors++;
|
||||||
$total_bytes_error += $h1_size;
|
$total_bytes_error += $h1_size;
|
||||||
|
$h1_nb_msg_processed +=1 ;
|
||||||
return( ) ;
|
return( ) ;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
@ -2819,12 +2851,15 @@ sub copy_message {
|
||||||
$h2_uidguess += 1 ;
|
$h2_uidguess += 1 ;
|
||||||
$total_bytes_transferred += $h1_size ;
|
$total_bytes_transferred += $h1_size ;
|
||||||
$nb_msg_transferred += 1 ;
|
$nb_msg_transferred += 1 ;
|
||||||
|
$h1_nb_msg_processed +=1 ;
|
||||||
|
|
||||||
my $time_spent = timesince( $begin_transfer_time ) ;
|
my $time_spent = timesince( $begin_transfer_time ) ;
|
||||||
my $rate = bytes_display_string( $total_bytes_transferred / $time_spent ) ;
|
my $rate = bytes_display_string( $total_bytes_transferred / $time_spent ) ;
|
||||||
|
my $eta = eta( $time_spent, $h1_nb_msg_processed, $h1_nb_msg_start, $nb_msg_transferred ) ;
|
||||||
|
#my $eta = eta( $time_spent, $nb_msg_transferred, $h1_nb_msg_start ) ;
|
||||||
|
|
||||||
printf( "msg %s/%-19s copied to %s/%-10s %.2f msgs/s %s/s\n",
|
printf( "msg %s/%-19s copied to %s/%-10s %.2f msgs/s %s/s %s\n",
|
||||||
$h1_fold, "$h1_msg {$string_len}", $h2_fold, $new_id, $nb_msg_transferred/$time_spent, $rate );
|
$h1_fold, "$h1_msg {$string_len}", $h2_fold, $new_id, $nb_msg_transferred/$time_spent, $rate, $eta );
|
||||||
|
|
||||||
if ( $usecache and $cacheaftercopy and $new_id =~ m{^\d+$} ) {
|
if ( $usecache and $cacheaftercopy and $new_id =~ m{^\d+$} ) {
|
||||||
$debugcache and print "touch $cache_dir/${h1_msg}_$new_id\n" ;
|
$debugcache and print "touch $cache_dir/${h1_msg}_$new_id\n" ;
|
||||||
|
@ -2844,8 +2879,39 @@ sub copy_message {
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
$nb_msg_skipped_dry_mode += 1;
|
$nb_msg_skipped_dry_mode += 1;
|
||||||
|
$h1_nb_msg_processed +=1 ;
|
||||||
}
|
}
|
||||||
return( );
|
}
|
||||||
|
|
||||||
|
sub eta {
|
||||||
|
|
||||||
|
return( '' ) if not $foldersizes ;
|
||||||
|
|
||||||
|
my( $time_spent, $h1_nb_msg_processed, $h1_nb_msg_start, $nb_msg_transferred ) = @_ ;
|
||||||
|
|
||||||
|
my $time_remaining = time_remaining( @_ ) ;
|
||||||
|
my $nb_msg_remaining = $h1_nb_msg_start - $h1_nb_msg_processed ;
|
||||||
|
my $eta_date = localtime( time + $time_remaining ) ;
|
||||||
|
return( sprintf( "ETA: %s %1.0f s %s msgs left", $eta_date, $time_remaining, $nb_msg_remaining ) ) ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sub time_remaining {
|
||||||
|
|
||||||
|
my( $time_spent, $h1_nb_msg_processed, $h1_nb_msg_start, $nb_msg_transferred ) = @_ ;
|
||||||
|
|
||||||
|
my $time_remaining = ( $time_spent / $nb_msg_transferred ) * ( $h1_nb_msg_start - $h1_nb_msg_processed ) ;
|
||||||
|
return( $time_remaining ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub tests_time_remaining {
|
||||||
|
|
||||||
|
|
||||||
|
ok( 1 == time_remaining( 1, 1, 2, 1 ), "time_remaining: 1, 1, 2, 1 -> 1") ;
|
||||||
|
ok( 1 == time_remaining( 9, 9, 10, 9 ), "time_remaining: 9, 9, 10, 9 -> 1") ;
|
||||||
|
ok( 9 == time_remaining( 1, 1, 10, 1 ), "time_remaining: 1, 1, 10, 1 -> 1") ;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3274,20 +3340,27 @@ sub touch {
|
||||||
return( ! $failures );
|
return( ! $failures );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub tests_cache_folder {
|
||||||
|
|
||||||
|
ok( '/path/fold1/fold2' eq cache_folder( '/path', 'fold1', 'fold2'), 'cache_folder: /path, fold1, fold2 -> /path/fold1/fold2' ) ;
|
||||||
|
ok( '/pa_th/fold1/fold2' eq cache_folder( '/pa*th', 'fold1', 'fold2'), 'cache_folder: /pa*th, fold1, fold2 -> /path/fold1/fold2' ) ;
|
||||||
|
ok( '/_p_a__th/fol_d1/fold2' eq cache_folder( '/>p<a|*th', 'fol*d1', 'fold2'), 'cache_folder: />p<a|*th, fol*d1, fold2 -> /path/fol_d1/fold2' ) ;
|
||||||
|
}
|
||||||
|
|
||||||
sub cache_folder {
|
sub cache_folder {
|
||||||
my( $cache_dir, $h1_fold, $h2_fold ) = @_ ;
|
my( $cache_dir, $h1_fold, $h2_fold ) = @_ ;
|
||||||
|
|
||||||
#print "sep1 $h1_sep sep2 $h2_sep\n";
|
|
||||||
my $sep1 = $h1_sep || '/';
|
my $sep1 = $h1_sep || '/';
|
||||||
my $sep2 = $h2_sep || '/';
|
my $sep2 = $h2_sep || '/';
|
||||||
|
|
||||||
|
#print "$cache_dir h1_fold $h1_fold sep1 $sep1 h2_fold $h2_fold sep2 $sep2\n";
|
||||||
$h1_fold = convert_sep_to_slash( $h1_fold, $sep1 ) ;
|
$h1_fold = convert_sep_to_slash( $h1_fold, $sep1 ) ;
|
||||||
$h2_fold = convert_sep_to_slash( $h2_fold, $sep2 ) ;
|
$h2_fold = convert_sep_to_slash( $h2_fold, $sep2 ) ;
|
||||||
|
|
||||||
$h1_fold = filter_forbidden_characters( $h1_fold ) ;
|
my $cache_folder = "$cache_dir/$h1_fold/$h2_fold" ;
|
||||||
$h2_fold = filter_forbidden_characters( $h2_fold ) ;
|
$cache_folder = filter_forbidden_characters( $cache_folder ) ;
|
||||||
|
#print "cache_folder [$cache_folder]\n" ;
|
||||||
return( "$cache_dir/$h1_fold/$h2_fold" ) ;
|
return( $cache_folder ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub filter_forbidden_characters {
|
sub filter_forbidden_characters {
|
||||||
|
@ -3606,6 +3679,7 @@ sub get_options {
|
||||||
"exitwhenover=i" => \$exitwhenover,
|
"exitwhenover=i" => \$exitwhenover,
|
||||||
"checkselectable!" => \$checkselectable,
|
"checkselectable!" => \$checkselectable,
|
||||||
"checkmessageexists!" => \$checkmessageexists,
|
"checkmessageexists!" => \$checkmessageexists,
|
||||||
|
"expungeaftereach!" => \$expungeaftereach,
|
||||||
);
|
);
|
||||||
|
|
||||||
$debug and print "get options: [$opt_ret]\n";
|
$debug and print "get options: [$opt_ret]\n";
|
||||||
|
@ -3795,7 +3869,7 @@ sub check_last_release {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub imapsync_version {
|
sub imapsync_version {
|
||||||
my $rcs = '$Id: imapsync,v 1.504 2012/08/28 13:10:26 gilles Exp gilles $ ';
|
my $rcs = '$Id: imapsync,v 1.508 2012/09/10 21:10:13 gilles Exp gilles $ ';
|
||||||
$rcs =~ m/,v (\d+\.\d+)/;
|
$rcs =~ m/,v (\d+\.\d+)/;
|
||||||
my $VERSION = ($1) ? $1: "UNKNOWN";
|
my $VERSION = ($1) ? $1: "UNKNOWN";
|
||||||
return($VERSION);
|
return($VERSION);
|
||||||
|
@ -4594,7 +4668,7 @@ sub tests_debug {
|
||||||
|
|
||||||
SKIP: {
|
SKIP: {
|
||||||
skip "No test in normal run" if ( not $tests_debug );
|
skip "No test in normal run" if ( not $tests_debug );
|
||||||
tests_cache_dir_fix( ) ;
|
tests_time_remaining( ) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4633,6 +4707,7 @@ sub tests {
|
||||||
tests_add_header( ) ;
|
tests_add_header( ) ;
|
||||||
tests_cache_dir_fix( ) ;
|
tests_cache_dir_fix( ) ;
|
||||||
tests_filter_forbidden_characters( ) ;
|
tests_filter_forbidden_characters( ) ;
|
||||||
|
tests_cache_folder( ) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
125
index.shtml
125
index.shtml
|
@ -5,7 +5,7 @@
|
||||||
<title>Imapsync: an IMAP migration tool ( release <!--#exec cmd="cat ./VERSION"--> )</title>
|
<title>Imapsync: an IMAP migration tool ( release <!--#exec cmd="cat ./VERSION"--> )</title>
|
||||||
<meta name="generator" content="Bluefish 1.0.7"/>
|
<meta name="generator" content="Bluefish 1.0.7"/>
|
||||||
<meta name="author" content="Gilles LAMIRAL"/>
|
<meta name="author" content="Gilles LAMIRAL"/>
|
||||||
<meta name="date" content="2012-08-29T12:23:32+0200"/>
|
<meta name="date" content="2012-09-12T00:06:47+0200"/>
|
||||||
<meta name="copyright" content="None"/>
|
<meta name="copyright" content="None"/>
|
||||||
<meta name="keywords" content="imap, transfert, migration"/>
|
<meta name="keywords" content="imap, transfert, migration"/>
|
||||||
<meta name="description" content="imap migration tool"/>
|
<meta name="description" content="imap migration tool"/>
|
||||||
|
@ -95,7 +95,7 @@ total is 93 millions for 2011</li>
|
||||||
<p>New features or bugfixes since previous releases:</p>
|
<p>New features or bugfixes since previous releases:</p>
|
||||||
|
|
||||||
<!-- <ul>
|
<!-- <ul>
|
||||||
<li><b>1.504</b></li>
|
<li><b>1.508</b></li>
|
||||||
<li><b>Enhancement</b>: </li>
|
<li><b>Enhancement</b>: </li>
|
||||||
<li><b>Enhancement</b>: </li>
|
<li><b>Enhancement</b>: </li>
|
||||||
<li><b>Enhancement</b>: </li>
|
<li><b>Enhancement</b>: </li>
|
||||||
|
@ -111,9 +111,18 @@ total is 93 millions for 2011</li>
|
||||||
</ul>
|
</ul>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><b>1.508</b></li>
|
||||||
|
<li><b>Usability</b>: imapsync guesses and <b>prints when it'll finish</b> the transfer; added <b>ETA</b> after each copy (Estimated Time of Arrival)</li>
|
||||||
|
<li><b>Enhancement</b>: Added <b>--noexpungeaftereach</b> to speedup --delete --expunge from Gmail.</li>
|
||||||
|
<li><b>Usability</b>: Added Host1 or Host2 before "Nb messages" "Total size" with --foldersiszes (to facilitate parsing)</li>
|
||||||
|
<li><b>Bug fix</b>: Previous fix about characters *|?:"<> in cache path was not complete.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>1.504</b></li>
|
<li><b>1.504</b></li>
|
||||||
<li><b>Enhancement</b>: Added option <b>--nocheckmessageexists</b> to <b>speed up</b> with <b>Tobbit imap server</b> as host1.</li>
|
<li><b>Enhancement</b>: Added option <b>--nocheckmessageexists</b> to <b>speed up</b> with <b>Tobit imap server</b> as host1.</li>
|
||||||
<li><b>Usability</b>: Added <b>transfer rate</b> and number of messages rate <b>after each copy</b>.</li>
|
<li><b>Usability</b>: Added <b>transfer rate</b> and number of messages rate <b>after each copy</b>.</li>
|
||||||
<li><b>Usability</b>: Use Time::HiRes time to get time with better precesion than the second.</li>
|
<li><b>Usability</b>: Use Time::HiRes time to get time with better precesion than the second.</li>
|
||||||
<li><b>Bug fix</b>: Convert characters <kbd>*|?:"<></kbd> to <kbd>_</kbd> in cache paths because they are forbidden on Windows paths.</li>
|
<li><b>Bug fix</b>: Convert characters <kbd>*|?:"<></kbd> to <kbd>_</kbd> in cache paths because they are forbidden on Windows paths.</li>
|
||||||
|
@ -422,71 +431,85 @@ Don't hesitate to have a try, I will help you and make efforts to switch them to
|
||||||
[host1] means "source server" and [host2] means "destination server":
|
[host1] means "source server" and [host2] means "destination server":
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
(<a href=""></a>)
|
||||||
|
-->
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>1und1 H mimap1 84498 [host1]</li>
|
<li>1und1 H mimap1 84498 [host1] (<a href="http://www.1und1.de/">http://www.1und1.de/</a>)</li>
|
||||||
<li>a1.net imap.a1.net IMAP4 Ready [host1]</li>
|
<li>a1.net imap.a1.net IMAP4 Ready [host1] </li>
|
||||||
<li>Archiveopteryx 2.03, 2.04, 2.09, 2.10 [host2], 3.0.0 [host2]
|
<li>Archiveopteryx 2.03, 2.04, 2.09, 2.10 [host2], 3.0.0 [host2]
|
||||||
(OSL 3.0) http://www.archiveopteryx.org/</li>
|
(OSL 3.0) (<a href="http://www.archiveopteryx.org/">http://www.archiveopteryx.org/</a>)</li>
|
||||||
<li>Axigen Mail Server Version 8.0.0</li>
|
<li>Axigen Mail Server Version 8.0.0 (<a href="http://www.axigen.com/">http://www.axigen.com/</a>)</li>
|
||||||
<li>BincImap 1.2.3 (GPL) (http://www.bincimap.org/)</li>
|
<li>BincImap 1.2.3 (GPL) (<a href="http://www.bincimap.org/">http://www.bincimap.org/</a>)</li>
|
||||||
<li>CommuniGatePro server (Redhat 8.0) (Solaris), CommuniGate Pro 5.2.17[host2] (CentOS 5.4)</li>
|
<li>CommuniGatePro server (Redhat 8.0) (Solaris), CommuniGate Pro 5.2.17[host2] (CentOS 5.4)
|
||||||
|
(<a href="http://www.communigate.com/">http://www.communigate.com/</a>) </li>
|
||||||
<li>Courier IMAP 1.5.1, 2.2.0, 2.1.1, 2.2.1, 3.0.8, 3.0.3, 4.1.1 (GPL)
|
<li>Courier IMAP 1.5.1, 2.2.0, 2.1.1, 2.2.1, 3.0.8, 3.0.3, 4.1.1 (GPL)
|
||||||
(http://www.courier-mta.org/)</li>
|
(<a href="http://www.courier-mta.org/imap/">http://www.courier-mta.org/imap/</a>) </li>
|
||||||
<li>Critical Path (7.0.020)</li>
|
<li>Critical Path (7.0.020) (<a href=""></a>) </li>
|
||||||
<li>Cyrus IMAP 1.5, 1.6,
|
<li>Cyrus IMAP 1.5, 1.6,
|
||||||
2.1, 2.1.15, 2.1.16, 2.1.18
|
2.1, 2.1.15, 2.1.16, 2.1.18
|
||||||
2.2.1, 2.2.2-BETA, 2.2.3, 2.2.6, 2.2.10, 2.2.12, 2.2.13,
|
2.2.1, 2.2.2-BETA, 2.2.3, 2.2.6, 2.2.10, 2.2.12, 2.2.13,
|
||||||
2.3-alpha (OSI Approved), 2.3.1, 2.3.7, 2.3.16
|
2.3-alpha (OSI Approved), 2.3.1, 2.3.7, 2.3.16
|
||||||
(http://asg.web.cmu.edu/cyrus/)
|
(<a href="http://cyrusimap.web.cmu.edu/">http://cyrusimap.web.cmu.edu/</a>)
|
||||||
</li>
|
</li>
|
||||||
<li>David Tobit V8.</li>
|
<li>David Tobit V8. (<a href="http://www.tobit.com/">http://www.tobit.com/</a>) </li>
|
||||||
<li>DBMail 1.2.1, 2.0.4, 2.0.9, 2.2rc1 (GPL) (http://www.dbmail.org/).
|
<li>DBMail 1.2.1, 2.0.4, 2.0.9, 2.2rc1 (GPL).
|
||||||
2.0.7 seems buggy.</li>
|
2.0.7 seems buggy. (<a href="http://www.dbmail.org/">http://www.dbmail.org/</a>) </li>
|
||||||
<li>Deerfield VisNetic MailServer 5.8.6 [host1]</li>
|
<li>Deerfield VisNetic MailServer 5.8.6 [host1]
|
||||||
<li>dkimap4 [host1]</li>
|
(<a href="http://www.deerfield.net/products/visnetic-mailserver/">http://www.deerfield.net/products/visnetic-mailserver/</a>) </li>
|
||||||
<li>Domino (Notes) 4.61[host1], 6.5, 5.0.6, 5.0.7, 7.0.2, 6.0.2CF1, 7.0.1[host1], 8.0.1[host1]</li>
|
<li>dkimap4 [host1] (<a href=""></a>) </li>
|
||||||
|
<li>Domino (Notes) 4.61[host1], 6.5, 5.0.6, 5.0.7, 7.0.2, 6.0.2CF1, 7.0.1[host1], 8.0.1[host1]
|
||||||
|
(<a href="http://www-01.ibm.com/software/lotus/products/notes/">http://www-01.ibm.com/software/lotus/products/notes/</a>) </li>
|
||||||
<li><b>Dovecot</b> 0.99.10.4, 0.99.14, 0.99.14-8.fc4, 1.0-0.beta2.7,
|
<li><b>Dovecot</b> 0.99.10.4, 0.99.14, 0.99.14-8.fc4, 1.0-0.beta2.7,
|
||||||
1.0.0 [dest/source] (LGPL) (http://www.dovecot.org/)</li>
|
1.0.0 [dest/source] (LGPL) (http://www.dovecot.org/) (<a href="http://www.dovecot.org/">http://www.dovecot.org/</a>) </li>
|
||||||
<li>Eudora WorldMail v2</li>
|
<li>Eudora WorldMail v2 (<a href="http://www.eudora.com/worldmail/">http://www.eudora.com/worldmail/</a>) </li>
|
||||||
<li><b>Gimap</b> (<b>Gmail</b> imap) [host1] [host2]</li>
|
<li><b>Gimap</b> (<b>Gmail</b> imap) [host1] [host2] (<a href="http://mail.google.com/">http://mail.google.com/</a>) </li>
|
||||||
<li>GMX IMAP4 StreamProxy.</li>
|
<li>GMX IMAP4 StreamProxy. (<a href="http://www.gmx.com/">http://www.gmx.com/</a>) </li>
|
||||||
<li>Godaddy IMAP (since Godaddy runs Courier)</li>
|
<li>Godaddy IMAP (since Godaddy runs Courier) (<a href="http://www.godaddy.com/">http://www.godaddy.com/</a>) </li>
|
||||||
<li>Groupwise IMAP (Novell) 6.x and 7.0. Buggy so see the FAQ.</li>
|
<li>Groupwise IMAP (Novell) 6.x and 7.0. Buggy so see the FAQ.
|
||||||
<li>hMailServer 5.3.3 [host2], 4.4.1 [host1], HMAILSERVER 5.3.2-B1769 on windows 2003 [hsot2]</li>
|
(<a href="http://www.novell.com/products/groupwise/">http://www.novell.com/products/groupwise/</a>) </li>
|
||||||
<li>iPlanet Messaging server 4.15, 5.1, 5.2</li>
|
<li>hMailServer 5.3.3 [host2], 4.4.1 [host1], HMAILSERVER 5.3.2-B1769 on windows 2003 [hsot2]
|
||||||
<li>IMail 7.15 (Ipswitch/Win2003), 8.12, 11.03 [host1]</li>
|
(<a href="http://www.hmailserver.com/">http://www.hmailserver.com/</a>) </li>
|
||||||
<li>Kerio 7.2.0P1 [host1]</li>
|
<li>iPlanet Messaging server 4.15, 5.1, 5.2
|
||||||
<li><b>MailEnable</b> 4.23 [host1][host2], 4.26 [host1][host2], 5 [host1]</li>
|
(<a href="http://en.wikipedia.org/wiki/Oracle_Communications_Messaging_Server">http://en.wikipedia.org/wiki/Oracle_Communications_Messaging_Server</a>) </li>
|
||||||
<li>MDaemon 7.0.1, 8.0.2, 8.1, 9.5.4 (Windows server 2003 R2 platform), 12 [host2], 12.0.3 [host1], 12.5.5 [host1]</li>
|
<li>IMail 7.15 (Ipswitch/Win2003), 8.12, 11.03 [host1] (<a href="http://www.imailserver.com/">http://www.imailserver.com/</a>) </li>
|
||||||
<li>Mercury 4.1 (Windows server 2000 platform)</li>
|
<li>Kerio 7.2.0P1 [host1] (<a href="http://www.kerio.com/">http://www.kerio.com/</a>) </li>
|
||||||
|
<li><b>MailEnable</b> 4.23 [host1][host2], 4.26 [host1][host2], 5 [host1]
|
||||||
|
(<a href="http://www.mailenable.com/">http://www.mailenable.com/</a>) </li>
|
||||||
|
<li>MDaemon 7.0.1, 8.0.2, 8.1, 9.5.4 (Windows server 2003 R2 platform), 12 [host2], 12.0.3 [host1], 12.5.5 [host1]
|
||||||
|
(<a href="http://www.altn.com/">http://www.altn.com/</a>) </li>
|
||||||
|
<li>Mercury 4.1 (Windows server 2000 platform) (<a href="http://www.pmail.com/">http://www.pmail.com/</a>) </li>
|
||||||
<li><b>Microsoft Exchange Server</b> 5.5, 6.0.6249.0[host1], 6.0.6487.0[host1],
|
<li><b>Microsoft Exchange Server</b> 5.5, 6.0.6249.0[host1], 6.0.6487.0[host1],
|
||||||
6.5.7638.1 [host2], 6.5 [host1], Exchange 2007 SP1 (with Update Rollup 2),
|
6.5.7638.1 [host2], 6.5 [host1], Exchange 2007 SP1 (with Update Rollup 2),
|
||||||
Exchange2007-EP-SP2,
|
Exchange2007-EP-SP2,
|
||||||
Exchange 2010 RTM (Release to Manufacturing) [host2],
|
Exchange 2010 RTM (Release to Manufacturing) [host2],
|
||||||
Exchange 2010 SP1 RU2 [host2]
|
Exchange 2010 SP1 RU2 [host2]
|
||||||
|
(<a href="http://www.microsoft.com/exchange/">http://www.microsoft.com/exchange/</a>)
|
||||||
</li>
|
</li>
|
||||||
<li>Mirapoint server 4.1.9-GA [host1]</li>
|
<li>Mirapoint server 4.1.9-GA [host1] (<a href="http://www.mirapoint.com/">http://www.mirapoint.com/</a>) </li>
|
||||||
<li>Netscape Mail Server 3.6 (Wintel)</li>
|
<li>Netscape Mail Server 3.6 (Wintel) </li>
|
||||||
<li>Netscape Messaging Server 4.15 Patch 7</li>
|
<li>Netscape Messaging Server 4.15 Patch 7 </li>
|
||||||
<li>OpenMail IMAP server B.07.00.k0</li>
|
<li>OpenMail IMAP server B.07.00.k0 </li>
|
||||||
<li>OpenWave</li>
|
<li>OpenWave (<a href="http://www.openwave.com/">http://www.openwave.com/</a>) </li>
|
||||||
<li>Oracle Beehive [host1]</li>
|
<li>Oracle Beehive [host1]
|
||||||
<li>Qualcomm Worldmail (NT)</li>
|
(<a href="http://www.oracle.com/technetwork/middleware/beehive/">http://www.oracle.com/technetwork/middleware/beehive/</a>) </li>
|
||||||
<li>Rockliffe Mailsite 5.3.11, 4.5.6</li>
|
<li>Qualcomm Worldmail (NT) (<a href="http://www.eudora.com/worldmail/">http://www.eudora.com/worldmail/</a>) </li>
|
||||||
<li>Samsung Contact IMAP server 8.5.0</li>
|
<li>Rockliffe Mailsite 5.3.11, 4.5.6 (<a href="http://www.mailsite.com/">http://www.mailsite.com/</a>) </li>
|
||||||
<li>Scalix v10.1, 10.0.1.3, 11.0.0.431</li>
|
<li>Samsung Contact IMAP server 8.5.0 </li>
|
||||||
<li>SmarterMail, Smarter Mail 5.0 Enterprise, Smarter Mail 5.5 [host1].</li>
|
<li>Scalix v10.1, 10.0.1.3, 11.0.0.431 (<a href="http://www.scalix.com/">http://www.scalix.com/</a>) </li>
|
||||||
<li>SunONE Messaging server 5.2, 6.0 (SUN JES - Java Enterprise System)</li>
|
<li>SmarterMail, Smarter Mail 5.0 Enterprise, Smarter Mail 5.5 [host1]. (<a href="http://www.smartertools.com/">http://www.smartertools.com/</a>) </li>
|
||||||
<li>Sun Java(tm) System Messaging Server 6.2-2.05, 6.2-7.05, 6.3</li>
|
<li>SunONE Messaging server 5.2, 6.0 (SUN JES - Java Enterprise System) (<a href="http://www.oracle.com/">http://www.oracle.com/</a>) </li>
|
||||||
<li>Surgemail 3.6f5-5</li>
|
<li>Sun Java(tm) System Messaging Server 6.2-2.05, 6.2-7.05, 6.3 (<a href="http://www.oracle.com/">http://www.oracle.com/</a>) </li>
|
||||||
|
<li>Surgemail 3.6f5-5 (<a href="http://netwinsite.com/surgemail/">http://netwinsite.com/surgemail/</a>) </li>
|
||||||
<li>UW-imap servers (imap-2000b) rijkkramer IMAP4rev1 2000.287
|
<li>UW-imap servers (imap-2000b) rijkkramer IMAP4rev1 2000.287
|
||||||
(RedHat uses UW like 2003.338rh), v12.264 Solaris 5.7 (OSI Approved)
|
(RedHat uses UW like 2003.338rh), v12.264 Solaris 5.7 (OSI Approved)
|
||||||
(http://www.washington.edu/imap/)</li>
|
(<a href="http://www.washington.edu/imap/">http://www.washington.edu/imap/</a>) </li>
|
||||||
<li>UW - QMail v2.1</li>
|
<li>VMS, Imap part of TCP/IP suite of VMS 7.3.2 (<a href="http://h71000.www7.hp.com/openvms/">http://h71000.www7.hp.com/openvms/</a>) </li>
|
||||||
<li>VMS, Imap part of TCP/IP suite of VMS 7.3.2</li>
|
<li><b>Yahoo</b> [host1] (<a href="http://www.yahoo.com/">http://www.yahoo.com/</a>) </li>
|
||||||
<li><b>Yahoo</b> [host1]</li>
|
|
||||||
<li><b>Zimbra-IMAP</b> 3.0.1 GA 160, 3.1.0 Build 279, 4.0.5, 4.5.2, 4.5.6,
|
<li><b>Zimbra-IMAP</b> 3.0.1 GA 160, 3.1.0 Build 279, 4.0.5, 4.5.2, 4.5.6,
|
||||||
Zimbra 5.0.24_GA_3356.RHEL4 [host1], 5.5, 6.x</li>
|
Zimbra 5.0.24_GA_3356.RHEL4 [host1], 5.5, 6.x
|
||||||
|
(<a href="http://www.zimbra.com/">http://www.zimbra.com/</a>) </li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2><a id="similar"></a>Similar softwares</h2>
|
<h2><a id="similar"></a>Similar softwares</h2>
|
||||||
|
@ -553,7 +576,7 @@ alt="Viewable With Any Browser" />
|
||||||
<!--#config timefmt="%D" -->
|
<!--#config timefmt="%D" -->
|
||||||
<!--#config timefmt="%A %B %d, %Y" -->
|
<!--#config timefmt="%A %B %d, %Y" -->
|
||||||
<b>This document last modified on <!--#echo var="LAST_MODIFIED" --></b>
|
<b>This document last modified on <!--#echo var="LAST_MODIFIED" --></b>
|
||||||
($Id: index.shtml,v 1.129 2012/08/29 10:25:29 gilles Exp gilles $)
|
($Id: index.shtml,v 1.131 2012/09/11 22:07:18 gilles Exp gilles $)
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
28
tests.sh
28
tests.sh
|
@ -1,9 +1,9 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# $Id: tests.sh,v 1.200 2012/08/28 13:11:30 gilles Exp gilles $
|
# $Id: tests.sh,v 1.201 2012/09/10 21:12:35 gilles Exp gilles $
|
||||||
|
|
||||||
# Example 1:
|
# Example 1:
|
||||||
# CMD_PERL='perl -I./Mail-IMAPClient-3.31/lib' sh -x tests.sh
|
# CMD_PERL='perl -I./Mail-IMAPClient-3.32/lib' sh -x tests.sh
|
||||||
|
|
||||||
# Example 2:
|
# Example 2:
|
||||||
# To select which Mail-IMAPClient within arguments:
|
# To select which Mail-IMAPClient within arguments:
|
||||||
|
@ -23,7 +23,7 @@ echo HOST2=$HOST2
|
||||||
|
|
||||||
# few debugging tests use:
|
# few debugging tests use:
|
||||||
CMD_PERL_2xx='perl -I./W/Mail-IMAPClient-2.2.9'
|
CMD_PERL_2xx='perl -I./W/Mail-IMAPClient-2.2.9'
|
||||||
CMD_PERL_3xx='perl -I./W/Mail-IMAPClient-3.31/lib'
|
CMD_PERL_3xx='perl -I./W/Mail-IMAPClient-3.32/lib'
|
||||||
|
|
||||||
CMD_PERL=${CMD_PERL:-$CMD_PERL_3xx}
|
CMD_PERL=${CMD_PERL:-$CMD_PERL_3xx}
|
||||||
|
|
||||||
|
@ -1591,6 +1591,28 @@ ll_delete2() {
|
||||||
--delete2 --expunge2
|
--delete2 --expunge2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ll_delete2_reverse() {
|
||||||
|
$CMD_PERL ./imapsync \
|
||||||
|
--host1 $HOST1 --user1 titi \
|
||||||
|
--passfile1 ../../var/pass/secret.titi \
|
||||||
|
--host2 $HOST2 --user2 tata \
|
||||||
|
--passfile2 ../../var/pass/secret.tata \
|
||||||
|
--folder INBOX \
|
||||||
|
--delete2 --expunge2
|
||||||
|
}
|
||||||
|
|
||||||
|
ll_delete_reverse() {
|
||||||
|
$CMD_PERL ./imapsync \
|
||||||
|
--host1 $HOST1 --user1 titi \
|
||||||
|
--passfile1 ../../var/pass/secret.titi \
|
||||||
|
--host2 $HOST2 --user2 tata \
|
||||||
|
--passfile2 ../../var/pass/secret.tata \
|
||||||
|
--folder INBOX \
|
||||||
|
--delete --minage 100 --maxage 300 --noexpungeaftereach
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ll_delete2_minage() {
|
ll_delete2_minage() {
|
||||||
can_send && sendtestmessage titi
|
can_send && sendtestmessage titi
|
||||||
$CMD_PERL ./imapsync \
|
$CMD_PERL ./imapsync \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue