1
0
mirror of https://github.com/imapsync/imapsync.git synced 2024-11-16 15:52:47 +01:00
This commit is contained in:
Nick Bebout 2013-12-29 20:03:13 -06:00
parent 8f266abab8
commit 6a0efa6bc8
86 changed files with 1747 additions and 28151 deletions

19
CREDITS
View File

@ -1,5 +1,5 @@
#!/bin/cat
# $Id: CREDITS,v 1.177 2013/09/28 11:52:08 gilles Exp gilles $
# $Id: CREDITS,v 1.180 2013/11/15 01:51:58 gilles Exp gilles $
If you want to make a donation to the author, Gilles LAMIRAL,
use any of the following ways:
@ -30,6 +30,21 @@ I thank very much all of these people.
I thank also very much all people who bought imapsync from the homepage
but I don't cite them here.
David Karnowski.
Suggested --disarm_read_receipts for its regex.
Erik Torsner.
Gave patch for create_folder() and nested folders.
http://erik.torgesta.com/2013/05/gmail-and-google-apps-mail-migration/
Ralf Hauber
Gave installation tips for Centos and a bug report about
final statistics for newly created folders.
Dave Murray
Simon Savva
Found, reported and solved the "Flagged" flag Exchange bug.
Krul, Patrick
Found bug about trailing blanc on Win32 cache dir.
@ -37,7 +52,6 @@ Jonathan Daley
Contributed by giving the book
13.33 EUR "Cartoon Guide to Statistics"
Bowman Gillianne
Contributed by giving the book
8.60 EUR "L'Épreuve de l'étranger: Culture et traduction dans l'Allemagne romantique"
@ -66,7 +80,6 @@ Peter Fuchs
Contributed by giving the book
30.86 "Designed for Use: Create Usable Interfaces for Applications and the Web"
Pierre GUILLAUME // e-Lixir
Fixed 2 bugs about [Gmail] folder names.
one is about $cache_dir and bsd_globs() that needs escaped characters.

View File

@ -1,17 +1,65 @@
RCS file: RCS/imapsync,v
Working file: imapsync
head: 1.569
head: 1.580
branch:
locks: strict
gilles: 1.569
gilles: 1.580
access list:
symbolic names:
keyword substitution: kv
total revisions: 569; selected revisions: 569
total revisions: 580; selected revisions: 580
description:
----------------------------
revision 1.569 locked by: gilles;
revision 1.580 locked by: gilles;
date: 2013/12/25 02:52:36; author: gilles; state: Exp; lines: +51 -27
Added --skipcrossduplicates to avoid copying messages that are already copied in another folder.
Added --debugcrossduplicates to print which messages (UIDs) are skipped with --skipcrossduplicates (and in what other folders they are).
----------------------------
revision 1.579
date: 2013/12/18 13:53:19; author: gilles; state: Exp; lines: +9 -8
--maxmessagespersecond, value can be float like 3.2
----------------------------
revision 1.578
date: 2013/12/17 02:14:09; author: gilles; state: Exp; lines: +73 -9
Added --maxbytespersecond to limit byte transfer rate.
Added --maxmessagespersecond to limit messages tranfer rate (office365 throttle limitation).
----------------------------
revision 1.577
date: 2013/12/05 05:57:51; author: gilles; state: Exp; lines: +28 -10
Added tests to play with win32 \\?\C:\TEMP syntax and try to solve long path bug.
----------------------------
revision 1.576
date: 2013/11/19 14:37:24; author: gilles; state: Exp; lines: +19 -14
Added --debugmemory option that prints memory consumption after each message is copied.
----------------------------
revision 1.575
date: 2013/11/06 13:55:38; author: gilles; state: Exp; lines: +12 -7
Do not append message if the fetch failed.
----------------------------
revision 1.574
date: 2013/10/28 16:22:04; author: gilles; state: Exp; lines: +16 -8
Added --create_folder_old in case users want the old behavior of create_folder().
----------------------------
revision 1.573
date: 2013/10/28 14:44:10; author: gilles; state: Exp; lines: +48 -7
Bugfix. Applied patch for create_folder() and nested folders. Thanks to Erik Torsner.
----------------------------
revision 1.572
date: 2013/10/27 02:04:01; author: gilles; state: Exp; lines: +13 -8
Bug fix. Final statistics were avoided for newly created folders.
----------------------------
revision 1.571
date: 2013/10/25 14:34:27; author: gilles; state: Exp; lines: +58 -20
Added --folderfirst <string> : Sync this folder first. --folderfirst "Work"
Added --folderlast <string> : Sync this folder last. --folderlast "[Gmail]/All Mail"
--folderlast <string> : then this one, etc.
----------------------------
revision 1.570
date: 2013/10/25 12:52:02; author: gilles; state: Exp; lines: +7 -7
--delete2foldersonly Junk example.
----------------------------
revision 1.569
date: 2013/10/16 21:58:17; author: gilles; state: Exp; lines: +125 -39
Fixed bug on Windows with --tmpdir "E:\TEMP". The colon was badly converted to _, ending with "E_\TEMP".
The fix also automatically moves the old cache to the new one if the new does not exist yet.

125
FAQ
View File

@ -1,5 +1,5 @@
#!/bin/cat
# $Id: FAQ,v 1.150 2013/10/17 00:55:53 gilles Exp gilles $
# $Id: FAQ,v 1.161 2013/12/25 03:25:18 gilles Exp gilles $
+------------------+
| FAQ for imapsync |
@ -116,6 +116,7 @@ events via IMAP. In other words, messages synced by imapsync from
Calendar or Contacts folders are not used by email servers to set
or get the contacts or calendars.
No way via IMAP, no way via imapsync.
See next question.
=======================================================================
Q. How can I copy or synchronize Calendars or Contacts?
@ -361,14 +362,25 @@ Fixing the long path problem directly in imapsync is in the TODO file.
=======================================================================
Q. How can I try imapsync with latest Mail::IMAPClient 3.xx perl module?
R. The answer R2 deals with any Perl module use.
Three solutions at least.
R1 - Look at the script named i3 in the tarball, it can be used to
run imapsync with included Mail-IMAPClient-3.33/ wherever you
R1 - Look at the script named "i3" in the tarball, it can be used to
run imapsync with the included Mail-IMAPClient-3.35/ wherever you
unpacked the imapsync tarball
R2 - Download latest Mail::IMAPClient 3.xx at
http://search.cpan.org/dist/Mail-IMAPClient/
R2 Run:
perl -MCPAN -e "install Mail::IMAPClient"
or
cpan -i Mail::IMAPClient
R3 If you want to install the Perl module locally in a directory
- Download latest Mail::IMAPClient 3.xx at
http://search.cpan.org/dist/Mail-IMAPClient/
- untar it anywhere:
tar xzvf Mail-IMAPClient-3.xx.tar.gz
@ -377,10 +389,10 @@ R2 - Download latest Mail::IMAPClient 3.xx at
- run imapsync with perl and -I option tailing to use the perl
module Mail-IMAPClient-3.xx. Example:
perl -I./Mail-IMAPClient-3.33/lib ./imapsync ...
perl -I./Mail-IMAPClient-3.35/lib ./imapsync ...
or if imapsync is in directory /path/
perl -I./Mail-IMAPClient-3.33/lib /path/imapsync ...
perl -I./Mail-IMAPClient-3.35/lib /path/imapsync ...
=======================================================================
@ -388,6 +400,14 @@ Q. How can I use imapsync with Mail::IMAPClient 2.2.9 perl module?
R. Mail::IMAPClient 2.2.9 is no longer supported.
=======================================================================
Q. I get "Out of memory" errors. How to fix that?
R. Usually "Out of memory" errors are related to old days,
to old Mail::IMAPClient module releases, before 3.26.
Look at imapsync output first lines to get the Mail::IMAPClient release used.
Then upgrade Mail::IMAPClient Perl module.
=======================================================================
Q. Can I use imapsync to migrate emails from pop3 server to imap server?
@ -401,6 +421,13 @@ the same mailboxes. They serve the same INBOX
(imap serves INBOX and several other folders, pop3 serves only INBOX)
So have a try with imapsync on the same host1.
=======================================================================
Q. Folders are not created on host2. What happens?
R. Do you use IMAP or POP3 with your client software?
It looks like you use POP3 instead of IMAP, POP3 has only INBOX.
=======================================================================
Q. I am interested in creating a local clone of the IMAP on a LAN
server for faster synchronisations, email will always be delivered
@ -586,6 +613,19 @@ Choose X as you wish: _ or SEP or
any string (including the empty string).
=======================================================================
Q. Is it possible to sync also the UIDL of the POP3 server?
R. imapsync does not POP3 but I think you mean UID in IMAP.
See next question.
=======================================================================
Q. Is it possible to sync also the UIDs of the IMAP server?
UIDs in IMAP are chosen and created by the servers, not by the clients,
imapsync is a client. So UIDs can not be synced by any method,
unless the server is duplicated as is.
=======================================================================
Q. The option --subscribe does not seem to work
@ -1515,6 +1555,44 @@ format issues. And now it works fine. (Thanks to Hansjoerg.Maurer)
=======================================================================
=======================================================================
Q. From XXX to Exchange 2013 or Office365 read receipts are all resent
again after a sync. Even for old messages. How can I fix that?
R. imapsync can remove the header containing this read receipt request.
On Unix, add:
--regexmess 's{\A(.*?(?! ^$))(^Disposition-Notification-To:.*?\n)}{$1}gxms'
On Windows, add:
--regexmess "s{\A(.*?(?! ^$))(^Disposition-Notification-To:.*?\n)}{$1}gxms"
Since those read receipts should be sent for unseen messages going
to a seen state after the migration, you could be strict and apply
the regex only to seen messages.
Selecting seen message can be done with:
imapsync ... --search1 "SEEN" --regexmess "..."
Of course a second run has to be run without the --regexmess for
unseen messages:
imapsync ... --search1 "SEEN"
If you want to keep the header content and still suppress read receipts
then use the following instead, it adds a prefix "X-" to "Disposition-Notification-To:"
--regexmess 's{\A(.*?(?! ^$))^Disposition-Notification-To:(.*?)$}{$1X-Disposition-Notification-To:$2}igxms'
The small regex remove the header Disposition-Notification-To, the long one
replace it so users can still see messages had a Disposition-Notification-To
header before.
I will add an option to set this regex.
Thanks to David Karnowski for pointing and solving this issue.
=======================================================================
Q. From XXX to Exchange 2013 or Office365 I get this error message
sometimes: "BAD Command Argument Error 11"
@ -1539,6 +1617,33 @@ R. This error message comes from Exchange IMAP server when it
imapsync ... --maxlinelength 1000
Have also in mind that Exchange closes the connection after 10 errors
encountered so you might also see "BYE Connection closed" errors from
Exchange, which means Exchange leaves the session and say goodbye,
come back later. Rerun a sync then.
=======================================================================
Q. From XXX to Exchange 2010 or 2013 or Office365 the flag Flagged does
not seem to be well synced.
R. Use the following trick. Run imapsync twice, one with --regexflag
and one without, like this:
1) imapsync ... --regexflag "s/\\Flagged//g"
2) imapsync ...
You can add --debugflags if you want to see what imapsync gets and
does in details with flags.
The magic of this trick is on ignoring the \Flagged flag on the first
sync and setting it on the second sync, with STORE instead of APPEND.
This Exchange bug seems that Exchange gets and sets well the Flagged
flag with APPEND in IMAP but then it forgets it with other protocols;
With STORE it sets and gets the "\Flagged" flag everywhere.
Thanks to Dave Murray and Simon Savva for reporting and solving
this issue.
=======================================================================
Q. From Zimbra to XXX
@ -1625,7 +1730,9 @@ See http://support.google.com/a/bin/answer.py?hl=en&answer=1071518
--regextrans2 "s/[ ]+/_/g" is there to convert blank characters not
accepted by gmail to character _ underscore. In fact only leading
and trailing blank characters are problems with gmail.
and trailing blank characters are problems with gmail, and
also succesive blank ending whith the IMAP error
"NO [CANNOT] Folder contains excess whitespace (Failure)"
--regextrans2 "s/[\^]/_/g" is mandatory. It converts, since
not accepted by gmail, character ^ to character _ underscore.

133
INSTALL
View File

