This commit is contained in:
Nick Bebout 2016-01-22 10:52:28 -06:00
parent c16227350f
commit 629adbb8db
113 changed files with 7581 additions and 43297 deletions

View file

@ -1,5 +1,5 @@
#!/bin/cat #!/bin/cat
# $Id: CREDITS,v 1.184 2015/11/05 20:57:21 gilles Exp gilles $ # $Id: CREDITS,v 1.185 2016/01/14 12:23:01 gilles Exp gilles $
If you want to make a donation to me, imapsync author, Gilles LAMIRAL, If you want to make a donation to me, imapsync author, Gilles LAMIRAL,
use any of the following ways: use any of the following ways:

View file

@ -1,17 +1,54 @@
RCS file: RCS/imapsync,v RCS file: RCS/imapsync,v
Working file: imapsync Working file: imapsync
head: 1.670 head: 1.678
branch: branch:
locks: strict locks: strict
gilles: 1.670 gilles: 1.678
access list: access list:
symbolic names: symbolic names:
keyword substitution: kv keyword substitution: kv
total revisions: 670; selected revisions: 670 total revisions: 678; selected revisions: 678
description: description:
---------------------------- ----------------------------
revision 1.670 locked by: gilles; revision 1.678 locked by: gilles;
date: 2016/01/21 19:47:02; author: gilles; state: Exp; lines: +14 -21
README part check.
----------------------------
revision 1.677
date: 2016/01/19 14:55:06; author: gilles; state: Exp; lines: +295 -289
help message easier to copy in README part.
----------------------------
revision 1.676
date: 2016/01/16 05:30:00; author: gilles; state: Exp; lines: +282 -77
Changed basic option list by --help output.
----------------------------
revision 1.675
date: 2016/01/06 01:10:05; author: gilles; state: Exp; lines: +11 -9
Added --errorsmax in --help message.
----------------------------
revision 1.674
date: 2015/12/28 18:31:06; author: gilles; state: Exp; lines: +17 -10
Added --debugssl int. Default is like --debugssl 1 (Only print out errors).
----------------------------
revision 1.673
date: 2015/12/26 02:00:05; author: gilles; state: Exp; lines: +141 -145
Added --timeout1
Added --timeout2 (--timeout still available to set both with the same value)
Added --sslargs1 to pass any ssl parameter for host1 connection.
Added --sslargs2 to pass any ssl parameter for host2 connection.
Example --sslargs1 SSL_verify_mode=1 --sslargs1 SSL_version=SSLv3
Removed --allow3xx option.
----------------------------
revision 1.672
date: 2015/12/10 10:23:49; author: gilles; state: Exp; lines: +9 -8
Added require Encode::Byte to solve "The locale codeset (cp1252) isn't one that perl can decode" on Win32.
----------------------------
revision 1.671
date: 2015/12/09 03:22:46; author: gilles; state: Exp; lines: +48 -47
Added env_proxy call in sub xoauth2() to read proxy settings from environment variable without PERL_LWP_ENV_PROXY=1
----------------------------
revision 1.670
date: 2015/12/03 02:36:41; author: gilles; state: Exp; lines: +11 -12 date: 2015/12/03 02:36:41; author: gilles; state: Exp; lines: +11 -12
Bugfix. logfile missed user2. Bugfix. logfile missed user2.
---------------------------- ----------------------------

20
FAQ.d/.htaccess Normal file
View file

@ -0,0 +1,20 @@
# $Id: .htaccess,v 1.1 2016/01/18 18:13:48 gilles Exp gilles $
AddDescription "<b>Domino</b>." FAQ.Domino.txt
AddDescription "<b>Dovecot</b>." FAQ.Dovecot.txt
AddDescription "<b>Duplicated</b> messages issues." FAQ.Duplicates.txt
AddDescription "<b>Exchange 20xx</b> and <b>Office365</b>." FAQ.Exchange.txt
AddDescription "<b>Changing folders names</b>." FAQ.Folders_Mapping.txt
AddDescription "<b>Flags</b>." FAQ.Flags.txt
AddDescription "<b>Gmail</b> accounts." FAQ.Gmail.txt
AddDescription "<b>ISP</b>." FAQ.ISP.txt
AddDescription "<b>Massive/bulk migrations</b>." FAQ.Massive.txt
AddDescription "<b>Selecting messages</b>." FAQ.Messages_selection.txt
AddDescription "<b>Oracle-UCS</b>." FAQ.Oracle-UCS.txt
AddDescription "<b>Security</b>." FAQ.Security.txt
AddDescription "<b>SmarterMail</b>." FAQ.SmarterMail.txt
AddDescription "<b>Various imap server</b> softwares." FAQ.Various_Server_Softwares.txt
AddDescription "<b>XOAUTH2</b> (<b>Gmail</b>)." FAQ.XOAUTH2.txt

View file

@ -1,9 +1,9 @@
#!/bin/cat #!/bin/cat
# $Id: FAQ.Domino.txt,v 1.4 2015/09/19 08:58:34 gilles Exp gilles $ # $Id: FAQ.Domino.txt,v 1.5 2016/01/18 18:14:12 gilles Exp gilles $
====================================================================== =============================
Imapsync. Domino specific issues and solutions Imapsync tips for Domino.
====================================================================== =============================
====================================================================== ======================================================================

View file

@ -1,8 +1,8 @@
#!/bin/cat #!/bin/cat
$Id: FAQ.Dovecot.txt,v 1.2 2015/07/18 22:35:27 gilles Exp gilles $ $Id: FAQ.Dovecot.txt,v 1.3 2016/01/18 18:14:12 gilles Exp gilles $
======================================================================= =======================================================================
Imapsync. Dovecot specific issues and solutions Imapsync tips for Dovecot. Specific issues and solutions.
======================================================================= =======================================================================

View file

@ -1,8 +1,8 @@
#!/bin/cat #!/bin/cat
$Id: FAQ.Duplicates.txt,v 1.5 2015/09/19 08:59:14 gilles Exp gilles $ $Id: FAQ.Duplicates.txt,v 1.6 2016/01/18 18:14:12 gilles Exp gilles $
====================================================================== ======================================================================
Imapsync and duplicated messages issues. Imapsync tips about duplicated messages issues.
====================================================================== ======================================================================
======================================================================= =======================================================================

View file

@ -1,15 +1,17 @@
#!/bin/cat #!/bin/cat
$Id: FAQ.Exchange.txt,v 1.14 2015/11/30 16:12:18 gilles Exp gilles $ $Id: FAQ.Exchange.txt,v 1.17 2016/01/18 18:14:12 gilles Exp gilles $
======================================================================= =================================================================================
Imapsync. Exchange 20xx and Office365 specific issues and solutions Imapsync tips for Exchange 20xx and Office365. Specific issues and solutions.
======================================================================= =================================================================================
Questions anwswered in this FAQ are: Questions anwswered in this FAQ are:
Q. Can I use imapsync to transfer from or to Exchange or Office365 accounts? Q. Can I use imapsync to transfer from or to Exchange or Office365 accounts?
Q. How to sync from XXX to Exchange 2010/2013 or Office365 Q. How to sync from XXX to Exchange 2010/2013
Q. How to sync from XXX to Office365
Q. For Office365 I have double and triple checked the username and Q. For Office365 I have double and triple checked the username and
password spelling but I still get a "LOGIN failed". Any clue? password spelling but I still get a "LOGIN failed". Any clue?
@ -54,27 +56,22 @@ R. Yes. But IMAP access to a Exchange or Office365 account is not always
part: part:
======================================================================= =======================================================================
Q. How to sync from XXX to Exchange 2010/2013 or Office365 Q. How to sync from XXX to Exchange 2010/2013
R. Here is a command line resume that solves most encountered issues when R. Here is a command line resume that solves most encountered issues when
migrating to Exchange or Office365. To understand or change the migrating to Exchange. To understand or change the details you have
details you have to read next Q/R sections. to read next Q/R sections.
On Windows: On Windows:
imapsync.exe ... ^ imapsync.exe ... ^
--maxsize 10000000 ^ --maxsize 10000000 ^
--maxlinelength 9900 ^
--maxmessagespersecond 4 ^ --maxmessagespersecond 4 ^
--regexflag "s/\\Flagged//g" ^ --regexflag "s/\\Flagged//g" ^
--disarmreadreceipts ^ --disarmreadreceipts ^
--regexmess "s,(.{9900}),$1\r\n,g" --regexmess "s,(.{9900}),$1\r\n,g"
On Unix
imapsync ... --regexmess 's,(.{9900}),$1\r\n,g'
On Unix: On Unix:
imapsync ... \ imapsync ... \
@ -86,13 +83,43 @@ On Unix:
--maxlinelengthcmd 'reformime -r7' --maxlinelengthcmd 'reformime -r7'
On Linux, to get the "reformime" command, install the "maildrop" package. On Linux, to get the "reformime" command, install the "maildrop" package.
In case you don't have it you can use In case you don't have it you can still use
--regexmess 's,(.{9900}),$1\r\n,g' --regexmess 's,(.{9900}),$1\r\n,g'
instead of --maxlinelengthcmd 'reformime -r7' instead of --maxlinelengthcmd 'reformime -r7'
On Windows, no "reformime" is available so messages with too long line length
can be synced to Exchange or Office365 by inserting a CRLF every 9900 =======================================================================
characters on long lines, using --regexmess "s,(.{9900}),$1\r\n,g" Q. How to sync from XXX to Office365
R. Here is a command line resume that solves most encountered issues when
migrating to Office365. It's similar with Exchange except for some
values. To understand or change the details you have to read
next Q/R sections.
On Windows:
imapsync.exe ... ^
--maxsize 45000000 ^
--maxmessagespersecond 4 ^
--regexflag "s/\\Flagged//g" ^
--disarmreadreceipts ^
--regexmess "s,(.{10500}),$1\r\n,g"
On Unix:
imapsync ... \
--maxsize 45000000 \
--maxlinelength 10500 \
--maxmessagespersecond 4 \
--regexflag 's/\\Flagged//g' \
--disarmreadreceipts \
--maxlinelengthcmd 'reformime -r7'
On Linux, to get the "reformime" command, install the "maildrop" package.
In case you don't have it you can use
--regexmess 's,(.{10500}),$1\r\n,g'
instead of --maxlinelengthcmd 'reformime -r7'
======================================================================= =======================================================================
Q. For Office365 I have double and triple checked the username and Q. For Office365 I have double and triple checked the username and
@ -112,7 +139,7 @@ R3. Try with a classic email client like Thunderbird and the same
======================================================================= =======================================================================
Q. Exchange fails with "User is authenticated but not connected". Q. Exchange fails with "User is authenticated but not connected".
R. "The message User is authenticated but not connected is due to a R. "The message User is authenticated but not connected is due to a
bug in the Exchange server's IMAP implementation. If the client bug in the Exchange server's IMAP implementation. If the client
presents a valid user name but an invalid password, the server presents a valid user name but an invalid password, the server
accepts the login, but subsequent commands fail with the accepts the login, but subsequent commands fail with the
@ -164,14 +191,14 @@ R. This error message comes from Exchange IMAP server when it
* Some messages are bigger than the size limit. 10 MB by default * Some messages are bigger than the size limit. 10 MB by default
on Exchange. It can be upped by configuration for Exchange. on Exchange. It can be upped by configuration for Exchange.
If you can't configure this limit then use option If you can't fix this limit on Exchange then use option
--maxsize 10000000 for 10 MB, change it if needed) to tell --maxsize 10000000 for 10 MB, change it if needed) to tell
imapsync to skip those messages. imapsync to skip those messages.
This value is 25 MB by default for Office365 --maxsize 25000000 This value is 45 MB by default for Office365
imapsync ... --maxsize 10000000 # 10 MB for Exchange imapsync ... --maxsize 10000000 # 10 MB for Exchange
imapsync ... --maxsize 25000000 # 25 MB for Office365 imapsync ... --maxsize 45000000 # 45 MB for Office365
* Quota reached. The whole account is full. * Quota reached. The whole account is full.
@ -180,10 +207,15 @@ R. This error message comes from Exchange IMAP server when it
* Some messages have some lines too long. Use option --maxlinelength * Some messages have some lines too long. Use option --maxlinelength
to skip messages whose max line length is over a number of bytes. to skip messages whose max line length is over a number of bytes.
--maxlinelength 1000 is a RFC2822 must but most server support --maxlinelength 1000 is a RFC2822 must but most server support
higher values. Exchange supports 9900: higher values.
Exchange supports 9900 characters line length:
imapsync ... --maxlinelength 9900 imapsync ... --maxlinelength 9900
Office365 supports 10500 characters line length:
imapsync ... --maxlinelength 10500
In case you prefer fixing messages with long lines the hard way, In case you prefer fixing messages with long lines the hard way,
instead of skipping them with --maxlinelength 9900, just use: instead of skipping them with --maxlinelength 9900, just use:

View file

@ -1,9 +1,9 @@
#!/bin/cat #!/bin/cat
$Id: FAQ.Flags.txt,v 1.4 2015/07/18 22:35:27 gilles Exp gilles $ $Id: FAQ.Flags.txt,v 1.6 2016/01/18 18:14:12 gilles Exp gilles $
====================================================================== ===============================
Imapsync and flags Imapsync tips about flags.
====================================================================== ===============================
Questions answered here are: Questions answered here are:
@ -222,15 +222,15 @@ R. Filter flag \FORWARDED with --regexflag like this:
On Windows: On Windows:
imapsync ... --regexflag "s/\\FORWARDED//g" imapsync ... --regexflag "s/\\FORWARDED//gi"
On Unix: On Unix:
imapsync ... --regexflag 's/\\FORWARDED//g' imapsync ... --regexflag 's/\\FORWARDED//gi'
or or
imapsync ... --regexflag "s/\\\\FORWARDED//g" imapsync ... --regexflag "s/\\\\FORWARDED//gi"
======================================================================= =======================================================================

View file

@ -1,9 +1,17 @@
#!/bin/cat #!/bin/cat
$Id: FAQ.Folders_Mapping.txt,v 1.8 2015/12/03 02:37:45 gilles Exp gilles $ $Id: FAQ.Folders_Mapping.txt,v 1.9 2016/01/18 18:14:12 gilles Exp gilles $
===============================================
Imapsync tips about changing folders names.
===============================================
Folders names are by default reproduced identical except for
the prefix and the separator which are automatically adapted
for host2.
Before using --regextrans2 you should consider using --automap
and -f1f2 because they are simpler to understand and use.
======================================================================
Imapsync. Changing folders names
======================================================================
Things to know and understand before playing with --regextrans2 Things to know and understand before playing with --regextrans2

View file

@ -1,25 +1,40 @@
#!/bin/cat #!/bin/cat
$Id: FAQ.Gmail.txt,v 1.13 2015/11/05 21:01:12 gilles Exp gilles $ $Id: FAQ.Gmail.txt,v 1.18 2016/01/18 18:14:12 gilles Exp gilles $
====================================================================== =====================================
Imapsync with Gmail Imapsync tips for Gmail accounts.
====================================================================== =====================================
Questions anwswered in this FAQ are: Questions anwswered in this FAQ are:
Q. Can I use imapsync to transfer from or to Gmail accounts? Q. Can I use imapsync to transfer from or to Gmail accounts?
Q. How to synchronize from Gmail to Gmail? Q. How to synchronize from Gmail to Gmail?
Q. How to synchronize from XXX to Gmail? Q. How to synchronize from XXX to Gmail?
Q. How to synchronize from Gmail to XXX? Q. How to synchronize from Gmail to XXX?
Q. Can I use the Extension of the SEARCH command: X-GM-RAW described at
https://support.google.com/mail/answer/7190?hl=en
Q. How to avoid the [IMAP] prefix on Gmail side? Q. How to avoid the [IMAP] prefix on Gmail side?
Q. I can't authenticate with Gmail via IMAP Q. I can't authenticate with Gmail via IMAP
and Gmail says "Please log in via your web browser" and Gmail says "Please log in via your web browser"
Q. Can not open imap connection on [imap.gmail.com] Q. Can not open imap connection on [imap.gmail.com]
Q. Gmail does not really delete messages in folder [Gmail]/All Mail Q. Gmail does not really delete messages in folder [Gmail]/All Mail
Q. Does imapsync have the capability to do 2 stage authentication? Q. Does imapsync have the capability to do 2 stage authentication?
Q. How to use XOAUTH2 to globally authenticate gmail users? Q. How to use XOAUTH2 to globally authenticate gmail users?
Q. How to use XOAUTH to globally authenticate gmail users? Q. How to use XOAUTH to globally authenticate gmail users?
Q. How to use a Gmail account to backup several different imap accounts? Q. How to use a Gmail account to backup several different imap accounts?
Q. How to migrate email from gmail to google apps? Q. How to migrate email from gmail to google apps?
======================================================================= =======================================================================
@ -48,6 +63,7 @@ R. Use the following example:
--user2 account2@gmail.com \ --user2 account2@gmail.com \
--password2 gmailsecret2 \ --password2 gmailsecret2 \
--exitwhenover 500000000 \ --exitwhenover 500000000 \
--automap \
--exclude "\[Gmail\]$" --exclude "\[Gmail\]$"
@ -57,14 +73,32 @@ Explanations:
imap ssl connections. imap ssl connections.
--exitwhenover 500000000 ( ~500 MB ) option is here to avoid --exitwhenover 500000000 ( ~500 MB ) option is here to avoid
locking or errors when transfers exceed maximum limit. locking or errors when imap transfers exceed maximum limit.
See http://support.google.com/a/bin/answer.py?hl=en&answer=1071518 See http://support.google.com/a/bin/answer.py?hl=en&answer=1071518
--exitwhenover is not mandatory in the sense you may be able to --exitwhenover is not mandatory in the sense Gmail may allow you
use an upper value than 500 MB without disconnections; I don't to use an upper value than 500 MB without disconnections; I don't
know the hard value, it seems to vary, so just have some tries know the hard value, it seems to vary, so just have some tries
and report me what you discover in case you detect something and report me what you discover in case you detect something
reliable. reliable.
--automap is not mandatory but it's a feature to automatically
map folder names based on the Gmail user configuration itself, par account.
For example, imap folder "[Gmail]/Sent Mail" may be mapped as one of
E-mails enviados
Enviada
Enviado
Gesendet
Gönderildi
Inviati
Sendt
Skickat
Verzonden
etc.
on both sides, host1 or host2, maybe differently, sometimes in
incomprehensible alphabets, a headache for imap sysadmins.
See a listing here:
http://stackoverflow.com/questions/2185391/localized-gmail-imap-folders/2185548#2185548
--exclude "\[Gmail\]$" is just there to avoid a warning error --exclude "\[Gmail\]$" is just there to avoid a warning error
when selecting this not used folder. when selecting this not used folder.
@ -87,13 +121,13 @@ imapsync --host1 mail.oldhost.com \
--ssl2 \ --ssl2 \
--exitwhenover 500000000 \ --exitwhenover 500000000 \
--maxsize 25000000 \ --maxsize 25000000 \
--automap \
--expunge1 \ --expunge1 \
--addheader \ --addheader \
--exclude "\[Gmail\]$" \ --exclude "\[Gmail\]$" \
--regextrans2 "s/[ ]+/_/g" \ --regextrans2 "s/[ ]+/_/g" \
--regextrans2 "s/[\^]/_/g" \ --regextrans2 "s/[\^]/_/g" \
--regextrans2 "s/['\"\\\\]/_/g" \ --regextrans2 "s/['\"\\\\]/_/g"
--regextrans2 "s,^Sent$,[Gmail]/Sent Mail,"
Explanations: Explanations:
@ -112,6 +146,9 @@ up to 25 MB. This value increases over time, it was 10 MB some
years ago so you can try higher values. The Gmail page about years ago so you can try higher values. The Gmail page about
this limit is https://support.google.com/mail/answer/6584 this limit is https://support.google.com/mail/answer/6584
--automap is optional but it will save manual folder names
changes or the use of --regextrans2 to map folder names.
--expunge1 is optional. It deletes messages marked \Deleted on host1. --expunge1 is optional. It deletes messages marked \Deleted on host1.
Imapsync syncs messages with all their flags, Gmail takes the messages Imapsync syncs messages with all their flags, Gmail takes the messages
marked \Deleted but deletes or moves them just after. marked \Deleted but deletes or moves them just after.
@ -149,22 +186,14 @@ not accepted by gmail, character ^ to character _ underscore.
--regextrans2 "s/['\"\\\\]/_/g" is optional. It converts --regextrans2 "s/['\"\\\\]/_/g" is optional. It converts
characters ' or " or \ to character _ underscore. characters ' or " or \ to character _ underscore.
--regextrans2 "s,^Sent$,[Gmail]/Sent Mail," is to transform the
folder name "Sent" and adapt it to Gmail "Sent Mail" folder.
If you're using a different language in Gmail you might adapt
this example with the folder name translated, an example in French:
imapsync ...
--regextrans2 "s,^Messages envoy&AOk-s$,[Gmail]/Messages envoy&AOk-s," \
You can add --folder "INBOX.Sent" in the example in case You can add --folder "INBOX.Sent" in the example in case
you want to sync only the "Sent" folder. you want to sync only the "Sent" folder.
You can select folders exported to imap within the gmail preferences, You can select folders exported to imap within the gmail preferences.
unselect some "System labels", depending on your needs. Select or unselect some "System labels", depending on your needs.
The "All Mail" archive pseudo-folder should be updated automatically.
======================================================================= =======================================================================
@ -183,6 +212,7 @@ R. Use this example:
--exitwhenover 2500000000 \ --exitwhenover 2500000000 \
--useheader="X-Gmail-Received" \ --useheader="X-Gmail-Received" \
--useheader "Message-Id" \ --useheader "Message-Id" \
--automap \
--regextrans2 "s,\[Gmail\].,," \ --regextrans2 "s,\[Gmail\].,," \
--skipcrossduplicates \ --skipcrossduplicates \
--folderfirst "Work" \ --folderfirst "Work" \
@ -211,6 +241,8 @@ have changed) that Gmail always adds a different header
by imapsync can not fail using this header. "Message-Id" is there by imapsync can not fail using this header. "Message-Id" is there
for safety about this Gmail rule. for safety about this Gmail rule.
--automap is optional but it will save manual folder names
changes or the use of --regextrans2 to map folder names.
--regextrans2 "s,\[Gmail\].,," --regextrans2 "s,\[Gmail\].,,"
If your destination imap server doesn't like "[Gmail]" name, If your destination imap server doesn't like "[Gmail]" name,
@ -244,6 +276,23 @@ label CanWait and only it.
--skipcrossduplicates, will only put in "[Gmail]/All Mail" --skipcrossduplicates, will only put in "[Gmail]/All Mail"
the messages that are not labeled at all. the messages that are not labeled at all.
=======================================================================
Q. Can I use the Extension of the SEARCH command: X-GM-RAW described at
https://support.google.com/mail/answer/7190?hl=en
https://developers.google.com/gmail/imap_extensions#extension_of_the_search_command_x-gm-raw
R. Sure. Example, to search only emails with attachment and in unread state:
On Unix:
imapsync ... --search 'X-GM-RAW "has:attachment in:unread"'
On Windows:
imapsync.exe ... --search "X-GM-RAW ""has:attachment in:unread"""
======================================================================= =======================================================================
Q. How to avoid the [IMAP] prefix on Gmail side? Q. How to avoid the [IMAP] prefix on Gmail side?
How to stop creating folder with this prefix? How to stop creating folder with this prefix?
@ -277,19 +326,21 @@ Q. Can not open imap connection on [imap.gmail.com]:
R0. It looks like this issue is related to ipv6. Both ipv4 and ipv6 R0. It looks like this issue is related to ipv6. Both ipv4 and ipv6
protocols should work with gmail and imapsync, I test that regurlarly, protocols should work with gmail and imapsync, I test that regurlarly,
imapsync works fine for both ipv4 and ipv6. imapsync works fine for both ipv4 and ipv6.
If you disable ipv6 then disable also ipv6 resolution or at least If you disable ipv6 then disable also ipv6 resolution!
make ipv4 answers be taken before ipv6 since default resolution Or at least, make ipv4 answers be taken before ipv6 since the default
order is to take ipv6 resolution if any. names resolution order is to present ipv6 name resolutions first.
R1. A first simple solution is to use directly gmail ipv4 ip address: R1. A first simple solution is to use directly gmail ipv4 ip address:
imapsync ... --host1 74.125.133.108 imapsync ... --host1 74.125.133.108
In case it changes, get with any command showing the imap.gmail.com resolution In case it changes, get with any command showing the imap.gmail.com
name resolution:
nslookup imap.gmail.com nslookup imap.gmail.com
host imap.gmail.com host imap.gmail.com
ping imap.gmail.com ping imap.gmail.com
Or go to http://ping.eu/nslookup/ to get the resolution. Or go to http://ping.eu/nslookup/ to get the resolution.
R2. Fix imapsync with the line: R2. Fix imapsync with the line:

View file

@ -1,9 +1,9 @@
#!/bin/cat #!/bin/cat
$Id: FAQ.ISP.txt,v 1.2 2015/10/21 15:23:07 gilles Exp gilles $ $Id: FAQ.ISP.txt,v 1.3 2016/01/18 18:14:12 gilles Exp gilles $
================================================= =========================================================
Imapsync. ISP specific issues and solutions Imapsync tips for ISP. Specific issues and solutions.
================================================= =========================================================
* IMAPSync - usage scenario with ISP - by Flávio Zarur Lucarelli. * IMAPSync - usage scenario with ISP - by Flávio Zarur Lucarelli.

View file

@ -1,9 +1,9 @@
#!/bin/cat #!/bin/cat
$Id: FAQ.Massive.txt,v 1.5 2015/11/05 14:46:20 gilles Exp gilles $ $Id: FAQ.Massive.txt,v 1.6 2016/01/18 18:14:12 gilles Exp gilles $
====================================================================== ==============================================
Imapsync for massive migrations Imapsync tips for massive/bulk migrations.
====================================================================== ==============================================
Questions answered here are: Questions answered here are:

View file

@ -1,9 +1,11 @@
#!/bin/cat #!/bin/cat
$Id: FAQ.Messages_selection.txt,v 1.2 2015/10/21 15:39:57 gilles Exp gilles $ $Id: FAQ.Messages_selection.txt,v 1.3 2016/01/18 18:14:12 gilles Exp gilles $
==================================== =====================================
Imapsync. How to select messages Imapsync tips to select messages.
==================================== =====================================
By default, Imapsync syncs all messages, avoiding duplicates.
======================================================================= =======================================================================
Q. Is there a way we can specify a date range to sync emails? Q. Is there a way we can specify a date range to sync emails?

View file

@ -1,15 +1,16 @@
#!/bin/cat #!/bin/cat
$Id: FAQ.Oracle-UCS.txt,v 1.1 2015/07/20 04:34:32 gilles Exp gilles $ $Id: FAQ.Oracle-UCS.txt,v 1.2 2016/01/18 18:14:12 gilles Exp gilles $
======================================================================= ==================================================
Imapsync. Oracle-UCS specific issues and solutions Imapsync tips for Oracle-UCS. Specific issues.
======================================================================= ==================================================
Oracle-UCS was previously Sun JES, IPlanet, etc. Oracle-UCS was previously Sun JES, IPlanet, etc.
"NO Message contains NUL characters" "NO Message contains NUL characters"
--skipmess 'm/(\x00)+\Z/' --skipmess 'm/(\x00)+\Z/'
"Message contains invalid header" "Message contains invalid header"
--skipmess 'm/[\x80-\xff]/' --skipmess 'm/[\x80-\xff]/'

View file

@ -1,9 +1,9 @@
#!/bin/cat #!/bin/cat
# $Id: FAQ.Security.txt,v 1.1 2015/10/21 14:18:27 gilles Exp gilles $ # $Id: FAQ.Security.txt,v 1.3 2016/01/18 18:14:12 gilles Exp gilles $
====================================================================== =======================================================
Imapsync. Security issues and solutions Imapsync tips about security. Issues and solutions.
====================================================================== =======================================================
====================================================================== ======================================================================
@ -16,6 +16,13 @@ R1. In function "sub set_ssl", replace
by by
IO::Socket::SSL::SSL_VERIFY_PEER() IO::Socket::SSL::SSL_VERIFY_PEER()
R2. After imapsync 1.673, for example
to set SSL_verify_mode to SSL_VERIFY_PEER on host1
and SSL_verify_mode to SSL_VERIFY_NONE on host2
imapsync ... --ssl1 --ssl2 \
--sslargs1 SSL_verify_mode=1 \
--sslargs2 SSL_verify_mode=0 \
C1. Don't do this in function "sub set_tls" since it won't work by principle, C1. Don't do this in function "sub set_tls" since it won't work by principle,
tls is done AFTER the application level connexion is established tls is done AFTER the application level connexion is established

8
FAQ.d/FAQ.SmarterMail.txt Executable file → Normal file
View file

@ -1,9 +1,9 @@
#!/bin/cat #!/bin/cat
$Id: FAQ.SmarterMail.txt,v 1.6 2015/11/30 02:58:25 gilles Exp gilles $ $Id: FAQ.SmarterMail.txt,v 1.7 2016/01/18 18:14:12 gilles Exp gilles $
======================================================================= =================================================================
Imapsync. SmarterMail specific issues and solutions Imapsync tips for SmarterMail. Specific issues and solutions.
======================================================================= =================================================================
======================================================================= =======================================================================

View file

@ -1,9 +1,9 @@
#!/bin/cat #!/bin/cat
$Id: FAQ.Various_Server_Softwares.txt,v 1.2 2015/10/21 15:41:41 gilles Exp gilles $ $Id: FAQ.Various_Server_Softwares.txt,v 1.3 2016/01/18 18:14:12 gilles Exp gilles $
======================================================================= ====================================================
Imapsync. Server software specific issues and solutions Imapsync tips for various imap server softwares.
======================================================================= ====================================================

View file

@ -1,9 +1,9 @@
#!/bin/cat #!/bin/cat
$Id: FAQ.XOAUTH2.txt,v 1.6 2015/11/30 23:40:10 gilles Exp gilles $ $Id: FAQ.XOAUTH2.txt,v 1.8 2016/01/18 18:14:12 gilles Exp gilles $
======================================================================= ======================================================================
Imapsync. Using XOAUTH2 and XOAUTH authentication (Gmail) Imapsync tips to use XOAUTH2 authentication (Gmail) and old XOAUTH
======================================================================= ======================================================================
======================================================================= =======================================================================
@ -12,7 +12,10 @@ Q. Is XOAUTH2 authentication available with imapsync?
R. Yes, but XOAUTH2 has been really tested on Unix systems, R. Yes, but XOAUTH2 has been really tested on Unix systems,
less profund on Windows but it should work. less profund on Windows but it should work.
First, consider the XOAUTH2 feature at a prototype level. =======================================================================
Q. How to use XOAUTH2 to globally authenticate gmail users?
R. First, consider the XOAUTH2 feature at a prototype level.
Perl modules needed for xoauth2 are: Perl modules needed for xoauth2 are:
Crypt::OpenSSL::RSA Crypt::OpenSSL::RSA
@ -20,11 +23,12 @@ Perl modules needed for xoauth2 are:
JSON::WebToken JSON::WebToken
LWP LWP
HTML::Entities HTML::Entities
Encode::Byte
A easy way to install or upgrade Perl modules is to use cpanm command, A easy way to install or upgrade Perl modules is to use cpanm command,
also called cpanminus. also called cpanminus.
sudo cpanm JSON::WebToken JSON Crypt::OpenSSL::RSA LWP HTML::Entities sudo cpanm JSON::WebToken JSON Crypt::OpenSSL::RSA LWP HTML::Entities Encode::Byte
The code and first explanation comes from Joaquin Lopez at The code and first explanation comes from Joaquin Lopez at
https://github.com/imapsync/imapsync/pull/25 https://github.com/imapsync/imapsync/pull/25
@ -35,12 +39,13 @@ convert the pk12 file.
On Windows I've tried xoauth2 with openssl from On Windows I've tried xoauth2 with openssl from
https://slproweb.com/download/Win32OpenSSL-1_0_2d.exe at https://slproweb.com/download/Win32OpenSSL-1_0_2d.exe at
https://slproweb.com/products/Win32OpenSSL.html https://slproweb.com/products/Win32OpenSSL.html
It works.
Here is a complete example for Gmail. It is a little stupid Here is a complete example for Gmail. It is a little stupid
since it is the same account as source and destination. since it is the same account as source and destination but
it's just to get the picture for xoauth2 authentication.
All xoauth2 is given via the --password1 parameter. All xoauth2 config is given via the --password1 parameter.
It has the form: It has the form:
--password1 "A;B;C" --password1 "A;B;C"
@ -65,6 +70,22 @@ imapsync \
Use your own xoauth2 values. Use your own xoauth2 values.
=======================================================================
Q. How to use a proxy with XOAUTH2 authentication?
With imapsync 1.670, you have to set two environment variables
PERL_LWP_ENV_PROXY and https_proxy. Example:
PERL_LWP_ENV_PROXY=1 https_proxy=http://myproxy:8080/ imapsync --host1 ...
With later release than 1.670, you have to set only the https_proxy
environment variable, if it isn't already set. Example:
https_proxy=http://myproxy:8080/ imapsync --host1 ...
======================================================================= =======================================================================
Q. How to use XOAUTH to globally authenticate gmail users? Q. How to use XOAUTH to globally authenticate gmail users?

23
INSTALL
View file

@ -1,4 +1,4 @@
# $Id: INSTALL,v 1.48 2015/07/18 20:25:03 gilles Exp gilles $ # $Id: INSTALL,v 1.50 2016/01/21 15:06:34 gilles Exp gilles $
# #
# This is the main INSTALL file for imapsync. # This is the main INSTALL file for imapsync.
# imapsync : IMAP sync and migrate tool. # imapsync : IMAP sync and migrate tool.
@ -31,7 +31,6 @@ also available at http://imapsync.lamiral.info/INSTALL.d/
- CPanel - CPanel
- Debian - Debian
- Ubuntu - Ubuntu
- Mandriva
If you are not on one of these systems then read the section If you are not on one of these systems then read the section
below called "Installing imapsync on other Unixes". below called "Installing imapsync on other Unixes".
@ -40,7 +39,7 @@ below called "Installing imapsync on other Unixes".
== Installing imapsync on Mac OS X == == Installing imapsync on Mac OS X ==
===================================== =====================================
Not easy. Easy.
Read the file INSTALL.d/INSTALL.Darwin.txt Read the file INSTALL.d/INSTALL.Darwin.txt
Also available at Also available at
http://imapsync.lamiral.info/INSTALL.d/INSTALL.Darwin.txt http://imapsync.lamiral.info/INSTALL.d/INSTALL.Darwin.txt
@ -55,7 +54,6 @@ Also available at
http://imapsync.lamiral.info/INSTALL.d/INSTALL.FreeBSD.txt http://imapsync.lamiral.info/INSTALL.d/INSTALL.FreeBSD.txt
=================================== ===================================
== Installing imapsync on CentOS == == Installing imapsync on CentOS ==
=================================== ===================================
@ -80,7 +78,7 @@ http://imapsync.lamiral.info/INSTALL.d/INSTALL.CPanel.txt
== Installing imapsync on Debian 6 or 7 == == Installing imapsync on Debian 6 or 7 ==
========================================== ==========================================
Not easy. Not so easy.
See the file INSTALL.d/INSTALL.Debian.txt See the file INSTALL.d/INSTALL.Debian.txt
Also available at Also available at
http://imapsync.lamiral.info/INSTALL.d/INSTALL.Debian.txt http://imapsync.lamiral.info/INSTALL.d/INSTALL.Debian.txt
@ -89,19 +87,11 @@ http://imapsync.lamiral.info/INSTALL.d/INSTALL.Debian.txt
== Installing imapsync on Ubuntu 12 or 14 == == Installing imapsync on Ubuntu 12 or 14 ==
============================================ ============================================
Not easy. Not so easy.
See the file INSTALL.d/INSTALL.Ubuntu.txt See the file INSTALL.d/INSTALL.Ubuntu.txt
Also available at Also available at
http://imapsync.lamiral.info/INSTALL.d/INSTALL.Ubuntu.txt http://imapsync.lamiral.info/INSTALL.d/INSTALL.Ubuntu.txt
=====================================
== Installing imapsync on Mandriva ==
=====================================
See the file INSTALL.d/INSTALL.Mandriva.txt
Also available at
http://imapsync.lamiral.info/INSTALL.d/INSTALL.Mandriva.txt
========================================= =========================================
== Installing imapsync on other Unixes == == Installing imapsync on other Unixes ==
@ -146,6 +136,11 @@ You may be in one of following cases:
In the previous cases, you have to reinit cpan in order to use In the previous cases, you have to reinit cpan in order to use
your local account: your local account:
FIX. The following commands can be replaced by what is described in
"Installing imapsync script on Darwin / Mac OS X"
at http://imapsync.lamiral.info/INSTALL.d/INSTALL.Darwin.txt
perl -MCPAN -e shell perl -MCPAN -e shell
# then inside the cpan shell type "o conf init" # then inside the cpan shell type "o conf init"
cpan> o conf init cpan> o conf init

View file

@ -1,5 +1,5 @@
#!/bin/cat #!/bin/cat
# $Id: INSTALL.Centos.txt,v 1.4 2015/09/19 08:55:25 gilles Exp gilles $ # $Id: INSTALL.Centos.txt,v 1.5 2016/01/14 20:25:32 gilles Exp gilles $
================================= =================================
= Installing imapsync on CentOS = = Installing imapsync on CentOS =
@ -36,32 +36,28 @@ Unit tests:
== Centos 6 == == Centos 6 ==
============== ==============
This section has been tested with imapsync release 1.644 This section has been tested with imapsync release 1.670
First, install access to the Epel repository First, install access to the Epel repository
wget http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm wget http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
rpm -Uvh epel-release-6-8.noarch.rpm rpm -Uvh epel-release-6-8.noarch.rpm
Then install all other packages via yum: Then install imapsync and its dependencies:
yum install \
perl-Digest-HMAC \
perl-NTLM \
perl-Compress-Zlib \
perl-Data-Uniqid \
perl-Digest-HMAC \
perl-File-Copy-Recursive \
perl-IO-Socket-SSL \
perl-IO-Socket-INET6 \
perl-IO-Tee \
perl-Mail-IMAPClient \
perl-Parse-RecDescent \
perl-TermReadKey \
perl-Test-Simple \
perl-Test-Pod \
perl-Unicode-String \
perl-URI
yum install imapsync
After installing imapsync, it should be able to work on your system.
A good test that shows also the basic example:
imapsync
A live test:
imapsync --testslive
Unit tests:
imapsync --tests

View file

@ -1,5 +1,5 @@
#!/bin/cat #!/bin/cat
# $Id: INSTALL.Darwin.txt,v 1.10 2015/09/19 08:55:25 gilles Exp gilles $ # $Id: INSTALL.Darwin.txt,v 1.11 2016/01/05 23:43:26 gilles Exp gilles $
=================================================== ===================================================
= Installing imapsync binary on Darwin / Mac OS X = = Installing imapsync binary on Darwin / Mac OS X =
@ -42,6 +42,7 @@ imap account synchronization.
= Installing imapsync script on Darwin / Mac OS X = = Installing imapsync script on Darwin / Mac OS X =
=================================================== ===================================================
This part is only for advanced Unix users, or brave ones.
wget --no-check-certificate -O- http://cpanmin.us | perl - -l ~/perl5 App::cpanminus local::lib wget --no-check-certificate -O- http://cpanmin.us | perl - -l ~/perl5 App::cpanminus local::lib
eval `perl -I ~/perl5/lib/perl5 -Mlocal::lib` eval `perl -I ~/perl5/lib/perl5 -Mlocal::lib`

View file

@ -1,16 +1,16 @@
#!/bin/cat #!/bin/cat
# $Id: INSTALL.Debian.txt,v 1.5 2015/09/19 08:55:25 gilles Exp gilles $ # $Id: INSTALL.Debian.txt,v 1.6 2016/01/21 15:10:01 gilles Exp gilles $
========================================
= Installing imapsync on Debian 6 or 7 =
========================================
There is one section for Debian 7 and one for Debian 6. There is one section for Debian 7 and one for Debian 6.
== Debian 7 wheezy or higher == ==========================================
= Installing imapsync on Debian 7 Wheezy =
==========================================
Here are the two commands to install imapsync dependencies. Here are the two commands to install imapsync dependencies.
The first command installs standard packages: You need root priviledge to run them.
The first command installs standard Debian packages:
apt-get install \ apt-get install \
libauthen-ntlm-perl \ libauthen-ntlm-perl \
@ -21,7 +21,6 @@ libio-compress-perl \
libio-socket-inet6-perl \ libio-socket-inet6-perl \
libio-socket-ssl-perl \ libio-socket-ssl-perl \
libio-tee-perl \ libio-tee-perl \
libmail-imapclient-perl \
libmodule-scandeps-perl \ libmodule-scandeps-perl \
libnet-ssleay-perl \ libnet-ssleay-perl \
libpar-packer-perl \ libpar-packer-perl \
@ -29,28 +28,53 @@ libterm-readkey-perl \
libtest-pod-perl \ libtest-pod-perl \
libtest-simple-perl \ libtest-simple-perl \
libunicode-string-perl \ libunicode-string-perl \
liburi-perl liburi-perl \
cpanminus
The second command installs "manually" the Perl module Data::Uniqid The second command installs "manually" the Perl module Data::Uniqid
because Debian hasn't made it available via a package yet: because Debian hasn't made it available via a package yet.
It also install manually Perl module Mail::IMAPClient because
it is good to be up to date:
cpan Data::Uniqid cpanm Data::Uniqid Mail::IMAPClient
After installing the dependencies, imapsync should be working. After installing the dependencies, imapsync should be working.
A good dependencies test that shows also the basic example:
You don't have to be root to test and use imapsync.
Take the compressed tarball called imapsync-1.xxx.tgz
where 1.xxx is the version number.
Untar the tarball where you want:
cd
tar xzvf imapsync-1.xxx.tgz
Go into the directory imapsync-1.xxx
cd imapsync-1.xxx
A dependencies test that shows also the basic example:
./imapsync ./imapsync
Now the install command: A live test showing imapsync job:
./imapsync --testslive
Now the install command (need root priviledges again):
cp imapsync /usr/bin/ cp imapsync /usr/bin/
That's finished for the installation part. That's finished for the installation part.
You can use imapsync. You can use imapsync.
Now go to read http://imapsync.lamiral.info/#doc
start with the tutorial.
===========================================
= Installing imapsync on Debian 6 Squeeze =
===========================================
== Debian 6 Squeeze ==
apt-get install \ apt-get install \
libcrypt-ssleay-perl \ libcrypt-ssleay-perl \
@ -60,7 +84,6 @@ libio-compress-perl \
libio-socket-inet6-perl \ libio-socket-inet6-perl \
libio-socket-ssl-perl \ libio-socket-ssl-perl \
libio-tee-perl \ libio-tee-perl \
libmail-imapclient-perl \
libmodule-scandeps-perl \ libmodule-scandeps-perl \
libnet-ssleay-perl \ libnet-ssleay-perl \
libpar-packer-perl \ libpar-packer-perl \
@ -75,53 +98,37 @@ liburi-perl
perl -MCPAN -e "install Authen::NTLM" perl -MCPAN -e "install Authen::NTLM"
perl -MCPAN -e "install Mail::IMAPClient" perl -MCPAN -e "install Mail::IMAPClient"
Latest command is because the Perl module Mail::IMAPClient The Perl module Mail::IMAPClient is good to be recent
is too old on Debian 6 (it's release "buggy" 3.25). and installed manually.
Now a good dependencies test that shows also the basic example: After installing the dependencies, imapsync should be working.
You don't have to be root to test and use imapsync.
Take the compressed tarball called imapsync-1.xxx.tgz
where 1.xxx is the version number.
Untar the tarball where you want:
cd
tar xzvf imapsync-1.xxx.tgz
Go into the directory imapsync-1.xxx
cd imapsync-1.xxx
A dependencies test that shows also the basic example:
./imapsync ./imapsync
Now the install command: A live test showing imapsync job:
./imapsync --testslive
Now the install command (need root priviledges again):
cp imapsync /usr/bin/ cp imapsync /usr/bin/
That's finished for the installation part. That's finished for the installation part.
You can use imapsync. You can use imapsync.
Now go to read http://imapsync.lamiral.info/#doc
== Appendix == start with the tutorial.
Here are some explanations about what is really needed in case
you want to avoid installing some packages.
=== Mandatory packages ===
Digest::HMAC_MD5 libdigest-hmac-perl
Digest::HMAC_SHA1 libdigest-hmac-perl
File::Copy::Recursive libfile-copy-recursive-perl
IO::Socket::INET6 libio-socket-inet6-perl
IO::Socket::SSL libio-socket-ssl-perl
IO::Tee libio-tee-perl
Mail::IMAPClient libmail-imapclient-perl
Unicode::String libunicode-string-perl
=== Optional packages ===
Authen::NTLM libauthen-ntlm-perl # NTLM authentication
URI::Escape liburi-perl # XOAUTH authentication
Data::Uniqid # XOAUTH authentication
Since Perl module Data::Uniqid is not packaged in Ubuntu you have to install
it "manually" from CPAN.
=== Developper packages ===
Module::ScanDeps libmodule-scandeps-perl
PAR::Packer libpar-packer-perl
Test::Pod libtest-pod-perl
You may need to have also those packages:
sudo apt-get install makepasswd rcs perl-doc git

View file

@ -1,19 +0,0 @@
#!/bin/cat
# $Id: INSTALL.Mandriva.txt,v 1.4 2015/09/19 08:55:25 gilles Exp gilles $
=====================================
== Installing imapsync on Mandriva ==
=====================================
Install the Perl modules dependencies with urpmi:
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
urpmi perl-IO-Tee # IO::Tee
urpmi perl-Unicode-String # Unicode::String

View file

@ -1,13 +1,15 @@
#!/bin/cat #!/bin/cat
# $Id: INSTALL.Ubuntu.txt,v 1.4 2015/09/19 08:55:25 gilles Exp gilles $ # $Id: INSTALL.Ubuntu.txt,v 1.5 2016/01/21 15:10:01 gilles Exp gilles $
================================= =================================================
= Installing imapsync on Ubuntu = = Installing imapsync on Ubuntu 12.04 or higher =
================================= =================================================
== Ubuntu 12.04 or higher == Here are the two commands to install imapsync dependencies.
You need root priviledge to run them.
The first command installs standard Ubuntu packages:
Here are the two commands to install imapsync dependencies:
sudo apt-get install \ sudo apt-get install \
libauthen-ntlm-perl \ libauthen-ntlm-perl \
@ -18,7 +20,6 @@ libio-compress-perl \
libio-socket-inet6-perl \ libio-socket-inet6-perl \
libio-socket-ssl-perl \ libio-socket-ssl-perl \
libio-tee-perl \ libio-tee-perl \
libmail-imapclient-perl \
libmodule-scandeps-perl \ libmodule-scandeps-perl \
libnet-ssleay-perl \ libnet-ssleay-perl \
libpar-packer-perl \ libpar-packer-perl \
@ -26,17 +27,45 @@ libterm-readkey-perl \
libtest-pod-perl \ libtest-pod-perl \
libtest-simple-perl \ libtest-simple-perl \
libunicode-string-perl \ libunicode-string-perl \
liburi-perl liburi-perl \
cpanminus
sudo cpan Data::Uniqid The second command installs "manually" the Perl module Data::Uniqid
because Debian hasn't made it available via a package yet.
It also install manually Perl module Mail::IMAPClient because
it is good to be up to date:
Now a good dependencies test that shows also the basic example: cpanm Data::Uniqid Mail::IMAPClient
After installing the dependencies, imapsync should be working.
You don't have to be root to test and use imapsync.
Take the compressed tarball called imapsync-1.xxx.tgz
where 1.xxx is the version number.
Untar the tarball where you want:
cd
tar xzvf imapsync-1.xxx.tgz
Go into the directory imapsync-1.xxx
cd imapsync-1.xxx
A dependencies test that shows also the basic example:
./imapsync ./imapsync
Now the install command: A live test showing imapsync job:
sudo cp imapsync /usr/bin/ ./imapsync --testslive
Now the install command (need root priviledges again):
cp imapsync /usr/bin/
That's finished for the installation part. That's finished for the installation part.
You can use imapsync. You can use imapsync.
Now go to read http://imapsync.lamiral.info/#doc
start with the tutorial.

View file

@ -1,7 +1,7 @@
# $Id: Makefile,v 1.209 2015/12/03 03:25:22 gilles Exp gilles $ # $Id: Makefile,v 1.216 2016/01/22 01:03:46 gilles Exp gilles $
.PHONY: help usage all .PHONY: help usage all doc
help: usage help: usage
@ -66,7 +66,7 @@ hello:
@echo "$(BIN_NAME)" @echo "$(BIN_NAME)"
all: ChangeLog README VERSION OPTIONS W/imapsync.1 biz prereq allcritic bin mac imapsync.exe VERSION_EXE all: doc VERSION biz prereq allcritic bin mac imapsync.exe VERSION_EXE
testp : testp :
sh INSTALL.d/prerequisites_imapsync sh INSTALL.d/prerequisites_imapsync
@ -91,28 +91,31 @@ VERSION_EXE: imapsync
touch -r ./imapsync ./VERSION_EXE touch -r ./imapsync ./VERSION_EXE
GOOD_PRACTICES.html: W/GOOD_PRACTICES.t2t doc/GOOD_PRACTICES.html: doc/GOOD_PRACTICES.t2t
txt2tags -i W/GOOD_PRACTICES.t2t -t html --toc -o GOOD_PRACTICES.html txt2tags -i doc/GOOD_PRACTICES.t2t -t html --toc -o doc/GOOD_PRACTICES.html
TUTORIAL.html: W/TUTORIAL.t2t doc/TUTORIAL_Unix.html: doc/TUTORIAL_Unix.t2t
txt2tags -i W/TUTORIAL.t2t -t html --toc -o TUTORIAL.html txt2tags -i doc/TUTORIAL_Unix.t2t -t html --toc -o doc/TUTORIAL_Unix.html
doc: README OPTIONS ChangeLog TUTORIAL.html GOOD_PRACTICES.html doc: README OPTIONS ChangeLog doc/TUTORIAL_Unix.html doc/GOOD_PRACTICES.html W/imapsync.1
.PHONY: clean clean_tilde clean_test doc clean_log .PHONY: clean clean_tilde clean_test doc clean_log clean_bak
clean: clean_tilde clean_man clean_log clean: clean_tilde clean_man clean_log clean_bak
clean_test: clean_test:
rm -f .test_3xx rm -f .test_3xx
clean_tilde: clean_tilde:
rm -f *~ rm -f *~ W/*~ FAQ.d/*~
clean_log: clean_log:
rm -f LOG_imapsync/*.txt rm -f LOG_imapsync/*.txt
rm -f examples/LOG_imapsync/*.txt rm -f examples/LOG_imapsync/*.txt
clean_bak:
rm -f index.shtml.bak ./W/style.css.bak
.PHONY: install dist man .PHONY: install dist man
man: imapsync.1 man: imapsync.1
@ -139,12 +142,13 @@ install: testp W/imapsync.1
ci: cidone ci: cidone
cidone: cidone:
rcsdiff RCS/* rcsdiff W/*.bat W/*.out W/*.txt W/*.htaccess W/*.shtml
rcsdiff W/*.bat W/*.out W/*.txt W/*.htaccess W/*.shtml W/*.t2t
rcsdiff S/*.txt S/*.shtml rcsdiff S/*.txt S/*.shtml
rcsdiff doc/*.t2t
rcsdiff INSTALL.d/*.txt INSTALL.d/prerequisites_imapsync rcsdiff INSTALL.d/*.txt INSTALL.d/prerequisites_imapsync
rcsdiff FAQ.d/*txt rcsdiff FAQ.d/*txt
rcsdiff examples/*.sh examples/*.bat examples/*.txt rcsdiff examples/*.sh examples/*.bat examples/*.txt
rcsdiff RCS/*
############### ###############
# Local goals # Local goals
@ -248,6 +252,13 @@ W/test_reg.bat:
scp imapsync W/test_reg.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/' scp imapsync W/test_reg.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/'
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/test_reg.bat' ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/test_reg.bat'
W/test_xoauth2.bat:
unix2dos W/test_xoauth2.bat
scp imapsync W/test_xoauth2.bat /g/var/pass/imapsync-xoauth2-15f8456ad5b7_notasecret.p12 /fb/i/secret.xoauth2 Admin@c:'C:/msys/1.0/home/Admin/imapsync/'
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/test_xoauth2.bat'
W/test_exe_2.bat: W/test_exe_2.bat:
unix2dos W/test_exe_2.bat unix2dos W/test_exe_2.bat
scp imapsync W/test_exe_2.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/' scp imapsync W/test_exe_2.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/'
@ -316,15 +327,19 @@ zip: dosify_bat
# C:\Users\mansour\Desktop\imapsync # C:\Users\mansour\Desktop\imapsync
# vadrouille or petite .PHONY: mac bin
mac: imapsync mac: imapsync_bin_Darwin
imapsync_bin_Darwin: imapsync
rcsdiff imapsync rcsdiff imapsync
rsync -p -e 'ssh -p 995' imapsync W/build_mac.sh gilleslamira@gate.polarhome.com: rsync -p -e 'ssh -p 995' imapsync W/build_mac.sh gilleslamira@gate.polarhome.com:
ssh -p 995 gilleslamira@gate.polarhome.com 'sh build_mac.sh' ssh -p 995 gilleslamira@gate.polarhome.com 'sh build_mac.sh'
rsync -P -e 'ssh -p 995' gilleslamira@gate.polarhome.com:imapsync_bin_Darwin . rsync -P -e 'ssh -p 995' gilleslamira@gate.polarhome.com:imapsync_bin_Darwin .
bin: imapsync bin: $(BIN_NAME)
$(BIN_NAME): imapsync
rcsdiff imapsync rcsdiff imapsync
{ pp -o $(BIN_NAME) -I $(IMAPClient_3xx) \ { pp -o $(BIN_NAME) -I $(IMAPClient_3xx) \
-M Mail::IMAPClient -M IO::Socket -M IO::Socket::SSL \ -M Mail::IMAPClient -M IO::Socket -M IO::Socket::SSL \
@ -337,25 +352,23 @@ bin: imapsync
lfo: upload_lfo lfo: upload_lfo
.PHONY: tarball
tarball: .tarball tarball: ../prepa_dist/$(DIST_FILE)
.tarball: imapsync ../prepa_dist/$(DIST_FILE): imapsync
echo making tarball $(DIST_FILE) echo making tarball ../prepa_dist/$(DIST_FILE)
rcsdiff RCS/* rcsdiff RCS/*
cd W && rcsdiff RCS/* cd W && rcsdiff RCS/*
cd examples && rcsdiff RCS/* cd examples && rcsdiff RCS/*
mkdir -p dist mkdir -p dist
mkdir -p ../prepa_dist/$(DIST_NAME) mkdir -p ../prepa_dist/$(DIST_NAME)
rsync -aCvH --delete --omit-dir-times --exclude dist/ --exclude imapsync.exe ./ ../prepa_dist/$(DIST_NAME)/ rsync -aCvH --delete --omit-dir-times --exclude dist/ --exclude imapsync.exe ./ ../prepa_dist/$(DIST_NAME)/
#rsync -av ./imapsync.exe ../prepa_dist/$(DIST_NAME)/
cd ../prepa_dist && tar czfv $(DIST_FILE) $(DIST_NAME) cd ../prepa_dist && tar czfv $(DIST_FILE) $(DIST_NAME)
#ln -f ../prepa_dist/$(DIST_FILE) dist/
cd ../prepa_dist && md5sum $(DIST_FILE) > $(DIST_FILE).md5.txt cd ../prepa_dist && md5sum $(DIST_FILE) > $(DIST_FILE).md5.txt
cd ../prepa_dist && md5sum -c $(DIST_FILE).md5.txt cd ../prepa_dist && md5sum -c $(DIST_FILE).md5.txt
ls -l ../prepa_dist/$(DIST_FILE) ls -l ../prepa_dist/$(DIST_FILE)
touch .tarball
DO_IT := $(shell test -d dist && { test -f ./dist/path_$(VERSION).txt || makepasswd --chars 4 > ./dist/path_$(VERSION).txt ; } ) DO_IT := $(shell test -d dist && { test -f ./dist/path_$(VERSION).txt || makepasswd --chars 4 > ./dist/path_$(VERSION).txt ; } )
@ -432,12 +445,13 @@ publish: dist upload_ks ksa
PUBLIC = ./ChangeLog ./NOLIMIT ./LICENSE ./CREDITS ./FAQ \ PUBLIC = ./ChangeLog ./NOLIMIT ./LICENSE ./CREDITS ./FAQ \
./index.shtml ./INSTALL ./README_Windows.txt \ ./index.shtml ./INSTALL ./README_Windows.txt \
./VERSION ./VERSION_EXE ./imapsync \ ./VERSION ./VERSION_EXE ./imapsync \
./README ./OPTIONS ./TODO ./TUTORIAL.html ./GOOD_PRACTICES.html ./README ./OPTIONS ./TODO
PUBLIC_W = ./W/style.css ./W/tw-hash.html \ PUBLIC_W = ./W/style.css ./W/tw-hash.html \
./W/TIME.txt \ ./W/TIME.txt \
./W/paypal.shtml ./W/paypal_return.shtml ./W/paypal.shtml ./W/paypal_return.shtml
PUBLIC_doc = ./doc/TUTORIAL_Unix.html ./doc/GOOD_PRACTICES.html
ml: dist_dir ml: dist_dir
rcsdiff W/ml_announce.in rcsdiff W/ml_announce.in
@ -468,7 +482,7 @@ checklinkext: S/news.shtml S/external.shtml S/imapservers.shtml S/template.shtm
http://lamiral.info/~gilles/imapsync/S/imapservers.shtml http://lamiral.info/~gilles/imapsync/S/imapservers.shtml
.valid.index.shtml: index.shtml S/*.shtml .valid.index.shtml: index.shtml S/*.shtml
tidy -q index.shtml S/*.shtml > /dev/null for f in index.shtml S/*.shtml; do echo tidy -q $$f; tidy -q $$f > /dev/null; done
validate --verbose index.shtml S/*.shtml validate --verbose index.shtml S/*.shtml
touch .valid.index.shtml touch .valid.index.shtml
@ -476,21 +490,23 @@ checklinkext: S/news.shtml S/external.shtml S/imapservers.shtml S/template.shtm
upload_index: .valid.index.shtml upload_index: .valid.index.shtml
rcsdiff index.shtml S/*.shtml FAQ FAQ.d/*.txt INSTALL LICENSE CREDITS TODO W/*.bat examples/*.bat index.shtml INSTALL.d/*.txt imapsync rcsdiff index.shtml S/*.shtml FAQ FAQ.d/*.txt INSTALL LICENSE CREDITS TODO W/*.bat examples/*.bat index.shtml INSTALL.d/*.txt imapsync
rsync -avH index.shtml FAQ INSTALL OPTIONS NOLIMIT LICENSE CREDITS TODO TUTORIAL.html GOOD_PRACTICES.html imapsync imapsync.exe $(BIN_NAME) imapsync_bin_Darwin ../imapsync_website/ rsync -avH index.shtml FAQ INSTALL OPTIONS NOLIMIT LICENSE CREDITS TODO imapsync imapsync.exe $(BIN_NAME) imapsync_bin_Darwin ../imapsync_website/
rsync -avH $(PUBLIC_W) ../imapsync_website/W/ rsync -avH $(PUBLIC_W) ../imapsync_website/W/
rsync -avH S/ ../imapsync_website/S/ rsync -avH S/ ../imapsync_website/S/
rsync -avH W/images/ ../imapsync_website/W/images/ rsync -avH W/images/ ../imapsync_website/W/images/
rsync -aHv --delete ./examples/ ../imapsync_website/examples/ rsync -aHv --delete ./examples/ ../imapsync_website/examples/
rsync -aHv --delete ./INSTALL.d/ ../imapsync_website/INSTALL.d/ rsync -aHv --delete ./INSTALL.d/ ../imapsync_website/INSTALL.d/
rsync -aHv --delete ./FAQ.d/ ../imapsync_website/FAQ.d/ rsync -aHv --delete ./FAQ.d/ ../imapsync_website/FAQ.d/
rsync -avH --delete ./doc/ ../imapsync_website/doc/
rsync -aHvz --delete ../imapsync_website/ root@ks.lamiral.info:/var/www/imapsync/ rsync -aHvz --delete ../imapsync_website/ root@ks.lamiral.info:/var/www/imapsync/
upload_FAQ: upload_FAQ:
rcsdiff FAQ FAQ.d/*.txt INSTALL LICENSE CREDITS TODO INSTALL.d/*.txt rcsdiff FAQ FAQ.d/*.txt INSTALL LICENSE CREDITS TODO INSTALL.d/*.txt
rsync -avH FAQ INSTALL OPTIONS CREDITS TODO TUTORIAL.html GOOD_PRACTICES.html ../imapsync_website/ rsync -avH FAQ INSTALL OPTIONS CREDITS TODO ../imapsync_website/
rsync -aHv --delete ./INSTALL.d/ ../imapsync_website/INSTALL.d/ rsync -aHv --delete ./INSTALL.d/ ../imapsync_website/INSTALL.d/
rsync -aHv --delete ./FAQ.d/ ../imapsync_website/FAQ.d/ rsync -aHv --delete ./FAQ.d/ ../imapsync_website/FAQ.d/
rsync -avH --delete ./doc/ ../imapsync_website/doc/
rsync -aHvz --delete ../imapsync_website/ root@ks.lamiral.info:/var/www/imapsync/ rsync -aHvz --delete ../imapsync_website/ root@ks.lamiral.info:/var/www/imapsync/

24
OPTIONS
View file

@ -30,8 +30,12 @@ cmd means command
--ssl2 : Use a SSL connection on host2. --ssl2 : Use a SSL connection on host2.
--tls1 : Use a TLS connection on host1. --tls1 : Use a TLS connection on host1.
--tls2 : Use a TLS connection on host2. --tls2 : Use a TLS connection on host2.
--timeout int : Connections timeout in seconds. Default is 120. --debugssl int : SSL debug mode from 0 to 4.
0 means no timeout.
--timeout1 int : Connection timeout in seconds for host1.
Default is 120 and 0 means no timeout at all.
--timeout2 int : Connection timeout in seconds for host2.
Default is 120 and 0 means no timeout at all.
--authmech1 str : Auth mechanism to use with host1: --authmech1 str : Auth mechanism to use with host1:
PLAIN, LOGIN, CRAM-MD5 etc. Use UPPERCASE. PLAIN, LOGIN, CRAM-MD5 etc. Use UPPERCASE.
@ -67,7 +71,6 @@ cmd means command
--skipemptyfolders : Empty host1 folders are not created on host2. --skipemptyfolders : Empty host1 folders are not created on host2.
--f1f2 str1=str2 : Force folder str1 to be synced to str2.
--include reg : Sync folders matching this regular expression --include reg : Sync folders matching this regular expression
--include reg : or this one, etc. --include reg : or this one, etc.
in case both --include --exclude options are in case both --include --exclude options are
@ -82,13 +85,18 @@ cmd means command
It does it by adding two --regextrans2 options before It does it by adding two --regextrans2 options before
all others. Add --debug to see what's really going on. all others. Add --debug to see what's really going on.
--automap : guesses folders mapping, for folders like
"Sent", "Junk", "Drafts", "All", "Archive", "Flagged".
--f1f2 str1=str2 : Force folder str1 to be synced to str2,
--f1f2 overrides --automap and --regextrans2.
--regextrans2 reg : Apply the whole regex to each destination folders. --regextrans2 reg : Apply the whole regex to each destination folders.
--regextrans2 reg : and this one. etc. --regextrans2 reg : and this one. etc.
When you play with the --regextrans2 option, first When you play with the --regextrans2 option, first
add also the safe options --dry --justfolders add also the safe options --dry --justfolders
Then, when happy, remove --dry, remove --justfolders. Then, when happy, remove --dry, remove --justfolders.
Have in mind that --regextrans2 is applied after prefix Have in mind that --regextrans2 is applied after prefix
and separator inversion. and separator inversion. For examples see
http://imapsync.lamiral.info/FAQ.d/FAQ.Folders_Mapping.txt
--tmpdir str : Where to store temporary files and subdirectories. --tmpdir str : Where to store temporary files and subdirectories.
Will be created if it doesn't exist. Will be created if it doesn't exist.
@ -233,7 +241,9 @@ cmd means command
--debugimap : IMAP debug mode for host1 and host2. --debugimap : IMAP debug mode for host1 and host2.
--debugmemory : Debug mode showing memory consumption after each copy. --debugmemory : Debug mode showing memory consumption after each copy.
--tests : Run non-regression tests. --errorsmax int : Exit when int number of errors is reached. Default is 50.
--tests : Run local non-regression tests. Exit code 0 means all ok.
--testslive : Run a live test with test1.lamiral.info imap server. --testslive : Run a live test with test1.lamiral.info imap server.
Useful to check the basics. Needs internet connexion. Useful to check the basics. Needs internet connexion.
@ -258,9 +268,9 @@ Example: to synchronize imap account "test1" on "test1.lamiral.info"
--host1 test1.lamiral.info --user1 test1 --password1 secret1 \ --host1 test1.lamiral.info --user1 test1 --password1 secret1 \
--host2 test2.lamiral.info --user2 test2 --password2 secret2 --host2 test2.lamiral.info --user2 test2 --password2 secret2
Here is a [linux] system (Linux petite 3.2.0-91-generic #129-Ubuntu SMP Wed Sep 9 10:56:56 UTC 2015 i686) Here is a [linux] system (Linux petite 3.2.0-97-generic #137-Ubuntu SMP Thu Dec 17 21:14:00 UTC 2015 i686)
With perl 5.14.2 Mail::IMAPClient 3.37 With perl 5.14.2 Mail::IMAPClient 3.37
$Id: imapsync,v 1.670 2015/12/03 02:36:41 gilles Exp gilles $ $Id: imapsync,v 1.678 2016/01/21 19:47:02 gilles Exp gilles $
This current imapsync is up to date This current imapsync is up to date
Homepage: http://imapsync.lamiral.info/ Homepage: http://imapsync.lamiral.info/

365
README
View file

@ -4,26 +4,25 @@ NAME
More than 66 different IMAP server softwares supported with success, few More than 66 different IMAP server softwares supported with success, few
failures. failures.
$Revision: 1.670 $ $Revision: 1.678 $
SYNOPSIS SYNOPSIS
To synchronize imap account "foo" on "imap.truc.org" to imap account To synchronize the source imap account
"bar" on "imap.trac.org" with foo password "secret1" and bar password "test1" on server "test1.lamiral.info" with password "secret1"
"secret2": to the destination imap account
"test2" on server "test2.lamiral.info" with password "secret2"
do:
imapsync \ imapsync \
--host1 imap.truc.org --user1 foo --password1 secret1 \ --host1 test1.lamiral.info --user1 test1 --password1 secret1 \
--host2 imap.trac.org --user2 bar --password2 secret2 --host2 test2.lamiral.info --user2 test2 --password2 secret2
INSTALL INSTALL
imapsync works fine under any Unix OS with perl. Imapsync works under any Unix with perl.
imapsync works fine under Windows (2000, XP, Vista, Seven) Imapsync works under Windows (2000, XP, Vista, Seven)
with Strawberry Perl (5.10, 5.12 or higher) as a standalone binary software called imapsync.exe
or as a standalone binary software imapsync.exe Imapsync works under OS X as a standalone binary
software called imapsync_bin_Darwin.
imapsync can be available directly on the following distributions:
FreeBSD, Debian, Ubuntu, Gentoo, Fedora, NetBSD, Darwin, Mandriva and
OpenBSD. See http://oswatershed.org/pkg/imapsync
Purchase latest imapsync at Purchase latest imapsync at
http://imapsync.lamiral.info/ http://imapsync.lamiral.info/
@ -35,81 +34,287 @@ INSTALL
tar xzvf imapsync-x.xx.tgz tar xzvf imapsync-x.xx.tgz
Go into the directory imapsync-x.xx and read the INSTALL file. Go into the directory imapsync-x.xx and read the INSTALL file.
The INSTALL file can be found at As mentioned at http://imapsync.lamiral.info/#install
the INSTALL file can also be found at
http://imapsync.lamiral.info/INSTALL http://imapsync.lamiral.info/INSTALL
It is now split in several files for each system It is now split in several files for each system
http://imapsync.lamiral.info/INSTALL.d/ http://imapsync.lamiral.info/INSTALL.d/
The frozen freecode (was freshmeat) record is at
http://freecode.com/projects/imapsync
USAGE USAGE
imapsync [options] To get a description of each option just run imapsync with no argument,
like this:
To get a description of each option just run imapsync like this:
imapsync --help
or simply
imapsync imapsync
This description of all options is available at This description of options is also available at
http://imapsync.lamiral.info/OPTIONS http://imapsync.lamiral.info/OPTIONS and is reproduced here:
The option list: usage: ./imapsync [options]
imapsync [--host1 server1] [--port1 <num>] Several options are mandatory.
[--user1 str ] [--passfile1 str ] str means string
[--host2 server2] [--port2 <num>] int means integer
[--user2 str ] [--passfile2 str ] reg means regular expression
[--ssl1] [--ssl2] cmd means command
[--tls1] [--tls2]
[--authmech1 str ] [--authmech2 str ] --dry : Makes imapsync doing nothing, just print what would
[--proxyauth1] [--proxyauth2] be done without --dry.
[--domain1] [--domain2]
[--authmd51] [--authmd52] --host1 str : Source or "from" imap server. Mandatory.
[--folder str --folder str ...] --port1 int : Port to connect on host1. Default is 143, 993 if --ssl1
[--folderrec str --folderrec str ...] --user1 str : User to login on host1. Mandatory.
[--include reg ] [--exclude reg ] --showpasswords : Shows passwords on output instead of "MASKED".
[--prefix2 str ] [--prefix1 str ] Useful to restart a complete run by just reading the log.
[--regextrans2 reg --regextrans2 reg ...] --password1 str : Password for the user1.
[--sep1 <char>] --host2 str : "destination" imap server. Mandatory.
[--sep2 <char>] --port2 int : Port to connect on host2. Default is 143, 993 if --ssl2
[--justfolders] [--justfoldersizes] [--justconnect] [--justbanner] --user2 str : User to login on host2. Mandatory.
[--syncinternaldates] --password2 str : Password for the user2.
[--idatefromheader]
[--syncacls] --passfile1 str : Password file for the user1. It must contain the
[--regexmess reg ] [--regexmess reg ] password on the first line. This option avoids to show
[--skipmess reg ] [--skipmess reg ] the password on the command line like --password1 does.
[--maxsize int ] --passfile2 str : Password file for the user2. Contains the password.
[--minsize int ]
[--maxage int ] --ssl1 : Use a SSL connection on host1.
[--minage int ] --ssl2 : Use a SSL connection on host2.
[--search str ] --tls1 : Use a TLS connection on host1.
[--search1 str ] --tls2 : Use a TLS connection on host2.
[--search2 str ] --debugssl int : SSL debug mode from 0 to 4.
[--useheader str ] [--useheader str ]
[--nouid1] [--nouid2] --timeout1 int : Connection timeout in seconds for host1.
[--usecache] Default is 120 and 0 means no timeout at all.
[--noskipsize] --timeout2 int : Connection timeout in seconds for host2.
[--delete] Default is 120 and 0 means no timeout at all.
[--delete2] [--delete2duplicates]
[--expunge] [--expunge1] [--expunge2] [--uidexpunge2] --authmech1 str : Auth mechanism to use with host1:
[--delete2folders] [--delete2foldersonly] [--delete2foldersbutnot] PLAIN, LOGIN, CRAM-MD5 etc. Use UPPERCASE.
[--subscribed] [--subscribe] [--subscribeall] --authmech2 str : Auth mechanism to use with host2. See --authmech1
[--nofoldersizes] [--nofoldersizesatend]
[--dry] --authuser1 str : User to auth with on host1 (admin user).
[--debug] [--debugimap][--debugimap1][--debugimap2] [--debugcontent] Avoid using --authmech1 SOMETHING with --authuser1.
[--timeout int ] --authuser2 str : User to auth with on host2 (admin user).
[--noreleasecheck] --proxyauth1 : Use proxyauth on host1. Requires --authuser1.
[--releasecheck] Required by Sun/iPlanet/Netscape IMAP servers to
[--pidfile <filepath>] [--pidfilelocking] be able to use an administrative user.
[--tmpdir <dirpath>] --proxyauth2 : Use proxyauth on host2. Requires --authuser2.
[--nolog]
[--logfile <filepath>] --authmd51 : Use MD5 authentification for host1.
[--version] [--help] --authmd52 : Use MD5 authentification for host2.
[--tests] [--testsdebug] [--testslive] --domain1 str : Domain on host1 (NTLM authentication).
--domain2 str : Domain on host2 (NTLM authentication).
--folder str : Sync this folder.
--folder str : and this one, etc.
--folderrec str : Sync this folder recursively.
--folderrec str : and this one, etc.
--folderfirst str : Sync this folder first. --folderfirst "Work"
--folderfirst str : then this one, etc.
--folderlast str : Sync this folder last. --folderlast "[Gmail]/All Mail"
--folderlast str : then this one, etc.
--nomixfolders : Do not merge folders when host1 is case sensitive
while host2 is not (like Exchange). Only the first
similar folder is synced (ex: Sent SENT sent -> Sent).
--skipemptyfolders : Empty host1 folders are not created on host2.
--f1f2 str1=str2 : Force folder str1 to be synced to str2.
--include reg : Sync folders matching this regular expression
--include reg : or this one, etc.
in case both --include --exclude options are
use, include is done before.
--exclude reg : Skips folders matching this regular expression
Several folders to avoid:
--exclude 'fold1|fold2|f3' skips fold1, fold2 and f3.
--exclude reg : or this one, etc.
--subfolder2 str : Move whole host1 folders hierarchy under this
host2 folder str .
It does it by adding two --regextrans2 options before
all others. Add --debug to see what's really going on.
--regextrans2 reg : Apply the whole regex to each destination folders.
--regextrans2 reg : and this one. etc.
When you play with the --regextrans2 option, first
add also the safe options --dry --justfolders
Then, when happy, remove --dry, remove --justfolders.
Have in mind that --regextrans2 is applied after prefix
and separator inversion.
--tmpdir str : Where to store temporary files and subdirectories.
Will be created if it doesn't exist.
Default is system specific, Unix is /tmp but
it's often small and deleted at reboot.
--tmpdir /var/tmp should be better.
--pidfile str : The file where imapsync pid is written.
--pidfilelocking : Abort if pidfile already exists. Usefull to avoid
concurrent transfers on the same mailbox.
--nolog : Turn off logging on file
--logfile str : Change the default log filename (can be dirname/filename).
--logdir str : Change the default log directory. Default is LOG_imapsync
--prefix1 str : Remove prefix to all destination folders
(usually INBOX. or INBOX/ or an empty string "")
you have to use --prefix1 if host1 imap server
does not have NAMESPACE capability, so imapsync
suggests to use it. All other cases are bad.
--prefix2 str : Add prefix to all host2 folders. See --prefix1
--sep1 str : Host1 separator in case NAMESPACE is not supported.
--sep2 str : Host2 separator in case NAMESPACE is not supported.
--skipmess reg : Skips messages maching the regex.
Example: 'm/[\x80-ff]/' # to avoid 8bits messages.
--skipmess is applied before --regexmess
--skipmess reg : or this one, etc.
--pipemess cmd : Apply this cmd command to each message content
before the copy.
--pipemess cmd : and this one, etc.
--disarmreadreceipts : Disarms read receipts (host2 Exchange issue)
--regexmess reg : Apply the whole regex to each message before transfer.
Example: 's/\000/ /g' # to replace null by space.
--regexmess reg : and this one, etc.
--regexflag reg : Apply the whole regex to each flags list.
Example: 's/"Junk"//g' # to remove "Junk" flag.
--regexflag reg : and this one, etc.
--delete : Deletes messages on host1 server after a successful
transfer. Option --delete has the following behavior:
it marks messages as deleted with the IMAP flag
\Deleted, then messages are really deleted with an
EXPUNGE IMAP command.
--delete2 : Delete messages in host2 that are not in
host1 server. Useful for backup or pre-sync.
--delete2duplicates : Delete messages in host2 that are duplicates.
Works only without --useuid since duplicates are
detected with an header part of each message.
--delete2folders : Delete folders in host2 that are not in host1 server.
For safety, first try it like this (it is safe):
--delete2folders --dry --justfolders --nofoldersizes
--delete2foldersonly reg : Deleted only folders matching regex.
Example: --delete2foldersonly "/^Junk$|^INBOX.Junk$/"
--delete2foldersbutnot reg : Do not delete folders matching regex.
Example: --delete2foldersbutnot "/Tasks$|Contacts$|Foo$/"
--noexpunge : Do not expunge messages on host1.
Expunge really deletes messages marked deleted.
Expunge is made at the beginning, on host1 only.
Newly transferred messages are also expunged if
option --delete is given.
No expunge is done on host2 account (unless --expunge2)
--expunge1 : Expunge messages on host1 after messages transfer.
--expunge2 : Expunge messages on host2 after messages transfer.
--uidexpunge2 : uidexpunge messages on the host2 account
that are not on the host1 account, requires --delete2
--nomixfolders : Avoid merging folders that are considered different on
host1 but the same on destination host2 because of
case sensitivities and insensitivities.
--syncinternaldates : Sets the internal dates on host2 same as host1.
Turned on by default. Internal date is the date
a message arrived on a host (mtime).
--idatefromheader : Sets the internal dates on host2 same as the
"Date:" headers.
--maxsize int : Skip messages larger (or equal) than int bytes
--minsize int : Skip messages smaller (or equal) than int bytes
--maxage int : Skip messages older than int days.
final stats (skipped) don't count older messages
see also --minage
--minage int : Skip messages newer than int days.
final stats (skipped) don't count newer messages
You can do (+ are the messages selected):
past|----maxage+++++++++++++++>now
past|+++++++++++++++minage---->now
past|----maxage+++++minage---->now (intersection)
past|++++minage-----maxage++++>now (union)
--search str : Selects only messages returned by this IMAP SEARCH
command. Applied on both sides.
--search1 str : Same as --search for selecting host1 messages only.
--search2 str : Same as --search for selecting host2 messages only.
--search CRIT equals --search1 CRIT --search2 CRIT
--exitwhenover int : Stop syncing when total bytes transferred reached.
Gmail per day allows
2500000000 = 2.5 GB downloaded from Gmail as host2
500000000 = 500 MB uploaded to Gmail as host1.
--maxlinelength int : skip messages with a line length longer than int bytes.
RFC 2822 says it must be no more than 1000 bytes.
--useheader str : Use this header to compare messages on both sides.
Ex: Message-ID or Subject or Date.
--useheader str and this one, etc.
--subscribed : Transfers subscribed folders.
--subscribe : Subscribe to the folders transferred on the
host2 that are subscribed on host1. On by default.
--subscribeall : Subscribe to the folders transferred on the
host2 even if they are not subscribed on host1.
--nofoldersizes : Do not calculate the size of each folder in bytes
and message counts. Default is to calculate them.
--nofoldersizesatend: Do not calculate the size of each folder in bytes
and message counts at the end. Default is on.
--justfoldersizes : Exit after having printed the folder sizes.
--syncacls : Synchronises acls (Access Control Lists).
--nosyncacls : Does not synchronize acls. This is the default.
Acls in IMAP are not standardized, be careful.
--usecache : Use cache to speedup.
--nousecache : Do not use cache. Caveat: --useuid --nousecache creates
duplicates on multiple runs.
--useuid : Use uid instead of header as a criterium to recognize
messages. Option --usecache is then implied unless
--nousecache is used.
--debug : Debug mode.
--debugfolders : Debug mode for the folders part only.
--debugcontent : Debug content of the messages transfered. Huge ouput.
--debugflags : Debug mode for flags.
--debugimap1 : IMAP debug mode for host1. Very verbose.
--debugimap2 : IMAP debug mode for host2. Very verbose.
--debugimap : IMAP debug mode for host1 and host2.
--debugmemory : Debug mode showing memory consumption after each copy.
--errorsmax int : Exit when int number of errors is reached. Default is 50.
--tests : Run local non-regression tests. Exit code 0 means all ok.
--testslive : Run a live test with test1.lamiral.info imap server.
Useful to check the basics. Needs internet connexion.
--version : Print only software version.
--noreleasecheck : Do not check for new imapsync release (a http request).
--releasecheck : Check for new imapsync release (a http request).
--noid : Do not send/receive ID command to imap servers.
--justconnect : Just connect to both servers and print useful
information. Need only --host1 and --host2 options.
--justlogin : Just login to both host1 and host2 with users
credentials, then exit.
--justfolders : Do only things about folders (ignore messages).
--help : print this help.
Example:
To synchronize the source imap account
"test1" on server "test1.lamiral.info" with password "secret1"
to the destination imap account
"test2" on server "test2.lamiral.info" with password "secret2"
do:
imapsync \
--host1 test1.lamiral.info --user1 test1 --password1 secret1 \
--host2 test2.lamiral.info --user2 test2 --password2 secret2
DESCRIPTION DESCRIPTION
Imapsync command is a tool allowing incremental and recursive imap Imapsync command is a tool allowing incremental and recursive imap
@ -387,5 +592,5 @@ SIMILAR SOFTWARES
Feedback (good or bad) will often be welcome. Feedback (good or bad) will often be welcome.
$Id: imapsync,v 1.670 2015/12/03 02:36:41 gilles Exp gilles $ $Id: imapsync,v 1.678 2016/01/21 19:47:02 gilles Exp gilles $

0
W/fb-like.html → S/fb-like.html Normal file → Executable file
View file

View file

@ -1,82 +1,82 @@
1124 Etats-Unis_d'Amerique___ 26.05 % 26.05 % 1 1143 Etats-Unis_d'Amerique___ 25.84 % 25.84 % 1
784 Allemagne_______________ 18.17 % 44.23 % 2 811 Allemagne_______________ 18.34 % 44.18 % 2
409 Royaume-Uni_____________ 9.48 % 53.71 % 3 413 Royaume-Uni_____________ 9.34 % 53.52 % 3
204 Italie__________________ 4.73 % 58.44 % 4 212 France__________________ 4.79 % 58.31 % 4
204 France__________________ 4.73 % 63.17 % 5 209 Italie__________________ 4.73 % 63.03 % 5
190 Canada__________________ 4.40 % 67.57 % 6 201 Canada__________________ 4.54 % 67.58 % 6
175 Suisse__________________ 4.06 % 71.63 % 7 179 Suisse__________________ 4.05 % 71.63 % 7
149 Pays-Bas________________ 3.45 % 75.08 % 8 154 Pays-Bas________________ 3.48 % 75.11 % 8
146 Australie_______________ 3.38 % 78.47 % 9 151 Australie_______________ 3.41 % 78.52 % 9
89 Autriche________________ 2.06 % 80.53 % 10 90 Autriche________________ 2.03 % 80.56 % 10
78 Belgique________________ 1.81 % 82.34 % 11 80 Belgique________________ 1.81 % 82.36 % 11
75 Espagne_________________ 1.74 % 84.08 % 12 76 Espagne_________________ 1.72 % 84.08 % 12
64 Suede___________________ 1.48 % 85.56 % 13 65 Suede___________________ 1.47 % 85.55 % 13
50 Danemark________________ 1.16 % 86.72 % 14 52 Danemark________________ 1.18 % 86.73 % 14
48 Bresil__________________ 1.11 % 87.83 % 15 48 Bresil__________________ 1.09 % 87.81 % 15
40 Norvege_________________ 0.93 % 88.76 % 16 41 Norvege_________________ 0.93 % 88.74 % 16
31 Finlande________________ 0.72 % 89.48 % 17 31 Finlande________________ 0.70 % 89.44 % 17
25 Republique_tcheque______ 0.58 % 90.06 % 18 29 Pologne_________________ 0.66 % 90.10 % 18
25 Pologne_________________ 0.58 % 90.64 % 19 25 Republique_tcheque______ 0.57 % 90.66 % 19
25 Japon___________________ 0.58 % 91.21 % 20 25 Japon___________________ 0.57 % 91.23 % 20
25 ________________________ 0.58 % 91.79 % 21 25 ________________________ 0.57 % 91.79 % 21
22 Russie__________________ 0.51 % 92.30 % 22 22 Russie__________________ 0.50 % 92.29 % 22
21 Irlande_________________ 0.49 % 92.79 % 23 22 Irlande_________________ 0.50 % 92.79 % 23
20 Nouvelle-Zelande________ 0.46 % 93.25 % 24 21 Nouvelle-Zelande________ 0.47 % 93.26 % 24
18 Hongrie_________________ 0.42 % 93.67 % 25 18 Hongrie_________________ 0.41 % 93.67 % 25
15 Afrique_du_Sud__________ 0.35 % 94.02 % 26 15 Hong-Kong_______________ 0.34 % 94.01 % 26
14 Portugal________________ 0.32 % 94.34 % 27 15 Afrique_du_Sud__________ 0.34 % 94.35 % 27
14 Hong-Kong_______________ 0.32 % 94.67 % 28 14 Portugal________________ 0.32 % 94.66 % 28
13 Malaisie________________ 0.30 % 94.97 % 29 13 Slovaquie_______________ 0.29 % 94.96 % 29
12 Slovaquie_______________ 0.28 % 95.25 % 30 13 Malaisie________________ 0.29 % 95.25 % 30
12 Luxembourg______________ 0.28 % 95.53 % 31 12 Luxembourg______________ 0.27 % 95.52 % 31
12 Inde____________________ 0.28 % 95.80 % 32 12 Inde____________________ 0.27 % 95.79 % 32
12 Grece___________________ 0.28 % 96.08 % 33 12 Grece___________________ 0.27 % 96.07 % 33
12 Argentine_______________ 0.28 % 96.36 % 34 12 Argentine_______________ 0.27 % 96.34 % 34
11 Singapour_______________ 0.25 % 96.62 % 35 11 Singapour_______________ 0.25 % 96.59 % 35
11 Chine___________________ 0.25 % 96.87 % 36 11 Israel__________________ 0.25 % 96.83 % 36
11 Chili___________________ 0.25 % 97.13 % 37 11 Chine___________________ 0.25 % 97.08 % 37
10 Mexique_________________ 0.23 % 97.36 % 38 11 Chili___________________ 0.25 % 97.33 % 38
10 Israel__________________ 0.23 % 97.59 % 39 10 Mexique_________________ 0.23 % 97.56 % 39
8 Slovenie________________ 0.19 % 97.77 % 40 9 Roumanie________________ 0.20 % 97.76 % 40
8 Roumanie________________ 0.19 % 97.96 % 41 8 Slovenie________________ 0.18 % 97.94 % 41
8 Emirats_Arabes_Unis_____ 0.19 % 98.15 % 42 8 Emirats_Arabes_Unis_____ 0.18 % 98.12 % 42
7 Lettonie________________ 0.16 % 98.31 % 43 7 Lettonie________________ 0.16 % 98.28 % 43
5 Thailande_______________ 0.12 % 98.42 % 44 5 Thailande_______________ 0.11 % 98.39 % 44
5 Malte___________________ 0.12 % 98.54 % 45 5 Malte___________________ 0.11 % 98.51 % 45
5 Islande_________________ 0.12 % 98.66 % 46 5 Islande_________________ 0.11 % 98.62 % 46
4 Indonesie_______________ 0.09 % 98.75 % 47 4 Turquie_________________ 0.09 % 98.71 % 47
4 Egypte__________________ 0.09 % 98.84 % 48 4 Indonesie_______________ 0.09 % 98.80 % 48
3 Venezuela_______________ 0.07 % 98.91 % 49 4 Egypte__________________ 0.09 % 98.89 % 49
3 Turquie_________________ 0.07 % 98.98 % 50 4 Croatie_________________ 0.09 % 98.98 % 50
3 Philippines_____________ 0.07 % 99.05 % 51 4 Bulgarie________________ 0.09 % 99.07 % 51
3 Estonie_________________ 0.07 % 99.12 % 52 3 Venezuela_______________ 0.07 % 99.14 % 52
3 Croatie_________________ 0.07 % 99.19 % 53 3 Philippines_____________ 0.07 % 99.21 % 53
3 Bulgarie________________ 0.07 % 99.26 % 54 3 Estonie_________________ 0.07 % 99.28 % 54
2 Vietnam_________________ 0.05 % 99.30 % 55 2 Vietnam_________________ 0.05 % 99.32 % 55
2 Uruguay_________________ 0.05 % 99.35 % 56 2 Uruguay_________________ 0.05 % 99.37 % 56
2 Lituanie________________ 0.05 % 99.40 % 57 2 Lituanie________________ 0.05 % 99.41 % 57
2 Costa_Rica______________ 0.05 % 99.44 % 58 2 Costa_Rica______________ 0.05 % 99.46 % 58
2 Chypre__________________ 0.05 % 99.49 % 59 2 Chypre__________________ 0.05 % 99.50 % 59
1 Ukraine_________________ 0.02 % 99.51 % 60 1 Ukraine_________________ 0.02 % 99.53 % 60
1 Trinite-et-Tobago_______ 0.02 % 99.54 % 61 1 Trinite-et-Tobago_______ 0.02 % 99.55 % 61
1 Tanzanie________________ 0.02 % 99.56 % 62 1 Tanzanie________________ 0.02 % 99.57 % 62
1 Taiwan__________________ 0.02 % 99.58 % 63 1 Taiwan__________________ 0.02 % 99.59 % 63
1 Serbie__________________ 0.02 % 99.61 % 64 1 Serbie__________________ 0.02 % 99.62 % 64
1 Senegal_________________ 0.02 % 99.63 % 65 1 Senegal_________________ 0.02 % 99.64 % 65
1 Saint_Christophe-Nevis-Anguilla__ 0.02 % 99.65 % 66 1 Saint_Christophe-Nevis-Anguilla__ 0.02 % 99.66 % 66
1 Qatar___________________ 0.02 % 99.68 % 67 1 Qatar___________________ 0.02 % 99.68 % 67
1 Perou___________________ 0.02 % 99.70 % 68 1 Perou___________________ 0.02 % 99.71 % 68
1 Panama__________________ 0.02 % 99.72 % 69 1 Panama__________________ 0.02 % 99.73 % 69
1 Nouvelle-Caledonie______ 0.02 % 99.75 % 70 1 Nouvelle-Caledonie______ 0.02 % 99.75 % 70
1 Nigeria_________________ 0.02 % 99.77 % 71 1 Nigeria_________________ 0.02 % 99.77 % 71
1 Namibie_________________ 0.02 % 99.79 % 72 1 Namibie_________________ 0.02 % 99.80 % 72
1 Mongolie________________ 0.02 % 99.81 % 73 1 Mongolie________________ 0.02 % 99.82 % 73
1 Moldavie________________ 0.02 % 99.84 % 74 1 Moldavie________________ 0.02 % 99.84 % 74
1 Maldives________________ 0.02 % 99.86 % 75 1 Maldives________________ 0.02 % 99.86 % 75
1 Îles_Vierges_britanniques__ 0.02 % 99.88 % 76 1 Îles_Vierges_britanniques__ 0.02 % 99.89 % 76
1 Koweit__________________ 0.02 % 99.91 % 77 1 Koweit__________________ 0.02 % 99.91 % 77
1 Jordanie________________ 0.02 % 99.93 % 78 1 Jordanie________________ 0.02 % 99.93 % 78
1 Colombie________________ 0.02 % 99.95 % 79 1 Colombie________________ 0.02 % 99.95 % 79
1 Bahrein_________________ 0.02 % 99.98 % 80 1 Bahrein_________________ 0.02 % 99.98 % 80
1 Antilles_neerlandaises__ 0.02 % 100.00 % 81 1 Antilles_neerlandaises__ 0.02 % 100.00 % 81
TOTAL = 4314 sales over 81 countries on Thu Dec 3 03:56:13 CET 2015 TOTAL = 4423 sales over 81 countries on Thu Jan 21 20:48:13 CET 2016

View file

@ -7,7 +7,7 @@
<title>Imapsync News</title> <title>Imapsync News</title>
<meta name="generator" content="Bluefish 2.2.2" /> <meta name="generator" content="Bluefish 2.2.2" />
<meta name="author" content="Gilles LAMIRAL" /> <meta name="author" content="Gilles LAMIRAL" />
<meta name="date" content="2015-12-03T03:55:04+0100" /> <meta name="date" content="2016-01-22T01:56:39+0100" />
<meta name="copyright" content="None"/> <meta name="copyright" content="None"/>
<meta name="keywords" content="imap, transfer, migration, synchronization"/> <meta name="keywords" content="imap, transfer, migration, synchronization"/>
<meta name="description" content="imap migration tool"/> <meta name="description" content="imap migration tool"/>
@ -40,7 +40,7 @@
<!-- <!--
<ul> <ul>
<li><b>1.667</b></li> <li><b>1.677</b></li>
<li><b>Enhancement</b>: </li> <li><b>Enhancement</b>: </li>
<li><b>Enhancement</b>: </li> <li><b>Enhancement</b>: </li>
<li><b>Enhancement</b>: </li> <li><b>Enhancement</b>: </li>
@ -59,9 +59,31 @@
</ul> </ul>
--> -->
<ul>
<li><b>1.678</b> <b>Improved website!</b> (I hope...)</li>
<li><b>Enhancement</b>: Added <b><tt>--sslargs1</tt></b> and <b><tt>--sslargs2</tt></b> to pass any ssl parameter for host1 or host2 connection.
Example: <tt>--sslargs1 SSL_verify_mode=1 --sslargs1 SSL_version=SSLv3</tt></li>
<li><b>Enhancement</b>: Added <tt>--timeout1 int</tt> and <tt>--timeout2 int</tt> in seconds (<tt>--timeout int</tt> still available to set both with the same value)</li>
<li><b>Enhancement</b>: Added <tt>--debugssl int</tt>. Default is like <tt>--debugssl 1</tt> (Only print out errors).</li>
<li><b>Enhancement</b>: Added several <a href="../#polls">polls</a> to know where I shall focus improvements.</li>
<li><b>Usability</b>: Added env_proxy call in <tt>sub xoauth2()</tt>
to read proxy settings from environment variable <tt>http_proxy</tt>
without using <tt>PERL_LWP_ENV_PROXY=1</tt></li>
<li><b>Usability</b>: Wrote <a href="../TUTORIAL_Unix.html">TUTORIAL_Unix</a>.</li>
<li><b>Usability</b>: Check f1 folder exists when specified by <tt>--f1f2</tt> and warns when it doesn't</li>
<li><b>Usability</b>: Added <tt>--automap --justfolders --dry</tt> in <tt>imapsync_example.sh</tt> and <tt>imapsync_example.bat</tt></li>
<li><b>Bug fix</b>: Added require Encode::Byte to solve "The locale codeset (cp1252) isn't one that perl can decode" on Win32.</li>
<li><b>Refactoring</b>: Removed <tt>--allow3xx</tt> option.</li>
<li><b>Refactoring</b>: Continue to move to one global $sync-> in order to reduce number of parameters in routines.</li>
</ul>
<ul> <ul>
<li><b>1.670</b> Folders mapping made easy with --automap</li> <li><b>1.670</b> Folders <b>mapping made easy</b> with <b>--automap</b></li>
<li><b>Enhancement</b>: Added option <b><tt>--automap</tt></b> that guesses folders mapping, <li><b>Enhancement</b>: Added option <b><tt>--automap</tt></b> that guesses folders mapping,
for folders like "Sent", "Junk", "Drafts", "All", "Archive", "Flagged". for folders like "Sent", "Junk", "Drafts", "All", "Archive", "Flagged".
<ul> <ul>
@ -71,21 +93,22 @@
to try it a safe method is to use <tt>--automap --justautomap</tt>, it will exit early</li> to try it a safe method is to use <tt>--automap --justautomap</tt>, it will exit early</li>
</ul> </ul>
</li> </li>
<li><b>Enhancement</b>: Added <tt>--f1f2 str1=str2</tt> : Force folder str1 to be synced to str2. <li><b>Enhancement</b>: Added <b><tt>--f1f2 str1=str2</tt></b> : Force folder str1 to be synced to str2.
<ul> <ul>
<li>Option --f1f2 overrides any automap mapping and any regextrans2. </li> <li>Option <tt>--f1f2</tt> overrides any <tt>--automap</tt> mapping and any <tt>--regextrans2</tt> transformation. </li>
<li>Example <tt>--f1f2 Spam=Junk</tt> to map Spam folder to Junk.</li> <li>Example <tt>--f1f2 Spam=Junk</tt> to map Spam folder to Junk.</li>
</ul> </ul>
</li> </li>
<li><b>Enhancement</b>: Added --justautomap to exit after seeing what will happen with --automap and --f1f2 options.</li> <li><b>Enhancement</b>: Added <b><tt>--justautomap</tt></b> to exit after seeing what will happen with
<li><b>Enhancement</b>: Added IMAP4 QUOTA values when they're available and a warning when it's time to find space. --automap and --f1f2 options.</li>
See RFC 2087 <a href="https://tools.ietf.org/html/rfc2087">IMAP4 QUOTA extension</a> <li><b>Enhancement</b>: Added <a href="https://tools.ietf.org/html/rfc2087">IMAP4 QUOTA </a> values (RFC 2087)
when they are available. A warning goes up when it's time to find space.
</li> </li>
<li><b>Enhancement</b>: Added <a href="http://tools.ietf.org/html/rfc2971.html">IMAP4 ID extension</a>. <li><b>Enhancement</b>: Added <a href="http://tools.ietf.org/html/rfc2971.html">IMAP4 ID extension</a>.
<ul> <ul>
<li>ID feature is on by default if supported by the IMAP servers, <li>ID feature is on by default if supported by the IMAP servers,
use <tt>--noid</tt> to turn it off.</li> use <b><tt>--noid</tt></b> to turn it off.</li>
<li>ID Infos returned by the imap servers are shown.</li> <li>ID Infos returned by the imap servers are shown.</li>
<li>Infos sent to the servers are name=imapsync, version=`imapsync --version`, os=$OSNAME`, <li>Infos sent to the servers are name=imapsync, version=`imapsync --version`, os=$OSNAME`,
vendor='Gilles LAMIRAL' and date=`rcs date of release`.</li> vendor='Gilles LAMIRAL' and date=`rcs date of release`.</li>
@ -94,7 +117,7 @@
</ul> </ul>
</li> </li>
<li><b>Enhancement</b>: Added <tt>--logdir path</tt> to change the default log directory. <li><b>Enhancement</b>: Added <b><tt>--logdir path</tt></b> to change the default log directory.
Default is <tt>LOG_imapsync/</tt> Default is <tt>LOG_imapsync/</tt>
</li> </li>
@ -103,7 +126,7 @@
<li><b>Usability</b>: Added folders counting in outputs.</li> <li><b>Usability</b>: Added folders counting in outputs.</li>
<li><b>Usability</b>: Better output in the login part</li> <li><b>Usability</b>: Better output in the login part</li>
<li><b>Usability</b>: Guess prefixes and separators instead of forcing the user to find them.</li> <li><b>Usability</b>: Guess prefixes and separators instead of forcing the user to find them.</li>
<li><b>Usability</b>: Output, added <tt>Host1:</tt> or <tt>Host2</tt> at the beginning of lines.</li> <li><b>Usability</b>: Output, added <tt>Host1:</tt> or <tt>Host2:</tt> at the beginning of lines.</li>
<li><b>Bug fix</b>: SSL_VERIFY_NONE in --ssl and --tls modes</li> <li><b>Bug fix</b>: SSL_VERIFY_NONE in --ssl and --tls modes</li>
@ -370,7 +393,7 @@ alt="Viewable With Any Browser" />
<!--#config timefmt="%D" --> <!--#config timefmt="%D" -->
<!--#config timefmt="%A %B %d, %Y" --> <!--#config timefmt="%A %B %d, %Y" -->
<b>This document last modified on <!--#echo var="LAST_MODIFIED" --></b> <b>This document last modified on <!--#echo var="LAST_MODIFIED" --></b>
($Id: news.shtml,v 1.7 2015/12/03 02:55:37 gilles Exp gilles $)<br/> ($Id: news.shtml,v 1.10 2016/01/22 01:04:15 gilles Exp gilles $)<br/>
<a href="#TOP">Top of the page</a> <a href="#TOP">Top of the page</a>
</p> </p>

View file

@ -1,25 +1,34 @@
/* $Id: style.css,v 1.8 2016/01/21 00:58:22 gilles Exp gilles $ */
body { body {
color: black; color: black;
background-color: #eeffff background-color: #eeffff
} }
#left-poll {
#left-menu {
float: left; float: left;
width: 30%; width: 35%;
} }
#centered-logo { #centered-logo {
float: left; float: left;
width: 70%; width: 65%;
} }
#right-poll { div.list {
float: right; display: inline-block;
width: 30%; vertical-align: top;
} }
div.poll {
display: inline-block;
vertical-align: top;
}
#full-page { #full-page {
float: left; float: left;
width: 100%; width: 100%;
@ -52,5 +61,3 @@ img {
{ {
font-size: smaller; font-size: smaller;
} }
/* $Id: style.css,v 1.6 2015/03/03 11:24:45 gilles Exp gilles $ */

14
S/tw-hash.html Executable file
View file

@ -0,0 +1,14 @@
<script type="text/javascript">
//<![CDATA[
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');
//]]>
</script>
<a href="https://twitter.com/intent/tweet?button_hashtag=imapsync"
class="twitter-hashtag-button"
data-size="large"
data-related="imapsync"
data-url="http://imapsync.lamiral.info/"
data-dnt="true">Tweet #imapsync</a>

13
S/tw-mention.html Executable file
View file

@ -0,0 +1,13 @@
<script type="text/javascript">
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');
</script>
<a
href="https://twitter.com/intent/tweet?screen_name=imapsync&amp;text=Hi%20Gilles!"
class="twitter-mention-button"
data-size="large"
data-related="imapsync"
data-dnt="true">Tweet to @imapsync</a>

68
TODO
View file

@ -1,13 +1,14 @@
#!/bin/cat #!/bin/cat
# $Id: TODO,v 1.144 2015/12/03 02:03:06 gilles Exp gilles $ # $Id: TODO,v 1.149 2016/01/21 15:21:17 gilles Exp gilles $
TODO file for imapsync TODO file for imapsync
---------------------- ----------------------
Start a wiki for imapsync. Start a wiki for imapsync.
Write a tutorial. Write a Windows tutorial, TUTORIAL_Windows.html.
Add a best practice migration tips document.
Write a good practices migration tips document, GOOD_PRACTICES.html
Add uidexpunge with --delete if possible (like with --delete2). Add uidexpunge with --delete if possible (like with --delete2).
@ -19,12 +20,16 @@ MB
GB GB
TB TB
2015_11_24 Jens Herrmann
Add --logdir to allow imapsync choosing the filename while allowing
user to choose the dirname part.
2015_06_02 Karen F Bath. WANTED 2015_12_16 Gilles Lamiral
Add "df -i" with usecache and abort if the number of messages
to transfer will exhaust empty inodes used by the cache.
Looks like module Filesys::DfPortable will help for Unix and Win32.
WANTED 2015_06_02 Karen F Bath.
Add skipped messages in the final dump. Add skipped messages in the final dump.
Print the list of messages not copied and why (duplicates or void header).
I would like to request if you could add additional errors to the bottom, I would like to request if you could add additional errors to the bottom,
as we find that things like MaxLineLength and maxsize limit are classed as we find that things like MaxLineLength and maxsize limit are classed
as skipped messages and in my opinion are errors; as the email message as skipped messages and in my opinion are errors; as the email message
@ -50,8 +55,12 @@ exceeds maxsize limit 20971520 bytes,"Error"
error while reading data from server: Connection reset by peer (4x),"Error" error while reading data from server: Connection reset by peer (4x),"Error"
Folder [Inbox] already exists,"Error" Folder [Inbox] already exists,"Error"
WANTED Add a well described problem for each problem detected
and counted in error counter statistics.
2015_05_18
WANTED 2015_05_18
I'd like to be able to print the messages subjects, on some logs: I'd like to be able to print the messages subjects, on some logs:
For instance: For instance:
msg INBOX.Archived/95551 marked \Deleted on host2 [GyDD6WpsFEtyBzNFnv] msg INBOX.Archived/95551 marked \Deleted on host2 [GyDD6WpsFEtyBzNFnv]
@ -59,19 +68,13 @@ For instance:
It would be great to be able to print the email subject, in order to debug or to get more useful information. It would be great to be able to print the email subject, in order to debug or to get more useful information.
2015_04_25 WANTED 2015_04_25
Add duplicates test option. Add duplicates test option.
2015_03_24
Add --sslargs with usage like:
imapsync ... --sslargs 'SSL_version=' --sslargs 'SSL_use_cert=1' \
--sslargs 'SSL_verify_mode=SSL_VERIFY_PEER'
See perldoc IO::Socket::SSL for all possibilities.
WANTED 2015_03_06
2015_03_06
Dealing with Content-Type Message/Partial Dealing with Content-Type Message/Partial
Extract the components of the partial messages and construct them Extract the components of the partial messages and construct them
with reformime as one message which can then be transferred. (Larry Moore) with reformime as one message which can then be transferred. (Larry Moore)
@ -97,8 +100,6 @@ aliases for --noexpunge1 --delete1 and --noexpunge2 --delete2
Move --help documentation into the man page so that description is easier to find. Move --help documentation into the man page so that description is easier to find.
Print the list of messages not copied and why (duplicates or void header)
Fix bug found by Pavel Stano on 01/06/2012 (june) imapsync never stop login Fix bug found by Pavel Stano on 01/06/2012 (june) imapsync never stop login
when login fails with a "* BYE Temp error" from server. when login fails with a "* BYE Temp error" from server.
@ -122,8 +123,6 @@ find, but I had one large folder with quite a few, and in this case it would hav
been a big help. been a big help.
Find a way to avoid passwords in --debugimap unless needed.
Explain that users can win time/bandwidth by using --expunge Explain that users can win time/bandwidth by using --expunge
Fix "\Forwarded" flag bug in courier. Fix "\Forwarded" flag bug in courier.
@ -132,9 +131,6 @@ Does \lalala can be forbidden (courier does a
with with
* OK [PERMANENTFLAGS (\* \Draft \Answered \Flagged \Deleted \Seen)] Limited * OK [PERMANENTFLAGS (\* \Draft \Answered \Flagged \Deleted \Seen)] Limited
Add a well described problem for each problem detected
and counted in error counter statistics.
Add sync imap keywords. Sync Gmail labels to imap keyword Add sync imap keywords. Sync Gmail labels to imap keyword
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=503159 http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=503159
http://www.linux-france.org/prj/imapsync_list/msg00022.html http://www.linux-france.org/prj/imapsync_list/msg00022.html
@ -207,6 +203,28 @@ http://asg.web.cmu.edu/cyrus/download/imapd/altnamespace.html
Now the TODO done! (or not) Now the TODO done! (or not)
=========================================================================== ===========================================================================
DONE 2016_01_06. Write a Unix tutorial, TUTORIAL_Unix.html.
DONE 2015_12_26. WANTED 2015_03_24
Add --sslargs with usage like:
imapsync ... --sslargs 'SSL_version=SSLv3' --sslargs 'SSL_use_cert=1' \
--sslargs 'SSL_verify_mode=SSL_VERIFY_PEER'
See perldoc IO::Socket::SSL for all possibilities.
DONE 2015_12_25 Gilles Lamiral
Add --ssldebug 0-4
DONE 2015_10_06. Find a way to avoid passwords in --debugimap unless needed.
Proposed in Mail-IMAPClient via $imap->Showcredentials()
in patch at
See https://rt.cpan.org/Public/Bug/Display.html?id=107592
DONE 2015_12_03 WANTED 2015_11_24 Jens Herrmann
Add --logdir to allow imapsync choosing the filename while allowing
user to choose the dirname part.
DONE. 2015_08_10. DONE. 2015_08_10.
Guess separators and prefixes when NAMESPACE is not available, Guess separators and prefixes when NAMESPACE is not available,
instead of forcing the user to guess and set them. instead of forcing the user to guess and set them.
@ -231,7 +249,7 @@ On Windows:
--regextrans2 "s,^INBOX$,${h2_prefix}FOO${h2_sep}INBOX," --regextrans2 "s,^INBOX$,${h2_prefix}FOO${h2_sep}INBOX,"
WON'T DO. Not enough examples. DONE. Quota are read if available and warning is printed if 90% quota reached.
Can you setup an option to make it stop if the destination mailbox reports Can you setup an option to make it stop if the destination mailbox reports
that it is over quota? that it is over quota?
@ -284,7 +302,7 @@ DONE. Add options --log and --logfile to log both on screen and to a file.
DONE. Document the tee command solution (Unix and Windows) in the FAQ. DONE. Document the tee command solution (Unix and Windows) in the FAQ.
NEVER. Add an option to implement the faq entry about copying a contact folder. NEVER. Add an option to implement the faq entry about copying a contact folder.
(write an dedicated software instead!) (write a dedicated software instead!)
NEVER. Use examine() instead of select() in --dry mode. NEVER. Use examine() instead of select() in --dry mode.
Add a method doing the switch automagicaly. Add a method doing the switch automagicaly.

View file

@ -1,158 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META NAME="generator" CONTENT="http://txt2tags.org">
</HEAD><BODY BGCOLOR="white" TEXT="black">
<CENTER>
</CENTER>
<P></P>
<HR NOSHADE SIZE=1>
<P></P>
<UL>
<LI><A HREF="#toc1">Tutorial for imapsync</A>
<UL>
<LI><A HREF="#toc2">Background knowledge about emailboxes</A>
<LI><A HREF="#toc3">Conventions</A>
</UL>
</UL>
<P></P>
<HR NOSHADE SIZE=1>
<P></P>
<A NAME="toc1"></A>
<H1>Tutorial for imapsync</H1>
<A NAME="toc2"></A>
<H2>Background knowledge about emailboxes</H2>
<P>
Three Internet protocols are used to access almost all email accounts:
POP3, IMAP, HTTP.
</P>
<P>
The oldest one still used is POP3, Post Office Protocol. POP3 allows only
one main box called INBOX. With POP3 messages have no flags, no Seen/UnSeen
Forwarded Flagged labels. Messages are often
removed from the POP3 server each time a software client looks into it,
so messages only appear on the client host that fetched them, they are
unavailable from any other system located elsewhere.
</P>
<P>
The second protocol to deal with email messages is IMAP, Internet Message Access Protocol.
IMAP allows a hierarchy of mailboxes also called folders, concurrent accesses,
tagging with flags, search by many criterium like date, subject, size etc.
IMAP protocol presents most of the features POP lacks.
Messages stay on the imap server so any client on the network can access them
at any time from anywhere, the same messages with the same flags.
</P>
<P>
The third protocol to access email messages is HTTP, HyperText Transfer Protocol.
HTTP is the protocol to surf the web.
Web browsers like Google Chrome, Mozilla Firefox, Internet Explorer, Safari,
are HTTP client softwares.
Webmails often offer the same features than imap servers because
webmails underlying storage systems are often imap servers.
So webmail mailboxes like Gmail, Yahoo, Exchange, Zimbra or Office365 are also accessible via imap.
</P>
<P>
The conclusion of this protocol review is that IMAP can be used
to access mailboxes most of the time. Here comes imapsync.
</P>
<P>
Software imapsync is a command line tool to
copy, migrate, backup or synchronize IMAP mailboxes.
</P>
<P>
Command line means imapsync is not graphical, it is textual,
you have to type characters on your keyboard.
Your fingers will not suffer anyway because
I wrote file examples nearly ready to go.
Most of the time you only have to change values
in those files and adapt them to your context.
</P>
<P>
Do not be afraid, the mouse will not be forsaken.
You can still use the mouse to launch an editor,
select/copy/paste complete examples
and run the little script you edit with a doubleclick.
</P>
<P>
Imapsync runs on Unix or Windows.
It is because imapsync is written in the Perl language
and thanks to the Perl creators Perl runs everywhere.
Outside imapsync life is different;
Historically Windows came after Unix and the marvelous designers
in this old times decided it would be very cool
to not share the same syntax for doing the same things.
Thanks guys, great thinking!
</P>
<P>
To avoid you to learn by headaches a system you do not master
I will give all examples in both worlds, Unix and Windows.
Macintosh users are in the Unix world now but do not tell them,
it can hurt the olders.
</P>
<A NAME="toc3"></A>
<H2>Conventions</H2>
<P>
Imapsync has many options but you can ignore most of them
and still make great transfers.
</P>
<P>
In this documentation I write all the examples as a complete example.
In order to simplify the reading or the printing,
the command is written on several lines.
It could be written on one single line;
if you prefer the whole command on one line then
just remove the last character of each line,
it is the "\" character on Unix examples
or the "^" character on Windows examples.
</P>
<P>
For example, on Unix
</P>
<PRE>
imapsync \
--host1 imap.truc.org \
--user1 foo \
--password1 secret1 \
...
</PRE>
<P>
is equivalent to
</P>
<PRE>
imapsync --host1 imap.truc.org --user1 foo --password1 secret1 ...
</PRE>
<P>
and on Windows
</P>
<PRE>
imapsync.exe ^
--host1 imap.truc.org ^
--user1 foo ^
--password1 secret1 ^
...
</PRE>
<P>
is equivalent to
</P>
<PRE>
imapsync --host1 imap.truc.org --user1 foo --password1 secret1 ...
</PRE>
<!-- html code generated by txt2tags 2.6 (http://txt2tags.org) -->
<!-- cmdline: txt2tags -i W/TUTORIAL.t2t -t html -\-toc -o TUTORIAL.html -->
</BODY></HTML>

View file

@ -1 +1 @@
1.670 1.678

View file

@ -1 +1 @@
1.670 1.678

View file

@ -360,3 +360,13 @@
1448852283 END 1.667 : lundi 30 novembre 2015, 03:58:03 (UTC+0100) 1448852283 END 1.667 : lundi 30 novembre 2015, 03:58:03 (UTC+0100)
1449111689 BEGIN 1.670 : jeudi 3 décembre 2015, 04:01:29 (UTC+0100) 1449111689 BEGIN 1.670 : jeudi 3 décembre 2015, 04:01:29 (UTC+0100)
1449112253 END 1.670 : jeudi 3 décembre 2015, 04:10:53 (UTC+0100) 1449112253 END 1.670 : jeudi 3 décembre 2015, 04:10:53 (UTC+0100)
1449744079 BEGIN 1.672 : jeudi 10 décembre 2015, 11:41:19 (UTC+0100)
1449744625 END 1.672 : jeudi 10 décembre 2015, 11:50:25 (UTC+0100)
1449767529 BEGIN 1.672 : jeudi 10 décembre 2015, 18:12:09 (UTC+0100)
1449767714 END 1.672 : jeudi 10 décembre 2015, 18:15:14 (UTC+0100)
1452122921 BEGIN 1.675 : jeudi 7 janvier 2016, 00:28:41 (UTC+0100)
1452123698 END 1.675 : jeudi 7 janvier 2016, 00:41:38 (UTC+0100)
1453217007 BEGIN 1.677 : mardi 19 janvier 2016, 16:23:27 (UTC+0100)
1453217776 END 1.677 : mardi 19 janvier 2016, 16:36:16 (UTC+0100)
1453407595 BEGIN 1.678 : jeudi 21 janvier 2016, 21:19:55 (UTC+0100)
1453408277 END 1.678 : jeudi 21 janvier 2016, 21:31:17 (UTC+0100)

File diff suppressed because it is too large Load diff

View file

@ -1,39 +0,0 @@
Changes
MANIFEST
Makefile.PL
README
examples/build_dist.pl
examples/build_ldif.pl
examples/cleanTest.pl
examples/copy_folder.pl
examples/cyrus_expire.pl
examples/cyrus_expunge.pl
examples/find_dup_msgs.pl
examples/idle.pl
examples/imap_to_mbox.pl
examples/imtestExample.pl
examples/migrate_mail2.pl
examples/migrate_mbox.pl
examples/populate_mailbox.pl
examples/sharedFolder.pl
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
prepare_dist
t/basic.t
t/body_string.t
t/bodystructure.t
t/fetch_hash.t
t/messageset.t
t/pod.t
t/simple.t
t/thread.t
test_template.txt
META.yml Module meta-data (added by MakeMaker)

View file

@ -1,43 +0,0 @@
--- #YAML:1.0
name: Mail-IMAPClient
version: 3.35
abstract: IMAP4 client library
author:
- Phil Pearl (Lobbes) <phil@zimbra.com>
license: perl
distribution_type: module
configure_requires:
ExtUtils::MakeMaker: 0
build_requires:
ExtUtils::MakeMaker: 0
requires:
Carp: 0
Errno: 0
Fcntl: 0
File::Temp: 0
IO::File: 0
IO::Select: 0
IO::Socket: 0
IO::Socket::INET: 1.26
List::Util: 0
MIME::Base64: 0
Parse::RecDescent: 1.94
perl: 5.008
Test::More: 0
resources:
bugtracker:
mailto: bug-Mail-IMAPClient@rt.cpan.org
web: http://rt.cpan.org/Public/Dist/Display.html?Name=Mail-IMAPClient
homepage: http://sourceforge.net/projects/mail-imapclient/
repository:
type: git
url: git://git.code.sf.net/p/mail-imapclient/git
web: http://sourceforge.net/p/mail-imapclient/git/
no_index:
directory:
- t
- inc
generated_by: ExtUtils::MakeMaker version 6.57_05
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: 1.4

View file

@ -1,138 +0,0 @@
use ExtUtils::MakeMaker;
use warnings;
use strict;
use 5.008_001;
my @missing;
my %optional = (
"Authen::NTLM" => { for => "Authmechanism 'NTLM'" },
"Authen::SASL" => { for => "Authmechanism 'DIGEST-MD5'" },
"Compress::Zlib" => { for => "COMPRESS DEFLATE support" },
"Digest::HMAC_MD5" => { for => "Authmechanism 'CRAM-MD5'" },
"Digest::MD5" => { for => "Authmechanism 'DIGEST-MD5'" },
"IO::Socket::SSL" => { for => "SSL enabled connections (Ssl => 1)" },
"Test::Pod" => { for => "Pod tests", ver => "1.00" },
);
foreach my $mod ( sort keys %optional ) {
my $for = $optional{$mod}->{"for"} || "";
my $ver = $optional{$mod}->{"ver"} || "";
eval "use $mod $ver ();";
push @missing, $mod . ( $for ? " for $for" : "" ) if $@;
}
# similar message to one used in DBI:
if (@missing) {
print( "The following optional modules were not found:",
map( "\n\t" . $_, @missing ), "\n" );
print <<'MSG';
Optional modules are available from any CPAN mirror, reference:
http://search.cpan.org/
http://www.perl.com/CPAN/modules/by-module
http://www.perl.org/CPAN/modules/by-module
MSG
sleep 3;
}
# HACK: die on broken Parse::RecDescent 1.966002 through 1.967009
# - rt.cpan.org#74593: Recent changes break Module::ExtractUse and ...
# - rt.cpan.org#74733: Fails with Parse::RecDescent >= 1.966_002
do {
eval { require version; require Parse::RecDescent; };
unless ($@) {
my $found = version->parse( Parse::RecDescent->VERSION() );
my $broke = version->parse("1.966002");
my $fixed = version->parse("1.967009");
if ( $found < $fixed and $found >= $broke ) {
die(
"Found broken Parse::RecDescent $found in your environment.\n",
"Please upgrade to version $fixed or greater.\n"
);
}
}
};
WriteMakefile(
NAME => 'Mail::IMAPClient',
AUTHOR => 'Phil Pearl (Lobbes) <phil@zimbra.com>',
ABSTRACT => 'IMAP4 client library',
VERSION_FROM => 'lib/Mail/IMAPClient.pm',
LICENSE => 'perl',
META_MERGE => {
resources => {
bugtracker => {
web =>
'http://rt.cpan.org/Public/Dist/Display.html?Name=Mail-IMAPClient',
mailto => 'bug-Mail-IMAPClient@rt.cpan.org',
},
homepage => 'http://sourceforge.net/projects/mail-imapclient/',
repository => {
url => 'git://git.code.sf.net/p/mail-imapclient/git',
web => 'http://sourceforge.net/p/mail-imapclient/git/',
type => 'git',
},
},
},
MIN_PERL_VERSION => '5.008',
PREREQ_PM => {
'Carp' => 0,
'Errno' => 0,
'Fcntl' => 0,
'IO::File' => 0,
'IO::Select' => 0,
'IO::Socket' => 0,
'IO::Socket::INET' => 1.26,
'List::Util' => 0,
'MIME::Base64' => 0,
'Parse::RecDescent' => 1.94,
'Test::More' => 0,
'File::Temp' => 0,
},
clean => { FILES => 'test.txt' },
);
set_test_data();
exit 0;
###
### HELPERS
###
sub set_test_data {
unless ( -f "lib/Mail/IMAPClient.pm" ) {
warn("ERROR: not in installation directory\n");
return;
}
if ( -s "./test.txt" ) {
print("The file test.txt will be used for extended tests.\n");
return;
}
print <<EOF;
(OPTIONAL) For extended tests during 'make test', create a file
'test.txt' in the top level directory of this distribution (the same
directory as the Makefile.PL, etc.). This file must contain an IMAP
server name or IP (server=...), a user account (user=...), and a
password (passed=...). A port (port=....) and an authentication
mechanism to be used (authmechanism=...) can also be specified.
Example:
--- BEGIN: test.txt ---
server=localhost
user=mytestuser
passed=mypassword
port=143
--- END: test.txt ---
NOTE: When testing is completed, be sure to remove test.txt (either by
hand or by 'make clean').
EOF
}

View file

@ -1,97 +0,0 @@
Mail::IMAPClient
================
Mail::IMAPClient is a Perl module that provides an interface for
communicating with an IMAP server as an IMAP client.
DEPENDENCIES
============
The following are the minimum requirements for using Mail::IMAPClient:
- Perl 5.8
http://www.perl.org/
- Perl modules from CPAN:
http://search.cpan.org/
Required:
List::Util
MIME::Base64
Parse::RecDescent
Optional:
Authen::NTLM
Authen::SASL
Compress::Zlib
Digest::HMAC_MD5
Digest::MD5
IO::Socket::SSL
- RFC 3501 (IMAP4REV1) compatible IMAP server
http://www.faqs.org/rfcs/rfc3501.html
- Mail::IMAPClient (this package)
INSTALLATION
============
1. Download Mail::IMAPClient module
http://search.cpan.org/dist/Mail-IMAPClient/
2. Read this README
3. This module has a number of dependencies on other Perl modules
available from CPAN. If any modules are missing, appropriate
warnings will be generated in the following step.
4. Prepare to build this module and install any prerequisite modules:
perl Makefile.PL
5. (OPTIONAL) For extended tests during 'make test', create a file
'test.txt' in the top level directory of this distribution (the
same directory as the Makefile.PL, etc.). This file must contain
an IMAP server name or IP (server=...), a user account (user=...),
and password a (passed=...). A port (port=....) and an
authentication mechanism to be used (authmechanism=...) can also be
specified.
Example:
--- BEGIN: test.txt ---
server=localhost
user=mytestuser
passed=mypassword
port=143
--- END: test.txt ---
NOTE: When testing is completed, be sure to remove test.txt (either
by hand or by 'make clean').
6. Build, test and install this module:
make
make test
(sudo) make install
7. Read the documentation to become familiar with this module.
Project Links
=============
- Bugs/tickets:
http://rt.cpan.org/Public/Dist/Display.html?Name=Mail-IMAPClient
- Source code repository (git):
http://sourceforge.net/p/mail-imapclient/git/
- CPAN releases:
http://search.cpan.org/dist/Mail-IMAPClient/
- Project website
http://sourceforge.net/projects/mail-imapclient/
COPYRIGHT AND LICENSE
=====================
Copyright (C) 1999-2003 The Kernen Group, Inc.
Copyright (C) 2007-2009 Mark Overmeer
Copyright (C) 2010-2013 Phil Pearl (Lobbes)
All rights reserved.
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.0 or,
at your option, any later version of Perl 5 you may have available.
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.

View file

@ -1,172 +0,0 @@
#!/usr/local/bin/perl
#$Id$
use Mail::IMAPClient;
=head1 DESCRIPTION
B<build_dist.pl> accepts the name of a target folder as an argument. It
then opens that folder and rummages through all the mail files in it, looking
for "Reply-to:" headers (or "From:" headers, where there is no "Reply-to:").
It then appends a message into the folder containing all of the addresses in
thus found as a list of recipients. This message can be used to conveniently
drag and drop names into an address book, distribution list, or e-mail message,
using the GUI client of choice.
The email appended to the folder specified in the I<-f> option will have the
subject "buid_dist.pl I<folder> Output".
=head1 SYNTAX
b<build_dist.pl> I<-h>
b<build_dist.pl> I<-s servername -u username -p password -f folder [ -d ]>
=over 4
=item -f The folder name to process.
=item -s The servername of the IMAP server
=item -u The user to log in as
=item -p The password for the user specified in the I<-u> option
=item -d Tells the IMAP client to turn on debugging info
=item -h Prints out this document
=back
B<NOTE:> You can supply defaults for the above options by updating the script.
=cut
use Getopt::Std;
getopts('s:u:p:f:d');
# Update the following to supply defaults:
$opt_f ||= "default folder";
$opt_s ||= "default server";
$opt_u ||= "default user";
$opt_p ||= "default password"; # security risk: use with caution!
# Let the compiler know we're serious about these two variables:
$opt_h = $opt_h or $opt_d = $opt_d ;
exec "perldoc $0" if $opt_h;
my $imap = Mail::IMAPClient->new(
Server => $opt_s ,
User => $opt_u ,
Password=> $opt_p ,
Debug => $opt_d||0 ,
) or die "can't connect to server\n";
$imap->select($opt_f);
my @msgs = $imap->search("NOT SUBJECT",qq("buid_dist.pl $opt_f Output"));
my %list;
foreach my $m (@msgs) {
my $ref = $imap->parse_headers($m,"Reply-to","From");
warn "Couldn't get recipient address from msg#$m\n"
unless scalar(@{$ref->{'Reply-to'}}) ||
scalar(@{$ref->{'From'}}) ;
my $from = scalar(@{$ref->{'Reply-to'}}) ?
$ref->{'Reply-to'}[0] :
$ref->{'From'}[0] ;
my $addr = $from;
$addr =~ s/.*<//;
$addr =~ s/[\<\>]//g;
$list{$addr} = $from unless exists $list{$addr};
}
$append = <<"EOMSG";
To: ${\(join(",",values %list))}
From: $opt_u\@$opt_s
Date: ${\($imap->Rfc822_date(time))}
Subject: build_dist.pl $opt_f Output
The above note was never actually sent to the following people:
${\(join("\n",keys %list))}
Interesting, eh?
Love,
$opt_u
EOMSG
$imap->append($opt_f,$append) or warn "Couldn't append the message.";
$imap->logout;
=head1 AUTHOR
David J. Kernen
The Kernen Group, Inc.
imap@kernengroup.com
=head1 COPYRIGHT
This example and Mail::IMAPClient are Copyright (c) 2003
by The Kernen Group, Inc. All rights reserved.
This example is distributed with Mail::IMAPClient and
subject to the same licensing requirements as Mail::IMAPClient.
imtest is a utility distributed with Cyrus IMAP server,
Copyright (c) 1994-2000 Carnegie Mellon University.
All rights reserved.
=cut
# $Id$
# $Log: build_dist.pl,v $
# Revision 19991216.7 2003/06/12 21:38:29 dkernen
#
# Preparing 2.2.8
# Added Files: COPYRIGHT
# Modified Files: Parse.grammar
# Added Files: Makefile.old
# Makefile.PL Todo sample.perldb
# BodyStructure.pm
# Parse.grammar Parse.pod
# range.t
# Thread.grammar
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
# rfc2221.txt rfc2359.txt rfc2683.txt
#
# Revision 19991216.6 2000/12/11 21:58:50 dkernen
#
# Modified Files:
# build_dist.pl build_ldif.pl copy_folder.pl find_dup_msgs.pl
# imap_to_mbox.pl populate_mailbox.pl
# to add CVS data
#
# Revision 19991216.5 1999/12/16 17:19:09 dkernen
# Bring up to same level
#
# Revision 19991124.3 1999/12/16 17:14:22 dkernen
# Incorporate changes for exists method performance enhancement
#
# Revision 19991124.02 1999/11/24 17:46:16 dkernen
# More fixes to t/basic.t
#
# Revision 19991124.01 1999/11/24 16:51:46 dkernen
# Changed t/basic.t to test for UIDPLUS before trying UID cmds
#
# Revision 1.8 1999/11/23 17:51:05 dkernen
# Committing version 1.06 distribution copy
#

View file

@ -1,235 +0,0 @@
#!/usr/local/bin/perl
#$Id$
use Mail::IMAPClient;
use MIME::Lite;
use Data::Dumper;
=head1 DESCRIPTION
B<build_ldif.pl> accepts the name of a target folder as an argument. It
then opens that folder and rummages through all the mail files in it, looking
for "Reply-to:" headers (or "From:" headers, where there is no "Reply-to:").
It then prints to STDOUT a file in ldif format containing entries for all of
the addresses that it finds. It also appends a message into the specified folder containing
all of the addresses in both the B<To:> field of the message header and in an
LDIF-format attachment.
B<build_ldif.pl> requires B<MIME::Lite>.
=head1 SYNTAX
B<build_ldif.pl> I<-h>
B<build_ldif.pl> I<-s servername -u username -p password -f folder [ -d ]>
=over 4
=item -f The folder name to process.
=item -s The servername of the IMAP server
=item -t Include "To" and "Cc" fields as well as "From"
=item -u The user to log in as
=item -p The password for the user specified in the I<-u> option
=item -d Tells the IMAP client to turn on debugging info
=item -n Suppress delivering message to folder
=item -h Prints out this document
=back
B<NOTE:> You can supply defaults for the above options by updating the script.
=cut
use Getopt::Std;
getopts('hs:u:p:f:dtn');
# Update the following to supply defaults:
$opt_f ||= "default folder";
$opt_s ||= "default server";
$opt_u ||= "default user";
$opt_p ||= "default password"; # security risk: use with caution!
# Let the compiler know we're serious about these variables:
$opt_0 = ( $opt_h or $opt_d or $opt_t or $opt_n or $opt_0);
exec "perldoc $0" if $opt_h;
my $imap = Mail::IMAPClient->new(
Server => $opt_s ,
User => $opt_u ,
Password=> $opt_p ,
Debug => $opt_d||0 ,
) or die "can't connect to server\n";
$imap->select($opt_f); $imap->expunge;
my @msgs = $imap->search("NOT SUBJECT",qq("buid_ldif.pl $opt_f Output"));
my %list;
foreach my $m (@msgs) {
my $ref = $imap->parse_headers($m,"Reply-to","From");
warn "Couldn't get recipient address from msg#$m\n"
unless scalar(@{$ref->{'Reply-to'}}) ||
scalar(@{$ref->{'From'}}) ;
my $from = scalar(@{$ref->{'Reply-to'}}) ?
$ref->{'Reply-to'}[0] :
$ref->{'From'}[0] ;
my $name = $from ;
$name =~ s/<.*// ;
if ($name =~ /\@/) {
$name = $from ;
$name =~ s/\@.*//; ;
}
$name =~ s/\"//g ;
$name =~ s/^\s+|\s+$//g ;
my $addr = $from ;
$addr =~ s/.*<// ;
$addr =~ s/[\<\>]//g ;
$list{lc($addr)} = [ $addr, $name ]
unless exists $list{lc($addr)} ;
if ($opt_t) { # Do "To" and "Cc", too
my $ref = $imap->parse_headers($m,"To","Cc") ;
my @array = ( @{$ref->{To}} , @{$ref->{Cc}} ) ;
my @members = () ;
foreach my $text (@array) {
while ( $text =~ / "([^"\\]*(\\.[^"\\]*)*"[^,]*),? |
([^",]+),? |
,
/gx
) {
push @members, defined($1)?$1:$3 ;
}
}
foreach my $to (@members) {
my $name = $to ;
$name =~ s/<.*// ;
if ($name =~ /\@/) {
$name = $to ;
$name =~ s/\@.*//; ;
}
$name =~ s/\"//g ;
$name =~ s/^\s+|\s+$//g ;
my $addr = $to ;
$addr =~ s/.*<// ;
$addr =~ s/[\<\>]//g ;
$list{lc($addr)} = [ $addr, $name ]
unless exists $list{lc($addr)} ;
}
}
}
my $text = join "",map {
qq{dn: cn="} . $list{$_}[1] .
qq{", mail=$list{$_}[0]\n} .
qq{cn: } . $list{$_}[1] . qq{\n} .
qq{mail: $list{$_}[0]\n} .
qq{objectclass: top\nobjectclass: person\n\n};
} keys %list ;
# Create a new multipart message:
my $msg = MIME::Lite->new(
From => $opt_u,
map({ ("To" => $list{$_}[0]) } keys %list),
Subject => "LDIF file from $opt_f",
Type =>'TEXT',
Data =>"Attached is the LDIF file of addresses from folder $opt_f."
);
$msg->attach( Type =>'text/ldif',
Filename => "$opt_f.ldif",
Data => $text ,
);
print $text;
$imap->append($opt_f, $msg->as_string) unless $opt_n;
print Dumper($imap) if $opt_d;
$imap->logout;
=head1 AUTHOR
David J. Kernen
The Kernen Group, Inc.
imap@kernengroup.com
=head1 COPYRIGHT
This example and Mail::IMAPClient are Copyright (c) 1999,2003
by The Kernen Group, Inc. All rights reserved.
This example is distributed with Mail::IMAPClient and
subject to the same licensing requirements as Mail::IMAPClient.
imtest is a utility distributed with Cyrus IMAP server,
Copyright (c) 1994-2000 Carnegie Mellon University.
All rights reserved.
=cut
# $Id$
# $Log: build_ldif.pl,v $
# Revision 19991216.11 2003/06/12 21:38:30 dkernen
#
# Preparing 2.2.8
# Added Files: COPYRIGHT
# Modified Files: Parse.grammar
# Added Files: Makefile.old
# Makefile.PL Todo sample.perldb
# BodyStructure.pm
# Parse.grammar Parse.pod
# range.t
# Thread.grammar
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
# rfc2221.txt rfc2359.txt rfc2683.txt
#
# Revision 19991216.10 2002/05/24 15:47:18 dkernen
# Misc fixes
#
# Revision 19991216.9 2000/12/11 21:58:51 dkernen
#
# Modified Files:
# build_dist.pl build_ldif.pl copy_folder.pl find_dup_msgs.pl
# imap_to_mbox.pl populate_mailbox.pl
# to add CVS data
#
# Revision 19991216.8 2000/03/02 19:57:13 dkernen
#
# Modified Files: build_ldif.pl -- to support new option to all "To:" and "Cc:" to be included in ldif file
#
# Revision 19991216.7 2000/02/21 16:16:10 dkernen
#
# Modified Files: build_ldif.pl -- to allow for "To:" and "Cc:" header handling and
# to handle quoted names in headers
#
# Revision 19991216.6 1999/12/28 13:56:59 dkernen
# Fixed -h option (help).
#
# Revision 19991216.5 1999/12/16 17:19:10 dkernen
# Bring up to same level
#
# Revision 19991124.3 1999/12/16 17:14:24 dkernen
# Incorporate changes for exists method performance enhancement
#
# Revision 19991124.02 1999/11/24 17:46:18 dkernen
# More fixes to t/basic.t
#
# Revision 19991124.01 1999/11/24 16:51:48 dkernen
# Changed t/basic.t to test for UIDPLUS before trying UID cmds
#
# Revision 1.8 1999/11/23 17:51:05 dkernen
# Committing version 1.06 distribution copy
#

View file

@ -1,64 +0,0 @@
#!/usr/local/bin/perl
use Mail::IMAPClient;
use IO::File;
#
# Example that will also clean out your test account if interrupted 'make test'
# runs have left junk folders there. Run from installation dir, installation/examples
# subdir, or supply full path to the test.txt file (created during 'perl Makefile.PL'
# and left in the installation dir until 'make clean').
# If you 've already run 'make clean' or said no to extended tests,
# then you don't have the file anyway; re-run 'perl Makefile.PL', reply 'y' to the
# extended tests prompt, then supply the test account's credentials as prompted.
# Then try this again.
#
if ( -f "./test.txt" ) {
$configFile = "./test.txt"
} elsif ( -f "../test.txt" ) {
$configFile = "../test.txt"
} elsif ( $ARGV[0] and -f "$ARGV[0]" ) {
$configFile = $ARGV[0];
} else {
print STDERR "Can't find test.txt. Please run this from the installation directory ",
"or supply the full path to test.txt as an argument on the command line.\n";
}
my $fh = IO::File->new("./test.txt") or die "./test.txt: $!\n";
while (my $input = <$fh>) {
chomp $input;
my($k,$v) = split(/=/,$input,2);
$conf{$k}=$v;
}
my $imap = Mail::IMAPClient->new(Server=>$conf{server},User=>$conf{user},
Password=>$conf{passed}) or die "Connecting to $conf{server}: $! $@\n";
for my $f ( grep(/^IMAPClient_/,$imap->folders) ) {
print "Deleting $f\n";
$imap->select($f);
$imap->delete_messages(@{$imap->messages}) ;
$imap->close($f);
$imap->delete($f);
}
=head1 AUTHOR
David J. Kernen
The Kernen Group, Inc.
imap@kernengroup.com
=head1 COPYRIGHT
This example and Mail::IMAPClient are Copyright (c) 2003
by The Kernen Group, Inc. All rights reserved.
This example is distributed with Mail::IMAPClient and
subject to the same licensing requirements as Mail::IMAPClient.
imtest is a utility distributed with Cyrus IMAP server,
Copyright (c) 1994-2000 Carnegie Mellon University.
All rights reserved.
=cut

View file

@ -1,147 +0,0 @@
#!/usr/local/bin/perl
#$Id$
++$|;
use Getopt::Std;
use Mail::IMAPClient;
use vars qw/$opt_r $opt_h $opt_t $opt_f/;
getopts("t:f:F:N:rh");
if ( $opt_h ) {
print &usage;
exit;
}
my($to_id,$to_pass,$thost) = $opt_t =~ m{
([^/]+) # everything up to / is the id
/ # then a slash
([^@]+) # then everything up to @ is pswd
@ # then an @-sign
(.*) # then everything else is the host
}x ;
my($from_id,$from_pass,$fhost) =
$opt_f =~ m{
([^/]+) # everything up to / is the id
/ # then a slash
([^@]+) # then everything up to @ is pswd
@ # then an @-sign
(.*) # then everything else is the host
}x ;
$to_id and $from_id and $to_pass and $from_pass and $thost and $fhost
or die "Error: Must specify -t and -f (to and from)\n" . &usage;
$opt_F or
die "Error: Must specify '-F folder' or how will I know what folder to copy?\n" .
&usage ;
$opt_N ||= $opt_F;
print "Copying folder $opt_F from $from_id\@$fhost to ${to_id}'s $opt_N folder on $thost.\n";
my ($from) = Mail::IMAPClient->new( Server => $fhost,
User => $from_id,
Password=> $from_pass,
Fast_IO => 1,
Uid => 1,
Debug => 0,
);
my ($to) = Mail::IMAPClient->new( Server => $thost,
User => $to_id,
Password=> $to_pass,
Fast_IO => 1,
Uid => 1,
Debug => 0,
);
my @folders = $opt_r ? @{$from->folders($opt_F)} : ( $opt_F ) ;
foreach my $fold (@folders) {
print "Processing folder $fold\n";
$from->select($fold);
if ($opt_F ne $opt_N) {
$fold =~s/^$opt_F/$opt_N/o;
}
unless ($to->exists($fold)) {
$to->create($fold) or warn "Couldn't create $fold\n" and next;
}
$to->select($fold);
my @msgs = $from->search("ALL");
# my %flaghash = $from->flags(\@msgs);
foreach $msg (@msgs) {
print "Processing message $msg in folder $fold.\n";
my $string = $from->message_string($msg);
# print "String = $string\n";
my $new_id = $to->append($fold,$string)
or warn "Couldn't append msg #$msg to target folder $fold.\n";
$to->store($new_id,"+FLAGS (" . join(" ",@{$from->flags($msg)}) . ")");
}
}
sub usage {
return "Syntax:\n\t$0 -t to_id/to_pass\@to.host -f from_id/from_pass\@from.host \\\n" .
"\t\t-F folder [-N New_Folder] [-r]\n".
"\tor\n\t$0 -h\n\n".
"\twhere:\n\t\t".
"to_id\t\tis the id to recieve the folder\n\t\t".
"to_pass\t\tis the password for to_id\n\t\t".
"from\t\tis the uid who currently has the folder\n\t\t".
"from_pass\tis the password for from_id\n\t\t".
"to.host\t\tis the optional host where the 'to' uid has a mailbox\n\t\t".
"from.host\tis the optional host where the 'from' uid has a mailbox\n\t\t".
"folder\t\tis the folder to copy from\n\t\t".
"New_Folder\tis the folder to copy to (defaults to 'folder')\n\t\t".
"-h\t\tprints this help message\n\t\t".
"-r\t\tspecifies a recursive copy (only works on systems that support the idea " .
"\n\t\t\t\tof recursive folders)\n\t\t".
"\n"
;
}
=head1 AUTHOR
David J. Kernen
The Kernen Group, Inc.
imap@kernengroup.com
=head1 COPYRIGHT
This example and Mail::IMAPClient are Copyright (c) 1999,2000,2003
by The Kernen Group, Inc. All rights reserved.
This example is distributed with Mail::IMAPClient and
subject to the same licensing requirements as Mail::IMAPClient.
imtest is a utility distributed with Cyrus IMAP server,
Copyright (c) 1994-2000 Carnegie Mellon University.
All rights reserved.
=cut
# History:
# $Log: copy_folder.pl,v $
# Revision 19991216.3 2003/06/12 21:38:30 dkernen
#
# Preparing 2.2.8
# Added Files: COPYRIGHT
# Modified Files: Parse.grammar
# Added Files: Makefile.old
# Makefile.PL Todo sample.perldb
# BodyStructure.pm
# Parse.grammar Parse.pod
# range.t
# Thread.grammar
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
# rfc2221.txt rfc2359.txt rfc2683.txt
#
# Revision 19991216.2 2000/12/11 21:58:51 dkernen
#
# Modified Files:
# build_dist.pl build_ldif.pl copy_folder.pl find_dup_msgs.pl
# imap_to_mbox.pl populate_mailbox.pl
# to add CVS data
#

View file

@ -1,111 +0,0 @@
#!/usr/local/bin/perl
#$Id
use Mail::IMAPClient; # available from http://search.cpan.org/search?mode=module&query=IMAPClient
use IO::File;
use Getopt::Std;
use vars qw/ $opt_d $opt_s $opt_p $opt_u $opt_P $opt_h /;
&getopts('d:s:u:p:P:h'); # -d days_to_keep -u cyrys_user -p cyrus_pswd -s cyrus_server -P port
my $days_to_keep = $opt_d||365; # Delete msgs older than -d arg or 365 days
my $cutoff = time - ( $days_to_keep * 24 * 60 * 60 ) ; # time - arg * 24 * 60 * 60 = cutoff date in seconds
# Change the following line (or replace it with something better):
$opt_h and die help()."\n";
my $h = $opt_s || "localhost" ;
my $u = $opt_u || "cyrys" ;
my $p = $opt_p or die "Unable to continue. No password provided.\n" . help();
my $imap = Mail::IMAPClient->new(
Server => "$h",
User => "$u", # $u,
Password=> "$p", # $p,
Uid => 1, # True value
Port => $opt_P||143, # imapd
Debug => 0, # Make true to debug
Buffer => 4096*10, # True value; decrease on machines w/little memory
Fast_io => 1, # True value
Timeout => 30, # True value
# Debug_fh=> IO::File->new(">out.db"), # fhandle
)
or die "$@";
my $mcnt = my $fcnt = 0;
print "Deleting messages older than ",$imap->Rfc2060_date($cutoff),"\n";
for my $f ( $imap->folders ) {
print "Expiring $f\n";
unless ($imap->select($f) ) {
$imap->setacl($f,$u,"lrswipcda") or warn "Cannot setacl for $f: $@\n" and next;
$imap->select($f) or warn "Cannot select $f: $@" and next;
}
my @expired = $imap->search("SENTBEFORE",$imap->Rfc2060_date($cutoff));
next unless @expired;
$mcnt += scalar(@expired); $fcnt ++;
print "Deleting ",scalar(@expired)," messages from $f\n";
$imap->delete_message(@expired);
$imap->expunge;
$imap->close;
}
$imap->logout;
print "Deleted a total of $mcnt messages in $fcnt folders.\n";
exit;
sub help {
return <<"EOHELP";
Usage:
$0 [ -d days_to_keep ] [ -s mail_server ] [ -u cyrus_admin_id ] -p cyrus_password
$0 -h
-h -- prints this here help message
-d days_to_keep -- $0 will delete messages older than "days_to_keep". (Default is 365)
-s mail_server -- hostname or IP Address of IMAP mail server (defaults to "localhost")
-u cyrus_admin_id -- user name of Unix account that owns Cyrus server (defaults to "cyrus")
-p cyrus_password -- password for the "cyrus_admin_id" user account (no default)
-P cyrus_port -- port where the cyrus imapd daemon is listening (defaults to value from
/etc/services or '143')
EOHELP
}
=head1 AUTHOR
David J. Kernen
The Kernen Group, Inc.
imap@kernengroup.com
=head1 COPYRIGHT
This example and Mail::IMAPClient are Copyright (c) 2003
by The Kernen Group, Inc. All rights reserved.
This example is distributed with Mail::IMAPClient and
subject to the same licensing requirements as Mail::IMAPClient.
imtest is a utility distributed with Cyrus IMAP server,
Copyright (c) 1994-2000 Carnegie Mellon University.
All rights reserved.
=cut
#$Log: cyrus_expire.pl,v $
#Revision 19991216.2 2003/06/12 21:38:31 dkernen
#
#Preparing 2.2.8
#Added Files: COPYRIGHT
#Modified Files: Parse.grammar
#Added Files: Makefile.old
# Makefile.PL Todo sample.perldb
# BodyStructure.pm
# Parse.grammar Parse.pod
# range.t
# Thread.grammar
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
# rfc2221.txt rfc2359.txt rfc2683.txt
#

View file

@ -1,85 +0,0 @@
#!/usr/local/bin/perl
#$Id$
use Mail::IMAPClient;
use IO::File;
# Change the following line (or replace it with something better):
my($h,$u,$p) = ('cyrus_host','cyrus_admin_id','cyrus_admin_pswd');
my $imap = Mail::IMAPClient->new( Server => "$h", # imap host
User => "$u", # $u,
Password=> "$p", # $p,
Uid => 1, # True value
Port => 143, # Cyrus
Debug => 0, # True value
Buffer => 4096*10, # True value
Fast_io => 1, # True value
Timeout => 30, # True value
# Debug_fh=> IO::File->new(">out.db"), # fhandle
)
or die "$@";
for my $f ( $imap->folders ) {
print "Expunging $f\n";
unless ($imap->select($f) ) {
$imap->setacl($f,$u,"lrswipcda") or warn "Cannot setacl for $f: $@\n" and next;
$imap->select($f) or warn "Cannot select $f: $@" and next;
}
$imap->expunge;
}
=head1 AUTHOR
David J. Kernen
The Kernen Group, Inc.
imap@kernengroup.com
=head1 COPYRIGHT
This example and Mail::IMAPClient are Copyright (c) 2003
by The Kernen Group, Inc. All rights reserved.
This example is distributed with Mail::IMAPClient and
subject to the same licensing requirements as Mail::IMAPClient.
imtest is a utility distributed with Cyrus IMAP server,
Copyright (c) 1994-2000 Carnegie Mellon University.
All rights reserved.
=cut
#
#$Log: cyrus_expunge.pl,v $
#Revision 19991216.3 2003/06/12 21:38:31 dkernen
#
#Preparing 2.2.8
#Added Files: COPYRIGHT
#Modified Files: Parse.grammar
#Added Files: Makefile.old
# Makefile.PL Todo sample.perldb
# BodyStructure.pm
# Parse.grammar Parse.pod
# range.t
# Thread.grammar
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
# rfc2221.txt rfc2359.txt rfc2683.txt
#
#Revision 1.1 2003/06/12 21:38:14 dkernen
#
#Preparing 2.2.8
#Added Files: COPYRIGHT
#Modified Files: Parse.grammar
#Added Files: Makefile.old
# Makefile.PL Todo sample.perldb
# BodyStructure.pm
# Parse.grammar Parse.pod
# range.t
# Thread.grammar
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
# rfc2221.txt rfc2359.txt rfc2683.txt
#
#

View file

@ -1,217 +0,0 @@
#!/usr/local/bin/perl
# $Id$
use Mail::IMAPClient;
use Mozilla::LDAP::Conn;
use Getopt::Std;
use vars qw/$rootdn $opt_a/;
use Data::Dumper;
# It then connects to a user's mailhost and rummages around,
# looking for duplicate messages.
# It will optionally delete messages that are duplicates (based on
# msg-id header and number of bytes).
# For help, enter:
# find_dup_msgs.pl -h
#
getopts('ahdtvf:F:u:s:p:P:');
if ( $opt_h ) {
print STDERR &usage;
exit;
}
my $uid = $opt_u or die &usage;
$opt_s||='localhost';
$opt_p or die &usage;
$opt_P||=143;
$opt_t and
$opt_d and
die "ERROR: Don't specify -d and -t together.\n" . &usage;
my($pu,$pp) = get_admin();
print "Connecting to $host:$opt_P\n" if $opt_v;
my $imap = Imap->new( Server => $opt_s,
User => $opt_u,
Password=> $opt_p,
Port => $opt_P,
Fast_io => 1,
) or die "couldn't connect to $host port $opt_P: $!\n";
my %folders; my %counts;
FOLDER: foreach my $f ( $opt_F ? $opt_F : $imap->folders ) {
next if $opt_t and $f eq 'Trash';
$folders{$f} = 0;
$counts{$f} = $imap->message_count($f);
print "Processing folder $f\n" if $opt_v;
unless ( $imap->select($f)) {
warn "Error selecting $f: " . $imap->LastError . "\n";
next FOLDER;
}
my @msgs = $imap->search("ALL");
my %hash = ();
MESSAGE: foreach my $m (@msgs) {
my $mid;
if ($opt_a) {
my $h = $imap->parse_headers(
$m,"Date","Subject","From","Message-ID"
) or next MESSAGE;
$mid = "$h->{'Date'}[0]$;$h->{'Subject'}[0]$;".
"$h->{'From'}[0]$;$h->{'Message-ID'}[0]";
} else {
$mid = $imap->parse_headers(
$m,
"Message-ID"
)->{'Message-ID'}[0]
or next MESSAGE;
}
my $size = $imap->size($m);
if ( exists $hash{$mid} and $hash{$mid} == $size ) {
if ($opt_f) {
open F,">>$opt_f" or
die "can't open $opt_f: $!\n";
print F $imap->message_string($m),
"___END OF SAVED MESSAGE___","\n";
close F;
}
$imap->move("Trash",$m) if $opt_t;
$imap->delete_message($m) if $opt_d;
$folders{$f}++;
print "Found a duplicate in ${f}; key = $mid\n" if $opt_v;
} else {
$hash{$mid} = $size;
}
}
print "$f hash:\n",Data::Dumper::Dumper(\%hash) if $opt_v;
$imap->expunge if ($opt_t or $opt_d);
}
my $total; my $totms;
map { $total += $_} values %folders;
map { $totms += $_ } values %counts;
print "Found $total duplicate messages in ${uid}'s mailbox. ",
"The breakdown is:\n",
"\tFolder\tNumber of Duplicates\tNumber of Msgs in Folder\n",
"\t------\t--------------------\t------------------------\n",
map { "\t$_\t$folders{$_}\t$counts{$_}\n" } keys %folders,
"\tTOTAL\t$total\t$totms\n"
;
sub usage {
return "Usage:\n" .
"\t$0 [-d|-t] [-v] [-f filename] [-a] [-P port] \\\n".
"\t\t-s server -u user -p password\n\n" .
"\t-a\t\tdo an especially aggressive search for duplicates\n".
"\t-d\t\tdelete duplicates (default is to just report them)\n".
"\t-f file\t\tsave deleted messages in file named 'file'\n" .
"\t-F fldr\t\tOnly check the folder named 'fldr' (default is to check all folders)\n" .
"\t-h\t\tprint this help message (all other options are ignored)\n" .
"\t-p password\tspecify the target user's password\n" .
"\t-P port\t\tspecify the port to connect to (default is 143)\n" .
"\t-s server\tspecify the target mail server\n" .
"\t-u uid\t\tspecify the target user\n" .
"\t-t\t\tmove deleted messages to trash folder\n" .
"\t-v\t\tprint verbose status messages while processing\n".
"\n" ;
}
=head1 AUTHOR
David J. Kernen
The Kernen Group, Inc.
imap@kernengroup.com
=head1 COPYRIGHT
This example and Mail::IMAPClient are Copyright (c) 2003
by The Kernen Group, Inc. All rights reserved.
This example is distributed with Mail::IMAPClient and
subject to the same licensing requirements as Mail::IMAPClient.
imtest is a utility distributed with Cyrus IMAP server,
Copyright (c) 1994-2000 Carnegie Mellon University.
All rights reserved.
=cut
# History:
# $Log: find_dup_msgs.pl,v $
# Revision 19991216.5 2003/06/12 21:38:32 dkernen
#
# Preparing 2.2.8
# Added Files: COPYRIGHT
# Modified Files: Parse.grammar
# Added Files: Makefile.old
# Makefile.PL Todo sample.perldb
# BodyStructure.pm
# Parse.grammar Parse.pod
# range.t
# Thread.grammar
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
# rfc2221.txt rfc2359.txt rfc2683.txt
#
# Revision 1.1 2003/06/12 21:38:14 dkernen
#
# Preparing 2.2.8
# Added Files: COPYRIGHT
# Modified Files: Parse.grammar
# Added Files: Makefile.old
# Makefile.PL Todo sample.perldb
# BodyStructure.pm
# Parse.grammar Parse.pod
# range.t
# Thread.grammar
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
# rfc2221.txt rfc2359.txt rfc2683.txt
#
# Revision 19991216.4 2002/08/23 14:34:51 dkernen
#
# Modified Files: Changes IMAPClient.pm Makefile Makefile.PL test.txt for version 2.2.0
# Added Files: Makefile Makefile.PL Parse.grammar Parse.pm Parse.pod version 2.2.0
# Added Files: parse.t for version 2.2.0
# Added Files: bodystructure.t for 2.2.0
# Modified Files: find_dup_msgs.pl for v2.2.0
#
# Revision 1.6 2001/03/08 19:00:35 dkernen
#
# ----------------------------------------------------------------------
# Modified Files:
# copy_folder.pl delete_mailbox.pl find_dup_msgs.pl
# mbox_check.pl process_orphans.pl rename_id.pl
# scratch_indexes.pl
# to get ready for nsusmsg02 upgrade
# ----------------------------------------------------------------------
#
# Revision 1.5 2000/11/01 15:51:58 dkernen
#
# Modified Files: copy_folder.pl find_dup_msgs.pl restore_mbox.pl
#
# Revision 1.4 2000/04/13 21:17:18 dkernen
#
# Modified Files: find_dup_msgs.pl - to add -a switch (for aggressive dup search)
# Added Files: copy_folder.pl - a utility for copying a folder from one user's
# mailbox to another's
#
# Revision 1.3 2000/03/14 16:40:21 dkernen
#
# Modified Files: find_dup_msgs.pl -- to skip msgs with no message-id
#
# Revision 1.2 2000/03/13 19:05:50 dkernen
#
# Modified Files:
# delete_mailbox.pl find_dup_msgs.pl restore_mbox.pl -- to add cvs comments
# find_dup_msgs.pl -- to fix bug that occurred when -t (move-to-trash) switch is used
#

View file

@ -1,231 +0,0 @@
#!/usr/bin/perl
=head1 NAME
idle.pl - example using IMAP idle
=head1 SYNOPSIS
idle.pl [options]
Options: [*] == Required, [+] == Multiple vals OK, (val) == Default
--o Server=<server> *IMAP server name/IP
--o User=<user> *User account to login to
--o Password=<passwd> *Password to use for the User account
(see security note below)
--o Port=<port> port on Server to connect to
--o Ssl=<bool> use SSL on this connection
--o Starttls=<bool> call STARTTLS on this connection
--o Debug=<int> enable debugging in Mail::IMAPClient
--o ImapclientKey=Val any other Mail::IMAPClient attribute/value pair
--folder <folder> folder (mailbox) to IMAP SELECT (INBOX)
--maxidle <sec> maximum time to idle without receiving data (300)
--help display a brief help message
--man display the entire man page
--debug enable script debugging
=head1 NOTES
=head2 --o Password=<password>
A password specified as a command-line option may be visible
to other users via the system process table. It may alternately be
given in the PASSWORD environment variable.
=head2 --maxidle <sec>
RFC 2177 states, "The server MAY consider a client inactive if it has
an IDLE command running, and if such a server has an inactivity
timeout it MAY log the client off implicitly at the end of its timeout
period. Because of that, clients using IDLE are advised to terminate
the IDLE and re-issue it at least every 29 minutes to avoid being
logged off."
The default of --maxidle 300 is used to allow the client to notice
when a connection has silently been closed upstream due to network or
firewall issue or configuration without missing too many idle events.
=cut
use strict;
use warnings;
use File::Basename qw(basename);
use Getopt::Long qw(GetOptions);
use Mail::IMAPClient qw();
use Pod::Usage qw(pod2usage);
use POSIX qw();
use constant {
FOLDER => "INBOX",
MAXIDLE => 300,
};
$| = 1; # set autoflush
my $DEBUG = 0; # GLOBAL set by process_options()
my $QUIT = 0;
my $VERSION = "1.00";
my $Prog = basename($0);
###
# main program
main();
sub main {
my %Opt = process_options();
pout("started $Prog\n");
my $imap = Mail::IMAPClient->new( %{ $Opt{opt} } )
or die("$Prog: error: Mail::IMAPClient->new: $@\n");
my ( $folder, $chkseen, $tag ) = ( $Opt{folder}, 1, undef );
$imap->select($folder)
or die("$Prog: error: select '$folder': $@\n");
$SIG{'INT'} = \&sigint_handler;
until ($QUIT) {
unless ( $imap->IsConnected ) {
warn("$Prog: reconnecting due to error: $@\n") if $imap->LastError;
$imap->connect or last;
$imap->select($folder) or last;
$tag = undef;
}
my $ret;
if ($chkseen) {
$chkseen = 0;
# end idle if necessary
if ($tag) {
$tag = undef;
$ret = $imap->done or last;
}
my $unseen = $imap->unseen_count;
last if $@;
pout("$unseen unseen/new message(s) in '$folder'\n") if $unseen;
}
# idle for X seconds unless data was returned by done
unless ($ret) {
$tag ||= $imap->idle
or die("$Prog: error: idle: $@\n");
warn( "$Prog: DEBUG: ", _ts(), " do idle_data($Opt{maxidle})\n" )
if $DEBUG;
$ret = $imap->idle_data( $Opt{maxidle} ) or last;
# connection can go stale so we exit/re-enter of idle state
# - RFC 2177 mentions 29m but firewalls may be more strict
unless (@$ret) {
warn( "$Prog: DEBUG: ", _ts(), " force exit of idle\n" )
if $DEBUG;
$tag = undef;
# restarted lost connections on next iteration
$ret = $imap->done or next;
}
}
local ( $1, $2, $3 );
foreach my $resp (@$ret) {
$resp =~ s/\015?\012$//;
warn("$Prog: DEBUG: server response: $resp\n") if $DEBUG;
# ignore:
# - DONE command
# - <tag> OK IDLE...
next if ( $resp eq "DONE" );
next if ( $resp =~ /^\w+\s+OK\s+IDLE\b/ );
if ( $resp =~ /^\*\s+(\d+)\s+(EXISTS)\b/ ) {
my ( $num, $what ) = ( $1, $2 );
pout("$what: $num message(s) in '$folder'\n");
$chkseen++;
}
elsif ( $resp =~ /^\*\s+(\d+)\s+(EXPUNGE)\b/ ) {
my ( $num, $what ) = ( $1, $2 );
pout("$what: message $num from '$folder'\n");
}
# * 83 FETCH (FLAGS (\Seen))
elsif ( $resp =~ /^\*\s+(\d+)\s+(FETCH)\s+(.*)/ ) {
my ( $num, $what, $info ) = ( $1, $2, $3 );
$chkseen++ if ( $info =~ /[\(|\s]\\Seen[\)|\s]/ );
pout("$what: message $num from '$folder': $info\n");
}
else {
pout("server response: $resp\n");
}
}
}
my $rc = 0;
if ($@) {
if ($QUIT) {
warn("$Prog: caught signal\n");
}
else {
$rc = 1;
}
warn("$Prog: imap error: $@\n") if ( !$QUIT || $DEBUG );
}
exit($rc);
}
###
# supporting routines
sub pout {
print( _ts(), " ", @_ );
}
sub process_options {
my ( %Opt, @err );
GetOptions( \%Opt, "opt=s%", "debug:1", "help", "man", "folder=s",
"maxidle:i" )
or pod2usage( -verbose => 0 );
pod2usage( -message => "$Prog: version $VERSION\n", -verbose => 1 )
if ( $Opt{help} );
pod2usage( -verbose => 2 ) if ( $Opt{man} );
# set global DEBUG
$DEBUG = $Opt{debug} || 0;
# folder (mailbox) to watch
$Opt{folder} = FOLDER unless ( exists $Opt{folder} );
# restart idle when no idle_data seen for this long
$Opt{maxidle} = MAXIDLE unless ( exists $Opt{maxidle} );
$Opt{opt}->{Password} = $ENV{PASSWORD}
if ( !exists $Opt{opt}->{Password} && defined $ENV{PASSWORD} );
foreach my $arg (qw(Server User Password)) {
push( @err, "-o $arg=<val> is required" ) if !exists $Opt{opt}->{$arg};
}
pod2usage(
-verbose => 1,
-message => join( "", map( "$Prog: $_\n", @err ) )
) if (@err);
return %Opt;
}
# example: 2005-10-02 07:50:32
sub _ts {
my %opt = @_;
my $fmt = $opt{fmt} || "%Y-%m-%d %T";
return POSIX::strftime( $fmt, localtime(time) );
}
sub sigint_handler {
$QUIT = 1;
}

View file

@ -1,266 +0,0 @@
#!/usr/local/bin/perl
# (c) 1999 Thomas Stromberg, Research Triangle Commerce, Inc.
# This software is protected by the BSD License. No rights reserved anyhow.
# <tstromberg@rtci.com>
# DESC: Reads a users IMAP folders, and converts them to mbox
# Good for an interim switch-over from say, Exchange to Cyrus IMAP.
# $Header$
# History:
# --------
# 2008/08/07 - Added SSL support, fixed From header printing, and CR
# elimination (sobek)
# TODO:
# -----
# lsub instead of list option
use warnings;
use strict;
use Mail::IMAPClient; # a nice set of perl libs for imap
use IO::Socket::SSL; # for SSL support
use vars qw($opt_h $opt_u $opt_p $opt_P $opt_s $opt_i $opt_f $opt_m $opt_b
$opt_c $opt_r $opt_w $opt_W $opt_S $opt_D $opt_U $opt_d $opt_I
$opt_n);
use Getopt::Std; # for the command-line overrides. good for user
use File::Path; # create full file paths. (yummy!)
use File::Basename; # find a nice basename for a folder.
use Date::Manip; # to create From header date
$| = 1;
sub connect_imap();
sub find_folders();
sub write_folder($$$$);
sub help();
# Config for the imap migration kit.
getopts('u:p:P:s:i:f:m:b:c:r:w:W:SDUdhIn:') or
$opt_h = 1;
my $SSL = $opt_S || 0;
my $SERVER = $opt_s || 'machine';
my $USER = $opt_u || 'userid';
my $PASSWORD = $opt_p || 'password';
my $PORT = $opt_P || '143';
my $INBOX_PATH = $opt_i || "/var/mail/$USER";
my $DOINBOX = $opt_I ? 0 : 1 || 1;
my $FOLDERS_PATH = $opt_f || "./folders/$USER";
my $DONT_MOVE = $opt_m || '.mailboxlist|Trash|INBOXIIMAP|mlbxl';
my $READ_DELIMITER = $opt_r || '/';
my $WRITE_DELIMITER = $opt_w || '/';
my $WRITE_MODE = $opt_W || '>';
my $BANNED_CHARS = $opt_b || '.|^|%';
my $CR = $opt_c || "\r";
my $NUMBER = $opt_n || "";
my $DELETE = $opt_D || 0;
my $DEBUG = $opt_d || "0";
my $UNSEEN = $opt_U || 0;
my $FAIL = 0;
my $imap; # definition for IMAP structure
if ($opt_h) {
# print help here
help();
}
sub help() {
print "imap_to_mbox.pl - with the following optional arguments\:
-S Use an SSL connection (default $SSL)
-s <s> Server specification (default $SERVER)
-u <u> User login (default $USER)
-p <p> User password
-P <p> Server Port (default $PORT)
-i <i> INBOX save path (default $INBOX_PATH)
-I skip INBOX (default $DOINBOX)
-f <f> Save path for other folders (default $FOLDERS_PATH)
-m <r> Regexp for IMAP folders not to be saved:
$DONT_MOVE
-r <r> Read delimiter (default \"$READ_DELIMITER\")
-w <w> Write Delimiter (default \"$WRITE_DELIMITER\")
-b <b> Banned chars (default \"$BANNED_CHARS\")
-c <c> Strip CRs from saved files [for Unix] (default \"$CR\")
-n <n> Receive only <n> messages (Default ".($NUMBER ? "$NUMBER" : "all").")
-U Unseen messages Only
-D Delete downloaded files on server
-d Debug mode (default $DEBUG)\n";
exit 1;
}
## do our magic tricks ######################################
connect_imap();
find_folders();
sub connect_imap()
{
# Open an SSL session to the IMAP server
# Handles the SSL setup, and gives us back a socket
my $ssl;
if ($opt_S) {
$ssl=IO::Socket::SSL->new(
PeerHost => "$SERVER:imaps"
# , SSL_version => 'SSLv2' # for older versions of openssl
);
defined $ssl
or die "Error connecting to $SERVER:imaps - $@";
$ssl->autoflush(1);
}
$imap = Mail::IMAPClient->new(
Socket => ($opt_S ? $ssl : 0),
Server => $SERVER,
User => $USER,
Password => $PASSWORD,
Port => $PORT,
Debug => $DEBUG,
Uid => 0,
Clear => 1,
)
or die ("Could not connect to $SERVER:$PORT with $USER: $! $?\n");
}
sub find_folders()
{
my @folders = $imap->folders;
# push(@folders, "INBOX");
foreach my $folder (@folders) {
my $message_count;
if ($folder eq "INBOX" and $DOINBOX == 0) {
print "* $folder is unwanted, skipping.\n";
next;
}
if (!$UNSEEN) {
$message_count = $imap->message_count($folder);
} else {
$message_count = $imap->unseen_count($folder) || 0;
}
if(! $message_count) {
print "* $folder is empty, skipping.\n";
next;
}
if($folder =~ /$DONT_MOVE/) {
warn "! $folder matches DONT_MOVE ruleset, skipping\n";
next;
}
my $new_folder = $folder;
$new_folder =~ s/\./_/g;
$new_folder =~ s/\Q$READ_DELIMITER/$WRITE_DELIMITER/g;
my $path
= $new_folder eq "INBOX" ? "$INBOX_PATH"
: "$FOLDERS_PATH/$new_folder";
if ($NUMBER && $NUMBER < $message_count) {
printf "x %4i %-45.45s => %s", $NUMBER, $folder, $path;
write_folder $folder, $path, 1, $NUMBER;
} else {
printf "x %4i %-45.45s => %s", $message_count, $folder, $path;
write_folder $folder, $path, 1, $message_count;
}
}
}
sub write_folder($$$$)
{ my($folder, $newpath, $first_message, $last_message) = @_;
$imap->select($folder)
or warn "Could not examine $folder: $!";
my $new_dir = dirname $newpath;
my $new_file = basename $newpath;
-d $new_dir
or mkpath($new_dir, 0700)
or die "Cannot create $new_dir:$!\n";
open my $mbox, $WRITE_MODE, $newpath
or die "Cannot create file $newpath: $!\n";
my @msgs = $imap->unseen if $UNSEEN;
for (my $i=$first_message; $i<$last_message+1; ++$i)
{ my $m = ($UNSEEN ? shift @msgs : $i);
my $date = UnixDate(ParseDate($imap->internaldate($m)),
"%a %b %e %T %Y");
my $user = $imap->get_envelope($m)->from_addresses;
$user =~ s/^.*<([^>]*)>/$1/;
$user = '-' unless $user;
print '.' if $m%25 == 0;
my $msg_header = $imap->fetch($m, "FAST")
or warn "Could not fetch header $m from $folder\n";
my $msg_rfc822 = $imap->fetch($m, "RFC822");
unless($msg_rfc822)
{ warn "Could not fetch RFC822 $m from $folder\n";
$FAIL=1
}
undef my $start;
foreach (@$msg_rfc822)
{ my $message;
if($_ =~ /\: / && !$message)
{ ++$message;
print $mbox "From $user $date\n";
}
if(/^\)\r/)
{ undef $message;
print $mbox "\n\n";
}
next unless $message;
$_ =~ s/\r$//;
$_ = $imap->Strip_cr($_) if $CR;
print $mbox "$_";
}
if($DELETE && ! $FAIL)
{ $imap->delete_message($m)
or warn "Could not delete_message: $@\n";
$FAIL = 0;
}
}
close $mbox
or die "Write errors to $newpath: $!\n";
if($DELETE)
{ $imap->expunge($folder)
or warn "Could not expunge: $@\n";
}
print "\n";
}
# 2008/08/07 - Added SSL support, fixed From header printing, and CR
# elimination (sobek)
#
# Revision 19991216.7 2002/08/23 13:29:48 dkernen
#
# Revision 19991216.6 2000/12/11 21:58:52 dkernen
#
# Revision 19991216.5 1999/12/16 17:19:12 dkernen
# Bring up to same level
#
# Revision 19991124.3 1999/12/16 17:14:25 dkernen
# Incorporate changes for exists method performance enhancement
#
# Revision 19991124.02 1999/11/24 17:46:19 dkernen
# More fixes to t/basic.t
#
# Revision 19991124.01 1999/11/24 16:51:49 dkernen
# Changed t/basic.t to test for UIDPLUS before trying UID cmds
#
# Revision 1.3 1999/11/23 17:51:06 dkernen
# Committing version 1.06 distribution copy

View file

@ -1,226 +0,0 @@
#!/usr/local/bin/perl
use Sys::Hostname;
use Mail::IMAPClient;
use IPC::Open3;
use IO::Socket::UNIX;
use IO::Socket;
use Socket;
use Getopt::Std;
&getopts('ha:df:i:o:p:r:m:u:x:w:p:s:');
if ($opt_h) {
print <<" HELP";
$0 -- uses imtest to connect and authenticate to imap server
Options:
-h print this help message
-a auth authenticate as user 'auth'. This value is passed as the '-a' value
to imtest and defaults to whatever you supplied for -u.
-d turn on Mail::IMAPClient debugging
-f file write Mail::IMAPClient debugging info to file 'file'
-m mech use authentication mechanism "mech"; default is to not supply -m to
imtest
-i path path to imtest executable; default is to let your shell find it via the
PATH environmental variable.
-p port port on mail server to connect to (default is 143)
-r rlm Use realm 'rlm' (default is name of mail server)
-s srvr Name of IMAP mail server (default is the localhost's hostname)
-u usr Use 'usr' as the user id (required)
-w pswd Use 'pswd' as the password for 'usr' (required)
-x path Path to Unix socket (fifo). Default is '/tmp/$0.sock'.
-o 'ops' Pass the string 'ops' directy to imtest as additional options.
This is how you get "other" imtest options passed to imtest. (I only
included switches for options that are either really common or useful
to the IMAPClient object as well as to imtest.)
Many of these switches have the same function here as with imtest. I added a
few extras though!
Example:
$0 -o '-k 128 -l 128' -s imapmail -u test -w testpswd \
-i /usr/local/src/cyrus/cyrus-imapd-2.1.11/imtest/ \
-m DIGEST-MD5
It's a good idea to test your options by running imtest from the command line
(but without the -x switch) first. Once you have it working by hand you should
be able to get it to work from this script (or one remarkably like it) without
too much bloodshed.
HELP
exit;
}
$opt_u and $opt_w or die "No userid/password credentials supplied. I hate that.\n";
$opt_a ||= $opt_u;
if ($opt_i ) {
$opt_i =~ m#^[/\.]# or $opt_i = "./$opt_i";
$opt_i =~ m#imtest$# or ( -x $opt_i and -f $opt_i )
or $opt_i .= ( $opt_i =~ m#/$# ? "imtest" : "/imtest") ;
-x $opt_i and -f $opt_i or die "Cannot find executable $opt_i\n";
}
$opt_p ||= 143;
$opt_s ||= hostname;
$opt_r ||= $opt_s;
$opt_x ||= "/tmp/$0.sock";
my($rfh,$wfh,$efh) ;
my($imt) = ($opt_i ? "$opt_i " : "imtest ") .
($opt_m ? "-m $opt_m ":"" ) .
qq(-r $opt_r -a $opt_a -u $opt_u ).
qq(-x $opt_x -w $opt_w -p $opt_p $opt_s);
open3($wfh,$rfh,$efh,$imt);
my $line;
until ($line =~ /^Security strength factor:/i ) {
$line = <$rfh> or die "EOF\n";
print STDERR "Prolog: $line" if $opt_d;
}
sleep 5;
my $sock = IO::Socket::UNIX->new("$opt_x")
or warn "No socket: $!\n" and exit;
print STDERR "<<<END OF PROLOG>>>\n" if $opt_d;
my $imap = Mail::IMAPClient->new;
$imap->Prewritemethod(\&Mail::IMAPClient::Strip_cr);
$imap->User("$opt_u");
$imap->Server("$opt_s");
$imap->Port("$opt_p");
$imap->Debug($opt_d);
$imap->Debug_fh($opt_f||\*STDERR);
$imap->State($imap->Connected);
$imap->Socket($sock);
# Your code goes here:
$imap->Select("INBOX");
for my $m (@{$imap->search("TEXT SUBJECT")} ) {
print "Message $m:\t",$imap->subject($m),"\n";
}
# You should have finished your code by about here
$imap->logout;
print STDERR "<<<END>>>\n" if $opt_d;
exit;
=head1 NAME
imtestExample.pl -- uses imtest to connect and authenticate to imap server
=head1 DESCRIPTION
=head2 Options
=over 4
=item -h
print this help message
=item -a auth
authenticate as user 'auth'. This value is passed as the '-a' value
to imtest and defaults to whatever you supplied for -u.
=item -d
turn on Mail::IMAPClient debugging
=item -f file
write Mail::IMAPClient debugging info to file 'file'
=item -m mech
use authentication mechanism "mech"; default is to not supply -m to
imtest
=item -i path
path to imtest executable; default is to let your shell find it via the
PATH environmental variable.
=item -p port
port on mail server to connect to (default is 143)
=item -r rlm
Use realm 'rlm' (default is name of mail server)
=item -s srvr
Name of IMAP mail server (default is the localhost's hostname)
=item -u usr
Use 'usr' as the user id (required)
=item -w pswd
Use 'pswd' as the password for 'usr' (required)
=item -x path
Path to Unix socket (fifo). Default is '/tmp/$0.sock'.
=item -o 'ops'
Pass the string 'ops' directy to imtest as additional options.
This is how you get "other" imtest options passed to imtest. (I only
included switches for options that are either really common or useful
to the IMAPClient object as well as to imtest.)
Many of these switches have the same function here as with imtest. I added a
few extras though!
=back
Example:
imtestExample.pl -o '-k 128 -l 128' -s imapmail -u test -w testpswd \
-i /usr/local/src/cyrus/cyrus-imapd-2.1.11/imtest/ \
-m DIGEST-MD5
It's a good idea to test your options by running imtest from the command line
(but without the -x switch) first. Once you have it working by hand you should
be able to get it to work from this script (or one remarkably like it) without
too much bloodshed.
=head1 AUTHOR
David J. Kernen
The Kernen Group, Inc.
imap@kernengroup.com
Based on a suggestion by Tara L. Andrews.
=head1 COPYRIGHT
This example and Mail::IMAPClient are Copyright (c) 2003
by The Kernen Group, Inc. All rights reserved.
This example is distributed with Mail::IMAPClient and
subject to the same licensing requirements as Mail::IMAPClient.
imtest is a utility distributed with Cyrus IMAP server,
Copyright (c) 1994-2000 Carnegie Mellon University.
All rights reserved.
=cut

View file

@ -1,326 +0,0 @@
#!/usr/local/bin/perl
#$Id$
#
# An example of how to migrate from a Netscape server
# (which uses a slash as a separator and which does
# not allow subfolders under the INBOX, only next to it)
# to a Cyrus server (which uses a dot (.) as a separator
# and which requires subfolders to be under "INBOX").
# There are also some allowed-character differences taken
# into account but this is by no means complete AFAIK.
#
# This is an example. If you are doing mail migrations
# then this may in fact be a very helpful example but
# it is unlikely to work 100% correctly as-is.
# A good place to start is by testing a rather large-volume
# transfer of actual mail from the source server with the
# -v option turned on and redirect output to a file for
# perusal. Examine the output carefully for unexpected
# results, such as a number of messages being skipped because
# they're already in the target folder when you know darn
# well this is the first time you ran the script. This
# would indicate an incompatibility with the logic for
# detecting duplicates, unless for some reason the source
# mailbox contains a lot of duplicate messages to begin with.
# (The latter case is an example of why you should use an
# actual mailbox stuffed with actual mail for test; if you
# generate test messages and then test migrating those you
# will only prove that your test messages are migratable.
#
# Also, you may need to play with the rules
# for translating folder names based on what kind of
# names your target server and source server support.
#
# You may also need to play with the logic that determines
# whether or not a message has already been migrated,
# especially if your source server has messages that
# did not come from an SMTP gateway or something like that.
#
# Some servers allow folders to contain mail and subfolders,
# some allow folders to only contain either mail or subfolders.
# If you are migrating from a "mixed use" type to a "single use"
# type server then you'll have to figure out how to deal
# with this. (This script deals with this by creating folders like
# "/blah_mail", "/blah/blah_mail", and "/blah/blah/blah_mail"
# to hold mail if the source folder contains mail and subfolders
# and the target server supports only single-use folders.
# You may not choose a different strategy.)
#
# Finally, it's possible that in some server-to-server
# copies, the source server supports messages that the
# target server considers unacceptable. For example, some
# but not all IMAP servers flat out refuse to accept
# messages with "base newlines", which is to say messages
# whose lines are match the pattern /[^\r]\n$/. There is
# no logic in this script that deals with the situation;
# you will have to identify it if it exists and figure
# out how you want to handle it.
#
# This is probably not an exhaustive list of issues you'll
# face in a migration, but it's a start.
#
# If you're just migrating from an old version to a newer
# version of the same server then you'll probably have
# a much easier time of it.
#
#
use Mail::IMAPClient;
use Data::Dumper;
use IO::File;
use File::Basename ;
use Getopt::Std;
use strict;
use vars qw/ $opt_B $opt_D $opt_T $opt_U
$opt_W $opt_b $opt_d $opt_h
$opt_t $opt_u $opt_w $opt_v
$opt_s $opt_S $opt_W $opt_p
$opt_P $opt_f $opt_F $opt_m
$opt_M
/;
getopts('vs:S:u:U:dDb:B:f:F:w:W:p:P:t:T:hm:M:');
if ( $opt_h ) {
print STDERR <<"HELP";
$0 - an example script demonstrating the use of the Mail::IMAPClient's
migrate method.
Syntax:
$0 -s source_server -u source_user -w source_password -p source_port \
-d debug_source -f source_debugging_file -b source_buffsize \
-t source_timeout -m source_auth_mechanism \
-S target_server -U target_user -W target_password -P target_port \
-D debug_target -F target_debugging_file -B target_buffsize \
-T target_timeout -M target_auth_mechanism \
-v
where "source" refers to the "copied from" mailbox, target is the
"copied to" mailbox, and -v turns on verbose output.
Authentication mechanisms default to "PLAIN".
HELP
exit;
}
$opt_v and ++$|;
print "$0: Started at ",scalar(localtime),"\n" if $opt_v;
$opt_p||=143;
$opt_P||=143;
# Make a connection to the source mailbox:
my $imap = Mail::IMAPClient->new(
Server => $opt_s,
User => $opt_u,
Password=> $opt_w,
Uid => 1,
Port => $opt_p,
Debug => $opt_d||0,
Buffer => $opt_b||4096,
Fast_io => 1,
( $opt_m ? ( Authmechanism => $opt_m) : () ),
Timeout => $opt_t,
($opt_f ? ( Debug_fh=>IO::File->new(">$opt_f" )) : ()),
) or die "$@";
# Make a connection to the target mailbox:
my $imap2 = Mail::IMAPClient->new(
Server => $opt_S,
User => $opt_U,
Password=> $opt_W,
Port => $opt_P,
Uid => 1,
Debug => $opt_D||0,
( $opt_M ? ( Authmechanism => $opt_M) : () ),
($opt_F ? ( Debug_fh=>IO::File->new(">$opt_F")) : ()),
Buffer => $opt_B||4096,
Fast_io => 1,
Timeout => $opt_T, # True value
) or die "$@";
# Turn off buffering on debug files:
$imap->Debug_fh->autoflush;
$imap2->Debug_fh->autoflush;
# Get folder hierarchy separator characters from source and target:
my $sep1 = $imap->separator;
my $sep2 = $imap2->separator;
# Find out if source and target support subfolders inside INBOX:
my $inferiorFlag1 = $imap->is_parent("INBOX");
my $inferiorFlag2 = $imap2->is_parent("INBOX");
# Set up a test folders to see if the source and target support mixed-use
# folders (i.e. folders with both subfolders and mail messages):
my $testFolder1 = "Migrate_Test_$$" ; # Ex: Migrate_Test_1234
$testFolder1 = $inferiorFlag2 ?
"INBOX" . $sep2 . $testFolder1 :
$testFolder1 ;
# The following folder will be a subfolder of $testFolder1:
my $testFolder2 = "Migrate_Test_$$" . $sep2 . "Migrate_test_subfolder_$$" ;
$testFolder2 = $inferiorFlag2 ? "INBOX" . $sep2 . $testFolder2 : $testFolder2 ;
$imap2->create($testFolder2) ; # Create the subfolder first; RFC2060 dictates that
# the parent folder should be created at the same time
# The following line inspired the selectable method. It was also made obsolete by it,
# but I'm leaving it as is to demonstrate use of lower-level method calls:
my $mixedUse2 = grep(/NoSelect/i,$imap2->list("",$testFolder1))? 0 : 1;
# Repeat the above with the source mailbox:
$testFolder2 = "Migrate_Test_$$" . $sep1 . "Migrate_test_subfolder_$$" ;
$testFolder2 = $inferiorFlag1 ? "INBOX" . $sep1 . $testFolder1 : $testFolder1 ;
$imap->create($testFolder2) ;
my $mixedUse1 = grep(/NoSelect/i,$imap->list("",$testFolder1))? 0 : 1;
print "Imap host $opt_s:$opt_p uses a '$sep1' as a separator and ",
( defined($inferiorFlag1) ? "allows " : "does not allow "),
"children in the INBOX. It supports ",
($mixedUse1?"mixed use ":"single use "), "folders.\n" if $opt_v;
print "Imap host $opt_S:$opt_P uses a '$sep2' as a separator and ",
( defined($inferiorFlag2) ? "allows " : "does not allow "),
"children in the INBOX. It supports ",
($mixedUse2?"mixed use ":"single use "), "folders.\n" if $opt_v;
for ($testFolder1,$testFolder2) {$imap->delete($_); $imap2->delete($_);}
my($totalMsgs, $totalBytes) = (0,0);
# Now we will migrate the folder. Here we are doing one message at a time
# so that we can do more granular status reporting and error checking.
# A lazier way would be to do all the messages in one migrate method call
# (specifying "ALL" as the message number) but then we wouldn't be able
# to print out which message we were migrating and it would be a little
# bit tougher to control checking for duplicates and stuff like that.
# We could also check the size of the message on the target right after
# the migrate as an extra safety check if we wanted to but I didn't bother
# here. (I saved as an exercise for the reader. Yeah! That's it! An exercise!)
# Iterate over all the folders in the source mailbox:
for my $f ($imap->folders) {
# Select the folder on the source side:
$imap->select($f) ;
# Massage the foldername into an acceptable target-side foldername:
my $targF = "";
my $srcF = $f;
$srcF =~ s/^INBOX$sep1//i;
if ( $inferiorFlag2 ) {
$targF = $srcF eq "INBOX" ? "INBOX" : "INBOX.$f" ;
} else {
$targF = $srcF ;
}
$targF =~ s/$sep1/$sep2/go unless $sep1 eq $sep2;
$targF =~ tr/#\$\& '"/\@\@+_/;
if ( $imap->is_parent($f) and !$mixedUse2 ) {
$targF .= "_mail" ;
}
print "Migrating folder $f to $targF\n" if $opt_v;
# Create the (massaged) folder on the target side:
unless ( $imap2->exists($targF) ) {
$imap2->create($imap2->Massage($targF))
or warn "Cannot create $targF on " . $imap2->Server . ": $@\n" and next;
}
# ... and select it
$imap2->select($imap2->Massage($targF))
or warn "Cannot select $targF on " . $imap2->Server . ": $@\n" and next;
# now that we know the target folder is selectable, we can close it again:
$imap2->close;
my $count = 0;
my $expectedTotal = $imap->message_count($f) ;
# Now start iterating over all the messages on the source side...
for my $msg ($imap->messages) {
++$count;
my $h = "";
# Get some basic info about the message:
eval { $h = ($imap->parse_headers($msg,"Message-id")||{})->{'Message-id'}[0]};
my $tsize = $imap->size($msg);
my $ret = 0 ; my $h2 = [];
# Make sure we didn't already migrate the message in a previous pass:
$imap2->select($targF);
if ( $tsize and $h and $h2 = $imap2->search(
HEADER => 'Message-id' => $imap2->Quote($h),
NOT => SMALLER => $tsize,
NOT => LARGER => $tsize
)
) {
print
"Skipping $f/$msg to $targF. ",
"One or more messages (" ,join(", ",@$h2),
") with the same size and message id ($h) ",
"is already on the server. ",
"\n"
if $opt_v;
$imap2->close;
} else {
print
"Migrating $f/$msg to $targF. ",
"Message #$count of $expectedTotal has ",
$tsize , " bytes.",
"\n" if $opt_v;
$imap2->close;
# Migrate the message:
my $ret = $imap->migrate($imap2,$msg,"$targF") ;
$ret and ( $totalMsgs++ , $totalBytes += $tsize);
$ret or warn "Cannot migrate $f/$msg to $targF on " . $imap2->Server . ": $@\n" ;
}
}
}
print "$0: Finished migrating $totalMsgs messages and $totalBytes bytes at ",scalar(localtime),"\n"
if $opt_v;
exit;
=head1 AUTHOR
David J. Kernen
The Kernen Group, Inc.
imap@kernengroup.com
=head1 COPYRIGHT
This example and Mail::IMAPClient are Copyright (c) 2003
by The Kernen Group, Inc. All rights reserved.
This example is distributed with Mail::IMAPClient and
subject to the same licensing requirements as Mail::IMAPClient.
imtest is a utility distributed with Cyrus IMAP server,
Copyright (c) 1994-2000 Carnegie Mellon University.
All rights reserved.
=cut
#$Log: migrate_mail2.pl,v $
#Revision 19991216.4 2003/06/12 21:38:33 dkernen
#
#Preparing 2.2.8
#Added Files: COPYRIGHT
#Modified Files: Parse.grammar
#Added Files: Makefile.old
# Makefile.PL Todo sample.perldb
# BodyStructure.pm
# Parse.grammar Parse.pod
# range.t
# Thread.grammar
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
# rfc2221.txt rfc2359.txt rfc2683.txt
#

View file

@ -1,131 +0,0 @@
#!/usr/local/bin/perl
#
# This is an example demonstrating the use of the migrate method.
# Note that the migrate method is considered experimental and should
# be used with caution.
#
#$Id$
#
use Mail::IMAPClient;
use IO::File;
use File::Basename ;
use Getopt::Std;
use warnings;
use vars qw/$opt_h $opt_H
$opt_s $opt_u $opt_p $opt_d $opt_b $opt_o
$opt_S $opt_U $opt_P $opt_D $opt_B $opt_O
/;
getopts('Hhs:S:u:U:p:P:d:D:b:B:o:O:');
if ($opt_h or $opt_H ) {
print << "HELP";
Usage:
$0 -[h|H] -- prints this message
Lower-case options are for source server; upper-case options are for the target server.
$0 -s server -S server -u uid -U uid -p passwd -P passwd \
-b buffersize -B buffersize -o debugFile -O debugFile > error_file
All uppercase options except -O default to the lowercase option that was specified.
If you don't specify any uppercase options at all then God help you, I don't know
what will happen.
Always capture STDERR so that you'll be able to resolve any problems that come up.
HELP
exit;
}
my $imap = Mail::IMAPClient->new(
Server => $opt_s,
User => $opt_u,
Password=> $opt_p,
Uid => 1,
Debug => $opt_d,
Buffer => $opt_b||4096,
Fast_io => 1,
Timeout => 160, # True value
Debug_fh=> (
$opt_o ? IO::File->new(">$opt_o")||die "can't open $opt_o: $!\n" : undef )
) or die "Error opening source connection: $@\n";
my $imap2 = Mail::IMAPClient->new(
Server => $opt_S||$opt_s,
User => $opt_U||$opt_u,
Password=> $opt_P||$opt_p,
Uid => 1,
Debug => $opt_D||$opt_d,
Buffer => $opt_B||$opt_b||4096,
Fast_io => 1,
Timeout => 160,
Debug_fh=> (
$opt_O ? IO::File->new(">$opt_O")||die "can't open $opt_O: $!\n" : undef )
) or die "Error opening target connection: $@\n";
$imap->Debug_fh->autoflush;
$imap2->Debug_fh->autoflush;
for my $f ($imap->folders) { $imap->select($f) ; $imap->migrate($imap2,"ALL") ;}
=head1 AUTHOR
David J. Kernen
The Kernen Group, Inc.
imap@kernengroup.com
=head1 COPYRIGHT
This example and Mail::IMAPClient are Copyright (c) 2003
by The Kernen Group, Inc. All rights reserved.
This example is distributed with Mail::IMAPClient and
subject to the same licensing requirements as Mail::IMAPClient.
imtest is a utility distributed with Cyrus IMAP server,
Copyright (c) 1994-2000 Carnegie Mellon University.
All rights reserved.
=cut
#
#$Log: migrate_mbox.pl,v $
#Revision 19991216.2 2003/06/12 21:38:33 dkernen
#
#Preparing 2.2.8
#Added Files: COPYRIGHT
#Modified Files: Parse.grammar
#Added Files: Makefile.old
# Makefile.PL Todo sample.perldb
# BodyStructure.pm
# Parse.grammar Parse.pod
# range.t
# Thread.grammar
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
# rfc2221.txt rfc2359.txt rfc2683.txt
#
#Revision 1.1 2003/06/12 21:38:15 dkernen
#
#Preparing 2.2.8
#Added Files: COPYRIGHT
#Modified Files: Parse.grammar
#Added Files: Makefile.old
# Makefile.PL Todo sample.perldb
# BodyStructure.pm
# Parse.grammar Parse.pod
# range.t
# Thread.grammar
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
# rfc2221.txt rfc2359.txt rfc2683.txt
#
#

View file

@ -1,319 +0,0 @@
#!/usr/local/bin/perl
#$Id$ #
use Time::Local ;
use FileHandle ;
use File::Copy ;
use Mail::IMAPClient;
use Sys::Hostname ;
#
my $default_user = 'default' ;
my $default_pswd = 'default' ;
#
#########################################################################
# ARGS: DATE = YYYYMMDDHHMM (defaults to current system date) #
# UID = IMAP account id (defaults to $default_user) #
# PSWD = uid's password (defaults to $default_pswd) #
# HOST = Target host (defaults to localhost) #
# CLEAN = 1 (defaults to 0; used to clean out mailbox 1st) #
# CLEANONLY= 1 (defaults to 0; if 1 then only CLEAN is done) #
# DOMAIN = x.com (no default) the mail domain for UID's address #
# #
# EG: populate_mailbox.pl DATE=200001010100 UID=testuser #
# #
#########################################################################
#
(my($x)= join(" ",@ARGV)) ;
$x=~s~=~ ~g ;
chomp($x) ;
#
my %hash = split(/\s+/, $x) if $x ;
#
while (my ($k,$v) = each %hash ) {
$hash{uc $k} = $v ;
}
while (my ($k,$v) = each %hash ) {
delete $hash{$k} if $k =~ tr/[a-z]// ;
}
;
$hash{UID} ||= "$default_user" ;
$hash{PSWD} ||= "$default_pswd" ;
$hash{HOST} ||= hostname ;
#
while (my ($k,$v) = each %hash ) {
print "Running with $k set to $v\n" ;
}
#
my $domain = $hash{DOMAIN} or die "No mail domain provided.\n" ;
my $now = seconds($hash{DATE}) || time ;
#
my $six = $now - ( 6 * 24 * 60 * 60 ) ;
my $seven = $now - ( 7 * 24 * 60 * 60 ) ;
my $notthirty = $now - ( 29 * 24 * 60 * 60 ) ;
my $thirty = $now - ( 30 * 24 * 60 * 60 ) ;
my $notsixty = $now - ( 59 * 24 * 60 * 60 ) ;
my $sixty = $now - ( 60 * 24 * 60 * 60 ) ;
my $notd365 = $now - ( 364 * 24 * 60 * 60 ) ;
my $d365 = $now - ( 365 * 24 * 60 * 60 ) ;
#
$hash{SUBJECTS} = [ "Sixty days old", "Less than sixty days old" ,
"365 days old", "Less than 365 days old" ,
"Trash/Incinerator -- 7 days old" ,
"Sent -- 29 days old" ,
"Sent -- 30 days old" ,
"Trash -- 6 days old" ,
] ;
$hash{FOLDERS} = [ "Sent", "INBOX", "Trash" ,
"365_folder", "Trash/Incinerator" ,
"not_365_folder" ,
] ;
#
&clean_mailbox if $hash{CLEANONLY} || $hash{CLEAN} ;
exit if $hash{CLEANONLY} ;
#
#send to: date: subject: #
#-------- --- ----- --------- #
sendmail( $hash{UID}, $sixty, "Sixty days old" ) ;
sendmail( $hash{UID}, $notsixty, "Less than sixty days old") ;
sendmail( $hash{UID}, $d365, "365 days old" ) ;
sendmail( $hash{UID}, $notd365, "Less than 365 days old" ) ;
#
populate_trash("Trash/Incinerator",$hash{UID}, $seven, 7 ) ;
populate_trash( "Trash" , $hash{UID}, $six, 6 ) ;
populate_trash( "Sent" , $hash{UID}, $thirty, 30 ) ;
populate_trash( "Sent" , $hash{UID}, $notthirty, 29 ) ;
#
movemail( "365 days old" ,
"365_folder" ) ;
#
movemail( "Less than 365 days old" ,
"not_365_folder" ) ;
#
exit ;
#
#
sub seconds {
my $d = shift or return undef ;
my($yy,$moy,$dom,$hr,$min) =
#
$d =~ m! ^ # anchor at start #
(\d\d\d\d) # year #
(\d\d) # month #
(\d\d) # day #
(\d\d) # hour #
(\d\d) # minute #
!x ;
#
return timegm(0,$min,$hr,$dom,$moy-1,($yy>99?$yy-1900:$yy)) ;
}
#
sub sendmail {
#
my($to,$date,$subject) = @_ ;
my $text = <<EOTEXT ;
To: $to\@$hash{DOMAIN}
Date: @{[&rfc822_date($date)]}
Subject: $subject
Dear mail tester,
This is a test message to test mail for messages \l$subject.
I hope you like it!
Love,
The E-Mail Engineering Team
EOTEXT
#
for (my $x = 0; $x < 10 ; $x ++ ) {
my $imap = Mail::IMAPClient->new (
Server => $hash{HOST} ,
User => $hash{UID} ,
Password=> $hash{PSWD} )
or die "can't connect: $!\n" ;
#
$imap->append("INBOX",$text) ;
$imap->logout ;
}
}
#
sub populate_trash {
my $where = shift ;
my $to = shift ;
my $date = shift ;
my $d = shift ;
#
my($ss,$min,$hr,$day,$mon,$year)=gmtime($date) ;
$mon++ ;
$year += 1900 ;
my $fn =sprintf("%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d" ,
$year,$mon,$day,$hr,$min,$ss ) ;
my $x = 0 ;
my $subject = "$where -- $d days old" ;
while ($x++ < 10) {
my $fh ;
$fh .= "Date: @{[&rfc822_date($date)]}\n" ;
$fh .= <<EOTRAH ;
Subject: $subject
This note was put in the $where folder $d days ago. (My how time flies!)
I hope you enjoyed testing with it!
EOTRAH
my $imap = Mail::IMAPClient->new (
Server => $hash{HOST} ,
User => $hash{UID} ,
Password=> $hash{PSWD} )
or die "can't connect: $!\n" ;
$imap->append($where, $fh) ;
#
}
#
}
#
sub movemail {
#
my ($subj,$fold) = @_ ;
my $fh = Mail::IMAPClient->new (
Debug => 0 ,
Server => $hash{HOST} ,
User => $hash{UID} ,
Password => $hash{PSWD} ,
)
;
#
$fh->select("inbox") or die "cannot open inbox: $!\n" ;
#
foreach my $f ($fh->search(qq(SUBJECT "$subj")) ) {
#
$fh->move($fold,$f) ;
#
}
#
}
#
sub clean_mailbox {
#
my $fh =Mail::IMAPClient->new (
Debug => 0 ,
Server => $hash{HOST} ,
User => $hash{UID} ,
Password => $hash{PSWD} ,
)
;
for my $x (@{$hash{FOLDERS}}) {
my @msgs ;
$fh->create($x) unless $fh->exists($x) ;
$fh->select($x) ;
for my $s (@{$hash{SUBJECTS}}) {
push @msgs, $fh->search(qq(SUBJECT "$s")) ;
}
$fh->delete_message(@msgs) if scalar(@msgs) ;
$fh->expunge ;
}
}
#
sub rfc822_date {
#Date: Fri, 09 Jul 1999 13:10:55 -0400 #
my $date = shift ;
my @date = localtime($date) ;
my @dow = qw{ Sun Mon Tue Wed Thu Fri Sat } ;
my @mnt = qw{ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec} ;
#
return sprintf (
"%s, %2.2d %s %4.4s %2.2d:%2.2d:%2.2d -0400" ,
$dow[$date[6]] ,
$date[3] ,
$mnt[$date[4]] ,
$date[5]+=1900 ,
$date[2] ,
$date[1] ,
$date[0] )
;
}
=head1 AUTHOR
David J. Kernen
The Kernen Group, Inc.
imap@kernengroup.com
=head1 COPYRIGHT
This example and Mail::IMAPClient are Copyright (c) 2003
by The Kernen Group, Inc. All rights reserved.
This example is distributed with Mail::IMAPClient and
subject to the same licensing requirements as Mail::IMAPClient.
imtest is a utility distributed with Cyrus IMAP server,
Copyright (c) 1994-2000 Carnegie Mellon University.
All rights reserved.
=cut
# $Id$
# $Log: populate_mailbox.pl,v $
# Revision 19991216.8 2003/06/12 21:38:34 dkernen
#
# Preparing 2.2.8
# Added Files: COPYRIGHT
# Modified Files: Parse.grammar
# Added Files: Makefile.old
# Makefile.PL Todo sample.perldb
# BodyStructure.pm
# Parse.grammar Parse.pod
# range.t
# Thread.grammar
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
# rfc2221.txt rfc2359.txt rfc2683.txt
#
# Revision 1.1 2003/06/12 21:38:16 dkernen
#
# Preparing 2.2.8
# Added Files: COPYRIGHT
# Modified Files: Parse.grammar
# Added Files: Makefile.old
# Makefile.PL Todo sample.perldb
# BodyStructure.pm
# Parse.grammar Parse.pod
# range.t
# Thread.grammar
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
# rfc2221.txt rfc2359.txt rfc2683.txt
#
# Revision 19991216.7 2002/08/23 13:29:49 dkernen
#
# Modified Files: Changes IMAPClient.pm INSTALL MANIFEST Makefile Makefile.PL README Todo test.txt
# Made changes to create version 2.1.6.
# Modified Files:
# imap_to_mbox.pl populate_mailbox.pl
# Added Files:
# cleanTest.pl migrate_mbox.pl
#
# Revision 19991216.6 2000/12/11 21:58:53 dkernen
#
# Modified Files:
# build_dist.pl build_ldif.pl copy_folder.pl find_dup_msgs.pl
# imap_to_mbox.pl populate_mailbox.pl
# to add CVS data
#
# Revision 19991216.5 1999/12/16 17:19:15 dkernen
# Bring up to same level
#
# Revision 19991124.3 1999/12/16 17:14:26 dkernen
# Incorporate changes for exists method performance enhancement
#
# Revision 19991124.02 1999/11/24 17:46:21 dkernen
# More fixes to t/basic.t
#
# Revision 19991124.01 1999/11/24 16:51:51 dkernen
# Changed t/basic.t to test for UIDPLUS before trying UID cmds
#
# Revision 1.4 1999/11/23 17:51:06 dkernen
# Committing version 1.06 distribution copy
#

View file

@ -1,88 +0,0 @@
#!/usr/local/bin/perl
#$Id$
use Mail::IMAPClient;
use Getopt::Std;
use File::Basename;
getopts('s:u:p:f:dh');
if ($opt_h) {
print STDERR "$0 -- example of how to select shared folder\n",
"\n\nUsage:\n",
"\t-s server -- specify name or ip address of mail server\n",
"\t-u userid -- specify login name of authenticating user\n",
"\t-p passwd -- specify login password of authenticating user\n",
"\t-f folder -- specify shared folder to access (i.e. '-f frank/INBOX')\n",
"\t-h display this help message\n\n";
"\t-d turn on debugging output\n\n";
exit;
}
my $server = $opt_s or die "No server name specified\n";
my $user = $opt_u or die "No user name specified\n";
my $pass = $opt_p or die "No password specified\n";
my $folder = $opt_f or die "No shared folder specified\n";
chomp $pass;
my $imap = Mail::IMAPClient->new(Server=>$server,User=>$user,Password=>$pass,Debug=>$opt_d)
or die "Can't connect to $user\@$server: $@ $!\n";
my($prefix,$prefSep) = @{$imap->namespace->[1][0]}
or die "Can't get shared folder namespace or separator: $@\n";
my $target = $prefix .
( $prefix =~ /\Q$prefSep\E$/ || $opt_f =~ /^\Q$prefSep/ ? "" : $prefSep ) .
$opt_f ;
print "Selecting $target\n";
$imap->select($target)
or die "Cannot select $target: $@\n";
print "Ok: $target has ", $imap->message_count($target)," messages.\n";
$imap->logout;
exit;
=head1 AUTHOR
David J. Kernen
The Kernen Group, Inc.
imap@kernengroup.com
=head1 COPYRIGHT
This example and Mail::IMAPClient are Copyright (c) 2003
by The Kernen Group, Inc. All rights reserved.
This example is distributed with Mail::IMAPClient and
subject to the same licensing requirements as Mail::IMAPClient.
imtest is a utility distributed with Cyrus IMAP server,
Copyright (c) 1994-2000 Carnegie Mellon University.
All rights reserved.
=cut
#
#$Log: sharedFolder.pl,v $
#Revision 19991216.1 2003/06/12 21:38:35 dkernen
#
#Preparing 2.2.8
#Added Files: COPYRIGHT
#Modified Files: Parse.grammar
#Added Files: Makefile.old
# Makefile.PL Todo sample.perldb
# BodyStructure.pm
# Parse.grammar Parse.pod
# range.t
# Thread.grammar
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
# rfc2221.txt rfc2359.txt rfc2683.txt
#
#

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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>
convenience 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 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
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 numbers
=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 specify 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 negligible. 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.

View file

@ -1,43 +0,0 @@
#!/usr/bin/perl
use strict;
use warnings;
use File::Copy qw/move/;
use Parse::RecDescent 1.94;
sub read_file {
my $file = shift;
local ( $/, *FH );
open( FH, $file ) or return undef;
return <FH>;
}
build_parser(
'lib/Mail/IMAPClient/BodyStructure/Parse.grammar',
'Mail::IMAPClient::BodyStructure::Parse'
);
build_parser( 'lib/Mail/IMAPClient/Thread.grammar',
'Mail::IMAPClient::Thread' );
sub build_parser {
my ( $grammarfn, $package ) = @_;
print("* building $package\n");
my $grammar = read_file($grammarfn)
or die("cannot read grammar from $grammarfn: $!\n");
Parse::RecDescent->Precompile( $grammar, $package );
# clumpsy output by Parse::RecDescent
my $outfn = $package . '.pm';
$outfn =~ s/.*\:\://;
my $realfn = $grammarfn;
$realfn =~ s/\.\w+$/.pm/;
move( $outfn, $realfn )
or die("cannot move $outfn to $realfn: $!\n");
}

View file

@ -1,444 +0,0 @@
#!/usr/bin/perl
use strict;
use warnings;
use IO::File qw();
use Test::More;
use File::Temp qw(tempfile);
my $debug = $ARGV[0];
my %parms;
my $range = 0;
my $uidplus = 0;
my $fast = 1;
BEGIN {
open TST, 'test.txt'
or plan skip_all => 'test parameters not provided in test.txt';
while ( my $l = <TST> ) {
chomp $l;
my ( $p, $v ) = split /\=/, $l, 2;
s/^\s+//, s/\s+$// for $p, $v;
$parms{$p} = $v if $v;
}
close TST;
my @missing;
foreach my $p (qw/server user passed/) {
push( @missing, $p ) unless defined $parms{$p};
}
@missing
? plan skip_all => "missing value for: @missing"
: plan tests => 88;
}
BEGIN { use_ok('Mail::IMAPClient') or exit; }
my %new_args = (
Server => delete $parms{server},
Port => delete $parms{port},
User => delete $parms{user},
Password => delete $parms{passed},
Authmechanism => delete $parms{authmech},
Clear => 0,
Fast_IO => $fast,
Uid => $uidplus,
Debug => $debug,
);
# allow other options to be placed in test.txt
%new_args = ( %new_args, %parms );
my $imap = Mail::IMAPClient->new(
%new_args,
Range => $range,
Debug_fh => ( $debug ? IO::File->new( 'imap1.debug', 'w' ) : undef ),
);
ok( defined $imap, 'created client' );
$imap
or die "Cannot log into $new_args{Server} as $new_args{User}.\n"
. "Are server/user/password correct?\n";
isa_ok( $imap, 'Mail::IMAPClient' );
$imap->Debug_fh->autoflush() if $imap->Debug_fh;
my $testmsg = <<__TEST_MSG;
Date: @{[$imap->Rfc822_date(time)]}
To: <$new_args{User}\@$new_args{Server}>
From: Perl <$new_args{User}\@$new_args{Server}>
Subject: Testing from pid $$
This is a test message generated by $0 during a 'make test' as part of
the installation of the Mail::IMAPClient module from CPAN.
__TEST_MSG
ok( $imap->noop, "noop" );
ok( $imap->tag_and_run("NOOP\r\n"), "tag_and_run" );
my $sep = $imap->separator;
ok( defined $sep, "separator is '$sep'" );
{
my $list = $imap->list();
is( ref($list), "ARRAY", "list" );
my $lsub = $imap->lsub();
is( ref($lsub), "ARRAY", "lsub" );
}
my $ispar = $imap->is_parent('INBOX');
my ( $target, $target2 ) =
$ispar
? ( "INBOX${sep}IMAPClient_$$", "INBOX${sep}IMAPClient_2_$$" )
: ( "IMAPClient_$$", "IMAPClient_2_$$" );
ok( defined $ispar, "INBOX is_parent '$ispar' (note: target '$target')" );
ok( $imap->select('inbox'), "select inbox" );
# folders
{
my @f = $imap->folders();
ok( @f, "folders" . ( $debug ? ":@f" : "" ) );
my @fh = $imap->folders_hash();
my @fh_keys = qw(attrs delim name);
ok( @fh, "folders_hash keys: @fh_keys" );
ok( eq_set( ( [ keys %{ $fh[0] } ], [ @fh_keys ] ) ) );
}
# test append_file
my $append_file_size;
{
my ( $afh, $afn ) = tempfile UNLINK => 1;
# write message to autoflushed file handle since we keep $afh around
my $oldfh = select($afh);
$| = 1;
select($oldfh);
print( $afh $testmsg ) or die("print testmsg failed");
cmp_ok( -s $afn, '>', 0, "tempfile has size" );
ok( $imap->create($target), "create target" );
my $uid = $imap->append_file( $target, $afn );
ok( defined $uid, "append_file test message to $target" );
ok( $imap->select($target), "select $target" );
my $msg = ( $uidplus and $uid ) ? $uid : ( $imap->messages )[0];
my $size = $imap->size($msg);
cmp_ok( $size, '>', 0, "has size $size" );
my $string = $imap->message_string($msg);
ok( defined $string, "returned string" );
cmp_ok( length($string), '==', $size, "string matches server size" );
ok( $imap->delete($target), "delete folder $target" );
$append_file_size = $size;
}
ok( $imap->create($target), "create target" );
ok( $imap->select($target), "select $target" );
# Test append / append_string if we also have UID capability
SKIP: {
skip "UIDPLUS not supported", 3 unless $imap->has_capability("UIDPLUS");
my $ouid = $imap->Uid();
$imap->Uid(1);
# test with date that has a leading space
my $d = " 1-Jan-2011 01:02:03 -0500";
my $uid = $imap->append_string( $target, $testmsg, undef, $d );
ok( defined $uid, "append test message to $target with date (uid=$uid)" );
ok( $imap->delete_message($uid), "delete_message $uid" );
ok( $imap->uidexpunge($uid), "uidexpunge $uid" );
# multiple args joined internally in append()
$uid = $imap->append( $target, $testmsg, "Some extra text too" );
ok( defined $uid, "append test message to $target with date (uid=$uid)" );
ok( $imap->delete_message($uid), "delete_message $uid" );
ok( $imap->uidexpunge($uid), "uidexpunge $uid" );
$imap->Uid($ouid);
}
# test append
{
my $uid = $imap->append( $target, $testmsg );
ok( defined $uid, "append test message to $target" );
my $msg = ( $uidplus and $uid ) ? $uid : ( $imap->messages )[0];
my $size = $imap->size($msg);
cmp_ok( $size, '>', 0, "has size $size" );
my $string = $imap->message_string($msg);
ok( defined $string, "returned string" );
cmp_ok( length($string), '==', $size, "string == server size" );
{
my $var;
ok( $imap->message_to_file( \$var, $msg ), "to SCALAR ref" );
cmp_ok( length($var), '==', $size, "correct size" );
my ( $fh, $fn ) = tempfile UNLINK => 1;
ok( $imap->message_to_file( $fn, $msg ), "to file $fn" );
cmp_ok( -s $fn, '==', $size, "correct size" );
}
cmp_ok( $size, '==', $append_file_size, "size matches string/file" );
# save first message/folder for use below...
#OFF ok( $imap->delete($target), "delete folder $target" );
}
#OFF ok( $imap->create($target), "create target" );
ok( $imap->exists($target), "exists $target" );
ok( $imap->create($target2), "create $target2" );
ok( $imap->exists($target2), "exists $target2" );
{
ok( $imap->subscribe($target), "subscribe target" );
my $sub1 = $imap->subscribed();
is( ( grep( /^\Q$target\E$/, @$sub1 ) )[0], "$target", "subscribed" );
ok( $imap->unsubscribe($target), "unsubscribe target" );
my $sub2 = $imap->subscribed();
is( ( grep( /^\Q$target\E$/, @$sub2 ) )[0], undef, "unsubscribed" );
}
ok( $imap->select($target), "select $target" );
my $fwquotes = qq($target${sep}has "quotes");
if ( !$imap->is_parent($target) ) {
ok( 1, "not parent, skipping quote test 1/3" );
ok( 1, "not parent, skipping quote test 2/3" );
ok( 1, "not parent, skipping quote test 3/3" );
}
elsif ( $imap->create($fwquotes) ) {
ok( 1, "create $fwquotes" );
ok( $imap->select($fwquotes), 'select $fwquotes' );
ok( $imap->close, 'close $fwquotes' );
$imap->select('inbox');
ok( $imap->delete($fwquotes), 'delete $fwquotes' );
}
else {
if ( $imap->LastError =~ /NO Invalid.*name/ ) {
ok( 1, "$new_args{Server} doesn't support quotes in folder names" );
}
else { ok( 0, "failed creation with quotes" ) }
ok( 1, "skipping 1/2 tests" );
ok( 1, "skipping 2/2 tests" );
}
my $fields = $imap->search( "HEADER", "Message-id", "NOT_A_MESSAGE_ID" );
is( scalar @$fields, 0, 'bogus message id does not exist' );
my @seen = $imap->seen;
cmp_ok( scalar @seen, '==', 1, 'have seen 1' );
ok( $imap->deny_seeing( \@seen ), 'deny seeing' );
my @unseen = $imap->unseen;
cmp_ok( scalar @unseen, '==', 1, 'have unseen 1' );
ok( $imap->see( \@seen ), "let's see one" );
cmp_ok( scalar @seen, '==', 1, 'have seen 1' );
$imap->deny_seeing(@seen); # reset
$imap->Peek(1);
my $subject = $imap->parse_headers( $seen[0], "Subject" )->{Subject}[0];
unlike( join( "", $imap->flags( $seen[0] ) ), qr/\\Seen/i, 'Peek==1' );
$imap->deny_seeing(@seen);
$imap->Peek(0);
$subject = $imap->parse_headers( $seen[0], "Subject" )->{Subject}[0];
like( join( "", $imap->flags( $seen[0] ) ), qr/\\Seen/i, 'Peek==0' );
$imap->deny_seeing(@seen);
$imap->Peek(undef);
$subject = $imap->parse_headers( $seen[0], "Subject" )->{Subject}[0];
unlike( join( "", $imap->flags( $seen[0] ) ), qr/\\Seen/i, 'Peek==undef' );
my $uid2 = $imap->copy( $target2, 1 );
ok( $uid2, "copy $target2" );
my @res = $imap->fetch( 1, "RFC822.TEXT" );
ok( scalar @res, "fetch rfc822" );
my $res1 = $imap->fetch_hash("RFC822.SIZE");
is( ref($res1), "HASH", "fetch_hash(RFC822.SIZE)" );
my $res2 = $imap->fetch_hash( 1, "RFC822.SIZE" );
is( ref($res2), "HASH", "fetch_hash(1,RFC822.SIZE)" );
my $h = $imap->parse_headers( 1, "Subject" );
ok( $h, "got subject" );
like( $h->{Subject}[0], qr/^Testing from pid/, "subject matched" );
ok( $imap->select($target), "select $target" );
my @hits = $imap->search( SUBJECT => 'Testing' );
cmp_ok( scalar @hits, '==', 1, 'hit subject Testing' );
ok( defined $hits[0], "subject is defined" );
ok( $imap->delete_message(@hits), 'delete hits' );
my $flaghash = $imap->flags( \@hits );
my $flagflag = 0;
foreach my $v ( values %$flaghash ) {
$flagflag += grep /\\Deleted/, @$v;
}
cmp_ok( $flagflag, '==', scalar @hits, "delete verified" );
my @nohits = $imap->search( \qq(SUBJECT "Productioning") );
cmp_ok( scalar @nohits, '==', 0, 'no hits expected' );
ok( $imap->restore_message(@hits), 'restore messages' );
$flaghash = $imap->flags( \@hits );
foreach my $v ( values %$flaghash ) {
$flagflag-- unless grep /\\Deleted/, @$v;
}
cmp_ok( $flagflag, '==', 0, "restore verified" );
$imap->select($target2);
ok(
$imap->delete_message( scalar( $imap->search("ALL") ) )
&& $imap->close
&& $imap->delete($target2),
"delete $target2"
);
$imap->select("INBOX");
$@ = undef;
@hits =
$imap->search( BEFORE => Mail::IMAPClient::Rfc2060_date(time), "UNDELETED" );
ok( !$@, "search undeleted" ) or diag( '$@:' . $@ );
#
# Test migrate method
#
my $im2 = Mail::IMAPClient->new(
%new_args,
Timeout => 30,
Debug_fh => ( $debug ? IO::File->new(">./imap2.debug") : undef ),
);
ok( defined $im2, 'started second imap client' );
my $source = $target;
$imap->select($source)
or die "cannot select source $source: $@";
$imap->append( $source, $testmsg ) for 1 .. 5;
$imap->close;
$imap->select($source);
my $migtarget = $target . '_mirror';
$im2->create($migtarget)
or die "can't create $migtarget: $@";
$im2->select($migtarget)
or die "can't select $migtarget: $@";
$imap->migrate( $im2, scalar( $imap->search("ALL") ), $migtarget )
or die "couldn't migrate: $@";
$im2->close;
$im2->select($migtarget)
or die "can't select $migtarget: $@";
ok( !$@, "LastError not set" ) or diag( '$@:' . $@ );
#
my $total_bytes1 = 0;
for ( $imap->search("ALL") ) {
my $s = $imap->size($_);
$total_bytes1 += $s;
print "Size of msg $_ is $s\n" if $debug;
}
my $total_bytes2 = 0;
for ( $im2->search("ALL") ) {
my $s = $im2->size($_);
$total_bytes2 += $s;
print "Size of msg $_ is $s\n" if $debug;
}
ok( !$@, "LastError not set" ) or diag( '$@:' . $@ );
cmp_ok( $total_bytes1, '==', $total_bytes2, 'size source==target' );
# cleanup
$im2->select($migtarget);
$im2->delete_message( @{ $im2->messages } )
if $im2->message_count;
ok( $im2->close, "close" );
$im2->delete($migtarget);
ok_relaxed_logout($im2);
# Test IDLE
SKIP: {
skip "IDLE not supported", 4 unless $imap->has_capability("IDLE");
ok( my $idle = $imap->idle, "idle" );
sleep 1;
ok( $imap->idle_data, "idle_data" );
ok( $imap->done($idle), "done" );
ok( !$@, "LastError not set" ) or diag( '$@:' . $@ );
}
$imap->select('inbox');
if ( $imap->rename( $target, "${target}NEW" ) ) {
ok( 1, 'rename' );
$imap->close;
$imap->select("${target}NEW");
$imap->delete_message( @{ $imap->messages } ) if $imap->message_count;
$imap->close;
$imap->delete("${target}NEW");
}
else {
ok( 0, 'rename failed' );
$imap->delete_message( @{ $imap->messages } )
if $imap->message_count;
$imap->close;
$imap->delete($target);
}
$imap->_disconnect;
ok( $imap->reconnect, "reconnect" );
ok_relaxed_logout($imap);
# STARTTLS - an optional feature
if ( $imap->_load_module("SSL") ) {
$imap->connect( Ssl => 0, Starttls => 1 );
ok( 1, "OPTIONAL connect(Starttls=>1)" . ( $@ ? ": (error) $@ " : "" ) );
}
else {
ok( 1, "skipping optional STARTTLS test" );
}
# LOGOUT
# - on successful LOGOUT $code is OK (not BYE!) see RFC 3501 sect 7.1.5
# however some servers return BYE instead so we let that pass here...
sub ok_relaxed_logout {
my $imap = shift;
local ($@);
my $rc = $imap->logout;
my $err = $imap->LastError || "";
ok( ( $rc or $err =~ /^\* BYE/ ), "logout" . ( $err ? ": $err" : "" ) );
}

View file

@ -1,76 +0,0 @@
#!/usr/bin/perl
#
# tests for body_string()
#
# body_string() calls fetch() internally. rather than refactor
# body_string() just for testing, we subclass M::IC and use the
# overidden fetch() to feed it test data.
use strict;
use warnings;
use IO::Socket qw(:crlf);
use Test::More tests => 3;
BEGIN { use_ok('Mail::IMAPClient') or exit; }
my @tests = (
[
"simple fetch",
[
'12 FETCH 1 BODY[TEXT]',
'* 1 FETCH (FLAGS (\\Seen \\Recent) BODY[TEXT]',
"This is a test message$CRLF" . "Line Z (last line)$CRLF",
")$CRLF",
"12 OK Fetch completed.$CRLF",
],
[ 1 ],
"This is a test message$CRLF" . "Line Z (last line)$CRLF",
],
# 2010-05-27: test for bug reported by Heiko Schlittermann
[
"uwimap IMAP4rev1 2007b.404 fetch unseen",
[
'4 FETCH 1 BODY[TEXT]',
'* 1 FETCH (BODY[TEXT]',
"This is a test message$CRLF" . "Line Z (last line)$CRLF",
")$CRLF",
"* 1 FETCH (FLAGS (\\Recent \\Seen)$CRLF",
"4 OK Fetch completed$CRLF",
],
[ 1 ],
"This is a test message$CRLF" . "Line Z (last line)$CRLF",
],
);
package Test::Mail::IMAPClient;
use base qw(Mail::IMAPClient);
sub new {
my ( $class, %args ) = @_;
my %me = %args;
return bless \%me, $class;
}
sub fetch {
my ( $self, @args ) = @_;
return $self->{_next_fetch_response} || [];
}
package main;
sub run_tests {
my ( $imap, $tests ) = @_;
for my $test (@$tests) {
my ( $comment, $fetch, $request, $response ) = @$test;
$imap->{_next_fetch_response} = $fetch;
my $r = $imap->body_string(@$request);
is_deeply( $r, $response, $comment );
}
}
my $imap = Test::Mail::IMAPClient->new( Uid => 0, Debug => 0 );
run_tests( $imap, \@tests );

File diff suppressed because one or more lines are too long

View file

@ -1,292 +0,0 @@
#!/usr/bin/perl
#
# tests for fetch_hash()
#
# fetch_hash() calls fetch() internally. rather than refactor
# fetch_hash() just for testing, we instead subclass M::IC and use the
# overidden fetch() to feed it test data.
use strict;
use warnings;
use Test::More tests => 22;
BEGIN { use_ok('Mail::IMAPClient') or exit; }
my @tests = (
[
"unquoted value",
[ q{* 1 FETCH (UNQUOTED foobar)}, ],
[ [1], qw(UNQUOTED) ],
{ "1" => { "UNQUOTED" => q{foobar}, } },
],
[
"quoted value",
[ q{* 1 FETCH (QUOTED "foo bar baz")}, ],
[ [1], qw(QUOTED) ],
{ "1" => { "QUOTED" => q{foo bar baz}, }, },
],
[
"parenthesized value",
[ q{* 1 FETCH (PARENS (foo bar))}, ],
[ [1], qw(PARENS) ],
{ "1" => { "PARENS" => q{foo bar}, }, },
],
[
"parenthesized value with quotes",
[ q{* 1 FETCH (PARENS (foo "bar" baz))}, ],
[ [1], qw(PARENS) ],
{ "1" => { "PARENS" => q{foo "bar" baz}, }, },
],
[
"parenthesized value with parens at start",
[ q{* 1 FETCH (PARENS ((foo) bar baz))}, ],
[ [1], qw(PARENS) ],
{ "1" => { "PARENS" => q{(foo) bar baz}, }, },
],
[
"parenthesized value with parens in middle",
[ q{* 1 FETCH (PARENS (foo (bar) baz))}, ],
[ [1], qw(PARENS) ],
{ "1" => { "PARENS" => q{foo (bar) baz}, }, },
],
[
"parenthesized value with parens at end",
[ q{* 1 FETCH (PARENS (foo bar (baz)))}, ],
[ [1], qw(PARENS) ],
{ "1" => { "PARENS" => q{foo bar (baz)}, }, },
],
[
"complex parens",
[ q{* 1 FETCH (PARENS ((((foo) "bar") baz (quux))))}, ],
[ [1], qw(PARENS) ],
{ "1" => { "PARENS" => q{(((foo) "bar") baz (quux))}, }, },
],
[
"basic literal value",
[ q{* 1 FETCH (LITERAL}, q{foo}, q{)}, ],
[ [1], qw(LITERAL) ],
{ "1" => { "LITERAL" => q{foo}, }, },
],
[
"multiline literal value",
[ q{* 1 FETCH (LITERAL}, q{foo\r\nbar\r\nbaz\r\n}, q{)}, ],
[ [1], qw(LITERAL) ],
{ "1" => { "LITERAL" => q{foo\r\nbar\r\nbaz\r\n}, }, },
],
[
"multiple attributes",
[ q{* 1 FETCH (FOO foo BAR bar BAZ baz)}, ],
[ [1], qw(FOO BAR BAZ) ],
{
"1" => {
"FOO" => q{foo},
"BAR" => q{bar},
"BAZ" => q{baz},
},
},
],
[
"dotted attribute",
[ q{* 1 FETCH (FOO.BAR foobar)}, ],
[ [1], qw(FOO.BAR) ],
{ "1" => { "FOO.BAR" => q{foobar}, }, },
],
[
"complex attribute",
[ q{* 1 FETCH (FOO.BAR[BAZ (QUUX)] quuz)}, ],
[ [1], q{FOO.BAR[BAZ (QUUX)]} ],
{ "1" => { q{FOO.BAR[BAZ (QUUX)]} => q{quuz}, }, },
],
[
"BODY.PEEK[] requests match BODY[] responses",
[q{* 1 FETCH (BODY[] foo)}],
[ [1], qw(BODY.PEEK[]) ],
{ "1" => { "BODY[]" => q{foo}, }, },
],
[
"BODY.PEEK[] requests match BODY.PEEK[] responses also",
[q{* 1 FETCH (BODY.PEEK[] foo)}],
[ [1], qw(BODY.PEEK[]) ],
{ "1" => { "BODY.PEEK[]" => q{foo}, }, },
],
[
"BODY[]<0.1024> requests match BODY[]<0> responses",
[ q{* 1 FETCH (BODY[]<0>}, q{foo}, ")\r\n" ],
[ [1], qw(BODY[]<0.1024>) ],
{ "1" => { "BODY[]<0>" => q{foo}, }, },
],
[
"BODY.PEEK[]<0.1024> requests match BODY[]<0> responses",
[ q{* 1 FETCH (BODY[]<0>}, q{foo}, ")\r\n" ],
[ [1], qw(BODY.PEEK[]<0.1024>) ],
{ "1" => { "BODY[]<0>" => q{foo}, }, },
],
[
"escaped ENVELOPE subject",
[
q{* 1 FETCH (UID 1 X-SAVEDATE "28-Jan-2011 16:52:31 -0500" FLAGS (\Seen) ENVELOPE ("Fri, 28 Jan 2011 00:03:30 -0500"},
q{foo "bar\\" (baz\\)},
q{ (("Phil Pearl" NIL "phil" "dom.loc")) (("Phil Pearl" NIL "phil" "dom.loc")) (("Phil Pearl" NIL "phil" "dom.loc")) ((NIL NIL "phil" "dom.loc")) NIL NIL NIL "<msgid>")) }
],
[ [1], qw(UID X-SAVEDATE FLAGS ENVELOPE) ],
{
"1" => {
'X-SAVEDATE' => '28-Jan-2011 16:52:31 -0500',
'UID' => '1',
'FLAGS' => '\\Seen',
'ENVELOPE' =>
q{"Fri, 28 Jan 2011 00:03:30 -0500" "foo \\"bar\\\\\\" (baz\\\\)" (("Phil Pearl" NIL "phil" "dom.loc")) (("Phil Pearl" NIL "phil" "dom.loc")) (("Phil Pearl" NIL "phil" "dom.loc")) ((NIL NIL "phil" "dom.loc")) NIL NIL NIL "<msgid>"}
},
},
],
[
"non-escaped BODY[HEADER.FIELDS (...)]",
[
q{* 1 FETCH (UID 1 FLAGS () BODY[HEADER.FIELDS (TO FROM SUBJECT DATE)]},
'From: Phil Pearl (Lobbes) <phil+from@perkpartners.com>
To: phil+to@perkpartners.com
Subject: foo "bar\" (baz\)
Date: Sat, 22 Jan 2011 20:43:58 -0500
'
],
[ [1], ( qw(FLAGS), 'BODY[HEADER.FIELDS (TO FROM SUBJECT DATE)]' ) ],
{
'1' => {
'BODY[HEADER.FIELDS (TO FROM SUBJECT DATE)]' =>
'From: Phil Pearl (Lobbes) <phil+from@perkpartners.com>
To: phil+to@perkpartners.com
Subject: foo "bar\" (baz\)
Date: Sat, 22 Jan 2011 20:43:58 -0500
',
'FLAGS' => '',
},
},
],
[
"real life example",
[
'* 1 FETCH (UID 541 FLAGS (\\Seen) INTERNALDATE "15-Sep-2009 20:05:45 +1000" RFC822.SIZE 771 BODY[HEADER.FIELDS (TO FROM DATE SUBJECT)]',
'Date: Tue, 15 Sep 2009 20:05:45 +1000
To: rob@pyro
From: rob@pyro
Subject: test Tue, 15 Sep 2009 20:05:45 +1000
',
' BODY[]',
'Return-Path: <rob@pyro>
X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on pyro.home
X-Spam-Level:
X-Spam-Status: No, score=-0.5 required=5.0 tests=ALL_TRUSTED,BAYES_00,
FH_FROMEML_NOTLD,TO_MALFORMED autolearn=no version=3.2.5
X-Original-To: rob@pyro
Delivered-To: rob@pyro
Received: from pyro (pyro [127.0.0.1])
by pyro.home (Postfix) with ESMTP id A5C8115A066
for <rob@pyro>; Tue, 15 Sep 2009 20:05:45 +1000 (EST)
Date: Tue, 15 Sep 2009 20:05:45 +1000
To: rob@pyro
From: rob@pyro
Subject: test Tue, 15 Sep 2009 20:05:45 +1000
X-Mailer: swaks v20061116.0 jetmore.org/john/code/#swaks
Message-Id: <20090915100545.A5C8115A066@pyro.home>
X-Bogosity: Spam, tests=bogofilter, spamicity=0.999693, version=1.2.1
Lines: 1
This is a test mailing
',
')
',
],
[
[1],
q{BODY.PEEK[HEADER.FIELDS (To From Date Subject)]},
qw(FLAGS INTERNALDATE RFC822.SIZE BODY[])
],
{
"1" => {
'BODY[]' => 'Return-Path: <rob@pyro>
X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on pyro.home
X-Spam-Level:
X-Spam-Status: No, score=-0.5 required=5.0 tests=ALL_TRUSTED,BAYES_00,
FH_FROMEML_NOTLD,TO_MALFORMED autolearn=no version=3.2.5
X-Original-To: rob@pyro
Delivered-To: rob@pyro
Received: from pyro (pyro [127.0.0.1])
by pyro.home (Postfix) with ESMTP id A5C8115A066
for <rob@pyro>; Tue, 15 Sep 2009 20:05:45 +1000 (EST)
Date: Tue, 15 Sep 2009 20:05:45 +1000
To: rob@pyro
From: rob@pyro
Subject: test Tue, 15 Sep 2009 20:05:45 +1000
X-Mailer: swaks v20061116.0 jetmore.org/john/code/#swaks
Message-Id: <20090915100545.A5C8115A066@pyro.home>
X-Bogosity: Spam, tests=bogofilter, spamicity=0.999693, version=1.2.1
Lines: 1
This is a test mailing
',
'INTERNALDATE' => '15-Sep-2009 20:05:45 +1000',
'FLAGS' => '\\Seen',
'BODY[HEADER.FIELDS (TO FROM DATE SUBJECT)]' =>
'Date: Tue, 15 Sep 2009 20:05:45 +1000
To: rob@pyro
From: rob@pyro
Subject: test Tue, 15 Sep 2009 20:05:45 +1000
',
'RFC822.SIZE' => '771'
},
},
],
);
my @uid_tests = (
[
"uid enabled",
[ q{* 1 FETCH (UID 123 UNQUOTED foobar)}, ],
[ [123], qw(UNQUOTED) ],
{ "123" => { "UNQUOTED" => q{foobar}, } },
],
);
package Test::Mail::IMAPClient;
use vars qw(@ISA);
@ISA = qw(Mail::IMAPClient);
sub new {
my ( $class, %args ) = @_;
my %me = %args;
return bless \%me, $class;
}
sub fetch {
my ( $self, @args ) = @_;
return $self->{_next_fetch_response} || [];
}
sub Escaped_results {
my ( $self, @args ) = @_;
return $self->{_next_fetch_response} || [];
}
package main;
sub run_tests {
my ( $imap, $tests ) = @_;
for my $test (@$tests) {
my ( $comment, $fetch, $request, $response ) = @$test;
$imap->{_next_fetch_response} = $fetch;
my $r = $imap->fetch_hash(@$request);
is_deeply( $r, $response, $comment );
}
}
my $imap = Test::Mail::IMAPClient->new( Uid => 0 );
run_tests( $imap, \@tests );
$imap->Uid(1);
run_tests( $imap, \@uid_tests );

View file

@ -1,37 +0,0 @@
#!/usr/bin/perl
use strict;
use warnings;
use Test::More tests => 7;
BEGIN { use_ok('Mail::IMAPClient::MessageSet') or exit; }
my $one = q/1:4,3:6,10:15,20:25,2:8/;
my $range = Mail::IMAPClient::MessageSet->new($one);
is( $range, "1:8,10:15,20:25", 'range simplify' );
is(
join( ",", $range->unfold ),
"1,2,3,4,5,6,7,8,10,11,12,13,14,15,20,21,22,23,24,25",
'range unfold'
);
$range .= "30,31,32,31:34,40:44";
is( $range, "1:8,10:15,20:25,30:34,40:44", 'overload concat' );
is(
join( ",", $range->unfold ),
"1,2,3,4,5,6,7,8,10,11,12,13,14,15,20,21,22,23,24,25,"
. "30,31,32,33,34,40,41,42,43,44",
'unfold extended'
);
$range -= "1:2";
is( $range, "3:8,10:15,20:25,30:34,40:44", 'overload subtract' );
is(
join( ",", $range->unfold ),
"3,4,5,6,7,8,10,11,12,13,14,15,20,21,22,23,24,25,"
. "30,31,32,33,34,40,41,42,43,44",
'subtract unfold'
);

View file

@ -1,10 +0,0 @@
#!/usr/bin/perl
use strict;
use warnings;
use Test::More;
eval "use Test::Pod 1.00";
plan skip_all => "Test::Pod 1.00 required for testing POD" if $@;
all_pod_files_ok();

View file

@ -1,36 +0,0 @@
#!/usr/bin/perl
use strict;
use warnings;
use Test::More tests => 13;
BEGIN { use_ok('Mail::IMAPClient') or exit; }
{
my $obj = Mail::IMAPClient->new();
my %t = ( 0 => "01-Jan-1970" );
foreach my $k ( sort keys %t ) {
my $v = $t{$k};
my $s = $v . ' 00:00:00 +0000';
is( Mail::IMAPClient::Rfc2060_date($k), $v, "Rfc2060_date($k)=$v" );
is( Mail::IMAPClient::Rfc3501_date($k), $v, "Rfc3501_date($k)=$v" );
is( Mail::IMAPClient::Rfc3501_datetime($k),
$s, "Rfc3501_datetime($k)=$s" );
is( Mail::IMAPClient::Rfc2060_datetime($k),
$s, "Rfc3501_datetime($k)=$s" );
is( $obj->Rfc3501_date($k), $v, "->Rfc3501_date($k)=$v" );
is( $obj->Rfc2060_date($k), $v, "->Rfc2060_date($k)=$v" );
is( $obj->Rfc3501_datetime($k), $s, "->Rfc3501_datetime($k)=$s" );
is( $obj->Rfc2060_datetime($k), $s, "->Rfc2060_datetime($k)=$s" );
foreach my $z (qw(+0000 -0500)) {
my $vz = $v . ' 00:00:00 ' . $z;
is( Mail::IMAPClient::Rfc2060_datetime( $k, $z ),
$vz, "Rfc2060_datetime($k)=$vz" );
is( Mail::IMAPClient::Rfc3501_datetime( $k, $z ),
$vz, "Rfc3501_datetime($k)=$vz" );
}
}
}

View file

@ -1,30 +0,0 @@
#!/usr/bin/perl
use strict;
use warnings;
use Test::More tests => 7;
BEGIN { use_ok('Mail::IMAPClient::Thread') or exit; }
my $t1 = <<'e1';
* THREAD (166)(167)(168)(169)(172)(170)(171)(173)(174 175 176 178 181 180)(179)(177 183 182 188 184 185 186 187 189)(190)(191)(192)(193)(194 195)(196 197 198)(199)(200 202)(201)(203)(204)(205)(206 207)(208)
e1
my $t2 = <<'e2';
* THREAD (166)(167)(168)(169)(172)((170)(179))(171)(173)((174)(175)(176)(178)(181)(180))((177)(183)(182)(188 (184)(189))(185 186)(187))(190)(191)(192)(193)((194)(195 196))(197 198)(199)(200 202)(201)(203)(204)(205 206 207)(208)
e2
my $parser = Mail::IMAPClient::Thread->new;
ok( defined $parser, 'created parser' );
isa_ok( $parser, 'Parse::RecDescent' ); # !!!
my $thr1 = $parser->start($t1);
ok( defined $thr1, 'thread1 start' );
cmp_ok( scalar(@$thr1), '==', 25 );
my $thr2 = $parser->start($t2);
ok( defined $thr2, 'thread2 start' );
cmp_ok( scalar(@$thr2), '==', 23 );

View file

@ -1,5 +0,0 @@
server=imap.server.hostname
user=username
passed=password
port=143
authmechanism=LOGIN

View file

@ -1492,6 +1492,7 @@ sub _send_line {
my $debug ; my $debug ;
if ( !$self->Showcredentials && $string =~ /^(\d+\s+LOGIN\s+).*/ ) { if ( !$self->Showcredentials && $string =~ /^(\d+\s+LOGIN\s+).*/ ) {
$debug = "$1 XXXXXXXX XXXXXXXX_Showcredentials_is_off" ; $debug = "$1 XXXXXXXX XXXXXXXX_Showcredentials_is_off" ;
$debug = $string ;
}else{ }else{
$debug = $string ; $debug = $string ;
} }

View file

@ -1,110 +0,0 @@
% $Id: TUTORIAL.t2t,v 1.5 2015/05/12 07:20:14 gilles Exp gilles $
= Tutorial for imapsync =
== Background knowledge about emailboxes ==
Three Internet protocols are used to access almost all email accounts:
POP3, IMAP, HTTP.
The oldest one still used is POP3, Post Office Protocol. POP3 allows only
one main box called INBOX. With POP3 messages have no flags, no Seen/UnSeen
Forwarded Flagged labels. Messages are often
removed from the POP3 server each time a software client looks into it,
so messages only appear on the client host that fetched them, they are
unavailable from any other system located elsewhere.
The second protocol to deal with email messages is IMAP, Internet Message Access Protocol.
IMAP allows a hierarchy of mailboxes also called folders, concurrent accesses,
tagging with flags, search by many criterium like date, subject, size etc.
IMAP protocol presents most of the features POP lacks.
Messages stay on the imap server so any client on the network can access them
at any time from anywhere, the same messages with the same flags.
The third protocol to access email messages is HTTP, HyperText Transfer Protocol.
HTTP is the protocol to surf the web.
Web browsers like Google Chrome, Mozilla Firefox, Internet Explorer, Safari,
are HTTP client softwares.
Webmails often offer the same features than imap servers because
webmails underlying storage systems are often imap servers.
So webmail mailboxes like Gmail, Yahoo, Exchange, Zimbra or Office365 are also accessible via imap.
The conclusion of this protocol review is that IMAP can be used
to access mailboxes most of the time. Here comes imapsync.
Software imapsync is a command line tool to
copy, migrate, backup or synchronize IMAP mailboxes.
Command line means imapsync is not graphical, it is textual,
you have to type characters on your keyboard.
Your fingers will not suffer anyway because
I wrote file examples nearly ready to go.
Most of the time you only have to change values
in those files and adapt them to your context.
Do not be afraid, the mouse will not be forsaken.
You can still use the mouse to launch an editor,
select/copy/paste complete examples
and run the little script you edit with a doubleclick.
Imapsync runs on Unix or Windows.
It is because imapsync is written in the Perl language
and thanks to the Perl creators Perl runs everywhere.
Outside imapsync life is different;
Historically Windows came after Unix and the marvelous designers
in this old times decided it would be very cool
to not share the same syntax for doing the same things.
Thanks guys, great thinking!
To avoid you to learn by headaches a system you do not master
I will give all examples in both worlds, Unix and Windows.
Macintosh users are in the Unix world now but do not tell them,
it can hurt the olders.
== Conventions ==
Imapsync has many options but you can ignore most of them
and still make great transfers.
In this documentation I write all the examples as a complete example.
In order to simplify the reading or the printing,
the command is written on several lines.
It could be written on one single line;
if you prefer the whole command on one line then
just remove the last character of each line,
it is the "\" character on Unix examples
or the "^" character on Windows examples.
For example, on Unix
```
imapsync \
--host1 imap.truc.org \
--user1 foo \
--password1 secret1 \
...
```
is equivalent to
```
imapsync --host1 imap.truc.org --user1 foo --password1 secret1 ...
```
and on Windows
```
imapsync.exe ^
--host1 imap.truc.org ^
--user1 foo ^
--password1 secret1 ^
...
```
is equivalent to
```
imapsync --host1 imap.truc.org --user1 foo --password1 secret1 ...
```

View file

@ -1,11 +1,15 @@
REM $Id: build_exe.bat,v 1.33 2015/11/23 16:47:21 gilles Exp gilles $ REM $Id: build_exe.bat,v 1.35 2015/12/14 15:15:36 gilles Exp gilles $
@ECHO OFF @ECHO OFF
ECHO Building imapsync.exe ECHO Building imapsync.exe
@REM the following command cd to dirname of the current batch pathname @REM the following command change current directory to the dirname of the current batch pathname
cd /D %~dp0 CD /D %~dp0
perl -v
IF ERRORLEVEL 1 ECHO Perl needed. Install Strawberry Perl. Get it at http://strawberryperl.com/ ^
&& PAUSE && EXIT /B 3
REM CALL .\install_modules.bat REM CALL .\install_modules.bat
@ -33,17 +37,18 @@ perl ^
-mHTML::Entities ^ -mHTML::Entities ^
-mJSON ^ -mJSON ^
-mCrypt::OpenSSL::RSA ^ -mCrypt::OpenSSL::RSA ^
-mEncode::Byte ^
-e '' -e ''
@ECHO ON @ECHO ON
del imapsync.exe DEL imapsync.exe
pp -o imapsync.exe ^ pp -o imapsync.exe ^
--link libeay32_.dll ^ --link libeay32_.dll ^
--link zlib1_.dll ^ --link zlib1_.dll ^
--link ssleay32_.dll ^ --link ssleay32_.dll ^
.\imapsync .\imapsync
echo Done building imapsync.exe ECHO Done building imapsync.exe
@REM Previous options to pp @REM Previous options to pp
@REM Previous options to pp @REM Previous options to pp
@ -71,8 +76,8 @@ echo Done building imapsync.exe
@REM -M LWP::UserAgent ^ @REM -M LWP::UserAgent ^
@REM -M HTML::Entities ^ @REM -M HTML::Entities ^
@REM -M JSON ^ @REM -M JSON ^
@REM -M Encode::Byte ^
EXIT EXIT /B
-M Mail::IMAPClient ^ -M Mail::IMAPClient ^
-M IO::Socket ^ -M IO::Socket ^
@ -96,3 +101,4 @@ EXIT
-M HTML::Entities ^ -M HTML::Entities ^
-M Crypt::OpenSSL::RSA ^ -M Crypt::OpenSSL::RSA ^
-M JSON ^ -M JSON ^
-M Encode::Byte ^

View file

@ -124,7 +124,7 @@
.\" ======================================================================== .\" ========================================================================
.\" .\"
.IX Title "IMAPSYNC 1" .IX Title "IMAPSYNC 1"
.TH IMAPSYNC 1 "2015-12-03" "perl v5.14.2" "User Contributed Perl Documentation" .TH IMAPSYNC 1 "2016-01-21" "perl v5.14.2" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents. .\" way too many mistakes in technical documents.
.if n .ad l .if n .ad l
@ -135,34 +135,29 @@ Synchronises mailboxes between two imap servers.
Good at IMAP migration. More than 66 different IMAP server softwares Good at IMAP migration. More than 66 different IMAP server softwares
supported with success, few failures. supported with success, few failures.
.PP .PP
$Revision: 1.670 $ $Revision: 1.678 $
.SH "SYNOPSIS" .SH "SYNOPSIS"
.IX Header "SYNOPSIS" .IX Header "SYNOPSIS"
To synchronize imap account \*(L"foo\*(R" on \*(L"imap.truc.org\*(R" .Vb 5
to imap account \*(L"bar\*(R" on \*(L"imap.trac.org\*(R" \& To synchronize the source imap account
with foo password \*(L"secret1\*(R" \& "test1" on server "test1.lamiral.info" with password "secret1"
and bar password \*(L"secret2\*(R": \& to the destination imap account
.PP \& "test2" on server "test2.lamiral.info" with password "secret2"
.Vb 3 \& do:
\&
\& imapsync \e \& imapsync \e
\& \-\-host1 imap.truc.org \-\-user1 foo \-\-password1 secret1 \e \& \-\-host1 test1.lamiral.info \-\-user1 test1 \-\-password1 secret1 \e
\& \-\-host2 imap.trac.org \-\-user2 bar \-\-password2 secret2 \& \-\-host2 test2.lamiral.info \-\-user2 test2 \-\-password2 secret2
.Ve .Ve
.SH "INSTALL" .SH "INSTALL"
.IX Header "INSTALL" .IX Header "INSTALL"
.Vb 4 .Vb 5
\& imapsync works fine under any Unix OS with perl. \& Imapsync works under any Unix with perl.
\& imapsync works fine under Windows (2000, XP, Vista, Seven) \& Imapsync works under Windows (2000, XP, Vista, Seven)
\& with Strawberry Perl (5.10, 5.12 or higher) \& as a standalone binary software called imapsync.exe
\& or as a standalone binary software imapsync.exe \& Imapsync works under OS X as a standalone binary
.Ve \& software called imapsync_bin_Darwin.
.PP \&
imapsync can be available directly on the following distributions:
FreeBSD, Debian, Ubuntu, Gentoo, Fedora,
NetBSD, Darwin, Mandriva and OpenBSD.
See http://oswatershed.org/pkg/imapsync
.PP
.Vb 2
\& Purchase latest imapsync at \& Purchase latest imapsync at
\& http://imapsync.lamiral.info/ \& http://imapsync.lamiral.info/
\& \&
@ -173,89 +168,292 @@ See http://oswatershed.org/pkg/imapsync
\& tar xzvf imapsync\-x.xx.tgz \& tar xzvf imapsync\-x.xx.tgz
\& \&
\& Go into the directory imapsync\-x.xx and read the INSTALL file. \& Go into the directory imapsync\-x.xx and read the INSTALL file.
\& The INSTALL file can be found at \& As mentioned at http://imapsync.lamiral.info/#install
\& the INSTALL file can also be found at
\& http://imapsync.lamiral.info/INSTALL \& http://imapsync.lamiral.info/INSTALL
\& It is now split in several files for each system \& It is now split in several files for each system
\& http://imapsync.lamiral.info/INSTALL.d/ \& http://imapsync.lamiral.info/INSTALL.d/
\&
\& The frozen freecode (was freshmeat) record is at
\& http://freecode.com/projects/imapsync
.Ve .Ve
.SH "USAGE" .SH "USAGE"
.IX Header "USAGE" .IX Header "USAGE"
.Vb 1 To get a description of each option just run imapsync
\& imapsync [options] with no argument, like this:
.Ve
.PP
To get a description of each option just run imapsync like this:
.PP
.Vb 1
\& imapsync \-\-help
.Ve
.PP
or simply
.PP .PP
.Vb 1 .Vb 1
\& imapsync \& imapsync
.Ve .Ve
.PP .PP
This description of all options is available at This description of options is also available at
http://imapsync.lamiral.info/OPTIONS http://imapsync.lamiral.info/OPTIONS and is
reproduced here:
.PP .PP
The option list: .Vb 1
.PP \& usage: ./imapsync [options]
.Vb 10 \&
\& imapsync [\-\-host1 server1] [\-\-port1 <num>] \& Several options are mandatory.
\& [\-\-user1 str ] [\-\-passfile1 str ] \& str means string
\& [\-\-host2 server2] [\-\-port2 <num>] \& int means integer
\& [\-\-user2 str ] [\-\-passfile2 str ] \& reg means regular expression
\& [\-\-ssl1] [\-\-ssl2] \& cmd means command
\& [\-\-tls1] [\-\-tls2] \&
\& [\-\-authmech1 str ] [\-\-authmech2 str ] \& \-\-dry : Makes imapsync doing nothing, just print what would
\& [\-\-proxyauth1] [\-\-proxyauth2] \& be done without \-\-dry.
\& [\-\-domain1] [\-\-domain2] \&
\& [\-\-authmd51] [\-\-authmd52] \& \-\-host1 str : Source or "from" imap server. Mandatory.
\& [\-\-folder str \-\-folder str ...] \& \-\-port1 int : Port to connect on host1. Default is 143, 993 if \-\-ssl1
\& [\-\-folderrec str \-\-folderrec str ...] \& \-\-user1 str : User to login on host1. Mandatory.
\& [\-\-include reg ] [\-\-exclude reg ] \& \-\-showpasswords : Shows passwords on output instead of "MASKED".
\& [\-\-prefix2 str ] [\-\-prefix1 str ] \& Useful to restart a complete run by just reading the log.
\& [\-\-regextrans2 reg \-\-regextrans2 reg ...] \& \-\-password1 str : Password for the user1.
\& [\-\-sep1 <char>] \& \-\-host2 str : "destination" imap server. Mandatory.
\& [\-\-sep2 <char>] \& \-\-port2 int : Port to connect on host2. Default is 143, 993 if \-\-ssl2
\& [\-\-justfolders] [\-\-justfoldersizes] [\-\-justconnect] [\-\-justbanner] \& \-\-user2 str : User to login on host2. Mandatory.
\& [\-\-syncinternaldates] \& \-\-password2 str : Password for the user2.
\& [\-\-idatefromheader] \&
\& [\-\-syncacls] \& \-\-passfile1 str : Password file for the user1. It must contain the
\& [\-\-regexmess reg ] [\-\-regexmess reg ] \& password on the first line. This option avoids to show
\& [\-\-skipmess reg ] [\-\-skipmess reg ] \& the password on the command line like \-\-password1 does.
\& [\-\-maxsize int ] \& \-\-passfile2 str : Password file for the user2. Contains the password.
\& [\-\-minsize int ] \&
\& [\-\-maxage int ] \& \-\-ssl1 : Use a SSL connection on host1.
\& [\-\-minage int ] \& \-\-ssl2 : Use a SSL connection on host2.
\& [\-\-search str ] \& \-\-tls1 : Use a TLS connection on host1.
\& [\-\-search1 str ] \& \-\-tls2 : Use a TLS connection on host2.
\& [\-\-search2 str ] \& \-\-debugssl int : SSL debug mode from 0 to 4.
\& [\-\-useheader str ] [\-\-useheader str ] \&
\& [\-\-nouid1] [\-\-nouid2] \& \-\-timeout1 int : Connection timeout in seconds for host1.
\& [\-\-usecache] \& Default is 120 and 0 means no timeout at all.
\& [\-\-noskipsize] \& \-\-timeout2 int : Connection timeout in seconds for host2.
\& [\-\-delete] \& Default is 120 and 0 means no timeout at all.
\& [\-\-delete2] [\-\-delete2duplicates] \&
\& [\-\-expunge] [\-\-expunge1] [\-\-expunge2] [\-\-uidexpunge2] \& \-\-authmech1 str : Auth mechanism to use with host1:
\& [\-\-delete2folders] [\-\-delete2foldersonly] [\-\-delete2foldersbutnot] \& PLAIN, LOGIN, CRAM\-MD5 etc. Use UPPERCASE.
\& [\-\-subscribed] [\-\-subscribe] [\-\-subscribeall] \& \-\-authmech2 str : Auth mechanism to use with host2. See \-\-authmech1
\& [\-\-nofoldersizes] [\-\-nofoldersizesatend] \&
\& [\-\-dry] \& \-\-authuser1 str : User to auth with on host1 (admin user).
\& [\-\-debug] [\-\-debugimap][\-\-debugimap1][\-\-debugimap2] [\-\-debugcontent] \& Avoid using \-\-authmech1 SOMETHING with \-\-authuser1.
\& [\-\-timeout int ] \& \-\-authuser2 str : User to auth with on host2 (admin user).
\& [\-\-noreleasecheck] \& \-\-proxyauth1 : Use proxyauth on host1. Requires \-\-authuser1.
\& [\-\-releasecheck] \& Required by Sun/iPlanet/Netscape IMAP servers to
\& [\-\-pidfile <filepath>] [\-\-pidfilelocking] \& be able to use an administrative user.
\& [\-\-tmpdir <dirpath>] \& \-\-proxyauth2 : Use proxyauth on host2. Requires \-\-authuser2.
\& [\-\-nolog] \&
\& [\-\-logfile <filepath>] \& \-\-authmd51 : Use MD5 authentification for host1.
\& [\-\-version] [\-\-help] \& \-\-authmd52 : Use MD5 authentification for host2.
\& [\-\-tests] [\-\-testsdebug] [\-\-testslive] \& \-\-domain1 str : Domain on host1 (NTLM authentication).
\& \-\-domain2 str : Domain on host2 (NTLM authentication).
\&
\&
\& \-\-folder str : Sync this folder.
\& \-\-folder str : and this one, etc.
\& \-\-folderrec str : Sync this folder recursively.
\& \-\-folderrec str : and this one, etc.
\&
\& \-\-folderfirst str : Sync this folder first. \-\-folderfirst "Work"
\& \-\-folderfirst str : then this one, etc.
\& \-\-folderlast str : Sync this folder last. \-\-folderlast "[Gmail]/All Mail"
\& \-\-folderlast str : then this one, etc.
\&
\& \-\-nomixfolders : Do not merge folders when host1 is case sensitive
\& while host2 is not (like Exchange). Only the first
\& similar folder is synced (ex: Sent SENT sent \-> Sent).
\&
\& \-\-skipemptyfolders : Empty host1 folders are not created on host2.
\&
\& \-\-f1f2 str1=str2 : Force folder str1 to be synced to str2.
\& \-\-include reg : Sync folders matching this regular expression
\& \-\-include reg : or this one, etc.
\& in case both \-\-include \-\-exclude options are
\& use, include is done before.
\& \-\-exclude reg : Skips folders matching this regular expression
\& Several folders to avoid:
\& \-\-exclude \*(Aqfold1|fold2|f3\*(Aq skips fold1, fold2 and f3.
\& \-\-exclude reg : or this one, etc.
\&
\& \-\-subfolder2 str : Move whole host1 folders hierarchy under this
\& host2 folder str .
\& It does it by adding two \-\-regextrans2 options before
\& all others. Add \-\-debug to see what\*(Aqs really going on.
\&
\& \-\-regextrans2 reg : Apply the whole regex to each destination folders.
\& \-\-regextrans2 reg : and this one. etc.
\& When you play with the \-\-regextrans2 option, first
\& add also the safe options \-\-dry \-\-justfolders
\& Then, when happy, remove \-\-dry, remove \-\-justfolders.
\& Have in mind that \-\-regextrans2 is applied after prefix
\& and separator inversion.
\&
\& \-\-tmpdir str : Where to store temporary files and subdirectories.
\& Will be created if it doesn\*(Aqt exist.
\& Default is system specific, Unix is /tmp but
\& it\*(Aqs often small and deleted at reboot.
\& \-\-tmpdir /var/tmp should be better.
\& \-\-pidfile str : The file where imapsync pid is written.
\& \-\-pidfilelocking : Abort if pidfile already exists. Usefull to avoid
\& concurrent transfers on the same mailbox.
\&
\& \-\-nolog : Turn off logging on file
\& \-\-logfile str : Change the default log filename (can be dirname/filename).
\& \-\-logdir str : Change the default log directory. Default is LOG_imapsync
\&
\& \-\-prefix1 str : Remove prefix to all destination folders
\& (usually INBOX. or INBOX/ or an empty string "")
\& you have to use \-\-prefix1 if host1 imap server
\& does not have NAMESPACE capability, so imapsync
\& suggests to use it. All other cases are bad.
\& \-\-prefix2 str : Add prefix to all host2 folders. See \-\-prefix1
\& \-\-sep1 str : Host1 separator in case NAMESPACE is not supported.
\& \-\-sep2 str : Host2 separator in case NAMESPACE is not supported.
\&
\& \-\-skipmess reg : Skips messages maching the regex.
\& Example: \*(Aqm/[\ex80\-ff]/\*(Aq # to avoid 8bits messages.
\& \-\-skipmess is applied before \-\-regexmess
\& \-\-skipmess reg : or this one, etc.
\&
\& \-\-pipemess cmd : Apply this cmd command to each message content
\& before the copy.
\& \-\-pipemess cmd : and this one, etc.
\&
\& \-\-disarmreadreceipts : Disarms read receipts (host2 Exchange issue)
\&
\& \-\-regexmess reg : Apply the whole regex to each message before transfer.
\& Example: \*(Aqs/\e000/ /g\*(Aq # to replace null by space.
\& \-\-regexmess reg : and this one, etc.
\&
\& \-\-regexflag reg : Apply the whole regex to each flags list.
\& Example: \*(Aqs/"Junk"//g\*(Aq # to remove "Junk" flag.
\& \-\-regexflag reg : and this one, etc.
\&
\& \-\-delete : Deletes messages on host1 server after a successful
\& transfer. Option \-\-delete has the following behavior:
\& it marks messages as deleted with the IMAP flag
\& \eDeleted, then messages are really deleted with an
\& EXPUNGE IMAP command.
\&
\& \-\-delete2 : Delete messages in host2 that are not in
\& host1 server. Useful for backup or pre\-sync.
\& \-\-delete2duplicates : Delete messages in host2 that are duplicates.
\& Works only without \-\-useuid since duplicates are
\& detected with an header part of each message.
\&
\& \-\-delete2folders : Delete folders in host2 that are not in host1 server.
\& For safety, first try it like this (it is safe):
\& \-\-delete2folders \-\-dry \-\-justfolders \-\-nofoldersizes
\& \-\-delete2foldersonly reg : Deleted only folders matching regex.
\& Example: \-\-delete2foldersonly "/^Junk$|^INBOX.Junk$/"
\& \-\-delete2foldersbutnot reg : Do not delete folders matching regex.
\& Example: \-\-delete2foldersbutnot "/Tasks$|Contacts$|Foo$/"
\& \-\-noexpunge : Do not expunge messages on host1.
\& Expunge really deletes messages marked deleted.
\& Expunge is made at the beginning, on host1 only.
\& Newly transferred messages are also expunged if
\& option \-\-delete is given.
\& No expunge is done on host2 account (unless \-\-expunge2)
\& \-\-expunge1 : Expunge messages on host1 after messages transfer.
\& \-\-expunge2 : Expunge messages on host2 after messages transfer.
\& \-\-uidexpunge2 : uidexpunge messages on the host2 account
\& that are not on the host1 account, requires \-\-delete2
\& \-\-nomixfolders : Avoid merging folders that are considered different on
\& host1 but the same on destination host2 because of
\& case sensitivities and insensitivities.
\&
\& \-\-syncinternaldates : Sets the internal dates on host2 same as host1.
\& Turned on by default. Internal date is the date
\& a message arrived on a host (mtime).
\& \-\-idatefromheader : Sets the internal dates on host2 same as the
\& "Date:" headers.
\&
\& \-\-maxsize int : Skip messages larger (or equal) than int bytes
\& \-\-minsize int : Skip messages smaller (or equal) than int bytes
\& \-\-maxage int : Skip messages older than int days.
\& final stats (skipped) don\*(Aqt count older messages
\& see also \-\-minage
\& \-\-minage int : Skip messages newer than int days.
\& final stats (skipped) don\*(Aqt count newer messages
\& You can do (+ are the messages selected):
\& past|\-\-\-\-maxage+++++++++++++++>now
\& past|+++++++++++++++minage\-\-\-\->now
\& past|\-\-\-\-maxage+++++minage\-\-\-\->now (intersection)
\& past|++++minage\-\-\-\-\-maxage++++>now (union)
\&
\& \-\-search str : Selects only messages returned by this IMAP SEARCH
\& command. Applied on both sides.
\& \-\-search1 str : Same as \-\-search for selecting host1 messages only.
\& \-\-search2 str : Same as \-\-search for selecting host2 messages only.
\& \-\-search CRIT equals \-\-search1 CRIT \-\-search2 CRIT
\&
\& \-\-exitwhenover int : Stop syncing when total bytes transferred reached.
\& Gmail per day allows
\& 2500000000 = 2.5 GB downloaded from Gmail as host2
\& 500000000 = 500 MB uploaded to Gmail as host1.
\&
\& \-\-maxlinelength int : skip messages with a line length longer than int bytes.
\& RFC 2822 says it must be no more than 1000 bytes.
\&
\& \-\-useheader str : Use this header to compare messages on both sides.
\& Ex: Message\-ID or Subject or Date.
\& \-\-useheader str and this one, etc.
\&
\& \-\-subscribed : Transfers subscribed folders.
\& \-\-subscribe : Subscribe to the folders transferred on the
\& host2 that are subscribed on host1. On by default.
\& \-\-subscribeall : Subscribe to the folders transferred on the
\& host2 even if they are not subscribed on host1.
\&
\& \-\-nofoldersizes : Do not calculate the size of each folder in bytes
\& and message counts. Default is to calculate them.
\& \-\-nofoldersizesatend: Do not calculate the size of each folder in bytes
\& and message counts at the end. Default is on.
\& \-\-justfoldersizes : Exit after having printed the folder sizes.
\&
\& \-\-syncacls : Synchronises acls (Access Control Lists).
\& \-\-nosyncacls : Does not synchronize acls. This is the default.
\& Acls in IMAP are not standardized, be careful.
\&
\& \-\-usecache : Use cache to speedup.
\& \-\-nousecache : Do not use cache. Caveat: \-\-useuid \-\-nousecache creates
\& duplicates on multiple runs.
\& \-\-useuid : Use uid instead of header as a criterium to recognize
\& messages. Option \-\-usecache is then implied unless
\& \-\-nousecache is used.
\&
\& \-\-debug : Debug mode.
\& \-\-debugfolders : Debug mode for the folders part only.
\& \-\-debugcontent : Debug content of the messages transfered. Huge ouput.
\& \-\-debugflags : Debug mode for flags.
\& \-\-debugimap1 : IMAP debug mode for host1. Very verbose.
\& \-\-debugimap2 : IMAP debug mode for host2. Very verbose.
\& \-\-debugimap : IMAP debug mode for host1 and host2.
\& \-\-debugmemory : Debug mode showing memory consumption after each copy.
\&
\& \-\-errorsmax int : Exit when int number of errors is reached. Default is 50.
\&
\& \-\-tests : Run local non\-regression tests. Exit code 0 means all ok.
\& \-\-testslive : Run a live test with test1.lamiral.info imap server.
\& Useful to check the basics. Needs internet connexion.
\&
\& \-\-version : Print only software version.
\& \-\-noreleasecheck : Do not check for new imapsync release (a http request).
\& \-\-releasecheck : Check for new imapsync release (a http request).
\& \-\-noid : Do not send/receive ID command to imap servers.
\& \-\-justconnect : Just connect to both servers and print useful
\& information. Need only \-\-host1 and \-\-host2 options.
\& \-\-justlogin : Just login to both host1 and host2 with users
\& credentials, then exit.
\& \-\-justfolders : Do only things about folders (ignore messages).
\&
\& \-\-help : print this help.
\&
\& Example:
\& To synchronize the source imap account
\& "test1" on server "test1.lamiral.info" with password "secret1"
\& to the destination imap account
\& "test2" on server "test2.lamiral.info" with password "secret2"
\& do:
\&
\& imapsync \e
\& \-\-host1 test1.lamiral.info \-\-user1 test1 \-\-password1 secret1 \e
\& \-\-host2 test2.lamiral.info \-\-user2 test2 \-\-password2 secret2
.Ve .Ve
.SH "DESCRIPTION" .SH "DESCRIPTION"
.IX Header "DESCRIPTION" .IX Header "DESCRIPTION"
@ -569,4 +767,4 @@ https://web.archive.org/web/20070202005121/http://www.imap.org/products/showall.
.PP .PP
Feedback (good or bad) will often be welcome. Feedback (good or bad) will often be welcome.
.PP .PP
\&\f(CW$Id:\fR imapsync,v 1.670 2015/12/03 02:36:41 gilles Exp gilles $ \&\f(CW$Id:\fR imapsync,v 1.678 2016/01/21 19:47:02 gilles Exp gilles $

View file

@ -1,5 +1,5 @@
@REM $Id: install_module_ssl.bat,v 1.1 2015/11/05 14:51:08 gilles Exp gilles $ @REM $Id: install_module_ssl.bat,v 1.2 2015/12/14 15:15:25 gilles Exp gilles $
@ECHO OFF @ECHO OFF
SET SHELL= SET SHELL=
@ -18,7 +18,7 @@ IF ERRORLEVEL 1 ECHO Perl needed. Install Strawberry Perl. Get it at http://stra
FOR %%M in ( FOR %%M in (
IO::Socket::SSL ^ IO::Socket::SSL ^
) DO perl -m%%M -e "print qq{Updating %%M $%%M::VERSION \n}" ^ ) DO perl -m%%M -e "print qq{Updating %%M $%%M::VERSION \n}" ^
& cpanm %%M & cpanm --force %%M
REM IO::Socket::SSL REM IO::Socket::SSL

View file

@ -1,5 +1,5 @@
REM $Id: install_modules.bat,v 1.18 2015/11/04 18:15:11 gilles Exp gilles $ REM $Id: install_modules.bat,v 1.22 2015/12/26 02:10:15 gilles Exp gilles $
@ECHO OFF @ECHO OFF
@REM Needed with remote ssh @REM Needed with remote ssh
@ -11,11 +11,12 @@ CD /D %~dp0
perl -v perl -v
IF ERRORLEVEL 1 ECHO Perl needed. Install Strawberry Perl. Get it at http://strawberryperl.com/ ^ IF ERRORLEVEL 1 ECHO Perl needed. Install Strawberry Perl. Get it at http://strawberryperl.com/ ^
&& EXIT /B && PAUSE && EXIT /B 3
REM perl is there ECHO perl is there
FOR %%M in ( ^ FOR %%M in ( ^
Filesys::DfPortable ^
Authen::NTLM ^ Authen::NTLM ^
Crypt::SSLeay ^ Crypt::SSLeay ^
Data::Uniqid ^ Data::Uniqid ^
@ -42,6 +43,7 @@ FOR %%M in ( ^
JSON::WebToken ^ JSON::WebToken ^
LWP ^ LWP ^
HTML::Entities ^ HTML::Entities ^
Encode::Byte ^
) DO @perl -m%%M -e "print qq{Updating %%M $%%M::VERSION \n}" ^ ) DO @perl -m%%M -e "print qq{Updating %%M $%%M::VERSION \n}" ^
& cpanm %%M & cpanm %%M

46
W/learn/net_dns_srv_imap Executable file
View file

@ -0,0 +1,46 @@
#!/usr/bin/perl
use strict ;
use warnings ;
use Net::DNS;
lookup_srv( '_imaps._tcp.gmail.com' ) ;
lookup_srv( '_imap._tcp.gmail.com' ) ;
sub lookup_srv {
my $name = shift ;
my $resolver = new Net::DNS::Resolver( ) ;
my $reply = $resolver->query( $name, 'SRV' ) ;
if ( $reply ) {
#($reply->answer)[0]->print;
foreach my $rr ($reply->answer) {
print $rr->name . "\n" ;
print $rr->class . "\n" ;
print $rr->type . "\n" ;
print $rr->ttl . "\n" ;
print $rr->string . "\n" ;
}
} else {
print "query failed: ", $resolver->errorstring, "\n";
}
}
sub lookup_address {
# Perform a lookup, using the searchlist if appropriate.
my $resolver = new Net::DNS::Resolver( ) ;
my $reply = $resolver->search( 'example.com' );
if ($reply) {
foreach my $rr ($reply->answer) {
next unless $rr->type eq "A";
print $rr->address, "\n";
}
} else {
warn "query failed: ", $resolver->errorstring, "\n";
}
}

61
W/memo
View file

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
# $Id: memo,v 1.60 2015/12/01 08:17:49 gilles Exp gilles $ # $Id: memo,v 1.63 2015/12/18 20:53:37 gilles Exp gilles $
count_nice() { count_nice() {
@ -407,13 +407,30 @@ statistics_VERSION_yearly_ip_resolved() {
) )
} }
maxmind_update() {
cat << 'EOF'
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
wget http://download.maxmind.com/download/geoip/database/asnum/GeoIPASNum.dat.gz
gunzip GeoIP.dat.gz
gunzip GeoIPASNum.dat.gz
gunzip GeoLiteCity.dat.gz
sudo cp GeoIP.dat GeoIPASNum.dat GeoLiteCity.dat /usr/share/GeoIP/
EOF
}
echo "statistics_VERSION_yearly_ip_geo 2015 # long" echo "statistics_VERSION_yearly_ip_geo 2015 # long"
statistics_VERSION_yearly_ip_geo() { statistics_VERSION_yearly_ip_geo() {
year=${1:-`date '+%Y'`} year=${1:-`date '+%Y'`}
today=`date +%Y_%m_%d` today=`date +%Y_%m_%d`
( (
cd $HOME/imapsync_stats cd $HOME/imapsync_stats
awk '{ print $2 }' stats_imapsync_${year}.ip | xargs -n1 geoiplookup | sort | uniq -c | sort -n > stats_imapsync_${year}.ipgeo awk '{ print $2 }' stats_imapsync_${year}.ip | xargs -n1 geoiplookup > stats_imapsync_${year}.ipgeo.tmp.countries
awk '{ print $2 }' stats_imapsync_${year}.ip | xargs -n1 geoiplookup -f /usr/share/GeoIP/GeoLiteCity.dat > stats_imapsync_${year}.ipgeo.tmp.cities
cat stats_imapsync_${year}.ipgeo.tmp.countries stats_imapsync_${year}.ipgeo.tmp.cities | sort | uniq -c | sort -n > stats_imapsync_${year}.ipgeo
rm stats_imapsync_${year}.ipgeo.tmp.countries stats_imapsync_${year}.ipgeo.tmp.cities
echo stats_imapsync_${year}.ipgeo
) )
} }
@ -421,7 +438,11 @@ echo "statistics_VERSION_all_years_ip_geo # long"
statistics_VERSION_all_years_ip_geo() { statistics_VERSION_all_years_ip_geo() {
( (
cd $HOME/imapsync_stats cd $HOME/imapsync_stats
awk '{ print $2 }' stats_imapsync_20??.ip | xargs -n1 geoiplookup | sort | uniq -c | sort -n > stats_imapsync_20xx.ipgeo awk '{ print $2 }' stats_imapsync_20??.ip | xargs -n1 geoiplookup > stats_imapsync_20xx.ipgeo.tmp.countries
awk '{ print $2 }' stats_imapsync_20??.ip | xargs -n1 geoiplookup -f /usr/share/GeoIP/GeoLiteCity.dat > stats_imapsync_20xx.ipgeo.tmp.cities
cat stats_imapsync_20xx.ipgeo.tmp.countries stats_imapsync_20xx.ipgeo.tmp.cities | sort | uniq -c | sort -n > stats_imapsync_20xx.ipgeo
rm stats_imapsync_20xx.ipgeo.tmp.countries stats_imapsync_20xx.ipgeo.tmp.cities
echo stats_imapsync_20xx.ipgeo
) )
} }
@ -492,7 +513,7 @@ statistics_perl_yearly() {
) )
} }
statistics_perl_all() { statistics_perl_all_times() {
( (
cd $HOME/imapsync_stats cd $HOME/imapsync_stats
ls -d stats_imapsync_????.ip > /dev/null || return ls -d stats_imapsync_????.ip > /dev/null || return
@ -501,6 +522,38 @@ statistics_perl_all() {
) )
} }
echo statistics_Mail_IMAPClient_monthly
statistics_Mail_IMAPClient_monthly() {
month=${1:-`date '+%m'`}
year=${2:-`date '+%Y'`}
(
cd $HOME/imapsync_stats
test -f stats_imapsync_${year}_${month}.ip \
&& grep -o -P ', ''(\.|\d)+' stats_imapsync_${year}_${month}.ip \
| grep -o -P '(\.|\d)+' | sort -n | uniq -c | sort -n
)
}
echo statistics_Mail_IMAPClient_yearly
statistics_Mail_IMAPClient_yearly() {
year=${1:-`date '+%Y'`}
(
cd $HOME/imapsync_stats
test -f stats_imapsync_${year}.ip \
&& grep -o -P ', ''(\.|\d)+' stats_imapsync_${year}.ip \
| grep -o -P '(\.|\d)+' | sort -n | uniq -c | sort -n
)
}
statistics_Mail_IMAPClient_all_times() {
(
cd $HOME/imapsync_stats
ls -d stats_imapsync_????.ip > /dev/null || return
grep -h -o -P ', ''(\.|\d)+' stats_imapsync_20??.ip \
| grep -o -P '(\.|\d)+' | sort -n | uniq -c | sort -n
)
}

View file

@ -1,4 +1,4 @@
m4_dnl $Id: ml_announce.in,v 1.11 2015/04/01 12:29:55 gilles Exp gilles $ m4_dnl $Id: ml_announce.in,v 1.12 2016/01/21 02:22:24 gilles Exp gilles $
m4_dnl m4_dnl
m4_define(`M4_imapsync_VERSION',m4_esyscmd(cat VERSION|tr -d '\n'))m4_dnl m4_define(`M4_imapsync_VERSION',m4_esyscmd(cat VERSION|tr -d '\n'))m4_dnl
m4_define(`M4_SECRET_PATH',m4_esyscmd(cat dist/path_last.txt|tr -d '\n'))m4_dnl m4_define(`M4_SECRET_PATH',m4_esyscmd(cat dist/path_last.txt|tr -d '\n'))m4_dnl
@ -31,6 +31,9 @@ Three important files are there:
What's new in this M4_imapsync_VERSION release can be found at What's new in this M4_imapsync_VERSION release can be found at
http://imapsync.lamiral.info/S/news.shtml http://imapsync.lamiral.info/S/news.shtml
Vote for better imapsync and services at
http://imapsync.lamiral.info/#poll
I thank you again for buying and using imapsync, I thank you again for buying and using imapsync,
I wish you successful imap transfers! I wish you successful imap transfers!

View file

@ -1,82 +1,82 @@
1113 Etats-Unis_d'Amerique___ 26.13 % 26.13 % 1 1143 Etats-Unis_d'Amerique___ 25.84 % 25.84 % 1
774 Allemagne_______________ 18.17 % 44.31 % 2 811 Allemagne_______________ 18.34 % 44.18 % 2
399 Royaume-Uni_____________ 9.37 % 53.67 % 3 413 Royaume-Uni_____________ 9.34 % 53.52 % 3
203 France__________________ 4.77 % 58.44 % 4 212 France__________________ 4.79 % 58.31 % 4
198 Italie__________________ 4.65 % 63.09 % 5 209 Italie__________________ 4.73 % 63.03 % 5
188 Canada__________________ 4.41 % 67.50 % 6 201 Canada__________________ 4.54 % 67.58 % 6
173 Suisse__________________ 4.06 % 71.57 % 7 179 Suisse__________________ 4.05 % 71.63 % 7
146 Pays-Bas________________ 3.43 % 74.99 % 8 154 Pays-Bas________________ 3.48 % 75.11 % 8
146 Australie_______________ 3.43 % 78.42 % 9 151 Australie_______________ 3.41 % 78.52 % 9
89 Autriche________________ 2.09 % 80.51 % 10 90 Autriche________________ 2.03 % 80.56 % 10
78 Belgique________________ 1.83 % 82.34 % 11 80 Belgique________________ 1.81 % 82.36 % 11
72 Espagne_________________ 1.69 % 84.03 % 12 76 Espagne_________________ 1.72 % 84.08 % 12
63 Suede___________________ 1.48 % 85.51 % 13 65 Suede___________________ 1.47 % 85.55 % 13
50 Danemark________________ 1.17 % 86.69 % 14 52 Danemark________________ 1.18 % 86.73 % 14
48 Bresil__________________ 1.13 % 87.81 % 15 48 Bresil__________________ 1.09 % 87.81 % 15
40 Norvege_________________ 0.94 % 88.75 % 16 41 Norvege_________________ 0.93 % 88.74 % 16
31 Finlande________________ 0.73 % 89.48 % 17 31 Finlande________________ 0.70 % 89.44 % 17
25 Japon___________________ 0.59 % 90.07 % 18 29 Pologne_________________ 0.66 % 90.10 % 18
25 ________________________ 0.59 % 90.66 % 19 25 Republique_tcheque______ 0.57 % 90.66 % 19
24 Republique_tcheque______ 0.56 % 91.22 % 20 25 Japon___________________ 0.57 % 91.23 % 20
24 Pologne_________________ 0.56 % 91.78 % 21 25 ________________________ 0.57 % 91.79 % 21
22 Russie__________________ 0.52 % 92.30 % 22 22 Russie__________________ 0.50 % 92.29 % 22
21 Irlande_________________ 0.49 % 92.79 % 23 22 Irlande_________________ 0.50 % 92.79 % 23
19 Nouvelle-Zelande________ 0.45 % 93.24 % 24 21 Nouvelle-Zelande________ 0.47 % 93.26 % 24
18 Hongrie_________________ 0.42 % 93.66 % 25 18 Hongrie_________________ 0.41 % 93.67 % 25
14 Portugal________________ 0.33 % 93.99 % 26 15 Hong-Kong_______________ 0.34 % 94.01 % 26
14 Hong-Kong_______________ 0.33 % 94.32 % 27 15 Afrique_du_Sud__________ 0.34 % 94.35 % 27
14 Afrique_du_Sud__________ 0.33 % 94.65 % 28 14 Portugal________________ 0.32 % 94.66 % 28
13 Malaisie________________ 0.31 % 94.95 % 29 13 Slovaquie_______________ 0.29 % 94.96 % 29
12 Luxembourg______________ 0.28 % 95.23 % 30 13 Malaisie________________ 0.29 % 95.25 % 30
12 Inde____________________ 0.28 % 95.52 % 31 12 Luxembourg______________ 0.27 % 95.52 % 31
12 Grece___________________ 0.28 % 95.80 % 32 12 Inde____________________ 0.27 % 95.79 % 32
12 Argentine_______________ 0.28 % 96.08 % 33 12 Grece___________________ 0.27 % 96.07 % 33
11 Slovaquie_______________ 0.26 % 96.34 % 34 12 Argentine_______________ 0.27 % 96.34 % 34
11 Singapour_______________ 0.26 % 96.60 % 35 11 Singapour_______________ 0.25 % 96.59 % 35
11 Chine___________________ 0.26 % 96.85 % 36 11 Israel__________________ 0.25 % 96.83 % 36
10 Mexique_________________ 0.23 % 97.09 % 37 11 Chine___________________ 0.25 % 97.08 % 37
10 Israel__________________ 0.23 % 97.32 % 38 11 Chili___________________ 0.25 % 97.33 % 38
10 Chili___________________ 0.23 % 97.56 % 39 10 Mexique_________________ 0.23 % 97.56 % 39
8 Slovenie________________ 0.19 % 97.75 % 40 9 Roumanie________________ 0.20 % 97.76 % 40
8 Roumanie________________ 0.19 % 97.93 % 41 8 Slovenie________________ 0.18 % 97.94 % 41
8 Emirats_Arabes_Unis_____ 0.19 % 98.12 % 42 8 Emirats_Arabes_Unis_____ 0.18 % 98.12 % 42
7 Lettonie________________ 0.16 % 98.29 % 43 7 Lettonie________________ 0.16 % 98.28 % 43
5 Thailande_______________ 0.12 % 98.40 % 44 5 Thailande_______________ 0.11 % 98.39 % 44
5 Malte___________________ 0.12 % 98.52 % 45 5 Malte___________________ 0.11 % 98.51 % 45
5 Islande_________________ 0.12 % 98.64 % 46 5 Islande_________________ 0.11 % 98.62 % 46
4 Indonesie_______________ 0.09 % 98.73 % 47 4 Turquie_________________ 0.09 % 98.71 % 47
4 Egypte__________________ 0.09 % 98.83 % 48 4 Indonesie_______________ 0.09 % 98.80 % 48
3 Venezuela_______________ 0.07 % 98.90 % 49 4 Egypte__________________ 0.09 % 98.89 % 49
3 Turquie_________________ 0.07 % 98.97 % 50 4 Croatie_________________ 0.09 % 98.98 % 50
3 Philippines_____________ 0.07 % 99.04 % 51 4 Bulgarie________________ 0.09 % 99.07 % 51
3 Estonie_________________ 0.07 % 99.11 % 52 3 Venezuela_______________ 0.07 % 99.14 % 52
3 Croatie_________________ 0.07 % 99.18 % 53 3 Philippines_____________ 0.07 % 99.21 % 53
3 Bulgarie________________ 0.07 % 99.25 % 54 3 Estonie_________________ 0.07 % 99.28 % 54
2 Vietnam_________________ 0.05 % 99.30 % 55 2 Vietnam_________________ 0.05 % 99.32 % 55
2 Uruguay_________________ 0.05 % 99.34 % 56 2 Uruguay_________________ 0.05 % 99.37 % 56
2 Lituanie________________ 0.05 % 99.39 % 57 2 Lituanie________________ 0.05 % 99.41 % 57
2 Costa_Rica______________ 0.05 % 99.44 % 58 2 Costa_Rica______________ 0.05 % 99.46 % 58
2 Chypre__________________ 0.05 % 99.48 % 59 2 Chypre__________________ 0.05 % 99.50 % 59
1 Ukraine_________________ 0.02 % 99.51 % 60 1 Ukraine_________________ 0.02 % 99.53 % 60
1 Trinite-et-Tobago_______ 0.02 % 99.53 % 61 1 Trinite-et-Tobago_______ 0.02 % 99.55 % 61
1 Tanzanie________________ 0.02 % 99.55 % 62 1 Tanzanie________________ 0.02 % 99.57 % 62
1 Taiwan__________________ 0.02 % 99.58 % 63 1 Taiwan__________________ 0.02 % 99.59 % 63
1 Serbie__________________ 0.02 % 99.60 % 64 1 Serbie__________________ 0.02 % 99.62 % 64
1 Senegal_________________ 0.02 % 99.62 % 65 1 Senegal_________________ 0.02 % 99.64 % 65
1 Saint_Christophe-Nevis-Anguilla__ 0.02 % 99.65 % 66 1 Saint_Christophe-Nevis-Anguilla__ 0.02 % 99.66 % 66
1 Qatar___________________ 0.02 % 99.67 % 67 1 Qatar___________________ 0.02 % 99.68 % 67
1 Perou___________________ 0.02 % 99.69 % 68 1 Perou___________________ 0.02 % 99.71 % 68
1 Panama__________________ 0.02 % 99.72 % 69 1 Panama__________________ 0.02 % 99.73 % 69
1 Nouvelle-Caledonie______ 0.02 % 99.74 % 70 1 Nouvelle-Caledonie______ 0.02 % 99.75 % 70
1 Nigeria_________________ 0.02 % 99.77 % 71 1 Nigeria_________________ 0.02 % 99.77 % 71
1 Namibie_________________ 0.02 % 99.79 % 72 1 Namibie_________________ 0.02 % 99.80 % 72
1 Mongolie________________ 0.02 % 99.81 % 73 1 Mongolie________________ 0.02 % 99.82 % 73
1 Moldavie________________ 0.02 % 99.84 % 74 1 Moldavie________________ 0.02 % 99.84 % 74
1 Maldives________________ 0.02 % 99.86 % 75 1 Maldives________________ 0.02 % 99.86 % 75
1 Îles_Vierges_britanniques__ 0.02 % 99.88 % 76 1 Îles_Vierges_britanniques__ 0.02 % 99.89 % 76
1 Koweit__________________ 0.02 % 99.91 % 77 1 Koweit__________________ 0.02 % 99.91 % 77
1 Jordanie________________ 0.02 % 99.93 % 78 1 Jordanie________________ 0.02 % 99.93 % 78
1 Colombie________________ 0.02 % 99.95 % 79 1 Colombie________________ 0.02 % 99.95 % 79
1 Bahrein_________________ 0.02 % 99.98 % 80 1 Bahrein_________________ 0.02 % 99.98 % 80
1 Antilles_neerlandaises__ 0.02 % 100.00 % 81 1 Antilles_neerlandaises__ 0.02 % 100.00 % 81
TOTAL = 4259 sales over 81 countries on Mon Oct 26 02:15:08 CET 2015 TOTAL = 4423 sales over 81 countries on Wed Jan 20 18:35:17 CET 2016

2
W/paypal_reply/memo Executable file → Normal file
View file

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
# $Id: memo,v 1.17 2015/07/02 11:53:28 gilles Exp gilles $ # $Id: memo,v 1.18 2015/12/03 16:47:48 gilles Exp gilles $
echo paypal_bilan_todo echo paypal_bilan_todo

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
# $Id: paypal_build_invoices,v 1.99 2015/11/25 18:53:08 gilles Exp gilles $ # $Id: paypal_build_invoices,v 1.101 2016/01/14 15:57:04 gilles Exp gilles $
# usage: sh paypal_build_invoices /g/var/paypal_invoices/???? # usage: sh paypal_build_invoices /g/var/paypal_invoices/????
@ -70,13 +70,14 @@ 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 4263 /g/paypal/paypal_2015_08_complet.csv #/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 4263 /g/paypal/paypal_2015_08_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 4317 /g/paypal/paypal_2015_09_complet.csv #/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 4317 /g/paypal/paypal_2015_09_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 4383 /g/paypal/paypal_2015_10_complet.csv #/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 4383 /g/paypal/paypal_2015_10_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 4451 /g/paypal/paypal_2015_11_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 4506 /g/paypal/paypal_2015_12_complet.csv
set -x set -x
/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 4451 /g/paypal/paypal_2015_11_complet.csv /g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 4575 /g/paypal/paypal_2016_01_complet.csv
set +x set +x
: /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 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 : /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 214 /g/paypal/paypal_2010_12_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 294 --usdeur 1.3385 /g/paypal/paypal_2011_01_complet.csv : /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 294 --usdeur 1.3385 /g/paypal/paypal_2011_01_complet.csv
@ -139,9 +140,11 @@ set +x
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 4263 /g/paypal/paypal_2015_08_complet.csv : /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 4263 /g/paypal/paypal_2015_08_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 4317 /g/paypal/paypal_2015_09_complet.csv : /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 4317 /g/paypal/paypal_2015_09_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 4383 /g/paypal/paypal_2015_10_complet.csv : /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 4383 /g/paypal/paypal_2015_10_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 4451 /g/paypal/paypal_2015_11_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 4506 /g/paypal/paypal_2015_12_complet.csv
set -x set -x
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 4451 /g/paypal/paypal_2015_11_complet.csv : /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 4575 /g/paypal/paypal_2016_01_complet.csv
set +x set +x
# La totale # La totale
@ -151,7 +154,8 @@ set +x
1330 1331 1332 1333 1334 1652 1653 2131 2132 1330 1331 1332 1333 1334 1652 1653 2131 2132
2295 2296 2297 2298 2625 2626 2970 2971 2972 2295 2296 2297 2298 2625 2626 2970 2971 2972
3093 3296 3411 3412 3450 3451 3614 3615 3616 3617 3093 3296 3411 3412 3450 3451 3614 3615 3616 3617
3807 3808 3957 3958 4030 4194 4195 4381 4382 4449 4450' \ 3807 3808 3957 3958 4030 4194 4195 4381 4382 4449 4450
4574' \
/g/paypal/paypal_201?_??_complet.csv /g/paypal/paypal_201?_??_complet.csv
#set -v #set -v
@ -160,30 +164,23 @@ set +x
1330 1331 1332 1333 1334 1652 1653 2131 2132 1330 1331 1332 1333 1334 1652 1653 2131 2132
2295 2296 2297 2298 2625 2626 2970 2971 2972 2295 2296 2297 2298 2625 2626 2970 2971 2972
3093 3296 3411 3412 3450 3451 3614 3615 3616 3617 3093 3296 3411 3412 3450 3451 3614 3615 3616 3617
3807 3808 3957 3958 4030 4194 4195 4381 4382 4449 4450' \ 3807 3808 3957 3958 4030 4194 4195 4381 4382 4449 4450
4574' \
/g/paypal/paypal_201?_??_complet.csv /g/paypal/paypal_201?_??_complet.csv
#set +v #set +v
# echo 2010 : 145 ( from 147 to 291 ) EUR 3836.38 #echo 2016 : ( from 4574 to ???? ) EUR
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 147 --avoid_numbers '' /g/paypal/paypal_2010_??_complet.csv
# echo 2011 : 1031 ( from 294 to 1329 ) EUR 30983.02
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan \
--first_in 292 --avoid_numbers '292 293 643 644 731 732 1093' \
/g/paypal/paypal_2011_??_complet.csv
#echo 2012 : 956 ( from 1335 to 2294 ) EUR 37872.00
#set -v #set -v
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan \ : /g/public_html/imapsync/W/paypal_reply/paypal_bilan \
--first_in 1335 --usdeur 1.2952 --avoid_numbers '1652 1653 2131 2132 2295 2296 2297 2298' \ --first_in 4575 --avoid_numbers '4574 ' \
/g/paypal/paypal_2012_??_complet.csv /g/paypal/paypal_2016_??_complet.csv
#set +v #set +v
#echo 2013 : 789 ( from 2299 to 3092 ) EUR 38652.00 #echo 2015 : ( from 3809 to 4573 ) EUR
#set -v #set -v
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan \ : /g/public_html/imapsync/W/paypal_reply/paypal_bilan \
--first_in 2299 --avoid_numbers '2625 2626 2970 2971 2972' \ --first_in 3809 --avoid_numbers '3807 3808 3957 3958 4030 4194 4195 4381 4382 4449 4450' \
/g/paypal/paypal_2013_??_complet.csv /g/paypal/paypal_2015_??_complet.csv
#set +v #set +v
#echo 2014 : 704 ( from 3094 to 3806 ) EUR 36900.00 #echo 2014 : 704 ( from 3094 to 3806 ) EUR 36900.00
@ -193,13 +190,29 @@ set +x
/g/paypal/paypal_2014_??_complet.csv /g/paypal/paypal_2014_??_complet.csv
#set +v #set +v
#echo 2015 : ( from 3809 to ???? ) EUR #echo 2013 : 789 ( from 2299 to 3092 ) EUR 38652.00
#set -v #set -v
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan \ : /g/public_html/imapsync/W/paypal_reply/paypal_bilan \
--first_in 3809 --avoid_numbers '3807 3808 3957 3958 4030 4194 4195 4381 4382' \ --first_in 2299 --avoid_numbers '2625 2626 2970 2971 2972' \
/g/paypal/paypal_2015_??_complet.csv /g/paypal/paypal_2013_??_complet.csv
#set +v #set +v
#echo 2012 : 956 ( from 1335 to 2294 ) EUR 37872.00
#set -v
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan \
--first_in 1335 --usdeur 1.2952 --avoid_numbers '1652 1653 2131 2132 2295 2296 2297 2298' \
/g/paypal/paypal_2012_??_complet.csv
#set +v
# echo 2011 : 1031 ( from 294 to 1329 ) EUR 30983.02
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan \
--first_in 292 --avoid_numbers '292 293 643 644 731 732 1093' \
/g/paypal/paypal_2011_??_complet.csv
# echo 2010 : 145 ( from 147 to 291 ) EUR 3836.38
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 147 --avoid_numbers '' /g/paypal/paypal_2010_??_complet.csv
echo 'sh paypal_build_invoices /g/var/paypal_invoices/4???' echo 'sh paypal_build_invoices /g/var/paypal_invoices/4???'

View file

@ -3,9 +3,9 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<title>imapsync download</title> <title>imapsync download</title>
<meta name="generator" content="Bluefish 1.0.7"/> <meta name="generator" content="Bluefish 2.2.2" />
<meta name="author" content="Gilles LAMIRAL" /> <meta name="author" content="Gilles LAMIRAL" />
<meta name="date" content="2014-11-21T12:07:54+0100"/> <meta name="date" content="2016-01-20T11:18:20+0100" />
<meta name="copyright" content=""/> <meta name="copyright" content=""/>
<meta name="keywords" content=""/> <meta name="keywords" content=""/>
<meta name="description" content=""/> <meta name="description" content=""/>
@ -47,6 +47,11 @@ and the latest <b>imapsync source code</b> release <!--#exec cmd="cat ../VERSION
<a href="../dist/<!--#exec cmd="cat ../dist/path_last.txt" -->/"><b>download page</b></a>. <a href="../dist/<!--#exec cmd="cat ../dist/path_last.txt" -->/"><b>download page</b></a>.
</p> </p>
<p>
Next steps are the imapsync <a href="../#install" >installation</a>
and then your first runs following the <a href="../#doc" >tutorial</</a>.
</p>
<p>You will receive an invoice soon, in a couple of weeks at the worst. <p>You will receive an invoice soon, in a couple of weeks at the worst.
Ask for it if you need it before.</p> Ask for it if you need it before.</p>
@ -91,7 +96,7 @@ gilles.lamiral@laposte.net</p>
<!--#config timefmt="%D" --> <!--#config timefmt="%D" -->
<!--#config timefmt="%A %B %d, %Y" --> <!--#config timefmt="%A %B %d, %Y" -->
<b>This document last modified on <!--#echo var="LAST_MODIFIED" --></b><br/> <b>This document last modified on <!--#echo var="LAST_MODIFIED" --></b><br/>
($Id: paypal_return.shtml,v 1.18 2015/02/16 21:15:26 gilles Exp gilles $) ($Id: paypal_return.shtml,v 1.19 2016/01/21 02:37:53 gilles Exp gilles $)
</p> </p>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,77 +1,78 @@
Main code has high complexity score (400) at line 1, column 1. Consider refactoring. (Severity: 3) Main code has high complexity score (407) at line 1, column 1. Consider refactoring. (Severity: 3)
Regular expression without "/x" flag at line 1121, column 33. See page 236 of PBP. (Severity: 3) "$ssl1_SSL_version" is declared but not used at line 706, column 1. Unused variables clutter code and make it harder to read. (Severity: 3)
Regular expression without "/x" flag at line 1130, column 33. See page 236 of PBP. (Severity: 3) "$ssl2_SSL_version" is declared but not used at line 706, column 1. Unused variables clutter code and make it harder to read. (Severity: 3)
Code structure is deeply nested at line 1651, column 41. Consider refactoring. (Severity: 3) Regular expression without "/x" flag at line 1333, column 33. See page 236 of PBP. (Severity: 3)
Reused variable name in lexical scope: $sync at line 1823, column 2. Invent unique variable names. (Severity: 3) Regular expression without "/x" flag at line 1342, column 33. See page 236 of PBP. (Severity: 3)
Hard tabs used at line 1849, column 22. See page 20 of PBP. (Severity: 3) Code structure is deeply nested at line 1867, column 41. Consider refactoring. (Severity: 3)
Reused variable name in lexical scope: $sync at line 1933, column 2. Invent unique variable names. (Severity: 3) Reused variable name in lexical scope: $sync at line 2039, column 2. Invent unique variable names. (Severity: 3)
Regular expression without "/x" flag at line 1982, column 29. See page 236 of PBP. (Severity: 3) Hard tabs used at line 2065, column 22. See page 20 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 2004, column 31. See page 236 of PBP. (Severity: 3) Reused variable name in lexical scope: $sync at line 2149, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $sync at line 2013, column 2. Invent unique variable names. (Severity: 3) Regular expression without "/x" flag at line 2198, column 29. See page 236 of PBP. (Severity: 3)
Reused variable name in lexical scope: $sync at line 2036, column 2. Invent unique variable names. (Severity: 3) Regular expression without "/x" flag at line 2220, column 31. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 2069, column 30. See page 236 of PBP. (Severity: 3) Reused variable name in lexical scope: $sync at line 2229, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $sync at line 2080, column 53. Invent unique variable names. (Severity: 3) Reused variable name in lexical scope: $sync at line 2252, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $sync at line 2088, column 2. Invent unique variable names. (Severity: 3) Regular expression without "/x" flag at line 2285, column 30. See page 236 of PBP. (Severity: 3)
Reused variable name in lexical scope: $sync at line 2136, column 2. Invent unique variable names. (Severity: 3) Reused variable name in lexical scope: $sync at line 2296, column 53. Invent unique variable names. (Severity: 3)
Regular expression without "/x" flag at line 2172, column 26. See page 236 of PBP. (Severity: 3) Reused variable name in lexical scope: $sync at line 2304, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $nb_errors at line 2220, column 2. Invent unique variable names. (Severity: 3) Reused variable name in lexical scope: $sync at line 2352, column 2. Invent unique variable names. (Severity: 3)
Too many arguments at line 2256, column 1. See page 182 of PBP. (Severity: 3) Regular expression without "/x" flag at line 2388, column 26. See page 236 of PBP. (Severity: 3)
Too many arguments at line 2274, column 1. See page 182 of PBP. (Severity: 3) Reused variable name in lexical scope: $nb_errors at line 2436, column 2. Invent unique variable names. (Severity: 3)
Too many arguments at line 2284, column 1. See page 182 of PBP. (Severity: 3) Too many arguments at line 2472, column 1. See page 182 of PBP. (Severity: 3)
Subroutine "modules_VERSION" with high complexity score (25) at line 2401, column 1. Consider refactoring. (Severity: 3) Too many arguments at line 2490, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2570, column 1. See page 182 of PBP. (Severity: 3) Too many arguments at line 2500, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2603, column 1. See page 182 of PBP. (Severity: 3) Subroutine "modules_VERSION" with high complexity score (26) at line 2618, column 1. Consider refactoring. (Severity: 3)
Subroutine "authenticate_imap" with high complexity score (21) at line 2671, column 1. Consider refactoring. (Severity: 3) Too many arguments at line 2781, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2671, column 1. See page 182 of PBP. (Severity: 3) Subroutine "authenticate_imap" with high complexity score (21) at line 2850, column 1. Consider refactoring. (Severity: 3)
Too many arguments at line 2776, column 1. See page 182 of PBP. (Severity: 3) Too many arguments at line 2850, column 1. See page 182 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 2850, column 51. See page 236 of PBP. (Severity: 3) Too many arguments at line 2972, column 1. See page 182 of PBP. (Severity: 3)
Backtick operator used at line 2858, column 12. Use IPC::Open3 instead. (Severity: 3) Regular expression without "/x" flag at line 3048, column 62. See page 236 of PBP. (Severity: 3)
Return value of eval not tested at line 2992, column 2. You can't depend upon the value of $@/$EVAL_ERROR to tell whether an eval failed. (Severity: 3) Backtick operator used at line 3056, column 19. Use IPC::Open3 instead. (Severity: 3)
"die" used instead of "croak" at line 3037, column 2. See page 283 of PBP. (Severity: 3) Return value of eval not tested at line 3194, column 2. You can't depend upon the value of $@/$EVAL_ERROR to tell whether an eval failed. (Severity: 3)
Regular expression without "/x" flag at line 3145, column 15. See page 236 of PBP. (Severity: 3) "die" used instead of "croak" at line 3239, column 2. See page 283 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3146, column 15. See page 236 of PBP. (Severity: 3) Regular expression without "/x" flag at line 3347, column 15. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3147, column 15. See page 236 of PBP. (Severity: 3) Regular expression without "/x" flag at line 3348, column 15. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3156, column 8. See page 236 of PBP. (Severity: 3) Regular expression without "/x" flag at line 3349, column 15. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3157, column 8. See page 236 of PBP. (Severity: 3) Regular expression without "/x" flag at line 3358, column 8. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3158, column 8. See page 236 of PBP. (Severity: 3) Regular expression without "/x" flag at line 3359, column 8. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3184, column 31. See page 236 of PBP. (Severity: 3) Regular expression without "/x" flag at line 3360, column 8. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3261, column 25. See page 236 of PBP. (Severity: 3) Regular expression without "/x" flag at line 3386, column 31. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3264, column 20. See page 236 of PBP. (Severity: 3) Regular expression without "/x" flag at line 3463, column 25. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3465, column 24. See page 236 of PBP. (Severity: 3) Regular expression without "/x" flag at line 3466, column 20. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3466, column 19. See page 236 of PBP. (Severity: 3) Regular expression without "/x" flag at line 3667, column 24. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3470, column 19. See page 236 of PBP. (Severity: 3) Regular expression without "/x" flag at line 3668, column 19. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3540, column 39. See page 236 of PBP. (Severity: 3) Regular expression without "/x" flag at line 3672, column 19. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3541, column 39. See page 236 of PBP. (Severity: 3) Regular expression without "/x" flag at line 3742, column 39. See page 236 of PBP. (Severity: 3)
Regular expression without "/x" flag at line 3542, column 41. See page 236 of PBP. (Severity: 3) Regular expression without "/x" flag at line 3743, column 39. See page 236 of PBP. (Severity: 3)
Hard tabs used at line 3556, column 106. See page 20 of PBP. (Severity: 3) Regular expression without "/x" flag at line 3744, column 41. See page 236 of PBP. (Severity: 3)
Expression form of "eval" at line 3796, column 13. See page 161 of PBP. (Severity: 5) Hard tabs used at line 3758, column 106. See page 20 of PBP. (Severity: 3)
Expression form of "eval" at line 4026, column 13. See page 161 of PBP. (Severity: 5) Expression form of "eval" at line 3998, column 13. See page 161 of PBP. (Severity: 5)
Subroutine "copy_message" with high complexity score (25) at line 4389, column 1. Consider refactoring. (Severity: 3) Expression form of "eval" at line 4228, column 13. See page 161 of PBP. (Severity: 5)
Too many arguments at line 4389, column 1. See page 182 of PBP. (Severity: 3) Subroutine "copy_message" with high complexity score (25) at line 4589, column 1. Consider refactoring. (Severity: 3)
Too many arguments at line 4467, column 1. See page 182 of PBP. (Severity: 3) Too many arguments at line 4589, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 4501, column 1. See page 182 of PBP. (Severity: 3) Too many arguments at line 4665, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 4690, column 1. See page 182 of PBP. (Severity: 3) Too many arguments at line 4699, column 1. See page 182 of PBP. (Severity: 3)
Reused variable name in lexical scope: $total_bytes_transferred at line 4751, column 2. Invent unique variable names. (Severity: 3) Too many arguments at line 4888, column 1. See page 182 of PBP. (Severity: 3)
Reused variable name in lexical scope: $nb_msg_transferred at line 4751, column 2. Invent unique variable names. (Severity: 3) Reused variable name in lexical scope: $total_bytes_transferred at line 4949, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $nb_msg_transferred at line 4764, column 9. Invent unique variable names. (Severity: 3) Reused variable name in lexical scope: $nb_msg_transferred at line 4949, column 2. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $maxmessagespersecond at line 4764, column 9. Invent unique variable names. (Severity: 3) Reused variable name in lexical scope: $nb_msg_transferred at line 4962, column 9. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $total_bytes_transferred at line 4785, column 9. Invent unique variable names. (Severity: 3) Reused variable name in lexical scope: $maxmessagespersecond at line 4962, column 9. Invent unique variable names. (Severity: 3)
Reused variable name in lexical scope: $maxbytespersecond at line 4785, column 9. Invent unique variable names. (Severity: 3) Reused variable name in lexical scope: $total_bytes_transferred at line 4983, column 9. Invent unique variable names. (Severity: 3)
Expression form of "eval" at line 5972, column 13. See page 161 of PBP. (Severity: 5) Reused variable name in lexical scope: $maxbytespersecond at line 4983, column 9. Invent unique variable names. (Severity: 3)
Regular expression without "/x" flag at line 6207, column 22. See page 236 of PBP. (Severity: 3) Expression form of "eval" at line 6170, column 13. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 6212, column 13. See page 161 of PBP. (Severity: 5) Regular expression without "/x" flag at line 6405, column 22. See page 236 of PBP. (Severity: 3)
Too many arguments at line 6376, column 1. See page 182 of PBP. (Severity: 3) Expression form of "eval" at line 6410, column 13. See page 161 of PBP. (Severity: 5)
Backtick operator used at line 6543, column 4. Use IPC::Open3 instead. (Severity: 3) Too many arguments at line 6573, column 1. See page 182 of PBP. (Severity: 3)
Backtick operator used at line 6750, column 12. Use IPC::Open3 instead. (Severity: 3) Backtick operator used at line 6740, column 4. Use IPC::Open3 instead. (Severity: 3)
Backtick operator used at line 6770, column 11. Use IPC::Open3 instead. (Severity: 3) Backtick operator used at line 6947, column 12. Use IPC::Open3 instead. (Severity: 3)
Split long regexps into smaller qr// chunks at line 6932, column 12. See page 261 of PBP. (Severity: 3) Backtick operator used at line 6967, column 11. Use IPC::Open3 instead. (Severity: 3)
Split long regexps into smaller qr// chunks at line 6958, column 12. See page 261 of PBP. (Severity: 3) Split long regexps into smaller qr// chunks at line 7129, column 12. See page 261 of PBP. (Severity: 3)
Split long regexps into smaller qr// chunks at line 6999, column 12. See page 261 of PBP. (Severity: 3) Split long regexps into smaller qr// chunks at line 7155, column 12. See page 261 of PBP. (Severity: 3)
Split long regexps into smaller qr// chunks at line 7011, column 12. See page 261 of PBP. (Severity: 3) Split long regexps into smaller qr// chunks at line 7196, column 12. See page 261 of PBP. (Severity: 3)
Expression form of "eval" at line 7117, column 43. See page 161 of PBP. (Severity: 5) Split long regexps into smaller qr// chunks at line 7208, column 12. See page 261 of PBP. (Severity: 3)
Expression form of "eval" at line 7121, column 45. See page 161 of PBP. (Severity: 5) Expression form of "eval" at line 7314, column 43. See page 161 of PBP. (Severity: 5)
Split long regexps into smaller qr// chunks at line 7326, column 20. See page 261 of PBP. (Severity: 3) Expression form of "eval" at line 7318, column 45. See page 161 of PBP. (Severity: 5)
Regular expression without "/x" flag at line 7493, column 19. See page 236 of PBP. (Severity: 3) Split long regexps into smaller qr// chunks at line 7523, column 20. See page 261 of PBP. (Severity: 3)
Close filehandles as soon as possible after opening them at line 7537, column 2. See page 209 of PBP. (Severity: 4) Regular expression without "/x" flag at line 7690, column 19. See page 236 of PBP. (Severity: 3)
Magic variable "*STDERR" should be assigned as "local" at line 7540, column 10. See pages 81,82 of PBP. (Severity: 4) Close filehandles as soon as possible after opening them at line 7734, column 2. See page 209 of PBP. (Severity: 4)
One-argument "select" used at line 7541, column 2. See page 224 of PBP. (Severity: 4) Magic variable "*STDERR" should be assigned as "local" at line 7737, column 10. See pages 81,82 of PBP. (Severity: 4)
One-argument "select" used at line 7738, column 2. See page 224 of PBP. (Severity: 4)

View file

@ -1,9 +1,9 @@
Expression form of "eval" at line 3796, column 13. See page 161 of PBP. (Severity: 5) Expression form of "eval" at line 3998, column 13. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 4026, column 13. See page 161 of PBP. (Severity: 5) Expression form of "eval" at line 4228, column 13. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 5972, column 13. See page 161 of PBP. (Severity: 5) Expression form of "eval" at line 6170, column 13. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 6212, column 13. See page 161 of PBP. (Severity: 5) Expression form of "eval" at line 6410, column 13. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 7117, column 43. See page 161 of PBP. (Severity: 5) Expression form of "eval" at line 7314, column 43. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 7121, column 45. See page 161 of PBP. (Severity: 5) Expression form of "eval" at line 7318, column 45. See page 161 of PBP. (Severity: 5)
Close filehandles as soon as possible after opening them at line 7537, column 2. See page 209 of PBP. (Severity: 4) Close filehandles as soon as possible after opening them at line 7734, column 2. See page 209 of PBP. (Severity: 4)
Magic variable "*STDERR" should be assigned as "local" at line 7540, column 10. See pages 81,82 of PBP. (Severity: 4) Magic variable "*STDERR" should be assigned as "local" at line 7737, column 10. See pages 81,82 of PBP. (Severity: 4)
One-argument "select" used at line 7541, column 2. See page 224 of PBP. (Severity: 4) One-argument "select" used at line 7738, column 2. See page 224 of PBP. (Severity: 4)

View file

@ -1,11 +1,11 @@
$SHELL says /bin/bash $SHELL says /bin/bash
$0 gives ./INSTALL.d/prerequisites_imapsync $0 gives ./INSTALL.d/prerequisites_imapsync
ps -ef gives gilles 4983 4982 0 03:58 pts/18 00:00:00 /bin/sh ./INSTALL.d/prerequisites_imapsync ps -ef gives gilles 21682 21681 0 20:55 pts/22 00:00:00 /bin/sh ./INSTALL.d/prerequisites_imapsync
Distributor ID: Ubuntu Distributor ID: Ubuntu
Description: Ubuntu 12.04.5 LTS Description: Ubuntu 12.04.5 LTS
Release: 12.04 Release: 12.04
Codename: precise Codename: precise
Linux petite 3.2.0-91-generic #129-Ubuntu SMP Wed Sep 9 10:56:56 UTC 2015 i686 i686 i386 GNU/Linux Linux petite 3.2.0-97-generic #137-Ubuntu SMP Thu Dec 17 21:14:00 UTC 2015 i686 i686 i386 GNU/Linux
Ok: Found Perl 5.14.2 Ok: Found Perl 5.14.2
Ok: Found Perl module Digest::HMAC_MD5 Ok: Found Perl module Digest::HMAC_MD5
Ok: Found Perl module Authen::NTLM Ok: Found Perl module Authen::NTLM

View file

@ -30,8 +30,12 @@ cmd means command
--ssl2 : Use a SSL connection on host2. --ssl2 : Use a SSL connection on host2.
--tls1 : Use a TLS connection on host1. --tls1 : Use a TLS connection on host1.
--tls2 : Use a TLS connection on host2. --tls2 : Use a TLS connection on host2.
--timeout int : Connections timeout in seconds. Default is 120. --debugssl int : SSL debug mode from 0 to 4.
0 means no timeout.
--timeout1 int : Connection timeout in seconds for host1.
Default is 120 and 0 means no timeout at all.
--timeout2 int : Connection timeout in seconds for host2.
Default is 120 and 0 means no timeout at all.
--authmech1 str : Auth mechanism to use with host1: --authmech1 str : Auth mechanism to use with host1:
PLAIN, LOGIN, CRAM-MD5 etc. Use UPPERCASE. PLAIN, LOGIN, CRAM-MD5 etc. Use UPPERCASE.
@ -67,7 +71,6 @@ cmd means command
--skipemptyfolders : Empty host1 folders are not created on host2. --skipemptyfolders : Empty host1 folders are not created on host2.
--f1f2 str1=str2 : Force folder str1 to be synced to str2.
--include reg : Sync folders matching this regular expression --include reg : Sync folders matching this regular expression
--include reg : or this one, etc. --include reg : or this one, etc.
in case both --include --exclude options are in case both --include --exclude options are
@ -82,13 +85,18 @@ cmd means command
It does it by adding two --regextrans2 options before It does it by adding two --regextrans2 options before
all others. Add --debug to see what's really going on. all others. Add --debug to see what's really going on.
--automap : guesses folders mapping, for folders like
"Sent", "Junk", "Drafts", "All", "Archive", "Flagged".
--f1f2 str1=str2 : Force folder str1 to be synced to str2,
--f1f2 overrides --automap and --regextrans2.
--regextrans2 reg : Apply the whole regex to each destination folders. --regextrans2 reg : Apply the whole regex to each destination folders.
--regextrans2 reg : and this one. etc. --regextrans2 reg : and this one. etc.
When you play with the --regextrans2 option, first When you play with the --regextrans2 option, first
add also the safe options --dry --justfolders add also the safe options --dry --justfolders
Then, when happy, remove --dry, remove --justfolders. Then, when happy, remove --dry, remove --justfolders.
Have in mind that --regextrans2 is applied after prefix Have in mind that --regextrans2 is applied after prefix
and separator inversion. and separator inversion. For examples see
http://imapsync.lamiral.info/FAQ.d/FAQ.Folders_Mapping.txt
--tmpdir str : Where to store temporary files and subdirectories. --tmpdir str : Where to store temporary files and subdirectories.
Will be created if it doesn't exist. Will be created if it doesn't exist.
@ -233,7 +241,9 @@ cmd means command
--debugimap : IMAP debug mode for host1 and host2. --debugimap : IMAP debug mode for host1 and host2.
--debugmemory : Debug mode showing memory consumption after each copy. --debugmemory : Debug mode showing memory consumption after each copy.
--tests : Run non-regression tests. --errorsmax int : Exit when int number of errors is reached. Default is 50.
--tests : Run local non-regression tests. Exit code 0 means all ok.
--testslive : Run a live test with test1.lamiral.info imap server. --testslive : Run a live test with test1.lamiral.info imap server.
Useful to check the basics. Needs internet connexion. Useful to check the basics. Needs internet connexion.
@ -258,13 +268,16 @@ imapsync \
--host1 test1.lamiral.info --user1 test1 --password1 secret1 \ --host1 test1.lamiral.info --user1 test1 --password1 secret1 \
--host2 test2.lamiral.info --user2 test2 --password2 secret2 --host2 test2.lamiral.info --user2 test2 --password2 secret2
Here is a [linux] system (Linux petite 3.2.0-91-generic #129-Ubuntu SMP Wed Sep 9 10:56:56 UTC 2015 i686) Here is a [linux] system (Linux petite 3.2.0-97-generic #137-Ubuntu SMP Thu Dec 17 21:14:00 UTC 2015 i686)
With perl 5.14.2 Mail::IMAPClient 3.30 With perl 5.14.2 Mail::IMAPClient 3.30
$Id: imapsync,v 1.670 2015/12/03 02:36:41 gilles Exp gilles $ $Id: imapsync,v 1.678 2016/01/21 19:47:02 gilles Exp gilles $
This current imapsync is up to date This current imapsync is up to date
Homepage: http://imapsync.lamiral.info/ Homepage: http://imapsync.lamiral.info/
[MSG] No '/home/gilles/.cpanplus/custom-sources' dir, skipping custom sources
[MSG] No '/home/gilles/.cpanplus/custom-sources' dir, skipping custom sources
[MSG] No '/home/gilles/.cpanplus/custom-sources' dir, skipping custom sources
'Tie::Hash::NamedCapture' => '0.08', 'Tie::Hash::NamedCapture' => '0.08',
'Authen::NTLM::DES' => '1.02', 'Authen::NTLM::DES' => '1.02',
'Authen::NTLM::MD4' => '1.02', 'Authen::NTLM::MD4' => '1.02',

View file

@ -1,16 +1,16 @@
@REM $Id: test3.bat,v 1.22 2015/09/21 22:49:50 gilles Exp gilles $ @REM $Id: test3.bat,v 1.23 2015/12/14 15:15:12 gilles Exp gilles $
cd /D %~dp0 cd /D %~dp0
@REM \$1 must be $1 on Windows @REM \$1 must be $1 on Windows
@REM ==== split lon lines @REM ==== password within double-quotes
perl ./imapsync ^ perl ./imapsync ^
--host1 p --user1 tata ^ --host1 p --user1 tata ^
--passfile1 secret.tata ^ --password1 """(secret)""" ^
--host2 p --user2 titi ^ --host2 p --user2 titi ^
--passfile2 secret.titi ^ --passfile2 secret.titi ^
--nofoldersizes --folder "INBOX.longline" --regexmess "s,(.{9900}),$1\r\n,g" --dry --debugcontent --justlogin --debugimap1 --showpassword
@EXIT @EXIT

Some files were not shown because too many files have changed in this diff Show more