This commit is contained in:
Nick Bebout 2013-10-17 19:11:27 -05:00
parent 4c70a807bd
commit 8f266abab8
79 changed files with 28408 additions and 2906 deletions

10
CREDITS
View file

@ -1,5 +1,5 @@
#!/bin/cat #!/bin/cat
# $Id: CREDITS,v 1.175 2013/08/28 22:44:09 gilles Exp gilles $ # $Id: CREDITS,v 1.177 2013/09/28 11:52:08 gilles Exp gilles $
If you want to make a donation to the author, Gilles LAMIRAL, If you want to make a donation to the author, Gilles LAMIRAL,
use any of the following ways: use any of the following ways:
@ -30,6 +30,14 @@ I thank very much all of these people.
I thank also very much all people who bought imapsync from the homepage I thank also very much all people who bought imapsync from the homepage
but I don't cite them here. but I don't cite them here.
Krul, Patrick
Found bug about trailing blanc on Win32 cache dir.
Jonathan Daley
Contributed by giving the book
13.33 EUR "Cartoon Guide to Statistics"
Bowman Gillianne Bowman Gillianne
Contributed by giving the book Contributed by giving the book
8.60 EUR "L'Épreuve de l'étranger: Culture et traduction dans l'Allemagne romantique" 8.60 EUR "L'Épreuve de l'étranger: Culture et traduction dans l'Allemagne romantique"

View file

@ -1,17 +1,27 @@
RCS file: RCS/imapsync,v RCS file: RCS/imapsync,v
Working file: imapsync Working file: imapsync
head: 1.567 head: 1.569
branch: branch:
locks: strict locks: strict
gilles: 1.567 gilles: 1.569
access list: access list:
symbolic names: symbolic names:
keyword substitution: kv keyword substitution: kv
total revisions: 567; selected revisions: 567 total revisions: 569; selected revisions: 569
description: description:
---------------------------- ----------------------------
revision 1.567 locked by: gilles; revision 1.569 locked by: gilles;
date: 2013/10/16 21:58:17; author: gilles; state: Exp; lines: +125 -39
Fixed bug on Windows with --tmpdir "E:\TEMP". The colon was badly converted to _, ending with "E_\TEMP".
The fix also automatically moves the old cache to the new one if the new does not exist yet.
Fix. Example for --delete2foldersonly "/Junk$/" in help message.
----------------------------
revision 1.568
date: 2013/09/28 02:43:51; author: gilles; state: Exp; lines: +25 -13
Bug fix. On Win32 trailing blanc in cache dir name raized an error. Blanc now move to underscore _.
----------------------------
revision 1.567
date: 2013/09/18 20:38:10; author: gilles; state: Exp; lines: +8 -7 date: 2013/09/18 20:38:10; author: gilles; state: Exp; lines: +8 -7
Fixed a warning when RFC822.SIZE is null or undef. Fixed a warning when RFC822.SIZE is null or undef.
---------------------------- ----------------------------

96
FAQ
View file

@ -1,5 +1,5 @@
#!/bin/cat #!/bin/cat
# $Id: FAQ,v 1.145 2013/09/21 21:56:33 gilles Exp gilles $ # $Id: FAQ,v 1.150 2013/10/17 00:55:53 gilles Exp gilles $
+------------------+ +------------------+
| FAQ for imapsync | | FAQ for imapsync |
@ -324,6 +324,21 @@ Two workarounds to reduce the cache directory name:
1) Use --tmpdir "D:\\temp" or simply --tmpdir "D:" 1) Use --tmpdir "D:\\temp" or simply --tmpdir "D:"
Currently (until 1.568) there is a bug with --tmpdir "D:\\temp" or "D:".
Since character : is forbidden in Windows paths the directory is transform
to convert those characters and others () to character _
So "D:\\temp" becomes "D_\\temp".
A fix is to change to D: before running imapsync and use --tmpdir "."
like this in a batch file:
D:
cd \
cd .\temp
%~dp0\imapsync.exe ... --tmpdir "."
This bug should be fixed in release 1.569
2) add two equivalent entries in the etc/hosts for host1 imap.truc.org 2) add two equivalent entries in the etc/hosts for host1 imap.truc.org
and host2 imap.trac.org. and host2 imap.trac.org.
If you map the ip of imap.truc.org just with the letter a If you map the ip of imap.truc.org just with the letter a
@ -509,6 +524,37 @@ The file imapsync.pid contains the PID of the imapsync process.
This file is removed at the end of a normal run. This file is removed at the end of a normal run.
You can safely ignore the warning if you don't use imapsync.pid file. You can safely ignore the warning if you don't use imapsync.pid file.
=======================================================================
Q. Couldn't create folder [trash] from [INBOX.trash]:
588 NO Mailbox already exists.
R. Some servers take care about character case in folder names,
some servers do not, like Exchange. Since non-respecting case
can merge two different folders into one then imapsync respects case.
For example, if a host1 server has a folder name called "trash"
and the host2 server already has a folder "Trash" or "TRASH"
then imapsync will try to create the folder "trash" on host2,
because trash and Trash are different strings. But if host2
does not repect character case it will consider folder "trash"
already exists and will say it, that's the error message
reported by imapsync: "Mailbox already exists", message coming
from the server.
The folder creation fails but messages are well transfered in
so take a look at this warning, understand why it happens
and it should be fine most of the time.
To avoid this warning use --regextrans2 to map the folder names
imapsync ... --regextrans2 "s/^trash$/Trash/"
If there are two folders Trash and trash on host1 then both
will be merge into only one Trash folder on host2.
In case option --delete2 is used the regextans2 above becomes
mandatory, otherwise imapsync will sync messages from the
first Trash and then delete them when syncing trash.
======================================================================= =======================================================================
Q. Couldn't create [INBOX.Ops/foo/bar]: NO Invalid mailbox name: Q. Couldn't create [INBOX.Ops/foo/bar]: NO Invalid mailbox name:
INBOX.Ops/foo/bar INBOX.Ops/foo/bar
@ -548,6 +594,28 @@ R1. Use it with --subscribed
R2. There is also the --subscribe_all option that subscribe R2. There is also the --subscribe_all option that subscribe
to all folders on host2. to all folders on host2.
=======================================================================
Q. Is there a way we can specify a date range to sync emails?
If yes, can you please share an example?
Yes, with the --search option.
imapsync ... --search "SENTSINCE 1-Jan-2010 SENTBEFORE 31-Dec-2010"
Jan
Feb
Mar
Apr
May
Jun
Jul
Aug
Sep
Oct
Nov
Dec
======================================================================= =======================================================================
Q. Does imapsync retain the \Answered and $Forwarded flags? Q. Does imapsync retain the \Answered and $Forwarded flags?
@ -792,8 +860,15 @@ Q. Flags are not well synchonized. Is it a bug?
R. It happens with some servers on the first sync. R. It happens with some servers on the first sync.
Also, it was a bug from revision 1.200 to revision 1.207 Also, it was a bug from revision 1.200 to revision 1.207
Solution: run imapsync a second time. imapsync synchronizes flags Two solutions:
on each run.
* Run imapsync a second time. imapsync synchronizes flags on each run.
* Use option --syncflagsaftercopy. With this option imapsync will
also sync flags after each message transfer. Flags are already
synced during the transfer with the imap APPEND command but
option --syncflagsaftercopy does it again using the imap STORE
command.
======================================================================= =======================================================================
Q. On Unix, some passwords contain * and " characters. Login fails. Q. On Unix, some passwords contain * and " characters. Login fails.
@ -1561,6 +1636,13 @@ characters ' or " or \ to character _ underscore.
You can select folders exported to imap within the gmail preferences, You can select folders exported to imap within the gmail preferences,
unselect all "System labels" depending on your needs. unselect all "System labels" depending on your needs.
=======================================================================
Q. Some of the folders are getting created with [IMAP] prefix on Google
side. How to stop creating folder with this prefix?
Any switch we can use? e.g. [IMAP]/Archive
R. No switch in imapsync since [IMAP]/ prefix is done by Gmail,
it might be configurable with Gmail parameters.
======================================================================= =======================================================================
Q. Synchronizing from Gmail to XXX Q. Synchronizing from Gmail to XXX
@ -1683,6 +1765,14 @@ To Folder [Sonja] Size: 1024546 Messages: 96
R. Just run imapsync a time like this : R. Just run imapsync a time like this :
imapsync ... --folder Alexander imapsync ... --folder Alexander
=======================================================================
Q. Migrating from or to Parallels Plex Server
R. It depends on the OS
Parallells Plesk Panel for Windows requires --sep2 / --prefix2 ""
Parallells Plesk Panel for Linux works with default parameters.
======================================================================= =======================================================================
Q. I'm migrating from WU to Cyrus, and the mail folders are under Q. I'm migrating from WU to Cyrus, and the mail folders are under
/home/user/mail but the tool copies everything in /home/user, how /home/user/mail but the tool copies everything in /home/user, how

View file

@ -1,4 +1,4 @@
# $Id: INSTALL,v 1.30 2013/07/03 04:13:52 gilles Exp gilles $ # $Id: INSTALL,v 1.31 2013/09/28 11:11:48 gilles Exp gilles $
# #
# INSTALL file for imapsync # INSTALL file for imapsync
# imapsync : IMAP sync or copy tool. # imapsync : IMAP sync or copy tool.
@ -94,10 +94,10 @@ Here is some individual module help:
New Mail-IMAPClient-3.xx works very well with imapsync, New Mail-IMAPClient-3.xx works very well with imapsync,
Use at least Mail-IMAPClient-3.25 (previous may bug). Use at least Mail-IMAPClient-3.25 (previous may bug).
Don't hesitate to use latest Mail-IMAPClient-3.xx Don't hesitate to use latest Mail-IMAPClient-3.xx
(3.xx >= 3.33 at the time of this writing) (3.xx >= 3.34 at the time of this writing)
Look at the script named "i3" in the tarball, it can be used to Look at the script named "i3" in the tarball, it can be used to
run imapsync with included Mail-IMAPClient-3.33/ wherever you run imapsync with included Mail-IMAPClient-3.34/ wherever you
unpacked the imapsync tarball. unpacked the imapsync tarball.

View file