@ -1,7 +1,7 @@
# $Id: INSTALL,v 1.31 2013/09/28 11:11:48 gilles Exp gilles $
# $Id: INSTALL,v 1.33 2013/12/25 03:25:18 gilles Exp gilles $
#
# INSTALL file for imapsync
# imapsync : IMAP sync or copy tool.
# imapsync : IMAP sync and migrate tool.
INTRODUCTION
------------
@ -31,16 +31,22 @@ a) Simplest way:
- Buy imapsync.exe at http://imapsync.lamiral.info/
- Run imapsync.exe in a command prompt (execute cmd.exe).
- Run imapsync.exe in a command prompt (execute cmd.exe)
but I suggest the next process, I use it myself.
- Or simpler, look at the batch file at
http://imapsync.lamiral.info/examples/imapsync_example.bat
and replace the parameters with your values
then run the batch file with a double-click.
It is simpler to edit a batch file with notepad than
the command line in dos mode.
- Since it is simpler to edit a batch file with notepad than
the command line in DOS mode:
b) Hard way:
a) Look at the batch file at
http://imapsync.lamiral.info/examples/imapsync_example.bat
b) Take it and put this batch file in the same directory as imapsync.exe
c) Edit this batch file with notepad and replace the parameters
with your own values
d) Run the batch file with a double-click.
b) Hard way. It is the hard way because it installs all software
dependencies. The way for changing imapsync if needed.
- Get imapsync-x.xx.tgz
- Install Perl if it isn't already installed.
@ -69,21 +75,28 @@ You need :
Get Perl here:
http://www.perl.org/
- Some perl modules. To verify you have
all modules in one command, just run:
- Some perl modules. To verify in one command that you have
all needed modules, just run:
perl -c imapsync
The good answer is "imapsync syntax OK".
Any other output will list the missing modules in the
Perl paths (it then talks about @INC variable).
Here is some individual module help:
- Perl Mail::IMAPClient module
- To check if your system has Perl Mail::IMAPClient module
try :
perl -mMail::IMAPClient -e ''
Get the latest Mail::IMAPClient module here:
It should print nothing, nothing printed means Mail::IMAPClient
is already installed on your system.
If the module Mail::IMAPClient is not on the system,
you can use a copy included in the imapsync tarball
or get the latest Mail::IMAPClient module here:
http://search.cpan.org/dist/Mail-IMAPClient/
I use always the latest Mail-IMAPClient-3.xx
@ -92,18 +105,15 @@ Here is some individual module help:
perl -mMail::IMAPClient -e 'print $Mail::IMAPClient::VERSION, "\n"'
New Mail-IMAPClient-3.xx works very well with imapsync,
Use at least Mail-IMAPClient-3.25 (previous may bug).
Don't hesitate to use latest Mail-IMAPClient-3.xx
(3.xx >= 3.34 at the time of this writing)
Use at least Mail-IMAPClient-3.25 (previous releases may bug).
Do not hesitate to use latest Mail-IMAPClient-3.xx
(3.xx >= 3.35 at the time of this writing)
Look at the script named "i3" in the tarball, it can be used to
run imapsync with included Mail-IMAPClient-3.34/ wherever you
Look at the shell script named "i3" in the tarball, it can be used to
run imapsync with included Mail-IMAPClient-3.35/ wherever you
unpacked the imapsync tarball.
- Perl Digest::MD5 module.
try:
- Digest::MD5
perl -mDigest::MD5 -e ""
http://search.cpan.org/
@ -118,66 +128,87 @@ Here is some individual module help:
- IO::Socket::SSL
perl -mIO::Socket::SSL -e ""
- File::Spec
perl -mFile::Spec -e ""
- File::Path
perl -mFile::Path -e ""
- Perl Digest::HMAC_MD5 module
- Digest::HMAC_MD5
Good for non plain text password over network.
perl -mDigest::HMAC_MD5 -e ""
- Perl Authen::NTLM
- Authen::NTLM
perl -mAuthen::NTLM -e ""
- Perl Time::HiRes
- Time::HiRes
perl -mTime::HiRes -e ""
- Perl Data::Uniqid
- Data::Uniqid
perl -mData::Uniqid -e ""
- Perl URI::Escape
- URI::Escape
perl -mURI::Escape -e ""
- File::Copy::Recursive
perl -mFile::Copy::Recursive -e ""
Test everything in one command:
perl -mMail::IMAPClient -mDigest::MD5 -mTerm::ReadKey -mIO::Socket::SSL \
-mFile::Spec -mDigest::HMAC_MD5 -mAuthen::NTLM -e -mTime::HiRes \
-mDigest::HMAC_MD5 -mAuthen::NTLM -e -mTime::HiRes \
-mData::Uniqid -mURI::Escape ""
You can install easily those Perl modules in latest release via the
following commands (with root permissions)
perl -MCPAN -e "install Mail::IMAPClient"
perl -MCPAN -e "install Digest::MD5"
perl -MCPAN -e "install Term::ReadKey"
perl -MCPAN -e "install IO::Socket::SSL"
perl -MCPAN -e "install File::Spec"
perl -MCPAN -e "install Digest::HMAC_MD5"
perl -MCPAN -e "install Authen::NTLM"
perl -MCPAN -e "install Time::HiRes"
perl -MCPAN -e "install Data::Uniqid"
perl -MCPAN -e "install URI::Escape"
perl -MCPAN -e "install File::Copy::Recursive"
perl -MCPAN -e "install Data::Uniqid"
perl -MCPAN -e "install Authen::NTLM"
You can install them easily too by using the standard install
You can also install them easily too by using the standard install
command on your system if the packages have been made on it
(so you may not have the latest but most of the time it
doesn't care).
Modules Authen::NTLM, Data::Uniqid may be not available
this way since I haven't find them on Ubuntu.
Modules
Authen::NTLM
Data::Uniqid
may be not available this distribution way since I haven't find them
on Ubuntu nor on Mandriva.
Example on Debian/Ubuntu:
On Debian/Ubuntu:
aptitude install libmail-imapclient-perl # Mail::IMAPClient
aptitude install libdigest-md5-file-perl # Digest::MD5
aptitude install libterm-readkey-perl # Term::ReadKey
aptitude install libio-socket-ssl-perl # IO::Socket::SSL
aptitude install libfile-spec-perl # File::Spec
aptitude install libdigest-hmac-perl # Digest::HMAC_MD5 Digest::HMAC_SHA1
aptitude install libmail-imapclient-perl # Mail::IMAPClient
aptitude install libterm-readkey-perl # Term::ReadKey
aptitude install libio-socket-ssl-perl # IO::Socket::SSL
aptitude install libdigest-hmac-perl # Digest::HMAC_MD5 Digest::HMAC_SHA1
aptitude install liburi-perl # URI::Escape
aptitude install libfile-copy-recursive-perl # File::Copy::Recursive
On Mandriva:
urpmi perl-Mail-IMAPClient # Mail::IMAPClient
urpmi perl-Term-ReadKey # Term::ReadKey
urpmi perl-IO-Socket-SSL # IO::Socket::SSL
urpmi perl-Digest-HMAC # Digest::HMAC_MD5 Digest::HMAC_SHA1
urpmi perl-URI # URI::Escape
urpmi perl-File-Copy-Recursive # File::Copy::Recursive
On CentOS (thanks to Ralf Hauber)
Install RPM Repository: Fedora Epel
See http://pkgs.org/centos-6-rhel-6/epel-i386/perl-Data-Uniqid-0.12-2.el6.noarch.rpm.html
wget http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
rpm -Uvh epel-release*rpm
yum install perl-Mail-IMAPClient
yum install "perl(Term::ReadKey)"
yum install "perl(Authen::NTLM)"
yum install perl-Data-Uniqid
yum install perl-File-Copy-Recursive
INSTALLING on Unix

View File

@ -1,5 +1,5 @@
# $Id: Makefile,v 1.132 2013/10/17 00:55:16 gilles Exp gilles $
# $Id: Makefile,v 1.139 2013/12/25 11:36:53 gilles Exp gilles $
.PHONY: help usage all
@ -33,7 +33,7 @@ VERSION=$(shell perl -I$(IMAPClient) ./imapsync --version)
VERSION_EXE=$(shell cat ./VERSION_EXE)
HELLO=$(shell date;uname -a)
IMAPClient_3xx=./W/Mail-IMAPClient-3.34/lib
IMAPClient_3xx=./W/Mail-IMAPClient-3.35/lib
IMAPClient=$(IMAPClient_3xx)
hello:
@ -126,7 +126,7 @@ test_quick_3xx: imapsync tests.sh
testv3: imapsync tests.sh
CMD_PERL='perl -I./$(IMAPClient_3xx)' /usr/bin/time sh tests.sh
touch .test_3xx
./i3 --version >> .test_3xx
testv: testv3
@ -136,7 +136,7 @@ tests: test
.test_3xx: imapsync tests.sh
CMD_PERL='perl -I./$(IMAPClient_3xx)' /usr/bin/time sh tests.sh 1>/dev/null
touch .test_3xx
./i3 --version >> .test_3xx
testf: clean_test test
@ -167,8 +167,6 @@ tests_win32_dev3: dosify_bat
scp imapsync W/test3.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/'
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/test3.bat'
test_imapsync_exe: dosify_bat
scp W/test_exe.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/'
time ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/test_exe.bat'
@ -259,8 +257,8 @@ tarball: .tarball
touch .tarball
DO_IT := $(shell test -f ./dist/path_$(VERSION).txt || makepasswd --chars 4 > ./dist/path_$(VERSION).txt)
DIST_SECRET := $(shell cat ./dist/path_$(VERSION).txt)
DO_IT := $(shell test -d dist && { test -f ./dist/path_$(VERSION).txt || makepasswd --chars 4 > ./dist/path_$(VERSION).txt ; } )
DIST_SECRET := $(shell test -d dist && cat ./dist/path_$(VERSION).txt)
DIST_PATH := ./dist/$(DIST_SECRET)
lalala:
@ -295,11 +293,11 @@ dist_prepa_exe: imapsync.exe
ks:
rsync -avHz --delete --exclude imapsync.exe \
. imapsync@ks.lamiral.info:public_html/imapsync/
. gilles@ks.lamiral.info:public_html/imapsync/
ksa:
rsync -avHz --delete -P \
. imapsync@ks.lamiral.info:public_html/imapsync/
. gilles@ks.lamiral.info:public_html/imapsync/
upload_ks: ci tarball
rsync -lptvHzP $(PUBLIC_FILES) \
@ -345,10 +343,14 @@ upload_lfo:
/home/gilles/public_html/www.linux-france.org/html/prj/imapsync/.htaccess
sh ~/memo/lfo-rsync
upload_index: FAQ LICENSE CREDITS TUTORIAL.html GOOD_PRACTICES.html W/*.bat examples/*.bat examples/sync_loop_unix.sh index.shtml
rcsdiff index.shtml FAQ LICENSE CREDITS W/*.bat examples/*.bat index.shtml
.valid.index.shtml: index.shtml
validate --verbose index.shtml
touch .valid.index.shtml
upload_index: .valid.index.shtml FAQ LICENSE CREDITS TUTORIAL.html GOOD_PRACTICES.html W/*.bat examples/*.bat examples/*.sh
rcsdiff index.shtml FAQ LICENSE CREDITS W/*.bat examples/*.bat index.shtml
rsync -avH index.shtml FAQ NOLIMIT LICENSE CREDITS TUTORIAL.html GOOD_PRACTICES.html root@ks.lamiral.info:/var/www/imapsync/
rsync -avH W/*.bat root@ks.lamiral.info:/var/www/imapsync/W/
rsync -avH examples/*.bat examples/sync_loop_unix.sh root@ks.lamiral.info:/var/www/imapsync/examples/
rsync -avH examples/*.bat examples/*.sh root@ks.lamiral.info:/var/www/imapsync/examples/

6
README
View File

@ -4,7 +4,7 @@ NAME
More than 52 different IMAP server softwares supported with success, few
failures.
$Revision: 1.569 $
$Revision: 1.580 $
SYNOPSIS
To synchronize imap account "foo" on "imap.truc.org" to imap account
@ -353,7 +353,7 @@ IMAP SERVERS
- Gimap (Gmail imap)
- GMX IMAP4 StreamProxy.
- Groupwise IMAP (Novell) 6.x and 7.0. Buggy so see the FAQ.
- hMailServer 5.3.3 [host2], 4.4.1 [host1] (see FAQ)
- hMailServer 5.40-B1950 [host12], 5.3.3 [host2], 4.4.1 [host1] (see FAQ)
- IceWarp Server 10.4.5 [host1] (http://www.icewarp.com/)
- iPlanet Messaging server 4.15, 5.1, 5.2
- IMail 7.15 (Ipswitch/Win2003), 8.12, 11.03 [host1]
@ -471,5 +471,5 @@ SIMILAR SOFTWARES
Feedback (good or bad) will often be welcome.
$Id: imapsync,v 1.569 2013/10/16 21:58:17 gilles Exp gilles $
$Id: imapsync,v 1.580 2013/12/25 02:52:36 gilles Exp gilles $

20
TODO
View File

@ -1,5 +1,5 @@
#!/bin/cat
# $Id: TODO,v 1.123 2013/08/16 00:49:52 gilles Exp gilles $
# $Id: TODO,v 1.124 2013/12/25 03:04:53 gilles Exp gilles $
TODO file for imapsync
----------------------
@ -17,15 +17,17 @@ http://www.yippiemove.com/
http://www.migrationwiz.com/
http://www.microsoft.com/download/en/details.aspx?id=1329 "Microsoft Transporter Suite"
Write --disarm_read_receipts that does:
--regexmess 's{\A(.*?(?! ^$))^Disposition-Notification-To:(.*?)$}{$1X-Disposition-Notification-To:$2}igxms'
May be apply it only to UNSEEN messages.
Write --max_messages_per_second and --max_bytes_per_second for staying under Microsoft's throttling policies.
Convert folder names to utf-8 and print them next to the uft-7 ones.
Look at imapsync/W/learn/
./imap_utf7 data_utf7
DONE. Inform about --addheader when the problem occurs "(no wanted headers so we ignore this message)"
DONE. Print the timeout value.
DONE. Inform --timeout is is seconds.
Add an exit value when exiting because of --exitwhenover
The goal is to know easily why to restart later.
@ -165,6 +167,12 @@ http://asg.web.cmu.edu/cyrus/download/imapd/altnamespace.html
===========================================================================
DONE. Inform about --addheader when the problem occurs "(no wanted headers so we ignore this message)"
DONE. Print the timeout value.
DONE. Inform --timeout is is seconds.
DONE. Add an entry to http://lsm.qqx.org/lsm/
See lsm.imapsync

View File

@ -1 +1 @@
1.569
1.580

View File

@ -1 +1 @@
1.569
1.580

View File

@ -258,3 +258,8 @@
1381970545 END 1.569 : jeudi 17 octobre 2013, 02:42:25 (UTC+0200)
1381974866 BEGIN 1.569 : jeudi 17 octobre 2013, 03:54:26 (UTC+0200)
1381975685 END 1.569 : jeudi 17 octobre 2013, 04:08:05 (UTC+0200)
1383010060 BEGIN 1.574 : mardi 29 octobre 2013, 02:27:40 (UTC+0100)
1383012576 END 1.574 : mardi 29 octobre 2013, 03:09:36 (UTC+0100)
1387941690 BEGIN 1.580 : mercredi 25 décembre 2013, 04:21:30 (UTC+0100)
1387967067 BEGIN 1.580 : mercredi 25 décembre 2013, 11:24:28 (UTC+0100)
1387967901 END 1.580 : mercredi 25 décembre 2013, 11:38:21 (UTC+0100)

View File

@ -1,874 +0,0 @@
# This Makefile is for the Mail::IMAPClient extension to perl.
#
# It was generated automatically by MakeMaker version
# 6.55_02 (Revision: 65502) from the contents of
# Makefile.PL. Don't edit this file, edit Makefile.PL instead.
#
# ANY CHANGES MADE HERE WILL BE LOST!
#
# MakeMaker ARGV: ()
#
# MakeMaker Parameters:
# ABSTRACT => q[IMAP4 client library]
# AUTHOR => q[Phil Pearl (Lobbes) <phil@zimbra.com>]
# BUILD_REQUIRES => { }
# LICENSE => q[perl]
# META_MERGE => { resources=>{ repository=>{ web=>q[http://sourceforge.net/p/mail-imapclient/git/], url=>q[git://git.code.sf.net/p/mail-imapclient/git], type=>q[git] }, homepage=>q[http://sourceforge.net/projects/mail-imapclient/], bugtracker=>{ web=>q[http://rt.cpan.org/Public/Dist/Display.html?Name=Mail-IMAPClient], mailto=>q[bug-Mail-IMAPClient@rt.cpan.org] } } }
# MIN_PERL_VERSION => q[5.008]
# NAME => q[Mail::IMAPClient]
# PREREQ_PM => { IO::File=>q[0], Fcntl=>q[0], IO::Socket::INET=>q[1.26], Carp=>q[0], Parse::RecDescent=>q[1.94], List::Util=>q[0], Test::More=>q[0], MIME::Base64=>q[0], IO::Socket=>q[0], IO::Select=>q[0], File::Temp=>q[0], Errno=>q[0] }
# VERSION_FROM => q[lib/Mail/IMAPClient.pm]
# clean => { FILES=>q[test.txt] }
# --- MakeMaker post_initialize section:
# --- MakeMaker const_config section:
# These definitions are from config.sh (via /usr/lib/perl/5.10/Config.pm).
# They may have been overridden via Makefile.PL or on the command line.
AR = ar
CC = cc
CCCDLFLAGS = -fPIC
CCDLFLAGS = -Wl,-E
DLEXT = so
DLSRC = dl_dlopen.xs
EXE_EXT =
FULL_AR = /usr/bin/ar
LD = cc
LDDLFLAGS = -shared -O2 -g -L/usr/local/lib -fstack-protector
LDFLAGS = -fstack-protector -L/usr/local/lib
LIBC = /lib/libc-2.11.1.so
LIB_EXT = .a
OBJ_EXT = .o
OSNAME = linux
OSVERS = 2.6.42-37-generic
RANLIB = :
SITELIBEXP = /usr/local/share/perl/5.10.1
SITEARCHEXP = /usr/local/lib/perl/5.10.1
SO = so
VENDORARCHEXP = /usr/lib/perl5
VENDORLIBEXP = /usr/share/perl5
# --- MakeMaker constants section:
AR_STATIC_ARGS = cr
DIRFILESEP = /
DFSEP = $(DIRFILESEP)
NAME = Mail::IMAPClient
NAME_SYM = Mail_IMAPClient
VERSION = 3.34
VERSION_MACRO = VERSION
VERSION_SYM = 3_34
DEFINE_VERSION = -D$(VERSION_MACRO)=\"$(VERSION)\"
XS_VERSION = 3.34
XS_VERSION_MACRO = XS_VERSION
XS_DEFINE_VERSION = -D$(XS_VERSION_MACRO)=\"$(XS_VERSION)\"
INST_ARCHLIB = blib/arch
INST_SCRIPT = blib/script
INST_BIN = blib/bin
INST_LIB = blib/lib
INST_MAN1DIR = blib/man1
INST_MAN3DIR = blib/man3
MAN1EXT = 1p
MAN3EXT = 3pm
INSTALLDIRS = site
DESTDIR =
PREFIX = /usr
PERLPREFIX = $(PREFIX)
SITEPREFIX = $(PREFIX)/local
VENDORPREFIX = $(PREFIX)
INSTALLPRIVLIB = $(PERLPREFIX)/share/perl/5.10
DESTINSTALLPRIVLIB = $(DESTDIR)$(INSTALLPRIVLIB)
INSTALLSITELIB = $(SITEPREFIX)/share/perl/5.10.1
DESTINSTALLSITELIB = $(DESTDIR)$(INSTALLSITELIB)
INSTALLVENDORLIB = $(VENDORPREFIX)/share/perl5
DESTINSTALLVENDORLIB = $(DESTDIR)$(INSTALLVENDORLIB)
INSTALLARCHLIB = $(PERLPREFIX)/lib/perl/5.10
DESTINSTALLARCHLIB = $(DESTDIR)$(INSTALLARCHLIB)
INSTALLSITEARCH = $(SITEPREFIX)/lib/perl/5.10.1
DESTINSTALLSITEARCH = $(DESTDIR)$(INSTALLSITEARCH)
INSTALLVENDORARCH = $(VENDORPREFIX)/lib/perl5
DESTINSTALLVENDORARCH = $(DESTDIR)$(INSTALLVENDORARCH)
INSTALLBIN = $(PERLPREFIX)/bin
DESTINSTALLBIN = $(DESTDIR)$(INSTALLBIN)
INSTALLSITEBIN = $(SITEPREFIX)/bin
DESTINSTALLSITEBIN = $(DESTDIR)$(INSTALLSITEBIN)
INSTALLVENDORBIN = $(VENDORPREFIX)/bin
DESTINSTALLVENDORBIN = $(DESTDIR)$(INSTALLVENDORBIN)
INSTALLSCRIPT = $(PERLPREFIX)/bin
DESTINSTALLSCRIPT = $(DESTDIR)$(INSTALLSCRIPT)
INSTALLSITESCRIPT = $(SITEPREFIX)/bin
DESTINSTALLSITESCRIPT = $(DESTDIR)$(INSTALLSITESCRIPT)
INSTALLVENDORSCRIPT = $(VENDORPREFIX)/bin
DESTINSTALLVENDORSCRIPT = $(DESTDIR)$(INSTALLVENDORSCRIPT)
INSTALLMAN1DIR = $(PERLPREFIX)/share/man/man1
DESTINSTALLMAN1DIR = $(DESTDIR)$(INSTALLMAN1DIR)
INSTALLSITEMAN1DIR = $(SITEPREFIX)/man/man1
DESTINSTALLSITEMAN1DIR = $(DESTDIR)$(INSTALLSITEMAN1DIR)
INSTALLVENDORMAN1DIR = $(VENDORPREFIX)/share/man/man1
DESTINSTALLVENDORMAN1DIR = $(DESTDIR)$(INSTALLVENDORMAN1DIR)
INSTALLMAN3DIR = $(PERLPREFIX)/share/man/man3
DESTINSTALLMAN3DIR = $(DESTDIR)$(INSTALLMAN3DIR)
INSTALLSITEMAN3DIR = $(SITEPREFIX)/man/man3
DESTINSTALLSITEMAN3DIR = $(DESTDIR)$(INSTALLSITEMAN3DIR)
INSTALLVENDORMAN3DIR = $(VENDORPREFIX)/share/man/man3
DESTINSTALLVENDORMAN3DIR = $(DESTDIR)$(INSTALLVENDORMAN3DIR)
PERL_LIB = /usr/share/perl/5.10
PERL_ARCHLIB = /usr/lib/perl/5.10
LIBPERL_A = libperl.a
FIRST_MAKEFILE = Makefile
MAKEFILE_OLD = Makefile.old
MAKE_APERL_FILE = Makefile.aperl
PERLMAINCC = $(CC)
PERL_INC = /usr/lib/perl/5.10/CORE
PERL = /usr/bin/perl
FULLPERL = /usr/bin/perl
ABSPERL = $(PERL)
PERLRUN = $(PERL)
FULLPERLRUN = $(FULLPERL)
ABSPERLRUN = $(ABSPERL)
PERLRUNINST = $(PERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
FULLPERLRUNINST = $(FULLPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
ABSPERLRUNINST = $(ABSPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
PERL_CORE = 0
PERM_DIR = 755
PERM_RW = 644
PERM_RWX = 755
MAKEMAKER = /usr/share/perl/5.10/ExtUtils/MakeMaker.pm
MM_VERSION = 6.55_02
MM_REVISION = 65502
# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle).
# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle)
# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar)
# DLBASE = Basename part of dynamic library. May be just equal BASEEXT.
MAKE = make
FULLEXT = Mail/IMAPClient
BASEEXT = IMAPClient
PARENT_NAME = Mail
DLBASE = $(BASEEXT)
VERSION_FROM = lib/Mail/IMAPClient.pm
OBJECT =
LDFROM = $(OBJECT)
LINKTYPE = dynamic
BOOTDEP =
# Handy lists of source code files:
XS_FILES =
C_FILES =
O_FILES =
H_FILES =
MAN1PODS =
MAN3PODS = lib/Mail/IMAPClient.pod \
lib/Mail/IMAPClient/BodyStructure.pm \
lib/Mail/IMAPClient/BodyStructure/Parse.pod \
lib/Mail/IMAPClient/MessageSet.pm \
lib/Mail/IMAPClient/Thread.pod
# Where is the Config information that we are using/depend on
CONFIGDEP = $(PERL_ARCHLIB)$(DFSEP)Config.pm $(PERL_INC)$(DFSEP)config.h
# Where to build things
INST_LIBDIR = $(INST_LIB)/Mail
INST_ARCHLIBDIR = $(INST_ARCHLIB)/Mail
INST_AUTODIR = $(INST_LIB)/auto/$(FULLEXT)
INST_ARCHAUTODIR = $(INST_ARCHLIB)/auto/$(FULLEXT)
INST_STATIC =
INST_DYNAMIC =
INST_BOOT =
# Extra linker info
EXPORT_LIST =
PERL_ARCHIVE =
PERL_ARCHIVE_AFTER =
TO_INST_PM = lib/Mail/IMAPClient.pm \
lib/Mail/IMAPClient.pod \
lib/Mail/IMAPClient/BodyStructure.pm \
lib/Mail/IMAPClient/BodyStructure/Parse.grammar \
lib/Mail/IMAPClient/BodyStructure/Parse.pm \
lib/Mail/IMAPClient/BodyStructure/Parse.pod \
lib/Mail/IMAPClient/MessageSet.pm \
lib/Mail/IMAPClient/Thread.grammar \
lib/Mail/IMAPClient/Thread.pm \
lib/Mail/IMAPClient/Thread.pod
PM_TO_BLIB = lib/Mail/IMAPClient/BodyStructure/Parse.pm \
blib/lib/Mail/IMAPClient/BodyStructure/Parse.pm \
lib/Mail/IMAPClient/Thread.pm \
blib/lib/Mail/IMAPClient/Thread.pm \
lib/Mail/IMAPClient/BodyStructure/Parse.grammar \
blib/lib/Mail/IMAPClient/BodyStructure/Parse.grammar \
lib/Mail/IMAPClient.pod \
blib/lib/Mail/IMAPClient.pod \
lib/Mail/IMAPClient/Thread.pod \
blib/lib/Mail/IMAPClient/Thread.pod \
lib/Mail/IMAPClient/MessageSet.pm \
blib/lib/Mail/IMAPClient/MessageSet.pm \
lib/Mail/IMAPClient/Thread.grammar \
blib/lib/Mail/IMAPClient/Thread.grammar \
lib/Mail/IMAPClient/BodyStructure.pm \
blib/lib/Mail/IMAPClient/BodyStructure.pm \
lib/Mail/IMAPClient/BodyStructure/Parse.pod \
blib/lib/Mail/IMAPClient/BodyStructure/Parse.pod \
lib/Mail/IMAPClient.pm \
blib/lib/Mail/IMAPClient.pm
# --- MakeMaker platform_constants section:
MM_Unix_VERSION = 6.55_02
PERL_MALLOC_DEF = -DPERL_EXTMALLOC_DEF -Dmalloc=Perl_malloc -Dfree=Perl_mfree -Drealloc=Perl_realloc -Dcalloc=Perl_calloc
# --- MakeMaker tool_autosplit section:
# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
AUTOSPLITFILE = $(ABSPERLRUN) -e 'use AutoSplit; autosplit($$ARGV[0], $$ARGV[1], 0, 1, 1)' --
# --- MakeMaker tool_xsubpp section:
# --- MakeMaker tools_other section:
SHELL = /bin/sh
CHMOD = chmod
CP = cp
MV = mv
NOOP = $(TRUE)
NOECHO = @
RM_F = rm -f
RM_RF = rm -rf
TEST_F = test -f
TOUCH = touch
UMASK_NULL = umask 0
DEV_NULL = > /dev/null 2>&1
MKPATH = $(ABSPERLRUN) -MExtUtils::Command -e 'mkpath' --
EQUALIZE_TIMESTAMP = $(ABSPERLRUN) -MExtUtils::Command -e 'eqtime' --
FALSE = false
TRUE = true
ECHO = echo
ECHO_N = echo -n
UNINST = 0
VERBINST = 0
MOD_INSTALL = $(ABSPERLRUN) -MExtUtils::Install -e 'install([ from_to => {@ARGV}, verbose => '\''$(VERBINST)'\'', uninstall_shadows => '\''$(UNINST)'\'', dir_mode => '\''$(PERM_DIR)'\'' ]);' --
DOC_INSTALL = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'perllocal_install' --
UNINSTALL = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'uninstall' --
WARN_IF_OLD_PACKLIST = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'warn_if_old_packlist' --
MACROSTART =
MACROEND =
USEMAKEFILE = -f
FIXIN = $(ABSPERLRUN) -MExtUtils::MY -e 'MY->fixin(shift)' --
# --- MakeMaker makemakerdflt section:
makemakerdflt : all
$(NOECHO) $(NOOP)
# --- MakeMaker dist section:
TAR = tar
TARFLAGS = cvf
ZIP = zip
ZIPFLAGS = -r
COMPRESS = gzip --best
SUFFIX = .gz
SHAR = shar
PREOP = $(NOECHO) $(NOOP)
POSTOP = $(NOECHO) $(NOOP)
TO_UNIX = $(NOECHO) $(NOOP)
CI = ci -u
RCS_LABEL = rcs -Nv$(VERSION_SYM): -q
DIST_CP = best
DIST_DEFAULT = tardist
DISTNAME = Mail-IMAPClient
DISTVNAME = Mail-IMAPClient-3.34
# --- MakeMaker macro section:
# --- MakeMaker depend section:
# --- MakeMaker cflags section:
# --- MakeMaker const_loadlibs section:
# --- MakeMaker const_cccmd section:
# --- MakeMaker post_constants section:
# --- MakeMaker pasthru section:
PASTHRU = LIBPERL_A="$(LIBPERL_A)"\
LINKTYPE="$(LINKTYPE)"\
PREFIX="$(PREFIX)"
# --- MakeMaker special_targets section:
.SUFFIXES : .xs .c .C .cpp .i .s .cxx .cc $(OBJ_EXT)
.PHONY: all config static dynamic test linkext manifest blibdirs clean realclean disttest distdir
# --- MakeMaker c_o section:
# --- MakeMaker xs_c section:
# --- MakeMaker xs_o section:
# --- MakeMaker top_targets section:
all :: pure_all manifypods
$(NOECHO) $(NOOP)
pure_all :: config pm_to_blib subdirs linkext
$(NOECHO) $(NOOP)
subdirs :: $(MYEXTLIB)
$(NOECHO) $(NOOP)
config :: $(FIRST_MAKEFILE) blibdirs
$(NOECHO) $(NOOP)
help :
perldoc ExtUtils::MakeMaker
# --- MakeMaker blibdirs section:
blibdirs : $(INST_LIBDIR)$(DFSEP).exists $(INST_ARCHLIB)$(DFSEP).exists $(INST_AUTODIR)$(DFSEP).exists $(INST_ARCHAUTODIR)$(DFSEP).exists $(INST_BIN)$(DFSEP).exists $(INST_SCRIPT)$(DFSEP).exists $(INST_MAN1DIR)$(DFSEP).exists $(INST_MAN3DIR)$(DFSEP).exists
$(NOECHO) $(NOOP)
# Backwards compat with 6.18 through 6.25
blibdirs.ts : blibdirs
$(NOECHO) $(NOOP)
$(INST_LIBDIR)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_LIBDIR)
$(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_LIBDIR)
$(NOECHO) $(TOUCH) $(INST_LIBDIR)$(DFSEP).exists
$(INST_ARCHLIB)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_ARCHLIB)
$(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_ARCHLIB)
$(NOECHO) $(TOUCH) $(INST_ARCHLIB)$(DFSEP).exists
$(INST_AUTODIR)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_AUTODIR)
$(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_AUTODIR)
$(NOECHO) $(TOUCH) $(INST_AUTODIR)$(DFSEP).exists
$(INST_ARCHAUTODIR)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR)
$(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_ARCHAUTODIR)
$(NOECHO) $(TOUCH) $(INST_ARCHAUTODIR)$(DFSEP).exists
$(INST_BIN)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_BIN)
$(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_BIN)
$(NOECHO) $(TOUCH) $(INST_BIN)$(DFSEP).exists
$(INST_SCRIPT)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_SCRIPT)
$(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_SCRIPT)
$(NOECHO) $(TOUCH) $(INST_SCRIPT)$(DFSEP).exists
$(INST_MAN1DIR)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_MAN1DIR)
$(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_MAN1DIR)
$(NOECHO) $(TOUCH) $(INST_MAN1DIR)$(DFSEP).exists
$(INST_MAN3DIR)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_MAN3DIR)
$(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_MAN3DIR)
$(NOECHO) $(TOUCH) $(INST_MAN3DIR)$(DFSEP).exists
# --- MakeMaker linkext section:
linkext :: $(LINKTYPE)
$(NOECHO) $(NOOP)
# --- MakeMaker dlsyms section:
# --- MakeMaker dynamic section:
dynamic :: $(FIRST_MAKEFILE) $(INST_DYNAMIC) $(INST_BOOT)
$(NOECHO) $(NOOP)
# --- MakeMaker dynamic_bs section:
BOOTSTRAP =
# --- MakeMaker dynamic_lib section:
# --- MakeMaker static section:
## $(INST_PM) has been moved to the all: target.
## It remains here for awhile to allow for old usage: "make static"
static :: $(FIRST_MAKEFILE) $(INST_STATIC)
$(NOECHO) $(NOOP)
# --- MakeMaker static_lib section:
# --- MakeMaker manifypods section:
POD2MAN_EXE = $(PERLRUN) "-MExtUtils::Command::MM" -e pod2man "--"
POD2MAN = $(POD2MAN_EXE)
manifypods : pure_all \
lib/Mail/IMAPClient/Thread.pod \
lib/Mail/IMAPClient/MessageSet.pm \
lib/Mail/IMAPClient/BodyStructure.pm \
lib/Mail/IMAPClient/BodyStructure/Parse.pod \
lib/Mail/IMAPClient.pod
$(NOECHO) $(POD2MAN) --section=$(MAN3EXT) --perm_rw=$(PERM_RW) \
lib/Mail/IMAPClient/Thread.pod $(INST_MAN3DIR)/Mail::IMAPClient::Thread.$(MAN3EXT) \
lib/Mail/IMAPClient/MessageSet.pm $(INST_MAN3DIR)/Mail::IMAPClient::MessageSet.$(MAN3EXT) \
lib/Mail/IMAPClient/BodyStructure.pm $(INST_MAN3DIR)/Mail::IMAPClient::BodyStructure.$(MAN3EXT) \
lib/Mail/IMAPClient/BodyStructure/Parse.pod $(INST_MAN3DIR)/Mail::IMAPClient::BodyStructure::Parse.$(MAN3EXT) \
lib/Mail/IMAPClient.pod $(INST_MAN3DIR)/Mail::IMAPClient.$(MAN3EXT)
# --- MakeMaker processPL section:
# --- MakeMaker installbin section:
# --- MakeMaker subdirs section:
# none
# --- MakeMaker clean_subdirs section:
clean_subdirs :
$(NOECHO) $(NOOP)
# --- MakeMaker clean section:
# Delete temporary files but do not touch installed files. We don't delete
# the Makefile here so a later make realclean still has a makefile to use.
clean :: clean_subdirs
- $(RM_F) \
*$(LIB_EXT) core \
core.[0-9] $(INST_ARCHAUTODIR)/extralibs.all \
core.[0-9][0-9] $(BASEEXT).bso \
pm_to_blib.ts core.[0-9][0-9][0-9][0-9] \
$(BASEEXT).x $(BOOTSTRAP) \
perl$(EXE_EXT) tmon.out \
*$(OBJ_EXT) pm_to_blib \
$(INST_ARCHAUTODIR)/extralibs.ld blibdirs.ts \
core.[0-9][0-9][0-9][0-9][0-9] *perl.core \
core.*perl.*.? $(MAKE_APERL_FILE) \
perl $(BASEEXT).def \
core.[0-9][0-9][0-9] mon.out \
lib$(BASEEXT).def perlmain.c \
perl.exe so_locations \
$(BASEEXT).exp
- $(RM_RF) \
test.txt blib
- $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) $(DEV_NULL)
# --- MakeMaker realclean_subdirs section:
realclean_subdirs :
$(NOECHO) $(NOOP)
# --- MakeMaker realclean section:
# Delete temporary files (via clean) and also delete dist files
realclean purge :: clean realclean_subdirs
- $(RM_F) \
$(MAKEFILE_OLD) $(FIRST_MAKEFILE)
- $(RM_RF) \
$(DISTVNAME)
# --- MakeMaker metafile section:
metafile : create_distdir
$(NOECHO) $(ECHO) Generating META.yml
$(NOECHO) $(ECHO) '--- #YAML:1.0' > META_new.yml
$(NOECHO) $(ECHO) 'name: Mail-IMAPClient' >> META_new.yml
$(NOECHO) $(ECHO) 'version: 3.34' >> META_new.yml
$(NOECHO) $(ECHO) 'abstract: IMAP4 client library' >> META_new.yml
$(NOECHO) $(ECHO) 'author:' >> META_new.yml
$(NOECHO) $(ECHO) ' - Phil Pearl (Lobbes) <phil@zimbra.com>' >> META_new.yml
$(NOECHO) $(ECHO) 'license: perl' >> META_new.yml
$(NOECHO) $(ECHO) 'distribution_type: module' >> META_new.yml
$(NOECHO) $(ECHO) 'configure_requires:' >> META_new.yml
$(NOECHO) $(ECHO) ' ExtUtils::MakeMaker: 0' >> META_new.yml
$(NOECHO) $(ECHO) 'build_requires:' >> META_new.yml
$(NOECHO) $(ECHO) ' ExtUtils::MakeMaker: 0' >> META_new.yml
$(NOECHO) $(ECHO) 'requires:' >> META_new.yml
$(NOECHO) $(ECHO) ' Carp: 0' >> META_new.yml
$(NOECHO) $(ECHO) ' Errno: 0' >> META_new.yml
$(NOECHO) $(ECHO) ' Fcntl: 0' >> META_new.yml
$(NOECHO) $(ECHO) ' File::Temp: 0' >> META_new.yml
$(NOECHO) $(ECHO) ' IO::File: 0' >> META_new.yml
$(NOECHO) $(ECHO) ' IO::Select: 0' >> META_new.yml
$(NOECHO) $(ECHO) ' IO::Socket: 0' >> META_new.yml
$(NOECHO) $(ECHO) ' IO::Socket::INET: 1.26' >> META_new.yml
$(NOECHO) $(ECHO) ' List::Util: 0' >> META_new.yml
$(NOECHO) $(ECHO) ' MIME::Base64: 0' >> META_new.yml
$(NOECHO) $(ECHO) ' Parse::RecDescent: 1.94' >> META_new.yml
$(NOECHO) $(ECHO) ' perl: 5.008' >> META_new.yml
$(NOECHO) $(ECHO) ' Test::More: 0' >> META_new.yml
$(NOECHO) $(ECHO) 'resources:' >> META_new.yml
$(NOECHO) $(ECHO) ' bugtracker:' >> META_new.yml
$(NOECHO) $(ECHO) ' mailto: bug-Mail-IMAPClient@rt.cpan.org' >> META_new.yml
$(NOECHO) $(ECHO) ' web: http://rt.cpan.org/Public/Dist/Display.html?Name=Mail-IMAPClient' >> META_new.yml
$(NOECHO) $(ECHO) ' homepage: http://sourceforge.net/projects/mail-imapclient/' >> META_new.yml
$(NOECHO) $(ECHO) ' repository:' >> META_new.yml
$(NOECHO) $(ECHO) ' type: git' >> META_new.yml
$(NOECHO) $(ECHO) ' url: git://git.code.sf.net/p/mail-imapclient/git' >> META_new.yml
$(NOECHO) $(ECHO) ' web: http://sourceforge.net/p/mail-imapclient/git/' >> META_new.yml
$(NOECHO) $(ECHO) 'no_index:' >> META_new.yml
$(NOECHO) $(ECHO) ' directory:' >> META_new.yml
$(NOECHO) $(ECHO) ' - t' >> META_new.yml
$(NOECHO) $(ECHO) ' - inc' >> META_new.yml
$(NOECHO) $(ECHO) 'generated_by: ExtUtils::MakeMaker version 6.55_02' >> META_new.yml
$(NOECHO) $(ECHO) 'meta-spec:' >> META_new.yml
$(NOECHO) $(ECHO) ' url: http://module-build.sourceforge.net/META-spec-v1.4.html' >> META_new.yml
$(NOECHO) $(ECHO) ' version: 1.4' >> META_new.yml
-$(NOECHO) $(MV) META_new.yml $(DISTVNAME)/META.yml
# --- MakeMaker signature section:
signature :
cpansign -s
# --- MakeMaker dist_basics section:
distclean :: realclean distcheck
$(NOECHO) $(NOOP)
distcheck :
$(PERLRUN) "-MExtUtils::Manifest=fullcheck" -e fullcheck
skipcheck :
$(PERLRUN) "-MExtUtils::Manifest=skipcheck" -e skipcheck
manifest :
$(PERLRUN) "-MExtUtils::Manifest=mkmanifest" -e mkmanifest
veryclean : realclean
$(RM_F) *~ */*~ *.orig */*.orig *.bak */*.bak *.old */*.old
# --- MakeMaker dist_core section:
dist : $(DIST_DEFAULT) $(FIRST_MAKEFILE)
$(NOECHO) $(ABSPERLRUN) -l -e 'print '\''Warning: Makefile possibly out of date with $(VERSION_FROM)'\''' \
-e ' if -e '\''$(VERSION_FROM)'\'' and -M '\''$(VERSION_FROM)'\'' < -M '\''$(FIRST_MAKEFILE)'\'';' --
tardist : $(DISTVNAME).tar$(SUFFIX)
$(NOECHO) $(NOOP)
uutardist : $(DISTVNAME).tar$(SUFFIX)
uuencode $(DISTVNAME).tar$(SUFFIX) $(DISTVNAME).tar$(SUFFIX) > $(DISTVNAME).tar$(SUFFIX)_uu
$(DISTVNAME).tar$(SUFFIX) : distdir
$(PREOP)
$(TO_UNIX)
$(TAR) $(TARFLAGS) $(DISTVNAME).tar $(DISTVNAME)
$(RM_RF) $(DISTVNAME)
$(COMPRESS) $(DISTVNAME).tar
$(POSTOP)
zipdist : $(DISTVNAME).zip
$(NOECHO) $(NOOP)
$(DISTVNAME).zip : distdir
$(PREOP)
$(ZIP) $(ZIPFLAGS) $(DISTVNAME).zip $(DISTVNAME)
$(RM_RF) $(DISTVNAME)
$(POSTOP)
shdist : distdir
$(PREOP)
$(SHAR) $(DISTVNAME) > $(DISTVNAME).shar
$(RM_RF) $(DISTVNAME)
$(POSTOP)
# --- MakeMaker distdir section:
create_distdir :
$(RM_RF) $(DISTVNAME)
$(PERLRUN) "-MExtUtils::Manifest=manicopy,maniread" \
-e "manicopy(maniread(),'$(DISTVNAME)', '$(DIST_CP)');"
distdir : create_distdir distmeta
$(NOECHO) $(NOOP)
# --- MakeMaker dist_test section:
disttest : distdir
cd $(DISTVNAME) && $(ABSPERLRUN) Makefile.PL
cd $(DISTVNAME) && $(MAKE) $(PASTHRU)
cd $(DISTVNAME) && $(MAKE) test $(PASTHRU)
# --- MakeMaker dist_ci section:
ci :
$(PERLRUN) "-MExtUtils::Manifest=maniread" \
-e "@all = keys %{ maniread() };" \
-e "print(qq{Executing $(CI) @all\n}); system(qq{$(CI) @all});" \
-e "print(qq{Executing $(RCS_LABEL) ...\n}); system(qq{$(RCS_LABEL) @all});"
# --- MakeMaker distmeta section:
distmeta : create_distdir metafile
$(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'eval { maniadd({q{META.yml} => q{Module meta-data (added by MakeMaker)}}) } ' \
-e ' or print "Could not add META.yml to MANIFEST: $${'\''@'\''}\n"' --
# --- MakeMaker distsignature section:
distsignature : create_distdir
$(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'eval { maniadd({q{SIGNATURE} => q{Public-key signature (added by MakeMaker)}}) } ' \
-e ' or print "Could not add SIGNATURE to MANIFEST: $${'\''@'\''}\n"' --
$(NOECHO) cd $(DISTVNAME) && $(TOUCH) SIGNATURE
cd $(DISTVNAME) && cpansign -s
# --- MakeMaker install section:
install :: pure_install doc_install
$(NOECHO) $(NOOP)
install_perl :: pure_perl_install doc_perl_install
$(NOECHO) $(NOOP)
install_site :: pure_site_install doc_site_install
$(NOECHO) $(NOOP)
install_vendor :: pure_vendor_install doc_vendor_install
$(NOECHO) $(NOOP)
pure_install :: pure_$(INSTALLDIRS)_install
$(NOECHO) $(NOOP)
doc_install :: doc_$(INSTALLDIRS)_install
$(NOECHO) $(NOOP)
pure__install : pure_site_install
$(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site
doc__install : doc_site_install
$(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site
pure_perl_install :: all
$(NOECHO) umask 022; $(MOD_INSTALL) \
$(INST_LIB) $(DESTINSTALLPRIVLIB) \
$(INST_ARCHLIB) $(DESTINSTALLARCHLIB) \
$(INST_BIN) $(DESTINSTALLBIN) \
$(INST_SCRIPT) $(DESTINSTALLSCRIPT) \
$(INST_MAN1DIR) $(DESTINSTALLMAN1DIR) \
$(INST_MAN3DIR) $(DESTINSTALLMAN3DIR)
$(NOECHO) $(WARN_IF_OLD_PACKLIST) \
$(SITEARCHEXP)/auto/$(FULLEXT)
pure_site_install :: all
$(NOECHO) umask 02; $(MOD_INSTALL) \
read $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist \
write $(DESTINSTALLSITEARCH)/auto/$(FULLEXT)/.packlist \
$(INST_LIB) $(DESTINSTALLSITELIB) \
$(INST_ARCHLIB) $(DESTINSTALLSITEARCH) \
$(INST_BIN) $(DESTINSTALLSITEBIN) \
$(INST_SCRIPT) $(DESTINSTALLSITESCRIPT) \
$(INST_MAN1DIR) $(DESTINSTALLSITEMAN1DIR) \
$(INST_MAN3DIR) $(DESTINSTALLSITEMAN3DIR)
$(NOECHO) $(WARN_IF_OLD_PACKLIST) \
$(PERL_ARCHLIB)/auto/$(FULLEXT)
pure_vendor_install :: all
$(NOECHO) umask 022; $(MOD_INSTALL) \
$(INST_LIB) $(DESTINSTALLVENDORLIB) \
$(INST_ARCHLIB) $(DESTINSTALLVENDORARCH) \
$(INST_BIN) $(DESTINSTALLVENDORBIN) \
$(INST_SCRIPT) $(DESTINSTALLVENDORSCRIPT) \
$(INST_MAN1DIR) $(DESTINSTALLVENDORMAN1DIR) \
$(INST_MAN3DIR) $(DESTINSTALLVENDORMAN3DIR)
doc_perl_install :: all
doc_site_install :: all
$(NOECHO) $(ECHO) Appending installation info to $(DESTINSTALLSITEARCH)/perllocal.pod
-$(NOECHO) umask 02; $(MKPATH) $(DESTINSTALLSITEARCH)
-$(NOECHO) umask 02; $(DOC_INSTALL) \
"Module" "$(NAME)" \
"installed into" "$(INSTALLSITELIB)" \
LINKTYPE "$(LINKTYPE)" \
VERSION "$(VERSION)" \
EXE_FILES "$(EXE_FILES)" \
>> $(DESTINSTALLSITEARCH)/perllocal.pod
doc_vendor_install :: all
uninstall :: uninstall_from_$(INSTALLDIRS)dirs
$(NOECHO) $(NOOP)
uninstall_from_perldirs ::
uninstall_from_sitedirs ::
$(NOECHO) $(UNINSTALL) $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist
uninstall_from_vendordirs ::
# --- MakeMaker force section:
# Phony target to force checking subdirectories.
FORCE :
$(NOECHO) $(NOOP)
# --- MakeMaker perldepend section:
# --- MakeMaker makefile section:
# We take a very conservative approach here, but it's worth it.
# We move Makefile to Makefile.old here to avoid gnu make looping.
$(FIRST_MAKEFILE) : Makefile.PL $(CONFIGDEP)
$(NOECHO) $(ECHO) "Makefile out-of-date with respect to $?"
$(NOECHO) $(ECHO) "Cleaning current config before rebuilding Makefile..."
-$(NOECHO) $(RM_F) $(MAKEFILE_OLD)
-$(NOECHO) $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD)
- $(MAKE) $(USEMAKEFILE) $(MAKEFILE_OLD) clean $(DEV_NULL)
$(PERLRUN) Makefile.PL
$(NOECHO) $(ECHO) "==> Your Makefile has been rebuilt. <=="
$(NOECHO) $(ECHO) "==> Please rerun the $(MAKE) command. <=="
$(FALSE)
# --- MakeMaker staticmake section:
# --- MakeMaker makeaperl section ---
MAP_TARGET = perl
FULLPERL = /usr/bin/perl
$(MAP_TARGET) :: static $(MAKE_APERL_FILE)
$(MAKE) $(USEMAKEFILE) $(MAKE_APERL_FILE) $@
$(MAKE_APERL_FILE) : $(FIRST_MAKEFILE) pm_to_blib
$(NOECHO) $(ECHO) Writing \"$(MAKE_APERL_FILE)\" for this $(MAP_TARGET)
$(NOECHO) $(PERLRUNINST) \
Makefile.PL DIR= \
MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \
MAKEAPERL=1 NORECURS=1 CCCDLFLAGS=
# --- MakeMaker test section:
TEST_VERBOSE=0
TEST_TYPE=test_$(LINKTYPE)
TEST_FILE = test.pl
TEST_FILES = t/*.t
TESTDB_SW = -d
testdb :: testdb_$(LINKTYPE)
test :: $(TEST_TYPE) subdirs-test
subdirs-test ::
$(NOECHO) $(NOOP)
test_dynamic :: pure_all
PERL_DL_NONLAZY=1 $(FULLPERLRUN) "-MExtUtils::Command::MM" "-e" "test_harness($(TEST_VERBOSE), '$(INST_LIB)', '$(INST_ARCHLIB)')" $(TEST_FILES)
testdb_dynamic :: pure_all
PERL_DL_NONLAZY=1 $(FULLPERLRUN) $(TESTDB_SW) "-I$(INST_LIB)" "-I$(INST_ARCHLIB)" $(TEST_FILE)
test_ : test_dynamic
test_static :: test_dynamic
testdb_static :: testdb_dynamic
# --- MakeMaker ppd section:
# Creates a PPD (Perl Package Description) for a binary distribution.
ppd :
$(NOECHO) $(ECHO) '<SOFTPKG NAME="$(DISTNAME)" VERSION="3.34">' > $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <ABSTRACT>IMAP4 client library</ABSTRACT>' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <AUTHOR>Phil Pearl (Lobbes) &lt;phil@zimbra.com&gt;</AUTHOR>' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <IMPLEMENTATION>' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <PERLCORE VERSION="5,008,0,0" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <REQUIRE NAME="Carp::" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <REQUIRE NAME="Errno::" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <REQUIRE NAME="Fcntl::" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <REQUIRE NAME="File::Temp" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <REQUIRE NAME="IO::File" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <REQUIRE NAME="IO::Select" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <REQUIRE NAME="IO::Socket" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <REQUIRE NAME="IO::Socket::INET" VERSION="1.26" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <REQUIRE NAME="List::Util" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <REQUIRE NAME="MIME::Base64" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <REQUIRE NAME="Parse::RecDescent" VERSION="1.94" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <REQUIRE NAME="Test::More" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <ARCHITECTURE NAME="i486-linux-gnu-thread-multi-5.10" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <CODEBASE HREF="" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' </IMPLEMENTATION>' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) '</SOFTPKG>' >> $(DISTNAME).ppd
# --- MakeMaker pm_to_blib section:
pm_to_blib : $(FIRST_MAKEFILE) $(TO_INST_PM)
$(NOECHO) $(ABSPERLRUN) -MExtUtils::Install -e 'pm_to_blib({@ARGV}, '\''$(INST_LIB)/auto'\'', q[$(PM_FILTER)], '\''$(PERM_DIR)'\'')' -- \
lib/Mail/IMAPClient/BodyStructure/Parse.pm blib/lib/Mail/IMAPClient/BodyStructure/Parse.pm \
lib/Mail/IMAPClient/Thread.pm blib/lib/Mail/IMAPClient/Thread.pm \
lib/Mail/IMAPClient/BodyStructure/Parse.grammar blib/lib/Mail/IMAPClient/BodyStructure/Parse.grammar \
lib/Mail/IMAPClient.pod blib/lib/Mail/IMAPClient.pod \
lib/Mail/IMAPClient/Thread.pod blib/lib/Mail/IMAPClient/Thread.pod \
lib/Mail/IMAPClient/MessageSet.pm blib/lib/Mail/IMAPClient/MessageSet.pm \
lib/Mail/IMAPClient/Thread.grammar blib/lib/Mail/IMAPClient/Thread.grammar \
lib/Mail/IMAPClient/BodyStructure.pm blib/lib/Mail/IMAPClient/BodyStructure.pm \
lib/Mail/IMAPClient/BodyStructure/Parse.pod blib/lib/Mail/IMAPClient/BodyStructure/Parse.pod \
lib/Mail/IMAPClient.pm blib/lib/Mail/IMAPClient.pm
$(NOECHO) $(TOUCH) pm_to_blib
# --- MakeMaker selfdocument section:
# --- MakeMaker postamble section:
# End.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,576 +0,0 @@
use warnings;
use strict;
package Mail::IMAPClient::BodyStructure;
use Mail::IMAPClient::BodyStructure::Parse;
# BUG?: old code used name "HEAD" instead of "HEADER", change?
my $HEAD = "HEAD";
# my has file scope, not limited to package!
my $parser = Mail::IMAPClient::BodyStructure::Parse->new
or die "Cannot parse rules: $@\n"
. "Try remaking Mail::IMAPClient::BodyStructure::Parse.\n";
sub new {
my $class = shift;
my $bodystructure = shift;
my $self = $parser->start($bodystructure)
or return undef;
$self->{_prefix} = "";
$self->{_id} = exists $self->{bodystructure} ? $HEAD : 1;
$self->{_top} = 1;
bless $self, ref($class) || $class;
}
sub _get_thingy {
my $thingy = shift;
my $object = shift || ( ref $thingy ? $thingy : undef );
unless ( $object && ref $object ) {
warn $@ = "No argument passed to $thingy method.";
return undef;
}
unless ( UNIVERSAL::isa( $object, 'HASH' ) && exists $object->{$thingy} ) {
my $a = $thingy =~ /^[aeiou]/i ? 'an' : 'a';
my $has = ref $object eq 'HASH' ? join( ", ", keys %$object ) : '';
warn $@ =
ref($object)
. " $object does not have $a $thingy. "
. ( $has ? "It has $has" : '' );
return undef;
}
my $value = $object->{$thingy};
$value =~ s/\\ ( [\\\(\)"\x0d\x0a] )/$1/gx;
$value =~ s/^"(.*)"$/$1/;
$value;
}
BEGIN {
no strict 'refs';
foreach my $datum (
qw/ bodytype bodysubtype bodyparms bodydisp bodyid bodydesc bodyenc
bodysize bodylang envelopestruct textlines /
)
{
*$datum = sub { _get_thingy( $datum, @_ ) };
}
}
sub parts {
my $self = shift;
return wantarray ? @{ $self->{PartsList} } : $self->{PartsList}
if exists $self->{PartsList};
my @parts;
$self->{PartsList} = \@parts;
# BUG?: should this default to ($HEAD, TEXT)
unless ( exists $self->{bodystructure} ) {
$self->{PartsIndex}{1} = $self;
@parts = ( $HEAD, 1 );
return wantarray ? @parts : \@parts;
}
foreach my $p ( $self->bodystructure ) {
my $id = $p->id;
push @parts, $id;
$self->{PartsIndex}{$id} = $p;
my $type = uc $p->bodytype || '';
push @parts, "$id.$HEAD"
if $type eq 'MESSAGE';
}
wantarray ? @parts : \@parts;
}
sub bodystructure {
my $self = shift;
my $partno = 0;
my @parts;
if ( $self->{_top} ) {
$self->{_id} ||= $HEAD;
$self->{_prefix} ||= $HEAD;
$partno = 0;
foreach my $b ( @{ $self->{bodystructure} } ) {
$b->{_id} = ++$partno;
$b->{_prefix} = $partno;
push @parts, $b, $b->bodystructure;
}
return wantarray ? @parts : \@parts;
}
my $prefix = $self->{_prefix} || "";
$prefix =~ s/\.?$/./;
foreach my $p ( @{ $self->{bodystructure} } ) {
$partno++;
# BUG?: old code didn't add .TEXT sections, should we skip these?
# - This code needs to be generalised (maybe it belongs in parts()?)
# - Should every message should have HEAD (actually MIME) and TEXT?
# at least dovecot and iplanet appear to allow this even for
# non-multipart sections
my $pno = $partno;
my $stype = $self->{bodytype} || "";
my $ptype = $p->{bodytype} || "";
# a message and the multipart inside of it "collapse together"
if ( $partno == 1 and $stype eq 'MESSAGE' and $ptype eq 'MULTIPART' ) {
$pno = "TEXT";
$p->{_prefix} = "$prefix";
}
else {
$p->{_prefix} = "$prefix$partno";
}
$p->{_id} ||= "$prefix$pno";
push @parts, $p, $p->{bodystructure} ? $p->bodystructure : ();
}
wantarray ? @parts : \@parts;
}
sub id {
my $self = shift;
return $self->{_id}
if exists $self->{_id};
return $HEAD
if $self->{_top};
# BUG?: can this be removed? ... seems wrong
if ( $self->{bodytype} eq 'MULTIPART' ) {
my $p = $self->{_id} || $self->{_prefix};
$p =~ s/\.$//;
return $p;
}
else {
return $self->{_id} ||= 1;
}
}
package Mail::IMAPClient::BodyStructure::Part;
our @ISA = qw/Mail::IMAPClient::BodyStructure/;
package Mail::IMAPClient::BodyStructure::Envelope;
our @ISA = qw/Mail::IMAPClient::BodyStructure/;
sub new {
my ( $class, $envelope ) = @_;
$parser->envelope($envelope);
}
sub parse_string {
my ( $class, $envelope ) = @_;
$envelope = "(" . $envelope . ")" unless ( $envelope =~ /^\(/ );
$parser->envelopestruct($envelope);
}
sub from_addresses { shift->_addresses( from => 1 ) }
sub sender_addresses { shift->_addresses( sender => 1 ) }
sub replyto_addresses { shift->_addresses( replyto => 1 ) }
sub to_addresses { shift->_addresses( to => 0 ) }
sub cc_addresses { shift->_addresses( cc => 0 ) }
sub bcc_addresses { shift->_addresses( bcc => 0 ) }
sub _addresses($$$) {
my ( $self, $name, $isSender ) = @_;
ref $self->{$name} eq 'ARRAY'
or return ();
my @list;
foreach ( @{ $self->{$name} } ) {
my $pn = $_->personalname;
my $name = $pn && $pn ne 'NIL' ? "$pn " : '';
push @list, $name . '<' . $_->mailboxname . '@' . $_->hostname . '>';
}
wantarray ? @list
: $isSender ? $list[0]
: \@list;
}
BEGIN {
no strict 'refs';
for my $datum (
qw(subject inreplyto from messageid bcc date
replyto to sender cc)
)
{
*$datum = sub { @_ > 1 ? $_[0]->{$datum} = $_[1] : $_[0]->{$datum} }
}
}
package Mail::IMAPClient::BodyStructure::Address;
our @ISA = qw/Mail::IMAPClient::BodyStructure/;
for my $datum (qw(personalname mailboxname hostname sourcename)) {
no strict 'refs';
*$datum = sub { shift->{$datum}; };
}
1;
__END__
=head1 NAME
Mail::IMAPClient::BodyStructure - parse fetched results
=head1 SYNOPSIS
use Mail::IMAPClient;
use Mail::IMAPClient::BodyStructure;
my $imap = Mail::IMAPClient->new(
Server => $server, User => $login, Password => $pass
);
$imap->select("INBOX") or die "Could not select INBOX: $@\n";
my @recent = $imap->search("recent") or die "No recent msgs in INBOX\n";
foreach my $id (@recent) {
my $bsdat = $imap->fetch( $id, "bodystructure" );
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
This extension will parse the result of an IMAP FETCH BODYSTRUCTURE
command into a perl data structure. It also provides helper methods
to help pull information out of the data structure.
This module requires Parse::RecDescent.
=head1 Class Methods
The following class method is available:
=head2 new
This class method is the constructor method for instantiating new
Mail::IMAPClient::BodyStructure objects. The B<new> method accepts
one argument, a string containing a server response to a FETCH
BODYSTRUCTURE directive.
The module B<Mail::IMAPClient> provides the B<get_bodystructure>
conveniece method to simplify use of this module when starting with
just a messages sequence number or unique ID (UID).
=head1 Object Methods
The following object methods are available:
=head2 bodytype
The B<bodytype> object method requires no arguments. It returns the
bodytype for the message whose structure is described by the calling
B<Mail::IMAPClient::Bodystructure> object.
=head2 bodysubtype
The B<bodysubtype> object method requires no arguments. It returns the
bodysubtype for the message whose structure is described by the calling
B<Mail::IMAPClient::Bodystructure> object.
=head2 bodyparms
The B<bodyparms> object method requires no arguments. It returns the
bodyparms for the message whose structure is described by the calling
B<Mail::IMAPClient::Bodystructure> object.
=head2 bodydisp
The B<bodydisp> object method requires no arguments. It returns the
bodydisp for the message whose structure is described by the calling
B<Mail::IMAPClient::Bodystructure> object.
=head2 bodyid
The B<bodyid> object method requires no arguments. It returns the
bodyid for the message whose structure is described by the calling
B<Mail::IMAPClient::Bodystructure> object.
=head2 bodydesc
The B<bodydesc> object method requires no arguments. It returns the
bodydesc for the message whose structure is described by the calling
B<Mail::IMAPClient::Bodystructure> object.
=head2 bodyenc
The B<bodyenc> object method requires no arguments. It returns the
bodyenc for the message whose structure is described by the calling
B<Mail::IMAPClient::Bodystructure> object.
=head2 bodysize
The B<bodysize> object method requires no arguments. It returns the
bodysize for the message whose structure is described by the calling
B<Mail::IMAPClient::Bodystructure> object.
=head2 bodylang
The B<bodylang> object method requires no arguments. It returns the
bodylang for the message whose structure is described by the calling
B<Mail::IMAPClient::Bodystructure> object.
=head2 bodystructure
The B<bodystructure> object method requires no arguments. It returns
the bodystructure for the message whose structure is described by the
calling B<Mail::IMAPClient::Bodystructure> object.
=head2 envelopestruct
The B<envelopestruct> object method requires no arguments. It returns
a B<Mail::IMAPClient::BodyStructure::Envelope> object for the message
from the calling B<Mail::IMAPClient::Bodystructure> object.
=head2 textlines
The B<textlines> object method requires no arguments. It returns the
textlines for the message whose structure is described by the calling
B<Mail::IMAPClient::Bodystructure> object.
=head1 Mail::IMAPClient::BodyStructure::Envelope
The IMAP standard specifies that output from the IMAP B<FETCH
ENVELOPE> command will be an RFC2060 envelope structure. It further
specifies that output from the B<FETCH BODYSTRUCTURE> command may also
contain embedded envelope structures (if, for example, a message's
subparts contain one or more included messages). Objects belonging to
B<Mail::IMAPClient::BodyStructure::Envelope> are Perl representations
of these envelope structures, which is to say the nested parenthetical
lists of RFC2060 translated into a Perl datastructure.
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, in B<Mail::IMAPClient>, C<$imap->fetch($msgid,"ENVELOPE")> or
C<my $env = $imap->get_envelope($msgid)>) are for the message, but
fields from within a bodystructure relate to the message subpart and
not the parent message.
An envelope structure's B<Mail::IMAPClient::BodyStructure::Envelope>
representation is a hash of thingies that looks like this:
{
subject => "subject",
inreplyto => "reference_message_id",
from => [ addressStruct1 ],
messageid => "message_id",
bcc => [ addressStruct1, addressStruct2 ],
date => "Tue, 09 Jul 2002 14:15:53 -0400",
replyto => [ adressStruct1, addressStruct2 ],
to => [ adressStruct1, addressStruct2 ],
sender => [ adressStruct1 ],
cc => [ adressStruct1, addressStruct2 ],
}
The B<...::Envelope> object also has methods for accessing data in the
structure. They are:
=over 4
=item date
Returns the date of the message.
=item inreplyto
Returns the message id of the message to which this message is a reply.
=item subject
Returns the subject of the message.
=item messageid
Returns the message id of the message.
=back
You can also use the following methods to get addressing information.
Each of these methods returns an array of
B<Mail::IMAPClient::BodyStructure::Address> objects, which are perl
data structures representing RFC2060 address structures. Some of
these arrays would naturally contain one element (such as B<from>,
which normally contains a single "From:" address); others will often
contain more than one address. However, because RFC2060 defines all
of these as "lists of address structures", they are all translated
into arrays of B<...::Address> objects.
See the section on B<Mail::IMAPClient::BodyStructure::Address>, below,
for alternate (and preferred) ways of accessing these data.
The methods available are:
=over 4
=item bcc
Returns an array of blind cc'ed recipients' address structures.
(Don't expect much in here unless the message was sent from the
mailbox you're poking around in, by the way.)
=item cc
Returns an array of cc'ed recipients' address structures.
=item from
Returns an array of "From:" address structures--usually just one.
=item replyto
Returns an array of "Reply-to:" address structures. Once again there
is usually just one address in the list.
=item sender
Returns an array of senders' address structures--usually just one and
usually the same as B<from>.
=item to
Returns an array of recipients' address structures.
=back
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 analagous method that will return a list of E-Mail addresses
instead. The addresses are in the format C<personalname
E<lt>mailboxname@hostnameE<gt>> (see the section on
B<Mail::IMAPClient::BodyStructure::Address>, below) However, if the
personal name is 'NIL' then it is omitted from the address.
These methods are:
=over 4
=item bcc_addresses
Returns a list (or an array reference if called in scalar context) of
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,
by the way.)
=item cc_addresses
Returns a list of cc'ed recipients' email addresses. If called in a
scalar context it returns a reference to an array of email addresses.
=item from_addresses
Returns a list of "From:" email addresses. If called in a scalar
context it returns the first email address in the list. (It's usually
a list of just one anyway.)
=item replyto_addresses
Returns a list of "Reply-to:" email addresses. If called in a scalar
context it returns the first email address in the list.
=item sender_addresses
Returns a list of senders' email addresses. If called in a scalar
context it returns the first email address in the list.
=item to_addresses
Returns a list of recipients' email addresses. If called in a scalar
context it returns a reference to an array of email addresses.
=back
Note that context affects the behavior of all of the above methods.
Those fields that will commonly contain multiple entries (i.e. they
are recipients) will return an array reference when called in scalar
context. You can use this behavior to optimize performance.
Those fields that will commonly contain just one address (the
sender's) will return the first (and usually only) address. You can
use this behavior to optimize your development time.
=head1 Addresses and the Mail::IMAPClient::BodyStructure::Address
Several components of an envelope structure are address structures.
They are each parsed into their own object,
B<Mail::IMAPClient::BodyStructure::Address>, which looks like this:
{
mailboxname => 'somebody.special',
hostname => 'somplace.weird.com'
personalname => 'Somebody Special
sourceroute => 'NIL'
}
RFC2060 specifies that each address component of a bodystructure is a
list of address structures, so B<Mail::IMAPClient::BodyStructure>
parses each of these into an array of
B<Mail::IMAPClient::BodyStructure::Address> objects.
Each of these objects has the following methods available to it:
=over 4
=item mailboxname
Returns the "mailboxname" portion of the address, which is the part to
the left of the '@' sign.
=item hostname
Returns the "hostname" portion of the address, which is the part to
the right of the '@' sign.
=item personalname
Returns the "personalname" portion of the address, which is the part
of the address that's treated like a comment.
=item sourceroute
Returns the "sourceroute" portion of the address, which is typically "NIL".
=back
Taken together, the parts of an address structure form an address that
will look something like this:
C<personalname E<lt>mailboxname@hostnameE<gt>>
Note that because the B<Mail::IMAPClient::BodyStructure::Address>
objects come in arrays, it's generally easier to use the methods
available to B<Mail::IMAPClient::BodyStructure::Envelope> to obtain
all of the addresses in a particular array in one operation. These
methods are provided, however, in case you'd rather do things the hard
way. (And also because the aforementioned methods from
B<Mail::IMAPClient::BodyStructure::Envelope> need them anyway.)
=cut
=head1 AUTHOR
Original author: David J. Kernen; Reworked by: Mark Overmeer;
Maintained by Phil Pearl.
=head1 SEE ALSO
perl(1), Mail::IMAPClient, Parse::RecDescent, and RFC2060.
=cut

View File

@ -1,189 +0,0 @@
# Directives
# ( none)
# Start-up Actions
{
my $mibs = "Mail::IMAPClient::BodyStructure";
my $subpartCount = 0;
my $partCount = 0;
sub take_optional_items($$@)
{ my ($r, $items) = (shift, shift);
foreach (@_)
{ my $opt = $_ .'(?)';
exists $items->{$opt} or next;
$r->{$_} = UNIVERSAL::isa($items->{$opt}, 'ARRAY')
? $items->{$opt}[0] : $items->{$opt};
}
}
sub merge_hash($$)
{ my $to = shift;
my $from = shift or return;
while( my($k,$v) = each %$from) { $to->{$k} = $v }
}
}
# Atoms
TEXT: /^"TEXT"|^TEXT/i { $return = "TEXT" }
PLAIN: /^"PLAIN"|^PLAIN/i { $return = "PLAIN" }
HTML: /"HTML"|HTML/i { $return = "HTML" }
MESSAGE: /^"MESSAGE"|^MESSAGE/i { $return = "MESSAGE"}
RFC822: /^"RFC822"|^RFC822/i { $return = "RFC822" }
NIL: /^NIL/i { $return = "NIL" }
RFCNONCOMPLY: /^\(\)/i { $return = "NIL" }
NUMBER: /^(\d+)/ { $return = $item[1] }
# Strings:
SINGLE_QUOTED_STRING: "'" /(?:\\'|[^'])*/ "'" { $return = $item{__PATTERN1__} }
DOUBLE_QUOTED_STRING: '"' /(?:\\"|[^"])*/ '"' { $return = $item{__PATTERN1__} }
BARESTRING: ...!/^[)('"]/ /^(?!\(|\))(?:\\ |\S)+/
{ $return = $item{__PATTERN1__} }
STRING: DOUBLE_QUOTED_STRING | SINGLE_QUOTED_STRING | BARESTRING
STRINGS: "(" STRING(s) ")" { $return = $item{'STRING(s)'} }
textlines: NIL | NUMBER
rfc822message: MESSAGE RFC822 { $return = "MESSAGE RFC822" }
bodysubtype: PLAIN | HTML | NIL | STRING
key: STRING
value: NIL | NUMBER | STRING | KVPAIRS
kvpair: ...!")" key value
{ $return = { $item{key} => $item{value} } }
KVPAIRS: "(" kvpair(s) ")"
{ $return = { map { (%$_) } @{$item{'kvpair(s)'}} } }
bodytype: STRING
bodyparms: NIL | KVPAIRS
bodydisp: NIL | KVPAIRS
bodyid: ...!/[()]/ NIL | STRING
bodydesc: ...!/[()]/ NIL | STRING
bodysize: ...!/[()]/ NIL | NUMBER
bodyenc: NIL | STRING | KVPAIRS
bodyMD5: NIL | STRING
bodylang: NIL | STRING | STRINGS
bodyextra: NIL | STRING | STRINGS
bodyloc: NIL | STRING
personalname: NIL | STRING
sourceroute: NIL | STRING
mailboxname: NIL | STRING
hostname: NIL | STRING
addressstruct: "(" personalname sourceroute mailboxname hostname ")"
{ bless { personalname => $item{personalname}
, sourceroute => $item{sourceroute}
, mailboxname => $item{mailboxname}
, hostname => $item{hostname}
}, 'Mail::IMAPClient::BodyStructure::Address';
}
subject: NIL | STRING
inreplyto: NIL | STRING
messageid: NIL | STRING
date: NIL | STRING
ADDRESSES: NIL | RFCNONCOMPLY
| "(" addressstruct(s) ")" { $return = $item{'addressstruct(s)'} }
cc: ADDRESSES
bcc: ADDRESSES
from: ADDRESSES
replyto: ADDRESSES
sender: ADDRESSES
to: ADDRESSES
envelopestruct: "(" date subject from sender replyto to cc
bcc inreplyto messageid ")"
{ $return = bless {}, "Mail::IMAPClient::BodyStructure::Envelope";
$return->{$_} = $item{$_}
for qw/date subject from sender replyto to cc/
, qw/bcc inreplyto messageid/;
1;
}
basicfields: bodysubtype bodyparms(?) bodyid(?)
bodydesc(?) bodyenc(?) bodysize(?)
{ $return = { bodysubtype => $item{bodysubtype} };
take_optional_items($return, \%item,
qw/bodyparms bodyid bodydesc bodyenc bodysize/);
1;
}
textmessage: TEXT <commit> basicfields textlines(?) bodyMD5(?)
bodydisp(?) bodylang(?) bodyextra(?)
{
$return = $item{basicfields} || {};
$return->{bodytype} = 'TEXT';
take_optional_items($return, \%item
, qw/textlines bodyMD5 bodydisp bodylang bodyextra/);
1;
}
othertypemessage: bodytype basicfields bodyMD5(?) bodydisp(?)
bodylang(?) bodyextra(?)
{ $return = { bodytype => $item{bodytype} };
take_optional_items($return, \%item
, qw/bodyMD5 bodydisp bodylang bodyextra/ );
merge_hash($return, $item{basicfields});
1;
}
nestedmessage: rfc822message <commit> bodyparms bodyid bodydesc bodyenc
# bodysize envelopestruct bodystructure textlines
bodysize envelopestruct(?) bodystructure(?) textlines(?)
bodyMD5(?) bodydisp(?) bodylang(?) bodyextra(?)
{
$return = {};
$return->{$_} = $item{$_}
for qw/bodyparms bodyid bodydesc bodyenc bodysize/;
# envelopestruct bodystructure textlines/;
take_optional_items($return, \%item
, qw/envelopestruct bodystructure textlines/
, qw/bodyMD5 bodydisp bodylang bodyextra/);
merge_hash($return, $item{bodystructure}[0]);
merge_hash($return, $item{basicfields});
$return->{bodytype} = "MESSAGE" ;
$return->{bodysubtype} = "RFC822" ;
1;
}
multipart: subpart(s) <commit> bodysubtype
bodyparms(?) bodydisp(?) bodylang(?) bodyloc(?) bodyextra(?)
<defer: $subpartCount = 0>
{ $return =
{ bodysubtype => $item{bodysubtype}
, bodytype => 'MULTIPART'
, bodystructure => $item{'subpart(s)'}
};
take_optional_items($return, \%item
, qw/bodyparms bodydisp bodylang bodyloc bodyextra/);
1;
}
subpart: "(" part ")" {$return = $item{part}} <defer: ++$subpartCount;>
part: multipart { $return = bless $item{multipart}, $mibs }
| textmessage { $return = bless $item{textmessage}, $mibs }
| nestedmessage { $return = bless $item{nestedmessage}, $mibs }
| othertypemessage { $return = bless $item{othertypemessage}, $mibs }
bodystructure: "(" part(s) ")"
{ $return = $item{'part(s)'} }
start: /.*?\(.*?BODYSTRUCTURE \(/i part(1) /\).*\)\r?\n?/
{ $return = $item{'part(1)'}[0] }
envelope: /.*?\(.*?ENVELOPE/ envelopestruct /.*\)/
{ $return = $item{envelopestruct} }

View File

@ -1,15 +0,0 @@
=head1 NAME
Mail::IMAPClient::BodyStructure::Parse - used internally by Mail::IMAPClient::BodyStructure
=head1 DESCRIPTION
This module is used internally by L<Mail::IMAPClient::BodyStructure>
and is generated using L<Parse::RecDescent>. It is not meant to be used
directly by other scripts nor is there much point in debugging it.
=head1 SYNOPSIS
This module is used internally by L<Mail::IMAPClient::BodyStructure>
and is not meant to be used or called directly from applications. So
don't do that.

View File

@ -1,280 +0,0 @@
use warnings;
use strict;
package Mail::IMAPClient::MessageSet;
=head1 NAME
Mail::IMAPClient::MessageSet - ranges of message sequence nummers
=cut
use overload
'""' => "str"
, '.=' => sub {$_[0]->cat($_[1])}
, '+=' => sub {$_[0]->cat($_[1])}
, '-=' => sub {$_[0]->rem($_[1])}
, '@{}' => "unfold"
, fallback => 1;
sub new
{ my $class = shift;
my $range = $class->range(@_);
bless \$range, $class;
}
sub str { overload::StrVal( ${$_[0]} ) }
sub _unfold_range($)
# { my $x = shift; return if $x =~ m/[^0-9,:]$/; $x =~ s/\:/../g; eval $x; }
{ map { /(\d+)\s*\:\s*(\d+)/ ? ($1..$2) : $_ }
split /\,/, shift;
}
sub rem
{ my $self = shift;
my %delete = map { ($_ => 1) } map { _unfold_range $_ } @_;
$$self = $self->range(grep {not $delete{$_}} $self->unfold);
$self;
}
sub cat
{ my $self = shift;
$$self = $self->range($$self, @_);
$self;
}
sub range
{ my $self = shift;
my @msgs;
foreach my $m (@_)
{ defined $m && length $m
or next;
foreach my $mm (ref $m eq 'ARRAY' ? @$m : $m)
{ push @msgs, _unfold_range $mm;
}
}
@msgs
or return undef;
@msgs = sort {$a <=> $b} @msgs;
my $low = my $high = shift @msgs;
my @ranges;
foreach my $m (@msgs)
{ next if $m == $high; # double
if($m == $high + 1) { $high = $m }
else
{ push @ranges, $low == $high ? $low : "$low:$high";
$low = $high = $m;
}
}
push @ranges, $low == $high ? $low : "$low:$high" ;
join ",", @ranges;
}
sub unfold
{ my $self = shift;
wantarray ? ( _unfold_range $$self ) : [ _unfold_range $$self ];
}
=head1 SYNOPSIS
my @msgs = $imap->search("SUBJECT","Virus"); # returns 1,3,4,5,6,9,10
my $msgset = Mail::IMAPClient::MessageSet->new(@msgs);
print $msgset; # prints "1,3:6,9:10"
# add message 14 to the set:
$msgset += 14;
print $msgset; # prints "1,3:6,9:10,14"
# add messages 16,17,18,19, and 20 to the set:
$msgset .= "16,17,18:20";
print $msgset; # prints "1,3:6,9:10,14,16:20"
# Hey, I didn't really want message 17 in there; let's take it out:
$msgset -= 17;
print $msgset; # prints "1,3:6,9:10,14,16,18:20"
# Now let's iterate over each message:
for my $msg (@$msgset)
{ print "$msg\n"; # Prints: "1\n3\n4\n5\n6..16\n18\n19\n20\n"
}
print join("\n", @$msgset)."\n"; # same simpler
local $" = "\n"; print "@$msgset\n"; # even more simple
=head1 DESCRIPTION
The B<Mail::IMAPClient::MessageSet> module is designed to make life easier
for programmers who need to manipulate potentially large sets of IMAP
message UID's or sequence numbers.
This module presents an object-oriented interface into handling your
message sets. The object reference returned by the L<new> method is an
overloaded reference to a scalar variable that contains the message set's
compact RFC2060 representation. The object is overloaded so that using
it like a string returns this compact message set representation. You
can also add messages to the set (using either a '.=' operator or a '+='
operator) or remove messages (with the '-=' operator). And if you use
it as an array reference, it will humor you and act like one by calling
L<unfold> for you.
RFC2060 specifies that multiple messages can be provided to certain IMAP
commands by separating them with commas. For example, "1,2,3,4,5" would
specify messages 1, 2, 3, 4, and (you guessed it!) 5. However, if you are
performing an operation on lots of messages, this string can get quite long.
So long that it may slow down your transaction, and perhaps even cause the
server to reject it. So RFC2060 also permits you to specifiy a range of
messages, so that messages 1, 2, 3, 4 and 5 can also be specified as
"1:5".
This is where B<Mail::IMAPClient::MessageSet> comes in. It will convert
your message set into the shortest correct syntax. This could potentially
save you tons of network I/O, as in the case where you want to fetch the
flags for all messages in a 10000 message folder, where the messages
are all numbered sequentially. Delimited as commas, and making the
best-case assumption that the first message is message "1", it would take
48893 bytes to specify the whole message set using the comma-delimited
method. To specify it as a range, it takes just seven bytes (1:10000).
Note that the L<Mail::IMAPClient> B<Range> method can be used as
a short-cut to specifying C<Mail::IMAPClient::MessageSet-E<gt>new(@etc)>.)
=head1 CLASS METHODS
The only class method you need to worry about is B<new>. And if you create
your B<Mail::IMAPClient::MessageSet> objects via L<Mail::IMAPClient>'s
B<Range> method then you don't even need to worry about B<new>.
=head2 new
Example:
my $msgset = Mail::IMAPClient::MessageSet->new(@msgs);
The B<new> method requires at least one argument. That argument can be
either a message, a comma-separated list of messages, a colon-separated
range of messages, or a combination of comma-separated messages and
colon-separated ranges. It can also be a reference to an array of messages,
comma-separated message lists, and colon separated ranges.
If more then one argument is supplied to B<new>, then those arguments should
be more message numbers, lists, and ranges (or references to arrays of them)
just as in the first argument.
The message numbers passed to B<new> can really be any kind of number at
all but to be useful in a L<Mail::IMAPClient> session they should be either
message UID's (if your I<Uid> parameter is true) or message sequence numbers.
The B<new> method will return a reference to a B<Mail::IMAPClient::MessageSet>
object. That object, when double quoted, will act just like a string whose
value is the message set expressed in the shortest possible way, with the
message numbers sorted in ascending order and with duplicates removed.
=head1 OBJECT METHODS
The only object method currently available to a B<Mail::IMAPClient::MessageSet>
object is the L<unfold> method.
=head2 unfold
Example:
my $msgset = $imap->Range( $imap->messages ) ;
my @all_messages = $msgset->unfold;
The B<unfold> method returns an array of messages that belong to the
message set. If called in a scalar context it returns a reference to the
array instead.
=head1 OVERRIDDEN OPERATIONS
B<Mail::IMAPClient::MessageSet> overrides a number of operators in order
to make manipulating your message sets easier. The overridden operations are:
=head2 stringify
Attempts to stringify a B<Mail::IMAPClient::MessageSet> object will result in
the compact message specification being returned, which is almost certainly
what you will want.
=head2 Auto-increment
Attempts to autoincrement a B<Mail::IMAPClient::MessageSet> object will
result in a message (or messages) being added to the object's message set.
Example:
$msgset += 34;
# Message #34 is now in the message set
=head2 Concatenate
Attempts to concatenate to a B<Mail::IMAPClient::MessageSet> object will
result in a message (or messages) being added to the object's message set.
Example:
$msgset .= "34,35,36,40:45";
# Messages 34,35,36,40,41,42,43,44,and 45 are now in the message set
The C<.=> operator and the C<+=> operator can be used interchangeably, but
as you can see by looking at the examples there are times when use of one
has an aesthetic advantage over use of the other.
=head2 Autodecrement
Attempts to autodecrement a B<Mail::IMAPClient::MessageSet> object will
result in a message being removed from the object's message set.
Examples:
$msgset -= 34;
# Message #34 is no longer in the message set
$msgset -= "1:10";
# Messages 1 through 10 are no longer in the message set
If you attempt to remove a message that was not in the original message set
then your resulting message set will be the same as the original, only more
expensive. However, if you attempt to remove several messages from the message
set and some of those messages were in the message set and some were not,
the additional overhead of checking for the messages that were not there
is negligable. In either case you get back the message set you want regardless
of whether it was already like that or not.
=head1 AUTHOR
David J. Kernen
The Kernen Consulting Group, Inc
=head1 COPYRIGHT
Copyright 1999, 2000, 2001, 2002 The Kernen Group, Inc.
All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the terms of either:
=over 4
=item a) the "Artistic License" which comes with this Kit, or
=item b) the GNU General Public License as published by the Free Software
Foundation; either version 1, or (at your option) any later version.
=back
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the GNU
General Public License or the Artistic License for more details. All your
base are belong to us.
=cut
1;