@ -1,5 +1,5 @@
# $Id: Makefile,v 1.129 2013/08/16 01:21:14 gilles Exp gilles $ # $Id: Makefile,v 1.132 2013/10/17 00:55:16 gilles Exp gilles $
.PHONY: help usage all .PHONY: help usage all
@ -33,7 +33,7 @@ VERSION=$(shell perl -I$(IMAPClient) ./imapsync --version)
VERSION_EXE=$(shell cat ./VERSION_EXE) VERSION_EXE=$(shell cat ./VERSION_EXE)
HELLO=$(shell date;uname -a) HELLO=$(shell date;uname -a)
IMAPClient_3xx=./W/Mail-IMAPClient-3.33/lib IMAPClient_3xx=./W/Mail-IMAPClient-3.34/lib
IMAPClient=$(IMAPClient_3xx) IMAPClient=$(IMAPClient_3xx)
hello: hello:
@ -108,7 +108,7 @@ cidone:
.PHONY: test tests testp testf test3xx testv3 perlcritic .PHONY: test tests testp testf test3xx testv3 perlcritic
perlcritic: perlcritic_3.out perlcritic_2.out perlcritic_1.out perlcritic: perlcritic_3.out perlcritic_2.out
perlcritic_1.out: imapsync perlcritic_1.out: imapsync
perlcritic -1 imapsync > perlcritic_1.out || : perlcritic -1 imapsync > perlcritic_1.out || :
@ -174,8 +174,8 @@ test_imapsync_exe: dosify_bat
time ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/test_exe.bat' time ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/test_exe.bat'
.prereq_win32: examples/install_modules.bat .dosify_bat .prereq_win32: examples/install_modules.bat .dosify_bat
scp examples/install_modules.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/' scp examples/install_modules.bat Admin@c:'C:/msys/1.0/home/Admin/imapsync/examples/'
ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/install_modules.bat' ssh Admin@c 'C:/msys/1.0/home/Admin/imapsync/examples/install_modules.bat'
touch .prereq_win32 touch .prereq_win32
imapsync.exe: imapsync .prereq_win32 imapsync.exe: imapsync .prereq_win32
@ -321,7 +321,7 @@ publish: dist upload_ks ksa
PUBLIC_FILES = ./ChangeLog ./NOLIMIT ./LICENSE ./CREDITS ./FAQ \ PUBLIC_FILES = ./ChangeLog ./NOLIMIT ./LICENSE ./CREDITS ./FAQ \
./index.shtml ./INSTALL \ ./index.shtml ./INSTALL \
./VERSION ./VERSION_EXE \ ./VERSION ./VERSION_EXE \
./README ./TODO ./README ./TODO ./TUTORIAL.html ./GOOD_PRACTICES.html
PUBLIC_FILES_W = ./W/style.css \ PUBLIC_FILES_W = ./W/style.css \
./W/TIME \ ./W/TIME \
@ -345,10 +345,10 @@ upload_lfo:
/home/gilles/public_html/www.linux-france.org/html/prj/imapsync/.htaccess /home/gilles/public_html/www.linux-france.org/html/prj/imapsync/.htaccess
sh ~/memo/lfo-rsync sh ~/memo/lfo-rsync
upload_index: FAQ LICENSE CREDITS W/*.bat examples/*.bat examples/sync_loop_unix.sh index.shtml upload_index: FAQ LICENSE CREDITS TUTORIAL.html GOOD_PRACTICES.html W/*.bat examples/*.bat examples/sync_loop_unix.sh index.shtml
rcsdiff index.shtml FAQ LICENSE CREDITS W/*.bat examples/*.bat index.shtml rcsdiff index.shtml FAQ LICENSE CREDITS W/*.bat examples/*.bat index.shtml
validate --verbose index.shtml validate --verbose index.shtml
rsync -avH index.shtml FAQ NOLIMIT LICENSE CREDITS root@ks.lamiral.info:/var/www/imapsync/ rsync -avH index.shtml FAQ NOLIMIT LICENSE CREDITS TUTORIAL.html GOOD_PRACTICES.html root@ks.lamiral.info:/var/www/imapsync/
rsync -avH W/*.bat root@ks.lamiral.info:/var/www/imapsync/W/ rsync -avH W/*.bat root@ks.lamiral.info:/var/www/imapsync/W/
rsync -avH examples/*.bat examples/sync_loop_unix.sh root@ks.lamiral.info:/var/www/imapsync/examples/ rsync -avH examples/*.bat examples/sync_loop_unix.sh root@ks.lamiral.info:/var/www/imapsync/examples/

8
README
View file

@ -4,7 +4,7 @@ NAME
More than 52 different IMAP server softwares supported with success, few More than 52 different IMAP server softwares supported with success, few
failures. failures.
$Revision: 1.567 $ $Revision: 1.569 $
SYNOPSIS SYNOPSIS
To synchronize imap account "foo" on "imap.truc.org" to imap account To synchronize imap account "foo" on "imap.truc.org" to imap account
@ -317,7 +317,7 @@ IMAP SERVERS
- Hotmail since hotmail.com does not provide IMAP access - Hotmail since hotmail.com does not provide IMAP access
- Outlook.com since outlook.com does not provide IMAP access - Outlook.com since outlook.com does not provide IMAP access
Success stories reported with the following 55 imap servers (software Success stories reported with the following 57 imap servers (software
names are in alphabetic order): names are in alphabetic order):
- 1und1 H mimap1 84498 [host1] H mibap4 95231 [host1] - 1und1 H mimap1 84498 [host1] H mibap4 95231 [host1]
@ -354,6 +354,7 @@ IMAP SERVERS
- GMX IMAP4 StreamProxy. - GMX IMAP4 StreamProxy.
- Groupwise IMAP (Novell) 6.x and 7.0. Buggy so see the FAQ. - Groupwise IMAP (Novell) 6.x and 7.0. Buggy so see the FAQ.
- hMailServer 5.3.3 [host2], 4.4.1 [host1] (see FAQ) - hMailServer 5.3.3 [host2], 4.4.1 [host1] (see FAQ)
- IceWarp Server 10.4.5 [host1] (http://www.icewarp.com/)
- iPlanet Messaging server 4.15, 5.1, 5.2 - iPlanet Messaging server 4.15, 5.1, 5.2
- IMail 7.15 (Ipswitch/Win2003), 8.12, 11.03 [host1] - IMail 7.15 (Ipswitch/Win2003), 8.12, 11.03 [host1]
- Kerio 7.2.0 Patch 1 [host12], Kerio 8 [host1] - Kerio 7.2.0 Patch 1 [host12], Kerio 8 [host1]
@ -374,6 +375,7 @@ IMAP SERVERS
- OpenMail IMAP server B.07.00.k0 (Samsung Contact ?) - OpenMail IMAP server B.07.00.k0 (Samsung Contact ?)
- OpenWave - OpenWave
- Oracle Beehive [host1] - Oracle Beehive [host1]
- Parallels Plesk Panel 9.x [host2] 11.x [host2] (http://www.parallels.com/)
- Qualcomm Worldmail (NT) - Qualcomm Worldmail (NT)
- QQMail IMAP4Server [host1] [host2] https://en.mail.qq.com/ - QQMail IMAP4Server [host1] [host2] https://en.mail.qq.com/
- RackSpace hoster secure.emailsrvr.com:993 http://www.rackspace.com/ - RackSpace hoster secure.emailsrvr.com:993 http://www.rackspace.com/
@ -469,5 +471,5 @@ SIMILAR SOFTWARES
Feedback (good or bad) will often be welcome. Feedback (good or bad) will often be welcome.
$Id: imapsync,v 1.567 2013/09/18 20:38:10 gilles Exp gilles $ $Id: imapsync,v 1.569 2013/10/16 21:58:17 gilles Exp gilles $

View file

@ -1 +1 @@
1.567 1.569

View file

@ -1 +1 @@
1.567 1.569

View file

@ -246,3 +246,15 @@
1379550371 END 1.567 : jeudi 19 septembre 2013, 02:26:11 (UTC+0200) 1379550371 END 1.567 : jeudi 19 septembre 2013, 02:26:11 (UTC+0200)
1379803429 BEGIN 1.567 : dimanche 22 septembre 2013, 00:43:49 (UTC+0200) 1379803429 BEGIN 1.567 : dimanche 22 septembre 2013, 00:43:49 (UTC+0200)
1379804324 END 1.567 : dimanche 22 septembre 2013, 00:58:44 (UTC+0200) 1379804324 END 1.567 : dimanche 22 septembre 2013, 00:58:44 (UTC+0200)
1380337279 BEGIN 1.568 : samedi 28 septembre 2013, 05:01:20 (UTC+0200)
1380337867 END 1.568 : samedi 28 septembre 2013, 05:11:07 (UTC+0200)
1380340560 BEGIN 1.568 : samedi 28 septembre 2013, 05:56:00 (UTC+0200)
1380341166 END 1.568 : samedi 28 septembre 2013, 06:06:06 (UTC+0200)
1380369597 BEGIN 1.568 : samedi 28 septembre 2013, 13:59:57 (UTC+0200)
1380370230 END 1.568 : samedi 28 septembre 2013, 14:10:30 (UTC+0200)
1381964425 BEGIN 1.569 : jeudi 17 octobre 2013, 01:00:25 (UTC+0200)
1381964810 BEGIN 1.569 : jeudi 17 octobre 2013, 01:06:50 (UTC+0200)
1381969720 BEGIN 1.569 : jeudi 17 octobre 2013, 02:28:40 (UTC+0200)
1381970545 END 1.569 : jeudi 17 octobre 2013, 02:42:25 (UTC+0200)
1381974866 BEGIN 1.569 : jeudi 17 octobre 2013, 03:54:26 (UTC+0200)
1381975685 END 1.569 : jeudi 17 octobre 2013, 04:08:05 (UTC+0200)

View file

@ -5,6 +5,20 @@ Changes from 2.99_01 to 3.16 made by Mark Overmeer
Changes from 0.09 to 2.99_01 made by David Kernen Changes from 0.09 to 2.99_01 made by David Kernen
- Potential compatibility issues from 3.17+ highlighted with '*' - Potential compatibility issues from 3.17+ highlighted with '*'
version 3.34: Fri, Sep 27, 2013 12:50:17 AM
- make Makefile.PL use non-interactive and document test.txt usage
- new attribute: Socketargs => [ (IO::Socket::.. args) ]
+ cleanup connect() to more flexible with IO::Socket::* args
- untagged server data during send literal may cause client to hang
[Arthur Wolfe, Josh Hillman]
+ _send_line() needs '+' only to know it is OK to send LITERAL data
+ created _response_code_sub() to simplify _get_response()
- remove internal "Folders" cache
- Allow for RFC 6154 "IMAP LIST Extension for Special-Use Mailboxes"
[Mathias Reitinger]
+ new method: folders_hash()
+ deprecate: xlist_folders(), xlist()
version 3.33: Tue, May 14, 2013 10:12:43 AM version 3.33: Tue, May 14, 2013 10:12:43 AM
- more cleanup on use of $@ and $! - more cleanup on use of $@ and $!
- cleanup get_bodystructure / get_envelope - cleanup get_bodystructure / get_envelope

View file

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

View file

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

View file

@ -104,87 +104,35 @@ exit 0;
sub set_test_data { sub set_test_data {
unless ( -f "lib/Mail/IMAPClient.pm" ) { unless ( -f "lib/Mail/IMAPClient.pm" ) {
warn "ERROR: not in installation directory\n"; warn("ERROR: not in installation directory\n");
return; return;
} }
return if -s "./test.txt"; if ( -s "./test.txt" ) {
print("The file test.txt will be used for extended tests.\n");
print <<'__INTRO';
You have the option of running an extended suite of tests during
'make test'. This requires an IMAP server name, user account, and
password to test with.
Note: this prompt will automatically timeout after 60 seconds.
__INTRO
# HACK: alarm() allows broken interfaces to timeout gracefully...
# - rt.cpan.org#57659: install fails when using cPanel GUI
my $yes;
eval {
local $SIG{ALRM} = sub { die "alarm\n" };
alarm(60);
$yes = prompt "Do you want to run the extended tests? (n/y)";
alarm(0);
};
print "\n" if $@;
return unless ( $yes and $yes =~ /^y(?:es)?$/i );
unless ( open TST, '>', "./test.txt" ) {
warn "ERROR: couldn't open ./test.txt: $!\n";
return; return;
} }
my $server = ""; print <<EOF;
until ($server) {
$server =
prompt "\nPlease provide the hostname or IP address of "
. "a host running an\nIMAP server (or QUIT to skip "
. "the extended tests)";
chomp $server;
return if $server =~ /^\s*quit\s*$/i;
}
print TST "server=$server\n"; (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.
my $user = ""; Example:
until ($user) {
$user =
prompt "\nProvide the username of an account on $server (or QUIT)";
chomp $user;
return if $user =~ /^\s*quit\s*$/i;
}
print TST "user=$user\n";
my $passed = ""; --- BEGIN: test.txt ---
until ($passed) { server=localhost
$passed = prompt "\nProvide the password for $user (or QUIT)"; user=mytestuser
chomp $passed; passed=mypassword
return if $passed =~ /^\s+$|^quit$/i; port=143
} --- END: test.txt ---
print TST "passed=$passed\n"; NOTE: When testing is completed, be sure to remove test.txt (either by
hand or by 'make clean').
my $port = prompt "\nPlease provide the port to connect to on $server "
. "to run the test\n(default is 143)";
chomp $port;
$port ||= 143;
print TST "port=$port\n";
my $authmech = prompt "\nProvide the authentication mechanism to use "
. "on $server to\nrun the test (default is LOGIN)";
chomp $authmech;
$authmech ||= 'LOGIN';
print TST "authmechanism=$authmech\n";
close TST;
print <<'__THANKS';
The information you provided (including the password!) has been stored
in test.txt and SHOULD BE REMOVED (either by hand or by 'make clean')
after testing.
__THANKS
EOF
} }

View file

@ -41,13 +41,33 @@ INSTALLATION
perl Makefile.PL perl Makefile.PL
5. Build, test and install this module: 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
make test make test
(sudo) make install (sudo) make install
6. Read the documentation to become familiar with this module. 7. Read the documentation to become familiar with this module.
Project Links Project Links
============= =============

View file

View file

View file

@ -7,7 +7,7 @@ use strict;
use warnings; use warnings;
package Mail::IMAPClient; package Mail::IMAPClient;
our $VERSION = '3.33'; our $VERSION = '3.34';
use Mail::IMAPClient::MessageSet; use Mail::IMAPClient::MessageSet;
@ -48,7 +48,9 @@ my %SEARCH_KEYS = map { ( $_ => 1 ) } qw(
# modules require(d) during runtime when applicable # modules require(d) during runtime when applicable
my %Load_Module = ( my %Load_Module = (
"Compress-Zlib" => "Compress::Zlib", "Compress-Zlib" => "Compress::Zlib",
"INET" => "IO::Socket::INET",
"SSL" => "IO::Socket::SSL", "SSL" => "IO::Socket::SSL",
"UNIX" => "IO::Socket::UNIX",
"BodyStructure" => "Mail::IMAPClient::BodyStructure", "BodyStructure" => "Mail::IMAPClient::BodyStructure",
"Envelope" => "Mail::IMAPClient::BodyStructure::Envelope", "Envelope" => "Mail::IMAPClient::BodyStructure::Envelope",
"Thread" => "Mail::IMAPClient::Thread", "Thread" => "Mail::IMAPClient::Thread",
@ -92,8 +94,8 @@ BEGIN {
Debug Debug_fh Domain Folder Ignoresizeerrors Keepalive Debug Debug_fh Domain Folder Ignoresizeerrors Keepalive
Maxappendstringlength Maxcommandlength Maxtemperrors Maxappendstringlength Maxcommandlength Maxtemperrors
Password Peek Port Prewritemethod Proxy Ranges Readmethod Password Peek Port Prewritemethod Proxy Ranges Readmethod
Readmoremethod Reconnectretry Server Showcredentials Ssl Starttls Readmoremethod Reconnectretry Server Showcredentials
Supportedflags Timeout Uid User) Socketargs Ssl Starttls Supportedflags Timeout Uid User)
) )
{ {
no strict 'refs'; no strict 'refs';
@ -253,7 +255,7 @@ sub Transaction { shift->Count }
# remove doubles from list # remove doubles from list
sub _remove_doubles(@) { sub _remove_doubles(@) {
my %seen; my %seen;
grep { !$seen{$_}++ } @_; grep { !$seen{ $_->{name} }++ } @_;
} }
# the constructor: # the constructor:
@ -322,44 +324,43 @@ sub connect(@) {
# BUG? We should restrict which keys can be passed/set here. # BUG? We should restrict which keys can be passed/set here.
%$self = ( %$self, @_ ) if @_; %$self = ( %$self, @_ ) if @_;
my @sockargs = $self->Timeout ? ( Timeout => $self->Timeout ) : ();
push( @sockargs, $self->Debug ? ( Debug => $self->Debug ) : () );
# give caller control of IO::Socket::... args to new if desired
if ( $self->Socketargs and ref $self->Socketargs eq "ARRAY" ) {
push( @sockargs, @{ $self->Socketargs } );
}
my $server = $self->Server; my $server = $self->Server;
my $port = $self->Port || $self->Port( $self->Ssl ? "993" : "143" ); my $port = $self->Port || $self->Port( $self->Ssl ? "993" : "143" );
my @timeout = $self->Timeout ? ( Timeout => $self->Timeout ) : (); my ( $ioclass, $sock );
my $sock;
if ( File::Spec->file_name_is_absolute($server) ) { if ( File::Spec->file_name_is_absolute($server) ) {
$self->_debug("Connecting to unix socket $server @timeout"); $ioclass = $self->_load_module("UNIX");
$sock = IO::Socket::UNIX->new( unshift( @sockargs, Peer => $server );
Peer => $server,
Debug => $self->Debug,
@timeout
);
} }
else { else {
my $ioclass = "IO::Socket::INET"; unshift(
my @args; @sockargs,
PeerAddr => $server,
PeerPort => $port,
Proto => "tcp",
);
# extra control of SSL args is supported
if ( $self->Ssl ) { if ( $self->Ssl ) {
$ioclass = $self->_load_module("SSL"); $ioclass = $self->_load_module("SSL");
push( @sockargs, @{ $self->Ssl } ) if ref $self->Ssl eq "ARRAY";
# give caller control of args to new if desired }
@args = else {
( ref( $self->Ssl ) eq "ARRAY" ) $ioclass = $self->_load_module("INET");
? ( @{ $self->Ssl } ) }
: ();
} }
if ($ioclass) { if ($ioclass) {
$self->_debug("Connecting via $ioclass to $server:$port @timeout"); $self->_debug("Connecting with $ioclass @sockargs");
$sock = $ioclass->new( $sock = $ioclass->new(@sockargs);
PeerAddr => $server,
PeerPort => $port,
Proto => 'tcp',
Debug => $self->Debug,
@timeout,
@args
);
}
} }
if ($sock) { if ($sock) {
@ -668,6 +669,7 @@ sub _list_or_lsub {
sub list { shift->_list_or_lsub( "LIST", @_ ) } sub list { shift->_list_or_lsub( "LIST", @_ ) }
sub lsub { shift->_list_or_lsub( "LSUB", @_ ) } sub lsub { shift->_list_or_lsub( "LSUB", @_ ) }
# deprecated 3.34
sub xlist { sub xlist {
my ($self) = @_; my ($self) = @_;
return undef unless $self->has_capability("XLIST"); return undef unless $self->has_capability("XLIST");
@ -710,7 +712,7 @@ sub _folders_or_subscribed {
foreach my $resp (@list) { foreach my $resp (@list) {
my $rec = $self->_list_or_lsub_response_parse($resp); my $rec = $self->_list_or_lsub_response_parse($resp);
next unless defined $rec->{name}; next unless defined $rec->{name};
push @folders, $rec->{name}; push @folders, $rec;
} }
} }
}; };
@ -722,14 +724,19 @@ sub _folders_or_subscribed {
sub folders { sub folders {
my ( $self, $what ) = @_; my ( $self, $what ) = @_;
return wantarray ? @{ $self->{Folders} } : $self->{Folders} my @folders =
if !$what && $self->{Folders}; map( $_->{name}, $self->_folders_or_subscribed( "list", $what ) );
my @folders = $self->_folders_or_subscribed( "list", $what );
$self->{Folders} = \@folders unless $what;
return wantarray ? @folders : \@folders; return wantarray ? @folders : \@folders;
} }
sub folders_hash {
my ( $self, $what ) = @_;
my @folders_hash = $self->_folders_or_subscribed( "list", $what );
return wantarray ? @folders_hash : \@folders_hash;
}
# deprecated 3.34
sub xlist_folders { sub xlist_folders {
my ($self) = @_; my ($self) = @_;
my $xlist = $self->xlist; my $xlist = $self->xlist;
@ -751,7 +758,8 @@ sub xlist_folders {
sub subscribed { sub subscribed {
my ( $self, $what ) = @_; my ( $self, $what ) = @_;
my @folders = $self->_folders_or_subscribed( "lsub", $what ); my @folders =
map( $_->{name}, $self->_folders_or_subscribed( "lsub", $what ) );
return wantarray ? @folders : \@folders; return wantarray ? @folders : \@folders;
} }
@ -1328,6 +1336,44 @@ sub _imap_command_do {
} }
} }
sub _response_code_sub {
my ( $self, $tag, $good ) = @_;
# tag/good can be a ref (compiled regex) otherwise quote it
my $qtag = ref($tag) ? $tag : defined($tag) ? quotemeta($tag) : undef;
my $qgood = ref($good) ? $good : defined($good) ? quotemeta($good) : undef;
# using closure, a variable alias, and sub returns on first match
# - $_[0] is $o->[DATA]
# - returns list ( $code, $byemsg )
my $getcodesub = sub {
if ( defined $qgood ) {
if ( $good eq '+' and $_[0] =~ /^$qgood/ ) {
return ($good);
}
if ( defined $qtag and $_[0] =~ /^$qtag\s+($qgood)/i ) {
return ( ref($qgood) ? $1 : uc($1) );
}
}
if ( defined $qtag ) {
if ( $tag eq '+' and $_[0] =~ /^$qtag/ ) {
return ($tag);
}
if ( $_[0] =~ /^$qtag\s+(OK|BAD|NO)\b/i ) {
my $code = uc($1);
$self->LastError( $_[0] ) unless ( $code eq 'OK' );
return ($code);
}
}
if ( $_[0] =~ /^\*\s+(BYE)\b/i ) {
return ( uc($1), $_[0] ); # ( 'BYE', $byemsg )
}
return (undef);
};
return $getcodesub;
}
# _get_response get IMAP response optionally send data somewhere # _get_response get IMAP response optionally send data somewhere
# options: # options:
# outref => GLOB|CODE - reference to send output to (see _read_line) # outref => GLOB|CODE - reference to send output to (see _read_line)
@ -1337,15 +1383,12 @@ sub _get_response {
my $tag = shift; my $tag = shift;
my $good = shift; my $good = shift;
# tag can be a ref (compiled regex) or we quote it or default to \S+
my $qtag = ref($tag) ? $tag : defined($tag) ? quotemeta($tag) : qr/\S+/;
my $qgood = ref($good) ? $good : defined($good) ? quotemeta($good) : undef;
my $outref = $opt->{outref}; my $outref = $opt->{outref};
my @readopt = defined($outref) ? ($outref) : (); my @readopt = defined($outref) ? ($outref) : ();
my $getcode = $self->_response_code_sub( $tag, $good );
my ( $count, $out, $code, $byemsg ) = ( $self->Count, [], undef, undef ); my ( $count, $out, $code, $byemsg ) = ( $self->Count, [], undef, undef );
until ( defined($code) ) { until ( defined $code ) {
my $output = $self->_read_line(@readopt) or return undef; my $output = $self->_read_line(@readopt) or return undef;
$out = $output; # keep last response just in case $out = $output; # keep last response just in case
@ -1354,30 +1397,13 @@ sub _get_response {
foreach my $o (@$output) { foreach my $o (@$output) {
$self->_record( $count, $o ); $self->_record( $count, $o );
$self->_is_output($o) or next; $self->_is_output($o) or next;
my ( $tcode, $tbyemsg ) = $getcode->( $o->[DATA] );
my $data = $o->[DATA]; $code = $tcode if ( defined $tcode );
if ( $good and $good ne '+' and $data =~ /^$qtag\s+($qgood)/i ) { $byemsg = $tbyemsg if ( defined $tbyemsg );
$code = $1;
$code = uc($code) unless ref($good);
}
elsif ( $good and $good eq '+' and $data =~ /^$qgood/ ) {
$code = $good;
}
elsif ( $tag eq '+' and $data =~ /^$qtag/ ) {
$code = $tag;
}
elsif ( $data =~ /^$qtag\s+(OK|BAD|NO)\b/i ) {
$code = uc($1);
$self->LastError($data) unless ( $code eq 'OK' );
}
elsif ( $data =~ /^\*\s+(BYE)\b/i ) {
$code = uc($1);
$byemsg = $data;
}
} }
} }
if ( defined($code) ) { if ( defined $code ) {
$code =~ s/$CR?$LF?$//o; $code =~ s/$CR?$LF?$//o;
$code = uc($code) unless ( $good and $code eq $good ); $code = uc($code) unless ( $good and $code eq $good );
@ -1452,8 +1478,8 @@ sub _send_line {
$self->_debug("Sending literal: $first\tthen: $string"); $self->_debug("Sending literal: $first\tthen: $string");
$self->_send_line($first) or return undef; $self->_send_line($first) or return undef;
# look for "<anything> OK|NO|BAD" or "+..." # look for "+..."
my $code = $self->_get_response( qr(\S+), '+' ) or return undef; my $code = $self->_get_response('+') or return undef;
return undef unless $code eq '+'; return undef unless $code eq '+';
} }
@ -1898,7 +1924,6 @@ sub _disconnect {
my $self = shift; my $self = shift;
delete $self->{CAPABILITY}; delete $self->{CAPABILITY};
delete $self->{Folders};
delete $self->{_IMAP4REV1}; delete $self->{_IMAP4REV1};
$self->State(Unconnected); $self->State(Unconnected);
if ( my $sock = delete $self->{Socket} ) { if ( my $sock = delete $self->{Socket} ) {
@ -2270,7 +2295,6 @@ sub fetch_hash {
sub store { sub store {
my ( $self, @a ) = @_; my ( $self, @a ) = @_;
delete $self->{Folders};
$self->_imap_uid_command( STORE => @a ) $self->_imap_uid_command( STORE => @a )
or return undef; or return undef;
return wantarray ? $self->History : $self->Results; return wantarray ? $self->History : $self->Results;
@ -2278,7 +2302,6 @@ sub store {
sub _imap_folder_command($$@) { sub _imap_folder_command($$@) {
my ( $self, $command ) = ( shift, shift ); my ( $self, $command ) = ( shift, shift );
delete $self->{Folders};
my $folder = $self->Massage(shift); my $folder = $self->Massage(shift);
$self->_imap_command( join ' ', $command, $folder, @_ ) $self->_imap_command( join ' ', $command, $folder, @_ )
@ -2303,7 +2326,6 @@ sub myrights($) { $_[0]->_imap_folder_command( MYRIGHTS => $_[1] ) }
sub close { sub close {
my $self = shift; my $self = shift;
delete $self->{Folders};
$self->_imap_command('CLOSE') $self->_imap_command('CLOSE')
or return undef; or return undef;
return wantarray ? $self->History : $self->Results; return wantarray ? $self->History : $self->Results;

View file

@ -1154,7 +1154,7 @@ The B<folders> method returns an array listing the available folders.
It will only be successful if the object is in the I<Authenticated> or It will only be successful if the object is in the I<Authenticated> or
I<Selected> states. I<Selected> states.
The B<folders> argument accepts one optional argument, which is a The B<folders> method accepts one optional argument, which is a
prefix. If a prefix is supplied to the B<folders> method, then only prefix. If a prefix is supplied to the B<folders> method, then only
folders beginning with the prefix will be returned. folders beginning with the prefix will be returned.
@ -1177,7 +1177,41 @@ the L</separator> method). However, this does not match the behavior
of the existing implementation, so you will need to manually exclude of the existing implementation, so you will need to manually exclude
the parent folder from the results. the parent folder from the results.
=head2 xlist_folders =head2 folders_hash
my @fhashes = $imap->folders_hash
or die "Could not get list of folder hashes.\n";
The B<folders_hash> method accepts one optional argument, which is a
prefix. If a prefix is supplied to the B<folders_hash> method, then
only folders beginning with the prefix will be returned.
An array(ref) of hashes is returned that contain information about the
requested folders. Each hash contains three keys (name, attrs, delim)
and looks like the following:
{
name => 'Mail/Box/Name',
attrs => '\Marked \HasNoChildren',
delim => '/',
}
IMAP servers implementing RFC6154 return attributes to be used to
identify special-use mailboxes (folders).
my $sattr_re = /\b\\(?:All|Archive|Drafts|Flagged|Junk|Sent|Trash)\b/;
foreach my $fhash (@fhashes) {
next unless ( $fhash->{attrs} =~ $sattr_re );
print("special: $fhash->{name} : $fhash->{attrs}\n");
}
Version note: method added in Mail::IMAPClient 3.34
=head2 xlist_folders (DEPRECATED)
This method is deprecated as of version 3.34. Please use folders_hash
instead. See RFC6154 for attributes to be used to identify
special-use mailboxes (folders).
Example: Example:
@ -3454,6 +3488,23 @@ containing the desired arguments.
Version note: attribute added in Mail::IMAPClient 3.22 Version note: attribute added in Mail::IMAPClient 3.22
=head2 Socketargs
The arguments used in the call to IO::Socket::{UNIX|INET|SSL}->new can
be controlled by setting this attribute to an ARRAY reference
containing the desired arguments.
For example, to always pass MultiHomed => 1 to IO::Socket::...->new
the following can be used:
$imap = Mail::IMAPClient->new(
..., Socketargs => [ MultiHomed => 1 ], ...
);
See also L</Ssl> for specific control of the args to IO::Socket::SSL.
Version note: attribute added in Mail::IMAPClient 3.34
=head2 Ssl =head2 Ssl
If an IMAP connection requires SSL you can set the Ssl attribute to If an IMAP connection requires SSL you can set the Ssl attribute to

View file

View file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

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

View file

@ -0,0 +1,189 @@
# 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} }

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
=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

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

View file

@ -0,0 +1,18 @@
# 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

@ -0,0 +1,14 @@
=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

View file

@ -33,7 +33,7 @@ BEGIN {
@missing @missing
? plan skip_all => "missing value for: @missing" ? plan skip_all => "missing value for: @missing"
: plan tests => 85; : plan tests => 88;
} }
BEGIN { use_ok('Mail::IMAPClient') or exit; } BEGIN { use_ok('Mail::IMAPClient') or exit; }
@ -56,7 +56,7 @@ my %new_args = (
my $imap = Mail::IMAPClient->new( my $imap = Mail::IMAPClient->new(
%new_args, %new_args,
Range => $range, Range => $range,
Debug_fh => ( $debug ? IO::File->new( 'imap1.debug', 'w' ) : undef ) Debug_fh => ( $debug ? IO::File->new( 'imap1.debug', 'w' ) : undef ),
); );
ok( defined $imap, 'created client' ); ok( defined $imap, 'created client' );
@ -102,6 +102,16 @@ ok( defined $ispar, "INBOX is_parent '$ispar' (note: target '$target')" );
ok( $imap->select('inbox'), "select inbox" ); 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 # test append_file
my $append_file_size; my $append_file_size;
{ {

View file

@ -41,7 +41,8 @@ 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 2627 /g/paypal/paypal_2013_06_complet.csv #/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 2627 /g/paypal/paypal_2013_06_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 2682 /g/paypal/paypal_2013_07_complet.csv #/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 2682 /g/paypal/paypal_2013_07_complet.csv
#/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 2741 /g/paypal/paypal_2013_08_complet.csv #/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 2741 /g/paypal/paypal_2013_08_complet.csv
/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 2820 /g/paypal/paypal_2013_09_complet.csv #/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 2820 /g/paypal/paypal_2013_09_complet.csv
/g/public_html/imapsync/W/paypal_reply/paypal_bilan --write_invoices --first_in 2891 /g/paypal/paypal_2013_10_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --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
@ -80,6 +81,7 @@ cp /home/gilles/public_html/AGIL/factures/000/facture_imapsync-000.tex /g/var/pa
set -x set -x
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 2820 /g/paypal/paypal_2013_09_complet.csv : /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 2820 /g/paypal/paypal_2013_09_complet.csv
: /g/public_html/imapsync/W/paypal_reply/paypal_bilan --first_in 2891 /g/paypal/paypal_2013_10_complet.csv
set +x set +x
# La totale # La totale

View file

@ -2,8 +2,17 @@
cd /D %~dp0 cd /D %~dp0
.\imapsync.exe --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi --ssl1 --ssl2 --delete2 --folder INBOX --usecache --tmpdir "E:\\temp" REM E:
REM cd .\temp
REM cd \
imapsync.exe --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi --usecache --tmpdir "E:\TEMP" --include "blanc"
REM perl imapsync --tests_debug
perl imapsync --tests
PAUSE
perl imapsync --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi --usecache --tmpdir "E:\TEMP"
REM perl imapsync --host1 p --user1 tata --passfile1 secret.tata --host2 p --user2 titi --passfile2 secret.titi --usecache
REM rmdir "E:\TEMP\imapsync_cache" /s /q

View file

@ -1,5 +1,5 @@
REM $Id: build_exe.bat,v 1.20 2013/09/21 21:56:14 gilles Exp gilles $ REM $Id: build_exe.bat,v 1.21 2013/10/17 00:54:53 gilles Exp gilles $
@ECHO OFF @ECHO OFF
ECHO Building imapsync.exe ECHO Building imapsync.exe
@ -12,7 +12,7 @@ perl -mMail::IMAPClient -mIO::Socket -mIO::Socket::SSL -mIO::Socket::IP ^
-mDigest::MD5 -mDigest::HMAC_MD5 -mDigest::HMAC_SHA1 ^ -mDigest::MD5 -mDigest::HMAC_MD5 -mDigest::HMAC_SHA1 ^
-mTerm::ReadKey -mFile::Spec -mAuthen::NTLM ^ -mTerm::ReadKey -mFile::Spec -mAuthen::NTLM ^
-mTime::Local -mURI::Escape -mData::Uniqid ^ -mTime::Local -mURI::Escape -mData::Uniqid ^
-e '' -mFile::Copy::Recursive -e ''
cd cd
@ECHO ON @ECHO ON
@ -23,7 +23,7 @@ pp -o imapsync.exe ^
-M Digest::MD5 -M Digest::HMAC_MD5 -M Digest::HMAC_SHA1 ^ -M Digest::MD5 -M Digest::HMAC_MD5 -M Digest::HMAC_SHA1 ^
-M Term::ReadKey -M Authen::NTLM ^ -M Term::ReadKey -M Authen::NTLM ^
-M Time::Local -M URI::Escape -M Data::Uniqid ^ -M Time::Local -M URI::Escape -M Data::Uniqid ^
^ -M File::Copy::Recursive ^
imapsync imapsync
echo Done building imapsync.exe echo Done building imapsync.exe

View file

@ -1,5 +1,5 @@
REM $Id: install_modules.bat,v 1.8 2013/09/19 10:34:33 gilles Exp gilles $ REM $Id: install_modules.bat,v 1.9 2013/10/17 01:50:42 gilles Exp gilles $
@ECHO OFF @ECHO OFF
@ -12,19 +12,27 @@ IF ERRORLEVEL 1 ECHO Perl needed. Install Strawberry Perl. Get it at http://stra
REM perl is there REM perl is there
FOR %%M in ( Test::Pod ^ FOR %%M in ( Mail::IMAPClient ^
IO::Socket::INET IO::Socket::INET6 IO::Socket::IP ^ File::Copy::Recursive ^
PAR::Packer ^
Test::Pod ^
IO::Socket::INET ^
IO::Socket::INET6 ^
IO::Socket::IP ^
Net::SSLeay ^ Net::SSLeay ^
Crypt::SSLeay Net::SSL IO::Socket::SSL ^ Crypt::SSLeay ^
Digest::MD5 Digest::HMAC_MD5 ^ Net::SSL IO::Socket::SSL ^
Term::ReadKey File::Spec ^ Digest::MD5 ^
Digest::HMAC_MD5 ^
Term::ReadKey ^
File::Spec ^
Time::HiRes ^ Time::HiRes ^
Data::Uniqid URI::Escape ^ Data::Uniqid URI::Escape ^
Authen::NTLM ^ Authen::NTLM ^
Time::Local ^ Time::Local ^
Mail::IMAPClient ^ Getopt::ArgvFile ^
Getopt::ArgvFile Module::ScanDeps ^ Module::ScanDeps ^
PAR::Packer ) DO ECHO Updating %%M ^ ) DO ECHO Updating %%M ^
& perl -MCPAN -e "install %%M" & perl -MCPAN -e "install %%M"
REM & perl -m%%M -e "" || perl -MCPAN -e "install %%M" REM & perl -m%%M -e "" || perl -MCPAN -e "install %%M"

4
i3
View file

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

182
imapsync
View file

@ -22,7 +22,7 @@ Synchronises mailboxes between two imap servers.
Good at IMAP migration. More than 52 different IMAP server softwares Good at IMAP migration. More than 52 different IMAP server softwares
supported with success, few failures. supported with success, few failures.
$Revision: 1.567 $ $Revision: 1.569 $
=head1 SYNOPSIS =head1 SYNOPSIS
@ -367,7 +367,7 @@ Failure stories reported with the following 3 imap servers:
- Hotmail since hotmail.com does not provide IMAP access - Hotmail since hotmail.com does not provide IMAP access
- Outlook.com since outlook.com does not provide IMAP access - Outlook.com since outlook.com does not provide IMAP access
Success stories reported with the following 55 imap servers Success stories reported with the following 57 imap servers
(software names are in alphabetic order): (software names are in alphabetic order):
- 1und1 H mimap1 84498 [host1] H mibap4 95231 [host1] - 1und1 H mimap1 84498 [host1] H mibap4 95231 [host1]
@ -404,6 +404,7 @@ Success stories reported with the following 55 imap servers
- GMX IMAP4 StreamProxy. - GMX IMAP4 StreamProxy.
- Groupwise IMAP (Novell) 6.x and 7.0. Buggy so see the FAQ. - Groupwise IMAP (Novell) 6.x and 7.0. Buggy so see the FAQ.
- hMailServer 5.3.3 [host2], 4.4.1 [host1] (see FAQ) - hMailServer 5.3.3 [host2], 4.4.1 [host1] (see FAQ)
- IceWarp Server 10.4.5 [host1] (http://www.icewarp.com/)
- iPlanet Messaging server 4.15, 5.1, 5.2 - iPlanet Messaging server 4.15, 5.1, 5.2
- IMail 7.15 (Ipswitch/Win2003), 8.12, 11.03 [host1] - IMail 7.15 (Ipswitch/Win2003), 8.12, 11.03 [host1]
- Kerio 7.2.0 Patch 1 [host12], Kerio 8 [host1] - Kerio 7.2.0 Patch 1 [host12], Kerio 8 [host1]
@ -424,6 +425,7 @@ Success stories reported with the following 55 imap servers
- OpenMail IMAP server B.07.00.k0 (Samsung Contact ?) - OpenMail IMAP server B.07.00.k0 (Samsung Contact ?)
- OpenWave - OpenWave
- Oracle Beehive [host1] - Oracle Beehive [host1]
- Parallels Plesk Panel 9.x [host2] 11.x [host2] (http://www.parallels.com/)
- Qualcomm Worldmail (NT) - Qualcomm Worldmail (NT)
- QQMail IMAP4Server [host1] [host2] https://en.mail.qq.com/ - QQMail IMAP4Server [host1] [host2] https://en.mail.qq.com/
- RackSpace hoster secure.emailsrvr.com:993 http://www.rackspace.com/ - RackSpace hoster secure.emailsrvr.com:993 http://www.rackspace.com/
@ -539,34 +541,35 @@ Entries for imapsync:
Feedback (good or bad) will often be welcome. Feedback (good or bad) will often be welcome.
$Id: imapsync,v 1.567 2013/09/18 20:38:10 gilles Exp gilles $ $Id: imapsync,v 1.569 2013/10/16 21:58:17 gilles Exp gilles $
=cut =cut
# pragmas # pragmas
use strict; use strict ;
use warnings; use warnings ;
++$|; ++$| ;
use Carp; use Carp ;
use Getopt::Long; use Getopt::Long ;
use Mail::IMAPClient 3.29 ; use Mail::IMAPClient 3.29 ;
use Digest::MD5 qw( md5 md5_hex md5_base64 ); use Digest::MD5 qw( md5 md5_hex md5_base64 ) ;
use Digest::HMAC_SHA1 qw( hmac_sha1 ) ; use Digest::HMAC_SHA1 qw( hmac_sha1 ) ;
#use Term::ReadKey; #use Term::ReadKey ;
#use IO::Socket::SSL; #use IO::Socket::SSL ;
use MIME::Base64; use MIME::Base64 ;
use English '-no_match_vars' ; use English '-no_match_vars' ;
use File::Basename; use File::Basename ;
use POSIX qw(uname SIGALRM); use POSIX qw(uname SIGALRM) ;
use Fcntl; use Fcntl ;
use File::Spec; use File::Spec ;
use File::Path qw(mkpath rmtree); use File::Path qw( mkpath rmtree ) ;
use IO::Socket qw(:crlf SOL_SOCKET SO_KEEPALIVE); use File::Copy::Recursive ;
use Errno qw(EAGAIN EPIPE ECONNRESET); use IO::Socket qw(:crlf SOL_SOCKET SO_KEEPALIVE) ;
use Errno qw(EAGAIN EPIPE ECONNRESET) ;
use File::Glob qw( :glob ) ; use File::Glob qw( :glob ) ;
use IO::File; use IO::File ;
use Time::Local ; use Time::Local ;
use Time::HiRes qw( time ) ; use Time::HiRes qw( time ) ;
use Test::More 'no_plan' ; use Test::More 'no_plan' ;
@ -661,13 +664,14 @@ my(
$fixInboxINBOX, $fixInboxINBOX,
$maxlinelength, $maxlinelength,
$uidnext_default, $uidnext_default,
$fixcolonbug,
); );
# main program # main program
# global variables initialisation # global variables initialisation
$rcs = '$Id: imapsync,v 1.567 2013/09/18 20:38:10 gilles Exp gilles $ '; $rcs = '$Id: imapsync,v 1.569 2013/10/16 21:58:17 gilles Exp gilles $ ';
$total_bytes_transferred = 0; $total_bytes_transferred = 0;
$total_bytes_skipped = 0; $total_bytes_skipped = 0;
@ -787,15 +791,19 @@ print banner_imapsync(@argv_copy);
print "Temp directory is $tmpdir\n"; print "Temp directory is $tmpdir\n";
is_valid_directory($tmpdir); is_valid_directory( $tmpdir ) ;
write_pidfile($pidfile) if ($pidfile); write_pidfile( $pidfile ) if ( $pidfile ) ;
$fixcolonbug = defined( $fixcolonbug ) ? $fixcolonbug : 1 ;
if ( $usecache and $fixcolonbug ) { tmpdir_fix_colon_bug( ) } ;
$modules_version and print "Modules version list:\n", modules_VERSION(), "\n"; $modules_version and print "Modules version list:\n", modules_VERSION(), "\n";
check_lib_version() or check_lib_version() or
croak "imapsync needs perl lib Mail::IMAPClient release 3.25 or superior \n"; croak "imapsync needs perl lib Mail::IMAPClient release 3.25 or superior \n";
exit_clean(0) if ($justbanner); exit_clean( 0 ) if ( $justbanner ) ;
# By default, 100 at a time, not more. # By default, 100 at a time, not more.
$split1 ||= 100; $split1 ||= 100;
@ -1256,8 +1264,8 @@ FOLDER: foreach my $h1_fold ( @h1_folders_wanted ) {
( $debug or $debugLIST ) and print "Host2 LIST: $h2_msgs_nb messages [@h2_msgs]\n"; ( $debug or $debugLIST ) and print "Host2 LIST: $h2_msgs_nb messages [@h2_msgs]\n";
$debug and print "Host2 selecting messages of folder [$h2_fold] took ", timenext(), " s\n"; $debug and print "Host2 selecting messages of folder [$h2_fold] took ", timenext(), " s\n";
my $cache_base = "$tmpdir/imapsync_cache/$host1/$user1/$host2/$user2" ; my $cache_base = "$tmpdir/imapsync_cache/" ;
my $cache_dir = cache_folder( $cache_base, $h1_fold, $h2_fold ) ; my $cache_dir = cache_folder( $cache_base, "$host1/$user1/$host2/$user2", $h1_fold, $h2_fold ) ;
my ( $cache_1_2_ref, $cache_2_1_ref ) = ( {}, {} ) ; my ( $cache_1_2_ref, $cache_2_1_ref ) = ( {}, {} ) ;
my $h1_uidvalidity = $imap1->uidvalidity( ) || '' ; my $h1_uidvalidity = $imap1->uidvalidity( ) || '' ;
@ -1700,7 +1708,7 @@ sub sync_flags_after_copy {
my @h2_flags = $imap2->flags( $h2_msg ) ; my @h2_flags = $imap2->flags( $h2_msg ) ;
my $h2_flags = "@h2_flags" ; my $h2_flags = "@h2_flags" ;
print "FLAGS $h2_msg: $h2_flags\n" ; ( $debug or $debugflags ) and print "Host2 flags before resync by STORE on msg $h2_msg: $h2_flags\n" ;
sync_flags( $h1_fold, $h1_msg, $h1_flags, $h2_fold, $h2_msg, $h2_flags, $permanentflags2 ) ; sync_flags( $h1_fold, $h1_msg, $h1_flags, $h2_fold, $h2_msg, $h2_flags, $permanentflags2 ) ;
return( ) ; return( ) ;
} }
@ -2265,8 +2273,8 @@ sub banner_imapsync {
my @argv = @_ ; my @argv = @_ ;
my $banner_imapsync = join("", my $banner_imapsync = join("",
'$RCSfile: imapsync,v $ ', '$RCSfile: imapsync,v $ ',
'$Revision: 1.567 $ ', '$Revision: 1.569 $ ',
'$Date: 2013/09/18 20:38:10 $ ', '$Date: 2013/10/16 21:58:17 $ ',
"\n",localhost_info(), "\n", "\n",localhost_info(), "\n",
"Command line used:\n", "Command line used:\n",
"$0 ", command_line_nopassword( @argv ), "\n", "$0 ", command_line_nopassword( @argv ), "\n",
@ -4090,16 +4098,91 @@ sub touch {
return( ! $failures ); return( ! $failures );
} }
sub tests_tmpdir_has_colon_bug {
ok( 0 == tmpdir_has_colon_bug( '' ), 'tmpdir_has_colon_bug: ' ) ;
ok( 0 == tmpdir_has_colon_bug( '/tmp' ), 'tmpdir_has_colon_bug: /tmp' ) ;
ok( 1 == tmpdir_has_colon_bug( 'C:' ), 'tmpdir_has_colon_bug: C:' ) ;
ok( 1 == tmpdir_has_colon_bug( 'C:\temp' ), 'tmpdir_has_colon_bug: C:\temp' ) ;
return( 0 ) ;
}
sub tmpdir_has_colon_bug {
my $path = shift ;
my $path_filtered = filter_forbidden_characters( $path ) ;
if ( $path_filtered ne $path ) {
( -d $path_filtered ) and print "Path $path was previously mistakely changed to $path_filtered\n" ;
return( 1 ) ;
}
return( 0 ) ;
}
sub tmpdir_fix_colon_bug {
my $err = 0 ;
if ( not (-d $tmpdir and -r _ and -w _) ) {
print "tmpdir $tmpdir is not valid\n" ;
return( 0 ) ;
}
my $cachedir_new = "$tmpdir/imapsync_cache" ;
if ( not tmpdir_has_colon_bug( $cachedir_new ) ) { return( 0 ) } ;
# check if old cache directory already exists
my $cachedir_old = filter_forbidden_characters( $cachedir_new ) ;
if ( not ( -d $cachedir_old ) ) {
print "Old cache directory $cachedir_new no exists, nothing to do\n" ;
return( 1 ) ;
}
# check if new cache directory already exists
if ( -d $cachedir_new ) {
print "New fixed cache directory $cachedir_new already exists, not moving the old one $cachedir_old. Fix this manually.\n" ;
return( 0 ) ;
}else{
# move the old one to the new place
print "Moving $cachedir_old to $cachedir_new Do not interrupt this task.\n" ;
File::Copy::Recursive::rmove( $cachedir_old, $cachedir_new )
or do {
print "Could not move $cachedir_old to $cachedir_new\n" ;
$err++ ;
} ;
# check it succeeded
if ( -d $cachedir_new and -r _ and -w _ ) {
print "New fixed cache directory $cachedir_new ok\n" ;
}else{
print "New fixed cache directory $cachedir_new does not exist\n" ;
$err++ ;
}
if ( -d $cachedir_old ) {
print "Old cache directory $cachedir_old still exists\n" ;
$err++ ;
}else{
print "Old cache directory $cachedir_old successfuly moved\n" ;
}
}
return( not $err ) ;
}
sub tests_cache_folder { sub tests_cache_folder {
ok( '/path/fold1/fold2' eq cache_folder( '/path', 'fold1', 'fold2'), 'cache_folder: /path, fold1, fold2 -> /path/fold1/fold2' ) ; ok( '/path/fold1/fold2' eq cache_folder( '', '/path', 'fold1', 'fold2'), 'cache_folder: /path, fold1, fold2 -> /path/fold1/fold2' ) ;
ok( '/pa_th/fold1/fold2' eq cache_folder( '/pa*th', 'fold1', 'fold2'), 'cache_folder: /pa*th, fold1, fold2 -> /path/fold1/fold2' ) ; ok( '/pa_th/fold1/fold2' eq cache_folder( '', '/pa*th', 'fold1', 'fold2'), 'cache_folder: /pa*th, fold1, fold2 -> /path/fold1/fold2' ) ;
ok( '/_p_a__th/fol_d1/fold2' eq cache_folder( '/>p<a|*th', 'fol*d1', 'fold2'), 'cache_folder: />p<a|*th, fol*d1, fold2 -> /path/fol_d1/fold2' ) ; ok( '/_p_a__th/fol_d1/fold2' eq cache_folder( '', '/>p<a|*th', 'fol*d1', 'fold2'), 'cache_folder: />p<a|*th, fol*d1, fold2 -> /path/fol_d1/fold2' ) ;
ok( 'D:/path/fold1/fold2' eq cache_folder( 'D:', '/path', 'fold1', 'fold2'), 'cache_folder: /path, fold1, fold2 -> /path/fold1/fold2' ) ;
ok( 'D:/pa_th/fold1/fold2' eq cache_folder( 'D:', '/pa*th', 'fold1', 'fold2'), 'cache_folder: /pa*th, fold1, fold2 -> /path/fold1/fold2' ) ;
ok( 'D:/_p_a__th/fol_d1/fold2' eq cache_folder( 'D:', '/>p<a|*th', 'fol*d1', 'fold2'), 'cache_folder: />p<a|*th, fol*d1, fold2 -> /path/fol_d1/fold2' ) ;
return( ) ; return( ) ;
} }
sub cache_folder { sub cache_folder {
my( $cache_dir, $h1_fold, $h2_fold ) = @_ ; my( $cache_base, $cache_dir, $h1_fold, $h2_fold ) = @_ ;
my $sep_1 = $h1_sep || '/'; my $sep_1 = $h1_sep || '/';
my $sep_2 = $h2_sep || '/'; my $sep_2 = $h2_sep || '/';
@ -4108,8 +4191,7 @@ sub cache_folder {
$h1_fold = convert_sep_to_slash( $h1_fold, $sep_1 ) ; $h1_fold = convert_sep_to_slash( $h1_fold, $sep_1 ) ;
$h2_fold = convert_sep_to_slash( $h2_fold, $sep_2 ) ; $h2_fold = convert_sep_to_slash( $h2_fold, $sep_2 ) ;
my $cache_folder = "$cache_dir/$h1_fold/$h2_fold" ; my $cache_folder = "$cache_base" . filter_forbidden_characters( "$cache_dir/$h1_fold/$h2_fold" ) ;
$cache_folder = filter_forbidden_characters( $cache_folder ) ;
#print "cache_folder [$cache_folder]\n" ; #print "cache_folder [$cache_folder]\n" ;
return( $cache_folder ) ; return( $cache_folder ) ;
} }
@ -4117,17 +4199,28 @@ sub cache_folder {
sub filter_forbidden_characters { sub filter_forbidden_characters {
my $string = shift ; my $string = shift ;
if ( 'MSWin32' eq $OSNAME ) {
# Move trailing whitespace to _ " a b /c d " -> " a b_/c d_"
$string =~ s{\ (/|$)}{_$1}xg ;
}
$string =~ s{[\Q*|?:"<>\E]}{_}xg ; $string =~ s{[\Q*|?:"<>\E]}{_}xg ;
#print "[$string]\n" ;
return ( $string ) ; return ( $string ) ;
} }
sub tests_filter_forbidden_characters { sub tests_filter_forbidden_characters {
ok( 'a_b' eq filter_forbidden_characters( 'a_b' ), 'filter_forbidden_characters: a_b -> a_b' ) ; ok( 'a_b' eq filter_forbidden_characters( 'a_b' ), 'filter_forbidden_characters: a_b -> a_b' ) ;
ok( 'a_b' eq filter_forbidden_characters( 'a*b' ), 'filter_forbidden_characters: a*b -> a_b' ); ok( 'a_b' eq filter_forbidden_characters( 'a*b' ), 'filter_forbidden_characters: a*b -> a_b' ) ;
ok( 'a_b' eq filter_forbidden_characters( 'a|b' ), 'filter_forbidden_characters: a|b -> a_b' ); ok( 'a_b' eq filter_forbidden_characters( 'a|b' ), 'filter_forbidden_characters: a|b -> a_b' ) ;
ok( 'a_b' eq filter_forbidden_characters( 'a?b' ), 'filter_forbidden_characters: a?*b -> a_b' ); ok( 'a_b' eq filter_forbidden_characters( 'a?b' ), 'filter_forbidden_characters: a?b -> a_b' ) ;
ok( 'a_______b' eq filter_forbidden_characters( 'a*|?:"<>b' ), 'filter_forbidden_characters: a*|?:"<>b -> a_______b' ); ok( 'a_______b' eq filter_forbidden_characters( 'a*|?:"<>b' ), 'filter_forbidden_characters: a*|?:"<>b -> a_______b' ) ;
( 'MSWin32' ne $OSNAME ) and ok( ( 'a b ' eq filter_forbidden_characters( 'a b ' ) ), 'filter_forbidden_characters: "a b " -> "a b "' ) ;
( 'MSWin32' eq $OSNAME ) and ok( ( ' a b_' eq filter_forbidden_characters( ' a b ' ) ), 'filter_forbidden_characters: "a b " -> "a b_"' ) ;
( 'MSWin32' eq $OSNAME ) and ok( ( ' a b_/ c d_' eq filter_forbidden_characters( ' a b / c d ' ) ), 'filter_forbidden_characters: " a b / c d " -> "a b_/ c d_"' ) ;
return( ) ; return( ) ;
} }
@ -4659,7 +4752,7 @@ sub check_last_release {
} }
sub imapsync_version { sub imapsync_version {
my $rcs_imapsync = '$Id: imapsync,v 1.567 2013/09/18 20:38:10 gilles Exp gilles $ ' ; my $rcs_imapsync = '$Id: imapsync,v 1.569 2013/10/16 21:58:17 gilles Exp gilles $ ' ;
my $imapsync_version ; my $imapsync_version ;
if ( $rcs_imapsync =~ m{,v\s+(\d+\.\d+)}xo ) { if ( $rcs_imapsync =~ m{,v\s+(\d+\.\d+)}xo ) {
@ -5512,8 +5605,9 @@ Several options are mandatory.
For safety, first try it like this (it is safe): For safety, first try it like this (it is safe):
--delete2folders --dry --justfolders --nofoldersizes --delete2folders --dry --justfolders --nofoldersizes
--delete2foldersonly <regex>: Deleted only folders matching regex. --delete2foldersonly <regex>: Deleted only folders matching regex.
Example: --delete2foldersonly "/Junk$/"
--delete2foldersbutnot <regex>: Do not delete folders matching regex. --delete2foldersbutnot <regex>: Do not delete folders matching regex.
Example: --delete2foldersbutnot "/Tasks|Contacts|Foo/" Example: --delete2foldersbutnot "/Tasks$|Contacts$|Foo$/"
--noexpunge : Do not expunge messages on host1. --noexpunge : Do not expunge messages on host1.
Expunge really deletes messages marked deleted. Expunge really deletes messages marked deleted.
Expunge is made at the beginning, on host1 only. Expunge is made at the beginning, on host1 only.
@ -5779,6 +5873,7 @@ sub get_options {
"abletosearch!" => \$abletosearch, "abletosearch!" => \$abletosearch,
"showpasswords!" => \$showpasswords, "showpasswords!" => \$showpasswords,
"maxlinelength=i" => \$maxlinelength, "maxlinelength=i" => \$maxlinelength,
"fixcolonbug!" => \$fixcolonbug,
); );
$debug and print "get options: [$opt_ret]\n"; $debug and print "get options: [$opt_ret]\n";
@ -5813,7 +5908,9 @@ sub tests_debug {
SKIP: { SKIP: {
skip "No test in normal run" if ( not $tests_debug ); skip "No test in normal run" if ( not $tests_debug );
tests_msgs_from_maxmin( ) ; tests_filter_forbidden_characters( ) ;
tests_cache_folder( ) ;
tests_tmpdir_has_colon_bug( ) ;
} }
return( ) ; return( ) ;
} }
@ -5865,6 +5962,7 @@ sub tests {
tests_max_line_length( ) ; tests_max_line_length( ) ;
tests_subject( ) ; tests_subject( ) ;
tests_msgs_from_maxmin( ) ; tests_msgs_from_maxmin( ) ;
tests_tmpdir_has_colon_bug( ) ;
} }
return( ) ; return( ) ;
} }

View file

@ -5,7 +5,7 @@
<title>Official imapsync migration tool ( release <!--#exec cmd="cat ./VERSION"--> )</title> <title>Official imapsync migration tool ( release <!--#exec cmd="cat ./VERSION"--> )</title>
<meta name="generator" content="Bluefish 1.0.7"/> <meta name="generator" content="Bluefish 1.0.7"/>
<meta name="author" content="Gilles LAMIRAL"/> <meta name="author" content="Gilles LAMIRAL"/>
<meta name="date" content="2013-09-22T00:28:13+0200"/> <meta name="date" content="2013-10-17T03:39:01+0200"/>
<meta name="copyright" content="None"/> <meta name="copyright" content="None"/>
<meta name="keywords" content="imap, transfert, migration"/> <meta name="keywords" content="imap, transfert, migration"/>
<meta name="description" content="imap migration tool"/> <meta name="description" content="imap migration tool"/>
@ -135,7 +135,7 @@ Via the <b>User-agent</b> parameter it also send:</p>
<!-- <!--
<ul> <ul>
<li><b>1.567</b></li> <li><b>1.569</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>
@ -155,6 +155,13 @@ Via the <b>User-agent</b> parameter it also send:</p>
</ul> </ul>
--> -->
<ul>
<li><b>1.569</b> Win32 --tmpdir "C:" bugfix</li>
<li><b>Bug fix</b>: On Win32 trailing blanc in cache dir name raized an error. Blanc is now moved to underscore _</li>
<li><b>Bug fix</b>: Fixed bug on Windows with for example --tmpdir "E:\TEMP". The colon was badly converted to _, ending with --tmpdir "E_\TEMP".
This fix also automatically moves the old cache to the new one if the new does not exist yet.</li>
</ul>
<ul> <ul>
<li><b>1.567</b> imapsync.exe crash fix</li> <li><b>1.567</b> imapsync.exe crash fix</li>
<li><b>Enhancement</b>: Added --authmech EXTERNAL.</li> <li><b>Enhancement</b>: Added --authmech EXTERNAL.</li>
@ -162,89 +169,41 @@ Via the <b>User-agent</b> parameter it also send:</p>
<li><b>Bug fix</b>: Fixed imapsync.exe crash with no error message when it exits on a error. Back to Perl 5.16</li> <li><b>Bug fix</b>: Fixed imapsync.exe crash with no error message when it exits on a error. Back to Perl 5.16</li>
</ul> </ul>
<p><b>Good changed</b> made before, listed because <b>they can help</b>:
</p>
<ul> <ul>
<li><b>1.564</b> QQMail support</li>
<li><b>Enhancement</b>: Adapted behavior for allowing --maxdate --mindate with --noabletosearch. <li><b>Enhancement</b>: Adapted behavior for allowing --maxdate --mindate with --noabletosearch.
Use internat date instead of Date: header.</li> Use internat date instead of Date: header.</li>
<li><b>Enhancement</b>: QQMail IMAP4Server success (with --noabletosearch option) </li> <li><b>Enhancement</b>: QQMail IMAP4Server success (with --noabletosearch option) </li>
<li><b>Usability</b>: Apply same treatment to --delete2duplicates as --delete2. <li><b>Usability</b>: Apply same treatment to --delete2duplicates as --delete2.
If --uidexpunge2 can be done, do it, else do --expunge2 (unless --nouidexpunge2 or --noexpunge2).</li> If --uidexpunge2 can be done, do it, else do --expunge2 (unless --nouidexpunge2 or --noexpunge2).</li>
<li><b>Usability</b>: Added --addheader suggestion in outpout in case messages with no header are found.</li>
<li><b>Usability</b>: Added --timeout in the --help output. Default timeout is 120 seconds now <li><b>Usability</b>: Added --timeout in the --help output. Default timeout is 120 seconds now
(was nothing by imapsync, 600 with underlying modules).</li> (was nothing by imapsync, 600 with underlying modules).</li>
</ul>
<ul>
<li><b>1.558</b> SSL fix.</li>
<li><b>Enhancement/Bug fix</b>: Added --ssl1_SSL_version and --ssl2_SSL_version to force the SSL_version <li><b>Enhancement/Bug fix</b>: Added --ssl1_SSL_version and --ssl2_SSL_version to force the SSL_version
in case the default auto-negociation does not work. Example: <b>--ssl1 --ssl1_SSL_version SSLv3</b></li> in case the default auto-negociation does not work. Example: <b>--ssl1 --ssl1_SSL_version SSLv3</b></li>
</ul>
<ul>
<li><b>1.555</b> Better Office365 and Mailenable handling</li>
<li><b>Enhancement</b>: Added option --messageidnodomain to fix Mailenable bug changing the domain part of Message-Id header, and avoid duplicates</li> <li><b>Enhancement</b>: Added option --messageidnodomain to fix Mailenable bug changing the domain part of Message-Id header, and avoid duplicates</li>
<li><b>Enhancement</b>: Added option --syncflagsaftercopy to fix Mailenable bug not getting the flags with the APPEND</li> <li><b>Enhancement</b>: Added option --syncflagsaftercopy to fix Mailenable bug not getting the flags with the APPEND</li>
<li><b>Enhancement</b>: Added option <b>--maxlinelength</b> to skip messages whose max line length is over a number of bytes. <li><b>Enhancement</b>: Added option <b>--maxlinelength</b> to skip messages whose max line length is over a number of bytes.
Exchange 2013 and Office365 need <b>--maxlinelength 1000</b> (which is a RFC2822 must) to avoid disconnections.</li> Exchange 2013 and Office365 need <b>--maxlinelength 1000</b> (which is a RFC2822 must) to avoid disconnections.</li>
<li><b>Usability</b>: Added back the banner of IMAP servers, ie, the first line given after the connection established.</li>
<li><b>Usability</b>: Added --fixInboxINBOX, turned on by default, to map automatically Inbox INBOX folder names.</li> <li><b>Usability</b>: Added --fixInboxINBOX, turned on by default, to map automatically Inbox INBOX folder names.</li>
<li><b>Usability</b>: IMAP server removing consecutive spaces on the header part doesn't generate duplicates (MailEnable does that)</li> <li><b>Usability</b>: IMAP server removing consecutive spaces on the header part doesn't generate duplicates (MailEnable does that)</li>
<li><b>Bug fix</b>: Better output of mailbox sizes in human style (could be 1024.00 Kib, now it is 1.000 Mib). Changed bytes_display_string(). </li>
<li><b>Bug fix</b>: Option --debugflags now prints flags on first sync (the copy) and also the PERMANENTFLAGS outpout.</li>
<li><b>Refactoring</b>: Fixed nearly 200 perlcritic at level 3, all level 4. Still 5 eval "" at level 5 and 12 critics at level 3. Nobody cares but me.</li>
</ul>
<ul>
<li><b>1.547</b> Nothing important except imapsync.exe supports also XOAUTH.</li>
<li><b>Enhancement</b>: DBOX 2.41 success</li>
<li><b>Enhancement</b>: Kerio 8 success</li>
<li><b>Usability</b>: SSL_verify_mode 0 to avoid warning about Man-In-The-Middle.</li> <li><b>Usability</b>: SSL_verify_mode 0 to avoid warning about Man-In-The-Middle.</li>
<li><b>Usability</b>: Added message "copying message ..." in dry mode.</li>
<li><b>Bug fix</b>: Applied patch from Jim Klimov to handle proxyauth failures</li>
<li><b>Bug fix</b>: Fixed binary previous imapsync.exe 1.542 bug with ssl</li>
<li><b>Refactoring</b>: Removed sub myconnect() RawSocket2() Split() (Hi Phil!)</li>
</ul>
<ul>
<li><b>1.542</b> XOAUTH supported! (Admin Gmail authentication)</li>
<li><b>Enhancement</b>: Added XOAUTH authentication. Thanks to Eduardo Bortoluzzi Junior.</li> <li><b>Enhancement</b>: Added XOAUTH authentication. Thanks to Eduardo Bortoluzzi Junior.</li>
<li><b>Refactoring</b>: Removed old 2.2.9 Mail::IMAPClient patch stuff.</li>
<li><b>Refactoring</b>: Started perlcritic corrections. Left 4 eval at level 5.</li>
</ul>
<ul>
<li><b>1.536</b></li>
<li><b>Enhancement</b>: Added <b>--search1</b> and <b>--search2</b> to allow different searches on each host.</li> <li><b>Enhancement</b>: Added <b>--search1</b> and <b>--search2</b> to allow different searches on each host.</li>
<li><b>Enhancement</b>: Speed up when messages are selected by --minage, --maxage or --search, (used to SEARCH ALL messages) </li>
<li><b>Usability</b>: Added --delete1 as an alias for --delete</li> <li><b>Usability</b>: Added --delete1 as an alias for --delete</li>
<li><b>Bug fix</b>: Applied Phil patch to improve the lost connection behavior</li>
<li><b>Bug fix</b>: Applied Phil patch to remove useless warnings</li>
</ul>
<ul>
<li><b>1.525</b></li>
<li><b>Bug fix</b>: Handles the case where <b>several folders</b> on host1 <b>go to one folder</b> on host2 with <b>--delete2</b> option. The bug was imapsync was copying messages and deleting them on next folder.</li>
<li><b>Bug fix</b>: Removed reference to DWTFPL since <b>license is <a href="LICENSE">NOLIMIT</a></b> since June 2012.</li>
<li><b>Speed</b>: Option <b>--nocheckmessageexists is activated by default</b> since --checkmessageexists often slow down transfers too much.</li> <li><b>Speed</b>: Option <b>--nocheckmessageexists is activated by default</b> since --checkmessageexists often slow down transfers too much.</li>
<li><b>Usability</b>: Reorganized the --help message.</li>
<li><b>Usability</b>: Option --foldersizesatend is on if --foldersizes is on. Off if --nofoldersizesatend</li> <li><b>Usability</b>: Option --foldersizesatend is on if --foldersizes is on. Off if --nofoldersizesatend</li>
</ul>
<ul>
<li><b>1.518</b></li>
<li><b>Bug fix</b>: When identtifying with header, change tabulations to spaces
(Gmail bug with "Received:" header on multilines).</li>
<li><b>Bug fix</b>: Bugfix. Automatic --nocheckmessageexists when --noabletosearch is set.</li>
</ul>
<ul>
<li><b>1.516</b></li>
<li><b>Usability</b>: Added <b>host2 minus host1 statistic</b>: number of messages and bytes. <li><b>Usability</b>: Added <b>host2 minus host1 statistic</b>: number of messages and bytes.
One difference at the start and one at the end. One difference at the start and one at the end.
@ -260,8 +219,6 @@ it deletes messages in host2 that are duplicates.
--delete2duplicates is on when --delete2 is set unless --nodelete2duplicates is set too. --delete2duplicates is on when --delete2 is set unless --nodelete2duplicates is set too.
</li> </li>
<li><b>Usability</b>: Added <b>current date at the beginning</b> of the run,
useful when imapsync doesn't end properly or hasn't finished yet.</li>
<li><b>Enhancement</b>: Added option <b>--pidfilelocking</b>; <li><b>Enhancement</b>: Added option <b>--pidfilelocking</b>;
it aborts imapsync, when just launched, it aborts imapsync, when just launched,
@ -286,49 +243,14 @@ to allow the listing of messages without the imap "SEARCH ALL" command.
It's useful for playing with poor imap servers like <b>Softalk 7.6.4</b> It's useful for playing with poor imap servers like <b>Softalk 7.6.4</b>
(8.6 is fine with SEARCH ALL).</li> (8.6 is fine with SEARCH ALL).</li>
</ul>
<ul>
<li><b>1.508</b></li>
<li><b>Usability</b>: imapsync guesses and <b>prints when it'll finish</b> the transfer;
added <b>ETA</b> after each copy (Estimated Time of Arrival)</li>
<li><b>Enhancement</b>: Added <b>--noexpungeaftereach</b> <li><b>Enhancement</b>: Added <b>--noexpungeaftereach</b>
to speedup --delete --expunge from Gmail.</li> to speedup --delete --expunge from Gmail.</li>
<li><b>Usability</b>: Added Host1 or Host2 before "Nb messages" "Total size"
with --foldersiszes (to facilitate parsing)</li>
<li><b>Bug fix</b>: Previous fix about characters <kbd>*|?:"&lt;&gt;</kbd> to <kbd>_</kbd>
in cache path was not complete.</li>
</ul>
<ul>
<li><b>1.504</b></li>
<li><b>Enhancement</b>: Added option <b>--nocheckmessageexists</b> to <b>speed up</b> with <b>Tobit imap server</b> as host1.</li> <li><b>Enhancement</b>: Added option <b>--nocheckmessageexists</b> to <b>speed up</b> with <b>Tobit imap server</b> as host1.</li>
<li><b>Usability</b>: Added <b>transfer rate</b> and number of messages rate <b>after each copy</b>.</li>
<li><b>Usability</b>: Use Time::HiRes time to get time with better precesion than the second.</li>
<li><b>Bug fix</b>: Convert characters <kbd>*|?:"&lt;&gt;</kbd> to <kbd>_</kbd> in cache paths because they are forbidden on Windows paths.</li>
</ul>
<ul>
<li><b>1.500</b></li>
<li><b>Enhancement</b>: Added option <b>--nocheckselectable</b> to fix INBOX issue with Jana-server.</li>
<li><b>Bug fix</b>: The cache system didn't work in Win32 (problem with \ transformation).</li>
<li><b>Bug fix</b>: Check the return of touch calls for the cache. </li>
<li><b>Usability</b>: Example for --delete2foldersbutnot "m/Contacts|Agenda|Trash/"</li>
</ul>
<ul>
<li><b>1.484</b></li>
<li><b>Bug fix</b>: Back to select() (read-write mode) instead of examine()
(read-only mode in 1.468) on host1. <b>Needed with --delete</b></li>
<li><b>Enhancement</b>: Added option --exitwhenover option <b>to avoid locking</b> <li><b>Enhancement</b>: Added option --exitwhenover option <b>to avoid locking</b>
when transfers exceed maximum limit. when transfers exceed maximum limit.
@ -336,16 +258,9 @@ See for example <a href="http://support.google.com/a/bin/answer.py?hl=en&amp;ans
<ul> <ul>
<li>imapsync ... --exitwhenover 2500000000 # 2.5GB if <b>host1 is Gmail</b></li> <li>imapsync ... --exitwhenover 2500000000 # 2.5GB if <b>host1 is Gmail</b></li>
<li>imapsync ... --exitwhenover 500000000 # 500MB if <b>host2 is Gmail</b></li> <li>imapsync ... --exitwhenover 500000000 # 500MB if <b>host2 is Gmail</b></li>
</ul> </ul>
</li> </li>
<li><b>Usability</b>: Unified outout in --debug mode. Lines start with Host1 or Host2.</li>
<li><b>Usability</b>: Changed output about messages ignored to better reflect what is going on.</li>
</ul>
<ul>
<li><b>1.476</b></li>
<li><b>Usability</b>: Default headers used to identify a message are now "Message-Id" and "Received" <li><b>Usability</b>: Default headers used to identify a message are now "Message-Id" and "Received"
(<b>Exchange compatibility</b> bu default).</li> (<b>Exchange compatibility</b> bu default).</li>
@ -662,7 +577,7 @@ I like it.
</ul> </ul>
<p>Now the long reported <b>success stories</b> list: <b> <p>Now the long reported <b>success stories</b> list: <b>
55 different imap server softwares supported!</b><br/> 57 different imap server softwares supported!</b><br/>
[host1] means "source server" and [host2] means "destination server": [host1] means "source server" and [host2] means "destination server":
</p> </p>
@ -710,6 +625,7 @@ I like it.
(<a href="http://www.novell.com/products/groupwise/">http://www.novell.com/products/groupwise/</a>) </li> (<a href="http://www.novell.com/products/groupwise/">http://www.novell.com/products/groupwise/</a>) </li>
<li>hMailServer 5.3.3 [host2], 4.4.1 [host1], HMAILSERVER 5.3.2-B1769 on windows 2003 [hsot2] <li>hMailServer 5.3.3 [host2], 4.4.1 [host1], HMAILSERVER 5.3.2-B1769 on windows 2003 [hsot2]
(<a href="http://www.hmailserver.com/">http://www.hmailserver.com/</a>) </li> (<a href="http://www.hmailserver.com/">http://www.hmailserver.com/</a>) </li>
<li>IceWarp Server 10.4.5 [host1] (<a href="http://www.icewarp.com/">http://www.icewarp.com/</a>)</li>
<li>iPlanet Messaging server 4.15, 5.1, 5.2 <li>iPlanet Messaging server 4.15, 5.1, 5.2
(<a href="http://en.wikipedia.org/wiki/Oracle_Communications_Messaging_Server">http://en.wikipedia.org/wiki/Oracle_Communications_Messaging_Server</a>) </li> (<a href="http://en.wikipedia.org/wiki/Oracle_Communications_Messaging_Server">http://en.wikipedia.org/wiki/Oracle_Communications_Messaging_Server</a>) </li>
<li>IMail 7.15 (Ipswitch/Win2003), 8.12, 11.03 [host1] (<a href="http://www.imailserver.com/">http://www.imailserver.com/</a>) </li> <li>IMail 7.15 (Ipswitch/Win2003), 8.12, 11.03 [host1] (<a href="http://www.imailserver.com/">http://www.imailserver.com/</a>) </li>
@ -736,6 +652,7 @@ I like it.
<li>OpenWave (<a href="http://www.openwave.com/">http://www.openwave.com/</a>) </li> <li>OpenWave (<a href="http://www.openwave.com/">http://www.openwave.com/</a>) </li>
<li>Oracle Beehive [host1] <li>Oracle Beehive [host1]
(<a href="http://www.oracle.com/technetwork/middleware/beehive/">http://www.oracle.com/technetwork/middleware/beehive/</a>) </li> (<a href="http://www.oracle.com/technetwork/middleware/beehive/">http://www.oracle.com/technetwork/middleware/beehive/</a>) </li>
<li>Parallels Plesk Panel 9.x [host2] 11.x [host2] (<a href="http://www.parallels.com/">http://www.parallels.com/</a>)</li>
<li>Qualcomm Worldmail (NT) (<a href="http://www.eudora.com/worldmail/">http://www.eudora.com/worldmail/</a>) </li> <li>Qualcomm Worldmail (NT) (<a href="http://www.eudora.com/worldmail/">http://www.eudora.com/worldmail/</a>) </li>
<li>Rockliffe Mailsite 5.3.11, 4.5.6 (<a href="http://www.mailsite.com/">http://www.mailsite.com/</a>) </li> <li>Rockliffe Mailsite 5.3.11, 4.5.6 (<a href="http://www.mailsite.com/">http://www.mailsite.com/</a>) </li>
<li>RackSpace hoster secure.emailsrvr.com:993 <a href="http://www.rackspace.com/">http://www.rackspace.com/</a>)</li> <li>RackSpace hoster secure.emailsrvr.com:993 <a href="http://www.rackspace.com/">http://www.rackspace.com/</a>)</li>
@ -825,7 +742,7 @@ alt="Viewable With Any Browser" />
<!--#config timefmt="%D" --> <!--#config timefmt="%D" -->
<!--#config timefmt="%A %B %d, %Y" --> <!--#config timefmt="%A %B %d, %Y" -->
<b>This document last modified on <!--#echo var="LAST_MODIFIED" --></b> <b>This document last modified on <!--#echo var="LAST_MODIFIED" --></b>
($Id: index.shtml,v 1.185 2013/09/21 22:28:26 gilles Exp gilles $) ($Id: index.shtml,v 1.186 2013/10/17 01:49:59 gilles Exp gilles $)
</p> </p>
</body> </body>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,23 +1,24 @@
Main code has high complexity score (335) at line 1, column 1. Consider refactoring. (Severity: 3) Main code has high complexity score (338) at line 1, column 1. Consider refactoring. (Severity: 3)
Code structure is deeply nested at line 1516, column 41. Consider refactoring. (Severity: 3) Code structure is deeply nested at line 1524, column 41. Consider refactoring. (Severity: 3)
Too many arguments at line 1683, column 1. See page 182 of PBP. (Severity: 3) Too many arguments at line 1691, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 1698, column 1. See page 182 of PBP. (Severity: 3) Too many arguments at line 1706, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 1708, column 1. See page 182 of PBP. (Severity: 3) Too many arguments at line 1716, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 1942, column 1. See page 182 of PBP. (Severity: 3) Too many arguments at line 1950, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 1997, column 1. See page 182 of PBP. (Severity: 3) Too many arguments at line 2005, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2053, column 1. See page 182 of PBP. (Severity: 3) Too many arguments at line 2061, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 2143, column 1. See page 182 of PBP. (Severity: 3) Too many arguments at line 2151, column 1. See page 182 of PBP. (Severity: 3)
Expression form of "eval" at line 2768, column 13. See page 161 of PBP. (Severity: 5) Expression form of "eval" at line 2776, column 13. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 2986, column 13. See page 161 of PBP. (Severity: 5) Expression form of "eval" at line 2994, column 13. See page 161 of PBP. (Severity: 5)
Subroutine "select_msgs" does not end with "return" at line 3127, column 1. See page 197 of PBP. (Severity: 4) Subroutine "select_msgs" does not end with "return" at line 3135, column 1. See page 197 of PBP. (Severity: 4)
Subroutine "tests_msgs_from_maxmin" does not end with "return" at line 3266, column 1. See page 197 of PBP. (Severity: 4) Subroutine "tests_msgs_from_maxmin" does not end with "return" at line 3274, column 1. See page 197 of PBP. (Severity: 4)
Subroutine "copy_message" with high complexity score (21) at line 3343, column 1. Consider refactoring. (Severity: 3) Subroutine "copy_message" with high complexity score (21) at line 3351, column 1. Consider refactoring. (Severity: 3)
Too many arguments at line 3343, column 1. See page 182 of PBP. (Severity: 3) Too many arguments at line 3351, column 1. See page 182 of PBP. (Severity: 3)
Too many arguments at line 3403, column 1. See page 182 of PBP. (Severity: 3) Too many arguments at line 3411, column 1. See page 182 of PBP. (Severity: 3)
Subroutine "tests_subject" does not end with "return" at line 3497, column 1. See page 197 of PBP. (Severity: 4) Subroutine "tests_subject" does not end with "return" at line 3505, column 1. See page 197 of PBP. (Severity: 4)
Too many arguments at line 3560, column 1. See page 182 of PBP. (Severity: 3) Too many arguments at line 3568, column 1. See page 182 of PBP. (Severity: 3)
Expression form of "eval" at line 4317, column 13. See page 161 of PBP. (Severity: 5) Hard tabs used at line 4139, column 10. See page 20 of PBP. (Severity: 3)
Too many arguments at line 4472, column 1. See page 182 of PBP. (Severity: 3) Expression form of "eval" at line 4410, column 13. See page 161 of PBP. (Severity: 5)
Expression form of "eval" at line 5104, column 43. See page 161 of PBP. (Severity: 5) Too many arguments at line 4565, column 1. See page 182 of PBP. (Severity: 3)
Expression form of "eval" at line 5108, column 45. See page 161 of PBP. (Severity: 5) Expression form of "eval" at line 5197, column 43. See page 161 of PBP. (Severity: 5)
"$i" is declared but not used at line 5372, column 9. Unused variables clutter code and make it harder to read. (Severity: 3) Expression form of "eval" at line 5201, column 45. See page 161 of PBP. (Severity: 5)
"$i" is declared but not used at line 5465, column 9. Unused variables clutter code and make it harder to read. (Severity: 3)

View file

@ -1,9 +1,9 @@
#!/bin/sh #!/bin/sh
# $Id: tests.sh,v 1.225 2013/09/21 21:55:17 gilles Exp gilles $ # $Id: tests.sh,v 1.227 2013/09/28 11:11:16 gilles Exp gilles $
# Example 1: # Example 1:
# CMD_PERL='perl -I./Mail-IMAPClient-3.33/lib' sh -x tests.sh # CMD_PERL='perl -I./W/Mail-IMAPClient-3.34/lib' sh -x tests.sh
# Example 2: # Example 2:
# To select which Mail-IMAPClient within arguments: # To select which Mail-IMAPClient within arguments:
@ -23,7 +23,7 @@ echo HOST2=$HOST2
# few debugging tests use: # few debugging tests use:
CMD_PERL_2xx='perl -I./W/Mail-IMAPClient-2.2.9' CMD_PERL_2xx='perl -I./W/Mail-IMAPClient-2.2.9'
CMD_PERL_3xx='perl -I./W/Mail-IMAPClient-3.33/lib' CMD_PERL_3xx='perl -I./W/Mail-IMAPClient-3.34/lib'
CMD_PERL=${CMD_PERL:-$CMD_PERL_3xx} CMD_PERL=${CMD_PERL:-$CMD_PERL_3xx}
@ -2312,7 +2312,8 @@ xxxxx_gmail_5_justfolders() {
--user2 gilles.lamiral@gmail.com \ --user2 gilles.lamiral@gmail.com \
--passfile2 ../../var/pass/secret.gilles_gmail \ --passfile2 ../../var/pass/secret.gilles_gmail \
--justfolders --nofoldersizes \ --justfolders --nofoldersizes \
--regextrans2 's,(/|^) +,$1,g' --regextrans2 's, +(/|$),$1,g' --regextrans2 's,(/|^) +,$1,g' --regextrans2 's, +(/|$),$1,g' \
--regextrans2 "s/[\^]/_/g" --debug
} }
@ -2822,6 +2823,35 @@ ll_nofastio()
########################## ##########################
courier_45() {
$CMD_PERL ./imapsync \
--host1 imap.timeweb.ru --user1 imaptest@avanta-consulting.ru \
--passfile1 ../../var/pass/secret.avanta \
--host2 $HOST2 --user2 tobbit \
--passfile2 ../../var/pass/secret.tobbit \
--folder INBOX
}
courier_45_reverse() {
$CMD_PERL ./imapsync \
--host2 imap.timeweb.ru --user2 imaptest@avanta-consulting.ru \
--passfile2 ../../var/pass/secret.avanta \
--host1 $HOST2 --user1 tobbit \
--passfile1 ../../var/pass/secret.tobbit \
--folder INBOX
}
courier_45_reverse_empty() {
$CMD_PERL ./imapsync \
--host2 imap.timeweb.ru --user2 imaptest@avanta-consulting.ru \
--passfile2 ../../var/pass/secret.avanta \
--host1 $HOST2 --user1 empty \
--passfile1 ../../var/pass/secret.empty \
--folder INBOX --delete2
}
tobbit_11() { tobbit_11() {
$CMD_PERL ./imapsync \ $CMD_PERL ./imapsync \
--host1 217.22.84.74 --user1 Test_IMAP \ --host1 217.22.84.74 --user1 Test_IMAP \