View File

@ -1,18 +0,0 @@
# Atoms:
NUMBER: /\d+/
# Rules:
threadmember: NUMBER { $return = $item{NUMBER} ; } |
thread { $return = $item{thread} ; }
thread: "(" threadmember(s) ")"
{
$return = $item{'threadmember(s)'}||undef;
}
# Start:
start: /^\* THREAD /i thread(s?) {
$return=$item{'thread(s?)'}||undef;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +0,0 @@
=head1 NAME
Mail::IMAPClient::Thread - used internally by Mail::IMAPClient->thread
=head1 DESCRIPTION
This module is used internally by L<Mail::IMAPClient> and is
generated using L<Parse::RecDescent>. It is not meant to be used directly by
other scripts nor is there much point in debugging it.
=head1 SYNOPSIS
This module is used internally by L<Mail::IMAPClient> and is not meant to
be used or called directly from applications. So don't do that.

Binary file not shown.

View File

@ -5,6 +5,21 @@ Changes from 2.99_01 to 3.16 made by Mark Overmeer
Changes from 0.09 to 2.99_01 made by David Kernen
- Potential compatibility issues from 3.17+ highlighted with '*'
version 3.35: Fri, Nov 22, 2013 2:18:41 PM
- *use Quote() over Massage() to avoid stripping double quotes from arg
+ removed constant NonFolderArg
+ may deprecate Massage() in a future release
- _list_or_lsub failed to handle folder names with double quotes
+ cleanup Escaped_results()
+ new methods: Escaped_history() _escaped_trans_data()
+ removed method: _list_response_preprocess()
[Gilles Lamiral, Victor Lé]
- rt.cpan.org#90315: getacl on a folder returned as literal failed
+ _read_line could remove extra space when literal data was received
[Carl Karcher]
- rt.cpan.org#89040: typo fixes
[David Steinbrunner]
version 3.34: Fri, Sep 27, 2013 12:50:17 AM
- make Makefile.PL use non-interactive and document test.txt usage
- new attribute: Socketargs => [ (IO::Socket::.. args) ]

View File

@ -1,6 +1,6 @@
--- #YAML:1.0
name: Mail-IMAPClient
version: 3.34
version: 3.35
abstract: IMAP4 client library
author:
- Phil Pearl (Lobbes) <phil@zimbra.com>

View File

@ -7,7 +7,7 @@ use strict;
use warnings;
package Mail::IMAPClient;
our $VERSION = '3.34';
our $VERSION = '3.35';
use Mail::IMAPClient::MessageSet;
@ -36,8 +36,6 @@ use constant {
DATA => 2, # Array index for output line data
};
use constant NonFolderArg => 1; # for Massage indicating non-folder arguments
my %SEARCH_KEYS = map { ( $_ => 1 ) } qw(
ALL ANSWERED BCC BEFORE BODY CC DELETED DRAFT FLAGGED
FROM HEADER KEYWORD LARGER NEW NOT OLD ON OR RECENT
@ -535,7 +533,7 @@ sub compress {
return $ret if ( !$ret && !$lz ); # $ret is undef or 0
}
# accummulate inflated data in $Ibuf
# accumulate inflated data in $Ibuf
if ($lz) {
my ( $tbuf, $rc ) = $io->inflate( \$Zbuf );
unless ( $rc == $zcl->Z_OK ) {
@ -649,21 +647,12 @@ sub _list_or_lsub {
length $target or $target = '""';
$target eq '*' || $target eq '""'
or $target = $self->Massage($target);
or $target = $self->Quote($target);
$self->_imap_command(qq($cmd "$reference" $target))
or return undef;
# cleanup any literal data that may be returned
my $ret = wantarray ? [ $self->History ] : $self->Results;
if ($ret) {
my $cmd = wantarray ? undef : shift @$ret;
$self->_list_response_preprocess($ret);
unshift( @$ret, $cmd ) if defined($cmd);
}
#return wantarray ? $self->History : $self->Results;
return wantarray ? @$ret : $ret;
return wantarray ? $self->Escaped_history : $self->Escaped_results;
}
sub list { shift->_list_or_lsub( "LIST", @_ ) }
@ -765,7 +754,7 @@ sub subscribed {
sub deleteacl {
my ( $self, $target, $user ) = @_;
$target = $self->Massage($target);
$target = $self->Quote($target);
$user = ( $user eq "" ) ? qq("") : $self->Quote($user);
$self->_imap_command(qq(DELETEACL $target $user))
@ -777,7 +766,7 @@ sub deleteacl {
sub setacl {
my ( $self, $target, $user, $acl ) = @_;
$target ||= $self->Folder;
$target = $self->Massage($target);
$target = $self->Quote($target);
$user ||= $self->User;
$user = ( $user eq "" ) ? qq("") : $self->Quote($user);
@ -792,7 +781,7 @@ sub setacl {
sub getacl {
my ( $self, $target ) = @_;
defined $target or $target = $self->Folder;
my $mtarget = $self->Massage($target);
my $mtarget = $self->Quote($target);
$self->_imap_command(qq(GETACL $mtarget))
or return undef;
@ -822,7 +811,7 @@ sub getacl {
sub listrights {
my ( $self, $target, $user ) = @_;
$target ||= $self->Folder;
$target = $self->Massage($target);
$target = $self->Quote($target);
$user ||= $self->User;
$user = ( $user eq "" ) ? qq("") : $self->Quote($user);
@ -841,7 +830,7 @@ sub select {
my ( $self, $target ) = @_;
defined $target or return undef;
my $qqtarget = $self->Massage($target);
my $qqtarget = $self->Quote($target);
my $old = $self->Folder;
$self->_imap_command("SELECT $qqtarget")
@ -1104,7 +1093,7 @@ sub examine {
my ( $self, $target ) = @_;
defined $target or return undef;
$self->_imap_command( 'EXAMINE ' . $self->Massage($target) )
$self->_imap_command( 'EXAMINE ' . $self->Quote($target) )
or return undef;
my $old = $self->Folder;
@ -1650,7 +1639,7 @@ sub _read_line {
while ( $iBuffer =~ s/^(.*?$CR?$LF)//o ) # consume line
{
my $current_line = $1;
if ( $current_line !~ s/\s*\{(\d+)\}$CR?$LF$//o ) {
if ( $current_line !~ s/\{(\d+)\}$CR?$LF$//o ) {
push @$oBuffer, [ $index++, 'OUTPUT', $current_line ];
next;
}
@ -1845,6 +1834,35 @@ sub _trans_data(;$) {
map { $_->[DATA] } $_[0]->_transaction( $_[1] );
}
sub _escaped_trans_data(;$) {
my ( $self, $trans ) = @_;
my @a;
my $prevwasliteral = 0;
foreach my $line ( $self->_transaction($trans) ) {
next unless defined $line;
my $data = $line->[DATA];
# literal is appended to previous data
if ( $self->_is_literal($line) ) {
$data = $self->Escape($data);
$a[-1] .= qq("$data");
$prevwasliteral = 1;
}
else {
if ($prevwasliteral) {
$a[-1] .= $data;
}
else {
push( @a, $data );
}
$prevwasliteral = 0;
}
}
return wantarray ? @a : \@a;
}
sub Report {
my $self = shift;
map { $self->_trans_data($_) } $self->_trans_index;
@ -1874,30 +1892,15 @@ sub _transaction_literals() {
grep { $self->_is_literal($_) } $self->_transaction;
}
sub Escaped_history {
my ( $self, $trans ) = @_;
my ( $cmd, @a ) = $self->_escaped_trans_data($trans);
return wantarray ? @a : \@a;
}
sub Escaped_results {
my ( $self, $trans ) = @_;
my @a;
my $prevwasliteral = 0;
foreach my $line ( grep defined, $self->_transaction($trans) ) {
my $data = $line->[DATA];
# literal is appended to previous data
if ( $self->_is_literal($line) ) {
$data = $self->Escape($data);
$a[-1] .= qq( "$data");
$prevwasliteral = 1;
}
else {
if ($prevwasliteral) {
$a[-1] .= $data;
}
else {
push( @a, $data );
}
$prevwasliteral = 0;
}
}
my @a = $self->_escaped_trans_data($trans);
return wantarray ? @a : \@a;
}
@ -1936,8 +1939,7 @@ sub _disconnect {
# LIST/XLIST/LSUB Response
# Contents: name attributes, hierarchy delimiter, name
# Example: * LIST (\Noselect) "/" ~/Mail/foo
# NOTE: in _list_response_preprocess we append literal data so we need
# to be liberal about our matching of folder name data
# NOTE: liberal matching as folder name data may be Escape()d
sub _list_or_lsub_response_parse {
my ( $self, $resp ) = @_;
@ -1959,25 +1961,6 @@ sub _list_or_lsub_response_parse {
return wantarray ? %info : \%info;
}
# handle listeral data returned in list/lsub responses
# some example responses:
# * LIST () "/" "My Folder" # nothing to do here...
# * LIST () "/" {9} # the {9} is already removed by _read_line()
# Special % # we append this to the previous line
sub _list_response_preprocess {
my ( $self, $data ) = @_;
return undef unless defined $data;
for ( my $m = 0 ; $m < @$data ; $m++ ) {
if ( $data->[$m] && $data->[$m] !~ /$CR?$LF$/o ) {
$self->_debug("concatenating '$data->[$m]' and '$data->[$m+1]'");
$data->[$m] .= " " . $data->[ $m + 1 ];
splice @$data, $m + 1, 1;
}
}
return $data;
}
sub exists {
my ( $self, $folder ) = @_;
$self->status($folder) ? $self : undef;
@ -2302,7 +2285,7 @@ sub store {
sub _imap_folder_command($$@) {
my ( $self, $command ) = ( shift, shift );
my $folder = $self->Massage(shift);
my $folder = $self->Quote(shift);
$self->_imap_command( join ' ', $command, $folder, @_ )
or return undef;
@ -2380,8 +2363,8 @@ sub uidexpunge {
sub rename {
my ( $self, $from, $to ) = @_;
$from = ( $from eq "" ) ? qq("") : $self->Massage($from);
$to = ( $to eq "" ) ? qq("") : $self->Massage($to);
$from = ( $from eq "" ) ? qq("") : $self->Quote($from);
$to = ( $to eq "" ) ? qq("") : $self->Quote($to);
$self->_imap_command(qq(RENAME $from $to)) ? $self : undef;
}
@ -2392,7 +2375,7 @@ sub status {
my $which = @_ ? join( " ", @_ ) : 'MESSAGES';
my $box = $self->Massage($folder);
my $box = $self->Quote($folder);
$self->_imap_command("STATUS $box ($which)")
or return undef;
@ -2621,11 +2604,10 @@ sub or {
return undef;
}
my $or = "OR "
. $self->Massage( shift @what ) . " "
. $self->Massage( shift @what );
my $or =
"OR " . $self->Quote( shift @what ) . " " . $self->Quote( shift @what );
$or = "OR $or " . $self->Massage($_) for @what;
$or = "OR $or " . $self->Quote($_) for @what;
$self->_imap_uid_command( SEARCH => $or )
or return undef;
@ -2708,7 +2690,7 @@ sub thread {
my $charset = shift || 'UTF-8';
my @a = @_ ? @_ : 'ALL';
$a[-1] = $self->Massage( $a[-1], 1 )
$a[-1] = $self->Quote( $a[-1], 1 )
if @a > 1 && !exists $SEARCH_KEYS{ uc $a[-1] };
$self->_imap_uid_command( THREAD => $algorythm, $charset, @a )
@ -2955,7 +2937,7 @@ sub append_string($$$;$$) {
my $text = defined( $_[2] ) ? $_[2] : '';
$folder = $self->Massage($folder);
$folder = $self->Quote($folder);
$flags = $self->_clean_flags($flags) if ( defined $flags );
$date = $self->_clean_date($date) if ( defined $date );
$text =~ s/\r?\n/$CRLF/og;
@ -3010,7 +2992,7 @@ sub append_file {
binmode($fh);
$folder = $self->Massage($folder) if ( defined $folder );
$folder = $self->Quote($folder) if ( defined $folder );
$flags = $self->_clean_flags($flags) if ( defined $flags );
# allow the date to be specified or even use mtime on file
@ -3254,7 +3236,7 @@ sub copy {
? $self->Range(@msgs)
: join ',', map { ref $_ ? @$_ : $_ } @msgs;
$self->_imap_uid_command( COPY => $msgs, $self->Massage($target) )
$self->_imap_uid_command( COPY => $msgs, $self->Quote($target) )
or return undef;
my @results = $self->History;
@ -3358,21 +3340,21 @@ sub size {
sub getquotaroot {
my ( $self, $what ) = @_;
my $who = $what ? $self->Massage($what) : "INBOX";
my $who = $what ? $self->Quote($what) : "INBOX";
return $self->_imap_command("GETQUOTAROOT $who") ? $self->Results : undef;
}
# BUG? using user/$User here and INBOX in quota/quota_usage
sub getquota {
my ( $self, $what ) = @_;
my $who = $what ? $self->Massage($what) : "user/" . $self->User;
my $who = $what ? $self->Quote($what) : "user/" . $self->User;
return $self->_imap_command("GETQUOTA $who") ? $self->Results : undef;
}
# usage: $self->setquota($quotaroot, storage => 512, ...)
sub setquota(@) {
my ( $self, $what ) = ( shift, shift );
my $who = $what ? $self->Massage($what) : "user/" . $self->User;
my $who = $what ? $self->Quote($what) : "user/" . $self->User;
my @limits;
while (@_) {
my ( $k, $v ) = ( $self->Quote( uc( shift @_ ) ), shift @_ );
@ -3396,8 +3378,6 @@ sub quota_usage {
return ( map { /.*STORAGE\s+(\d+)\s+\d+.*\n$/ ? $1 : () } @$tref )[0];
}
sub Quote($) { $_[0]->Massage( $_[1], NonFolderArg ) }
# rfc3501:
# atom-specials = "(" / ")" / "{" / SP / CTL / list-wildcards /
# quoted-specials / resp-specials
@ -3408,10 +3388,8 @@ sub Quote($) { $_[0]->Massage( $_[1], NonFolderArg ) }
# CTL ::= <any ASCII control character and DEL, 0x00 - 0x1f, 0x7f>
# Paranoia/safety:
# encode strings with "}" / "[" / "]" / non-ascii chars
sub Massage($;$) {
my ( $self, $name, $notFolder ) = @_;
$name =~ s/^\"(.*)\"$/$1/s unless $notFolder;
sub Quote($) {
my ( $self, $name ) = @_;
if ( $name =~ /["\\[:^ascii:][:cntrl:]]/s ) {
return "{" . length($name) . "}" . $CRLF . $name;
}
@ -3423,6 +3401,13 @@ sub Massage($;$) {
}
}
# legacy behavior: strip double quote around folder name args!
sub Massage($;$) {
my ( $self, $name, $notFolder ) = @_;
$name =~ s/^\"(.*)\"$/$1/s unless $notFolder;
return $self->Quote($name);
}
sub unseen_count {
my ( $self, $folder ) = ( shift, shift );
$folder ||= $self->Folder;

View File

@ -235,8 +235,7 @@ returned by B<Quote>.
Note this method should not be used on folder names for
Mail::IMAPClient methods, since methods that accept folder names as an
argument will quote the folder name arguments appropriately
automatically.
argument will quote the folder name arguments automatically.
If you are getting unexpected results when running methods with values
that have (or might have) embedded spaces, double quotes, braces, or
@ -680,7 +679,8 @@ Example:
The B<compress> method accepts no arguments. This method is used to
instruct the server to use the DEFLATE (RFC1951) compression
extension. See the L</Compress> attribute for how to specify arguments for use during the the initialization process.
extension. See the L</Compress> attribute for how to specify
arguments for use during the initialization process.
Version note: method added in Mail::IMAPClient 3.30
@ -1114,7 +1114,7 @@ context) listing the flags that have been set. Flag names are
provided with leading backslashes.
As of version 1.11, you can supply either a list of message id's or a
reference to an array of of message id's (which means either sequence
reference to an array of message id's (which means either sequence
number, if the Uid parameter is false, or message UID's, if the Uid
parameter is true) instead of supplying a single message sequence
number or UID. If you do, then the return value will not be an array
@ -1412,7 +1412,7 @@ which is just a version of the envelope that's been parsed into a Perl
object.
For more information on how to use this object once you've gotten it,
see the L<Mail::IMAPClient::BodyStructure> documention. (As of this
see the L<Mail::IMAPClient::BodyStructure> documentation. (As of this
writing there is no separate pod document for
B<Mail::IMAPClient::BodyStructure::Envelope>.)
@ -1633,7 +1633,7 @@ Example:
$imap->logout or die "Could not logout: $@\n";
The B<logout> method implements the LOGOUT IMAP client commmand. This
The B<logout> method implements the LOGOUT IMAP client command. This
method causes the server to end the connection and the IMAPClient
client enters the I<Unconnected> state. This method does not, destroy
the IMAPClient object, thus the L</connect> and L</login> methods can
@ -1688,20 +1688,23 @@ Example:
$imap->search(HEADER => 'Message-id' => $imap->Massage($msg_id,1));
WARNING: This method may be deprecated in the future, consider using
L</Quote> instead of this method.
The B<Massage> method accepts a value as an argument and, optionally,
a second value that, when true, indicates that the first argument is
not the name of an existing folder.
WARNING: If the first argument has double quotes at the beginning and
end of its value, those double quote will be stripped unless the
second argument does not evaluate to true.
It returns its argument as a correctly quoted string or a literal
string.
Note that you should rarely use this on folder names, since methods
that accept folder names as an argument will call B<Massage> for
you. In fact, it was originally developed as an undocumented helper
method meant for internal Mail::IMAPClient methods only.
You may also want to see the L</Quote> method, which is related to
this method.
that accept folder names as an argument will call B<Quote> for
you.
=head2 message_count
@ -1840,7 +1843,7 @@ The target ($imap_dest) Mail::IMAPClient object must not be the same
object as the source ($imap_src).
This method does not attempt to minimize memory usage. In the future
it could be enhanced to (optionaly) write message data to a temporary
it could be enhanced to (optionally) write message data to a temporary
file to avoid storing the entire message in memory.
To work around potential network timeouts on large messages, consider
@ -2802,8 +2805,8 @@ their private extensions to the protocol implementation.
=head2 copy($msg, $folder)
Copy a message from the currently selected folder in the the folder
whose name is in C<$folder>
Copy a message from the currently selected folder in the folder whose
name is in C<$folder>
=head2 subscribe($folder)
@ -3482,7 +3485,7 @@ will be used as arguments to IO::Socket::SSL->start_SSL. By default
this connection is set to blocking while establishing the connection
with a timeout of 30 seconds. The socket will be reset to the
original blocking/non-blocking value after a successful TLS
negotiation has occured. The arguments used in the call to start_SSL
negotiation has occurred. The arguments used in the call to start_SSL
can be controlled by setting this attribute to an ARRAY reference
containing the desired arguments.
@ -3514,7 +3517,7 @@ attribute is used in the L</connect> method. The arguments used in
the call to IO::Socket::SSL->new can be controlled by setting this
attribute to an ARRAY reference containing the desired arguments.
See also L</connect> for details on connection initiatiation and
See also L</connect> for details on connection initiation and
L</Socket> and L</Rawsocket> if you need to take more control of
connection management.
@ -3654,18 +3657,34 @@ object, but are particularly useful for determining the cause of
failure when a connection and login are attempted as part of a single
L</new> method invocation. The status methods are:
=head2 Escaped_history
Example:
my @history = $imap->Escaped_history;
The B<Escaped_history> method is almost identical to the B<History>
method. Unlike the B<History> method, however, server output
transmitted literally will be wrapped in double quotes, with all
double quotes, backslashes escaped. If called in a scalar context,
B<Escaped_history> returns an array reference rather than an array.
B<Escaped_history> is useful if you are retrieving output and
processing it manually, and you are depending on the above special
characters to delimit the data. It is not useful when retrieving
message contents; use B<message_string> or B<body_string> for that.
=head2 Escaped_results
Example:
my @results = $imap->Escaped_results;
The B<Escaped_results> method is almost identical to the B<History>
method. Unlike the B<History> method, however, server output
transmitted literally will be wrapped in double quotes, with all of
the parentheses, double quotes, backslashes, newlines, and carriage
returns escaped. If called in a scalar context, B<Escaped_results>
returns an array reference rather than an array.
The B<Escaped_results> method is almost identical to the B<Results>
method. Unlike the B<Results> method, however, server output
transmitted literally will be wrapped in double quotes, with all
double quotes, backslashes escaped. If called in a scalar context,
B<Escaped_results> returns an array reference rather than an array.
B<Escaped_results> is useful if you are retrieving output and
processing it manually, and you are depending on the above special

View File

@ -266,7 +266,7 @@ one argument, a string containing a server response to a FETCH
BODYSTRUCTURE directive.
The module B<Mail::IMAPClient> provides the B<get_bodystructure>
conveniece method to simplify use of this module when starting with
convenience method to simplify use of this module when starting with
just a messages sequence number or unique ID (UID).
=head1 Object Methods
@ -451,7 +451,7 @@ Returns an array of recipients' address structures.
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 analagous method that will return a list of E-Mail addresses
an analogous method that will return a list of E-Mail addresses
instead. The addresses are in the format C<personalname
E<lt>mailboxname@hostnameE<gt>> (see the section on
B<Mail::IMAPClient::BodyStructure::Address>, below) However, if the

View File

@ -5,7 +5,7 @@ package Mail::IMAPClient::MessageSet;
=head1 NAME
Mail::IMAPClient::MessageSet - ranges of message sequence nummers
Mail::IMAPClient::MessageSet - ranges of message sequence numbers
=cut
@ -129,7 +129,7 @@ commands by separating them with commas. For example, "1,2,3,4,5" would
specify messages 1, 2, 3, 4, and (you guessed it!) 5. However, if you are
performing an operation on lots of messages, this string can get quite long.
So long that it may slow down your transaction, and perhaps even cause the
server to reject it. So RFC2060 also permits you to specifiy a range of
server to reject it. So RFC2060 also permits you to specify a range of
messages, so that messages 1, 2, 3, 4 and 5 can also be specified as
"1:5".
@ -244,7 +244,7 @@ then your resulting message set will be the same as the original, only more
expensive. However, if you attempt to remove several messages from the message
set and some of those messages were in the message set and some were not,
the additional overhead of checking for the messages that were not there
is negligable. In either case you get back the message set you want regardless
is negligible. In either case you get back the message set you want regardless
of whether it was already like that or not.
=head1 AUTHOR

41
W/learn/copy Executable file
View File

@ -0,0 +1,41 @@
#!/usr/bin/perl
use warnings;
use strict;
use English;
use Mail::IMAPClient;
my $rcs = '$Id: append,v 1.1 2011/07/14 16:49:02 gilles Exp gilles $ ';
$ARGV[3] or die "usage: $0 host user password folder uid\n";
my $host = $ARGV[0];
my $user = $ARGV[1];
my $password = $ARGV[2];
my $folder_1 = $ARGV[3];
my $folder_2 = $ARGV[4];
my $imap = Mail::IMAPClient->new( );
$imap->Debug( 1 );
$imap->Server( $host );
$imap->connect( ) or die;
$imap->User( $user );
$imap->Password( $password ) ;
$imap->login( ) or die;
$imap->Uid( 1 ) ;
$imap->Peek( 1 ) ;
$imap->Clear( 0 ) ;
#print map {"$_\n"} $imap->folders( ) ;
$imap->select( $folder_1 ) or die ;
my @msgs_1 = $imap->messages ;
print "LIST_1: @msgs_1\n" ;
my $copy = $imap->copy( $folder_2, $msgs_1[0] ) ;
print "copy: $copy\n" ;
$imap->select( $folder_2 ) or die ;
my @msgs_2 = $imap->messages ;
print "LIST_2: @msgs_2\n" ;
$imap->close( ) ;

37
W/learn/hashes_set Executable file
View File

@ -0,0 +1,37 @@
#!/usr/bin/perl -w
use Data::Dumper ;
use strict ;
my %hash_1 = (
'abcd' => 'zzz',
'efgh' => 'zzz',
) ;
my %hash_2 = (
'2345' => 'zzz',
'8888' => 'zzz',
'efgh' => 'zzz',
) ;
print Data::Dumper->Dump( [ \%hash_1 ] ) ;
my %hash_X ;
foreach my $k ( keys( %hash_1 ) ) {
$hash_X{ $k }->{ 'folder_1' } ++ ;
}
foreach my $k ( keys( %hash_2 ) ) {
$hash_X{ $k }->{ 'folder_2'} ++ ;
}
foreach my $k ( keys( %hash_1 ) ) {
$hash_X{ $k }->{ 'folder_1' } ++ ;
}
print Data::Dumper->Dump( [ \%hash_X ] ) ;
print keys( %{ $hash_X{ 'efgh' } } ) ;

20
W/memo
View File

@ -1,6 +1,6 @@
#!/bin/sh
# $Id: memo,v 1.44 2013/07/03 04:14:44 gilles Exp gilles $
# $Id: memo,v 1.45 2013/11/11 19:32:19 gilles Exp gilles $
count_nice() {
@ -212,7 +212,7 @@ export TMPDIR
echo statistics_VERSION_getstats
statistics_VERSION_getstats() {
(
cd /home/imapsync/imapsync_stats
cd $HOME/imapsync_stats
for f in /var/log/apache2/access.log_????????.gz ; do
b=`basename "$f" .gz`
#echo "$b"
@ -228,7 +228,7 @@ statistics_VERSION_monthly_ip() {
month=${1:-`date '+%m'`}
year=${2:-`date '+%Y'`}
(
cd /home/imapsync/imapsync_stats
cd $HOME/imapsync_stats
cut -d ' ' -f 1,12,13,18,19 access.log_${year}${month}??.imapsync_VERSION |sort -n |uniq -c|sort -n > stats_imapsync_${year}_${month}.ip
)
}
@ -238,7 +238,7 @@ statistics_VERSION_monthly_os() {
month=${1:-`date '+%m'`}
year=${2:-`date '+%Y'`}
(
cd /home/imapsync/imapsync_stats
cd $HOME/imapsync_stats
Linux=`grep -i linux stats_imapsync_${year}_${month}.ip | wc -l`
Win32=`grep -i MSWin32 stats_imapsync_${year}_${month}.ip | wc -l`
Darwin=`grep -i darwin stats_imapsync_${year}_${month}.ip | wc -l`
@ -260,7 +260,7 @@ echo "statistics_VERSION_yearly_os 2012 # short"
statistics_VERSION_yearly_os() {
year=${1:-`date '+%Y'`}
(
cd /home/imapsync/imapsync_stats
cd $HOME/imapsync_stats
Linux=`grep -i linux stats_imapsync_${year}.ip | wc -l`
Win32=`grep -i MSWin32 stats_imapsync_${year}.ip | wc -l`
Darwin=`grep -i darwin stats_imapsync_${year}.ip | wc -l`
@ -284,7 +284,7 @@ statistics_VERSION_monthly_ip_wc() {
month=${1:-`date '+%m'`}
year=${2:-`date '+%Y'`}
(
cd /home/imapsync/imapsync_stats
cd $HOME/imapsync_stats
test -f stats_imapsync_${year}_${month}.ip || statistics_VERSION_monthly_ip $month ${year}
wc -l stats_imapsync_${year}_${month}.ip
)
@ -295,7 +295,7 @@ statistics_VERSION_monthly_runs() {
month=${1:-`date '+%m'`}
year=${2:-`date '+%Y'`}
(
cd /home/imapsync/imapsync_stats
cd $HOME/imapsync_stats
wc -l access.log_${year}${month}??.imapsync_VERSION > stats_imapsync_${year}_${month}.runs
cat stats_imapsync_${year}_${month}.runs
)
@ -320,7 +320,7 @@ statistics_VERSION_yearly_ip() {
year=${1:-`date '+%Y'`}
(
statistics_VERSION_getstats
cd /home/imapsync/imapsync_stats
cd $HOME/imapsync_stats
cut -d ' ' -f 1,12,13,18,19 access.log_${year}????.imapsync_VERSION |sort -n |uniq -c|sort -n > stats_imapsync_${year}.ip
)
}
@ -328,7 +328,7 @@ statistics_VERSION_yearly_ip() {
statistics_VERSION_yearly_runs() {
year=${1:-`date '+%Y'`}
(
cd /home/imapsync/imapsync_stats
cd $HOME/imapsync_stats
test -f stats_imapsync_${year}.ip && cat stats_imapsync_${year}.ip | awk '{ sum+=$1 } END {print sum}'
)
}
@ -339,7 +339,7 @@ echo "statistics_VERSION_synthesis 2012 # short"
statistics_VERSION_synthesis() {
year=${1:-`date '+%Y'`}
(
cd /home/imapsync/imapsync_stats
cd $HOME/imapsync_stats
echo Nb users each month
wc -l stats_imapsync_${year}_??.ip
echo Nb runs each month

View File

@ -0,0 +1,38 @@
create_folder {
my( $imap2, $h2_fold, $h1_fold ) = @_ ;
my(@parts, $parent);
print "Creating folder [$h2_fold] on host2\n";
if ( ( 'INBOX' eq uc( $h2_fold) )
and ( $imap2->exists( $h2_fold ) ) ) {
print "Folder [$h2_fold] already exists\n" ;
return( 1 ) ;
}
@parts = split($h2_sep, $h2_fold );
pop( @parts );
$parent = join($h2_sep, @parts );
$parent =~ s/^\s+|\s+$//g ;
if(($parent ne "") and !$imap2->exists( $parent )) {
create_folder( $imap2 , $parent , $h1_fold);
}
if ( ! $dry ){
if ( ! $imap2->create( $h2_fold ) ) {
print( "Couldn't create folder [$h2_fold] from [$h1_fold]: ",
$imap2->LastError( ), "\n" );
$nb_errors++;
# success if folder exists ("already exists" error)
return( 1 ) if $imap2->exists( $h2_fold ) ;
# failure since create failed
return( 0 );
}else{
#create succeeded
return( 1 );
}
}else{
# dry mode, no folder so many imap will fail, assuming failure
return( 0 );
}
}

View File

@ -1,6 +1,6 @@
#!/bin/sh
# $Id: paypal_build_invoices,v 1.56 2013/09/13 10:55:46 gilles Exp gilles $
# $Id: paypal_build_invoices,v 1.60 2013/12/14 17:30:04 gilles Exp gilles $
# usage: sh paypal_build_invoices /g/var/paypal_invoices/????
@ -42,7 +42,9 @@ cp /home/gilles/public_html/AGIL/factures/000/facture_imapsync-000.tex /g/var/pa
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 2682 /g/paypal/paypal_2013_07_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 2741 /g/paypal/paypal_2013_08_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 2820 /g/paypal/paypal_2013_09_complet.csv
/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 2891 /g/paypal/paypal_2013_10_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 2891 /g/paypal/paypal_2013_10_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 2973 /g/paypal/paypal_2013_11_complet.csv
/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 3040 /g/paypal/paypal_2013_12_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 147 /g/paypal/paypal_2010_11_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 214 /g/paypal/paypal_2010_12_complet.csv
@ -73,26 +75,29 @@ cp /home/gilles/public_html/AGIL/factures/000/facture_imapsync-000.tex /g/var/pa
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 2299 /g/paypal/paypal_2013_01_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 2384 /g/paypal/paypal_2013_02_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 2451 /g/paypal/paypal_2013_03_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 2519 /g/paypal/paypal_2013_04_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 2572 /g/paypal/paypal_2013_05_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 2627 /g/paypal/paypal_2013_06_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 2682 /g/paypal/paypal_2013_07_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 2519 /g/paypal/paypal_2013_04_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 2572 /g/paypal/paypal_2013_05_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 2627 /g/paypal/paypal_2013_06_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 2682 /g/paypal/paypal_2013_07_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 2741 /g/paypal/paypal_2013_08_complet.csv
set -x
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 2820 /g/paypal/paypal_2013_09_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 2891 /g/paypal/paypal_2013_10_complet.csv
set -x
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 2973 /g/paypal/paypal_2013_11_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 3040 /g/paypal/paypal_2013_12_complet.csv
set +x
# La totale
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --bnc --debug \
--first_in 147 --avoid_numbers '292 293 643 644 731 732 1093 1330 1331 1332 1333 1334 1652 1653 2131 2132 2295 2296 2297 2298 2625 2626 ' \
--first_in 147 --avoid_numbers '292 293 643 644 731 732 1093 1330 1331 1332 1333 1334 1652 1653 2131 2132 2295 2296 2297 2298 2625 2626 2970 2971 2972' \
/g/paypal/paypal_201?_??_complet.csv
set -v
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan \
--first_in 147 --avoid_numbers '292 293 643 644 731 732 1093 1330 1331 1332 1333 1334 1652 1653 2131 2132 2295 2296 2297 2298 2625 2626 ' \
--first_in 147 --avoid_numbers '292 293 643 644 731 732 1093 1330 1331 1332 1333 1334 1652 1653 2131 2132 2295 2296 2297 2298 2625 2626 2970 2971 2972' \
/g/paypal/paypal_201?_??_complet.csv
set +v
@ -100,12 +105,12 @@ set +v
#echo 2012
#set -v
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan \
--first_in 1335 --usdeur 1.2952 --bnc --avoid_numbers '292 293 643 644 731 732 1093 1330 1331 1332 1333 1334 1652 1653 2131 2132 2295 2296 2297 2298' \
--first_in 1335 --usdeur 1.2952 --bnc --avoid_numbers '1652 1653 2131 2132 2295 2296 2297 2298' \
/g/paypal/paypal_2012_??_complet.csv
#set +v
echo 'sh paypal_build_invoices /g/var/paypal_invoices/2???'
echo 'sh paypal_build_invoices /g/var/paypal_invoices/3???'
# USD de 147 à 340
# EUR de 341 à ...

View File

@ -1,6 +1,6 @@
#!/bin/sh
# $Id: paypal_send_invoices,v 1.9 2013/02/08 14:58:22 gilles Exp gilles $
# $Id: paypal_send_invoices,v 1.10 2013/11/17 06:36:39 gilles Exp gilles $
# usages:
# sh paypal_send_invoices /g/var/paypal_invoices/147
@ -55,5 +55,5 @@ done
echo ==== Saving to ks
rsync -avHz -P /g/var/paypal_invoices/ \
imapsync@ks.lamiral.info:var/paypal_invoices
gilles@ks.lamiral.info:var/paypal_invoices

26
W/pkgnames Normal file
View File

@ -0,0 +1,26 @@
#!/bin/sh
# $Id: pkgnames,v 1.2 2013/10/18 03:59:35 gilles Exp gilles $
MODULE_LIST="
Mail/IMAPClient.pm
Digest/MD5.pm
Term/ReadKey.pm
IO/Socket/SSL.pm
Digest/HMAC_MD5.pm
URI/Escape.pm
File/Copy/Recursive.pm
Data/Uniqid.pm
Authen/NTLM.pm
"
# SEARCH_CMD="urpmf" # Mandriva
SEARCH_CMD=${1:-"apt-file search"}
for module in $MODULE_LIST; do
echo ==== searching for $module ====
echo $SEARCH_CMD $module
$SEARCH_CMD $module
done
# End of pkgnames script.

View File

@ -5,14 +5,16 @@ cd /D %~dp0
REM E:
REM cd .\temp
REM cd \
imapsync.exe --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi --usecache --tmpdir "E:\TEMP" --include "blanc"
REM perl imapsync --tests_debug
perl imapsync --tests
PAUSE
perl imapsync --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi --usecache --tmpdir "E:\TEMP"
REM imapsync.exe --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi --usecache --tmpdir "E:\TEMP" --include "blanc"
REM PAUSE
REM perl imapsync --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi --usecache --tmpdir "E:\TEMP"
REM perl imapsync --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi --usecache
REM rmdir "E:\TEMP\imapsync_cache" /s /q
mkdir "\\?\E:\TEMP\lala"
REM mkdir "\\?\E:\TEMP\01_______\01_______\02_______\03_______\04_______\05_______\06_______\07_______\08_______\09_______\10_______\11_______\12_______\13_______\14_______\15_______\16_______\17_______\18_______\19_______\20_______\21_______\22_______\22_______\24_______\25_______\26_______\27_______\28_______\29_______\30_______\"
perl imapsync --tests_debug --tmpdir "\\?\E:\TEMP\long"
perl imapsync --tests --tmpdir "\\?\E:\TEMP\long"

View File

@ -0,0 +1,14 @@
#!/bin/sh
# $Id: install_modules_linux.sh,v 1.1 2013/11/02 14:00:19 gilles Exp gilles $
perl -MCPAN -e "install Mail::IMAPClient"
perl -MCPAN -e "install Term::ReadKey"
perl -MCPAN -e "install IO::Socket::SSL"
perl -MCPAN -e "install Digest::HMAC_MD5"
perl -MCPAN -e "install URI::Escape"
perl -MCPAN -e "install File::Copy::Recursive"
perl -MCPAN -e "install Data::Uniqid"
perl -MCPAN -e "install Authen::NTLM"

View File

@ -0,0 +1,9 @@
Bonjour Gilles,
Just a quick note to say thank you for a great piece of software. Its good to pay for something that does what it says - nice work!
All accounts migrated without a hitch.
Cheers,
Tim Jones

4
i3
View File

@ -1,7 +1,7 @@
#!/bin/sh
# $Id: i3,v 1.13 2013/09/28 11:50:16 gilles Exp gilles $
# $Id: i3,v 1.14 2013/12/25 03:25:18 gilles Exp gilles $
BASE=`dirname $0`
perl -I${BASE}/W/Mail-IMAPClient-3.34/lib ${BASE}/imapsync "$@"
perl -I${BASE}/W/Mail-IMAPClient-3.35/lib ${BASE}/imapsync "$@"

329
imapsync
View File

@ -5,11 +5,11 @@
# pragmas
# main program
# global variables initialisation
# get_options( ) ;
# default values
# folder loop
# subroutines
# IMAPClient 2.2.9 overrides
# IMAPClient 2.2.9 3.xx ads
# IMAPClient 3.xx ads
# pod documentation
@ -22,7 +22,7 @@ Synchronises mailboxes between two imap servers.
Good at IMAP migration. More than 52 different IMAP server softwares
supported with success, few failures.
$Revision: 1.569 $
$Revision: 1.580 $
=head1 SYNOPSIS
@ -403,7 +403,7 @@ Success stories reported with the following 57 imap servers
- Gimap (Gmail imap)
- GMX IMAP4 StreamProxy.
- Groupwise IMAP (Novell) 6.x and 7.0. Buggy so see the FAQ.
- hMailServer 5.3.3 [host2], 4.4.1 [host1] (see FAQ)
- hMailServer 5.40-B1950 [host12], 5.3.3 [host2], 4.4.1 [host1] (see FAQ)
- IceWarp Server 10.4.5 [host1] (http://www.icewarp.com/)
- iPlanet Messaging server 4.15, 5.1, 5.2
- IMail 7.15 (Ipswitch/Win2003), 8.12, 11.03 [host1]
@ -541,7 +541,7 @@ Entries for imapsync:
Feedback (good or bad) will often be welcome.
$Id: imapsync,v 1.569 2013/10/16 21:58:17 gilles Exp gilles $
$Id: imapsync,v 1.580 2013/12/25 02:52:36 gilles Exp gilles $
=cut
@ -571,7 +571,7 @@ use Errno qw(EAGAIN EPIPE ECONNRESET) ;
use File::Glob qw( :glob ) ;
use IO::File ;
use Time::Local ;
use Time::HiRes qw( time ) ;
use Time::HiRes qw( time sleep ) ;
use Test::More 'no_plan' ;
use IPC::Open3 'open3' ;
#use Unix::Sysexits ;
@ -581,12 +581,13 @@ use IPC::Open3 'open3' ;
my(
$rcs, $pidfile, $pidfilelocking,
$debug, $debugimap, $debugimap1, $debugimap2, $debugcontent, $debugflags,
$debugLIST, $debugsleep, $debugdev,
$debugLIST, $debugsleep, $debugdev, $debugmemory,
$nb_errors,
$host1, $host2, $port1, $port2,
$user1, $user2, $domain1, $domain2,
$password1, $password2, $passfile1, $passfile2,
@folder, @include, @exclude, @folderrec,
@folderfirst, @folderlast,
$prefix1, $prefix2,
@regextrans2, @regexmess, @regexflag,
$flagsCase, $filterflags, $syncflagsaftercopy,
@ -665,13 +666,17 @@ my(
$maxlinelength,
$uidnext_default,
$fixcolonbug,
$create_folder_old,
$maxmessagespersecond,
$maxbytespersecond,
$skipcrossduplicates, $debugcrossduplicates,
);
# main program
# global variables initialisation
$rcs = '$Id: imapsync,v 1.569 2013/10/16 21:58:17 gilles Exp gilles $ ';
$rcs = '$Id: imapsync,v 1.580 2013/12/25 02:52:36 gilles Exp gilles $ ';
$total_bytes_transferred = 0;
$total_bytes_skipped = 0;
@ -719,19 +724,19 @@ sub EX_USAGE {
# @ARGV will be eat by get_options()
my @argv_copy = @ARGV;
get_options();
get_options( ) ;
# $SIG{ INT } = \&catch_continue ;
local $SIG{ INT } = local $SIG{ QUIT } = local $SIG{ TERM } = \&catch_exit ;
$timestart = time( );
$timestart_int = int( $timestart ) ;
$timebefore = $timestart;
$timebefore = $timestart ;
my $timestart_str = localtime( $timestart ) ;
print "Transfer started at $timestart_str\n";
$modules_version = defined($modules_version) ? $modules_version : 1;
print "Transfer started at $timestart_str\n" ;
print "PID is $PROCESS_ID\n" ;
$modules_version = defined( $modules_version ) ? $modules_version : 1 ;
$releasecheck = defined($releasecheck) ? $releasecheck : 1;
@ -784,9 +789,13 @@ $checkmessageexists = 0 if ( not $abletosearch ) ;
$showpasswords = defined( $showpasswords ) ? $showpasswords : 0 ;
$fixslash2 = defined( $fixslash2 ) ? $fixslash2 : 1 ;
$fixInboxINBOX = defined( $fixInboxINBOX ) ? $fixInboxINBOX : 1 ;
$create_folder_old = defined( $create_folder_old ) ? $create_folder_old : 0 ;
$delete2duplicates = 1 if ( $delete2 and ( ! defined( $delete2duplicates ) ) ) ;
$maxmessagespersecond = defined( $maxmessagespersecond ) ? $maxmessagespersecond : 0 ;
$maxbytespersecond = defined( $maxbytespersecond ) ? $maxbytespersecond : 0 ;
print banner_imapsync(@argv_copy);
print "Temp directory is $tmpdir\n";
@ -1084,7 +1093,8 @@ if ( scalar( @include ) ) {
foreach my $include ( @include ) {
my @included_folders = grep { /$include/x } @h1_folders_all ;
add_to_requested_folders( @included_folders ) ;
print "Including folders matching pattern '$include': @included_folders\n" ;
my $included_folders = join( " ", map( "[$_]", @included_folders ) ) ;
print "Including folders matching pattern '$include': " . $included_folders . "\n" ;
}
}
@ -1093,7 +1103,8 @@ if ( scalar( @exclude ) ) {
my @requested_folder = sort( keys( %requested_folder ) ) ;
my @excluded_folders = grep { /$exclude/x } @requested_folder ;
remove_from_requested_folders( @excluded_folders ) ;
print "Excluding folders matching pattern '$exclude': @excluded_folders\n" ;
my $excluded_folders = join( " ", map( "[$_]", @excluded_folders ) ) ;
print "Excluding folders matching pattern '$exclude': " . $excluded_folders . "\n" ;
}
}
@ -1108,9 +1119,7 @@ $checkselectable and do {
}
} ;
my @requested_folder = sort(keys(%requested_folder));
@h1_folders_wanted = @requested_folder;
@h1_folders_wanted = sort_requested_folders( ) ;
#my $h1_namespace = $imap1->namespace() ;
#my $h2_namespace = $imap2->namespace() ;
@ -1194,6 +1203,8 @@ my $begin_transfer_time = time ;
my %uid_candidate_for_deletion ;
my %uid_candidate_no_deletion ;
my %h2_folders_of_md5 = ( ) ;
FOLDER: foreach my $h1_fold ( @h1_folders_wanted ) {
last FOLDER if $imap1->IsUnconnected();
@ -1284,8 +1295,8 @@ FOLDER: foreach my $h1_fold ( @h1_folders_wanted ) {
map ( { "$_->$cache_1_2_ref->{$_} " } keys %$cache_1_2_ref ), " ]\n";
}
my %h1_hash = ();
my %h2_hash = ();
my %h1_hash = () ;
my %h2_hash = () ;
my ( %h1_msgs, %h2_msgs ) ;
@h1_msgs{ @h1_msgs } = ();
@ -1405,6 +1416,13 @@ FOLDER: foreach my $h1_fold ( @h1_folders_wanted ) {
push(@h2_msgs_duplicate, $m);
}
}
# %h2_folders_of_md5
foreach my $md5 ( keys( %h2_hash ) ) {
$h2_folders_of_md5{ $md5 }->{ $h2_fold } ++ ;
}
my $h2_msgs_duplicate_nb = scalar( @h2_msgs_duplicate ) ;
$h2{ $h2_fold }{ 'duplicates_nb' } = $h2_msgs_duplicate_nb ;
@ -1547,16 +1565,20 @@ FOLDER: foreach my $h1_fold ( @h1_folders_wanted ) {
$debug and print "Host2 uidnext: $h2_uidnext\n" ;
$h2_uidguess = $h2_uidnext ;
MESS: foreach my $m_id (@h1_hash_keys_sorted_by_uid) {
last FOLDER if $imap1->IsUnconnected();
last FOLDER if $imap2->IsUnconnected();
last FOLDER if $imap1->IsUnconnected() ;
last FOLDER if $imap2->IsUnconnected() ;
#print "h1_nb_msg_processed: $h1_nb_msg_processed\n" ;
my $h1_size = $h1_hash{$m_id}{'s'};
my $h1_msg = $h1_hash{$m_id}{'m'};
my $h1_idate = $h1_hash{$m_id}{'D'};
unless (exists($h2_hash{$m_id})) {
if ( ( not exists( $h2_hash{ $m_id } ) )
and ( not exists( $h2_folders_of_md5{ $m_id } )
or not $skipcrossduplicates ) ) {
# copy
my $h2_msg = copy_message( $h1_msg, $h1_fold, $h2_fold, $h1_fir_ref, $permanentflags2, $cache_dir ) ;
$h2_folders_of_md5{ $m_id }->{ $h2_fold } ++ ;
if( $delete2 and exists( $h2_folders_from_1_several{ $h2_fold } ) and $h2_msg ) {
print "msg $h2_fold/$h2_msg will cancel deletion [fresh copy] on host2\n" ;
$uid_candidate_no_deletion{ $h2_fold }{ $h2_msg }++ ;
@ -1566,28 +1588,35 @@ FOLDER: foreach my $h1_fold ( @h1_folders_wanted ) {
}
else{
# already on host2
my $h2_msg = $h2_hash{$m_id}{'m'} ;
$debug and print "Host1 found msg $h1_fold/$h1_msg equals Host2 $h2_fold/$h2_msg\n" ;
if ( exists( $h2_hash{ $m_id } ) ) {
my $h2_msg = $h2_hash{$m_id}{'m'} ;
$debug and print "Host1 found msg $h1_fold/$h1_msg equals Host2 $h2_fold/$h2_msg\n" ;
if ( $usecache ) {
$debugcache and print "touch $cache_dir/${h1_msg}_$h2_msg\n" ;
touch( "$cache_dir/${h1_msg}_$h2_msg" )
or croak( "Couldn't touch $cache_dir/${h1_msg}_$h2_msg" ) ;
}
}elsif( exists( $h2_folders_of_md5{ $m_id } ) ) {
my @folders_dup = keys( %{ $h2_folders_of_md5{ $m_id } } ) ;
( $debug or $debugcrossduplicates ) and print "Host1 found msg $h1_fold/$h1_msg is also in Host2 folders @folders_dup\n" ;
}
$total_bytes_skipped += $h1_size ;
$nb_msg_skipped += 1 ;
$h1_nb_msg_processed +=1 ;
if ( $usecache ) {
$debugcache and print "touch $cache_dir/${h1_msg}_$h2_msg\n" ;
touch( "$cache_dir/${h1_msg}_$h2_msg" )
or croak( "Couldn't touch $cache_dir/${h1_msg}_$h2_msg" ) ;
}
}
}
#$debug and print "MESSAGE $m_id\n";
my $h2_msg = $h2_hash{$m_id}{'m'};
if ( exists( $h2_hash{ $m_id } ) ) {
#$debug and print "MESSAGE $m_id\n";
my $h2_msg = $h2_hash{$m_id}{'m'};
sync_flags_fir( $h1_fold, $h1_msg, $h2_fold, $h2_msg, $permanentflags2, $h1_fir_ref, $h2_fir_ref ) ;
sync_flags_fir( $h1_fold, $h1_msg, $h2_fold, $h2_msg, $permanentflags2, $h1_fir_ref, $h2_fir_ref ) ;
# Good
my $h2_size = $h2_hash{$m_id}{'s'};
$debug and print
"Host1 size msg $h1_fold/$h1_msg = $h1_size <> $h2_size = Host2 $h2_fold/$h2_msg\n";
}
last FOLDER if $imap2->IsUnconnected() ;
# Good
my $h2_size = $h2_hash{$m_id}{'s'};
$debug and print
"Host1 size msg $h1_fold/$h1_msg = $h1_size <> $h2_size = Host2 $h2_fold/$h2_msg\n";
if( $delete ) {
my $expunge_message = '' ;
$expunge_message = "and expunged" if ( $expungeaftereach and ( $expunge or $expunge1 ) ) ;
@ -1598,7 +1627,6 @@ FOLDER: foreach my $h1_fold ( @h1_folders_wanted ) {
$imap1->expunge() if ( $expungeaftereach and ( $expunge or $expunge1 ) ) ;
}
}
}
# END MESS: loop
last FOLDER if $imap1->IsUnconnected();
@ -1659,6 +1687,9 @@ $debug and print "Time: ", timenext(), " s\n";
if ( $foldersizesatend ) {
timenext() ;
# Get all folders on host2 again since new were created
@h2_folders_all = sort $imap2->folders();
for ( @h2_folders_all ) { $h2_folders_all{ $_ } = 1 } ;
( $h1_nb_msg_end, $h1_bytes_end ) = foldersizes( "Host1", $imap1, $search1, @h1_folders_wanted ) ;
( $h2_nb_msg_end, $h2_bytes_end ) = foldersizes( "Host2", $imap2, $search2, @h2_folders_from_1_wanted ) ;
}
@ -1691,6 +1722,9 @@ sub size_filtered_flag {
sub sync_flags_fir {
my ( $h1_fold, $h1_msg, $h2_fold, $h2_msg, $permanentflags2, $h1_fir_ref, $h2_fir_ref ) = @_ ;
if ( not defined( $h1_msg ) ) { return( ) } ;
if ( not defined( $h2_msg ) ) { return( ) } ;
my $h1_size = $h1_fir_ref->{$h1_msg}->{"RFC822.SIZE"} ;
return( ) if size_filtered_flag( $h1_size ) ;
@ -2273,8 +2307,8 @@ sub banner_imapsync {
my @argv = @_ ;
my $banner_imapsync = join("",
'$RCSfile: imapsync,v $ ',
'$Revision: 1.569 $ ',
'$Date: 2013/10/16 21:58:17 $ ',
'$Revision: 1.580 $ ',
'$Date: 2013/12/25 02:52:36 $ ',
"\n",localhost_info(), "\n",
"Command line used:\n",
"$0 ", command_line_nopassword( @argv ), "\n",
@ -2408,10 +2442,10 @@ sub examine_folder {
}
sub create_folder {
sub create_folder_old {
my( $imap, $h2_fold, $h1_fold ) = @_ ;
print "Creating folder [$h2_fold] on host2\n";
print "Creating (old way) folder [$h2_fold] on host2\n";
if ( ( 'INBOX' eq uc( $h2_fold) )
and ( $imap->exists( $h2_fold ) ) ) {
print "Folder [$h2_fold] already exists\n" ;
@ -2419,7 +2453,7 @@ sub create_folder {
}
if ( ! $dry ){
if ( ! $imap->create( $h2_fold ) ) {
print( "Couldn't create folder [$h2_fold] from [$h1_fold]: ",
print( "Could not create folder [$h2_fold] from [$h1_fold]: ",
$imap->LastError( ), "\n" );
$nb_errors++;
# success if folder exists ("already exists" error)
@ -2428,15 +2462,61 @@ sub create_folder {
return( 0 );
}else{
#create succeeded
print "Created (old way) folder [$h2_fold] on host2\n";
return( 1 );
}
}else{
# dry mode, no folder so many imap will fail, assuming failure
print "Created (old way) folder [$h2_fold] on host2 $dry_message\n";
return( 0 );
}
}
sub create_folder {
my( $imap2, $h2_fold, $h1_fold ) = @_ ;
my(@parts, $parent);
if ( $create_folder_old ) {
return( create_folder_old( $imap2, $h2_fold, $h1_fold ) ) ;
}
print "Creating folder [$h2_fold] on host2\n";
if ( ( 'INBOX' eq uc( $h2_fold) )
and ( $imap2->exists( $h2_fold ) ) ) {
print "Folder [$h2_fold] already exists\n" ;
return( 1 ) ;
}
@parts = split($h2_sep, $h2_fold );
pop( @parts );
$parent = join($h2_sep, @parts );
$parent =~ s/^\s+|\s+$//g ;
if(($parent ne "") and ! $imap2->exists( $parent )) {
create_folder( $imap2 , $parent , $h1_fold);
}
if ( ! $dry ){
if ( ! $imap2->create( $h2_fold ) ) {
print( "Could not create folder [$h2_fold] from [$h1_fold]: ",
$imap2->LastError( ), "\n" );
$nb_errors++;
# success if folder exists ("already exists" error)
return( 1 ) if $imap2->exists( $h2_fold ) ;
# failure since create failed
return( 0 );
}else{
#create succeeded
print "Created folder [$h2_fold] on host2\n";
return( 1 );
}
}else{
# dry mode, no folder so many imap will fail, assuming failure
print "Created folder [$h2_fold] on host2 $dry_message\n";
return( 0 );
}
}
sub tests_folder_routines {
ok( !is_requested_folder('folder_foo'), 'is_requested_folder folder_foo 1' );
@ -2449,12 +2529,46 @@ sub tests_folder_routines {
ok( @f = add_to_requested_folders('folder_bar', 'folder_toto'), "add result: @f" );
ok( is_requested_folder('folder_bar'), 'is_requested_folder 4' );
ok( is_requested_folder('folder_toto'), 'is_requested_folder 5' );
ok( remove_from_requested_folders('folder_toto'), 'remove_from_requested_folders' );
ok( remove_from_requested_folders('folder_toto'), 'remove_from_requested_folders: ' );
ok( !is_requested_folder('folder_toto'), 'is_requested_folder 6' );
ok( !remove_from_requested_folders('folder_bar'), "remove_from_requested_folders: empty" ) ;
ok( 0 == compare_lists( [ sort_requested_folders( ) ], [] ), 'sort_requested_folders: all empty' ) ;
ok( add_to_requested_folders('M_55'), 'add_to_requested_folders M_55' );
ok( 0 == compare_lists( [ sort_requested_folders( ) ], [ 'M_55' ] ), 'sort_requested_folders: middle' ) ;
@folderfirst = ( 'Z_11' ) ;
ok( 0 == compare_lists( [ sort_requested_folders( ) ], [ 'Z_11', 'M_55' ] ), 'sort_requested_folders: first+middle' ) ;
@folderlast = ( 'A_99' ) ;
ok( 0 == compare_lists( [ sort_requested_folders( ) ], [ 'Z_11', 'M_55', 'A_99' ] ), 'sort_requested_folders: first+middle+last 1' ) ;
ok( add_to_requested_folders('M_55', 'M_44',), 'add_to_requested_folders M_55 M_44' );
ok( 0 == compare_lists( [ sort_requested_folders( ) ], [ 'Z_11', 'M_44', 'M_55', 'A_99' ] ), 'sort_requested_folders: first+middle+last 2' ) ;
@folderfirst = ( 'Z_22', 'Z_11' ) ;
@folderlast = ( 'A_99', 'A_88' ) ;
ok( 0 == compare_lists( [ sort_requested_folders( ) ], [ 'Z_22', 'Z_11', 'M_44', 'M_55', 'A_99', 'A_88' ] ), 'sort_requested_folders: first+middle+last 3' ) ;
return( ) ;
}
sub sort_requested_folders {
my @requested_folders_sorted = () ;
foreach my $folder ( @folderfirst ) {
remove_from_requested_folders( $folder ) ;
}
foreach my $folder ( @folderlast ) {
remove_from_requested_folders( $folder ) ;
}
my @middle = sort( keys( %requested_folder ) ) ;
@requested_folders_sorted = ( @folderfirst, @middle, @folderlast ) ;
return( @requested_folders_sorted ) ;
}
sub is_requested_folder {
my ( $folder ) = @_;
@ -2474,8 +2588,8 @@ sub add_to_requested_folders {
sub remove_from_requested_folders {
my @wanted_folders = @_ ;
foreach my $folder (@wanted_folders) {
delete $requested_folder{$folder} ;
foreach my $folder ( @wanted_folders ) {
delete $requested_folder{ $folder } ;
}
return( keys( %requested_folder ) ) ;
}
@ -3376,6 +3490,11 @@ sub copy_message {
my ( $string, $string_len ) ;
( $string, $string_len ) = message_for_host2( $h1_msg, $h1_fold, $h1_size, $h1_flags, $h1_idate, $h1_fir_ref ) ;
if ( not defined( $string ) and not defined( $string_len ) ) {
print "- msg $h1_fold/$h1_msg skipped. Could not be fetched\n" ;
return( ) ;
}
# Lines two long => do no copy
if ( ( defined ( $maxlinelength ) )
and ( max_line_length( $string ) > $maxlinelength ) ) {
@ -3404,6 +3523,9 @@ sub copy_message {
sync_flags_after_copy( $h1_fold, $h1_msg, $h1_flags, $h2_fold, $new_id, $permanentflags2 ) ;
}
if ( $debugmemory ) {
printf ("Memory consumption: %.1f MiB\n", memory_consumption( ) / 1024 / 1024) ;
}
return( $new_id ) ;
}
@ -3600,7 +3722,7 @@ sub append_message_on_host2 {
printf( "msg %s/%-19s copied to %s/%-10s %.2f msgs/s %s/s %s\n",
$h1_fold, "$h1_msg {$string_len}", $h2_fold, $new_id, $nb_msg_transferred/$time_spent, $rate, $eta );
sleep_if_needed( $time_spent, $total_bytes_transferred, $nb_msg_transferred ) ;
if ( $usecache and $cacheaftercopy and $new_id =~ m{^\d+$}x ) {
$debugcache and print "touch $cache_dir/${h1_msg}_$new_id\n" ;
touch( "$cache_dir/${h1_msg}_$new_id" )
@ -3621,6 +3743,59 @@ sub append_message_on_host2 {
return( ) ;
}
sub sleep_if_needed {
my( $time_spent, $total_bytes_transferred, $nb_msg_transferred ) = @_ ;
my $sleep_max_messages = sleep_max_messages( $nb_msg_transferred, $time_spent, $maxmessagespersecond ) ;
my $sleep_max_bytes = sleep_max_bytes( $total_bytes_transferred, $time_spent, $maxbytespersecond ) ;
my $sleep_max = max( $sleep_max_messages, $sleep_max_bytes ) ;
if ( $sleep_max > 0 ) {
printf( "sleeping %.2f s\n", $sleep_max ) ;
sleep( $sleep_max ) ;
}
}
sub sleep_max_messages {
# how long we have to sleep to go under max_messages_per_second
my( $nb_msg_transferred, $time_spent, $maxmessagespersecond ) = @_ ;
if ( ( not defined( $maxmessagespersecond ) ) or $maxmessagespersecond <= 0 ) { return( 0 ) } ;
my $sleep = ( $nb_msg_transferred / $maxmessagespersecond ) - $time_spent ;
# the sleep must be positive
return( max( 0, $sleep ) ) ;
}
sub tests_sleep_max_messages {
ok( 0 == sleep_max_messages( 4, 2, undef ), 'sleep_max_messages: maxmessagespersecond = undef') ;
ok( 0 == sleep_max_messages( 4, 2, 0 ), 'sleep_max_messages: maxmessagespersecond = 0') ;
ok( 0 == sleep_max_messages( 4, 2, -1 ), 'sleep_max_messages: maxmessagespersecond = -1') ;
ok( 0 == sleep_max_messages( 4, 2, 2 ), 'sleep_max_messages: maxmessagespersecond = 2 max reached') ;
ok( 2 == sleep_max_messages( 8, 2, 2 ), 'sleep_max_messages: maxmessagespersecond = 2 max over') ;
ok( 0 == sleep_max_messages( 2, 2, 2 ), 'sleep_max_messages: maxmessagespersecond = 2 max not reached') ;
return( ) ;
}
sub sleep_max_bytes {
# how long we have to sleep to go under max_bytes_per_second
my( $total_bytes_transferred, $time_spent, $maxbytespersecond ) = @_ ;
if ( ( not defined( $maxbytespersecond ) ) or $maxbytespersecond <= 0 ) { return( 0 ) } ;
my $sleep = ( $total_bytes_transferred / $maxbytespersecond ) - $time_spent ;
# the sleep must be positive
return( max( 0, $sleep ) ) ;
}
sub tests_sleep_max_bytes {
ok( 0 == sleep_max_bytes( 4000, 2, undef ), 'sleep_max_bytes: maxbytespersecond = undef') ;
ok( 0 == sleep_max_bytes( 4000, 2, 0 ), 'sleep_max_bytes: maxbytespersecond = 0') ;
ok( 0 == sleep_max_bytes( 4000, 2, -1 ), 'sleep_max_bytes: maxbytespersecond = -1') ;
ok( 0 == sleep_max_bytes( 4000, 2, 2000 ), 'sleep_max_bytes: maxbytespersecond = 2 max reached') ;
ok( 2 == sleep_max_bytes( 8000, 2, 2000 ), 'sleep_max_bytes: maxbytespersecond = 2 max over') ;
ok( 0 == sleep_max_bytes( 2000, 2, 2000 ), 'sleep_max_bytes: maxbytespersecond = 2 max not reached') ;
return( ) ;
}
# 6 GlobVar: $dry_message $dry $imap1 $h1_nb_msg_deleted $expunge $expunge1
@ -4063,10 +4238,28 @@ sub tests_clean_cache_2 {
sub tests_mkpath {
my $long_path = "123456789/" x 30 ;
ok( (-d "W/tmp/tests/long/$long_path" or mkpath( "W/tmp/tests/long/$long_path" )), 'tests_mkpath: mkpath > 300 char' ) ;
ok( (-d "W/tmp/tests/long/$long_path" and rmtree( "W/tmp/tests/long/" )), 'tests_mkpath: rmtree > 300 char' ) ;
my $long_path_unix = "123456789/" x 30 ;
# \\?\C:\TEMP
my $long_path_2_prefix = $tmpdir || '\\\?\\E:\\TEMP\\' ;
print "long_path_2_prefix: $long_path_2_prefix\n" ;
my $long_path_2 = $long_path_2_prefix . "\\" . "123456789\\" x 30 . 'END';
( 'MSWin32' ne $OSNAME ) and ok( (-d "W/tmp/tests/long/$long_path_unix" or mkpath( "W/tmp/tests/long/$long_path_unix" )), 'tests_mkpath: mkpath > 300 char' ) ;
( 'MSWin32' ne $OSNAME ) and ok( (-d "W/tmp/tests/long/$long_path_unix" and rmtree( "W/tmp/tests/long/" )), 'tests_mkpath: rmtree > 300 char' ) ;
ok( 1 == 1, 'tests_mkpath: 1 == 1' ) ;
( 'MSWin32' eq $OSNAME ) and print "$long_path_2\n" ;
( 'MSWin32' eq $OSNAME ) and ok( ( -d $long_path_2_prefix ), 'tests_mkpath: -d \ small path' ) ;
( 'MSWin32' eq $OSNAME ) and ok( ( -d $long_path_2_prefix and rmtree( $long_path_2_prefix ) ), 'tests_mkpath: rmtree \ > 300 char' ) ;
( 'MSWin32' eq $OSNAME ) and ok( ( -d $long_path_2_prefix or mkpath( "\\\\\?\\E:\\\\TEMP" ) ), 'tests_mkpath: -d \ small path 1' ) ;
( 'MSWin32' eq $OSNAME ) and ok( ( -d $long_path_2 ), 'tests_mkpath: -d \ > 300 char' ) ;
( 'MSWin32' eq $OSNAME ) and ok( ( -d $long_path_2_prefix or mkpath( $long_path_2_prefix ) ), 'tests_mkpath: -d \ small path' ) ;
( 'MSWin32' eq $OSNAME ) and ok( ( -d $long_path_2 or mkpath( $long_path_2 ) ), 'tests_mkpath: mkpath \ > 300 char' ) ;
( 'MSWin32' eq $OSNAME ) and ok( ( -d $long_path_2_prefix and rmtree( $long_path_2_prefix ) ), 'tests_mkpath: rmtree \ > 300 char' ) ;
return( ) ;
}
@ -4752,7 +4945,7 @@ sub check_last_release {
}
sub imapsync_version {
my $rcs_imapsync = '$Id: imapsync,v 1.569 2013/10/16 21:58:17 gilles Exp gilles $ ' ;
my $rcs_imapsync = '$Id: imapsync,v 1.580 2013/12/25 02:52:36 gilles Exp gilles $ ' ;
my $imapsync_version ;
if ( $rcs_imapsync =~ m{,v\s+(\d+\.\d+)}xo ) {
@ -5548,6 +5741,12 @@ Several options are mandatory.
--folder <string> : and this one, etc.
--folderrec <string> : Sync this folder recursively.
--folderrec <string> : and this one, etc.
--folderfirst <string> : Sync this folder first. --folderfirst "Work"
--folderfirst <string> : then this one, etc.
--folderlast <string> : Sync this folder last. --folderlast "[Gmail]/All Mail"
--folderlast <string> : then this one, etc.
--include <regex> : Sync folders matching this regular expression
Blancs like in "foo bar" have to be written "foo\\ bar"
--include <regex> : or this one, etc.
@ -5605,9 +5804,9 @@ Several options are mandatory.
For safety, first try it like this (it is safe):
--delete2folders --dry --justfolders --nofoldersizes
--delete2foldersonly <regex>: Deleted only folders matching regex.
Example: --delete2foldersonly "/Junk$/"
Example: --delete2foldersonly "/^Junk\$|^INBOX.Junk\$/"
--delete2foldersbutnot <regex>: Do not delete folders matching regex.
Example: --delete2foldersbutnot "/Tasks$|Contacts$|Foo$/"
Example: --delete2foldersbutnot "/Tasks\$|Contacts\$|Foo\$/"
--noexpunge : Do not expunge messages on host1.
Expunge really deletes messages marked deleted.
Expunge is made at the beginning, on host1 only.
@ -5757,7 +5956,8 @@ sub get_options {
"debugimap!" => \$debugimap,
"debugimap1!" => \$debugimap1,
"debugimap2!" => \$debugimap2,
"debugdev!" => \$debugdev,
"debugdev!" => \$debugdev,
"debugmemory!" => \$debugmemory,
"host1=s" => \$host1,
"host2=s" => \$host2,
"port1=i" => \$port1,
@ -5779,6 +5979,8 @@ sub get_options {
"folderrec=s" => \@folderrec,
"include=s" => \@include,
"exclude=s" => \@exclude,
"folderfirst=s" => \@folderfirst,
"folderlast=s" => \@folderlast,
"prefix1=s" => \$prefix1,
"prefix2=s" => \$prefix2,
"fixslash2!" => \$fixslash2,
@ -5874,6 +6076,11 @@ sub get_options {
"showpasswords!" => \$showpasswords,
"maxlinelength=i" => \$maxlinelength,
"fixcolonbug!" => \$fixcolonbug,
"create_folder_old!" => \$create_folder_old,
"maxmessagespersecond=f" => \$maxmessagespersecond,
"maxbytespersecond=i" => \$maxbytespersecond,
"skipcrossduplicates!" => \$skipcrossduplicates,
"debugcrossduplicates!" => \$debugcrossduplicates,
);
$debug and print "get options: [$opt_ret]\n";
@ -5908,9 +6115,9 @@ sub tests_debug {
SKIP: {
skip "No test in normal run" if ( not $tests_debug );
tests_filter_forbidden_characters( ) ;
tests_cache_folder( ) ;
tests_tmpdir_has_colon_bug( ) ;
#tests_mkpath( ) ;
tests_sleep_max_messages( ) ;
tests_sleep_max_bytes( ) ;
}
return( ) ;
}
@ -5919,7 +6126,7 @@ sub tests {
SKIP: {
skip "No test in normal run" if (not $tests);
tests_folder_routines();
tests_folder_routines( ) ;
tests_compare_lists();
tests_regexmess();
tests_flags_regex();
@ -5963,6 +6170,8 @@ sub tests {
tests_subject( ) ;
tests_msgs_from_maxmin( ) ;
tests_tmpdir_has_colon_bug( ) ;
tests_sleep_max_messages( ) ;
tests_sleep_max_bytes( ) ;
}
return( ) ;
}

View File

@ -5,7 +5,7 @@
<title>Official imapsync migration tool ( release <!--#exec cmd="cat ./VERSION"--> )</title>
<meta name="generator" content="Bluefish 1.0.7"/>
<meta name="author" content="Gilles LAMIRAL"/>
<meta name="date" content="2013-10-17T03:39:01+0200"/>
<meta name="date" content="2013-12-25T12:16:53+0100"/>
<meta name="copyright" content="None"/>
<meta name="keywords" content="imap, transfert, migration"/>
<meta name="description" content="imap migration tool"/>
@ -29,10 +29,10 @@
<body>
<ul class="none">
<li>Are your <a href="#imap_server_success">imap servers <b>supported</b></a> by imapsync?</li>
<li>Buy <a href="#buy_source"><b>imapsync source code</b></a> (any OS)</li>
<li>Buy <a href="#buy_exe"><b>standalone win32</b></a> <b>imapsync.exe</b> (also <b>works on win64</b>)</li>
<li>Buy <b>full professional</b> <a href="#buy_support">imapsync <b>support</b></a> to successfully perform your migration</li>
<li>Are your <a href="#imap_server_success">imap servers <b>supported</b></a> by imapsync?</li>
</ul>
<div class="center">
@ -81,13 +81,23 @@ for <b>bidirectionnal (2 ways) synchronizations</b>.
<p>Alternatives to imapsync are listed in the <a href="#similar"><b>Similar softwares</b></a> section.
</p>
<p>Imapsync used to be free, open and gratis, before november 2010.
Now imapsync is free, open and not gratis from the homepage.
It is the best decision I've done about imapsync to continue to maintain it.
See detailed explanation and motivation here when
<a href="http://www.linux-france.org/prj/imapsync_list/msg00459.html">I looked for a business model</a>.
"Download and donate if happy" doesn't work well.
"Pay for download and I pay back if unhappy" works well.
</p>
<h2><a id="NUMBERS"></a>Facts and figures for 2011-2013</h2>
<ul>
<li><b>4000 to 5000 </b>users per month (45000 users a year)</li>
<li><b>6 to 25 millions mailboxes transfers per month</b>,
total is 93 millions for 2011, 91 millions for 2012, should be <b>110 millions for end 2013</b></li>
total is 93 millions for 2011, 91 millions for 2012, should be <b>140 millions for end 2013</b></li>
<li><b>Operating systems</b> run by imapsync users:
<ul>
@ -135,7 +145,7 @@ Via the <b>User-agent</b> parameter it also send:</p>
<!--
<ul>
<li><b>1.569</b></li>
<li><b>1.580</b></li>
<li><b>Enhancement</b>: </li>
<li><b>Enhancement</b>: </li>
<li><b>Enhancement</b>: </li>
@ -155,6 +165,20 @@ Via the <b>User-agent</b> parameter it also send:</p>
</ul>
-->
<ul>
<li><b>1.580</b></li>
<li><b>Enhancement</b>: Added <b>--maxmessagespersecond</b> to limit messages tranfer rate and fix <b>office365 throttle limitation</b> (use --maxmessagespersecond 4).</li>
<li><b>Enhancement</b>: Added --maxbytespersecond to limit byte transfer rate.</li>
<li><b>Enhancement</b>: Added --folderfirst string: Sync this folder first. --folderfirst "Work" --folderfirst "Friends"</li>
<li><b>Enhancement</b>: Added --folderlast string: Sync this folder last. --folderlast "[Gmail]/All Mail" etc.</li>
<li><b>Enhancement</b>: Added <b>--skipcrossduplicates</b> to avoid copying messages that are already copied in another folder, good <b>from Gmail to X</b>.</li>
<li><b>Enhancement</b>: Added --debugcrossduplicates to print which messages (UIDs) are skipped with --skipcrossduplicates (and in what other folders they are).</li>
<li><b>Enhancement</b>: Added --debugmemory option that prints memory consumption after each message is copied.</li>
<li><b>Bug fix</b>: Create nested folders in the sense of their path, parent first. Thanks to Erik Torsner.</li>
<li><b>Bug fix</b>: Final statistics were avoided for newly created folders.</li>
<li><b>Bug fix</b>: Do not try to append message if the fetch failed.</li>
</ul>
<ul>
<li><b>1.569</b> Win32 --tmpdir "C:" bugfix</li>
<li><b>Bug fix</b>: On Win32 trailing blanc in cache dir name raized an error. Blanc is now moved to underscore _</li>
@ -544,7 +568,7 @@ lists what may be coded or done in the future.
<form method="get" action="http://www.google.com/search">
<p> <b>Search</b> in the imapsync list <b>archives</b>:
<input type="text" name="q" value="migrate gmail exchange" size="30" />
<input type="text" name="q" value="migrate Gmail Exchange" size="30" />
<input type="hidden" name="as_sitesearch" value="www.linux-france.org/prj/imapsync_list/" />
(change the keywords with your own request and press <b>Enter</b>)
</p>
@ -623,7 +647,7 @@ I like it.
<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.
(<a href="http://www.novell.com/products/groupwise/">http://www.novell.com/products/groupwise/</a>) </li>
<li>hMailServer 5.3.3 [host2], 4.4.1 [host1], HMAILSERVER 5.3.2-B1769 on windows 2003 [hsot2]
<li>hMailServer 5.40-B1950 [host12], 5.3.3 [host2], 4.4.1 [host1], HMAILSERVER 5.3.2-B1769 on windows 2003 [hsot2]
(<a href="http://www.hmailserver.com/">http://www.hmailserver.com/</a>) </li>
<li>IceWarp Server 10.4.5 [host1] (<a href="http://www.icewarp.com/">http://www.icewarp.com/</a>)</li>
<li>iPlanet Messaging server 4.15, 5.1, 5.2
@ -742,7 +766,7 @@ alt="Viewable With Any Browser" />
<!--#config timefmt="%D" -->
<!--#config timefmt="%A %B %d, %Y" -->
<b>This document last modified on <!--#echo var="LAST_MODIFIED" --></b>
($Id: index.shtml,v 1.186 2013/10/17 01:49:59 gilles Exp gilles $)
($Id: index.shtml,v 1.189 2013/12/25 11:35:38 gilles Exp gilles $)
</p>
</body>

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +1,37 @@
Main code has high complexity score (338) at line 1, column 1. Consider refactoring. (Severity: 3)
Code structure is deeply nested at line 1524, column 41. Consider refactoring. (Severity: 3)
Too many arguments at line 1691, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 1706, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 1716, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 1950, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2005, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2061, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2151, column 1. See page 182 of PBP. (Severity: 3)
Expression form of "eval" at line 2776, column 13. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 2994, column 13. See page 161 of PBP. (Severity: 5)
Subroutine "select_msgs" does not end with "return" at line 3135, column 1. See page 197 of PBP. (Severity: 4)
Subroutine "tests_msgs_from_maxmin" does not end with "return" at line 3274, column 1. See page 197 of PBP. (Severity: 4)
Subroutine "copy_message" with high complexity score (21) at line 3351, column 1. Consider refactoring. (Severity: 3)
Too many arguments at line 3351, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 3411, column 1. See page 182 of PBP. (Severity: 3)
Subroutine "tests_subject" does not end with "return" at line 3505, column 1. See page 197 of PBP. (Severity: 4)
Too many arguments at line 3568, column 1. See page 182 of PBP. (Severity: 3)
Hard tabs used at line 4139, column 10. See page 20 of PBP. (Severity: 3)
Expression form of "eval" at line 4410, column 13. See page 161 of PBP. (Severity: 5)
Too many arguments at line 4565, column 1. See page 182 of PBP. (Severity: 3)
Expression form of "eval" at line 5197, column 43. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 5201, column 45. See page 161 of PBP. (Severity: 5)
"$i" is declared but not used at line 5465, column 9. Unused variables clutter code and make it harder to read. (Severity: 3)
Main code has high complexity score (350) at line 1, column 1. Consider refactoring. (Severity: 3)
Expression form of "map" at line 1096, column 51. See page 169 of PBP. (Severity: 4)
Expression form of "map" at line 1106, column 51. See page 169 of PBP. (Severity: 4)
Code structure is deeply nested at line 1542, column 41. Consider refactoring. (Severity: 3)
Too many arguments at line 1722, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 1740, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 1750, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 1984, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2039, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2095, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2185, column 1. See page 182 of PBP. (Severity: 3)
Reused variable name in lexical scope: $imap2 at line 2477, column 9. Invent unique variable names. (Severity: 3)
Regular expression without "/x" flag at line 2493, column 20. See page 236 of PBP. (Severity: 3)
Mixed high and low-precedence booleans at line 2494, column 12. See page 70 of PBP. (Severity: 4)
Expression form of "eval" at line 2890, column 13. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 3108, column 13. See page 161 of PBP. (Severity: 5)
Subroutine "select_msgs" does not end with "return" at line 3249, column 1. See page 197 of PBP. (Severity: 4)
Subroutine "tests_msgs_from_maxmin" does not end with "return" at line 3388, column 1. See page 197 of PBP. (Severity: 4)
Subroutine "copy_message" with high complexity score (24) at line 3465, column 1. Consider refactoring. (Severity: 3)
Too many arguments at line 3465, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 3533, column 1. See page 182 of PBP. (Severity: 3)
Subroutine "tests_subject" does not end with "return" at line 3627, column 1. See page 197 of PBP. (Severity: 4)
Too many arguments at line 3690, column 1. See page 182 of PBP. (Severity: 3)
Subroutine "sleep_if_needed" does not end with "return" at line 3746, column 1. See page 197 of PBP. (Severity: 4)
Reused variable name in lexical scope: $total_bytes_transferred at line 3747, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $nb_msg_transferred at line 3747, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $nb_msg_transferred at line 3759, column 9. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $maxmessagespersecond at line 3759, column 9. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $total_bytes_transferred at line 3780, column 9. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $maxbytespersecond at line 3780, column 9. Invent unique variable names. (Severity: 3)
Mismatched operator at line 4248, column 75. Numeric/string operators and operands should match. (Severity: 3)
Hard tabs used at line 4332, column 10. See page 20 of PBP. (Severity: 3)
Expression form of "eval" at line 4603, column 13. See page 161 of PBP. (Severity: 5)
Too many arguments at line 4758, column 1. See page 182 of PBP. (Severity: 3)
Expression form of "eval" at line 5390, column 43. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 5394, column 45. See page 161 of PBP. (Severity: 5)
"$i" is declared but not used at line 5658, column 9. Unused variables clutter code and make it harder to read. (Severity: 3)

199
tests.sh
View File

@ -1,9 +1,9 @@
#!/bin/sh
# $Id: tests.sh,v 1.227 2013/09/28 11:11:16 gilles Exp gilles $
# $Id: tests.sh,v 1.233 2013/12/25 03:25:18 gilles Exp gilles $
# Example 1:
# CMD_PERL='perl -I./W/Mail-IMAPClient-3.34/lib' sh -x tests.sh
# CMD_PERL='perl -I./W/Mail-IMAPClient-3.35/lib' sh -x tests.sh
# Example 2:
# To select which Mail-IMAPClient within arguments:
@ -23,7 +23,7 @@ echo HOST2=$HOST2
# few debugging tests use:
CMD_PERL_2xx='perl -I./W/Mail-IMAPClient-2.2.9'
CMD_PERL_3xx='perl -I./W/Mail-IMAPClient-3.34/lib'
CMD_PERL_3xx='perl -I./W/Mail-IMAPClient-3.35/lib'
CMD_PERL=${CMD_PERL:-$CMD_PERL_3xx}
@ -78,19 +78,12 @@ no_args() {
$CMD_PERL ./imapsync
}
# list of accounts on plume :
# list of accounts on petite :
# mailbox toto used on first_sync()
# bad_login()
# bad_host()
# mailboxes toto -> titi used on first_sync()
# mailbox titi used on first_sync()
# bad_host()
# locallocal()
# mailbox tata used on locallocal()
# mailbox tata titi on most ll_*() tests
# mailboxes tata -> titi used on locallocal()
# mailboxes tata -> titi on most ll_*() tests
# mailbox tete@est.belle used on big size tests:
# big_folder()
@ -185,6 +178,16 @@ ll_debug() {
--debug --nofoldersizes
}
ll_debugmemory() {
can_send && sendtestmessage
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--debugmemory --nofoldersizes
}
ll_nofoldersizes()
@ -327,6 +330,24 @@ ll_star() {
--folder 'INBOX.backstar\*' --dry --justfolders --debugimap1 --regextrans2 's#\\|\*#_#g'
}
ll_doublequote() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 ks.lamiral.info --user2 tata \
--passfile2 ../../var/pass/secret.tata \
--folder 'INBOX."uni"' --debugimap2 --nofoldersizes --justfolders --ssl1 --ssl2
}
ll_doublequote_rev() {
$CMD_PERL ./imapsync \
--host1 ks.lamiral.info --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 tata \
--passfile2 ../../var/pass/secret.tata \
--foldersizes --ssl1 --ssl2 --justfolders
}
ll_folder_noexist() {
@ -526,7 +547,17 @@ ll_justfolders() {
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--justfolders --nofoldersizes
echo "rm -rf /home/vmail/titi/.new_folder/"
echo "sudo rm -rf /home/vmail/titi/.new_folder/"
}
ll_justfolders_foldersizes() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--justfolders
echo "sudo rm -rf /home/vmail/titi/.new_folder/"
}
@ -1464,7 +1495,7 @@ ll_sep2()
ll_bad_login()
{
! $CMD_PERL ./imapsync \
--host1 $HOST1 --user1 toto \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.toto \
--host2 $HOST2 --user2 notiti \
--passfile2 ../../var/pass/secret.titi
@ -1474,8 +1505,8 @@ ll_bad_login()
ll_bad_host()
{
! $CMD_PERL ./imapsync \
--host1 badhost --user1 toto \
--passfile1 ../../var/pass/secret.toto \
--host1 badhost --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 badhost --user2 titi \
--passfile2 ../../var/pass/secret.titi
@ -2003,6 +2034,8 @@ ll_delete2_reverse() {
--delete2 --expunge2
}
ll_delete_reverse() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 titi \
@ -2013,6 +2046,28 @@ ll_delete_reverse() {
--delete --minage 100 --maxage 300 --noexpungeaftereach
}
ll_maxmessagespersecond() {
ll_delete_reverse
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--folder INBOX \
--maxmessagespersecond 3.3
}
ll_maxbytespersecond() {
ll_delete_reverse
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--folder INBOX \
--maxbytespersecond 10000
}
ll_delete2_minage() {
@ -2061,6 +2116,20 @@ ll_delete2duplicates() {
--delete2duplicates --uidexpunge2
}
ll_duplicates_across_folders() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--folder INBOX.zz_1 \
--folder INBOX.zz_2 \
--folder INBOX.zz_3 \
--skipcrossduplicates --debugcrossduplicates
}
ll_delete2_dev() {
can_send && sendtestmessage titi
@ -2208,6 +2277,16 @@ ll_change_characters_gmail() {
}
ll_blanc_vs_hyphen_gmail() {
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 $HOST2 --user2 titi \
--passfile2 ../../var/pass/secret.titi \
--folder "INBOX.A-B" --folder "INBOX.A B" --folder "INBOX.A.B" --justfolders
}
xxxxx_gmail() {
@ -2390,7 +2469,7 @@ gmail_xxxxx() {
--user2 tata \
--passfile2 ../../var/pass/secret.tata \
--nofoldersizes \
--dry --justfolders --exclude Gmail
--dry --justfolders --exclude Gmail --exclude "blanc\ $"
}
@ -2404,9 +2483,23 @@ gmail() {
--host2 $HOST2 \
--user2 tata \
--passfile2 ../../var/pass/secret.tata \
--exclude Gmail
--exclude Gmail --exclude "blanc\ $"
}
gmail_l_tata() {
! ping -c1 imap.gmail.com || $CMD_PERL ./imapsync \
--host1 imap.gmail.com \
--ssl1 \
--user1 gilles.lamiral@gmail.com \
--passfile1 ../../var/pass/secret.gilles_gmail \
--host2 $HOST2 \
--user2 tata \
--passfile2 ../../var/pass/secret.tata \
--folder INBOX
}
gmail_justfolders() {
! ping -c1 imap.gmail.com || $CMD_PERL ./imapsync \
@ -2417,7 +2510,7 @@ gmail_justfolders() {
--host2 $HOST2 \
--user2 tata \
--passfile2 ../../var/pass/secret.tata \
--justfolders --exclude Gmail
--justfolders --exclude Gmail --exclude "blanc\ $"
}
@ -2447,12 +2540,58 @@ gmail_gmail() {
--ssl2 \
--user2 imapsync.gl@gmail.com \
--passfile2 ../../var/pass/secret.imapsync.gl_gmail \
--justfolders --exclude Gmail
--justfolders --exclude Gmail --exclude "blanc\ $"
}
gmail_gl_gl2() {
! ping -c1 imap.gmail.com || $CMD_PERL ./imapsync \
--host1 imap.gmail.com \
--ssl1 \
--user1 imapsync.gl@gmail.com \
--passfile1 ../../var/pass/secret.imapsync.gl_gmail \
--host2 imap.gmail.com \
--ssl2 \
--user2 imapsync.gl2@gmail.com \
--passfile2 ../../var/pass/secret.imapsync.gl_gmail \
--justfolders --exclude Gmail --exclude "blanc\ $" --dry
}
gmail_gl_gl2_create_folder_old() {
! ping -c1 imap.gmail.com || $CMD_PERL ./imapsync \
--host1 imap.gmail.com \
--ssl1 \
--user1 imapsync.gl@gmail.com \
--passfile1 ../../var/pass/secret.imapsync.gl_gmail \
--host2 imap.gmail.com \
--ssl2 \
--user2 imapsync.gl2@gmail.com \
--passfile2 ../../var/pass/secret.imapsync.gl_gmail \
--justfolders --exclude Gmail --exclude "blanc\ $" \
--create_folder_old --dry --nofoldersizes
}
gmail_gmail_folderfirst() {
! ping -c1 imap.gmail.com || $CMD_PERL ./imapsync \
--host1 imap.gmail.com \
--ssl1 \
--user1 gilles.lamiral@gmail.com \
--passfile1 ../../var/pass/secret.gilles_gmail \
--host2 imap.gmail.com \
--ssl2 \
--user2 imapsync.gl@gmail.com \
--passfile2 ../../var/pass/secret.imapsync.gl_gmail \
--exclude "blanc\ $" --exclude Gmail \
--justfolders --folderfirst INBOX --folderfirst zz --folderlast "[Gmail]/All Mail"
}
gmail_gmail_2() {
gmail_gmail_INBOX() {
! ping -c1 imap.gmail.com || $CMD_PERL ./imapsync \
--host1 imap.gmail.com \
--ssl1 \
@ -2818,6 +2957,17 @@ ll_nofastio()
--folder INBOX --nofastio1 --nofastio2
}
l_office365()
{
$CMD_PERL ./imapsync \
--host1 $HOST1 --user1 tata \
--passfile1 ../../var/pass/secret.tata \
--host2 imap-mail.outlook.com --ssl2 --user2 gilles.lamiral@outlook.com \
--passfile2 ../../var/pass/secret.outlook.com \
--folder INBOX --regextrans2 's/INBOX/tata/' --debugflags
}
##########################
# specific tests
##########################
@ -3439,7 +3589,8 @@ xxxxx_gmail
gmail_xxxxx
gmail
gmail_gmail
gmail_gmail_2
gmail_gmail_INBOX
gmail_gmail_folderfirst
yahoo_xxxx
ll_unknow_option
ll_ask_password