mirror of
https://github.com/imapsync/imapsync.git
synced 2025-06-08 21:54:31 +02:00
1.536
This commit is contained in:
parent
32a552f56e
commit
c14f2f1c6b
119 changed files with 978 additions and 42838 deletions
56
ChangeLog
56
ChangeLog
|
@ -1,17 +1,63 @@
|
|||
|
||||
RCS file: RCS/imapsync,v
|
||||
Working file: imapsync
|
||||
head: 1.525
|
||||
head: 1.536
|
||||
branch:
|
||||
locks: strict
|
||||
gilles: 1.525
|
||||
gilles: 1.536
|
||||
access list:
|
||||
symbolic names:
|
||||
keyword substitution: kv
|
||||
total revisions: 525; selected revisions: 525
|
||||
total revisions: 536; selected revisions: 536
|
||||
description:
|
||||
----------------------------
|
||||
revision 1.525 locked by: gilles;
|
||||
revision 1.536 locked by: gilles;
|
||||
date: 2013/04/17 14:33:12; author: gilles; state: Exp; lines: +7 -7
|
||||
Added --delete1 as an alias for --delete
|
||||
----------------------------
|
||||
revision 1.535
|
||||
date: 2013/04/17 12:47:58; author: gilles; state: Exp; lines: +42 -33
|
||||
Updated README part.
|
||||
----------------------------
|
||||
revision 1.534
|
||||
date: 2013/04/16 15:31:50; author: gilles; state: Exp; lines: +26 -17
|
||||
Added --search1 and --search2 to allow different searches on each host.
|
||||
----------------------------
|
||||
revision 1.533
|
||||
date: 2013/04/10 12:03:39; author: gilles; state: Exp; lines: +8 -6
|
||||
Comment in select_msgs()
|
||||
----------------------------
|
||||
revision 1.532
|
||||
date: 2013/04/10 08:33:52; author: gilles; state: Exp; lines: +11 -9
|
||||
Fixed Scott issue again. Was not enough.
|
||||
----------------------------
|
||||
revision 1.531
|
||||
date: 2013/04/09 08:10:38; author: gilles; state: Exp; lines: +7 -7
|
||||
Fixed Scott issue, took long time (all messages list) even with --useuid --delete --nousecache --maxage 1
|
||||
----------------------------
|
||||
revision 1.530
|
||||
date: 2013/04/09 08:00:54; author: gilles; state: Exp; lines: +13 -14
|
||||
Clarified select_msgs() a little.
|
||||
----------------------------
|
||||
revision 1.529
|
||||
date: 2013/03/29 14:32:26; author: gilles; state: Exp; lines: +14 -12
|
||||
Phil patch.
|
||||
----------------------------
|
||||
revision 1.528
|
||||
date: 2013/03/29 03:12:45; author: gilles; state: Exp; lines: +60 -21
|
||||
Applied Phil patch.
|
||||
----------------------------
|
||||
revision 1.527
|
||||
date: 2013/03/29 01:15:05; author: gilles; state: Exp; lines: +10 -8
|
||||
Mail2World Server
|
||||
Zarafa Gateway
|
||||
----------------------------
|
||||
revision 1.526
|
||||
date: 2013/02/27 22:40:45; author: gilles; state: Exp; lines: +9 -7
|
||||
Apple Server
|
||||
Zarafa server
|
||||
----------------------------
|
||||
revision 1.525
|
||||
date: 2013/02/05 12:52:10; author: gilles; state: Exp; lines: +9 -9
|
||||
Typo synchronise -> synchronize.
|
||||
----------------------------
|
||||
|
@ -36,7 +82,7 @@ revision 1.520
|
|||
date: 2013/01/23 07:41:48; author: gilles; state: Exp; lines: +103 -30
|
||||
Fix. Removed reference to DWTFPL since license is NOLIMIT now.
|
||||
License file is LICENSE now, no longer COPYING.
|
||||
Fix. Handle the case where several folders on host2 go to one folder on host1 with --delete2 option.
|
||||
Fix. Handle the case where several folders on host1 go to one folder on host2 with --delete2 option.
|
||||
The bug was imapsync was copying messages and deleting them on next folder.
|
||||
----------------------------
|
||||
revision 1.519
|
||||
|
|
96
FAQ
96
FAQ
|
@ -1,5 +1,5 @@
|
|||
#!/bin/cat
|
||||
# $Id: FAQ,v 1.124 2013/02/05 18:40:50 gilles Exp gilles $
|
||||
# $Id: FAQ,v 1.130 2013/04/17 12:46:10 gilles Exp gilles $
|
||||
|
||||
+------------------+
|
||||
| FAQ for imapsync |
|
||||
|
@ -8,6 +8,11 @@
|
|||
http://imapsync.lamiral.info/FAQ
|
||||
|
||||
Unix versus Windows syntax.
|
||||
There are several differences between Unix and Windows
|
||||
in the command line syntax.
|
||||
- Character \ versus ^
|
||||
- Character ' versus "
|
||||
|
||||
|
||||
A) \ versus ^
|
||||
|
||||
|
@ -103,6 +108,34 @@ post to this list if you want to stay private.
|
|||
|
||||
Thank you for your participation.
|
||||
|
||||
=======================================================================
|
||||
Q. Can I copy or sync Calendar or Contacts with imapsync?
|
||||
|
||||
R. No. It's because most IMAP servers don't get contacts and calendar
|
||||
events via IMAP. In other words, messages synced by imapsync from
|
||||
Calendar or Contacts folders are not used by email servers to set
|
||||
or get the contacts or calendars.
|
||||
No way via IMAP, no way via imapsync.
|
||||
|
||||
=======================================================================
|
||||
Q. How can I copy or synchronize Calendars or Contacts?
|
||||
|
||||
R1. It can't be done with imapsync.
|
||||
|
||||
R2. It can be done, depending on the email server softwares used.
|
||||
|
||||
a) From Exchange to Exchange, export contacts and calendar to
|
||||
PST format files on host1 and import them on host2.
|
||||
|
||||
b) From Gmail to Gmail, export and import calandars in ical format,
|
||||
extension for those files is .ics.
|
||||
Contacts can be copied using a csv file. See the help page
|
||||
http://support.google.com/mail/bin/topic.py?hl=en&topic=1669027
|
||||
|
||||
c) Etc. Search the web. There's also specific tools and paid services.
|
||||
There's no silver bullet to migrate Calendars and Contacts,
|
||||
if you find one, tell me!
|
||||
|
||||
=======================================================================
|
||||
Q. I need to migrate hundred accounts, how can I do?
|
||||
|
||||
|
@ -145,10 +178,10 @@ Q. Where I can find free open and gratis imapsync releases?
|
|||
|
||||
R. Search the internet.
|
||||
|
||||
Q. Is is legal?
|
||||
Q. Is is legal to find imapsync gratis (or not) elsewhere?
|
||||
|
||||
R. Yes, the license permits it
|
||||
http://imapsync.lamiral.info/COPYING
|
||||
http://imapsync.lamiral.info/LICENSE
|
||||
|
||||
=======================================================================
|
||||
Q. I use --useuid which uses a cache in /tmp or --tmpdir, the hostnames
|
||||
|
@ -265,7 +298,13 @@ R2. Use --useuid then imapsync will avoid dealing with headers.
|
|||
=======================================================================
|
||||
Q. How can I try imapsync with Mail::IMAPClient 3.xx perl module?
|
||||
|
||||
R. - Download latest Mail::IMAPClient 3.xx at
|
||||
R. The answer R2 deals with any Perl module use.
|
||||
|
||||
R1 - Look at the script named i3 in the tarball, it can be used to
|
||||
run imapsync with included Mail-IMAPClient-3.32/ wherever you
|
||||
unpacked the imapsync tarball
|
||||
|
||||
R2 - Download latest Mail::IMAPClient 3.xx at
|
||||
http://search.cpan.org/dist/Mail-IMAPClient/
|
||||
- untar it anywhere:
|
||||
tar xzvf Mail-IMAPClient-3.xx.tar.gz
|
||||
|
@ -280,29 +319,11 @@ R. - Download latest Mail::IMAPClient 3.xx at
|
|||
or if imapsync is in directory /path/
|
||||
perl -I./Mail-IMAPClient-3.32/lib /path/imapsync ...
|
||||
|
||||
- Look at the script named i3 in the tarball, it can be used to
|
||||
run imapsync with included Mail-IMAPClient-3.32/ wherever you
|
||||
unpacked the imapsync tarball
|
||||
|
||||
=======================================================================
|
||||
Q. How can I use imapsync with Mail::IMAPClient 2.2.9 perl module?
|
||||
|
||||
R. - Download Mail::IMAPClient 2.2.9 at
|
||||
http://search.cpan.org/~djkernen/Mail-IMAPClient-2.2.9/
|
||||
http://search.cpan.org/CPAN/authors/id/D/DJ/DJKERNEN/Mail-IMAPClient-2.2.9.tar.gz
|
||||
- untar it anywhere:
|
||||
tar xzvf Mail-IMAPClient-2.2.9.tar.gz
|
||||
|
||||
- run imapsync with perl and -I option tailing to use Mail-IMAPClient-2.2.9:
|
||||
perl -I./Mail-IMAPClient-2.2.9 ./imapsync [...]
|
||||
|
||||
or if imapsync is in directory /path/
|
||||
perl -I./Mail-IMAPClient-2.2.9 /path/imapsync [...]
|
||||
|
||||
- Look at the script named i2 in the tarball, it can be used to
|
||||
run imapsync with included Mail-IMAPClient-2.2.9/ wherever you
|
||||
unpacked the imapsync tarball
|
||||
|
||||
R. Mail::IMAPClient 2.2.9 is no longer supported.
|
||||
|
||||
=======================================================================
|
||||
Q. Can I use imapsync to migrate emails from pop3 server to imap server?
|
||||
|
@ -408,12 +429,17 @@ R. Use redirections of both standard and error outputs "> log.txt 2>&1"
|
|||
|
||||
imapsync ... > log.txt 2>&1
|
||||
|
||||
This syntax is available both on Windows and Unix.
|
||||
|
||||
=======================================================================
|
||||
Q. I need to log every output on a file named log.txt and also to the
|
||||
screen in order to keep seeing what's going on during execution
|
||||
|
||||
R. Use the tee program (also available on Windows)
|
||||
http://en.wikipedia.org/wiki/Tee_%28command%29
|
||||
http://stackoverflow.com/questions/796476/displaying-windows-command-prompt-output-and-redirecting-it-to-a-file
|
||||
http://code.google.com/p/wintee/
|
||||
|
||||
|
||||
imapsync ... 2>&1 | tee log.txt
|
||||
|
||||
|
@ -1380,25 +1406,24 @@ imapsync --host1 mail.oldhost.com \
|
|||
--user2 my_email@gmail.com \
|
||||
--password2 password \
|
||||
--exitwhenover 500000000 \
|
||||
--folder "INBOX.Sent" \
|
||||
--regextrans2 "s,^Sent$,[Gmail]/Sent Mail," \
|
||||
--addheader
|
||||
--exclude "\[Gmail\]$" \
|
||||
--addheader \
|
||||
--regextrans2 "s,^Sent$,[Gmail]/Sent Mail,"
|
||||
|
||||
|
||||
If you're using a different language in Gmail you might adapt
|
||||
this example with the folder name translated, an example in French:
|
||||
|
||||
imapsync ...
|
||||
--folder 'INBOX.Messages envoy&AOk-s' \
|
||||
--regextrans2 "s,^Messages envoy&AOk-s$,[Gmail]/Messages envoy&AOk-s," \
|
||||
|
||||
The --addheader option is there because Sent folder messages
|
||||
The --addheader option is there because "Sent" folder messages
|
||||
sometimes lack the "Message-Id" header needed by imapsync
|
||||
when --useuid is not used. So option --addheader adds a "Message-Id" header.
|
||||
to identify messages (only when --useuid is not used).
|
||||
So option --addheader adds a "Message-Id" header.
|
||||
|
||||
You can remove --folder "INBOX.Sent" in the example in case
|
||||
you want to sync all folders, the --regextrans2 option will
|
||||
still apply only on "INBOX.Sent" folder.
|
||||
You can add --folder "INBOX.Sent" in the example in case
|
||||
you want to sync only the "Sent" folder.
|
||||
|
||||
The "All Mail" archive pseudo-folder should be updated automaticaly.
|
||||
|
||||
|
@ -1406,8 +1431,13 @@ The "All Mail" archive pseudo-folder should be updated automaticaly.
|
|||
exceed maximum limit.
|
||||
See http://support.google.com/a/bin/answer.py?hl=en&answer=1071518
|
||||
|
||||
--exclude "\[Gmail\]$" is there to avoid a small examine/select error:
|
||||
"Could not examine: 43 NO [NONEXISTENT] Unknown Mailbox: [Gmail]
|
||||
(now in authenticated state) (Failure)".
|
||||
|
||||
|
||||
You can select folders exported to imap within the gmail preferences,
|
||||
unselect all "System labels".
|
||||
unselect all "System labels" depending on your needs.
|
||||
|
||||
|
||||
=======================================================================
|
||||
|
|
15
INSTALL
15
INSTALL
|
@ -1,4 +1,4 @@
|
|||
# $Id: INSTALL,v 1.26 2012/09/11 21:00:06 gilles Exp gilles $
|
||||
# $Id: INSTALL,v 1.27 2013/04/17 12:35:18 gilles Exp gilles $
|
||||
#
|
||||
# INSTALL file for imapsync
|
||||
# imapsync : IMAP sync or copy tool.
|
||||
|
@ -70,18 +70,17 @@ Here is some individual module help:
|
|||
Get the latest Mail::IMAPClient module here:
|
||||
http://search.cpan.org/dist/Mail-IMAPClient/
|
||||
|
||||
In fact I use both Mail-IMAPClient-2.2.9 and latest Mail-IMAPClient-3.xx
|
||||
(xx >= 31 now) To know the version you have on your system try :
|
||||
I use always the latest Mail-IMAPClient-3.xx
|
||||
To know the version you have on your system try :
|
||||
|
||||
perl -mMail::IMAPClient -e 'print $Mail::IMAPClient::VERSION, "\n"'
|
||||
|
||||
New Mail-IMAPClient-3.xx works now very well with imapsync,
|
||||
better than old Mail-IMAPClient-2.2.9, with memory and other things.
|
||||
New Mail-IMAPClient-3.xx works very well with imapsync,
|
||||
Use at least Mail-IMAPClient-3.25 (previous may bug).
|
||||
Don't hesitate to use latest Mail-IMAPClient-3.xx (3.xx >= 3.32 at the time
|
||||
of this writing)
|
||||
Don't hesitate to use latest Mail-IMAPClient-3.xx
|
||||
(3.xx >= 3.32 at the time of this writing)
|
||||
|
||||
Look at the script named i3 in the tarball, it can be used to
|
||||
Look at the script named "i3" in the tarball, it can be used to
|
||||
run imapsync with included Mail-IMAPClient-3.32/ wherever you
|
||||
unpacked the imapsync tarball.
|
||||
|
||||
|
|
32
Makefile
32
Makefile
|
@ -1,5 +1,5 @@
|
|||
|
||||
# $Id: Makefile,v 1.114 2013/01/29 00:26:51 gilles Exp gilles $
|
||||
# $Id: Makefile,v 1.116 2013/04/18 01:24:25 gilles Exp gilles $
|
||||
|
||||
.PHONY: help usage all
|
||||
|
||||
|
@ -11,8 +11,6 @@ usage:
|
|||
@echo "make testf # run tests"
|
||||
@echo "make testv # run tests verbosely"
|
||||
@echo "make test_quick # few tests verbosely"
|
||||
@echo "make test3xx # run tests with (last) Mail-IMAPClient-3.xy"
|
||||
@echo "make test229 # run tests with Mail-IMAPClient-2.2.9"
|
||||
@echo "make tests_win32 # run tests on win32"
|
||||
@echo "make tests_win32_dev # run test2.bat on win32"
|
||||
@echo "make all "
|
||||
|
@ -31,7 +29,6 @@ VERSION=$(shell perl -I$(IMAPClient) ./imapsync --version)
|
|||
VERSION_EXE=$(shell cat ./VERSION_EXE)
|
||||
|
||||
HELLO=$(shell date;uname -a)
|
||||
IMAPClient_2xx=./W/Mail-IMAPClient-2.2.9
|
||||
IMAPClient_3xx=./W/Mail-IMAPClient-3.32/lib
|
||||
IMAPClient=$(IMAPClient_3xx)
|
||||
|
||||
|
@ -61,7 +58,7 @@ VERSION: imapsync
|
|||
clean: clean_tilde clean_man
|
||||
|
||||
clean_test:
|
||||
rm -f .test_3xx .test_229
|
||||
rm -f .test_3xx
|
||||
|
||||
clean_tilde:
|
||||
rm -f *~
|
||||
|
@ -98,20 +95,13 @@ cidone:
|
|||
###############
|
||||
|
||||
|
||||
.PHONY: test tests testp testf test3xx testv2 testv3
|
||||
.PHONY: test tests testp testf test3xx testv3
|
||||
|
||||
test_quick : test_quick_3xx test_quick_229
|
||||
|
||||
test_quick_229: imapsync tests.sh
|
||||
CMD_PERL='perl -I./$(IMAPClient_2xx)' /usr/bin/time sh -x tests.sh locallocal
|
||||
test_quick : test_quick_3xx
|
||||
|
||||
test_quick_3xx: imapsync tests.sh
|
||||
CMD_PERL='perl -I./$(IMAPClient_3xx)' /usr/bin/time sh -x tests.sh locallocal
|
||||
|
||||
testv2: imapsync tests.sh
|
||||
CMD_PERL='perl -I./$(IMAPClient_2xx)' /usr/bin/time sh tests.sh
|
||||
touch .test_229
|
||||
|
||||
testv3: imapsync tests.sh
|
||||
CMD_PERL='perl -I./$(IMAPClient_3xx)' /usr/bin/time sh tests.sh
|
||||
touch .test_3xx
|
||||
|
@ -122,14 +112,6 @@ test: .test_3xx
|
|||
|
||||
tests: test
|
||||
|
||||
test3xx: .test_3xx
|
||||
|
||||
test229: .test_229
|
||||
|
||||
.test_229: imapsync tests.sh
|
||||
CMD_PERL='perl -I./$(IMAPClient_2xx)' /usr/bin/time sh tests.sh 1>/dev/null
|
||||
touch .test_229
|
||||
|
||||
.test_3xx: imapsync tests.sh
|
||||
CMD_PERL='perl -I./$(IMAPClient_3xx)' /usr/bin/time sh tests.sh 1>/dev/null
|
||||
touch .test_3xx
|
||||
|
@ -223,7 +205,7 @@ tarball: .tarball
|
|||
cd examples && rcsdiff RCS/*
|
||||
mkdir -p dist
|
||||
mkdir -p ../prepa_dist/$(DIST_NAME)
|
||||
rsync -aCv --delete --omit-dir-times --exclude dist/ --exclude imapsync.exe ./ ../prepa_dist/$(DIST_NAME)/
|
||||
rsync -aCvH --delete --omit-dir-times --exclude dist/ --exclude imapsync.exe ./ ../prepa_dist/$(DIST_NAME)/
|
||||
#rsync -av ./imapsync.exe ../prepa_dist/$(DIST_NAME)/
|
||||
cd ../prepa_dist && (tar czfv $(DIST_FILE) $(DIST_NAME) || tar czfv $(DIST_FILE) $(DIST_NAME))
|
||||
#ln -f ../prepa_dist/$(DIST_FILE) dist/
|
||||
|
@ -277,7 +259,7 @@ ksa:
|
|||
|
||||
publish: upload_ks ksa ml
|
||||
|
||||
PUBLIC_FILES = ./ChangeLog ./COPYING ./LICENSE ./CREDITS ./FAQ \
|
||||
PUBLIC_FILES = ./ChangeLog ./NOLIMIT ./LICENSE ./CREDITS ./FAQ \
|
||||
./index.shtml ./INSTALL \
|
||||
./VERSION ./VERSION_EXE \
|
||||
./README ./TODO
|
||||
|
@ -321,7 +303,7 @@ upload_lfo:
|
|||
upload_index: FAQ LICENSE CREDITS W/*.bat examples/*.bat examples/sync_loop_unix.sh index.shtml
|
||||
rcsdiff index.shtml FAQ LICENSE CREDITS W/*.bat examples/*.bat index.shtml
|
||||
validate --verbose index.shtml
|
||||
rsync -avH index.shtml FAQ COPYING LICENSE CREDITS root@ks.lamiral.info:/var/www/imapsync/
|
||||
rsync -avH index.shtml FAQ NOLIMIT LICENSE CREDITS root@ks.lamiral.info:/var/www/imapsync/
|
||||
rsync -avH W/*.bat root@ks.lamiral.info:/var/www/imapsync/W/
|
||||
rsync -avH examples/*.bat examples/sync_loop_unix.sh root@ks.lamiral.info:/var/www/imapsync/examples/
|
||||
|
||||
|
|
69
README
69
README
|
@ -1,9 +1,10 @@
|
|||
NAME
|
||||
imapsync - IMAP synchronisation, sync, copy or migration tool.
|
||||
Synchronise mailboxes between two imap servers. Good at IMAP migration.
|
||||
More than 44 different IMAP server softwares supported with success.
|
||||
Synchronises mailboxes between two imap servers. Good at IMAP migration.
|
||||
More than 52 different IMAP server softwares supported with success, few
|
||||
failures.
|
||||
|
||||
$Revision: 1.525 $
|
||||
$Revision: 1.536 $
|
||||
|
||||
SYNOPSIS
|
||||
To synchronize imap account "foo" on "imap.truc.org" to imap account
|
||||
|
@ -16,8 +17,8 @@ SYNOPSIS
|
|||
|
||||
INSTALL
|
||||
imapsync works fine under any Unix OS with perl.
|
||||
imapsync works fine under Windows (2000, XP)
|
||||
with Strawberry Perl 5.10 or 5.12
|
||||
imapsync works fine under Windows (2000, XP, Vista, Seven)
|
||||
with Strawberry Perl (5.10, 5.12 or higher)
|
||||
or as a standalone binary software imapsync.exe
|
||||
|
||||
imapsync can be available directly on the following distributions:
|
||||
|
@ -76,6 +77,9 @@ USAGE
|
|||
[--minsize <int>]
|
||||
[--maxage <int>]
|
||||
[--minage <int>]
|
||||
[--search <string>]
|
||||
[--search1 <string>]
|
||||
[--search2 <string>]
|
||||
[--skipheader <regex>]
|
||||
[--useheader <string>] [--useheader <string>]
|
||||
[--nouid1] [--nouid2]
|
||||
|
@ -101,7 +105,8 @@ DESCRIPTION
|
|||
The command imapsync is a tool allowing incremental and recursive imap
|
||||
transfer from one mailbox to another.
|
||||
|
||||
By default all folders are transferred, recursively.
|
||||
By default all folders are transferred, recursively, all possible flags
|
||||
(\Seen \Answered \Flagged etc.) are synced too.
|
||||
|
||||
We sometimes need to transfer mailboxes from one imap server to another.
|
||||
This is called migration.
|
||||
|
@ -115,7 +120,7 @@ DESCRIPTION
|
|||
|
||||
You can decide to delete the messages from the source mailbox after a
|
||||
successful transfer, it can be a good feature when migrating live
|
||||
mailboxes since messages will be only one side. In that case, use the
|
||||
mailboxes since messages will be only on one side. In that case, use the
|
||||
--delete option. Option --delete implies also option --expunge so all
|
||||
messages marked deleted on host1 will be really deleted. (you can use
|
||||
--noexpunge to avoid this but I don't see any good real world scenario
|
||||
|
@ -179,7 +184,8 @@ SECURITY
|
|||
on host1. In this case, --authmech1 PLAIN will be used by default since
|
||||
it is the only way to go for now. So don't use --authmech1 SOMETHING
|
||||
with --authuser1 "adminuser", it will not work. Same behavior with the
|
||||
--authuser2 option.
|
||||
--authuser2 option. Authenticate with an admin account must be supported
|
||||
by your imap server to work with imapsync.
|
||||
|
||||
When working on Sun/iPlanet/Netscape IMAP servers you must use
|
||||
--proxyauth1 to enable administrative user to masquerade as another
|
||||
|
@ -199,11 +205,11 @@ EXIT STATUS
|
|||
LICENSE
|
||||
imapsync is free, open, public but not always gratis software cover by
|
||||
the NOLIMIT Public License. See the LICENSE file included in the
|
||||
distribution or just read this: No limit to do anything with this work
|
||||
and this license.
|
||||
distribution or just read this simple sentence as it is the licence
|
||||
text: No limit to do anything with this work and this license.
|
||||
|
||||
MAILING-LIST
|
||||
The public mailing-list may be the best way to get support.
|
||||
The public mailing-list may be the best way to get free support.
|
||||
|
||||
To write on the mailing-list, the address is:
|
||||
<imapsync@linux-france.org>
|
||||
|
@ -218,7 +224,7 @@ MAILING-LIST
|
|||
To contact the person in charge for the list:
|
||||
<imapsync-request@listes.linux-france.org>
|
||||
|
||||
The list archives may be available at:
|
||||
The list archives are available at:
|
||||
http://www.linux-france.org/prj/imapsync_list/ So consider that the list
|
||||
is public, anyone can see your post. Use a pseudonym or do not post to
|
||||
this list if you want to stay private.
|
||||
|
@ -226,17 +232,15 @@ MAILING-LIST
|
|||
Thank you for your participation.
|
||||
|
||||
AUTHOR
|
||||
Gilles LAMIRAL <lamiral@linux-france.org>
|
||||
Gilles LAMIRAL <gilles.lamiral@laposte.net>
|
||||
|
||||
Feedback good or bad is always welcome.
|
||||
Feedback good or bad is very often welcome.
|
||||
|
||||
The newsgroup comp.mail.imap may be a good place to talk about imapsync.
|
||||
I read it when imapsync is concerned. A better place is the public
|
||||
imapsync mailing-list (see below).
|
||||
|
||||
Gilles LAMIRAL earns his living writing, installing, configuring and
|
||||
teaching free, open and often gratis softwares. Do not hesitate to pay
|
||||
him for that services.
|
||||
Gilles LAMIRAL earns his living by writing, installing, configuring and
|
||||
teaching free, open and often gratis softwares. It used to be "always
|
||||
gratis" but now it is "often" because imapsync is sold by its author, a
|
||||
good way to stay maintening and supporting free open public softwares
|
||||
(see the license) over decades.
|
||||
|
||||
BUG REPORT GUIDELINES
|
||||
Help us to help you: follow the following guidelines.
|
||||
|
@ -258,8 +262,8 @@ BUG REPORT GUIDELINES
|
|||
"problem", a good title is made of keywords summary, not too long (one
|
||||
visible line).
|
||||
|
||||
Don't write imapsync in uppercase in the email title, we'll know you run
|
||||
Windows and you haven't read this README yet.
|
||||
Don't write imapsync in uppercase in the email title, I'll then know you
|
||||
run Windows and you haven't read this README yet.
|
||||
|
||||
Help us to help you: in your report, please include:
|
||||
|
||||
|
@ -277,7 +281,8 @@ BUG REPORT GUIDELINES
|
|||
|
||||
- IMAPClient.pm version.
|
||||
|
||||
- the run context. Do you run imapsync.exe, a unix binary or the perl script imapsync.
|
||||
- the run context. Do you run imapsync.exe, a unix binary
|
||||
or the perl script imapsync.
|
||||
|
||||
- operating system running imapsync.
|
||||
|
||||
|
@ -287,7 +292,8 @@ BUG REPORT GUIDELINES
|
|||
you run imapsync on a foreign host from the both.
|
||||
|
||||
Most of those values can be found as a copy/paste at the begining of the
|
||||
output.
|
||||
output, so a copy of the output is a very easy and very good debug
|
||||
report for me.
|
||||
|
||||
One time in your life, read the paper "How To Ask Questions The Smart
|
||||
Way" http://www.catb.org/~esr/faqs/smart-questions.html and then forget
|
||||
|
@ -303,12 +309,15 @@ IMAP SERVERS
|
|||
- (2011) MDaemon 12.0.3 as host2 but MDaemon is supported as host1.
|
||||
MDaemon is simply buggy with the APPEND IMAP command with
|
||||
any IMAP email client.
|
||||
- Hotmail since hotmail.com does not provide IMAP access
|
||||
- Outlook.com since outlook.com does not provide IMAP access
|
||||
|
||||
Success stories reported with the following 48 imap servers (software
|
||||
Success stories reported with the following 52 imap servers (software
|
||||
names are in alphabetic order):
|
||||
|
||||
- 1und1 H mimap1 84498 [host1]
|
||||
- 1und1 H mimap1 84498 [host1] H mibap4 95231 [host1]
|
||||
- a1.net imap.a1.net IMAP4 Ready [host1]
|
||||
- Apple Server 10.6 Snow Leopard [host1]
|
||||
- Archiveopteryx 2.03, 2.04, 2.09, 2.10 [host2], 3.0.0 [host2]
|
||||
(OSL 3.0) http://www.archiveopteryx.org/
|
||||
- Axigen Mail Server Version 8.0.0
|
||||
|
@ -340,6 +349,7 @@ IMAP SERVERS
|
|||
- iPlanet Messaging server 4.15, 5.1, 5.2
|
||||
- IMail 7.15 (Ipswitch/Win2003), 8.12, 11.03 [host1]
|
||||
- Kerio 7.2.0 Patch 1 [host1] [host2]
|
||||
- Mail2World IMAP4 Server 2.5 [host1] (http://www.mail2world.com/)
|
||||
- MailEnable 4.23 [host1] [host2], 4.26 [host1][host2], 5 [host1]
|
||||
- MDaemon 7.0.1, 8.0.2, 8.1, 9.5.4 (Windows server 2003 R2 platform), 12 [host2],
|
||||
12.0.3 [host1], 12.5.5 [host1],
|
||||
|
@ -352,6 +362,7 @@ IMAP SERVERS
|
|||
- Mirapoint, 4.1.9-GA [host1]
|
||||
- Netscape Mail Server 3.6 (Wintel !)
|
||||
- Netscape Messaging Server 4.15 Patch 7
|
||||
- Office 365 [host1] [host2]
|
||||
- OpenMail IMAP server B.07.00.k0 (Samsung Contact ?)
|
||||
- OpenWave
|
||||
- Oracle Beehive [host1]
|
||||
|
@ -370,6 +381,8 @@ IMAP SERVERS
|
|||
- UW - QMail v2.1
|
||||
- VMS, Imap part of TCP/IP suite of VMS 7.3.2
|
||||
- Yahoo [host1]
|
||||
- Zarafa 6,40,0,20653 [host1] (http://www.zarafa.com/)
|
||||
- Zarafa ZCP 7.1.4 IMAP Gateway [host2]
|
||||
- Zimbra-IMAP 3.0.1 GA 160, 3.1.0 Build 279, 4.0.5, 4.5.2, 4.5.6,
|
||||
Zimbra 5.0.24_GA_3356.RHEL4 [host1], 5.5, 6.x
|
||||
|
||||
|
@ -445,5 +458,5 @@ SIMILAR SOFTWARES
|
|||
|
||||
Feedback (good or bad) will often be welcome.
|
||||
|
||||
$Id: imapsync,v 1.525 2013/02/05 12:52:10 gilles Exp gilles $
|
||||
$Id: imapsync,v 1.536 2013/04/17 14:33:12 gilles Exp gilles $
|
||||
|
||||
|
|
8
TODO
8
TODO
|
@ -1,5 +1,5 @@
|
|||
#!/bin/cat
|
||||
# $Id: TODO,v 1.118 2013/02/08 06:28:40 gilles Exp gilles $
|
||||
# $Id: TODO,v 1.119 2013/04/17 13:04:21 gilles Exp gilles $
|
||||
|
||||
TODO file for imapsync
|
||||
----------------------
|
||||
|
@ -23,6 +23,9 @@ http://www.yippiemove.com/
|
|||
http://www.migrationwiz.com/
|
||||
http://www.microsoft.com/download/en/details.aspx?id=1329 "Microsoft Transporter Suite"
|
||||
|
||||
Add an exit value when exiting because of --exitwhenover
|
||||
The goal is to know easily why to restart later.
|
||||
|
||||
Add --delete1 as an alias for --delete
|
||||
Add --mark-as-deleted1 --mark-as-deleted2 as
|
||||
aliases for --noexpunge1 --delete1 and --noexpunge2 --delete2
|
||||
|
@ -46,6 +49,9 @@ Fix long path over than 260 character on Win32.
|
|||
Think about Digest::SHA or Digest::SHA::PurePerl.
|
||||
Think about a file database like DBM instead.
|
||||
|
||||
Add OAUTH autentication support
|
||||
https://developers.google.com/google-apps/gmail/oauth_overview
|
||||
|
||||
Find a way to avoid passwords in --debugimap unless needed.
|
||||
|
||||
Explain that users can win time/bandwidth by using --expunge
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
1.525
|
||||
1.536
|
||||
|
|
|
@ -1 +1 @@
|
|||
1.525
|
||||
1.536
|
||||
|
|
|
@ -172,3 +172,15 @@
|
|||
1359421989 END 1.522 : mardi 29 janvier 2013, 02:13:09 (UTC+0100)
|
||||
1360108747 BEGIN 1.525 : mercredi 6 février 2013, 00:59:07 (UTC+0100)
|
||||
1360109581 END 1.525 : mercredi 6 février 2013, 01:13:01 (UTC+0100)
|
||||
1364528510 BEGIN 1.528 : vendredi 29 mars 2013, 04:41:51 (UTC+0100)
|
||||
1364529434 END 1.528 : vendredi 29 mars 2013, 04:57:14 (UTC+0100)
|
||||
1365000098 BEGIN 1.529 : mercredi 3 avril 2013, 16:41:38 (UTC+0200)
|
||||
1365001150 END 1.529 : mercredi 3 avril 2013, 16:59:10 (UTC+0200)
|
||||
1365595458 BEGIN 1.533 : mercredi 10 avril 2013, 14:04:18 (UTC+0200)
|
||||
1365596319 END 1.533 : mercredi 10 avril 2013, 14:18:39 (UTC+0200)
|
||||
1366126390 BEGIN 1.534 : mardi 16 avril 2013, 17:33:10 (UTC+0200)
|
||||
1366127411 END 1.534 : mardi 16 avril 2013, 17:50:11 (UTC+0200)
|
||||
1366202919 BEGIN 1.535 : mercredi 17 avril 2013, 14:48:39 (UTC+0200)
|
||||
1366203902 END 1.535 : mercredi 17 avril 2013, 15:05:02 (UTC+0200)
|
||||
1366209307 BEGIN 1.536 : mercredi 17 avril 2013, 16:35:07 (UTC+0200)
|
||||
1366210370 END 1.536 : mercredi 17 avril 2013, 16:52:50 (UTC+0200)
|
||||
|
|
|
@ -1,131 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
The "Artistic License"
|
||||
|
||||
Preamble
|
||||
|
||||
The intent of this document is to state the conditions under which a
|
||||
Package may be copied, such that the Copyright Holder maintains some
|
||||
semblance of artistic control over the development of the package,
|
||||
while giving the users of the package the right to use and distribute
|
||||
the Package in a more-or-less customary fashion, plus the right to make
|
||||
reasonable modifications.
|
||||
|
||||
Definitions:
|
||||
|
||||
"Package" refers to the collection of files distributed by the
|
||||
Copyright Holder, and derivatives of that collection of files
|
||||
created through textual modification.
|
||||
|
||||
"Standard Version" refers to such a Package if it has not been
|
||||
modified, or has been modified in accordance with the wishes
|
||||
of the Copyright Holder as specified below.
|
||||
|
||||
"Copyright Holder" is whoever is named in the copyright or
|
||||
copyrights for the package.
|
||||
|
||||
"You" is you, if you're thinking about copying or distributing
|
||||
this Package.
|
||||
|
||||
"Reasonable copying fee" is whatever you can justify on the
|
||||
basis of media cost, duplication charges, time of people involved,
|
||||
and so on. (You will not be required to justify it to the
|
||||
Copyright Holder, but only to the computing community at large
|
||||
as a market that must bear the fee.)
|
||||
|
||||
"Freely Available" means that no fee is charged for the item
|
||||
itself, though there may be fees involved in handling the item.
|
||||
It also means that recipients of the item may redistribute it
|
||||
under the same conditions they received it.
|
||||
|
||||
1. You may make and give away verbatim copies of the source form of the
|
||||
Standard Version of this Package without restriction, provided that you
|
||||
duplicate all of the original copyright notices and associated disclaimers.
|
||||
|
||||
2. You may apply bug fixes, portability fixes and other modifications
|
||||
derived from the Public Domain or from the Copyright Holder. A Package
|
||||
modified in such a way shall still be considered the Standard Version.
|
||||
|
||||
3. You may otherwise modify your copy of this Package in any way, provided
|
||||
that you insert a prominent notice in each changed file stating how and
|
||||
when you changed that file, and provided that you do at least ONE of the
|
||||
following:
|
||||
|
||||
a) place your modifications in the Public Domain or otherwise make them
|
||||
Freely Available, such as by posting said modifications to Usenet or
|
||||
an equivalent medium, or placing the modifications on a major archive
|
||||
site such as uunet.uu.net, or by allowing the Copyright Holder to include
|
||||
your modifications in the Standard Version of the Package.
|
||||
|
||||
b) use the modified Package only within your corporation or organization.
|
||||
|
||||
c) rename any non-standard executables so the names do not conflict
|
||||
with standard executables, which must also be provided, and provide
|
||||
a separate manual page for each non-standard executable that clearly
|
||||
documents how it differs from the Standard Version.
|
||||
|
||||
d) make other distribution arrangements with the Copyright Holder.
|
||||
|
||||
4. You may distribute the programs of this Package in object code or
|
||||
executable form, provided that you do at least ONE of the following:
|
||||
|
||||
a) distribute a Standard Version of the executables and library files,
|
||||
together with instructions (in the manual page or equivalent) on where
|
||||
to get the Standard Version.
|
||||
|
||||
b) accompany the distribution with the machine-readable source of
|
||||
the Package with your modifications.
|
||||
|
||||
c) give non-standard executables non-standard names, and clearly
|
||||
document the differences in manual pages (or equivalent), together
|
||||
with instructions on where to get the Standard Version.
|
||||
|
||||
d) make other distribution arrangements with the Copyright Holder.
|
||||
|
||||
5. You may charge a reasonable copying fee for any distribution of this
|
||||
Package. You may charge any fee you choose for support of this
|
||||
Package. You may not charge a fee for this Package itself. However,
|
||||
you may distribute this Package in aggregate with other (possibly
|
||||
commercial) programs as part of a larger (possibly commercial) software
|
||||
distribution provided that you do not advertise this Package as a
|
||||
product of your own. You may embed this Package's interpreter within
|
||||
an executable of yours (by linking); this shall be construed as a mere
|
||||
form of aggregation, provided that the complete Standard Version of the
|
||||
interpreter is so embedded.
|
||||
|
||||
6. The scripts and library files supplied as input to or produced as
|
||||
output from the programs of this Package do not automatically fall
|
||||
under the copyright of this Package, but belong to whoever generated
|
||||
them, and may be sold commercially, and may be aggregated with this
|
||||
Package. If such scripts or library files are aggregated with this
|
||||
Package via the so-called "undump" or "unexec" methods of producing a
|
||||
binary executable image, then distribution of such an image shall
|
||||
neither be construed as a distribution of this Package nor shall it
|
||||
fall under the restrictions of Paragraphs 3 and 4, provided that you do
|
||||
not represent such an executable image as a Standard Version of this
|
||||
Package.
|
||||
|
||||
7. C subroutines (or comparably compiled subroutines in other
|
||||
languages) supplied by you and linked into this Package in order to
|
||||
emulate subroutines and variables of the language defined by this
|
||||
Package shall not be considered part of this Package, but are the
|
||||
equivalent of input as in Paragraph 6, provided these subroutines do
|
||||
not change the language in any way that would cause it to fail the
|
||||
regression tests for the language.
|
||||
|
||||
8. Aggregation of this Package with a commercial distribution is always
|
||||
permitted provided that the use of this Package is embedded; that is,
|
||||
when no overt attempt is made to make this Package's interfaces visible
|
||||
to the end user of the commercial distribution. Such use shall not be
|
||||
construed as a distribution of this Package.
|
||||
|
||||
9. The name of the Copyright Holder may not be used to endorse or promote
|
||||
products derived from this software without specific prior written permission.
|
||||
|
||||
10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
The End
|
|
@ -1,9 +0,0 @@
|
|||
REPORING BUGS
|
||||
|
||||
See the section on "REPORTING BUGS" in the module's documentation if you are
|
||||
having problems.
|
||||
|
||||
YOU MUST FOLLOW THE INSTRUCTIONS IN THE DOCUMENTATION AND PROVIDE ALL OF THE NECESSARY
|
||||
INFORMATION if you expect a response from your bug report. You should also look at
|
||||
the data you gather before you send it, since doing so will often solve your problem.
|
||||
|
|
@ -1,725 +0,0 @@
|
|||
package Mail::IMAPClient::BodyStructure;
|
||||
#$Id: BodyStructure.pm,v 1.3 2003/06/12 21:41:37 dkernen Exp $
|
||||
#use Parse::RecDescent;
|
||||
use Mail::IMAPClient;
|
||||
use Mail::IMAPClient::BodyStructure::Parse;
|
||||
use vars qw/$parser/;
|
||||
use Exporter;
|
||||
push @ISA, "Exporter";
|
||||
push @EXPORT_OK , '$parser';
|
||||
|
||||
$Mail::IMAPClient::BodyStructure::VERSION = '0.0.2';
|
||||
# Do it once more to show we mean it!
|
||||
$Mail::IMAPClient::BodyStructure::VERSION = '0.0.2';
|
||||
|
||||
$parser = Mail::IMAPClient::BodyStructure::Parse->new()
|
||||
|
||||
or die "Cannot parse rules: $@\n" .
|
||||
"Try remaking Mail::IMAPClient::BodyStructure::Parse.\n"
|
||||
and return undef;
|
||||
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $bodystructure = shift;
|
||||
my $self = $parser->start($bodystructure) or return undef;
|
||||
$self->{_prefix} = "";
|
||||
|
||||
if ( exists $self->{bodystructure} ) {
|
||||
$self->{_id} = 'HEAD' ;
|
||||
} else {
|
||||
$self->{_id} = 1;
|
||||
}
|
||||
|
||||
$self->{_top} = 1;
|
||||
|
||||
return bless($self ,ref($class)||$class);
|
||||
}
|
||||
|
||||
sub _get_thingy {
|
||||
my $thingy = shift;
|
||||
my $object = shift||(ref($thingy)?$thingy:undef);
|
||||
unless ( defined($object) and ref($object) ) {
|
||||
$@ = "No argument passed to $thingy method." ;
|
||||
$^W and print STDERR "$@\n" ;
|
||||
return undef;
|
||||
}
|
||||
unless ( "$object" =~ /HASH/
|
||||
and exists($object->{$thingy})
|
||||
) {
|
||||
$@ = ref($object) .
|
||||
" $object does not have " .
|
||||
( $thingy =~ /^[aeiou]/i ? "an " : "a " ) .
|
||||
"${thingy}. " .
|
||||
( ref($object) =~ /HASH/ ? "It has " . join(", ",keys(%$object)) : "") ;
|
||||
$^W and print STDERR "$@\n" ;
|
||||
return undef;
|
||||
}
|
||||
return Unwrapped($object->{$thingy});
|
||||
}
|
||||
|
||||
BEGIN {
|
||||
foreach my $datum (qw/ bodytype bodysubtype bodyparms bodydisp bodyid
|
||||
bodydesc bodyenc bodysize bodylang
|
||||
envelopestruct textlines
|
||||
/
|
||||
) {
|
||||
no strict 'refs';
|
||||
*$datum = sub { _get_thingy($datum, @_); };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub parts {
|
||||
my $self = shift;
|
||||
|
||||
|
||||
if ( exists $self->{PartsList} ) {
|
||||
return wantarray ? @{$self->{PartsList}} : $self->{PartsList} ;
|
||||
}
|
||||
|
||||
my @parts = ();
|
||||
$self->{PartsList} = \@parts;
|
||||
|
||||
unless ( exists($self->{bodystructure}) ) {
|
||||
$self->{PartsIndex}{1} = $self ;
|
||||
@parts = ("HEAD",1);
|
||||
return wantarray ? @parts : \@parts;
|
||||
}
|
||||
#@parts = ( 1 );
|
||||
#} else {
|
||||
|
||||
foreach my $p ($self->bodystructure()) {
|
||||
push @parts, $p->id();
|
||||
$self->{PartsIndex}{$p->id()} = $p ;
|
||||
if ( uc($p->bodytype()||"") eq "MESSAGE" ) {
|
||||
#print "Part $parts[-1] is a ",$p->bodytype,"\n";
|
||||
push @parts,$parts[-1] . ".HEAD";
|
||||
#} else {
|
||||
# print "Part $parts[-1] is a ",$p->bodytype,"\n";
|
||||
}
|
||||
}
|
||||
|
||||
#}
|
||||
|
||||
return wantarray ? @parts : \@parts;
|
||||
}
|
||||
|
||||
sub oldbodystructure {
|
||||
my $self = shift;
|
||||
if ( exists $self->{_bodyparts} ) {
|
||||
return wantarray ? @{$self->{_bodyparts}} : $self->{_bodyparts} ;
|
||||
}
|
||||
my @bodyparts = ( $self );
|
||||
$self->{_id} ||= "HEAD"; # aka "0"
|
||||
my $count = 0;
|
||||
#print STDERR "Analyzing a ",$self->bodytype, " part which I think is part number ",
|
||||
# $self->{_id},"\n";
|
||||
my $dump = Data::Dumper->new( [ $self ] , [ 'bodystructure' ] );
|
||||
$dump->Indent(1);
|
||||
|
||||
foreach my $struct (@{$self->{bodystructure}}) {
|
||||
$struct->{_prefix} ||= $self->{_prefix} . +$count . "." unless $struct->{_top};
|
||||
$struct->{_id} ||= $self->{_prefix} . $count unless $struct->{_top};
|
||||
#if (
|
||||
# uc($struct->bodytype) eq 'MULTIPART' or
|
||||
# uc($struct->bodytype) eq 'MESSAGE'
|
||||
#) {
|
||||
#} else {
|
||||
#}
|
||||
push @bodyparts, $struct,
|
||||
ref($struct->{bodystructure}) ? $struct->bodystructure : () ;
|
||||
}
|
||||
$self->{_bodyparts} = \@bodyparts ;
|
||||
return wantarray ? @bodyparts : $self->bodyparts ;
|
||||
}
|
||||
|
||||
sub bodystructure {
|
||||
my $self = shift;
|
||||
my @parts = ();
|
||||
my $partno = 0;
|
||||
|
||||
my $prefix = $self->{_prefix} || "";
|
||||
|
||||
#print STDERR "Analyzing a ",($self->bodytype||"unknown ") ,
|
||||
# " part which I think is part number ",
|
||||
# $self->{_id},"\n";
|
||||
|
||||
my $bs = $self;
|
||||
$prefix = "$prefix." if ( $prefix and $prefix !~ /\.$/);
|
||||
|
||||
if ( $self->{_top} ) {
|
||||
$self->{_id} ||= "HEAD";
|
||||
$self->{_prefix} ||= "HEAD";
|
||||
$partno = 0;
|
||||
for (my $x = 0; $x < scalar(@{$self->{bodystructure}}) ; $x++) {
|
||||
$self->{bodystructure}[$x]{_id} = ++$partno ;
|
||||
$self->{bodystructure}[$x]{_prefix} = $partno ;
|
||||
push @parts, $self->{bodystructure}[$x] ,
|
||||
$self->{bodystructure}[$x]->bodystructure;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
$partno = 0;
|
||||
foreach my $p ( @{$self->{bodystructure}} ) {
|
||||
$partno++;
|
||||
if (
|
||||
! exists $p->{_prefix}
|
||||
) {
|
||||
$p->{_prefix} = "$prefix$partno";
|
||||
}
|
||||
$p->{_prefix} = "$prefix$partno";
|
||||
$p->{_id} ||= "$prefix$partno";
|
||||
#my $bt = $p->bodytype;
|
||||
#if ($bt eq 'MESSAGE') {
|
||||
#$p->{_id} = $prefix .
|
||||
#$partno = 0;
|
||||
#}
|
||||
push @parts, $p, $p->{bodystructure} ? $p->bodystructure : ();
|
||||
}
|
||||
}
|
||||
|
||||
return wantarray ? @parts : \@parts;
|
||||
}
|
||||
|
||||
sub id {
|
||||
my $self = shift;
|
||||
|
||||
return $self->{_id} if exists $self->{_id};
|
||||
return "HEAD" if $self->{_top};
|
||||
#if ($self->bodytype eq 'MESSAGE') {
|
||||
# return
|
||||
#}
|
||||
|
||||
if ($self->{bodytype} eq 'MULTIPART') {
|
||||
my $p = $self->{_id}||$self->{_prefix} ;
|
||||
$p =~ s/\.$//;
|
||||
return $p;
|
||||
} else {
|
||||
return $self->{_id} ||= 1;
|
||||
}
|
||||
}
|
||||
|
||||
sub Unwrapped {
|
||||
my $unescape = Mail::IMAPClient::Unescape(@_);
|
||||
$unescape =~ s/^"(.*)"$/$1/ if defined($unescape);
|
||||
return $unescape;
|
||||
}
|
||||
|
||||
package Mail::IMAPClient::BodyStructure::Part;
|
||||
@ISA = qw/Mail::IMAPClient::BodyStructure/;
|
||||
|
||||
|
||||
package Mail::IMAPClient::BodyStructure::Envelope;
|
||||
@ISA = qw/Mail::IMAPClient::BodyStructure/;
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $envelope = shift;
|
||||
my $self = $Mail::IMAPClient::BodyStructure::parser->envelope($envelope);
|
||||
return $self;
|
||||
}
|
||||
|
||||
|
||||
sub _do_accessor {
|
||||
my $datum = shift;
|
||||
if (scalar(@_) > 1) {
|
||||
return $_[0]->{$datum} = $_[1] ;
|
||||
} else {
|
||||
return $_[0]->{$datum};
|
||||
}
|
||||
}
|
||||
|
||||
# the following for loop sets up accessor methods for
|
||||
# the object's address attributes:
|
||||
|
||||
sub _mk_address_method {
|
||||
my $datum = shift;
|
||||
my $method1 = $datum . "_addresses" ;
|
||||
no strict 'refs';
|
||||
*$method1 = sub {
|
||||
my $self = shift;
|
||||
return undef unless ref($self->{$datum}) eq 'ARRAY';
|
||||
my @list = map {
|
||||
my $pn = $_->personalname ;
|
||||
$pn = "" if $pn eq 'NIL' ;
|
||||
( $pn ? "$pn " : "" ) .
|
||||
"<" .
|
||||
$_->mailboxname .
|
||||
'@' .
|
||||
$_->hostname .
|
||||
">"
|
||||
} @{$self->{$datum}} ;
|
||||
if ( $senderFields{$datum} ) {
|
||||
return wantarray ? @list : $list[0] ;
|
||||
} else {
|
||||
return wantarray ? @list : \@list ;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
BEGIN {
|
||||
|
||||
for my $datum (
|
||||
qw( subject inreplyto from messageid bcc date replyto to sender cc )
|
||||
) {
|
||||
no strict 'refs';
|
||||
*$datum = sub { _do_accessor($datum, @_); };
|
||||
}
|
||||
my %senderFields = map { ($_ => 1) } qw/from sender replyto/ ;
|
||||
for my $datum (
|
||||
qw( from bcc replyto to sender cc )
|
||||
) {
|
||||
_mk_address_method($datum);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
package Mail::IMAPClient::BodyStructure::Address;
|
||||
@ISA = qw/Mail::IMAPClient::BodyStructure/;
|
||||
|
||||
for my $datum (
|
||||
qw( personalname mailboxname hostname sourcename )
|
||||
) {
|
||||
no strict 'refs';
|
||||
*$datum = sub { return $_[0]->{$datum}; };
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Mail::IMAPClient::BodyStructure - Perl extension to Mail::IMAPClient to facilitate
|
||||
the parsing of server responses to the FETCH BODYSTRUCTURE and FETCH ENVELOPE
|
||||
IMAP client commands.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Mail::IMAPClient::BodyStructure;
|
||||
use Mail::IMAPClient;
|
||||
|
||||
my $imap = Mail::IMAPClient->new(Server=>$serv,User=>$usr,Password=>$pwd);
|
||||
$imap->select("INBOX") or die "cannot select the inbox for $usr: $@\n";
|
||||
|
||||
my @recent = $imap->search("recent");
|
||||
|
||||
foreach my $new (@recent) {
|
||||
|
||||
my $struct = Mail::IMAPClient::BodyStructure->new(
|
||||
$imap->fetch($new,"bodystructure")
|
||||
);
|
||||
|
||||
print "Msg $new (Content-type: ",$struct->bodytype,"/",$struct->bodysubtype,
|
||||
") contains these parts:\n\t",join("\n\t",$struct->parts),"\n\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 that will help you pull information out
|
||||
of the data structure.
|
||||
|
||||
Use of this extension requires Parse::RecDescent. If you don't have Parse::RecDescent
|
||||
then you must either get it or refrain from using this module.
|
||||
|
||||
=head2 EXPORT
|
||||
|
||||
Nothing is exported by default. C<$parser> is exported upon request. C<$parser>
|
||||
is the BodyStucture object's Parse::RecDescent object, which you'll probably
|
||||
only need for debugging purposes.
|
||||
|
||||
=head1 Class Methods
|
||||
|
||||
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.
|
||||
Only one message's body structure should be described in this
|
||||
string, although that message may contain an arbitrary number of parts.
|
||||
|
||||
If you know the messages sequence number or unique ID (UID) but haven't got its
|
||||
body structure, and you want to get the body structure and parse it into a
|
||||
B<Mail::IMAPClient::BodyStructure> object, then you might as well save yourself
|
||||
some work and use B<Mail::IMAPClient>'s B<get_bodystructure> method, which
|
||||
accepts a message sequence number (or UID if I<Uid> is true) and returns a
|
||||
B<Mail::IMAPClient::BodyStructure> object. It's functionally equivalent to issuing the
|
||||
FETCH BODYSTRUCTURE IMAP client command and then passing the results to
|
||||
B<Mail::IMAPClient::BodyStructure>'s B<new> method but it does those things in one
|
||||
simple method call.
|
||||
|
||||
=head1 Object Methods
|
||||
|
||||
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.
|
||||
|
||||
=cut
|
||||
|
||||
=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.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
|
||||
=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.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
|
||||
=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.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
|
||||
=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.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
|
||||
=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.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
|
||||
=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.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
|
||||
=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.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
|
||||
=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.
|
||||
|
||||
=cut
|
||||
|
||||
=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.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
|
||||
=head2 envelopestruct
|
||||
|
||||
The B<envelopestruct> object method requires no arguments.
|
||||
It returns the envelopestruct for the message whose structure is described by the
|
||||
calling B<Mail::IMAPClient::Bodystructure> object. This envelope structure is blessed
|
||||
into the B<Mail::IMAPClient::BodyStructure::Envelope> subclass, which is explained more
|
||||
fully below.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
=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.
|
||||
|
||||
=cut
|
||||
|
||||
=head1 Envelopes and the Mail::IMAPClient::BodyStructure::Envelope Subclass
|
||||
|
||||
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
|
||||
|
||||
David J. Kernen
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
perl(1), Mail::IMAPClient, and RFC2060. See also Parse::RecDescent if you want
|
||||
to understand the internals of this module.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
# History:
|
||||
# $Log: BodyStructure.pm,v $
|
||||
# Revision 1.3 2003/06/12 21:41:37 dkernen
|
||||
# Cleaning up cvs repository
|
||||
#
|
||||
# Revision 1.1 2003/06/12 21:37:03 dkernen
|
||||
#
|
||||
# Preparing 2.2.8
|
||||
# Added Files: COPYRIGHT
|
||||
# Modified Files: Parse.grammar
|
||||
# Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
#
|
||||
# Revision 1.2 2002/09/26 17:56:14 dkernen
|
||||
#
|
||||
# Modified Files:
|
||||
# BUG_REPORTS Changes IMAPClient.pm INSTALL_perl5.80 MANIFEST
|
||||
# Makefile.PL for version 2.2.3. See the Changes file for details.
|
||||
# Modified Files: BodyStructure.pm -- cosmetic changes to pod doc
|
||||
#
|
||||
# Revision 1.1 2002/08/30 20:58:51 dkernen
|
||||
#
|
||||
# In Mail::IMAPClient/IMAPClient, added files: BUG_REPORTS getGrammer runtest sample.perldb
|
||||
# In Mail::IMAPClient/IMAPClient/BodyStructure, added files: BodyStructure.pm Makefile.PL debug.ksh runtest
|
||||
#
|
|
@ -1,21 +0,0 @@
|
|||
COPYRIGHT
|
||||
|
||||
Copyright 1999, 2000, 2001, 2002 , 2003 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:
|
||||
|
||||
|
||||
a) the "Artistic License" which comes with this Kit, or
|
||||
|
||||
b) the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 1, or (at your option) any later version.
|
||||
|
||||
|
||||
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.
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
use ExtUtils::MakeMaker;
|
||||
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
|
||||
# the contents of the Makefile that is written.
|
||||
WriteMakefile(
|
||||
'DIR' => [ 'Parse' ] ,
|
||||
'NAME' => 'Mail::IMAPClient::BodyStructure',
|
||||
'VERSION_FROM' => '../IMAPClient.pm', # finds $VERSION
|
||||
'PREREQ_PM' => {
|
||||
"Parse::RecDescent" => '1.94',
|
||||
"Exporter" => 0,
|
||||
},
|
||||
);
|
|
@ -1,46 +0,0 @@
|
|||
use ExtUtils::MakeMaker;
|
||||
use Parse::RecDescent;
|
||||
|
||||
unlink "./Parse.pm" if -f "./Parse.pm";
|
||||
sub MY::top_targets {
|
||||
package MY;
|
||||
|
||||
my $inherit = shift->SUPER::top_targets(@_);
|
||||
my @inherit = split("\n",$inherit);
|
||||
for (@inherit) {
|
||||
if ( /^\s*all\s*:{1,2}/ ) {
|
||||
s/(all\s*:{1,2}\s*)/$1Parse\.pm /;
|
||||
}
|
||||
}
|
||||
return join("\n",@inherit);
|
||||
}
|
||||
|
||||
sub MY::clean {
|
||||
package MY;
|
||||
|
||||
my $inherit = shift->SUPER::clean(@_);
|
||||
return join("\n",$inherit," rm Parse.pm") ;
|
||||
}
|
||||
|
||||
sub MY::postamble {
|
||||
my $string =
|
||||
'@$(PERL) "-MParse::RecDescent" "-" ' .
|
||||
'"Parse.grammar" '.
|
||||
'"Mail::IMAPClient::BodyStructure::Parse"' ;
|
||||
return "Parse.pm: Parse.grammar\n\t$string\n\n";
|
||||
}
|
||||
|
||||
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
|
||||
# the contents of the Makefile that is written.
|
||||
#print "",MY->top_target;
|
||||
|
||||
WriteMakefile(
|
||||
'NAME' => 'Mail::IMAPClient::Parse',
|
||||
'VERSION_FROM' => '../../IMAPClient.pm',
|
||||
'PREREQ_PM' => {"Parse::RecDescent" => 0 },
|
||||
'PM' => {
|
||||
'Parse.pm' =>
|
||||
'$(INST_LIBDIR)/BodyStructure/Parse.pm'
|
||||
},
|
||||
);
|
||||
|
|
@ -1,288 +0,0 @@
|
|||
# Directives
|
||||
# ( none)
|
||||
# Start-up Actions
|
||||
|
||||
{
|
||||
my $subpartCount = 0;
|
||||
my $partCount = 0;
|
||||
}
|
||||
|
||||
#
|
||||
# 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" }
|
||||
NUMBER: /^(\d+)/ { $return = $item[1]; $return||defined($return);}
|
||||
|
||||
# Strings:
|
||||
|
||||
SINGLE_QUOTED_STRING: "'" /(?:\\'|[^'])*/ "'" {
|
||||
|
||||
$return = $item{__PATTERN1__} ;
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
DOUBLE_QUOTED_STRING: '"' /(?:\\"|[^"])*/ '"' {
|
||||
|
||||
$return = $item{__PATTERN1__} ;
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
QUOTED_STRING: DOUBLE_QUOTED_STRING | SINGLE_QUOTED_STRING {
|
||||
|
||||
$return = $item{DOUBLE_QUOTED_STRING}||$item{SINGLE_QUOTED_STRING} ;
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
BARESTRING: ...!/^[)('"]/ /^(?!\(|\))(?:\\ |\S)+/ {
|
||||
$return = $item{__PATTERN1__} ; $return||defined($return);
|
||||
}
|
||||
|
||||
STRING: QUOTED_STRING | BARESTRING {
|
||||
$return = $item{QUOTED_STRING}||$item{BARESTRING} ;
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
OLDSTRING: /^"((?:[^"\\]|\\.)*)"/ | /^([^ \(\)]+)/
|
||||
{ $item{__PATTERN1__} =~ s/^"(.*)"$/$1/;
|
||||
$return = $item{__PATTERN1__} || $item{__PATTERN2__} ;
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
#BARESTRING: /^[^(]+\s+(?=\()/
|
||||
# { $return = $item[1] ; $return||defined($return);}
|
||||
|
||||
textlines: NIL | NUMBER { $return = $item[1] || $item[2]; $return||defined($return); }
|
||||
rfc822message: MESSAGE RFC822 { $return = "MESSAGE RFC822" }
|
||||
key: STRING { $return = $item{STRING} ; $return||defined($return);}
|
||||
value: NIL | '(' <commit> kvpair(s) ')'| NUMBER | STRING
|
||||
{ $return = $item{NIL} ||
|
||||
$item{NUMBER} ||
|
||||
$item{STRING} ||
|
||||
{ map { (%$_) } @{$item{'kvpair(s)'}} } ;
|
||||
$return||defined($return);
|
||||
}
|
||||
kvpair: ...!")" key value
|
||||
{ $return = { $item{key} => $item{value} }; $return||defined($return);}
|
||||
bodytype: STRING
|
||||
{ $return = $item{STRING} ; $return||defined($return);}
|
||||
bodysubtype: PLAIN | HTML | NIL | STRING
|
||||
{ $return = $item{PLAIN}||$item{HTML}||$item{NIL}||$item{STRING} ;
|
||||
$return||defined($return);
|
||||
}
|
||||
bodyparms: NIL | '(' kvpair(s) ')'
|
||||
{
|
||||
$return = $item{NIL} ||
|
||||
{ map { (%$_) } @{$item{'kvpair(s)'}} };
|
||||
$return || defined($return);
|
||||
}
|
||||
bodydisp: NIL | '(' kvpair(s) ')'
|
||||
{
|
||||
$return = $item{NIL} ||
|
||||
{ map { (%$_) } @{$item{'kvpair(s)'}} };
|
||||
$return || defined($return);
|
||||
}
|
||||
bodyid: ...!/[()]/ NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ; $return||defined($return);}
|
||||
bodydesc: ...!/[()]/ NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ; $return||defined($return);}
|
||||
bodyenc: NIL | STRING | '(' kvpair(s) ')'
|
||||
{
|
||||
$return = $item{NIL} ||
|
||||
$item{STRING} ||
|
||||
{ map { (%$_) } @{$item{'kvpair(s)'}} };
|
||||
$return||defined($return);
|
||||
}
|
||||
bodysize: ...!/[()]/ NIL | NUMBER
|
||||
{ $return = $item{NIL} || $item{NUMBER} ;$return||defined($return);}
|
||||
|
||||
bodyMD5: NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ;$return||defined($return);}
|
||||
bodylang: NIL | STRING | "(" STRING(s) ")"
|
||||
{ $return = $item{NIL} || $item{'STRING(s)'} ;$return||defined($return);}
|
||||
personalname: NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ;$return||defined($return);}
|
||||
sourceroute: NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ;$return||defined($return);}
|
||||
mailboxname: NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ;$return||defined($return);}
|
||||
hostname: NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ;$return||defined($return);}
|
||||
addressstruct: "(" personalname sourceroute mailboxname hostname ")"
|
||||
{ $return = {
|
||||
personalname => $item{personalname} ,
|
||||
sourceroute => $item{sourceroute} ,
|
||||
mailboxname => $item{mailboxname} ,
|
||||
hostname => $item{hostname} ,
|
||||
} ;
|
||||
bless($return, "Mail::IMAPClient::BodyStructure::Address");
|
||||
}
|
||||
subject: NIL | STRING
|
||||
{
|
||||
$return = $item{NIL} || $item{STRING} ;
|
||||
$return||defined($return);
|
||||
}
|
||||
inreplyto: NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ;$return||defined($return);}
|
||||
|
||||
messageid: NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ;$return||defined($return);}
|
||||
|
||||
date: NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ;$return||defined($return);}
|
||||
|
||||
cc: NIL | "(" addressstruct(s) ")"
|
||||
{ $return = $item{NIL} || $item{'addressstruct(s)'} }
|
||||
|
||||
bcc: NIL | "(" addressstruct(s) ")"
|
||||
{ $return = $item{NIL} || $item{'addressstruct(s)'} }
|
||||
|
||||
from: NIL | "(" addressstruct(s) ")"
|
||||
{ $return = $item{NIL} || $item{'addressstruct(s)'} }
|
||||
|
||||
replyto: NIL | "(" addressstruct(s) ")"
|
||||
{ $return = $item{NIL} || $item{'addressstruct(s)'} }
|
||||
|
||||
sender: NIL | "(" addressstruct(s) ")"
|
||||
{ $return = $item{NIL} || $item{'addressstruct(s)'} }
|
||||
|
||||
to: NIL | "(" addressstruct(s) ")"
|
||||
{ $return = $item{NIL} || $item{'addressstruct(s)'} }
|
||||
|
||||
envelopestruct: "(" date subject from sender replyto to cc bcc inreplyto messageid ")"
|
||||
{ $return = {};
|
||||
foreach my $what (qw/date subject from sender replyto to cc bcc inreplyto messageid/) {
|
||||
$return->{$what} = $item{$what};
|
||||
}
|
||||
bless $return, "Mail::IMAPClient::BodyStructure::Envelope";
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
basicfields: bodysubtype bodyparms bodyid(?)
|
||||
bodydesc(?) bodyenc(?)
|
||||
bodysize(?) {
|
||||
|
||||
$return = {
|
||||
bodysubtype => $item{bodysubtype} ,
|
||||
|
||||
bodyparms => $item{bodyparms} ,
|
||||
|
||||
bodyid => (ref $item{'bodyid(?)'} ?
|
||||
$item{'bodyid(?)'}[0] :
|
||||
$item{'bodyid(?)'} ),
|
||||
|
||||
'bodydesc' => (ref $item{'bodydesc(?)'} ?
|
||||
$item{'bodydesc(?)'}[0] :
|
||||
$item{'bodydesc(?)'} ),
|
||||
|
||||
'bodyenc' => (ref $item{'bodyenc(?)'} ?
|
||||
$item{'bodyenc(?)'}[0] :
|
||||
$item{'bodyenc(?)'} ),
|
||||
|
||||
'bodysize' => (ref $item{'bodysize(?)'} ?
|
||||
$item{'bodysize(?)'}[0] :
|
||||
$item{'bodysize(?)'} ),
|
||||
};
|
||||
$return;
|
||||
}
|
||||
|
||||
textmessage: TEXT <commit> basicfields textlines(?) bodyMD5(?) bodydisp(?) bodylang(?)
|
||||
{
|
||||
$return = $item{basicfields}||{};
|
||||
$return->{bodytype} = 'TEXT';
|
||||
foreach my $what (qw/textlines(?) bodyMD5(?) bodydisp(?) bodylang(?)/) {
|
||||
my $k = $what; $k =~ s/\(\?\)$//;
|
||||
ref($item{$what}) and $return->{$k} = $item{$what}[0];
|
||||
}
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
othertypemessage: bodytype basicfields bodyparms(?) bodydisp(?) bodylang(?)
|
||||
{ $return = {};
|
||||
foreach my $what (qw/bodytype bodyparms(?) bodydisp(?) bodylang(?)/) {
|
||||
my $k = $what; $k =~ s/\(\?\)$//;
|
||||
$return->{$k} = ref($item{$what})? $item{$what}[0] : $item{$what} ;
|
||||
}
|
||||
while ( my($k,$v) = each %{$item{basicfields}} ) { $return->{$k} = $v }
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
messagerfc822message:
|
||||
rfc822message <commit> bodyparms bodyid bodydesc bodyenc bodysize
|
||||
envelopestruct bodystructure textlines
|
||||
bodyMD5(?) bodydisp(?) bodylang(?)
|
||||
{
|
||||
$return = {};
|
||||
foreach my $what (qw/ bodyparms bodyid bodydesc bodyenc bodysize
|
||||
envelopestruct bodystructure textlines
|
||||
bodyMD5(?) bodydisp(?) bodylang(?)
|
||||
/
|
||||
) {
|
||||
my $k = $what; $k =~ s/\(\?\)$//;
|
||||
$return->{$k} = ref $item{$what} =~ 'ARRAY'?
|
||||
$item{$what}[0] : $item{$what};
|
||||
}
|
||||
while ( my($k,$v) = each %{$item{bodystructure}[0]} ) { $return->{$k} = $v }
|
||||
while ( my($k,$v) = each %{$item{basicfields}} ) { $return->{$k} = $v }
|
||||
$return->{bodytype} = "MESSAGE" ;
|
||||
$return->{bodysubtype}= "RFC822" ;
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
subpart: "(" part ")"
|
||||
{
|
||||
$return = $item{part} ;
|
||||
$return||defined($return);
|
||||
} <defer: ++$subpartCount;>
|
||||
|
||||
|
||||
part: subpart(s) <commit> basicfields
|
||||
bodyparms(?) bodydisp(?) bodylang(?)
|
||||
<defer: $subpartCount = 0>
|
||||
{
|
||||
$return = bless($item{basicfields},
|
||||
"Mail::IMAPClient::BodyStructure");
|
||||
$return->{bodytype} = "MULTIPART";
|
||||
$return->{bodystructure} = $item{'subpart(s)'};
|
||||
foreach my $b (qw/bodyparms(?) bodydisp(?) bodylang(?)/) {
|
||||
my $k = $b; $k =~ s/\(\?\)$//;
|
||||
$return->{$k} = ref($item{$b}) ? $item{$b}[0] : $item{$b};
|
||||
}
|
||||
$return||defined($return) ;
|
||||
}
|
||||
| textmessage
|
||||
{
|
||||
$return = bless $item{textmessage}, "Mail::IMAPClient::BodyStructure";
|
||||
$return||defined($return);
|
||||
}
|
||||
| messagerfc822message
|
||||
{
|
||||
$return = bless $item{messagerfc822message}, "Mail::IMAPClient::BodyStructure";
|
||||
$return||defined($return);
|
||||
}
|
||||
| othertypemessage
|
||||
{
|
||||
$return = bless $item{othertypemessage}, "Mail::IMAPClient::BodyStructure";
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
bodystructure: "(" part(s) ")"
|
||||
{
|
||||
$return = $item{'part(s)'} ;
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
start: /.*\(.*BODYSTRUCTURE \(/i part(1) /\).*\)\r?\n?/
|
||||
{
|
||||
#print STDERR "item = ",Data::Dumper->Dump([\%item],['$item']);
|
||||
$return = $item{'part(1)'}[0];
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
envelope: /.*\(.*ENVELOPE/ envelopestruct /.*\)/ {
|
||||
$return = $item{envelopestruct} ;
|
||||
$return||defined($return) ;
|
||||
}
|
|
@ -1,281 +0,0 @@
|
|||
# Directives
|
||||
# ( none)
|
||||
# Start-up Actions
|
||||
{
|
||||
my $subpartCount = 0;
|
||||
my $partCount = 0;
|
||||
}
|
||||
|
||||
#
|
||||
# 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" }
|
||||
NUMBER: /^(\d+)/ { $return = $item[1]; $return||defined($return);}
|
||||
|
||||
# Strings:
|
||||
|
||||
SINGLE_QUOTED_STRING: "'" /(?:\\'|[^'])*/ "'" {
|
||||
|
||||
$return = $item{__PATTERN1__} ;
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
DOUBLE_QUOTED_STRING: '"' /(?:\\"|[^"])*/ '"' {
|
||||
|
||||
$return = $item{__PATTERN1__} ;
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
QUOTED_STRING: DOUBLE_QUOTED_STRING | SINGLE_QUOTED_STRING {
|
||||
|
||||
$return = $item{DOUBLE_QUOTED_STRING}||$item{SINGLE_QUOTED_STRING} ;
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
BARESTRING: ...!/^[)('"]/ /^(?!\(|\))(?:\\ |\S)+/ {
|
||||
$return = $item{__PATTERN1__} ; $return||defined($return);
|
||||
}
|
||||
|
||||
STRING: QUOTED_STRING | BARESTRING {
|
||||
$return = $item{QUOTED_STRING}||$item{BARESTRING} ;
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
OLDSTRING: /^"((?:[^"\\]|\\.)*)"/ | /^([^ \(\)]+)/
|
||||
{ $item{__PATTERN1__} =~ s/^"(.*)"$/$1/;
|
||||
$return = $item{__PATTERN1__} || $item{__PATTERN2__} ;
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
#BARESTRING: /^[^(]+\s+(?=\()/
|
||||
# { $return = $item[1] ; $return||defined($return);}
|
||||
|
||||
textlines: NIL | NUMBER { $return = $item[1] || $item[2]; $return||defined($return); }
|
||||
rfc822message: MESSAGE RFC822 { $return = "MESSAGE RFC822" }
|
||||
key: STRING { $return = $item{STRING} ; $return||defined($return);}
|
||||
value: NIL | '(' <commit> kvpair(s) ')'| NUMBER | STRING
|
||||
{ $return = $item{NIL} ||
|
||||
$item{NUMBER} ||
|
||||
$item{STRING} ||
|
||||
{ map { (%$_) } @{$item{kvpair}} } ;
|
||||
$return||defined($return);
|
||||
}
|
||||
kvpair: ...!")" key value
|
||||
{ $return = { $item{key} => $item{value} }; $return||defined($return);}
|
||||
bodytype: STRING
|
||||
{ $return = $item{STRING} ; $return||defined($return);}
|
||||
bodysubtype: PLAIN | HTML | NIL | STRING
|
||||
{ $return = $item{PLAIN}||$item{HTML}||$item{NIL}||$item{STRING} ;
|
||||
$return||defined($return);
|
||||
}
|
||||
bodyparms: NIL | '(' kvpair(s) ')'
|
||||
{
|
||||
$return = $item{NIL} ||
|
||||
{ map { (%$_) } @{$item{kvpair}} };
|
||||
$return || defined($return);
|
||||
}
|
||||
bodydisp: NIL | '(' kvpair(s) ')'
|
||||
{
|
||||
$return = $item{NIL} ||
|
||||
{ map { (%$_) } @{$item{kvpair}} };
|
||||
$return || defined($return);
|
||||
}
|
||||
bodyid: ...!/[()]/ NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ; $return||defined($return);}
|
||||
bodydesc: ...!/[()]/ NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ; $return||defined($return);}
|
||||
bodyenc: NIL | STRING | '(' kvpair(s) ')'
|
||||
{
|
||||
$return = $item{NIL} ||
|
||||
$item{STRING} ||
|
||||
{ map { (%$_) } @{$item{kvpair}} };
|
||||
$return||defined($return);
|
||||
}
|
||||
bodysize: ...!/[()]/ NIL | NUMBER
|
||||
{ $return = $item{NIL} || $item{NUMBER} ;$return||defined($return);}
|
||||
|
||||
bodyMD5: NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ;$return||defined($return);}
|
||||
bodylang: NIL | STRING | "(" STRING(s) ")"
|
||||
{ $return = $item{NIL} || $item{STRING} ;$return||defined($return);}
|
||||
personalname: NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ;$return||defined($return);}
|
||||
sourceroute: NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ;$return||defined($return);}
|
||||
mailboxname: NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ;$return||defined($return);}
|
||||
hostname: NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ;$return||defined($return);}
|
||||
addressstruct: "(" personalname sourceroute mailboxname hostname ")"
|
||||
{ $return = {
|
||||
personalname => $item{personalname} ,
|
||||
sourceroute => $item{sourceroute} ,
|
||||
mailboxname => $item{mailboxname} ,
|
||||
hostname => $item{hostname} ,
|
||||
} ;
|
||||
bless($return, "Mail::IMAPClient::BodyStructure::Address");
|
||||
}
|
||||
subject: NIL | STRING
|
||||
{
|
||||
$return = $item{NIL} || $item{STRING} ;
|
||||
$return||defined($return);
|
||||
}
|
||||
inreplyto: NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ;$return||defined($return);}
|
||||
|
||||
messageid: NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ;$return||defined($return);}
|
||||
|
||||
date: NIL | STRING
|
||||
{ $return = $item{NIL} || $item{STRING} ;$return||defined($return);}
|
||||
|
||||
cc: NIL | "(" addressstruct(s) ")"
|
||||
{ $return = $item{NIL} || $item{addressstruct} }
|
||||
|
||||
bcc: NIL | "(" addressstruct(s) ")"
|
||||
{ $return = $item{NIL} || $item{addressstruct} }
|
||||
|
||||
from: NIL | "(" addressstruct(s) ")"
|
||||
{ $return = $item{NIL} || $item{addressstruct} }
|
||||
|
||||
replyto: NIL | "(" addressstruct(s) ")"
|
||||
{ $return = $item{NIL} || $item{addressstruct} }
|
||||
|
||||
sender: NIL | "(" addressstruct(s) ")"
|
||||
{ $return = $item{NIL} || $item{addressstruct} }
|
||||
|
||||
to: NIL | "(" addressstruct(s) ")"
|
||||
{ $return = $item{NIL} || $item{addressstruct} }
|
||||
|
||||
envelopestruct: "(" date subject from sender replyto to cc bcc inreplyto messageid ")"
|
||||
{ $return = {};
|
||||
foreach my $what (qw/date subject from sender replyto to cc bcc inreplyto messageid/) {
|
||||
$return->{$what} = $item{$what};
|
||||
}
|
||||
bless $return, "Mail::IMAPClient::BodyStructure::Envelope";
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
basicfields: bodysubtype bodyparms bodyid(?)
|
||||
bodydesc(?) bodyenc(?)
|
||||
bodysize(?) {
|
||||
|
||||
$return = {
|
||||
bodysubtype => $item{bodysubtype} ,
|
||||
|
||||
bodyparms => $item{bodyparms} ,
|
||||
|
||||
bodyid => (ref $item{bodyid} ?
|
||||
$item{bodyid}[0] :
|
||||
$item{bodyid} ),
|
||||
|
||||
bodydesc => (ref $item{bodydesc} ?
|
||||
$item{bodydesc}[0] :
|
||||
$item{bodydesc} ),
|
||||
|
||||
bodyenc => (ref $item{bodyenc} ?
|
||||
$item{bodyenc}[0] :
|
||||
$item{bodyenc} ),
|
||||
|
||||
bodysize => (ref $item{bodysize} ?
|
||||
$item{bodysize}[0] :
|
||||
$item{bodysize} ),
|
||||
};
|
||||
$return;
|
||||
}
|
||||
|
||||
textmessage: TEXT <commit> basicfields textlines(?) bodyMD5(?) bodydisp(?) bodylang(?)
|
||||
{
|
||||
$return = $item{basicfields}||{};
|
||||
$return->{bodytype} = 'TEXT';
|
||||
foreach my $what (qw/textlines bodyMD5 bodydisp bodylang/) {
|
||||
ref($item{$what}) and $return->{$what} = $item{$what}[0];
|
||||
}
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
othertypemessage: bodytype basicfields bodyparms(?) bodydisp(?) bodylang(?)
|
||||
{ $return = {};
|
||||
foreach my $what (qw/bodytype bodyparms bodydisp bodylang/) {
|
||||
$return->{$what} = ref($item{$what})? $item{$what}[0] : $item{$what} ;
|
||||
}
|
||||
while ( my($k,$v) = each %{$item{basicfields}} ) { $return->{$k} = $v }
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
messagerfc822message:
|
||||
rfc822message <commit> bodyparms bodyid bodydesc bodyenc bodysize
|
||||
envelopestruct bodystructure textlines
|
||||
bodyMD5(?) bodydisp(?) bodylang(?)
|
||||
{
|
||||
$return = {};
|
||||
foreach my $what (qw/ bodyparms bodyid bodydesc bodyenc bodysize
|
||||
envelopestruct bodystructure textlines
|
||||
bodyMD5 bodydisp bodylang
|
||||
/
|
||||
) {
|
||||
$return->{$what} = ref $item{$what} =~ 'ARRAY'?
|
||||
$item{$what}[0] : $item{$what};
|
||||
}
|
||||
while ( my($k,$v) = each %{$item{bodystructure}[0]} ) { $return->{$k} = $v }
|
||||
while ( my($k,$v) = each %{$item{basicfields}} ) { $return->{$k} = $v }
|
||||
$return->{bodytype} = "MESSAGE" ;
|
||||
$return->{bodysubtype}= "RFC822" ;
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
subpart: "(" part ")"
|
||||
{
|
||||
$return = $item{part} ;
|
||||
$return||defined($return);
|
||||
} <defer: ++$subpartCount;>
|
||||
|
||||
|
||||
part: subpart(s) <commit> basicfields
|
||||
bodyparms(?) bodydisp(?) bodylang(?)
|
||||
<defer: $subpartCount = 0>
|
||||
{
|
||||
$return = bless($item{basicfields}, "Mail::IMAPClient::BodyStructure");
|
||||
$return->{bodytype} = "MULTIPART";
|
||||
$return->{bodystructure} = $item{subpart};
|
||||
foreach my $b (qw/bodyparms bodydisp bodylang/) {
|
||||
$return->{$b} = ref($item{$b}) ? $item{$b}[0] : $item{$b};
|
||||
}
|
||||
$return||defined($return) ;
|
||||
}
|
||||
| textmessage
|
||||
{
|
||||
$return = bless $item{textmessage}, "Mail::IMAPClient::BodyStructure";
|
||||
$return||defined($return);
|
||||
}
|
||||
| messagerfc822message
|
||||
{
|
||||
$return = bless $item{messagerfc822message}, "Mail::IMAPClient::BodyStructure";
|
||||
$return||defined($return);
|
||||
}
|
||||
| othertypemessage
|
||||
{
|
||||
$return = bless $item{othertypemessage}, "Mail::IMAPClient::BodyStructure";
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
bodystructure: "(" part(s) ")"
|
||||
{
|
||||
$return = $item{part} ;
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
start: /.*\(.*BODYSTRUCTURE \(/i part(1) /\).*\)\r?\n?/
|
||||
{
|
||||
$return = $item{part}[0] ;
|
||||
$return||defined($return);
|
||||
}
|
||||
|
||||
envelope: /.*\(.*ENVELOPE/ envelopestruct /.*\)/ {
|
||||
$return = $item{envelopestruct} ;
|
||||
$return||defined($return) ;
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package Mail::IMAPClient::BodyStructure::Parse;
|
||||
$Mail::IMAPClient::BodyStructure::Parse::VERSION = "0.0.1";
|
||||
$Mail::IMAPClient::BodyStructure::Parse::VERSION = "0.0.1";
|
||||
|
||||
=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.
|
||||
|
||||
=cut
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
# Before `make install' is performed this script should be runnable with
|
||||
# `make test'. After `make install' it should work as `perl test.pl'
|
||||
# $Id: parse.t,v 1.2 2002/08/30 20:48:34 dkernen Exp $
|
||||
######################### We start with some black magic to print on failure.
|
||||
|
||||
# Change 1..1 below to 1..last_test_to_print .
|
||||
|
||||
use Mail::IMAPClient::BodyStructure::Parse;
|
||||
|
||||
BEGIN {
|
||||
print "1..1\n";
|
||||
$main::loaded = 1;
|
||||
$| = 1;
|
||||
print "ok 1\n";
|
||||
}
|
||||
END {print "not ok 1\n" unless $main::loaded;}
|
||||
|
||||
|
||||
# History:
|
||||
# $Log: parse.t,v $
|
||||
# Revision 1.2 2002/08/30 20:48:34 dkernen
|
||||
#
|
||||
# #
|
||||
# Modified Files:
|
||||
# Changes IMAPClient.pm MANIFEST Makefile Makefile.PL README
|
||||
# Todo test.txt
|
||||
# BodyStructure/Parse/Makefile
|
||||
# BodyStructure/Parse/Parse.pm
|
||||
# BodyStructure/Parse/Parse.pod
|
||||
# BodyStructure/Parse/t/parse.t
|
||||
# for version 2.2.1
|
||||
# #
|
||||
#
|
||||
# Revision 1.1 2002/08/23 14:34:29 dkernen
|
||||
#
|
||||
# Modified Files: Changes IMAPClient.pm Makefile Makefile.PL test.txt for version 2.2.0
|
||||
# Added Files: Makefile Makefile.PL Parse.grammar Parse.pm Parse.pod version 2.2.0
|
||||
# Added Files: parse.t for version 2.2.0
|
||||
#
|
|
@ -1,55 +0,0 @@
|
|||
# Before `make install' is performed this script should be runnable with
|
||||
# `make test'. After `make install' it should work as `perl test.pl'
|
||||
# $Id: bodystructure.t,v 1.1 2002/08/23 14:34:40 dkernen Exp $
|
||||
######################### We start with some black magic to print on failure.
|
||||
|
||||
# Change 1..1 below to 1..last_test_to_print .
|
||||
|
||||
use Mail::IMAPClient::BodyStructure;
|
||||
use warnings;
|
||||
|
||||
BEGIN {
|
||||
print "1..8\n";
|
||||
$main::loaded = 1;
|
||||
$| = 1;
|
||||
print "ok 1\n";
|
||||
}
|
||||
my $bs=<<"END_OF_BS";
|
||||
(BODYSTRUCTURE ("TEXT" "PLAIN" ("CHARSET" "us-ascii") NIL NIL "7BIT" 511 20 NIL NIL NIL))^M
|
||||
END_OF_BS
|
||||
my $bsobj = Mail::IMAPClient::BodyStructure->new($bs) ;
|
||||
if ($bsobj) { print "ok 2\n" } else {
|
||||
print "not ok 2\n";
|
||||
exit;
|
||||
}
|
||||
if ($bsobj->bodytype eq 'TEXT') { print "ok 3\n" }
|
||||
else {print "not ok 3 (expected 'TEXT' ; got '" . $bsobj->bodytype . "')\n"}
|
||||
if ($bsobj->bodysubtype eq 'PLAIN') { print "ok 4\n" }
|
||||
else {print "not ok 4 (expected 'PLAIN' ; got '" . $bsobj->bodytype . "')\n"}
|
||||
|
||||
my $bs2 = <<'END_OF_BS2';
|
||||
(BODYSTRUCTURE (("TEXT" "PLAIN" ("CHARSET" "us-ascii") NIL NIL "7BIT" 2 1 NIL NIL NIL)("MESSAGE" "RFC822" NIL NIL NIL "7BIT" 3930 ("Tue, 16 Jul 2002 15:29:17 -0400" "Re: [Fwd: Here is the the list of uids]" (("Michael Etcetera" NIL "michael.etcetera" "generic.com")) (("Michael Etcetera" NIL "michael.etcetera" "generic.com")) (("Michael Etcetera" NIL "michael.etcetera" "generic.com")) (("Michael Etcetera" NIL "michael.etcetera" "generic.com")) (("David J Kavid" NIL "david.kavid" "generic.com")) NIL NIL "<72f9a217.a21772f9@generic.com>") (("TEXT" "PLAIN" ("CHARSET" "us-ascii") NIL NIL "7BIT" 369 11 NIL NIL NIL)("MESSAGE" "RFC822" NIL NIL NIL "7BIT" 2599 ("Tue, 9 Jul 2002 13:42:04 -0400" "Here is the the list of uids" (("Nicholas Kringle" NIL "nicholas.kringle" "generic.com")) (("Nicholas Kringle" NIL "nicholas.kringle" "generic.com")) (("Nicholas Kringle" NIL "nicholas.kringle" "generic.com")) (("Michael Etcetera" NIL "michael.etcetera" "generic.com")) (("Richard W Continued" NIL "richard.continued" "generic.com")) NIL NIL "<015401c2276f$f09b7c10$59cab08c@one.two.generic.com>") ((("TEXT" "PLAIN" ("CHARSET" "iso-8859-1") NIL NIL "QUOTED-PRINTABLE" 256 10 NIL NIL NIL)("TEXT" "HTML" ("CHARSET" "iso-8859-1") NIL NIL "QUOTED-PRINTABLE" 791 22 NIL NIL NIL) "ALTERNATIVE" ("BOUNDARY" "----=_NextPart_001_0151_01C2274E.6969D0F0") NIL NIL) "MIXED" ("BOUNDARY" "----=_NextPart_000_0150_01C2274E.6969D0F0") NIL NIL) 75 NIL NIL NIL) "MIXED" ("BOUNDARY" "--1f34eac2082b02") NIL ("EN")) 118 NIL NIL NIL) "MIXED" ("BOUNDARY" "------------F600BD8FDDD648ABA72A09E0") NIL NIL))
|
||||
END_OF_BS2
|
||||
|
||||
$bsobj = Mail::IMAPClient::BodyStructure->new($bs2) ;
|
||||
if ($bsobj) { print "ok 5\n" } else {print "not ok 5\n"}
|
||||
if ($bsobj->bodytype eq 'MULTIPART') { print "ok 6\n" }
|
||||
else {print "not ok 6 (expected 'MULTIPART' ; got '" . $bsobj->bodytype . "')\n"}
|
||||
if ($bsobj->bodysubtype eq 'MIXED') { print "ok 7\n" }
|
||||
else {print "not ok 7 (expected 'MIXED' ; got '" . $bsobj->bodytype . "')\n"}
|
||||
if (join("#",$bsobj->parts) eq "1#2#2.HEAD#2.1#2.2#2.2.HEAD#2.2.1#2.2.1.1#2.2.1.2") {
|
||||
print "ok 8\n";
|
||||
} else {print "not ok 8\n"}
|
||||
|
||||
END {print "not ok 1\n" unless $main::loaded;}
|
||||
|
||||
|
||||
# History:
|
||||
# $Log: bodystructure.t,v $
|
||||
# Revision 1.1 2002/08/23 14:34:40 dkernen
|
||||
#
|
||||
# Modified Files: Changes IMAPClient.pm Makefile Makefile.PL test.txt for version 2.2.0
|
||||
# Added Files: Makefile Makefile.PL Parse.grammar Parse.pm Parse.pod version 2.2.0
|
||||
# Added Files: parse.t for version 2.2.0
|
||||
# Added Files: bodystructure.t for 2.2.0
|
||||
#
|
|
@ -1,21 +0,0 @@
|
|||
COPYRIGHT
|
||||
|
||||
Copyright 1999, 2000, 2001, 2002 , 2003 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:
|
||||
|
||||
|
||||
a) the "Artistic License" which comes with this Kit, or
|
||||
|
||||
b) the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 1, or (at your option) any later version.
|
||||
|
||||
|
||||
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.
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,248 +0,0 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 1, February 1989
|
||||
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The license agreements of most software companies try to keep users
|
||||
at the mercy of those companies. By contrast, our General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. The
|
||||
General Public License applies to the Free Software Foundation's
|
||||
software and to any other program whose authors commit to using it.
|
||||
You can use it for your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Specifically, the General Public License is designed to make
|
||||
sure that you have the freedom to give away or sell copies of free
|
||||
software, that you receive source code or can get it if you want it,
|
||||
that you can change the software or use pieces of it in new free
|
||||
programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of a such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must tell them their rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any program or other work which
|
||||
contains a notice placed by the copyright holder saying it may be
|
||||
distributed under the terms of this General Public License. The
|
||||
"Program", below, refers to any such program or work, and a "work based
|
||||
on the Program" means either the Program or any work containing the
|
||||
Program or a portion of it, either verbatim or with modifications. Each
|
||||
licensee is addressed as "you".
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's source
|
||||
code as you receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice and
|
||||
disclaimer of warranty; keep intact all the notices that refer to this
|
||||
General Public License and to the absence of any warranty; and give any
|
||||
other recipients of the Program a copy of this General Public License
|
||||
along with the Program. You may charge a fee for the physical act of
|
||||
transferring a copy.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion of
|
||||
it, and copy and distribute such modifications under the terms of Paragraph
|
||||
1 above, provided that you also do the following:
|
||||
|
||||
a) cause the modified files to carry prominent notices stating that
|
||||
you changed the files and the date of any change; and
|
||||
|
||||
b) cause the whole of any work that you distribute or publish, that
|
||||
in whole or in part contains the Program or any part thereof, either
|
||||
with or without modifications, to be licensed at no charge to all
|
||||
third parties under the terms of this General Public License (except
|
||||
that you may choose to grant warranty protection to some or all
|
||||
third parties, at your option).
|
||||
|
||||
c) If the modified program normally reads commands interactively when
|
||||
run, you must cause it, when started running for such interactive use
|
||||
in the simplest and most usual way, to print or display an
|
||||
announcement including an appropriate copyright notice and a notice
|
||||
that there is no warranty (or else, saying that you provide a
|
||||
warranty) and that users may redistribute the program under these
|
||||
conditions, and telling the user how to view a copy of this General
|
||||
Public License.
|
||||
|
||||
d) You may charge a fee for the physical act of transferring a
|
||||
copy, and you may at your option offer warranty protection in
|
||||
exchange for a fee.
|
||||
|
||||
Mere aggregation of another independent work with the Program (or its
|
||||
derivative) on a volume of a storage or distribution medium does not bring
|
||||
the other work under the scope of these terms.
|
||||
|
||||
3. You may copy and distribute the Program (or a portion or derivative of
|
||||
it, under Paragraph 2) in object code or executable form under the terms of
|
||||
Paragraphs 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of
|
||||
Paragraphs 1 and 2 above; or,
|
||||
|
||||
b) accompany it with a written offer, valid for at least three
|
||||
years, to give any third party free (except for a nominal charge
|
||||
for the cost of distribution) a complete machine-readable copy of the
|
||||
corresponding source code, to be distributed under the terms of
|
||||
Paragraphs 1 and 2 above; or,
|
||||
|
||||
c) accompany it with the information you received as to where the
|
||||
corresponding source code may be obtained. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form alone.)
|
||||
|
||||
Source code for a work means the preferred form of the work for making
|
||||
modifications to it. For an executable file, complete source code means
|
||||
all the source code for all modules it contains; but, as a special
|
||||
exception, it need not include source code for modules which are standard
|
||||
libraries that accompany the operating system on which the executable
|
||||
file runs, or for standard header files or definitions files that
|
||||
accompany that operating system.
|
||||
|
||||
4. You may not copy, modify, sublicense, distribute or transfer the
|
||||
Program except as expressly provided under this General Public License.
|
||||
Any attempt otherwise to copy, modify, sublicense, distribute or transfer
|
||||
the Program is void, and will automatically terminate your rights to use
|
||||
the Program under this License. However, parties who have received
|
||||
copies, or rights to use copies, from you under this General Public
|
||||
License will not have their licenses terminated so long as such parties
|
||||
remain in full compliance.
|
||||
|
||||
5. By copying, distributing or modifying the Program (or any work based
|
||||
on the Program) you indicate your acceptance of this license to do so,
|
||||
and all its terms and conditions.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the original
|
||||
licensor to copy, distribute or modify the Program subject to these
|
||||
terms and conditions. You may not impose any further restrictions on the
|
||||
recipients' exercise of the rights granted herein.
|
||||
|
||||
7. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of the license which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
the license, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
8. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to humanity, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these
|
||||
terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest to
|
||||
attach them to the start of each source file to most effectively convey
|
||||
the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
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 the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19xx name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the
|
||||
appropriate parts of the General Public License. Of course, the
|
||||
commands you use may be called something other than `show w' and `show
|
||||
c'; they could even be mouse-clicks or menu items--whatever suits your
|
||||
program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
program `Gnomovision' (a program to direct compilers to make passes
|
||||
at assemblers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
|
@ -1 +0,0 @@
|
|||
.
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,73 +0,0 @@
|
|||
Mail::IMAPClient Installation
|
||||
|
||||
The Mail::IMAPClient is written entirely in Perl, so it should install on any reasonably
|
||||
recent version of Perl. See the README file for a perl one-liner that you can run to verify
|
||||
that your perl has what it takes to run Mail::IMAPClient.
|
||||
|
||||
The installation is standard:
|
||||
|
||||
0) cd to installation directory
|
||||
1) perl Makefile.PL (and reply to the prompt(s))
|
||||
2) make (optional)
|
||||
3) make test (optional)
|
||||
4) make install
|
||||
|
||||
The 'make install' and 'make test' will both do step 2 ('make') if you haven't done it
|
||||
already. Currently the test script is lame (although not as lame as in the last release!)
|
||||
but I hope to incorporate more thorough testing in a future version. You should at least
|
||||
try it and let me know if your tests fail.
|
||||
|
||||
Version 1.0 changed the installation script so that it reuses the parameter file for
|
||||
the tests if it finds one. Installation can be run in the background if the test.txt file
|
||||
exists. Touching it is good enough to prevent prompts; having a correctly formatted
|
||||
version (as shown in test_template.txt) is even better, as it will allow you to do a
|
||||
thorough 'make test'. Invalid data in test.txt (either from precreating it or from
|
||||
responding inaccurately to prompts) will cause 'make test' to report 'not ok' results
|
||||
but won't break anything important (like the IMAPClient.pm file, or your car).
|
||||
|
||||
If you have tests that fail it may be more illuminating to run the tests by hand. IE:
|
||||
perl -I./blib/lib t/basic.t from the installation dir will pinpoint the failing test.
|
||||
Better yet, supply an argument to basic/t (any 'true' argument will do; I use '1') to
|
||||
turn on debugging, which will be placed in your installation directory in 'imap1.debug'
|
||||
and 'imap2.debug'. E-mail me the results.
|
||||
|
||||
If you don't have a test.txt file in your installation directory then you will have to
|
||||
answer at least one prompt. If you do have a test.txt file, and you run 'make clean',
|
||||
then you won't have a test.txt file anymore, so take precautions.
|
||||
|
||||
If you do have a test.txt file and you don't run 'make clean' then a text file will
|
||||
be sitting around containing logon credentials, so, again, take precautions. (It's just
|
||||
a test account anyway, right?)
|
||||
|
||||
If, when replying to the "perl Makefile.PL" prompts, you supply server, id, and
|
||||
password credentials for an id that has a ridiculously huge number of folders and
|
||||
subfolders then the 'make test' may run approximately forever. Next time try an id
|
||||
with less stuff.
|
||||
|
||||
For examples on using Mail::IMAPClient, check out the examples subdirectory. If you have
|
||||
better examples, then why haven't you e-mailed them to me? Also, I totally recommend
|
||||
that you have a copy of RFC2060 handy when using this module, since the documentation
|
||||
for this module is meant to compliment, not replace, RFC2060. In fact, I am so convinced
|
||||
that you'll need the RFC that I've included a copy of it in the distribution, under
|
||||
the "docs/" subdirectory. It's a smashing good read so have at it. Other IMAP related
|
||||
rfcs are there as well.
|
||||
|
||||
One of the examples in the examples/ subdirectory is called cleanTest.pl. If you find
|
||||
your 'make test' has had trouble and left some folders named "IMAPClient_*" in your
|
||||
test account, you can run this example to clean up the account. But probably only after
|
||||
you've fixed any problems encountered with 'make test'!
|
||||
|
||||
This module uses Damian Conway's excellent Parse::RecDescent module for some advanced
|
||||
features. If you don't have that module installed then you can still install
|
||||
Mail::IMAPClient but you won't have the full functionality. If you have
|
||||
Parse::RecDescent installed and then upgrade it, you may find that some features in
|
||||
Mail::IMAPClient suddenly start throwing compile-time errors. Just 'make clean' and
|
||||
then 'make', 'make test', and 'make install'. This happens because grammers compiled
|
||||
under older releases of Parse::RecDescent are sometimes incompatible with newer
|
||||
Parse::RecDescent runtime engines. This would never be a problem if Mail::IMAPClient
|
||||
recompiled grammers at run time, but for performance reasons it precompiles them at
|
||||
install time. TANSTAAFL.
|
||||
|
||||
Now go and write IMAP clients.
|
||||
|
||||
Dave Kernen
|
|
@ -1,25 +0,0 @@
|
|||
Please let me know if you have any problems under perl 5.8.x.
|
||||
|
||||
I do know of one issue under perl 5.8.0. If you are installing from
|
||||
a work directory that contains a double colon in one of the
|
||||
component subdirectory names then some of the tests may fail.
|
||||
For example, I do my development work from a subdirectory that
|
||||
has "Mail::IMAPClient" in the path, and 'make test' fails for
|
||||
the subcomponents of Mail::IMAPClient from that path; the test
|
||||
harness is unable to locate the ../lib/blib subdirectory and so
|
||||
cannot load the .pm file. If I install from a different directory
|
||||
without "::"'s then everything tests okay. I do not see this with
|
||||
earlier versions of perl.
|
||||
|
||||
A work around is to not install from a subdirectory with "::".
|
||||
|
||||
An alternative work around is to do 'make install' before 'make test'.
|
||||
This gets around the problem by placing a copy of the necessary files
|
||||
in your installation directories, so that even though 'make test'
|
||||
cannot find ../blib/lib, it can find the necessary .pm files in your
|
||||
(production!) installation libraries so the tests will still succeed.
|
||||
However, you have to remember to do 'make install' first every time
|
||||
you install a new version of this module, or you will be testing the
|
||||
old version instead of the new one.
|
||||
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
Changes
|
||||
COPYRIGHT
|
||||
Todo
|
||||
IMAPClient.pm
|
||||
IMAPClient.pod
|
||||
BodyStructure/BodyStructure.pm
|
||||
BodyStructure/Parse/Parse.pod
|
||||
INSTALL
|
||||
BUG_REPORTS
|
||||
INSTALL_perl5.80
|
||||
MANIFEST
|
||||
README
|
||||
Makefile.PL
|
||||
t/basic.t
|
||||
t/fast_io.t
|
||||
t/uidplus.t
|
||||
t/uidfast.t
|
||||
t/cram-md5.t
|
||||
t/ranges.t
|
||||
Copying
|
||||
Artistic
|
||||
examples/build_dist.pl
|
||||
examples/build_ldif.pl
|
||||
examples/cleanTest.pl
|
||||
examples/copy_folder.pl
|
||||
examples/cyrus_expunge.pl
|
||||
examples/cyrus_expire.pl
|
||||
examples/find_dup_msgs.pl
|
||||
examples/imap_to_mbox.pl
|
||||
examples/migrate_mbox.pl
|
||||
examples/migrate_mail2.pl
|
||||
examples/populate_mailbox.pl
|
||||
examples/sharedFolder.pl
|
||||
examples/imtestExample.pl
|
||||
test_template.txt
|
||||
sample.perldb
|
||||
docs/rfc1731.txt
|
||||
docs/rfc1732.txt
|
||||
docs/rfc1733.txt
|
||||
docs/rfc2060.txt
|
||||
docs/rfc2061.txt
|
||||
docs/rfc2062.txt
|
||||
docs/rfc2086.txt
|
||||
docs/rfc2087.txt
|
||||
docs/rfc2088.txt
|
||||
docs/rfc2177.txt
|
||||
docs/rfc2180.txt
|
||||
docs/rfc2192.txt
|
||||
docs/rfc2193.txt
|
||||
docs/rfc2195.txt
|
||||
docs/rfc2221.txt
|
||||
docs/rfc2222.txt
|
||||
docs/rfc2234.txt
|
||||
docs/rfc2245.txt
|
||||
docs/rfc2342.txt
|
||||
docs/rfc2359.txt
|
||||
docs/rfc2683.txt
|
||||
docs/rfc2831.txt
|
||||
docs/draft-ietf-imapext-sort-06.txt
|
||||
BodyStructure/Parse/Makefile.PL
|
||||
BodyStructure/Parse/Parse.grammar_old
|
||||
BodyStructure/Parse/Parse.grammar_new
|
||||
BodyStructure/Parse/t/parse.t
|
||||
BodyStructure/Makefile.PL
|
||||
BodyStructure/t/bodystructure.t
|
||||
docs/draft-crispin-imapv-17.txt
|
||||
docs/draft-ietf-imapext-annotate-04.txt
|
||||
docs/draft-ietf-imapext-thread-11.txt
|
||||
Thread/Thread.pod
|
||||
Thread/Thread.grammar_old
|
||||
Thread/Thread.grammar_new
|
||||
Thread/Makefile.PL
|
||||
Thread/t/thread.t
|
||||
MessageSet/Makefile.PL
|
||||
MessageSet/MessageSet.pm
|
||||
MessageSet/t/range.t
|
||||
BodyStructure/COPYRIGHT
|
||||
Thread/COPYRIGHT
|
||||
docs/COPYRIGHT
|
||||
examples/COPYRIGHT
|
||||
MessageSet/COPYRIGHT
|
|
@ -1 +0,0 @@
|
|||
.
|
|
@ -1,148 +0,0 @@
|
|||
use ExtUtils::MakeMaker;
|
||||
use File::Copy;
|
||||
use Cwd;
|
||||
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
|
||||
# the contents of the Makefile that is written.
|
||||
$DO_BODYSTRUCTURE = eval "require 'Parse/RecDescent.pm'" ;
|
||||
unless ($DO_BODYSTRUCTURE) {
|
||||
print
|
||||
"*** NOTE ***\n\n",
|
||||
"Unable to find and load Parse::RecDescent.\n",
|
||||
"Mail::IMAPClient will be installed without support for\n",
|
||||
"the get_bodystructure method and without the \n",
|
||||
"Mail::IMAPClient::BodyStructure subclasses. \n\n",
|
||||
"If you need these subclasses, install Parse::RecDescent \nand ",
|
||||
"re-run Makefile.PL. \n\n";
|
||||
}
|
||||
|
||||
&set_PRD_type if $DO_BODYSTRUCTURE;
|
||||
|
||||
WriteMakefile(
|
||||
'DIR' => [ 'MessageSet', $DO_BODYSTRUCTURE ? ( 'BodyStructure' , 'Thread' ) : () ],
|
||||
'NAME' => 'Mail::IMAPClient',
|
||||
'VERSION_FROM' => 'IMAPClient.pm', # finds $VERSION
|
||||
'clean' => { FILES => 'test.txt' },
|
||||
'PREREQ_PM' => {
|
||||
'Errno' => 0,
|
||||
'IO::Socket' => 0,
|
||||
'Fcntl' => 0,
|
||||
'IO::Select' => 0,
|
||||
'IO::File' => 0,
|
||||
'Data::Dumper' => 0,
|
||||
'Carp' => 0,
|
||||
},
|
||||
|
||||
);
|
||||
|
||||
=begin prereqs
|
||||
|
||||
The Mail::IMAPClient module uses the IO::Socket module to make a socket
|
||||
connection to an IMAP server and the Socket module to get some constants.
|
||||
It also uses Errno, Fcntl (for faster I/O) and IO::Select, IO::File,
|
||||
Data::Dumper, and Carp.
|
||||
|
||||
=end prereqs
|
||||
|
||||
=cut
|
||||
|
||||
&set_test_data;
|
||||
|
||||
sub set_test_data {
|
||||
unless (-f "./IMAPClient.pm") { warn "ERROR: not in installation directory\n"; return }
|
||||
return if -f "./test.txt";
|
||||
print "You have the option of running an extended suite of tests during\n",
|
||||
"'make test'. This requires an IMAP server name, user account, and ",
|
||||
"password to test with.","\n","\n",
|
||||
"Do you want to run the extended tests? (n/y) ==> ";
|
||||
my $yes = <STDIN>;
|
||||
return unless $yes =~ /^[Yy](?:[Ee]:[Ss]?)?$/ ;
|
||||
|
||||
unless (open TST,">./test.txt") { warn "ERROR: couldn't open ./test.txt: $!\n"; return }
|
||||
|
||||
my $server = "";
|
||||
until ($server ) {
|
||||
print "\nPlease provide the hostname or IP address of a host running an IMAP server \n",
|
||||
"(or QUIT to skip the extended tests) ==> ";
|
||||
$server = <STDIN>;
|
||||
chomp $server;
|
||||
return if $server =~ /^\s*quit\s*$/i ;
|
||||
}
|
||||
print TST "server=$server\n";
|
||||
|
||||
my $user = "";
|
||||
until ($user) {
|
||||
print "\nPlease provide the username of an account\non $server (or QUIT) ==> ";
|
||||
$user = <STDIN>;
|
||||
chomp $user;
|
||||
return if $user =~ /^\s*quit\s*$/i ;
|
||||
}
|
||||
|
||||
print TST "user=$user\n";
|
||||
my $passe = "";
|
||||
until ($passed) {
|
||||
print "\nPlease provide the password for $user\n(or QUIT) ==> ";
|
||||
$passed = <STDIN>;
|
||||
chomp $passed;
|
||||
return if $passed =~ /^\s+$|^quit$/i ;
|
||||
}
|
||||
|
||||
print TST "passed=$passed\n";
|
||||
|
||||
print "\nPlease provide the port to connect to on $server to run the test \n",
|
||||
"(default is 143) ==> ";
|
||||
my $port = <STDIN>;
|
||||
chomp $port;
|
||||
$port ||= 143;
|
||||
print TST "port=$port\n";
|
||||
print "\nPlease provide the authentication mechanism to use on $server to run the test \n",
|
||||
"(default is 'LOGIN', which uses the plain text LOGIN command) ==> ";
|
||||
my $authmech = <STDIN>;
|
||||
chomp $authmech;
|
||||
$authmech ||= 'LOGIN';
|
||||
print TST "authmechanism=$authmech\n";
|
||||
close TST;
|
||||
print "\nGracias! The information you provided (including the \n",
|
||||
" password!) has been stored in ",cwd,"/test.txt and should be\n",
|
||||
" removed (either by hand or by 'make clean') after testing.\n";
|
||||
}
|
||||
|
||||
|
||||
sub set_PRD_type {
|
||||
|
||||
my $g = <<' EOG';
|
||||
|
||||
start: thing(s)
|
||||
{ $return = \%item; }
|
||||
|
||||
thing: /YES/
|
||||
{ $return = \%item; }
|
||||
|
||||
EOG
|
||||
|
||||
my $p = Parse::RecDescent->new($g);
|
||||
|
||||
my $i = $p->start("YES YES");
|
||||
if ( exists($i->{'thing(s)'}) ) {
|
||||
print "Using new-style Parse::RecDescent grammars\n";
|
||||
copy("./Thread/Thread.grammar_new","./Thread/Thread.grammar");
|
||||
|
||||
copy( "./BodyStructure/Parse/Parse.grammar_new",
|
||||
"./BodyStructure/Parse/Parse.grammar"
|
||||
);
|
||||
|
||||
} elsif ($i->{'thing'}) {
|
||||
print "Using old-style Parse::RecDescent grammars\n";
|
||||
print "If you upgrade Parse::RecDescent then you will ",
|
||||
"have to re-run Makefile.PL and re-make and re-'make install'",
|
||||
"Mail::IMAPClient.\n";
|
||||
copy("./Thread/Thread.grammar_old","./Thread/Thread.grammar");
|
||||
copy( "./BodyStructure/Parse/Parse.grammar_old",
|
||||
"./BodyStructure/Parse/Parse.grammar"
|
||||
);
|
||||
} else {
|
||||
print "Unable to parse simple Parse::RecDescent code. ",
|
||||
"Skipping installation of advanced features.";
|
||||
$DO_BODYSTRUCTURE = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
MessageSet/MessageSet.pm
|
|
@ -1,21 +0,0 @@
|
|||
COPYRIGHT
|
||||
|
||||
Copyright 1999, 2000, 2001, 2002 , 2003 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:
|
||||
|
||||
|
||||
a) the "Artistic License" which comes with this Kit, or
|
||||
|
||||
b) the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 1, or (at your option) any later version.
|
||||
|
||||
|
||||
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.
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
#$Id: Makefile.PL,v 1.1 2002/10/23 20:45:54 dkernen Exp $
|
||||
use ExtUtils::MakeMaker;
|
||||
use Cwd;
|
||||
|
||||
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
|
||||
# the contents of the Makefile that is written.
|
||||
|
||||
WriteMakefile(
|
||||
'NAME' => 'Mail::IMAPClient::MessageSet',
|
||||
'VERSION_FROM' => '../IMAPClient.pm', # finds $VERSION
|
||||
);
|
||||
|
||||
#History:
|
||||
#$Log: Makefile.PL,v $
|
||||
#Revision 1.1 2002/10/23 20:45:54 dkernen
|
||||
#
|
||||
#Modified Files: Changes IMAPClient.pm MANIFEST Makefile.PL
|
||||
#Added Files: Makefile.PL MessageSet.pm
|
||||
#
|
||||
#
|
|
@ -1,416 +0,0 @@
|
|||
package Mail::IMAPClient::MessageSet;
|
||||
#$Id: MessageSet.pm,v 1.3 2002/12/13 18:08:49 dkernen Exp $
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Mail::IMAPClient::MessageSet -- an extension to Mail::IMAPClient that
|
||||
expresses lists of message sequence numbers or message UID's in the shortest
|
||||
way permissable by RFC2060.
|
||||
|
||||
=cut
|
||||
|
||||
sub str {
|
||||
# print "Overloaded ", overload::StrVal(${$_[0]}),"\n";
|
||||
return overload::StrVal(${$_[0]});
|
||||
}
|
||||
sub rem {
|
||||
my $self = shift;
|
||||
my $minus = ref($self)->new(@_);
|
||||
my %deleted = map { $_ => 1 } @{$minus->unfold} ;
|
||||
${$self} = $self->range(
|
||||
map { exists $deleted{$_} ? () : $_ } @{$self->unfold}
|
||||
);
|
||||
return $self;
|
||||
}
|
||||
sub cat {
|
||||
my $self = shift;
|
||||
my @a = ("$self",@_);
|
||||
${$self} = $self->range(@a);
|
||||
return $self;
|
||||
}
|
||||
use overload qq/""/ => "str" ,
|
||||
qq/.=/=>"cat",
|
||||
qq/+=/=>"cat",
|
||||
qq/-=/=>"rem",
|
||||
q/@{}/=>"unfold",
|
||||
fallback => "TRUE";
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my $range = $class->range(@_);
|
||||
my $object = \$range;
|
||||
bless $object, $class;
|
||||
return $object ;
|
||||
}
|
||||
|
||||
sub range {
|
||||
my $class = shift;
|
||||
if ( scalar(@_) == 1 and
|
||||
ref($_[0]) =~ /Mail::IMAPClient::MessageSet/
|
||||
) {
|
||||
return $_[0] ;
|
||||
}
|
||||
|
||||
my @msgs = ();
|
||||
for my $m (@_) {
|
||||
next if !defined($m) or $m eq "";
|
||||
if ( ref($m) ) {
|
||||
foreach my $mm (@$m) {
|
||||
foreach my $c ( split(/,/,$mm) ) {
|
||||
if ( $c =~ /:/ ) {
|
||||
my($l,$h) = split(/:/,$c) ;
|
||||
push @msgs,$l .. $h ;
|
||||
} else {
|
||||
push @msgs,$c;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#print STDERR "m=$m\n";
|
||||
foreach my $c ( split(/,/,$m) ) {
|
||||
if ( $c =~ /:/ ) {
|
||||
my($l,$h) = split(/:/,$c) ;
|
||||
push @msgs,$l .. $h ;
|
||||
} else {
|
||||
push @msgs,$c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return undef unless @msgs;
|
||||
my @range = ();
|
||||
my $high = $low = "";
|
||||
for my $m (sort {$a<=>$b} @msgs) {
|
||||
$low = $m if $low eq "";
|
||||
next if $high ne "" and $high == $m ; # been here, done this
|
||||
if ( $high eq "" ) {
|
||||
$high = $m ;
|
||||
} elsif ( $m == $high + 1 ) {
|
||||
$high = $m ;
|
||||
} else {
|
||||
push @range, $low == $high ? "$low," : "$low:$high," ;
|
||||
$low = $m ;
|
||||
$high = $m ;
|
||||
}
|
||||
}
|
||||
push @range, $low == $high ? "$low" : "$low:$high" ;
|
||||
my $range = join("",@range);
|
||||
return $range;
|
||||
}
|
||||
|
||||
sub unfold {
|
||||
my $self = $_[0];
|
||||
return wantarray ?
|
||||
( map { my($l,$h)= split(/:/,$_) ; $h?($l..$h):$l }
|
||||
split(/,/,$$self)
|
||||
) :
|
||||
[ map { my($l,$h)= split(/:/,$_) ; $h?($l..$h):$l }
|
||||
split(/,/,$$self)
|
||||
]
|
||||
;
|
||||
}
|
||||
|
||||
=head2 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. (But you need perl 5.6
|
||||
or above to do this.)
|
||||
|
||||
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).
|
||||
|
||||
=head2 SYNOPSIS
|
||||
|
||||
To illustrate, let's take the trivial example of a search that returns these
|
||||
message uids: 1,3,4,5,6,9,10, as follows:
|
||||
|
||||
@msgs = $imap->search("SUBJECT","Virus"); # returns 1,3,4,5,6,9,10
|
||||
my $msgset = Mail::IMAPClient::MessageSet->new(@msgs);
|
||||
print "$msgset\n"; # prints "1,3:6,9:10\n"
|
||||
# add message 14 to the set:
|
||||
$msgset += 14;
|
||||
print "$msgset\n"; # prints "1,3:6,9:10,14\n"
|
||||
# add messages 16,17,18,19, and 20 to the set:
|
||||
$msgset .= "16,17,18:20";
|
||||
print "$msgset\n"; # prints "1,3:6,9:10,14,16:20\n"
|
||||
# Hey, I didn't really want message 17 in there; let's take it out:
|
||||
$msgset -= 17;
|
||||
print "$msgset\n"; # prints "1,3:6,9:10,14,16,18:20\n"
|
||||
# Now let's iterate over each message:
|
||||
for my $msg (@$msgset) {
|
||||
print "$msg\n";
|
||||
} # Prints: "1\n3\n4\n5\n6\n9\n10\n14\n16\n18\n19\n20"
|
||||
|
||||
(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)>.)
|
||||
|
||||
=cut
|
||||
|
||||
=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.
|
||||
|
||||
=cut
|
||||
|
||||
=head1 REPORTING BUGS
|
||||
|
||||
Please feel free to e-mail the author at C<bug-Mail-IMAPClient@rt.cpan.org>
|
||||
if you encounter any strange behaviors. Don't worry about hurting my
|
||||
feelings or sounding like a whiner or anything like that;
|
||||
if there's a problem with this module you'll be doing me a favor by
|
||||
reporting it. However, I probably won't be able to do much about it if
|
||||
you don't include enough information, so please read and follow these
|
||||
instructions carefully.
|
||||
|
||||
When reporting a bug, please be sure to include the following:
|
||||
|
||||
- As much information about your environment as possible. I especially
|
||||
need to know B<which version of Mail::IMAPClient you are running> and the
|
||||
B<type/version of IMAP server> to which you are connecting. Your OS and
|
||||
perl verions would be helpful too.
|
||||
|
||||
- As detailed a description of the problem as possible. (What are you
|
||||
doing? What happens? Have you found a work-around?)
|
||||
|
||||
- An example script that demonstrates the problem (preferably with as
|
||||
few lines of code as possible!) and which calls the Mail::IMAPClient's
|
||||
L<new> method with the L<Debug> parameter set to "1". (If this generates
|
||||
a ridiculous amount of output and you're sure you know where the problem
|
||||
is, you can create your object with debugging turned off and then
|
||||
turn it on later, just before you issue the commands that recreate the
|
||||
problem. On the other hand, if you can do this you can probably also
|
||||
reduce the program rather than reducing the output, and this would be
|
||||
the best way to go under most circumstances.)
|
||||
|
||||
- Output from the example script when it's running with the Debug
|
||||
parameter turned on. You can edit the output to remove (or preferably
|
||||
to "X" out) sensitive data, such as hostnames, user names, and
|
||||
passwords, but PLEASE do not remove the text that identifies the TYPE
|
||||
of IMAP server to which you are connecting. Note that in most versions
|
||||
of B<Mail::IMAPClient>, debugging does not print out the user or
|
||||
password from the login command line. However, if you use some other
|
||||
means of authenticating then you may need to edit the debugging output
|
||||
with an eye to security.
|
||||
|
||||
- If something worked in a previous release and doesn't work now,
|
||||
please tell me which release did work. You don't have to test every
|
||||
intervening release; just let me know it worked in version x but
|
||||
doesn't work in version (x+n) or whatever.
|
||||
|
||||
- Don't be surprised if I come back asking for a trace of the problem.
|
||||
To provide this, you should create a file called I<.perldb> in your
|
||||
current working directory and include the following line of text in
|
||||
that file:
|
||||
|
||||
C<&parse_options("NonStop=1 LineInfo=mail_imapclient_db.out");>
|
||||
|
||||
For your debugging convenience, a sample .perldb file, which was
|
||||
randomly assigned the name F<sample.perldb>, is provided in the
|
||||
distribution.
|
||||
|
||||
Next, without changing your working directory, debug the example script
|
||||
like this: C<perl -d example_script.pl [ args ]>
|
||||
|
||||
Note that in these examples, the script that demonstrates your problem
|
||||
is named "example_script.pl" and the trace output will be saved in
|
||||
"mail_imapclient_db.out". You should either change these values to suit
|
||||
your needs, or change your needs to suit these values.
|
||||
|
||||
Bug reports should be mailed to:
|
||||
|
||||
bug-Mail-IMAPClient@rt.cpan.org
|
||||
|
||||
Please remember to place a SHORT description of the problem in the subject
|
||||
of the message. Please try to be a bit specific; things like "Bug
|
||||
in Mail::IMAPClient" or "Computer Problem" won't exactly expedite things
|
||||
on my end.
|
||||
|
||||
=head1 REPORTING THINGS THAT ARE NOT BUGS
|
||||
|
||||
If you have suggestions for extending this functionality of this module, or
|
||||
if you have a question and you can't find an answer in any of the
|
||||
documentation (including the RFC's, which are included in this distribution
|
||||
for a reason), then you can e-mail me at the following address:
|
||||
|
||||
comment-Mail-IMAPClient@rt.cpan.org
|
||||
|
||||
Please note that this address is for questions, suggestions, and other comments
|
||||
about B<Mail::IMAPClient>. It's not for reporting bugs, it's not for general
|
||||
correspondence, and it's especially not for selling porn, mortgages, Viagra,
|
||||
or anything else.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
David J. Kernen
|
||||
The Kernen Consulting Group, Inc
|
||||
DJKERNEN@cpan.org
|
||||
|
||||
=cut
|
||||
|
||||
=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
|
||||
|
||||
my $not_void = 11; # This module goes all the way up to 11!
|
||||
|
||||
# History:
|
||||
# $Log: MessageSet.pm,v $
|
||||
# Revision 1.3 2002/12/13 18:08:49 dkernen
|
||||
# Made changes for version 2.2.6 (see Changes file for more info)
|
||||
#
|
||||
# Revision 1.2 2002/11/08 15:48:42 dkernen
|
||||
#
|
||||
# Modified Files: Changes
|
||||
# IMAPClient.pm
|
||||
# Modified Files: MessageSet.pm
|
||||
#
|
||||
# Revision 1.1 2002/10/23 20:45:55 dkernen
|
||||
#
|
||||
# Modified Files: Changes IMAPClient.pm MANIFEST Makefile.PL
|
||||
# Added Files: Makefile.PL MessageSet.pm
|
||||
#
|
||||
#
|
|
@ -1,84 +0,0 @@
|
|||
#!/usr/local/bin/perl
|
||||
#$Id: range.t,v 1.2 2003/06/12 21:42:17 dkernen Exp $
|
||||
|
||||
END {print "not ok 1\n" unless $main::loaded;}
|
||||
use Mail::IMAPClient::MessageSet;
|
||||
|
||||
BEGIN {
|
||||
$| = 1;
|
||||
print "1..7\n";
|
||||
$main::loaded = 1;
|
||||
print "ok 1\n";
|
||||
}
|
||||
my $one = q/1:4,3:6,10:15,20:25,2:8/;
|
||||
my $range = Mail::IMAPClient::MessageSet->new($one);
|
||||
if ( "$range" eq "1:8,10:15,20:25" ) {
|
||||
print "ok 2\n";
|
||||
} else {
|
||||
print "not ok 2 ($range)\n";
|
||||
}
|
||||
if ( join(",",$range->unfold) eq
|
||||
"1,2,3,4,5,6,7,8,10,11,12,13,14,15,20,21,22,23,24,25"
|
||||
) {
|
||||
print "ok 3\n";
|
||||
} else {
|
||||
print "not ok 3 (",join("",$range->unfold),")\n";
|
||||
}
|
||||
|
||||
$range .= "30,31,32,31:34,40:44";
|
||||
if ( "$range" eq "1:8,10:15,20:25,30:34,40:44" ) {
|
||||
|
||||
print "ok 4\n";
|
||||
} else {
|
||||
print "not ok 4 ($range)\n";
|
||||
}
|
||||
if ( join(",",$range->unfold) eq
|
||||
"1,2,3,4,5,6,7,8,10,11,12,13,14,15,20,21,22,23,24,25," .
|
||||
"30,31,32,33,34,40,41,42,43,44"
|
||||
) {
|
||||
print "ok 5\n";
|
||||
} else {
|
||||
print "not ok 5 (",join("",$range->unfold),")\n";
|
||||
}
|
||||
|
||||
$range -= "1:2";
|
||||
if ( "$range" eq "3:8,10:15,20:25,30:34,40:44" ) {
|
||||
print "ok 6\n";
|
||||
} else {
|
||||
print "not ok 6 ($range)\n";
|
||||
}
|
||||
if ( join(",",$range->unfold) eq
|
||||
"3,4,5,6,7,8,10,11,12,13,14,15,20,21,22,23,24,25," .
|
||||
"30,31,32,33,34,40,41,42,43,44"
|
||||
) {
|
||||
print "ok 7\n";
|
||||
} else {
|
||||
print "not ok 7 (",join("",$range->unfold),")\n";
|
||||
}
|
||||
|
||||
exit;
|
||||
|
||||
|
||||
# History:
|
||||
# $Log: range.t,v $
|
||||
# Revision 1.2 2003/06/12 21:42:17 dkernen
|
||||
# Cleaning up cvs repository
|
||||
#
|
||||
# Revision 1.1 2003/06/12 21:37:24 dkernen
|
||||
#
|
||||
# Preparing 2.2.8
|
||||
# Added Files: COPYRIGHT
|
||||
# Modified Files: Parse.grammar
|
||||
# Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
# Parse.grammar Parse.pod
|
||||
# range.t
|
||||
#
|
||||
# Revision 1.1 2002/10/23 20:46:00 dkernen
|
||||
#
|
||||
# Modified Files: Changes IMAPClient.pm MANIFEST Makefile.PL
|
||||
# Added Files: Makefile.PL MessageSet.pm
|
||||
# Added Files: range.t
|
||||
#
|
||||
#
|
|
@ -1,150 +0,0 @@
|
|||
Mail::IMAPClient
|
||||
|
||||
COPYRIGHT
|
||||
|
||||
Copyright 1999, 2000 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:
|
||||
|
||||
a) the "Artistic License" which comes with this Kit, or
|
||||
|
||||
|
||||
b) the GNU General Public License as published by the Free Software
|
||||
Foundation; either versio n 1, or (at your option) any later version.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
This module provides perl routines that simplify a sockets connection
|
||||
to and an IMAP conversation with an IMAP server.
|
||||
|
||||
COMPATIBILITY
|
||||
|
||||
This module was developed on Solaris 2.5.1 and 2.6 against Netscape IMAP
|
||||
servers versions 3.6 and 4.1. However, since it is written in perl and
|
||||
designed for flexibility, it should run on any OS with a TCP/IP stack and
|
||||
a version of perl that includes the Socket and IO::Socket modules. It also
|
||||
should be able to talk to any IMAP server, even those that have, um,
|
||||
proprietary features (assuming that the programmer knows what those features
|
||||
are).
|
||||
|
||||
To date, I know that the test suite runs successfully with the following IMAP
|
||||
servers:
|
||||
|
||||
-Netscape Messenging Server v4.x
|
||||
-Netscape Messenging Server v3.x
|
||||
-UW-IMAP (I think it was 4.5)
|
||||
-Cyrus IMAP4 v1.5.19
|
||||
-Mirapoint Message Server Appliances (OS versions 1.6.1, 1.7.1, and 2.0.2)
|
||||
|
||||
I also know that it has some problems running against the InterMail server vM.4.001.02.00
|
||||
(and probably other versions of InterMail as well).
|
||||
|
||||
Version 2.0.3 has been tested with the mdaemon server with mixed results. It seems that mdaemon
|
||||
does not comply strictly with RFC2060 and so you may have problems using this module
|
||||
with mdaemon, especially with folder names with embedded spaces or embedded double quotes. You may
|
||||
be able to get some simple tasks to work but you won't be able to run the test suite successfully.
|
||||
Use with caution.
|
||||
|
||||
If your server requires the use of the AUTHENTICATE IMAP client command (say,
|
||||
for strong authentication) then you can still use this module, provided you can come
|
||||
up with the appropriate responses to any challenges offered by your server. Mark Bush's
|
||||
Authen::NTLM module can assist with this if you specifically are interested in NTLM
|
||||
authentication.
|
||||
|
||||
DEPENDENCIES
|
||||
|
||||
The Mail::IMAPClient module uses the IO::Socket module to make a socket
|
||||
connection to an IMAP server and the Socket module to get some constants.
|
||||
It also uses Errno, Fcntl (for faster I/O) and IO::Select, IO::File,
|
||||
Data::Dumper, and Carp.
|
||||
|
||||
You can verify that your system has a sufficient perl installation by
|
||||
entering on the command line:
|
||||
|
||||
perl -e "use constant; use Socket; use IO::Socket; use IO::File; use IO::Select; use Fcntl; \
|
||||
use Errno; use Carp; use Data::Dumper;"
|
||||
|
||||
If you get compile errors then you'll have trouble using Mail::IMAPClient.
|
||||
|
||||
If you need to use the bodystructure helper module Mail::IMAPClient::BodyStructure then you also need
|
||||
Parse::RecDescent. Try this on the command line:
|
||||
|
||||
perl -e "use Parse::RecDescent;"
|
||||
|
||||
If you get compile errors then you will not be able to use the
|
||||
Mail::IMAPClient::BodyStructure module (or the get_bodystructure
|
||||
method in Mail::IMAPClient). You will also get errors when you run
|
||||
'make test' in t/bodystructure and/or t/parse. If these tests fail
|
||||
you can still use Mail::IMAPClient safely (assuming the other tests passed!) but
|
||||
you will not be able to use Mail::IMAPClient::BodyStructure or the
|
||||
get_bodystructure method in Mail::IMAPClient.
|
||||
|
||||
(Note that as of version 2.2.0 the above is somewhat obsolete, since Makefile.PL
|
||||
will detect whether or not you have Parse::RecDescent and will either choose to
|
||||
or decline to install the ::BodyStructure stuff accordingly.)
|
||||
|
||||
REPORING BUGS
|
||||
|
||||
See the section on "REPORTING BUGS" in the module's documentation if you are having
|
||||
problems.
|
||||
|
||||
YOU MUST FOLLOW THE INSTRUCTIONS IN THE DOCUMENTATION AND PROVIDE ALL OF THE NECESSARY
|
||||
INFORMATION if you expect a response from your bug report. You should also look at
|
||||
the data you gather before you send it, since doing so will often solve your problem.
|
||||
|
||||
INSTALLATION
|
||||
|
||||
Generally, gunzipping and untarring the source file, running 'perl Makefile.PL'
|
||||
and 'make install' are all it takes to install this module. And if that's too
|
||||
much work you can always use the CPAN module! ;-)
|
||||
|
||||
OVERVIEW OF FUNCTIONALITY
|
||||
|
||||
Mail::IMAPClient.pm provides methods to simplify the connection to and the
|
||||
conversation between a perl script and an IMAP server. Virtually all IMAP Client
|
||||
commands (as defined in rfc2060) are supported, either through IMAPClient object
|
||||
methods or the 'default method', which is an AUTOLOAD hack that assumes a
|
||||
default syntax for IMAP Client commands of:
|
||||
|
||||
tagvalue COMMAND [Arg1 [Arg2 [... Arg3]]]"
|
||||
|
||||
By remarkable coincidence, AUTOLOAD's default syntax mimics the general syntax
|
||||
of IMAP Client commands. This means that if a script tries to use any undefined
|
||||
method then that method will be interpreted as an unimplemented IMAP command,
|
||||
and the default syntax will be used to create the command string. I did this
|
||||
as a short cut to writing a bunch of methods that were practically the same.
|
||||
There are inheritance implications because of this approach but as far as I
|
||||
can tell this is not a serious limitation. However, if you decide to write
|
||||
modules that inherit from this class that require AUTOLOAD logic of their
|
||||
own then you will have to take the Mail::IMAPClient's AUTOLOAD strategy into
|
||||
account.
|
||||
|
||||
Where methods are defined, they usually exist to add functionality, perhaps by
|
||||
massaging output or by supplying default arguments. An example is the search
|
||||
method, which accepts the same arguments as the SEARCH IMAP Client command (as
|
||||
documented in RFC2060) but which massages the results so that the return value
|
||||
is an array of message sequence numbers matching the search criteria, rather
|
||||
than a line of text listing the sequence numbers.
|
||||
|
||||
Some methods exists solely to add functionality, such as the folders method,
|
||||
which invokes the list method but then massages the results to produce an array
|
||||
containing all folder names. The message_count and delete_messsage methods are
|
||||
similarly examples of methods that add function to "raw" IMAP Client commands.
|
||||
|
||||
Further information is provided in the module's documentation, which you are
|
||||
encouraged to read and enjoy.
|
||||
|
||||
Good Luck!
|
||||
|
||||
Dave Kernen
|
||||
The Kernen Group, Inc.
|
||||
DJKERNEN@cpan.org
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
COPYRIGHT
|
||||
|
||||
Copyright 1999, 2000, 2001, 2002 , 2003 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:
|
||||
|
||||
|
||||
a) the "Artistic License" which comes with this Kit, or
|
||||
|
||||
b) the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 1, or (at your option) any later version.
|
||||
|
||||
|
||||
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.
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
use ExtUtils::MakeMaker;
|
||||
use Parse::RecDescent;
|
||||
unlink './Thread.pm' if -f './Thread.pm';
|
||||
sub MY::top_targets {
|
||||
package MY;
|
||||
|
||||
my $inherit = shift->SUPER::top_targets(@_);
|
||||
my @inherit = split("\n",$inherit);
|
||||
for (@inherit) {
|
||||
if ( /^\s*all\s*:{1,2}/ ) {
|
||||
s/(all\s*:{1,2}\s*)/$1Thread\.pm /;
|
||||
}
|
||||
}
|
||||
return join("\n",@inherit);
|
||||
}
|
||||
|
||||
sub MY::clean {
|
||||
package MY;
|
||||
|
||||
my $inherit = shift->SUPER::clean(@_);
|
||||
return join("\n",$inherit," rm Thread.pm") ;
|
||||
}
|
||||
|
||||
sub MY::postamble {
|
||||
my $string =
|
||||
'@$(PERL) "-MParse::RecDescent" "-" ' .
|
||||
'"Thread.grammar" '.
|
||||
'"Mail::IMAPClient::Thread"' ;
|
||||
return "Thread.pm: Thread.grammar\n\t$string\n\n";
|
||||
}
|
||||
|
||||
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
|
||||
# the contents of the Makefile that is written.
|
||||
#print "",MY->top_target;
|
||||
|
||||
WriteMakefile(
|
||||
'NAME' => 'Mail::IMAPClient::Thread',
|
||||
'VERSION_FROM' => '../IMAPClient.pm',
|
||||
'PREREQ_PM' => {"Parse::RecDescent" => 0 },
|
||||
'PM' => {
|
||||
'Thread.pm' =>
|
||||
'$(INST_LIBDIR)/Thread.pm'
|
||||
},
|
||||
);
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# Atoms:
|
||||
|
||||
NUMBER: /\d+/
|
||||
|
||||
# Rules:
|
||||
|
||||
threadmember: NUMBER { $return = $item{NUMBER} ; } |
|
||||
thread { $return = $item{thread} ; }
|
||||
|
||||
thread: "(" threadmember(s) ")"
|
||||
{
|
||||
$return = $item{'threadmember(s)'}||undef;
|
||||
}
|
||||
|
||||
# Start:
|
||||
start: /^\* THREAD /i thread(s?) {
|
||||
$return=$item{'thread(s?)'}||undef;
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# Atoms:
|
||||
|
||||
NUMBER: /\d+/
|
||||
|
||||
# Rules:
|
||||
|
||||
threadmember: NUMBER { $return = $item{NUMBER} ; } |
|
||||
thread { $return = $item{thread} ; }
|
||||
|
||||
thread: "(" threadmember(s) ")"
|
||||
{
|
||||
$return = $item{threadmember}||undef;
|
||||
}
|
||||
|
||||
# Start:
|
||||
start: /^\* THREAD /i thread(s?) {
|
||||
$return=$item{thread}||undef;
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
package Mail::IMAPClient::Thread;
|
||||
$Mail::IMAPClient::Thread::VERSION = "0.0.1";
|
||||
$Mail::IMAPClient::Thread::VERSION = "0.0.1";
|
||||
|
||||
=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.
|
||||
|
||||
=cut
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
# Before `make install' is performed this script should be runnable with
|
||||
# `make test'. After `make install' it should work as `perl test.pl'
|
||||
# $Id: thread.t,v 1.1 2002/08/30 20:50:43 dkernen Exp $
|
||||
######################### We start with some black magic to print on failure.
|
||||
|
||||
# Change 1..1 below to 1..last_test_to_print .
|
||||
|
||||
use Mail::IMAPClient::Thread;
|
||||
|
||||
BEGIN {
|
||||
print "1..6\n";
|
||||
$main::loaded = 1;
|
||||
$| = 1;
|
||||
print "ok 1\n";
|
||||
}
|
||||
|
||||
$t1 = <<'e1';
|
||||
* THREAD (166)(167)(168)(169)(172)(170)(171)(173)(174 175 176 178 181 180)(179)(177 183 182 188 184 185 186 187 189)(190)(191)(192)(193)(194 195)(196 197 198)(199)(200 202)(201)(203)(204)(205)(206 207)(208)
|
||||
e1
|
||||
$t2 = <<'e2';
|
||||
* THREAD (166)(167)(168)(169)(172)((170)(179))(171)(173)((174)(175)(176)(178)(181)(180))((177)(183)(182)(188 (184)(189))(185 186)(187))(190)(191)(192)(193)((194)(195 196))(197 198)(199)(200 202)(201)(203)(204)(205 206 207)(208)
|
||||
e2
|
||||
|
||||
my $parser = Mail::IMAPClient::Thread->new;
|
||||
|
||||
if ( $parser ) {
|
||||
print "ok 2\n";
|
||||
} else {
|
||||
print "not ok 2\n";
|
||||
}
|
||||
|
||||
my $thr1 = $parser->start($t1) ;
|
||||
|
||||
if ( $thr1 ) {
|
||||
print "ok 3\n";
|
||||
} else {
|
||||
print "not ok 3\n";
|
||||
}
|
||||
|
||||
if ( scalar(@$thr1) == 25 ) {
|
||||
print "ok 4\n";
|
||||
} else {
|
||||
print "not ok 4\n";
|
||||
}
|
||||
|
||||
my $thr2 = $parser->start($t2) ;
|
||||
|
||||
if ( $thr2 ) {
|
||||
print "ok 5\n";
|
||||
} else {
|
||||
print "not ok 5\n";
|
||||
}
|
||||
if ( scalar(@$thr2) == 23 ) {
|
||||
print "ok 6\n";
|
||||
} else {
|
||||
print "not ok 6\n";
|
||||
}
|
||||
|
||||
|
||||
END {print "not ok 1\n" unless $main::loaded;}
|
||||
|
||||
|
||||
# History:
|
||||
# $Log: thread.t,v $
|
||||
# Revision 1.1 2002/08/30 20:50:43 dkernen
|
||||
#
|
||||
# Added Files: Thread/Makefile.PL Thread/Thread.grammar Thread/Thread.pod
|
||||
# Added Files: Thread/t/thread.t
|
||||
#
|
||||
#
|
|
@ -1,44 +0,0 @@
|
|||
The following is a list of some items that I hope to include in a future
|
||||
release:
|
||||
|
||||
- Support for threaded perl programs (still pending as of version 2.2.0.).
|
||||
|
||||
-Support for imaps (Imap via SSL). I don't have any way to test this right now
|
||||
but if you get this to work or know someone who has I'd be really interested in
|
||||
hearing from you.
|
||||
|
||||
- Support for more authentication mechanisms. Currently plain authentication and
|
||||
cram-md5 authentication are supported. I have DIGEST-MD5 working at the AUTH
|
||||
qop, but haven't incorporated it into a released version because I'm still trying
|
||||
to get at least the integrity qop working, and maybe even privacy, but considering
|
||||
how much trouble I'm having with just the integrity level I wouldn't hold my breath
|
||||
if I were you ;-).
|
||||
|
||||
- Currently a number of IMAP Client commands are implemented using the
|
||||
'default method', which is an AUTOLOAD hack. I'd like to reduce that if
|
||||
possible to a bare minimum. (Some are still pending as of version 2.2.7.)
|
||||
|
||||
- I'd like to see this module certified for more OS's and more IMAP servers.
|
||||
This is (hopefully) just a matter of testing; the code should already be
|
||||
compatible with the IMAP servers that are out there and with any OS that
|
||||
allows the IO::Socket module to work. ** A number of platforms have been added
|
||||
to the list of tested platforms since this was first written. Please contact
|
||||
DJKernen@cpan.org if you have any to add.
|
||||
|
||||
- Support for newer/older/other versions of IMAP. Currently only RFC2060 is
|
||||
explicitly supported, although thanks to the 'default method' (implemented
|
||||
via an AUTOLOAD hack) virtually any IMAP command is supported, even
|
||||
proprietary commands, X- extensions, and so forth. But not necessarily other
|
||||
authentication mechanisms... :-( (NOTE: the AUTHENTICATE method
|
||||
partially addresses this issue.)
|
||||
|
||||
- Support for piping output from (some?) imap commands directly to a
|
||||
thingy of some sort (perhaps a coderef, a filehandle, or both).
|
||||
|
||||
- Your thingy here!!! Send me your request, and I'll do it in the order of
|
||||
( $popularity/$difficulty ).
|
||||
|
||||
- Support for perl version 6. This will probably involve a rewrite that will make
|
||||
portions of the Mail::IMAPClient module look more like the Mail::IMAPClient::BodyStructure
|
||||
module. (Perl 6 will have built-in support for semantics that look remarkably like
|
||||
Damian Conway's Parse::RecDescent module, which will solve a lot of problems for me.)
|
|
@ -1,21 +0,0 @@
|
|||
COPYRIGHT
|
||||
|
||||
Copyright 1999, 2000, 2001, 2002 , 2003 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:
|
||||
|
||||
|
||||
a) the "Artistic License" which comes with this Kit, or
|
||||
|
||||
b) the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 1, or (at your option) any later version.
|
||||
|
||||
|
||||
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.
|
||||
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,564 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
IMAP Extensions Working Group M. Crispin
|
||||
INTERNET-DRAFT: IMAP SORT K. Murchison
|
||||
Document: internet-drafts/draft-ietf-imapext-sort-06.txt December 2000
|
||||
|
||||
|
||||
INTERNET MESSAGE ACCESS PROTOCOL - SORT EXTENSION
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This document is an Internet-Draft and is in full conformance with
|
||||
all provisions of Section 10 of RFC 2026.
|
||||
|
||||
Internet-Drafts are working documents of the Internet Engineering
|
||||
Task Force (IETF), its areas, and its working groups. Note that
|
||||
other groups may also distribute working documents as
|
||||
Internet-Drafts.
|
||||
|
||||
Internet-Drafts are draft documents valid for a maximum of six months
|
||||
and may be updated, replaced, or obsoleted by other documents at any
|
||||
time. It is inappropriate to use Internet-Drafts as reference
|
||||
material or to cite them other than as "work in progress."
|
||||
|
||||
The list of current Internet-Drafts can be accessed at
|
||||
http://www.ietf.org/ietf/1id-abstracts.txt
|
||||
|
||||
To view the list Internet-Draft Shadow Directories, see
|
||||
http://www.ietf.org/shadow.html.
|
||||
|
||||
A revised version of this document will be submitted to the RFC
|
||||
editor as an Informational Document for the Internet Community.
|
||||
|
||||
A revised version of this draft document, describing an expanded
|
||||
version of this protocol extension, will be submitted to the RFC
|
||||
editor as a Proposed Standard for the Internet Community.
|
||||
|
||||
Discussion and suggestions for improvement are requested, and should
|
||||
be sent to ietf-imapext@IMC.ORG. This document will expire before 29
|
||||
June 2001. Distribution of this memo is unlimited.
|
||||
|
||||
|
||||
Abstract
|
||||
|
||||
This document describes an experimental server-based sorting
|
||||
extension to the IMAP4rev1 protocol, as implemented by the University
|
||||
of Washington's IMAP toolkit. This extension provides substantial
|
||||
performance improvements for IMAP clients which offer sorted views.
|
||||
|
||||
A server which supports this extension indicates this with a
|
||||
|
||||
|
||||
|
||||
Crispin [Page 1]
|
||||
|
||||
INTERNET DRAFT IMAP SORT EXPIRES 29 June 2000
|
||||
|
||||
|
||||
capability name of "SORT". Client implementations SHOULD accept any
|
||||
capability name which begins with "SORT" as indicating support for
|
||||
the extension described in this document. This provides for future
|
||||
upwards-compatible extensions.
|
||||
|
||||
At the time of this document was written, the IMAP Extensions Working
|
||||
Group (IETF-IMAPEXT) was considering upwards-compatible additions to
|
||||
the SORT extension described in this document, tentatively called the
|
||||
SORT2 extension.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin [Page 2]
|
||||
|
||||
INTERNET DRAFT IMAP SORT EXPIRES 29 June 2000
|
||||
|
||||
|
||||
Extracted Subject Text
|
||||
|
||||
The "SUBJECT" SORT criteria uses a version of the subject which has
|
||||
specific subject artifacts of deployed Internet mail software
|
||||
removed. Due to the complexity of these artifacts, the formal syntax
|
||||
for the subject extraction rules is ambiguous. The following
|
||||
procedure is followed to determine the actual "base subject" which is
|
||||
used to sort by subject:
|
||||
|
||||
(1) Convert any RFC 2047 encoded-words in the subject to
|
||||
UTF-8. Convert all tabs and continuations to space.
|
||||
Convert all multiple spaces to a single space.
|
||||
|
||||
(2) Remove all trailing text of the subject that matches
|
||||
the subj-trailer ABNF, repeat until no more matches are
|
||||
possible.
|
||||
|
||||
(3) Remove all prefix text of the subject that matches the
|
||||
subj-leader ABNF.
|
||||
|
||||
(4) If there is prefix text of the subject that matches the
|
||||
subj-blob ABNF, and removing that prefix leaves a non-empty
|
||||
subj-base, then remove the prefix text.
|
||||
|
||||
(5) Repeat (3) and (4) until no matches remain.
|
||||
|
||||
Note: it is possible to defer step (2) until step (6), but this
|
||||
requires checking for subj-trailer in step (4).
|
||||
|
||||
(6) If the resulting text begins with the subj-fwd-hdr ABNF
|
||||
and ends with the subj-fwd-trl ABNF, remove the
|
||||
subj-fwd-hdr and subj-fwd-trl and repeat from step (2).
|
||||
|
||||
(7) The resulting text is the "base subject" used in the
|
||||
SORT.
|
||||
|
||||
All servers and disconnected clients MUST use exactly this algorithm
|
||||
when sorting by subject. Otherwise there is potential for a user to
|
||||
get inconsistent results based on whether they are running in
|
||||
connected or disconnected IMAP mode.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin [Page 3]
|
||||
|
||||
INTERNET DRAFT IMAP SORT EXPIRES 29 June 2000
|
||||
|
||||
|
||||
Additional Commands
|
||||
|
||||
This command is an extension to the IMAP4rev1 base protocol.
|
||||
|
||||
The section header is intended to correspond with where it would be
|
||||
located in the main document if it was part of the base
|
||||
specification.
|
||||
|
||||
|
||||
6.3.SORT. SORT Command
|
||||
|
||||
Arguments: sort program
|
||||
charset specification
|
||||
searching criteria (one or more)
|
||||
|
||||
Data: untagged responses: SORT
|
||||
|
||||
Result: OK - sort completed
|
||||
NO - sort error: can't sort that charset or
|
||||
criteria
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
The SORT command is a variant of SEARCH with sorting semantics for
|
||||
the results. Sort has two arguments before the searching criteria
|
||||
argument; a parenthesized list of sort criteria, and the searching
|
||||
charset.
|
||||
|
||||
Note that unlike SEARCH, the searching charset argument is
|
||||
mandatory. The US-ASCII and UTF-8 charsets MUST be implemented.
|
||||
All other charsets are optional.
|
||||
|
||||
There is also a UID SORT command which corresponds to SORT the way
|
||||
that UID SEARCH corresponds to SEARCH.
|
||||
|
||||
The SORT command first searches the mailbox for messages that
|
||||
match the given searching criteria using the charset argument for
|
||||
the interpretation of strings in the searching criteria. It then
|
||||
returns the matching messages in an untagged SORT response, sorted
|
||||
according to one or more sort criteria.
|
||||
|
||||
If two or more messages exactly match according to the sorting
|
||||
criteria, these messages are sorted according to the order in
|
||||
which they appear in the mailbox. In other words, there is an
|
||||
implicit sort criterion of "sequence number".
|
||||
|
||||
When multiple sort criteria are specified, the result is sorted in
|
||||
the priority order that the criteria appear. For example,
|
||||
(SUBJECT DATE) will sort messages in order by their subject text;
|
||||
|
||||
|
||||
|
||||
Crispin [Page 4]
|
||||
|
||||
INTERNET DRAFT IMAP SORT EXPIRES 29 June 2000
|
||||
|
||||
|
||||
and for messages with the same subject text will sort by their
|
||||
sent date.
|
||||
|
||||
Untagged EXPUNGE responses are not permitted while the server is
|
||||
responding to a SORT command, but are permitted during a UID SORT
|
||||
command.
|
||||
|
||||
The defined sort criteria are as follows. Refer to the Formal
|
||||
Syntax section for the precise syntactic definitions of the
|
||||
arguments. If the associated RFC-822 header for a particular
|
||||
criterion is absent, it is treated as the empty string. The empty
|
||||
string always collates before non-empty strings.
|
||||
|
||||
ARRIVAL
|
||||
Internal date and time of the message. This differs from the
|
||||
ON criteria in SEARCH, which uses just the internal date.
|
||||
|
||||
CC
|
||||
RFC-822 local-part of the first "cc" address.
|
||||
|
||||
DATE
|
||||
Sent date and time from the Date: header, adjusted by time
|
||||
zone. This differs from the SENTON criteria in SEARCH, which
|
||||
uses just the date and not the time, nor adjusts by time zone.
|
||||
|
||||
FROM
|
||||
RFC-822 local-part of the "From" address.
|
||||
|
||||
REVERSE
|
||||
Followed by another sort criterion, has the effect of that
|
||||
criterion but in reverse order.
|
||||
Note: REVERSE only reverses a single criterion, and does not
|
||||
affect the implicit "sequence number" sort criterion if all
|
||||
other criteria are identicial. Consequently, a sort of
|
||||
REVERSE SUBJECT is not the same as a reverse ordering of a
|
||||
SUBJECT sort.
|
||||
This can be avoided by use of additional criteria, e.g.
|
||||
SUBJECT DATE vs. REVERSE SUBJECT REVERSE DATE. In general,
|
||||
however, it's better (and faster, if the client has a
|
||||
"reverse current ordering" command) to reverse the results
|
||||
in the client instead of issuing a new SORT.
|
||||
|
||||
SIZE
|
||||
Size of the message in octets.
|
||||
|
||||
SUBJECT
|
||||
Extracted subject text.
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin [Page 5]
|
||||
|
||||
INTERNET DRAFT IMAP SORT EXPIRES 29 June 2000
|
||||
|
||||
|
||||
TO
|
||||
RFC-822 local-part of the first "To" address.
|
||||
|
||||
|
||||
Example: C: A282 SORT (SUBJECT) UTF-8 SINCE 1-Feb-1994
|
||||
S: * SORT 2 84 882
|
||||
S: A282 OK SORT completed
|
||||
C: A283 SORT (SUBJECT REVERSE DATE) UTF-8 ALL
|
||||
S: * SORT 5 3 4 1 2
|
||||
S: A283 OK SORT completed
|
||||
C: A284 SORT (SUBJECT) US-ASCII TEXT "not in mailbox"
|
||||
S: * SORT
|
||||
S: A284 OK SORT completed
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin [Page 6]
|
||||
|
||||
INTERNET DRAFT IMAP SORT EXPIRES 29 June 2000
|
||||
|
||||
|
||||
Additional Responses
|
||||
|
||||
This response is an extension to the IMAP4rev1 base protocol.
|
||||
|
||||
The section heading of this response is intended to correspond with
|
||||
where it would be located in the main document.
|
||||
|
||||
|
||||
7.2.SORT. SORT Response
|
||||
|
||||
Data: zero or more numbers
|
||||
|
||||
The SORT response occurs as a result of a SORT or UID SORT
|
||||
command. The number(s) refer to those messages that match the
|
||||
search criteria. For SORT, these are message sequence numbers;
|
||||
for UID SORT, these are unique identifiers. Each number is
|
||||
delimited by a space.
|
||||
|
||||
Example: S: * SORT 2 3 6
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin [Page 7]
|
||||
|
||||
INTERNET DRAFT IMAP SORT EXPIRES 29 June 2000
|
||||
|
||||
|
||||
Formal Syntax of SORT commands and Responses
|
||||
|
||||
sort-data = "SORT" *(SP nz-number)
|
||||
|
||||
sort = ["UID" SP] "SORT" SP
|
||||
"(" sort-criterion *(SP sort-criterion) ")"
|
||||
SP search_charset 1*(SP search_key)
|
||||
|
||||
sort-criterion = ["REVERSE" SP] sort-key
|
||||
|
||||
sort-key = "ARRIVAL" / "CC" / "DATE" / "FROM" / "SIZE" /
|
||||
"SUBJECT" / "TO"
|
||||
|
||||
|
||||
The following syntax describes subject extraction rules (2)-(6):
|
||||
|
||||
subject = *subj-leader [subj-middle] *subj-trailer
|
||||
|
||||
subj-refwd = ("re" / ("fw" ["d"])) *WSP [subj-blob] ":"
|
||||
|
||||
subj-blob = "[" *BLOBCHAR "]" *WSP
|
||||
|
||||
subj-fwd = subj-fwd-hdr subject subj-fwd-trl
|
||||
|
||||
subj-fwd-hdr = "[fwd:"
|
||||
|
||||
subj-fwd-trl = "]"
|
||||
|
||||
subj-leader = (*subj-blob subj-refwd) / WSP
|
||||
|
||||
subj-middle = *subj-blob (subj-base / subj-fwd)
|
||||
; last subj-blob is subj-base if subj-base would
|
||||
; otherwise be empty
|
||||
|
||||
subj-trailer = "(fwd)" / WSP
|
||||
|
||||
subj-base = NONWSP *([*WSP] NONWSP)
|
||||
; can be a subj-blob
|
||||
|
||||
BLOBCHAR = %x01-5a / %x5c / %x5e-7f
|
||||
; any CHAR except '[' and ']'
|
||||
|
||||
NONWSP = %x01-08 / %x0a-1f / %x21-7f
|
||||
; any CHAR other than WSP
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin [Page 8]
|
||||
|
||||
INTERNET DRAFT IMAP SORT EXPIRES 29 June 2000
|
||||
|
||||
|
||||
Security Considerations
|
||||
|
||||
Security issues are not discussed in this memo.
|
||||
|
||||
|
||||
Internationalization Considerations
|
||||
|
||||
By default, strings are sorted according to the "minimum sorting
|
||||
collation algorithm". All implementations of SORT MUST implement the
|
||||
minimum sorting collation algorithm.
|
||||
|
||||
In the minimum sorting collation algorithm, the Basic Latin
|
||||
alphabetics (U+0041 to U+005A uppercase, U+0061 to U+007A lowercase)
|
||||
are sorted in a case-insensitive fashion; that is, "A" (U+0041) and
|
||||
"a" (U+0061) are treated as exact equals. The characters U+005B to
|
||||
U+0060 are sorted after the Basic Latin alphabetics; for example,
|
||||
U+005E is sorted after U+005A and U+007A. All other characters are
|
||||
sorted according to their octet values, as expressed in UTF-8. No
|
||||
attempt is made to treat composed characters specially, or to do
|
||||
case-insensitive comparisons of composed characters.
|
||||
|
||||
Note: this means, among other things, that the composed
|
||||
characters in the Latin-1 Supplement are not compared in
|
||||
what would be considered an ISO 8859-1 "case-insensitive"
|
||||
fashion. Case comparison rules for characters with
|
||||
diacriticals differ between languages; the minimum sorting
|
||||
collation does not attempt to deal with this at all. This
|
||||
is reserved for other sorting collations, which may be
|
||||
language-specific.
|
||||
|
||||
Other sorting collations, and the ability to change the sorting
|
||||
collation, will be defined in a separate document dealing with IMAP
|
||||
internationalization.
|
||||
|
||||
It is anticipated that there will be a generic Unicode sorting
|
||||
collation, which will provide generic case-insensitivity for
|
||||
alphabetic scripts, specification of composed character handling, and
|
||||
language-specific sorting collations. A server which implements
|
||||
non-default sorting collations will modify its sorting behavior
|
||||
according to the selected sorting collation.
|
||||
|
||||
Non-English translations of "Re" or "Fw"/"Fwd" are not specified for
|
||||
removal in the extracted subject text process. By specifying that
|
||||
only the English forms of the prefixes are used, it becomes a simple
|
||||
display time task to localize the prefix language for the user. If,
|
||||
on the other hand, prefixes in multiple languages are permitted, the
|
||||
result is a geometrically complex, and ultimately unimplementable,
|
||||
task. In order to improve the ability to support non-English display
|
||||
|
||||
|
||||
|
||||
Crispin [Page 9]
|
||||
|
||||
INTERNET DRAFT IMAP SORT EXPIRES 29 June 2000
|
||||
|
||||
|
||||
in Internet mail clients, only the English form of these prefixes
|
||||
should be transmitted in Internet mail messages.
|
||||
|
||||
|
||||
Author's Address
|
||||
|
||||
Mark R. Crispin
|
||||
Networks and Distributed Computing
|
||||
University of Washington
|
||||
4545 15th Avenue NE
|
||||
Seattle, WA 98105-4527
|
||||
|
||||
Phone: (206) 543-5762
|
||||
|
||||
EMail: MRC@CAC.Washington.EDU
|
||||
|
||||
|
||||
Kenneth Murchison
|
||||
Oceana Matrix Ltd.
|
||||
21 Princeton Place
|
||||
Orchard Park, NY 14127
|
||||
|
||||
Phone: (716) 662-8973 x26
|
||||
|
||||
EMail: ken@oceana.com
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin [Page 10]
|
||||
|
||||
|
|
@ -1,788 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
IMAP Extensions Working Group M. Crispin
|
||||
Internet Draft: IMAP THREAD K. Murchison
|
||||
Document: internet-drafts/draft-ietf-imapext-thread-11.txt June 2002
|
||||
|
||||
|
||||
INTERNET MESSAGE ACCESS PROTOCOL - THREAD EXTENSION
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This document is an Internet-Draft and is in full conformance with
|
||||
all provisions of Section 10 of RFC 2026.
|
||||
|
||||
Internet-Drafts are working documents of the Internet Engineering
|
||||
Task Force (IETF), its areas, and its working groups. Note that
|
||||
other groups may also distribute working documents as Internet-
|
||||
Drafts.
|
||||
|
||||
Internet-Drafts are draft documents valid for a maximum of six months
|
||||
and may be updated, replaced, or obsoleted by other documents at any
|
||||
time. It is inappropriate to use Internet-Drafts as reference
|
||||
material or to cite them other than as "work in progress."
|
||||
|
||||
The list of current Internet-Drafts can be accessed at
|
||||
http://www.ietf.org/ietf/1id-abstracts.txt
|
||||
|
||||
To view the list Internet-Draft Shadow Directories, see
|
||||
http://www.ietf.org/shadow.html.
|
||||
|
||||
A revised version of this draft document will be submitted to the RFC
|
||||
editor as a Proposed Standard for the Internet Community. Discussion
|
||||
and suggestions for improvement are requested, and should be sent to
|
||||
ietf-imapext@IMC.ORG. This document will expire before 22 December
|
||||
2002. Distribution of this memo is unlimited.
|
||||
|
||||
|
||||
Abstract
|
||||
|
||||
This document describes the server-based threading extension to the
|
||||
IMAP4rev1 protocol. This extension provides substantial performance
|
||||
improvements for IMAP clients which offer threaded views.
|
||||
|
||||
A server which supports this extension indicates this with one or
|
||||
more capability names consisting of "THREAD=" followed by a supported
|
||||
threading algorithm name as described in this document. This
|
||||
provides for future upwards-compatible extensions.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin and Murchison [Page 1]
|
||||
|
||||
INTERNET DRAFT IMAP THREAD EXPIRES 22 December 2002
|
||||
|
||||
|
||||
Base Subject Text
|
||||
|
||||
Threading uses the "base subject," which has specific subject
|
||||
artifacts of deployed Internet mail software removed. Due to the
|
||||
complexity of these artifacts, the formal syntax for the subject
|
||||
extraction rules is ambiguous. The following procedure is followed
|
||||
to determine the actual "base subject" which is used to thread:
|
||||
|
||||
(1) Convert any RFC 2047 encoded-words in the subject to
|
||||
UTF-8. Convert all tabs and continuations to space.
|
||||
Convert all multiple spaces to a single space.
|
||||
|
||||
(2) Remove all trailing text of the subject that matches
|
||||
the subj-trailer ABNF, repeat until no more matches are
|
||||
possible.
|
||||
|
||||
(3) Remove all prefix text of the subject that matches the
|
||||
subj-leader ABNF.
|
||||
|
||||
(4) If there is prefix text of the subject that matches the
|
||||
subj-blob ABNF, and removing that prefix leaves a non-empty
|
||||
subj-base, then remove the prefix text.
|
||||
|
||||
(5) Repeat (3) and (4) until no matches remain.
|
||||
|
||||
Note: it is possible to defer step (2) until step (6),
|
||||
but this requires checking for subj-trailer in step (4).
|
||||
|
||||
(6) If the resulting text begins with the subj-fwd-hdr ABNF
|
||||
and ends with the subj-fwd-trl ABNF, remove the
|
||||
subj-fwd-hdr and subj-fwd-trl and repeat from step (2).
|
||||
|
||||
(7) The resulting text is the "base subject" used in
|
||||
threading.
|
||||
|
||||
All servers and disconnected clients MUST use exactly this algorithm
|
||||
when threading. Otherwise there is potential for a user to get
|
||||
inconsistent results based on whether they are running in connected
|
||||
or disconnected IMAP mode.
|
||||
|
||||
Sent Date
|
||||
|
||||
As used in this document, the term "sent date" refers to the date and
|
||||
time from the Date: header, adjusted by time zone. This differs from
|
||||
date-related criteria in SEARCH, which use just the date and not the
|
||||
time, nor adjusts by time zone.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin and Murchison [Page 2]
|
||||
|
||||
INTERNET DRAFT IMAP THREAD EXPIRES 22 December 2002
|
||||
|
||||
|
||||
Additional Commands
|
||||
|
||||
This command is an extension to the IMAP4rev1 base protocol.
|
||||
|
||||
The section header is intended to correspond with where it would be
|
||||
located in the main document if it was part of the base
|
||||
specification.
|
||||
|
||||
|
||||
6.3.THREAD. THREAD Command
|
||||
|
||||
Arguments: threading algorithm
|
||||
charset specification
|
||||
searching criteria (one or more)
|
||||
|
||||
Data: untagged responses: THREAD
|
||||
|
||||
Result: OK - thread completed
|
||||
NO - thread error: can't thread that charset or
|
||||
criteria
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
The THREAD command is a variant of SEARCH with threading semantics
|
||||
for the results. Thread has two arguments before the searching
|
||||
criteria argument; a threading algorithm, and the searching
|
||||
charset. Note that unlike SEARCH, the searching charset argument
|
||||
is mandatory.
|
||||
|
||||
There is also a UID THREAD command which corresponds to THREAD the
|
||||
way that UID SEARCH corresponds to SEARCH.
|
||||
|
||||
The THREAD command first searches the mailbox for messages that
|
||||
match the given searching criteria using the charset argument for
|
||||
the interpretation of strings in the searching criteria. It then
|
||||
returns the matching messages in an untagged THREAD response,
|
||||
threaded according to the specified threading algorithm.
|
||||
|
||||
Sorting is in ascending order. Earlier dates sort before later
|
||||
dates; smaller sizes sort before larger sizes; and strings are
|
||||
sorted according to ascending values established by their
|
||||
collation algorithm (see under "Internationalization
|
||||
Considerations").
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin and Murchison [Page 3]
|
||||
|
||||
INTERNET DRAFT IMAP THREAD EXPIRES 22 December 2002
|
||||
|
||||
|
||||
The defined threading algorithms are as follows:
|
||||
|
||||
ORDEREDSUBJECT
|
||||
The ORDEREDSUBJECT threading algorithm is also referred to as
|
||||
"poor man's threading." The searched messages are sorted by
|
||||
base subject and then by the sent date. The messages are then
|
||||
split into separate threads, with each thread containing
|
||||
messages with the same base subject text. Finally, the threads
|
||||
are sorted by the sent date of the first message in the thread.
|
||||
|
||||
Note that each message in a thread is a child (as opposed to a
|
||||
sibling) of the previous message.
|
||||
|
||||
REFERENCES
|
||||
The REFERENCES threading algorithm is based on the algorithm
|
||||
written by Jamie Zawinski which was used in "Netscape Mail and
|
||||
News" versions 2.0 through 3.0. For details, see
|
||||
http://www.jwz.org/doc/threading.html.
|
||||
|
||||
This algorithm threads the searched messages by grouping them
|
||||
together in parent/child relationships based on which messages
|
||||
are replies to others. The parent/child relationships are
|
||||
built using two methods: reconstructing a message's ancestry
|
||||
using the references contained within it; and checking the
|
||||
original (not base) subject of a message to see if it is a
|
||||
reply to (or forward of) another message.
|
||||
|
||||
Note: "Message ID" in the following description refers to a
|
||||
normalized form of the msg-id in [RFC 2822]. The actual
|
||||
text in an RFC 2822 may use quoting, resulting in multiple
|
||||
ways of expressing the same Message ID. Implementations of
|
||||
the REFERENCES threading algorithm MUST normalize any msg-id
|
||||
in order to avoid false non-matches due to differences in
|
||||
quoting.
|
||||
|
||||
For example, the msg-id
|
||||
<"01KF8JCEOCBS0045PS"@xxx.yyy.com>
|
||||
and the msg-id
|
||||
<01KF8JCEOCBS0045PS@xxx.yyy.com>
|
||||
MUST be interpreted as being the same Message ID.
|
||||
|
||||
The references used for reconstructing a message's ancestry are
|
||||
found using the following rules:
|
||||
|
||||
If a message contains a [NEWS]-style References header line,
|
||||
then use the Message IDs in the References header line as
|
||||
the references.
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin and Murchison [Page 4]
|
||||
|
||||
INTERNET DRAFT IMAP THREAD EXPIRES 22 December 2002
|
||||
|
||||
|
||||
If a message does not contain a References header line, or
|
||||
the References header line does not contain any valid
|
||||
Message IDs, then use the first (if any) valid Message ID
|
||||
found in the In-Reply-To header line as the only reference
|
||||
(parent) for this message.
|
||||
|
||||
Note: Although [RFC 2822] permits multiple Message IDs in
|
||||
the In-Reply-To header, in actual practice this
|
||||
discipline has not been followed. For example,
|
||||
In-Reply-To headers have been observed with email
|
||||
addresses after the Message ID, and there are no good
|
||||
heuristics for software to determine the difference.
|
||||
This is not a problem with the References header however.
|
||||
|
||||
If a message does not contain an In-Reply-To header line, or
|
||||
the In-Reply-To header line does not contain a valid Message
|
||||
ID, then the message does not have any references (NIL).
|
||||
|
||||
A message is considered to be a reply or forward if the base
|
||||
subject extraction rules, applied to the original subject,
|
||||
remove any of the following: a subj-refwd, a "(fwd)"
|
||||
subj-trailer, or a subj-fwd-hdr and subj-fwd-trl.
|
||||
|
||||
The REFERENCES algorithm is significantly more complex than
|
||||
ORDEREDSUBJECT and consists of six main steps. These steps are
|
||||
outlined in detail below.
|
||||
|
||||
(1) For each searched message:
|
||||
|
||||
(A) Using the Message IDs in the message's references, link
|
||||
the corresponding messages (those whose Message-ID header
|
||||
line contains the given reference Message ID) together as
|
||||
parent/child. Make the first reference the parent of the
|
||||
second (and the second a child of the first), the second the
|
||||
parent of the third (and the third a child of the second),
|
||||
etc. The following rules govern the creation of these
|
||||
links:
|
||||
|
||||
If a message does not contain a Message-ID header line,
|
||||
or the Message-ID header line does not contain a valid
|
||||
Message ID, then assign a unique Message ID to this
|
||||
message.
|
||||
|
||||
If two or more messages have the same Message ID, assign
|
||||
a unique Message ID to each of the duplicates.
|
||||
|
||||
If no message can be found with a given Message ID,
|
||||
create a dummy message with this ID. Use this dummy
|
||||
|
||||
|
||||
|
||||
Crispin and Murchison [Page 5]
|
||||
|
||||
INTERNET DRAFT IMAP THREAD EXPIRES 22 December 2002
|
||||
|
||||
|
||||
message for all subsequent references to this ID.
|
||||
|
||||
If a message already has a parent, don't change the
|
||||
existing link. This is done because the References
|
||||
header line may have been truncated by a MUA. As a
|
||||
result, there is no guarantee that the messages
|
||||
corresponding to adjacent Message IDs in the References
|
||||
header line are parent and child.
|
||||
|
||||
Do not create a parent/child link if creating that link
|
||||
would introduce a loop. For example, before making
|
||||
message A the parent of B, make sure that A is not a
|
||||
descendent of B.
|
||||
|
||||
Note: Message ID comparisons are case-sensitive.
|
||||
|
||||
(B) Create a parent/child link between the last reference
|
||||
(or NIL if there are no references) and the current message.
|
||||
If the current message already has a parent, it is probably
|
||||
the result of a truncated References header line, so break
|
||||
the current parent/child link before creating the new
|
||||
correct one. As in step 1.A, do not create the parent/child
|
||||
link if creating that link would introduce a loop. Note
|
||||
that if this message has no references, that it will now
|
||||
have no parent.
|
||||
|
||||
Note: The parent/child links created in steps 1.A and 1.B
|
||||
MUST be kept consistent with one another at ALL times.
|
||||
|
||||
(2) Gather together all of the messages that have no parents
|
||||
and make them all children (siblings of one another) of a dummy
|
||||
parent (the "root"). These messages constitute the first
|
||||
(head) message of the threads created thus far.
|
||||
|
||||
(3) Prune dummy messages from the thread tree. Traverse each
|
||||
thread under the root, and for each message:
|
||||
|
||||
If it is a dummy message with NO children, delete it.
|
||||
|
||||
If it is a dummy message with children, delete it, but
|
||||
promote its children to the current level. In other words,
|
||||
splice them in with the dummy's siblings.
|
||||
|
||||
Do not promote the children if doing so would make them
|
||||
children of the root, unless there is only one child.
|
||||
|
||||
(4) Sort the messages under the root (top-level siblings only)
|
||||
by sent date. In the case of an exact match on sent date or if
|
||||
|
||||
|
||||
|
||||
Crispin and Murchison [Page 6]
|
||||
|
||||
INTERNET DRAFT IMAP THREAD EXPIRES 22 December 2002
|
||||
|
||||
|
||||
either of the Date: headers used in a comparison can not be
|
||||
parsed, use the order in which the messages appear in the
|
||||
mailbox (that is, by sequence number) to determine the order.
|
||||
In the case of a dummy message, sort its children by sent date
|
||||
and then use the first child for the top-level sort.
|
||||
|
||||
(5) Gather together messages under the root that have the same
|
||||
base subject text.
|
||||
|
||||
(A) Create a table for associating base subjects with
|
||||
messages, called the subject table.
|
||||
|
||||
(B) Populate the subject table with one message per each
|
||||
base subject. For each child of the root:
|
||||
|
||||
(i) Find the subject of this thread, by using the base
|
||||
subject from either the current message or its first
|
||||
child if the current message is a dummy. This is the
|
||||
thread subject.
|
||||
|
||||
(ii) If the thread subject is empty, skip this message.
|
||||
|
||||
(iii) Look up the message associated with the thread
|
||||
subject in the subject table.
|
||||
|
||||
(iv) If there is no message in the subject table with the
|
||||
thread subject, add the current message and the thread
|
||||
subject to the subject table.
|
||||
|
||||
Otherwise, if the message in the subject table is not a
|
||||
dummy, AND either of the following criteria are true:
|
||||
|
||||
The current message is a dummy, OR
|
||||
|
||||
The message in the subject table is a reply or forward
|
||||
and the current message is not.
|
||||
|
||||
then replace the message in the subject table with the
|
||||
current message.
|
||||
|
||||
(C) Merge threads with the same thread subject. For each
|
||||
child of the root:
|
||||
|
||||
(i) Find the message's thread subject as in step 5.B.i
|
||||
above.
|
||||
|
||||
(ii) If the thread subject is empty, skip this message.
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin and Murchison [Page 7]
|
||||
|
||||
INTERNET DRAFT IMAP THREAD EXPIRES 22 December 2002
|
||||
|
||||
|
||||
(iii) Lookup the message associated with this thread
|
||||
subject in the subject table.
|
||||
|
||||
(iv) If the message in the subject table is the current
|
||||
message, skip this message.
|
||||
|
||||
Otherwise, merge the current message with the one in the
|
||||
subject table using the following rules:
|
||||
|
||||
If both messages are dummies, append the current
|
||||
message's children to the children of the message in
|
||||
the subject table (the children of both messages
|
||||
become siblings), and then delete the current message.
|
||||
|
||||
If the message in the subject table is a dummy and the
|
||||
current message is not, make the current message a
|
||||
child of the message in the subject table (a sibling
|
||||
of its children).
|
||||
|
||||
If the current message is a reply or forward and the
|
||||
message in the subject table is not, make the current
|
||||
message a child of the message in the subject table (a
|
||||
sibling of its children).
|
||||
|
||||
Otherwise, create a new dummy message and make both
|
||||
the current message and the message in the subject
|
||||
table children of the dummy. Then replace the message
|
||||
in the subject table with the dummy message.
|
||||
|
||||
Note: Subject comparisons are case-insensitive, as
|
||||
described under "Internationalization
|
||||
Considerations."
|
||||
|
||||
(6) Traverse the messages under the root and sort each set of
|
||||
siblings by sent date. Traverse the messages in such a way
|
||||
that the "youngest" set of siblings are sorted first, and the
|
||||
"oldest" set of siblings are sorted last (grandchildren are
|
||||
sorted before children, etc). In the case of an exact match on
|
||||
sent date or if either of the Date: headers used in a
|
||||
comparison can not be parsed, use the order in which the
|
||||
messages appear in the mailbox (that is, by sequence number) to
|
||||
determine the order. In the case of a dummy message (which can
|
||||
only occur with top-level siblings), use its first child for
|
||||
sorting.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin and Murchison [Page 8]
|
||||
|
||||
INTERNET DRAFT IMAP THREAD EXPIRES 22 December 2002
|
||||
|
||||
|
||||
Example: C: A283 THREAD ORDEREDSUBJECT UTF-8 SINCE 5-MAR-2000
|
||||
S: * THREAD (166)(167)(168)(169)(172)(170)(171)
|
||||
(173)(174 175 176 178 181 180)(179)(177 183
|
||||
182 188 184 185 186 187 189)(190)(191)(192)
|
||||
(193)(194 195)(196 197 198)(199)(200 202)(201)
|
||||
(203)(204)(205)(206 207)(208)
|
||||
S: A283 OK THREAD completed
|
||||
C: A284 THREAD ORDEREDSUBJECT US-ASCII TEXT "gewp"
|
||||
S: * THREAD
|
||||
S: A284 OK THREAD completed
|
||||
C: A285 THREAD REFERENCES UTF-8 SINCE 5-MAR-2000
|
||||
S: * THREAD (166)(167)(168)(169)(172)((170)(179))
|
||||
(171)(173)((174)(175)(176)(178)(181)(180))
|
||||
((177)(183)(182)(188 (184)(189))(185 186)(187))
|
||||
(190)(191)(192)(193)((194)(195 196))(197 198)
|
||||
(199)(200 202)(201)(203)(204)(205 206 207)(208)
|
||||
S: A285 OK THREAD completed
|
||||
|
||||
|
||||
Note: The line breaks in the first and third client
|
||||
responses are for editorial clarity and do not appear in
|
||||
real THREAD responses.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin and Murchison [Page 9]
|
||||
|
||||
INTERNET DRAFT IMAP THREAD EXPIRES 22 December 2002
|
||||
|
||||
|
||||
Additional Responses
|
||||
|
||||
This response is an extension to the IMAP4rev1 base protocol.
|
||||
|
||||
The section heading of this response is intended to correspond with
|
||||
where it would be located in the main document.
|
||||
|
||||
|
||||
7.2.THREAD. THREAD Response
|
||||
|
||||
Data: zero or more threads
|
||||
|
||||
The THREAD response occurs as a result of a THREAD or UID THREAD
|
||||
command. It contains zero or more threads. A thread consists of
|
||||
a parenthesized list of thread members.
|
||||
|
||||
Thread members consist of zero or more message numbers, delimited
|
||||
by spaces, indicating successive parent and child. This continues
|
||||
until the thread splits into multiple sub-threads, at which point
|
||||
the thread nests into multiple sub-threads with the first member
|
||||
of each subthread being siblings at this level. There is no limit
|
||||
to the nesting of threads.
|
||||
|
||||
The messages numbers refer to those messages that match the search
|
||||
criteria. For THREAD, these are message sequence numbers; for UID
|
||||
THREAD, these are unique identifiers.
|
||||
|
||||
Example: S: * THREAD (2)(3 6 (4 23)(44 7 96))
|
||||
|
||||
The first thread consists only of message 2. The second thread
|
||||
consists of the messages 3 (parent) and 6 (child), after which it
|
||||
splits into two subthreads; the first of which contains messages 4
|
||||
(child of 6, sibling of 44) and 23 (child of 4), and the second of
|
||||
which contains messages 44 (child of 6, sibling of 4), 7 (child of
|
||||
44), and 96 (child of 7). Since some later messages are parents
|
||||
of earlier messages, the messages were probably moved from some
|
||||
other mailbox at different times.
|
||||
|
||||
-- 2
|
||||
|
||||
-- 3
|
||||
\-- 6
|
||||
|-- 4
|
||||
| \-- 23
|
||||
|
|
||||
\-- 44
|
||||
\-- 7
|
||||
\-- 96
|
||||
|
||||
|
||||
|
||||
Crispin and Murchison [Page 10]
|
||||
|
||||
INTERNET DRAFT IMAP THREAD EXPIRES 22 December 2002
|
||||
|
||||
|
||||
Example: S: * THREAD ((3)(5))
|
||||
|
||||
In this example, 3 and 5 are siblings of a parent which does not
|
||||
match the search criteria (and/or does not exist in the mailbox);
|
||||
however they are members of the same thread.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin and Murchison [Page 11]
|
||||
|
||||
INTERNET DRAFT IMAP THREAD EXPIRES 22 December 2002
|
||||
|
||||
|
||||
Formal Syntax of THREAD commands and Responses
|
||||
|
||||
thread-data = "THREAD" [SP 1*thread-list]
|
||||
|
||||
thread-list = "(" thread-members / thread-nested ")"
|
||||
|
||||
thread-members = nz-number *(SP nz-number) [SP thread-nested]
|
||||
|
||||
thread-nested = 2*thread-list
|
||||
|
||||
thread = ["UID" SP] "THREAD" SP thread-algorithm
|
||||
SP search-charset 1*(SP search-key)
|
||||
|
||||
thread-algorithm = "ORDEREDSUBJECT" / "REFERENCES" / atom
|
||||
|
||||
|
||||
The following syntax describes base subject extraction rules (2)-(6):
|
||||
|
||||
subject = *subj-leader [subj-middle] *subj-trailer
|
||||
|
||||
subj-refwd = ("re" / ("fw" ["d"])) *WSP [subj-blob] ":"
|
||||
|
||||
subj-blob = "[" *BLOBCHAR "]" *WSP
|
||||
|
||||
subj-fwd = subj-fwd-hdr subject subj-fwd-trl
|
||||
|
||||
subj-fwd-hdr = "[fwd:"
|
||||
|
||||
subj-fwd-trl = "]"
|
||||
|
||||
subj-leader = (*subj-blob subj-refwd) / WSP
|
||||
|
||||
subj-middle = *subj-blob (subj-base / subj-fwd)
|
||||
; last subj-blob is subj-base if subj-base would
|
||||
; otherwise be empty
|
||||
|
||||
subj-trailer = "(fwd)" / WSP
|
||||
|
||||
subj-base = NONWSP *([*WSP] NONWSP)
|
||||
; can be a subj-blob
|
||||
|
||||
BLOBCHAR = %x01-5a / %x5c / %x5e-7f
|
||||
; any CHAR except '[' and ']'
|
||||
|
||||
NONWSP = %x01-08 / %x0a-1f / %x21-7f
|
||||
; any CHAR other than WSP
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin and Murchison [Page 12]
|
||||
|
||||
INTERNET DRAFT IMAP THREAD EXPIRES 22 December 2002
|
||||
|
||||
|
||||
Security Considerations
|
||||
|
||||
Security issues are not discussed in this memo.
|
||||
|
||||
|
||||
Internationalization Considerations
|
||||
|
||||
By default, strings are threaded according to the "minimum sorting
|
||||
collation algorithm". All implementations of THREAD MUST implement
|
||||
the minimum sorting collation algorithm.
|
||||
|
||||
In the minimum sorting collation algorithm, the Basic Latin
|
||||
alphabetics (U+0041 to U+005A uppercase, U+0061 to U+007A lowercase)
|
||||
are sorted in a case-insensitive fashion; that is, "A" (U+0041) and
|
||||
"a" (U+0061) are treated as exact equals. The characters U+005B to
|
||||
U+0060 are sorted after the Basic Latin alphabetics; for example,
|
||||
U+005E is sorted after U+005A and U+007A. All other characters are
|
||||
sorted according to their octet values, as expressed in UTF-8. No
|
||||
attempt is made to treat composed characters specially, or to do
|
||||
case-insensitive comparisons of composed characters.
|
||||
|
||||
Note: this means, among other things, that the composed
|
||||
characters in the Latin-1 Supplement are not compared in
|
||||
what would be considered an ISO 8859-1 "case-insensitive"
|
||||
fashion. Case comparison rules for characters with
|
||||
diacriticals differ between languages; the minimum sorting
|
||||
collation does not attempt to deal with this at all. This
|
||||
is reserved for other sorting collations, which may be
|
||||
language-specific.
|
||||
|
||||
;;; *** ITEM FOR DISCUSSION ***
|
||||
;;; THERE IS SOME CONCERN THAT THIS MINIMUM COLLATION IS TOO MINIMAL,
|
||||
;;; AND THAT THE "GENERIC UNICODE SORTING COLLATION" DISCUSSED BELOW
|
||||
;;; NEEDS TO BE THE MINIMUM. ONE SUGGESTION IS UNICODE TECHNICAL
|
||||
;;; STANDARD 10 (TR-10). IF THIS IS THE MINIMUM, THAT REQUIRES THAT
|
||||
;;; ALL IMPLEMENTATIONS OF SORT AND THREAD BE UNICODE-SAVVY AT LEAST
|
||||
;;; TO THE POINT OF IMPLEMENTATION TR-10. IS THIS REALISTIC? DOES
|
||||
;;; THIS RAISE EXCESSIVE IMPLEMENTATION BARRIERS?
|
||||
Other sorting collations, and the ability to change the sorting
|
||||
collation, will be defined in a separate document dealing with IMAP
|
||||
internationalization.
|
||||
|
||||
It is anticipated that there will be a generic Unicode sorting
|
||||
collation, which will provide generic case-insensitivity for
|
||||
alphabetic scripts, specification of composed character handling, and
|
||||
language-specific sorting collations. A server which implements
|
||||
non-default sorting collations will modify its sorting behavior
|
||||
according to the selected sorting collation.
|
||||
|
||||
|
||||
|
||||
Crispin and Murchison [Page 13]
|
||||
|
||||
INTERNET DRAFT IMAP THREAD EXPIRES 22 December 2002
|
||||
|
||||
|
||||
Non-English translations of "Re" or "Fw"/"Fwd" are not specified for
|
||||
removal in the base subject extraction process. By specifying that
|
||||
only the English forms of the prefixes are used, it becomes a simple
|
||||
display time task to localize the prefix language for the user. If,
|
||||
on the other hand, prefixes in multiple languages are permitted, the
|
||||
result is a geometrically complex, and ultimately unimplementable,
|
||||
task. In order to improve the ability to support non-English display
|
||||
in Internet mail clients, only the English form of these prefixes
|
||||
should be transmitted in Internet mail messages.
|
||||
|
||||
|
||||
A. References
|
||||
|
||||
|
||||
[ABNF] Crocker, D., and Overell, P. "Augmented BNF for Syntax
|
||||
Specifications: ABNF", RFC 2234, November 1997.
|
||||
|
||||
[NEWS] Horton, M., and Adams, R., "Standard for interchange of USENET
|
||||
messages", RFC-1036, AT&T Bell Laboratories and Center for Seismic
|
||||
Studies, December, 1987.
|
||||
|
||||
[RFC-2822] Resnick, P. "Internet Message Format", RFC 2822, April
|
||||
2001.
|
||||
|
||||
Author's Address
|
||||
|
||||
Mark R. Crispin
|
||||
Networks and Distributed Computing
|
||||
University of Washington
|
||||
4545 15th Avenue NE
|
||||
Seattle, WA 98105-4527
|
||||
|
||||
Phone: (206) 543-5762
|
||||
|
||||
EMail: MRC@CAC.Washington.EDU
|
||||
|
||||
|
||||
Kenneth Murchison
|
||||
Oceana Matrix Ltd.
|
||||
21 Princeton Place
|
||||
Orchard Park, NY 14127
|
||||
|
||||
Phone: (716) 662-8973 x26
|
||||
|
||||
EMail: ken@oceana.com
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin and Murchison [Page 14]
|
||||
|
||||
|
|
@ -1,339 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group J. Myers
|
||||
Request for Comments: 1731 Carnegie Mellon
|
||||
Category: Standards Track December 1994
|
||||
|
||||
|
||||
IMAP4 Authentication Mechanisms
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This document specifies an Internet standards track protocol for the
|
||||
Internet community, and requests discussion and suggestions for
|
||||
improvements. Please refer to the current edition of the "Internet
|
||||
Official Protocol Standards" (STD 1) for the standardization state
|
||||
and status of this protocol. Distribution of this memo is unlimited.
|
||||
|
||||
|
||||
1. Introduction
|
||||
|
||||
The Internet Message Access Protocol, Version 4 [IMAP4] contains the
|
||||
AUTHENTICATE command, for identifying and authenticating a user to an
|
||||
IMAP4 server and for optionally negotiating a protection mechanism
|
||||
for subsequent protocol interactions. This document describes
|
||||
several authentication mechanisms for use by the IMAP4 AUTHENTICATE
|
||||
command.
|
||||
|
||||
|
||||
2. Kerberos version 4 authentication mechanism
|
||||
|
||||
The authentication type associated with Kerberos version 4 is
|
||||
"KERBEROS_V4".
|
||||
|
||||
The data encoded in the first ready response contains a random 32-bit
|
||||
number in network byte order. The client should respond with a
|
||||
Kerberos ticket and an authenticator for the principal
|
||||
"imap.hostname@realm", where "hostname" is the first component of the
|
||||
host name of the server with all letters in lower case and where
|
||||
"realm" is the Kerberos realm of the server. The encrypted checksum
|
||||
field included within the Kerberos authenticator should contain the
|
||||
server provided 32-bit number in network byte order.
|
||||
|
||||
Upon decrypting and verifying the ticket and authenticator, the
|
||||
server should verify that the contained checksum field equals the
|
||||
original server provided random 32-bit number. Should the
|
||||
verification be successful, the server must add one to the checksum
|
||||
and construct 8 octets of data, with the first four octets containing
|
||||
the incremented checksum in network byte order, the fifth octet
|
||||
containing a bit-mask specifying the protection mechanisms supported
|
||||
by the server, and the sixth through eighth octets containing, in
|
||||
|
||||
|
||||
|
||||
Myers [Page 1]
|
||||
|
||||
RFC 1731 IMAP4 Authentication Mechanisms December 1994
|
||||
|
||||
|
||||
network byte order, the maximum cipher-text buffer size the server is
|
||||
able to receive. The server must encrypt the 8 octets of data in the
|
||||
session key and issue that encrypted data in a second ready response.
|
||||
The client should consider the server authenticated if the first four
|
||||
octets the un-encrypted data is equal to one plus the checksum it
|
||||
previously sent.
|
||||
|
||||
The client must construct data with the first four octets containing
|
||||
the original server-issued checksum in network byte order, the fifth
|
||||
octet containing the bit-mask specifying the selected protection
|
||||
mechanism, the sixth through eighth octets containing in network byte
|
||||
order the maximum cipher-text buffer size the client is able to
|
||||
receive, and the following octets containing a user name string. The
|
||||
client must then append from one to eight octets so that the length
|
||||
of the data is a multiple of eight octets. The client must then PCBC
|
||||
encrypt the data with the session key and respond to the second ready
|
||||
response with the encrypted data. The server decrypts the data and
|
||||
verifies the contained checksum. The username field identifies the
|
||||
user for whom subsequent IMAP operations are to be performed; the
|
||||
server must verify that the principal identified in the Kerberos
|
||||
ticket is authorized to connect as that user. After these
|
||||
verifications, the authentication process is complete.
|
||||
|
||||
The protection mechanisms and their corresponding bit-masks are as
|
||||
follows:
|
||||
|
||||
1 No protection mechanism
|
||||
2 Integrity (krb_mk_safe) protection
|
||||
4 Privacy (krb_mk_priv) protection
|
||||
|
||||
|
||||
EXAMPLE: The following are two Kerberos version 4 login scenarios
|
||||
(note that the line breaks in the sample authenticators are for
|
||||
editorial clarity and are not in real authenticators)
|
||||
|
||||
S: * OK IMAP4 Server
|
||||
C: A001 AUTHENTICATE KERBEROS_V4
|
||||
S: + AmFYig==
|
||||
C: BAcAQU5EUkVXLkNNVS5FRFUAOCAsho84kLN3/IJmrMG+25a4DT
|
||||
+nZImJjnTNHJUtxAA+o0KPKfHEcAFs9a3CL5Oebe/ydHJUwYFd
|
||||
WwuQ1MWiy6IesKvjL5rL9WjXUb9MwT9bpObYLGOKi1Qh
|
||||
S: + or//EoAADZI=
|
||||
C: DiAF5A4gA+oOIALuBkAAmw==
|
||||
S: A001 OK Kerberos V4 authentication successful
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers [Page 2]
|
||||
|
||||
RFC 1731 IMAP4 Authentication Mechanisms December 1994
|
||||
|
||||
|
||||
S: * OK IMAP4 Server
|
||||
C: A001 AUTHENTICATE KERBEROS_V4
|
||||
S: + gcfgCA==
|
||||
C: BAcAQU5EUkVXLkNNVS5FRFUAOCAsho84kLN3/IJmrMG+25a4DT
|
||||
+nZImJjnTNHJUtxAA+o0KPKfHEcAFs9a3CL5Oebe/ydHJUwYFd
|
||||
WwuQ1MWiy6IesKvjL5rL9WjXUb9MwT9bpObYLGOKi1Qh
|
||||
S: A001 NO Kerberos V4 authentication failed
|
||||
|
||||
|
||||
3. GSSAPI authentication mechanism
|
||||
|
||||
The authentication type associated with all mechanisms employing the
|
||||
GSSAPI [RFC1508] is "GSSAPI".
|
||||
|
||||
The first ready response issued by the server contains no data. The
|
||||
client should call GSS_Init_sec_context, passing in 0 for
|
||||
input_context_handle (initially) and a targ_name equal to output_name
|
||||
from GSS_Import_Name called with input_name_type of NULL and
|
||||
input_name_string of "SERVICE:imap@hostname" where "hostname" is the
|
||||
fully qualified host name of the server with all letters in lower
|
||||
case. The client must then respond with the resulting output_token.
|
||||
If GSS_Init_sec_context returns GSS_CONTINUE_NEEDED, then the client
|
||||
should expect the server to issue a token in a subsequent ready
|
||||
response. The client must pass the token to another call to
|
||||
GSS_Init_sec_context.
|
||||
|
||||
If GSS_Init_sec_context returns GSS_COMPLETE, then the client should
|
||||
respond with any resulting output_token. If there is no
|
||||
output_token, the client should respond with no data. The client
|
||||
should then expect the server to issue a token in a subsequent ready
|
||||
response. The client should pass this token to GSS_Unseal and
|
||||
interpret the first octet of resulting cleartext as a bit-mask
|
||||
specifying the protection mechanisms supported by the server and the
|
||||
second through fourth octets as the maximum size output_message to
|
||||
send to the server. The client should construct data, with the first
|
||||
octet containing the bit-mask specifying the selected protection
|
||||
mechanism, the second through fourth octets containing in network
|
||||
byte order the maximum size output_message the client is able to
|
||||
receive, and the remaining octets containing a user name string. The
|
||||
client must pass the data to GSS_Seal with conf_flag set to FALSE,
|
||||
and respond with the generated output_message. The client can then
|
||||
consider the server authenticated.
|
||||
|
||||
The server must issue a ready response with no data and pass the
|
||||
resulting client supplied token to GSS_Accept_sec_context as
|
||||
input_token, setting acceptor_cred_handle to NULL (for "use default
|
||||
credentials"), and 0 for input_context_handle (initially). If
|
||||
GSS_Accept_sec_context returns GSS_CONTINUE_NEEDED, the server should
|
||||
|
||||
|
||||
|
||||
Myers [Page 3]
|
||||
|
||||
RFC 1731 IMAP4 Authentication Mechanisms December 1994
|
||||
|
||||
|
||||
return the generated output_token to the client in a ready response
|
||||
and pass the resulting client supplied token to another call to
|
||||
GSS_Accept_sec_context.
|
||||
|
||||
If GSS_Accept_sec_context returns GSS_COMPLETE, then if an
|
||||
output_token is returned, the server should return it to the client
|
||||
in a ready response and expect a reply from the client with no data.
|
||||
Whether or not an output_token was returned, the server then should
|
||||
then construct 4 octets of data, with the first octet containing a
|
||||
bit-mask specifying the protection mechanisms supported by the server
|
||||
and the second through fourth octets containing in network byte order
|
||||
the maximum size output_token the server is able to receive. The
|
||||
server must then pass the plaintext to GSS_Seal with conf_flag set to
|
||||
FALSE and issue the generated output_message to the client in a ready
|
||||
response. The server must then pass the resulting client supplied
|
||||
token to GSS_Unseal and interpret the first octet of resulting
|
||||
cleartext as the bit-mask for the selected protection mechanism, the
|
||||
second through fourth octets as the maximum size output_message to
|
||||
send to the client, and the remaining octets as the user name. Upon
|
||||
verifying the src_name is authorized to authenticate as the user
|
||||
name, The server should then consider the client authenticated.
|
||||
|
||||
The protection mechanisms and their corresponding bit-masks are as
|
||||
follows:
|
||||
|
||||
1 No protection mechanism
|
||||
2 Integrity protection.
|
||||
Sender calls GSS_Seal with conf_flag set to FALSE
|
||||
4 Privacy protection.
|
||||
Sender calls GSS_Seal with conf_flag set to TRUE
|
||||
|
||||
|
||||
4. S/Key authentication mechanism
|
||||
|
||||
The authentication type associated with S/Key [SKEY] is "SKEY".
|
||||
|
||||
The first ready response issued by the server contains no data. The
|
||||
client responds with the user name string.
|
||||
|
||||
The data encoded in the second ready response contains the decimal
|
||||
sequence number followed by a single space and the seed string for
|
||||
the indicated user. The client responds with the one-time-password,
|
||||
as either a 64-bit value in network byte order or encoded in the "six
|
||||
English words" format.
|
||||
|
||||
Upon successful verification of the one-time-password, the server
|
||||
should consider the client authenticated.
|
||||
|
||||
|
||||
|
||||
|
||||
Myers [Page 4]
|
||||
|
||||
RFC 1731 IMAP4 Authentication Mechanisms December 1994
|
||||
|
||||
|
||||
S/Key authentication does not provide for any protection mechanisms.
|
||||
|
||||
|
||||
EXAMPLE: The following are two S/Key login scenarios.
|
||||
|
||||
S: * OK IMAP4 Server
|
||||
C: A001 AUTHENTICATE SKEY
|
||||
S: +
|
||||
C: bW9yZ2Fu
|
||||
S: + OTUgUWE1ODMwOA==
|
||||
C: Rk9VUiBNQU5OIFNPT04gRklSIFZBUlkgTUFTSA==
|
||||
S: A001 OK S/Key authentication successful
|
||||
|
||||
|
||||
S: * OK IMAP4 Server
|
||||
C: A001 AUTHENTICATE SKEY
|
||||
S: +
|
||||
C: c21pdGg=
|
||||
S: + OTUgUWE1ODMwOA==
|
||||
C: BsAY3g4gBNo=
|
||||
S: A001 NO S/Key authentication failed
|
||||
|
||||
|
||||
5. References
|
||||
|
||||
[IMAP4] Crispin, M., "Internet Message Access Protocol - Version 4",
|
||||
RFC 1730, University of Washington, December 1994.
|
||||
|
||||
[RFC1508] Linn, J., "Generic Security Service Application Program
|
||||
Interface", RFC 1508, Geer Zolot Associates, September 1993.
|
||||
|
||||
[SKEY] Haller, Neil M. "The S/Key One-Time Password System",
|
||||
Bellcore, Morristown, New Jersey, October 1993,
|
||||
thumper.bellcore.com:pub/nmh/docs/ISOC.symp.ps
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers [Page 5]
|
||||
|
||||
RFC 1731 IMAP4 Authentication Mechanisms December 1994
|
||||
|
||||
|
||||
6. Security Considerations
|
||||
|
||||
Security issues are discussed throughout this memo.
|
||||
|
||||
|
||||
7. Author's Address
|
||||
|
||||
John G. Myers
|
||||
Carnegie-Mellon University
|
||||
5000 Forbes Ave.
|
||||
Pittsburgh PA, 15213-3890
|
||||
|
||||
EMail: jgm+@cmu.edu
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers [Page 6]
|
||||
|
|
@ -1,283 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group M. Crispin
|
||||
Request for Comments: 1732 University of Washington
|
||||
Category: Informational December 1994
|
||||
|
||||
|
||||
IMAP4 COMPATIBILITY WITH IMAP2 AND IMAP2BIS
|
||||
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This memo provides information for the Internet community. This memo
|
||||
does not specify an Internet standard of any kind. Distribution of
|
||||
this memo is unlimited.
|
||||
|
||||
Introduction
|
||||
|
||||
This is a summary of hints and recommendations to enable an IMAP4
|
||||
implementation to interoperate with implementations that conform to
|
||||
earlier specifications. None of these hints and recommendations are
|
||||
required by the IMAP4 specification; implementors must decide for
|
||||
themselves whether they want their implementation to fail if it
|
||||
encounters old software.
|
||||
|
||||
IMAP4 has been designed to be upwards compatible with earlier
|
||||
specifications. For the most part, IMAP4 facilities that were not in
|
||||
earlier specifications should be invisible to clients unless the
|
||||
client asks for the facility.
|
||||
|
||||
In some cases, older servers may support some of the capabilities
|
||||
listed as being "new in IMAP4" as experimental extensions to the
|
||||
IMAP2 protocol described in RFC 1176.
|
||||
|
||||
This information may not be complete; it reflects current knowledge
|
||||
of server and client implementations as well as "folklore" acquired
|
||||
in the evolution of the protocol.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin [Page 1]
|
||||
|
||||
RFC 1732 IMAP4 - Compatibility December 1994
|
||||
|
||||
|
||||
IMAP4 client interoperability with old servers
|
||||
|
||||
In general, a client should be able to discover whether an IMAP2
|
||||
server supports a facility by trial-and-error; if an attempt to use a
|
||||
facility generates a BAD response, the client can assume that the
|
||||
server does not support the facility.
|
||||
|
||||
A quick way to check whether a server implementation supports the
|
||||
IMAP4 specification is to try the CAPABILITY command. An OK response
|
||||
that includes the IMAP4 capability value indicates a server that
|
||||
supports IMAP4; a BAD response or one without the IMAP4 capability
|
||||
value indicates an older server.
|
||||
|
||||
The following is a list of facilities that are only in IMAP4, and
|
||||
suggestions for how new clients might interoperate with old servers:
|
||||
|
||||
CAPABILITY command
|
||||
A BAD response to this command indicates that the server
|
||||
implements IMAP2 (or IMAP2bis) and not IMAP4.
|
||||
|
||||
AUTHENTICATE command.
|
||||
Use the LOGIN command.
|
||||
|
||||
LSUB and LIST commands
|
||||
Try the RFC 1176 FIND command.
|
||||
|
||||
* in a sequence
|
||||
Use the number of messages in the mailbox from the EXISTS
|
||||
unsolicited response.
|
||||
|
||||
SEARCH extensions (character set, additional criteria)
|
||||
Reformulate the search request using only the searching
|
||||
options listed in search_old in the IMAP4 grammar. This may
|
||||
entail doing multiple searches to achieve the desired
|
||||
results.
|
||||
|
||||
BODYSTRUCTURE fetch data item
|
||||
Try to fetch the non-extensible BODY data item.
|
||||
|
||||
body section number 0
|
||||
Fetch the entire message and extract the header.
|
||||
|
||||
RFC822.HEADER.LINES and RFC822.HEADER.LINES.NOT fetch data items
|
||||
Use RFC822.HEADER and remove the unwanted information.
|
||||
|
||||
BODY.PEEK[section], RFC822.PEEK, and RFC822.TEXT.PEEK fetch data
|
||||
items Use the corresponding non-PEEK versions and manually
|
||||
clear the \Seen flag as necessary.
|
||||
|
||||
|
||||
|
||||
Crispin [Page 2]
|
||||
|
||||
RFC 1732 IMAP4 - Compatibility December 1994
|
||||
|
||||
|
||||
UID fetch data item and the UID commands
|
||||
No equivalent capabilitity exists in older servers.
|
||||
|
||||
FLAGS.SILENT, +FLAGS.SILENT, and -FLAGS.SILENT store data items
|
||||
Use the corresponding non-SILENT versions and ignore the
|
||||
untagged FETCH responses which com eback.
|
||||
|
||||
|
||||
The following IMAP4 facilities were introduced in the experimental
|
||||
IMAP2bis revisions to RFC-1176, and may be present in a server that
|
||||
does not support the CAPABILITY command:
|
||||
|
||||
CREATE, DELETE, and RENAME commands
|
||||
To test whether these commands are present, try a CREATE
|
||||
INBOX command. If the response is NO, these commands are
|
||||
supported by the server. If the response is BAD, they are
|
||||
not. Older servers without the CREATE capability may sup-
|
||||
port implicit creation of a mailbox by a COPY command with a
|
||||
non-existant name as the destination.
|
||||
|
||||
APPEND command
|
||||
To test whether this command is present, try to append a
|
||||
zero-length stream to a mailbox name that is known not to
|
||||
exist (or at least, highly unlikely to exist) on the remote
|
||||
system.
|
||||
|
||||
SUBSCRIBE and UNSUBSCRIBE commands
|
||||
Try the form of these commands with the optional MAILBOX
|
||||
keyword.
|
||||
|
||||
EXAMINE command
|
||||
Use the SELECT command instead.
|
||||
|
||||
flags and internal date argument to APPEND command
|
||||
Try the APPEND without any flag list and internal date argu-
|
||||
ments.
|
||||
|
||||
BODY, BODY[section], and FULL fetch data items
|
||||
Use RFC822.TEXT and ALL instead. Server does not support
|
||||
MIME.
|
||||
|
||||
PARTIAL command
|
||||
Use the appropriate FETCH command and ignore the unwanted
|
||||
data.
|
||||
|
||||
|
||||
IMAP4 client implementations must accept all responses and data for-
|
||||
mats documented in the IMAP4 specification, including those labeled
|
||||
|
||||
|
||||
|
||||
Crispin [Page 3]
|
||||
|
||||
RFC 1732 IMAP4 - Compatibility December 1994
|
||||
|
||||
|
||||
as obsolete. This includes the COPY and STORE unsolicited responses
|
||||
and the old format of dates and times. In particular, client imple-
|
||||
mentations must not treat a date/time as a fixed format string; nor
|
||||
may they assume that the time begins at a particular octet.
|
||||
|
||||
IMAP4 client implementations must not depend upon the presence of any
|
||||
server extensions that are not in the base IMAP4 specification.
|
||||
|
||||
The experimental IMAP2bis version specified that the TRYCREATE spe-
|
||||
cial information token is sent as a separate unsolicited OK response
|
||||
instead of inside the NO response.
|
||||
|
||||
The FIND BBOARDS, FIND ALL.BBOARDS, and BBOARD commands of RFC 1176
|
||||
are removed from IMAP4. There is no equivalent to the bboard com-
|
||||
mands, which provided a separate namespace with implicit restrictions
|
||||
on what may be done in that namespace.
|
||||
|
||||
Older server implementations may automatically create the destination
|
||||
mailbox on COPY if that mailbox does not already exist. This was how
|
||||
a new mailbox was created in older specifications. If the server
|
||||
does not support the CREATE command (see above for how to test for
|
||||
this), it will probably create a mailbox on COPY.
|
||||
|
||||
Older server implementations may not preserve flags or internal dates
|
||||
on COPY. Some server implementations may not permit the preservation
|
||||
of certain flags on COPY or their setting with APPEND as site policy.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin [Page 4]
|
||||
|
||||
RFC 1732 IMAP4 - Compatibility December 1994
|
||||
|
||||
|
||||
IMAP4 server interoperability with old clients
|
||||
|
||||
In general, there should be no interoperation problem between a
|
||||
server conforming to the IMAP4 specification and a well-written
|
||||
client that conforms to an earlier specification. Known problems are
|
||||
noted below:
|
||||
|
||||
Poor wording in the description of the CHECK command in earlier
|
||||
specifications implied that a CHECK command is the way to get the
|
||||
current number of messages in the mailbox. This is incorrect. A
|
||||
CHECK command does not necessarily result in an EXISTS response.
|
||||
Clients must remember the most recent EXISTS value sent from the
|
||||
server, and should not generate unnecessary CHECK commands.
|
||||
|
||||
An incompatibility exists with COPY in IMAP4. COPY in IMAP4
|
||||
servers does not automatically create the destination mailbox if
|
||||
that mailbox does not already exist. This may cause problems with
|
||||
old clients that expect automatic mailbox creation in COPY.
|
||||
|
||||
The PREAUTH unsolicited response is new in IMAP4. It is highly
|
||||
unlikely that an old client would ever see this response.
|
||||
|
||||
The format of dates and times has changed due to the impending end
|
||||
of the century. Clients that fail to accept a four-digit year or
|
||||
a signed four-digit timezone value will not work properly with
|
||||
IMAP4.
|
||||
|
||||
An incompatibility exists with the use of "\" in quoted strings.
|
||||
This is best avoided by using literals instead of quoted strings
|
||||
if "\" or <"> is embedded in the string.
|
||||
|
||||
Security Considerations
|
||||
|
||||
Security issues are not discussed in this memo.
|
||||
|
||||
Author's Address:
|
||||
|
||||
Mark R. Crispin
|
||||
Networks and Distributed Computing, JE-30
|
||||
University of Washington
|
||||
Seattle, WA 98195
|
||||
|
||||
Phone: (206) 543-5762
|
||||
|
||||
EMail: MRC@CAC.Washington.EDU
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin [Page 5]
|
||||
|
|
@ -1,171 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group M. Crispin
|
||||
Request for Comments: 1733 University of Washington
|
||||
Category: Informational December 1994
|
||||
|
||||
|
||||
DISTRIBUTED ELECTRONIC MAIL MODELS IN IMAP4
|
||||
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This memo provides information for the Internet community. This memo
|
||||
does not specify an Internet standard of any kind. Distribution of
|
||||
this memo is unlimited.
|
||||
|
||||
|
||||
Distributed Electronic Mail Models
|
||||
|
||||
There are three fundamental models of client/server email: offline,
|
||||
online, and disconnected use. IMAP4 can be used in any one of these
|
||||
three models.
|
||||
|
||||
The offline model is the most familiar form of client/server email
|
||||
today, and is used by protocols such as POP-3 (RFC 1225) and UUCP.
|
||||
In this model, a client application periodically connects to a
|
||||
server. It downloads all the pending messages to the client machine
|
||||
and deletes these from the server. Thereafter, all mail processing
|
||||
is local to the client. This model is store-and-forward; it moves
|
||||
mail on demand from an intermediate server (maildrop) to a single
|
||||
destination machine.
|
||||
|
||||
The online model is most commonly used with remote filesystem
|
||||
protocols such as NFS. In this model, a client application
|
||||
manipulates mailbox data on a server machine. A connection to the
|
||||
server is maintained throughout the session. No mailbox data are
|
||||
kept on the client; the client retrieves data from the server as is
|
||||
needed. IMAP4 introduces a form of the online model that requires
|
||||
considerably less network bandwidth than a remote filesystem
|
||||
protocol, and provides the opportunity for using the server for CPU
|
||||
or I/O intensive functions such as parsing and searching.
|
||||
|
||||
The disconnected use model is a hybrid of the offline and online
|
||||
models, and is used by protocols such as PCMAIL (RFC 1056). In this
|
||||
model, a client user downloads some set of messages from the server,
|
||||
manipulates them offline, then at some later time uploads the
|
||||
changes. The server remains the authoritative repository of the
|
||||
messages. The problems of synchronization (particularly when
|
||||
multiple clients are involved) are handled through the means of
|
||||
unique identifiers for each message.
|
||||
|
||||
|
||||
|
||||
Crispin [Page 1]
|
||||
|
||||
RFC 1733 IMAP4 - Model December 1994
|
||||
|
||||
|
||||
Each of these models have their own strengths and weaknesses:
|
||||
|
||||
Feature Offline Online Disc
|
||||
------- ------- ------ ----
|
||||
Can use multiple clients NO YES YES
|
||||
Minimum use of server connect time YES NO YES
|
||||
Minimum use of server resources YES NO NO
|
||||
Minimum use of client disk resources NO YES NO
|
||||
Multiple remote mailboxes NO YES YES
|
||||
Fast startup NO YES NO
|
||||
Mail processing when not online YES NO YES
|
||||
|
||||
Although IMAP4 has its origins as a protocol designed to accommodate
|
||||
the online model, it can support the other two models as well. This
|
||||
makes possible the creation of clients that can be used in any of the
|
||||
three models. For example, a user may wish to switch between the
|
||||
online and disconnected models on a regular basis (e.g. owing to
|
||||
travel).
|
||||
|
||||
IMAP4 is designed to transmit message data on demand, and to provide
|
||||
the facilities necessary for a client to decide what data it needs at
|
||||
any particular time. There is generally no need to do a wholesale
|
||||
transfer of an entire mailbox or even of the complete text of a
|
||||
message. This makes a difference in situations where the mailbox is
|
||||
large, or when the link to the server is slow.
|
||||
|
||||
More specifically, IMAP4 supports server-based RFC 822 and MIME
|
||||
processing. With this information, it is possible for a client to
|
||||
determine in advance whether it wishes to retrieve a particular
|
||||
message or part of a message. For example, a user connected to an
|
||||
IMAP4 server via a dialup link can determine that a message has a
|
||||
2000 byte text segment and a 40 megabyte video segment, and elect to
|
||||
fetch only the text segment.
|
||||
|
||||
In IMAP4, the client/server relationship lasts only for the duration
|
||||
of the TCP connection. There is no registration of clients. Except
|
||||
for any unique identifiers used in disconnected use operation, the
|
||||
client initially has no knowledge of mailbox state and learns it from
|
||||
the IMAP4 server when a mailbox is selected. This initial transfer
|
||||
is minimal; the client requests additional state data as it needs.
|
||||
|
||||
As noted above, the choice for the location of mailbox data depends
|
||||
upon the model chosen. The location of message state (e.g. whether
|
||||
or not a message has been read or answered) is also determined by the
|
||||
model, and is not necessarily the same as the location of the mailbox
|
||||
data. For example, in the online model message state can be co-
|
||||
located with mailbox data; it can also be located elsewhere (on the
|
||||
client or on a third agent) using unique identifiers to achieve
|
||||
|
||||
|
||||
|
||||
Crispin [Page 2]
|
||||
|
||||
RFC 1733 IMAP4 - Model December 1994
|
||||
|
||||
|
||||
common reference across sessions. The latter is particularly useful
|
||||
with a server that exports public data such as netnews and does not
|
||||
maintain per-user state.
|
||||
|
||||
The IMAP4 protocol provides the generality to implement these
|
||||
different models. This is done by means of server and (especially)
|
||||
client configuration, and not by requiring changes to the protocol or
|
||||
the implementation of the protocol.
|
||||
|
||||
|
||||
Security Considerations
|
||||
|
||||
Security issues are not discussed in this memo.
|
||||
|
||||
|
||||
Author's Address:
|
||||
|
||||
Mark R. Crispin
|
||||
Networks and Distributed Computing, JE-30
|
||||
University of Washington
|
||||
Seattle, WA 98195
|
||||
|
||||
Phone: (206) 543-5762
|
||||
|
||||
EMail: MRC@CAC.Washington.EDU
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin [Page 3]
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,171 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group M. Crispin
|
||||
Request for Comments: 2061 University of Washington
|
||||
Category: Informational December 1996
|
||||
|
||||
|
||||
IMAP4 COMPATIBILITY WITH IMAP2BIS
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This memo provides information for the Internet community. This memo
|
||||
does not specify an Internet standard of any kind. Distribution of
|
||||
this memo is unlimited.
|
||||
|
||||
Introduction
|
||||
|
||||
The Internet Message Access Protocol (IMAP) has been through several
|
||||
revisions and variants in its 10-year history. Many of these are
|
||||
either extinct or extremely rare; in particular, several undocumented
|
||||
variants and the variants described in RFC 1064, RFC 1176, and RFC
|
||||
1203 fall into this category.
|
||||
|
||||
One variant, IMAP2bis, is at the time of this writing very common and
|
||||
has been widely distributed with the Pine mailer. Unfortunately,
|
||||
there is no definite document describing IMAP2bis. This document is
|
||||
intended to be read along with RFC 1176 and the most recent IMAP4
|
||||
specification (RFC 2060) to assist implementors in creating an IMAP4
|
||||
implementation to interoperate with implementations that conform to
|
||||
earlier specifications. Nothing in this document is required by the
|
||||
IMAP4 specification; implementors must decide for themselves whether
|
||||
they want their implementation to fail if it encounters old software.
|
||||
|
||||
At the time of this writing, IMAP4 has been updated from the version
|
||||
described in RFC 1730. An implementor who wishes to interoperate
|
||||
with both RFC 1730 and RFC 2060 should refer to both documents.
|
||||
|
||||
This information is not complete; it reflects current knowledge of
|
||||
server and client implementations as well as "folklore" acquired in
|
||||
the evolution of the protocol. It is NOT a description of how to
|
||||
interoperate with all variants of IMAP, but rather with the old
|
||||
variant that is most likely to be encountered. For detailed
|
||||
information on interoperating with other old variants, refer to RFC
|
||||
1732.
|
||||
|
||||
IMAP4 client interoperability with IMAP2bis servers
|
||||
|
||||
A quick way to check whether a server implementation supports the
|
||||
IMAP4 specification is to try the CAPABILITY command. An OK response
|
||||
will indicate which variant(s) of IMAP4 are supported by the server.
|
||||
|
||||
|
||||
|
||||
Crispin Informational [Page 1]
|
||||
|
||||
RFC 2061 IMAP4 Compatibility December 1996
|
||||
|
||||
|
||||
If the client does not find any of its known variant in the response,
|
||||
it should treat the server as IMAP2bis. A BAD response indicates an
|
||||
IMAP2bis or older server.
|
||||
|
||||
Most IMAP4 facilities are in IMAP2bis. The following exceptions
|
||||
exist:
|
||||
|
||||
CAPABILITY command
|
||||
The absense of this command indicates IMAP2bis (or older).
|
||||
|
||||
AUTHENTICATE command.
|
||||
Use the LOGIN command.
|
||||
|
||||
LSUB, SUBSCRIBE, and UNSUBSCRIBE commands
|
||||
No direct functional equivalent. IMAP2bis had a concept
|
||||
called "bboards" which is not in IMAP4. RFC 1176 supported
|
||||
these with the BBOARD and FIND BBOARDS commands. IMAP2bis
|
||||
augmented these with the FIND ALL.BBOARDS, SUBSCRIBE BBOARD,
|
||||
and UNSUBSCRIBE BBOARD commands. It is recommended that
|
||||
none of these commands be implemented in new software,
|
||||
including servers that support old clients.
|
||||
|
||||
LIST command
|
||||
Use the command FIND ALL.MAILBOXES, which has a similar syn-
|
||||
tax and response to the FIND MAILBOXES command described in
|
||||
RFC 1176. The FIND MAILBOXES command is unlikely to produce
|
||||
useful information.
|
||||
|
||||
* in a sequence
|
||||
Use the number of messages in the mailbox from the EXISTS
|
||||
unsolicited response.
|
||||
|
||||
SEARCH extensions (character set, additional criteria)
|
||||
Reformulate the search request using only the RFC 1176 syn-
|
||||
tax. This may entail doing multiple searches to achieve the
|
||||
desired results.
|
||||
|
||||
BODYSTRUCTURE fetch data item
|
||||
Use the non-extensible BODY data item.
|
||||
|
||||
body sections HEADER, TEXT, MIME, HEADER.FIELDS, HEADER.FIELDS.NOT
|
||||
Use body section numbers only.
|
||||
|
||||
BODY.PEEK[section]
|
||||
Use BODY[section] and manually clear the \Seen flag as
|
||||
necessary.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin Informational [Page 2]
|
||||
|
||||
RFC 2061 IMAP4 Compatibility December 1996
|
||||
|
||||
|
||||
FLAGS.SILENT, +FLAGS.SILENT, and -FLAGS.SILENT store data items
|
||||
Use the corresponding non-SILENT versions and ignore the
|
||||
untagged FETCH responses which come back.
|
||||
|
||||
UID fetch data item and the UID commands
|
||||
No functional equivalent.
|
||||
|
||||
CLOSE command
|
||||
No functional equivalent.
|
||||
|
||||
|
||||
In IMAP2bis, the TRYCREATE special information token is sent as a
|
||||
separate unsolicited OK response instead of inside the NO response.
|
||||
|
||||
IMAP2bis is ambiguous about whether or not flags or internal dates
|
||||
are preserved on COPY. It is impossible to know what behavior is
|
||||
supported by the server.
|
||||
|
||||
IMAP4 server interoperability with IMAP2bis clients
|
||||
|
||||
The only interoperability problem between an IMAP4 server and a
|
||||
well-written IMAP2bis client is an incompatibility with the use of
|
||||
"\" in quoted strings. This is best avoided by using literals
|
||||
instead of quoted strings if "\" or <"> is embedded in the string.
|
||||
|
||||
Security Considerations
|
||||
|
||||
Security issues are not discussed in this memo.
|
||||
|
||||
Author's Address
|
||||
|
||||
Mark R. Crispin
|
||||
Networks and Distributed Computing
|
||||
University of Washington
|
||||
4545 15th Aveneue NE
|
||||
Seattle, WA 98105-4527
|
||||
|
||||
Phone: (206) 543-5762
|
||||
EMail: MRC@CAC.Washington.EDU
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin Informational [Page 3]
|
||||
|
|
@ -1,451 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group M. Crispin
|
||||
Request for Comments: 2062 University of Washington
|
||||
Category: Informational December 1996
|
||||
|
||||
|
||||
Internet Message Access Protocol - Obsolete Syntax
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This memo provides information for the Internet community. This memo
|
||||
does not specify an Internet standard of any kind. Distribution of
|
||||
this memo is unlimited.
|
||||
|
||||
Abstract
|
||||
|
||||
This document describes obsolete syntax which may be encountered by
|
||||
IMAP4 implementations which deal with older versions of the Internet
|
||||
Mail Access Protocol. IMAP4 implementations MAY implement this
|
||||
syntax in order to maximize interoperability with older
|
||||
implementations.
|
||||
|
||||
This document repeats information from earlier documents, most
|
||||
notably RFC 1176 and RFC 1730.
|
||||
|
||||
Obsolete Commands and Fetch Data Items
|
||||
|
||||
The following commands are OBSOLETE. It is NOT required to support
|
||||
any of these commands or fetch data items in new server
|
||||
implementations. These commands are documented here for the benefit
|
||||
of implementors who may wish to support them for compatibility with
|
||||
old client implementations.
|
||||
|
||||
The section headings of these commands are intended to correspond
|
||||
with where they would be located in the main document if they were
|
||||
not obsoleted.
|
||||
|
||||
6.3.OBS.1. FIND ALL.MAILBOXES Command
|
||||
|
||||
Arguments: mailbox name with possible wildcards
|
||||
|
||||
Data: untagged responses: MAILBOX
|
||||
|
||||
Result: OK - find completed
|
||||
NO - find failure: can't list that name
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin Informational [Page 1]
|
||||
|
||||
RFC 2062 IMAP4 Obsolete December 1996
|
||||
|
||||
|
||||
The FIND ALL.MAILBOXES command returns a subset of names from the
|
||||
complete set of all names available to the user. It returns zero
|
||||
or more untagged MAILBOX replies. The mailbox argument to FIND
|
||||
ALL.MAILBOXES is similar to that for LIST with an empty reference,
|
||||
except that the characters "%" and "?" match a single character.
|
||||
|
||||
Example: C: A002 FIND ALL.MAILBOXES *
|
||||
S: * MAILBOX blurdybloop
|
||||
S: * MAILBOX INBOX
|
||||
S: A002 OK FIND ALL.MAILBOXES completed
|
||||
|
||||
6.3.OBS.2. FIND MAILBOXES Command
|
||||
|
||||
Arguments: mailbox name with possible wildcards
|
||||
|
||||
Data: untagged responses: MAILBOX
|
||||
|
||||
Result: OK - find completed
|
||||
NO - find failure: can't list that name
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
The FIND MAILBOXES command returns a subset of names from the set
|
||||
of names that the user has declared as being "active" or
|
||||
"subscribed". It returns zero or more untagged MAILBOX replies.
|
||||
The mailbox argument to FIND MAILBOXES is similar to that for LSUB
|
||||
with an empty reference, except that the characters "%" and "?"
|
||||
match a single character.
|
||||
|
||||
Example: C: A002 FIND MAILBOXES *
|
||||
S: * MAILBOX blurdybloop
|
||||
S: * MAILBOX INBOX
|
||||
S: A002 OK FIND MAILBOXES completed
|
||||
|
||||
6.3.OBS.3. SUBSCRIBE MAILBOX Command
|
||||
|
||||
Arguments: mailbox name
|
||||
|
||||
Data: no specific data for this command
|
||||
|
||||
Result: OK - subscribe completed
|
||||
NO - subscribe failure: can't subscribe to that name
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
The SUBSCRIBE MAILBOX command is identical in effect to the
|
||||
SUBSCRIBE command. A server which implements this command must be
|
||||
able to distinguish between a SUBSCRIBE MAILBOX command and a
|
||||
SUBSCRIBE command with a mailbox name argument of "MAILBOX".
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin Informational [Page 2]
|
||||
|
||||
RFC 2062 IMAP4 Obsolete December 1996
|
||||
|
||||
|
||||
Example: C: A002 SUBSCRIBE MAILBOX #news.comp.mail.mime
|
||||
S: A002 OK SUBSCRIBE MAILBOX to #news.comp.mail.mime
|
||||
completed
|
||||
C: A003 SUBSCRIBE MAILBOX
|
||||
S: A003 OK SUBSCRIBE to MAILBOX completed
|
||||
|
||||
|
||||
6.3.OBS.4. UNSUBSCRIBE MAILBOX Command
|
||||
|
||||
Arguments: mailbox name
|
||||
|
||||
Data: no specific data for this command
|
||||
|
||||
Result: OK - unsubscribe completed
|
||||
NO - unsubscribe failure: can't unsubscribe that name
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
The UNSUBSCRIBE MAILBOX command is identical in effect to the
|
||||
UNSUBSCRIBE command. A server which implements this command must
|
||||
be able to distinguish between a UNSUBSCRIBE MAILBOX command and
|
||||
an UNSUBSCRIBE command with a mailbox name argument of "MAILBOX".
|
||||
|
||||
Example: C: A002 UNSUBSCRIBE MAILBOX #news.comp.mail.mime
|
||||
S: A002 OK UNSUBSCRIBE MAILBOX from #news.comp.mail.mime
|
||||
completed
|
||||
C: A003 UNSUBSCRIBE MAILBOX
|
||||
S: A003 OK UNSUBSCRIBE from MAILBOX completed
|
||||
|
||||
6.4.OBS.1 PARTIAL Command
|
||||
|
||||
Arguments: message sequence number
|
||||
message data item name
|
||||
position of first octet
|
||||
number of octets
|
||||
|
||||
Data: untagged responses: FETCH
|
||||
|
||||
Result: OK - partial completed
|
||||
NO - partial error: can't fetch that data
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
The PARTIAL command is equivalent to the associated FETCH command,
|
||||
with the added functionality that only the specified number of
|
||||
octets, beginning at the specified starting octet, are returned.
|
||||
Only a single message can be fetched at a time. The first octet
|
||||
of a message, and hence the minimum for the starting octet, is
|
||||
octet 1.
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin Informational [Page 3]
|
||||
|
||||
RFC 2062 IMAP4 Obsolete December 1996
|
||||
|
||||
|
||||
The following FETCH items are valid data for PARTIAL: RFC822,
|
||||
RFC822.HEADER, RFC822.TEXT, BODY[<section>], as well as any .PEEK
|
||||
forms of these.
|
||||
|
||||
Any partial fetch that attempts to read beyond the end of the text
|
||||
is truncated as appropriate. If the starting octet is beyond the
|
||||
end of the text, an empty string is returned.
|
||||
|
||||
The data are returned with the FETCH response. There is no
|
||||
indication of the range of the partial data in this response. It
|
||||
is not possible to stream multiple PARTIAL commands of the same
|
||||
data item without processing and synchronizing at each step, since
|
||||
streamed commands may be executed out of order.
|
||||
|
||||
There is no requirement that partial fetches follow any sequence.
|
||||
For example, if a partial fetch of octets 1 through 10000 breaks
|
||||
in an awkward place for BASE64 decoding, it is permitted to
|
||||
continue with a partial fetch of 9987 through 19987, etc.
|
||||
|
||||
The handling of the \Seen flag is the same as in the associated
|
||||
FETCH command.
|
||||
|
||||
Example: C: A005 PARTIAL 4 RFC822 1 1024
|
||||
S: * 1 FETCH (RFC822 {1024}
|
||||
S: Return-Path: <gray@cac.washington.edu>
|
||||
S: ...
|
||||
S: ......... FLAGS (\Seen))
|
||||
S: A005 OK PARTIAL completed
|
||||
|
||||
6.4.5.OBS.1 Obsolete FETCH Data Items
|
||||
|
||||
The following FETCH data items are obsolete:
|
||||
|
||||
BODY[<...>0] A body part number of 0 is the [RFC-822] header of
|
||||
the message. BODY[0] is functionally equivalent to
|
||||
BODY[HEADER], differing in the syntax of the
|
||||
resulting untagged FETCH data (BODY[0] is
|
||||
returned).
|
||||
|
||||
RFC822.HEADER.LINES <header_list>
|
||||
Functionally equivalent to BODY.PEEK[HEADER.LINES
|
||||
<header_list>], differing in the syntax of the
|
||||
resulting untagged FETCH data (RFC822.HEADER is
|
||||
returned).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin Informational [Page 4]
|
||||
|
||||
RFC 2062 IMAP4 Obsolete December 1996
|
||||
|
||||
|
||||
RFC822.HEADER.LINES.NOT <header_list>
|
||||
Functionally equivalent to
|
||||
BODY.PEEK[HEADER.LINES.NOT <header_list>],
|
||||
differing in the syntax of the resulting untagged
|
||||
FETCH data (RFC822.HEADER is returned).
|
||||
|
||||
RFC822.PEEK Functionally equivalent to BODY.PEEK[], except for
|
||||
the syntax of the resulting untagged FETCH data
|
||||
(RFC822 is returned).
|
||||
|
||||
RFC822.TEXT.PEEK
|
||||
Functionally equivalent to BODY.PEEK[TEXT], except
|
||||
for the syntax of the resulting untagged FETCH data
|
||||
(RFC822.TEXT is returned).
|
||||
|
||||
Obsolete Responses
|
||||
|
||||
The following responses are OBSOLETE. Except as noted below, these
|
||||
responses MUST NOT be transmitted by new server implementations.
|
||||
Client implementations SHOULD accept these responses.
|
||||
|
||||
The section headings of these responses are intended to correspond
|
||||
with where they would be located in the main document if they were
|
||||
not obsoleted.
|
||||
|
||||
7.2.OBS.1. MAILBOX Response
|
||||
|
||||
Data: name
|
||||
|
||||
The MAILBOX response MUST NOT be transmitted by server
|
||||
implementations except in response to the obsolete FIND MAILBOXES
|
||||
and FIND ALL.MAILBOXES commands. Client implementations that do
|
||||
not use these commands MAY ignore this response. It is documented
|
||||
here for the benefit of implementors who may wish to support it
|
||||
for compatibility with old client implementations.
|
||||
|
||||
This response occurs as a result of the FIND MAILBOXES and FIND
|
||||
ALL.MAILBOXES commands. It returns a single name that matches the
|
||||
FIND specification. There are no attributes or hierarchy
|
||||
delimiter.
|
||||
|
||||
Example: S: * MAILBOX blurdybloop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin Informational [Page 5]
|
||||
|
||||
RFC 2062 IMAP4 Obsolete December 1996
|
||||
|
||||
|
||||
7.3.OBS.1. COPY Response
|
||||
|
||||
Data: none
|
||||
|
||||
The COPY response MUST NOT be transmitted by new server
|
||||
implementations. Client implementations MUST ignore the COPY
|
||||
response. It is documented here for the benefit of client
|
||||
implementors who may encounter this response from old server
|
||||
implementations.
|
||||
|
||||
In some experimental versions of this protocol, this response was
|
||||
returned in response to a COPY command to indicate on a
|
||||
per-message basis that the message was copied successfully.
|
||||
|
||||
Example: S: * 44 COPY
|
||||
|
||||
7.3.OBS.2. STORE Response
|
||||
|
||||
Data: message data
|
||||
|
||||
The STORE response MUST NOT be transmitted by new server
|
||||
implementations. Client implementations MUST treat the STORE
|
||||
response as equivalent to the FETCH response. It is documented
|
||||
here for the benefit of client implementors who may encounter this
|
||||
response from old server implementations.
|
||||
|
||||
In some experimental versions of this protocol, this response was
|
||||
returned instead of FETCH in response to a STORE command to report
|
||||
the new value of the flags.
|
||||
|
||||
Example: S: * 69 STORE (FLAGS (\Deleted))
|
||||
|
||||
Formal Syntax of Obsolete Commands and Responses
|
||||
|
||||
Each obsolete syntax rule that is suffixed with "_old" is added to
|
||||
the corresponding name in the formal syntax. For example,
|
||||
command_auth_old adds the FIND command to command_auth.
|
||||
|
||||
command_auth_old ::= find
|
||||
|
||||
command_select_old
|
||||
::= partial
|
||||
|
||||
date_year_old ::= 2digit
|
||||
;; (year - 1900)
|
||||
|
||||
date_time_old ::= <"> date_day_fixed "-" date_month "-" date_year
|
||||
SPACE time "-" zone_name <">
|
||||
|
||||
|
||||
|
||||
Crispin Informational [Page 6]
|
||||
|
||||
RFC 2062 IMAP4 Obsolete December 1996
|
||||
|
||||
|
||||
find ::= "FIND" SPACE ["ALL."] "MAILBOXES" SPACE
|
||||
list_mailbox
|
||||
|
||||
fetch_att_old ::= "RFC822.HEADER.LINES" [".NOT"] SPACE header_list /
|
||||
fetch_text_old
|
||||
|
||||
fetch_text_old ::= "BODY" [".PEEK"] section_old /
|
||||
"RFC822" [".HEADER" / ".TEXT" [".PEEK"]]
|
||||
|
||||
msg_data_old ::= "COPY" / ("STORE" SPACE msg_att)
|
||||
|
||||
partial ::= "PARTIAL" SPACE nz_number SPACE fetch_text_old SPACE
|
||||
number SPACE number
|
||||
|
||||
section_old ::= "[" (number ["." number]) "]"
|
||||
|
||||
subscribe_old ::= "SUBSCRIBE" SPACE "MAILBOX" SPACE mailbox
|
||||
|
||||
unsubscribe_old ::= "UNSUBSCRIBE" SPACE "MAILBOX" SPACE mailbox
|
||||
|
||||
zone_name ::= "UT" / "GMT" / "Z" / ;; +0000
|
||||
"AST" / "EDT" / ;; -0400
|
||||
"EST" / "CDT" / ;; -0500
|
||||
"CST" / "MDT" / ;; -0600
|
||||
"MST" / "PDT" / ;; -0700
|
||||
"PST" / "YDT" / ;; -0800
|
||||
"YST" / "HDT" / ;; -0900
|
||||
"HST" / "BDT" / ;; -1000
|
||||
"BST" / ;; -1100
|
||||
"A" / "B" / "C" / "D" / "E" / "F" / ;; +1 to +6
|
||||
"G" / "H" / "I" / "K" / "L" / "M" / ;; +7 to +12
|
||||
"N" / "O" / "P" / "Q" / "R" / "S" / ;; -1 to -6
|
||||
"T" / "U" / "V" / "W" / "X" / "Y" ;; -7 to -12
|
||||
|
||||
Security Considerations
|
||||
|
||||
Security issues are not discussed in this memo.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin Informational [Page 7]
|
||||
|
||||
RFC 2062 IMAP4 Obsolete December 1996
|
||||
|
||||
|
||||
Author's Address
|
||||
|
||||
Mark R. Crispin
|
||||
Networks and Distributed Computing
|
||||
University of Washington
|
||||
4545 15th Aveneue NE
|
||||
Seattle, WA 98105-4527
|
||||
|
||||
Phone: (206) 543-5762
|
||||
EMail: MRC@CAC.Washington.EDU
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crispin Informational [Page 8]
|
||||
|
|
@ -1,451 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group J. Myers
|
||||
Request for Comments: 2086 Carnegie Mellon
|
||||
Category: Standards Track January 1997
|
||||
|
||||
|
||||
IMAP4 ACL extension
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This document specifies an Internet standards track protocol for the
|
||||
Internet community, and requests discussion and suggestions for
|
||||
improvements. Please refer to the current edition of the "Internet
|
||||
Official Protocol Standards" (STD 1) for the standardization state
|
||||
and status of this protocol. Distribution of this memo is unlimited.
|
||||
|
||||
1. Abstract
|
||||
|
||||
The ACL extension of the Internet Message Access Protocol [IMAP4]
|
||||
permits access control lists to be manipulated through the IMAP
|
||||
protocol.
|
||||
|
||||
Table of Contents
|
||||
|
||||
1. Abstract............................................... 1
|
||||
2. Conventions Used in this Document...................... 1
|
||||
3. Introduction and Overview.............................. 2
|
||||
4. Commands............................................... 3
|
||||
4.1. SETACL................................................. 3
|
||||
4.2. DELETEACL.............................................. 4
|
||||
4.3. GETACL................................................. 4
|
||||
4.4. LISTRIGHTS............................................. 4
|
||||
4.5. MYRIGHTS............................................... 5
|
||||
5. Responses.............................................. 5
|
||||
5.1. ACL.................................................... 5
|
||||
5.2. LISTRIGHTS............................................. 6
|
||||
5.3. MYRIGHTS............................................... 6
|
||||
6. Formal Syntax.......................................... 6
|
||||
7. References............................................. 7
|
||||
8. Security Considerations................................ 7
|
||||
9. Author's Address....................................... 8
|
||||
|
||||
2. Conventions Used in this Document
|
||||
|
||||
In examples, "C:" and "S:" indicate lines sent by the client and
|
||||
server respectively.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 1]
|
||||
|
||||
RFC 2086 ACL extension January 1997
|
||||
|
||||
|
||||
3. Introduction and Overview
|
||||
|
||||
The ACL extension is present in any IMAP4 implementation which
|
||||
returns "ACL" as one of the supported capabilities to the CAPABILITY
|
||||
command.
|
||||
|
||||
An access control list is a set of <identifier,rights> pairs.
|
||||
|
||||
Identifier is a US-ASCII string. The identifier anyone is reserved
|
||||
to refer to the universal identity (all authentications, including
|
||||
anonymous). All user name strings accepted by the LOGIN or
|
||||
AUTHENTICATE commands to authenticate to the IMAP server are reserved
|
||||
as identifiers for the corresponding user. Identifiers starting with
|
||||
a dash ("-") are reserved for "negative rights", described below.
|
||||
All other identifier strings are interpreted in an implementation-
|
||||
defined manner.
|
||||
|
||||
Rights is a string listing a (possibly empty) set of alphanumeric
|
||||
characters, each character listing a set of operations which is being
|
||||
controlled. Letters are reserved for ``standard'' rights, listed
|
||||
below. The set of standard rights may only be extended by a
|
||||
standards-track document. Digits are reserved for implementation or
|
||||
site defined rights. The currently defined standard rights are:
|
||||
|
||||
l - lookup (mailbox is visible to LIST/LSUB commands)
|
||||
r - read (SELECT the mailbox, perform CHECK, FETCH, PARTIAL,
|
||||
SEARCH, COPY from mailbox)
|
||||
s - keep seen/unseen information across sessions (STORE SEEN flag)
|
||||
w - write (STORE flags other than SEEN and DELETED)
|
||||
i - insert (perform APPEND, COPY into mailbox)
|
||||
p - post (send mail to submission address for mailbox,
|
||||
not enforced by IMAP4 itself)
|
||||
c - create (CREATE new sub-mailboxes in any implementation-defined
|
||||
hierarchy)
|
||||
d - delete (STORE DELETED flag, perform EXPUNGE)
|
||||
a - administer (perform SETACL)
|
||||
|
||||
An implementation may tie rights together or may force rights to
|
||||
always or never be granted to particular identifiers. For example,
|
||||
in an implementation that uses unix mode bits, the rights "wisd" are
|
||||
tied, the "a" right is always granted to the owner of a mailbox and
|
||||
is never granted to another user. If rights are tied in an
|
||||
implementation, the implementation must be conservative in granting
|
||||
rights in response to SETACL commands--unless all rights in a tied
|
||||
set are specified, none of that set should be included in the ACL
|
||||
entry for that identifier. A client may discover the set of rights
|
||||
which may be granted to a given identifier in the ACL for a given
|
||||
mailbox by using the LISTRIGHTS command.
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 2]
|
||||
|
||||
RFC 2086 ACL extension January 1997
|
||||
|
||||
|
||||
It is possible for multiple identifiers in an access control list to
|
||||
apply to a given user (or other authentication identity). For
|
||||
example, an ACL may include rights to be granted to the identifier
|
||||
matching the user, one or more implementation-defined identifiers
|
||||
matching groups which include the user, and/or the identifier
|
||||
"anyone". How these rights are combined to determine the user's
|
||||
access is implementation-defined. An implementation may choose, for
|
||||
example, to use the union of the rights granted to the applicable
|
||||
identifiers. An implementation may instead choose, for example, to
|
||||
only use those rights granted to the most specific identifier present
|
||||
in the ACL. A client may determine the set of rights granted to the
|
||||
logged-in user for a given mailbox by using the MYRIGHTS command.
|
||||
|
||||
When an identifier in an ACL starts with a dash ("-"), that indicates
|
||||
that associated rights are to be removed from the identifier that is
|
||||
prefixed by the dash. For example, if the identifier "-fred" is
|
||||
granted the "w" right, that indicates that the "w" right is to be
|
||||
removed from users matching the identifier "fred". Implementations
|
||||
need not support having identifiers which start with a dash in ACLs.
|
||||
|
||||
4. Commands
|
||||
|
||||
4.1. SETACL
|
||||
|
||||
Arguments: mailbox name
|
||||
authentication identifier
|
||||
access right modification
|
||||
|
||||
Data: no specific data for this command
|
||||
|
||||
Result: OK - setacl completed
|
||||
NO - setacl failure: can't set acl
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
The SETACL command changes the access control list on the
|
||||
specified mailbox so that the specified identifier is granted
|
||||
permissions as specified in the third argument.
|
||||
|
||||
The third argument is a string containing an optional plus ("+")
|
||||
or minus ("-") prefix, followed by zero or more rights characters.
|
||||
If the string starts with a plus, the following rights are added
|
||||
to any existing rights for the identifier. If the string starts
|
||||
with a minus, the following rights are removed from any existing
|
||||
rights for the identifier. If the string does not start with a
|
||||
plus or minus, the rights replace any existing rights for the
|
||||
identifier.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 3]
|
||||
|
||||
RFC 2086 ACL extension January 1997
|
||||
|
||||
|
||||
4.2. DELETEACL
|
||||
|
||||
Arguments: mailbox name
|
||||
authentication identifier
|
||||
|
||||
Data: no specific data for this command
|
||||
|
||||
Result: OK - deleteacl completed
|
||||
NO - deleteacl failure: can't delete acl
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
The DELETEACL command removes any <identifier,rights> pair for the
|
||||
specified identifier from the access control list for the specified
|
||||
mailbox.
|
||||
|
||||
4.3. GETACL
|
||||
|
||||
Arguments: mailbox name
|
||||
|
||||
Data: untagged responses: ACL
|
||||
|
||||
Result: OK - getacl completed
|
||||
NO - getacl failure: can't get acl
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
The GETACL command returns the access control list for mailbox in
|
||||
an untagged ACL reply.
|
||||
|
||||
Example: C: A002 GETACL INBOX
|
||||
S: * ACL INBOX Fred rwipslda
|
||||
S: A002 OK Getacl complete
|
||||
|
||||
4.4. LISTRIGHTS
|
||||
|
||||
Arguments: mailbox name
|
||||
authentication identifier
|
||||
|
||||
Data: untagged responses: LISTRIGHTS
|
||||
|
||||
Result: OK - listrights completed
|
||||
NO - listrights failure: can't get rights list
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
The LISTRIGHTS command takes a mailbox name and an identifier and
|
||||
returns information about what rights may be granted to the identifier
|
||||
in the ACL for the mailbox.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 4]
|
||||
|
||||
RFC 2086 ACL extension January 1997
|
||||
|
||||
|
||||
Example: C: a001 LISTRIGHTS ~/Mail/saved smith
|
||||
S: * LISTRIGHTS ~/Mail/saved smith la r swicd
|
||||
S: a001 OK Listrights completed
|
||||
|
||||
|
||||
C: a005 LISTRIGHTS archive.imap anyone
|
||||
S: * LISTRIGHTS archive.imap anyone "" l r s w i p c d a
|
||||
0 1 2 3 4 5 6 7 8 9
|
||||
|
||||
4.5. MYRIGHTS
|
||||
|
||||
Arguments: mailbox name
|
||||
|
||||
Data: untagged responses: MYRIGHTS
|
||||
|
||||
Result: OK - myrights completed
|
||||
NO - myrights failure: can't get rights
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
The MYRIGHTS command returns the set of rights that the user has
|
||||
to mailbox in an untagged MYRIGHTS reply.
|
||||
|
||||
Example: C: A003 MYRIGHTS INBOX
|
||||
S: * MYRIGHTS INBOX rwipslda
|
||||
S: A003 OK Myrights complete
|
||||
|
||||
5. Responses
|
||||
|
||||
5.1. ACL
|
||||
|
||||
Data: mailbox name
|
||||
zero or more identifier rights pairs
|
||||
|
||||
The ACL response occurs as a result of a GETACL command. The first
|
||||
string is the mailbox name for which this ACL applies. This is
|
||||
followed by zero or more pairs of strings, each pair contains the
|
||||
identifier for which the entry applies followed by the set of
|
||||
rights that the identifier has.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 5]
|
||||
|
||||
RFC 2086 ACL extension January 1997
|
||||
|
||||
|
||||
5.2. LISTRIGHTS
|
||||
|
||||
Data: mailbox name
|
||||
identifier
|
||||
required rights
|
||||
list of optional rights
|
||||
|
||||
The LISTRIGHTS response occurs as a result of a LISTRIGHTS
|
||||
command. The first two strings are the mailbox name and identifier
|
||||
for which this rights list applies. Following the identifier is a
|
||||
string containing the (possibly empty) set of rights the
|
||||
identifier will always be granted in the mailbox.
|
||||
|
||||
Following this are zero or more strings each containing a set of
|
||||
rights the identifier may be granted in the mailbox. Rights
|
||||
mentioned in the same string are tied together--either all must be
|
||||
granted to the identifier in the mailbox or none may be granted.
|
||||
|
||||
The same right may not be listed more than once in the LISTRIGHTS
|
||||
command.
|
||||
|
||||
5.3. MYRIGHTS
|
||||
|
||||
Data: mailbox name
|
||||
rights
|
||||
|
||||
The MYRIGHTS response occurs as a result of a MYRIGHTS command.
|
||||
The first string is the mailbox name for which these rights apply.
|
||||
The second string is the set of rights that the client has.
|
||||
|
||||
6. Formal Syntax
|
||||
|
||||
The following syntax specification uses the augmented Backus-Naur
|
||||
Form (BNF) notation as specified in [RFC-822] as modified by [IMAP4].
|
||||
Non-terminals referenced but not defined below are as defined by
|
||||
[IMAP4].
|
||||
|
||||
Except as noted otherwise, all alphabetic characters are case-
|
||||
insensitive. The use of upper or lower case characters to define
|
||||
token strings is for editorial clarity only. Implementations MUST
|
||||
accept these strings in a case-insensitive fashion.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 6]
|
||||
|
||||
RFC 2086 ACL extension January 1997
|
||||
|
||||
|
||||
acl_data ::= "ACL" SPACE mailbox *(SPACE identifier SPACE
|
||||
rights)
|
||||
|
||||
deleteacl ::= "DELETEACL" SPACE mailbox SPACE identifier
|
||||
|
||||
getacl ::= "GETACL" SPACE mailbox
|
||||
|
||||
identifier ::= astring
|
||||
|
||||
listrights ::= "LISTRIGHTS" SPACE mailbox SPACE identifier
|
||||
|
||||
listrights_data ::= "LISTRIGHTS" SPACE mailbox SPACE identifier
|
||||
SPACE rights *(SPACE rights)
|
||||
|
||||
mod_rights ::= astring
|
||||
;; +rights to add, -rights to remove
|
||||
;; rights to replace
|
||||
|
||||
myrights ::= "MYRIGHTS" SPACE mailbox
|
||||
|
||||
myrights_data ::= "MYRIGHTS" SPACE mailbox SPACE rights
|
||||
|
||||
rights ::= astring
|
||||
|
||||
setacl ::= "SETACL" SPACE mailbox SPACE identifier
|
||||
SPACE mod_rights
|
||||
|
||||
7. References
|
||||
|
||||
[IMAP4] Crispin, M., "Internet Message Access Protocol - Version 4",
|
||||
RFC 1730, University of Washington, December 1994.
|
||||
|
||||
[RFC-822] Crocker, D., "Standard for the Format of ARPA Internet Text
|
||||
Messages", STD 11, RFC 822.
|
||||
|
||||
8. Security Considerations
|
||||
|
||||
An implementation must make sure the ACL commands themselves do not
|
||||
give information about mailboxes with appropriately restricted ACL's.
|
||||
For example, a GETACL command on a mailbox for which the user has
|
||||
insufficient rights should not admit the mailbox exists, much less
|
||||
return the mailbox's ACL.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 7]
|
||||
|
||||
RFC 2086 ACL extension January 1997
|
||||
|
||||
|
||||
9. Author's Address
|
||||
|
||||
John G. Myers
|
||||
Carnegie-Mellon University
|
||||
5000 Forbes Ave.
|
||||
Pittsburgh PA, 15213-3890
|
||||
|
||||
Email: jgm+@cmu.edu
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 8]
|
||||
|
|
@ -1,283 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group J. Myers
|
||||
Request for Comments: 2087 Carnegie Mellon
|
||||
Category: Standards Track January 1997
|
||||
|
||||
|
||||
IMAP4 QUOTA extension
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This document specifies an Internet standards track protocol for the
|
||||
Internet community, and requests discussion and suggestions for
|
||||
improvements. Please refer to the current edition of the "Internet
|
||||
Official Protocol Standards" (STD 1) for the standardization state
|
||||
and status of this protocol. Distribution of this memo is unlimited.
|
||||
|
||||
1. Abstract
|
||||
|
||||
The QUOTA extension of the Internet Message Access Protocol [IMAP4]
|
||||
permits administrative limits on resource usage (quotas) to be
|
||||
manipulated through the IMAP protocol.
|
||||
|
||||
Table of Contents
|
||||
|
||||
1. Abstract........................................... 1
|
||||
2. Conventions Used in this Document.................. 1
|
||||
3. Introduction and Overview.......................... 2
|
||||
4. Commands........................................... 2
|
||||
4.1. SETQUOTA Command................................... 2
|
||||
4.2. GETQUOTA Command................................... 2
|
||||
4.3. GETQUOTAROOT Command............................... 3
|
||||
5. Responses.......................................... 3
|
||||
5.1. QUOTA Response..................................... 3
|
||||
5.2. QUOTAROOT Response................................. 4
|
||||
6. Formal syntax...................................... 4
|
||||
7. References......................................... 5
|
||||
8. Security Considerations............................ 5
|
||||
9. Author's Address................................... 5
|
||||
|
||||
|
||||
2. Conventions Used in this Document
|
||||
|
||||
In examples, "C:" and "S:" indicate lines sent by the client and
|
||||
server respectively.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 1]
|
||||
|
||||
RFC 2087 QUOTA January 1997
|
||||
|
||||
|
||||
3. Introduction and Overview
|
||||
|
||||
The QUOTA extension is present in any IMAP4 implementation which
|
||||
returns "QUOTA" as one of the supported capabilities to the
|
||||
CAPABILITY command.
|
||||
|
||||
An IMAP4 server which supports the QUOTA capability may support
|
||||
limits on any number of resources. Each resource has an atom name
|
||||
and an implementation-defined interpretation which evaluates to an
|
||||
integer. Examples of such resources are:
|
||||
|
||||
Name Interpretation
|
||||
|
||||
STORAGE Sum of messages' RFC822.SIZE, in units of 1024 octets
|
||||
MESSAGE Number of messages
|
||||
|
||||
|
||||
Each mailbox has zero or more implementation-defined named "quota
|
||||
roots". Each quota root has zero or more resource limits. All
|
||||
mailboxes that share the same named quota root share the resource
|
||||
limits of the quota root.
|
||||
|
||||
Quota root names do not necessarily have to match the names of
|
||||
existing mailboxes.
|
||||
|
||||
4. Commands
|
||||
|
||||
4.1. SETQUOTA Command
|
||||
|
||||
Arguments: quota root
|
||||
list of resource limits
|
||||
|
||||
Data: untagged responses: QUOTA
|
||||
|
||||
Result: OK - setquota completed
|
||||
NO - setquota error: can't set that data
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
The SETQUOTA command takes the name of a mailbox quota root and a
|
||||
list of resource limits. The resource limits for the named quota root
|
||||
are changed to be the specified limits. Any previous resource limits
|
||||
for the named quota root are discarded.
|
||||
|
||||
If the named quota root did not previously exist, an implementation
|
||||
may optionally create it and change the quota roots for any number of
|
||||
existing mailboxes in an implementation-defined manner.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 2]
|
||||
|
||||
RFC 2087 QUOTA January 1997
|
||||
|
||||
|
||||
Example: C: A001 SETQUOTA "" (STORAGE 512)
|
||||
S: * QUOTA "" (STORAGE 10 512)
|
||||
S: A001 OK Setquota completed
|
||||
|
||||
4.2. GETQUOTA Command
|
||||
|
||||
Arguments: quota root
|
||||
|
||||
Data: untagged responses: QUOTA
|
||||
|
||||
Result: OK - getquota completed
|
||||
NO - getquota error: no such quota root, permission
|
||||
denied
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
The GETQUOTA command takes the name of a quota root and returns the
|
||||
quota root's resource usage and limits in an untagged QUOTA response.
|
||||
|
||||
Example: C: A003 GETQUOTA ""
|
||||
S: * QUOTA "" (STORAGE 10 512)
|
||||
S: A003 OK Getquota completed
|
||||
|
||||
4.3. GETQUOTAROOT Command
|
||||
|
||||
Arguments: mailbox name
|
||||
|
||||
Data: untagged responses: QUOTAROOT, QUOTA
|
||||
|
||||
Result: OK - getquota completed
|
||||
NO - getquota error: no such mailbox, permission denied
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
The GETQUOTAROOT command takes the name of a mailbox and returns the
|
||||
list of quota roots for the mailbox in an untagged QUOTAROOT
|
||||
response. For each listed quota root, it also returns the quota
|
||||
root's resource usage and limits in an untagged QUOTA response.
|
||||
|
||||
Example: C: A003 GETQUOTAROOT INBOX
|
||||
S: * QUOTAROOT INBOX ""
|
||||
S: * QUOTA "" (STORAGE 10 512)
|
||||
S: A003 OK Getquota completed
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 3]
|
||||
|
||||
RFC 2087 QUOTA January 1997
|
||||
|
||||
|
||||
5. Responses
|
||||
|
||||
5.1. QUOTA Response
|
||||
|
||||
Data: quota root name
|
||||
list of resource names, usages, and limits
|
||||
|
||||
This response occurs as a result of a GETQUOTA or GETQUOTAROOT
|
||||
command. The first string is the name of the quota root for which
|
||||
this quota applies.
|
||||
|
||||
The name is followed by a S-expression format list of the resource
|
||||
usage and limits of the quota root. The list contains zero or
|
||||
more triplets. Each triplet conatins a resource name, the current
|
||||
usage of the resource, and the resource limit.
|
||||
|
||||
Resources not named in the list are not limited in the quota root.
|
||||
Thus, an empty list means there are no administrative resource
|
||||
limits in the quota root.
|
||||
|
||||
Example: S: * QUOTA "" (STORAGE 10 512)
|
||||
|
||||
5.2. QUOTAROOT Response
|
||||
|
||||
Data: mailbox name
|
||||
zero or more quota root names
|
||||
|
||||
This response occurs as a result of a GETQUOTAROOT command. The
|
||||
first string is the mailbox and the remaining strings are the
|
||||
names of the quota roots for the mailbox.
|
||||
|
||||
Example: S: * QUOTAROOT INBOX ""
|
||||
S: * QUOTAROOT comp.mail.mime
|
||||
|
||||
6. Formal syntax
|
||||
|
||||
The following syntax specification uses the augmented Backus-Naur
|
||||
Form (BNF) notation as specified in RFC 822 with one exception; the
|
||||
delimiter used with the "#" construct is a single space (SP) and not
|
||||
one or more commas.
|
||||
|
||||
Except as noted otherwise, all alphabetic characters are case-
|
||||
insensitive. The use of upper or lower case characters to define
|
||||
token strings is for editorial clarity only. Implementations MUST
|
||||
accept these strings in a case-insensitive fashion.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 4]
|
||||
|
||||
RFC 2087 QUOTA January 1997
|
||||
|
||||
|
||||
getquota ::= "GETQUOTA" SP astring
|
||||
|
||||
getquotaroot ::= "GETQUOTAROOT" SP astring
|
||||
|
||||
quota_list ::= "(" #quota_resource ")"
|
||||
|
||||
quota_resource ::= atom SP number SP number
|
||||
|
||||
quota_response ::= "QUOTA" SP astring SP quota_list
|
||||
|
||||
quotaroot_response
|
||||
::= "QUOTAROOT" SP astring *(SP astring)
|
||||
|
||||
setquota ::= "SETQUOTA" SP astring SP setquota_list
|
||||
|
||||
setquota_list ::= "(" 0#setquota_resource ")"
|
||||
|
||||
setquota_resource ::= atom SP number
|
||||
|
||||
7. References
|
||||
|
||||
[IMAP4] Crispin, M., "Internet Message Access Protocol - Version 4",
|
||||
RFC 1730, University of Washington, December 1994.
|
||||
|
||||
[RFC-822] Crocker, D., "Standard for the Format of ARPA Internet
|
||||
Text Messages", STD 11, RFC 822.
|
||||
|
||||
8. Security Considerations
|
||||
|
||||
Implementors should be careful to make sure the implementation of
|
||||
these commands does not violate the site's security policy. The
|
||||
resource usage of other users is likely to be considered confidential
|
||||
information and should not be divulged to unauthorized persons.
|
||||
|
||||
9. Author's Address
|
||||
|
||||
John G. Myers
|
||||
Carnegie-Mellon University
|
||||
5000 Forbes Ave.
|
||||
Pittsburgh PA, 15213-3890
|
||||
|
||||
EMail: jgm+@cmu.edu
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 5]
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group J. Myers
|
||||
Request for Comments: 2088 Carnegie Mellon
|
||||
Cateogry: Standards Track January 1997
|
||||
|
||||
|
||||
IMAP4 non-synchronizing literals
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This document specifies an Internet standards track protocol for the
|
||||
Internet community, and requests discussion and suggestions for
|
||||
improvements. Please refer to the current edition of the "Internet
|
||||
Official Protocol Standards" (STD 1) for the standardization state
|
||||
and status of this protocol. Distribution of this memo is unlimited.
|
||||
|
||||
1. Abstract
|
||||
|
||||
The Internet Message Access Protocol [IMAP4] contains the "literal"
|
||||
syntactic construct for communicating strings. When sending a
|
||||
literal from client to server, IMAP4 requires the client to wait for
|
||||
the server to send a command continuation request between sending the
|
||||
octet count and the string data. This document specifies an
|
||||
alternate form of literal which does not require this network round
|
||||
trip.
|
||||
|
||||
2. Conventions Used in this Document
|
||||
|
||||
In examples, "C:" and "S:" indicate lines sent by the client and
|
||||
server respectively.
|
||||
|
||||
3. Specification
|
||||
|
||||
The non-synchronizing literal is added an alternate form of literal,
|
||||
and may appear in communication from client to server instead of the
|
||||
IMAP4 form of literal. The IMAP4 form of literal, used in
|
||||
communication from client to server, is referred to as a
|
||||
synchronizing literal.
|
||||
|
||||
Non-synchronizing literals may be used with any IMAP4 server
|
||||
implementation which returns "LITERAL+" as one of the supported
|
||||
capabilities to the CAPABILITY command. If the server does not
|
||||
advertise the LITERAL+ capability, the client must use synchronizing
|
||||
literals instead.
|
||||
|
||||
The non-synchronizing literal is distinguished from the original
|
||||
synchronizing literal by having a plus ('+') between the octet count
|
||||
and the closing brace ('}'). The server does not generate a command
|
||||
continuation request in response to a non-synchronizing literal, and
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 1]
|
||||
|
||||
RFC 2088 LITERAL January 1997
|
||||
|
||||
|
||||
clients are not required to wait before sending the octets of a non-
|
||||
synchronizing literal.
|
||||
|
||||
The protocol receiver of an IMAP4 server must check the end of every
|
||||
received line for an open brace ('{') followed by an octet count, a
|
||||
plus ('+'), and a close brace ('}') immediately preceeding the CRLF.
|
||||
If it finds this sequence, it is the octet count of a non-
|
||||
synchronizing literal and the server MUST treat the specified number
|
||||
of following octets and the following line as part of the same
|
||||
command. A server MAY still process commands and reject errors on a
|
||||
line-by-line basis, as long as it checks for non-synchronizing
|
||||
literals at the end of each line.
|
||||
|
||||
Example: C: A001 LOGIN {11+}
|
||||
C: FRED FOOBAR {7+}
|
||||
C: fat man
|
||||
S: A001 OK LOGIN completed
|
||||
|
||||
4. Formal Syntax
|
||||
|
||||
The following syntax specification uses the augmented Backus-Naur
|
||||
Form (BNF) notation as specified in [RFC-822] as modified by [IMAP4].
|
||||
Non-terminals referenced but not defined below are as defined by
|
||||
[IMAP4].
|
||||
|
||||
literal ::= "{" number ["+"] "}" CRLF *CHAR8
|
||||
;; Number represents the number of CHAR8 octets
|
||||
|
||||
6. References
|
||||
|
||||
[IMAP4] Crispin, M., "Internet Message Access Protocol - Version 4",
|
||||
draft-crispin-imap-base-XX.txt, University of Washington, April 1996.
|
||||
|
||||
[RFC-822] Crocker, D., "Standard for the Format of ARPA Internet Text
|
||||
Messages", STD 11, RFC 822.
|
||||
|
||||
7. Security Considerations
|
||||
|
||||
There are no known security issues with this extension.
|
||||
|
||||
8. Author's Address
|
||||
|
||||
John G. Myers
|
||||
Carnegie-Mellon University
|
||||
5000 Forbes Ave.
|
||||
Pittsburgh PA, 15213-3890
|
||||
|
||||
Email: jgm+@cmu.edu
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 2]
|
||||
|
|
@ -1,227 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group B. Leiba
|
||||
Request for Comments: 2177 IBM T.J. Watson Research Center
|
||||
Category: Standards Track June 1997
|
||||
|
||||
|
||||
IMAP4 IDLE command
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This document specifies an Internet standards track protocol for the
|
||||
Internet community, and requests discussion and suggestions for
|
||||
improvements. Please refer to the current edition of the "Internet
|
||||
Official Protocol Standards" (STD 1) for the standardization state
|
||||
and status of this protocol. Distribution of this memo is unlimited.
|
||||
|
||||
1. Abstract
|
||||
|
||||
The Internet Message Access Protocol [IMAP4] requires a client to
|
||||
poll the server for changes to the selected mailbox (new mail,
|
||||
deletions). It's often more desirable to have the server transmit
|
||||
updates to the client in real time. This allows a user to see new
|
||||
mail immediately. It also helps some real-time applications based on
|
||||
IMAP, which might otherwise need to poll extremely often (such as
|
||||
every few seconds). (While the spec actually does allow a server to
|
||||
push EXISTS responses aysynchronously, a client can't expect this
|
||||
behaviour and must poll.)
|
||||
|
||||
This document specifies the syntax of an IDLE command, which will
|
||||
allow a client to tell the server that it's ready to accept such
|
||||
real-time updates.
|
||||
|
||||
2. Conventions Used in this Document
|
||||
|
||||
In examples, "C:" and "S:" indicate lines sent by the client and
|
||||
server respectively.
|
||||
|
||||
The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY"
|
||||
in this document are to be interpreted as described in RFC 2060
|
||||
[IMAP4].
|
||||
|
||||
3. Specification
|
||||
|
||||
IDLE Command
|
||||
|
||||
Arguments: none
|
||||
|
||||
Responses: continuation data will be requested; the client sends
|
||||
the continuation data "DONE" to end the command
|
||||
|
||||
|
||||
|
||||
Leiba Standards Track [Page 1]
|
||||
|
||||
RFC 2177 IMAP4 IDLE command June 1997
|
||||
|
||||
|
||||
|
||||
Result: OK - IDLE completed after client sent "DONE"
|
||||
NO - failure: the server will not allow the IDLE
|
||||
command at this time
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
The IDLE command may be used with any IMAP4 server implementation
|
||||
that returns "IDLE" as one of the supported capabilities to the
|
||||
CAPABILITY command. If the server does not advertise the IDLE
|
||||
capability, the client MUST NOT use the IDLE command and must poll
|
||||
for mailbox updates. In particular, the client MUST continue to be
|
||||
able to accept unsolicited untagged responses to ANY command, as
|
||||
specified in the base IMAP specification.
|
||||
|
||||
The IDLE command is sent from the client to the server when the
|
||||
client is ready to accept unsolicited mailbox update messages. The
|
||||
server requests a response to the IDLE command using the continuation
|
||||
("+") response. The IDLE command remains active until the client
|
||||
responds to the continuation, and as long as an IDLE command is
|
||||
active, the server is now free to send untagged EXISTS, EXPUNGE, and
|
||||
other messages at any time.
|
||||
|
||||
The IDLE command is terminated by the receipt of a "DONE"
|
||||
continuation from the client; such response satisfies the server's
|
||||
continuation request. At that point, the server MAY send any
|
||||
remaining queued untagged responses and then MUST immediately send
|
||||
the tagged response to the IDLE command and prepare to process other
|
||||
commands. As in the base specification, the processing of any new
|
||||
command may cause the sending of unsolicited untagged responses,
|
||||
subject to the ambiguity limitations. The client MUST NOT send a
|
||||
command while the server is waiting for the DONE, since the server
|
||||
will not be able to distinguish a command from a continuation.
|
||||
|
||||
The server MAY consider a client inactive if it has an IDLE command
|
||||
running, and if such a server has an inactivity timeout it MAY log
|
||||
the client off implicitly at the end of its timeout period. Because
|
||||
of that, clients using IDLE are advised to terminate the IDLE and
|
||||
re-issue it at least every 29 minutes to avoid being logged off.
|
||||
This still allows a client to receive immediate mailbox updates even
|
||||
though it need only "poll" at half hour intervals.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Leiba Standards Track [Page 2]
|
||||
|
||||
RFC 2177 IMAP4 IDLE command June 1997
|
||||
|
||||
|
||||
Example: C: A001 SELECT INBOX
|
||||
S: * FLAGS (Deleted Seen)
|
||||
S: * 3 EXISTS
|
||||
S: * 0 RECENT
|
||||
S: * OK [UIDVALIDITY 1]
|
||||
S: A001 OK SELECT completed
|
||||
C: A002 IDLE
|
||||
S: + idling
|
||||
...time passes; new mail arrives...
|
||||
S: * 4 EXISTS
|
||||
C: DONE
|
||||
S: A002 OK IDLE terminated
|
||||
...another client expunges message 2 now...
|
||||
C: A003 FETCH 4 ALL
|
||||
S: * 4 FETCH (...)
|
||||
S: A003 OK FETCH completed
|
||||
C: A004 IDLE
|
||||
S: * 2 EXPUNGE
|
||||
S: * 3 EXISTS
|
||||
S: + idling
|
||||
...time passes; another client expunges message 3...
|
||||
S: * 3 EXPUNGE
|
||||
S: * 2 EXISTS
|
||||
...time passes; new mail arrives...
|
||||
S: * 3 EXISTS
|
||||
C: DONE
|
||||
S: A004 OK IDLE terminated
|
||||
C: A005 FETCH 3 ALL
|
||||
S: * 3 FETCH (...)
|
||||
S: A005 OK FETCH completed
|
||||
C: A006 IDLE
|
||||
|
||||
4. Formal Syntax
|
||||
|
||||
The following syntax specification uses the augmented Backus-Naur
|
||||
Form (BNF) notation as specified in [RFC-822] as modified by [IMAP4].
|
||||
Non-terminals referenced but not defined below are as defined by
|
||||
[IMAP4].
|
||||
|
||||
command_auth ::= append / create / delete / examine / list / lsub /
|
||||
rename / select / status / subscribe / unsubscribe
|
||||
/ idle
|
||||
;; Valid only in Authenticated or Selected state
|
||||
|
||||
idle ::= "IDLE" CRLF "DONE"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Leiba Standards Track [Page 3]
|
||||
|
||||
RFC 2177 IMAP4 IDLE command June 1997
|
||||
|
||||
|
||||
5. References
|
||||
|
||||
[IMAP4] Crispin, M., "Internet Message Access Protocol - Version
|
||||
4rev1", RFC 2060, December 1996.
|
||||
|
||||
6. Security Considerations
|
||||
|
||||
There are no known security issues with this extension.
|
||||
|
||||
7. Author's Address
|
||||
|
||||
Barry Leiba
|
||||
IBM T.J. Watson Research Center
|
||||
30 Saw Mill River Road
|
||||
Hawthorne, NY 10532
|
||||
|
||||
Email: leiba@watson.ibm.com
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Leiba Standards Track [Page 4]
|
||||
|
|
@ -1,787 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group M. Gahrns
|
||||
Request for Comments: 2180 Microsoft
|
||||
Category: Informational July 1997
|
||||
|
||||
|
||||
IMAP4 Multi-Accessed Mailbox Practice
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This memo provides information for the Internet community. This memo
|
||||
does not specify an Internet standard of any kind. Distribution of
|
||||
this memo is unlimited.
|
||||
|
||||
1. Abstract
|
||||
|
||||
IMAP4[RFC-2060] is rich client/server protocol that allows a client
|
||||
to access and manipulate electronic mail messages on a server.
|
||||
Within the protocol framework, it is possible to have differing
|
||||
results for particular client/server interactions. If a protocol does
|
||||
not allow for this, it is often unduly restrictive.
|
||||
|
||||
For example, when multiple clients are accessing a mailbox and one
|
||||
attempts to delete the mailbox, an IMAP4 server may choose to
|
||||
implement a solution based upon server architectural constraints or
|
||||
individual preference.
|
||||
|
||||
With this flexibility comes greater client responsibility. It is not
|
||||
sufficient for a client to be written based upon the behavior of a
|
||||
particular IMAP server. Rather the client must be based upon the
|
||||
behavior allowed by the protocol.
|
||||
|
||||
By documenting common IMAP4 server practice for the case of
|
||||
simultaneous client access to a mailbox, we hope to ensure the widest
|
||||
amount of inter-operation between IMAP4 clients and servers.
|
||||
|
||||
The behavior described in this document reflects the practice of some
|
||||
existing servers or behavior that the consensus of the IMAP mailing
|
||||
list has deemed to be reasonable. The behavior described within this
|
||||
document is believed to be [RFC-2060] compliant. However, this
|
||||
document is not meant to define IMAP4 compliance, nor is it an
|
||||
exhaustive list of valid IMAP4 behavior. [RFC-2060] must always be
|
||||
consulted to determine IMAP4 compliance, especially for server
|
||||
behavior not described within this document.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Informational [Page 1]
|
||||
|
||||
RFC 2180 IMAP4 Multi-Accessed Mailbox Practice July 1997
|
||||
|
||||
|
||||
2. Conventions used in this document
|
||||
|
||||
In examples,"C1:", "C2:" and "C3:" indicate lines sent by 3 different
|
||||
clients (client #1, client #2 and client #3) that are connected to a
|
||||
server. "S1:", "S2:" and "S3:" indicated lines sent by the server to
|
||||
client #1, client #2 and client #3 respectively.
|
||||
|
||||
A shared mailbox, is a mailbox that can be used by multiple users.
|
||||
|
||||
A multi-accessed mailbox, is a mailbox that has multiple clients
|
||||
simultaneously accessing it.
|
||||
|
||||
A client is said to have accessed a mailbox after a successful SELECT
|
||||
or EXAMINE command.
|
||||
|
||||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
|
||||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
|
||||
document are to be interpreted as described in [RFC-2119].
|
||||
|
||||
|
||||
3. Deletion/Renaming of a multi-accessed mailbox
|
||||
|
||||
If an external agent or multiple clients are accessing a mailbox,
|
||||
care must be taken when handling the deletion or renaming of the
|
||||
mailbox. Following are some strategies an IMAP server may choose to
|
||||
use when dealing with this situation.
|
||||
|
||||
|
||||
3.1. The server MAY fail the DELETE/RENAME command of a multi-accessed
|
||||
mailbox
|
||||
|
||||
In some cases, this behavior may not be practical. For example, if a
|
||||
large number of clients are accessing a shared mailbox, the window in
|
||||
which no clients have the mailbox accessed may be small or non-
|
||||
existent, effectively rendering the mailbox undeletable or
|
||||
unrenamable.
|
||||
|
||||
Example:
|
||||
|
||||
<Client #1 and Client #2 have mailbox FOO accessed. Client #1 tries
|
||||
to DELETE the mailbox and is refused>
|
||||
|
||||
C1: A001 DELETE FOO
|
||||
S1: A001 NO Mailbox FOO is in use by another user.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Informational [Page 2]
|
||||
|
||||
RFC 2180 IMAP4 Multi-Accessed Mailbox Practice July 1997
|
||||
|
||||
|
||||
3.2. The server MAY allow the DELETE command of a multi-accessed
|
||||
mailbox, but keep the information in the mailbox available for
|
||||
those clients that currently have access to the mailbox.
|
||||
|
||||
When all clients have finished accessing the mailbox, it is
|
||||
permanently removed. For clients that do not already have access to
|
||||
the mailbox, the 'ghosted' mailbox would not be available. For
|
||||
example, it would not be returned to these clients in a subsequent
|
||||
LIST or LSUB command and would not be a valid mailbox argument to any
|
||||
other IMAP command until the reference count of clients accessing the
|
||||
mailbox reached 0.
|
||||
|
||||
In some cases, this behavior may not be desirable. For example if
|
||||
someone created a mailbox with offensive or sensitive information,
|
||||
one might prefer to have the mailbox deleted and all access to the
|
||||
information contained within removed immediately, rather than
|
||||
continuing to allow access until the client closes the mailbox.
|
||||
|
||||
Furthermore, this behavior, may prevent 'recycling' of the same
|
||||
mailbox name until all clients have finished accessing the original
|
||||
mailbox.
|
||||
|
||||
Example:
|
||||
|
||||
<Client #1 and Client #2 have mailbox FOO selected. Client #1 DELETEs
|
||||
mailbox FOO>
|
||||
|
||||
C1: A001 DELETE FOO
|
||||
S1: A001 OK Mailbox FOO is deleted.
|
||||
|
||||
<Client #2 is still able to operate on the deleted mailbox>
|
||||
|
||||
C2: B001 STORE 1 +FLAGS (\Seen)
|
||||
S2: * 1 FETCH FLAGS (\Seen)
|
||||
S2: B001 OK STORE completed
|
||||
|
||||
<Client #3 which did not have access to the mailbox prior to the
|
||||
deletion by client #1 does not have access to the mailbox>
|
||||
|
||||
C3: C001 STATUS FOO (MESSAGES)
|
||||
S3: C001 NO Mailbox does not exist
|
||||
|
||||
<Nor is client #3 able to create a mailbox with the name FOO, while
|
||||
the reference count is non zero>
|
||||
|
||||
C3: C002 CREATE FOO
|
||||
S3: C002 NO Mailbox FOO is still in use. Try again later.
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Informational [Page 3]
|
||||
|
||||
RFC 2180 IMAP4 Multi-Accessed Mailbox Practice July 1997
|
||||
|
||||
|
||||
<Client #2 closes its access to the mailbox, no other clients have
|
||||
access to the mailbox FOO and reference count becomes 0>
|
||||
|
||||
C2: B002 CLOSE
|
||||
S2: B002 OK CLOSE Completed
|
||||
|
||||
<Now that the reference count on FOO has reached 0, the mailbox name
|
||||
can be recycled>
|
||||
|
||||
C3: C003 CREATE FOO
|
||||
S3: C003 OK CREATE Completed
|
||||
|
||||
|
||||
3.3. The server MAY allow the DELETE/RENAME of a multi-accessed
|
||||
mailbox, but disconnect all other clients who have the mailbox
|
||||
accessed by sending a untagged BYE response.
|
||||
|
||||
A server may often choose to disconnect clients in the DELETE case,
|
||||
but may choose to implement a "friendlier" method for the RENAME
|
||||
case.
|
||||
|
||||
Example:
|
||||
|
||||
<Client #1 and Client #2 have mailbox FOO accessed. Client #1 DELETEs
|
||||
the mailbox FOO>
|
||||
|
||||
C1: A002 DELETE FOO
|
||||
S1: A002 OK DELETE completed.
|
||||
|
||||
<Server disconnects all other users of the mailbox>
|
||||
S2: * BYE Mailbox FOO has been deleted.
|
||||
|
||||
|
||||
3.4. The server MAY allow the RENAME of a multi-accessed mailbox by
|
||||
simply changing the name attribute on the mailbox.
|
||||
|
||||
Other clients that have access to the mailbox can continue issuing
|
||||
commands such as FETCH that do not reference the mailbox name.
|
||||
Clients would discover the renaming the next time they referred to
|
||||
the old mailbox name. Some servers MAY choose to include the
|
||||
[NEWNAME] response code in their tagged NO response to a command that
|
||||
contained the old mailbox name, as a hint to the client that the
|
||||
operation can succeed if the command is issued with the new mailbox
|
||||
name.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Informational [Page 4]
|
||||
|
||||
RFC 2180 IMAP4 Multi-Accessed Mailbox Practice July 1997
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
<Client #1 and Client #2 have mailbox FOO accessed. Client #1 RENAMEs
|
||||
the mailbox.>
|
||||
|
||||
C1: A001 RENAME FOO BAR
|
||||
S1: A001 OK RENAME completed.
|
||||
|
||||
<Client #2 is still able to do operations that do not reference the
|
||||
mailbox name>
|
||||
|
||||
C2: B001 FETCH 2:4 (FLAGS)
|
||||
S2: * 2 FETCH . . .
|
||||
S2: * 3 FETCH . . .
|
||||
S2: * 4 FETCH . . .
|
||||
S2: B001 OK FETCH completed
|
||||
|
||||
<Client #2 is not able to do operations that reference the mailbox
|
||||
name>
|
||||
|
||||
C2: B002 APPEND FOO {300} C2: Date: Mon, 7 Feb 1994
|
||||
21:52:25 0800 (PST) C2: . . . S2: B002 NO [NEWNAME FOO
|
||||
BAR] Mailbox has been renamed
|
||||
|
||||
|
||||
4. Expunging of messages on a multi-accessed mailbox
|
||||
|
||||
If an external agent or multiple clients are accessing a mailbox,
|
||||
care must be taken when handling the EXPUNGE of messages. Other
|
||||
clients accessing the mailbox may be in the midst of issuing a
|
||||
command that depends upon message sequence numbers. Because an
|
||||
EXPUNGE response can not be sent while responding to a FETCH, STORE
|
||||
or SEARCH command, it is not possible to immediately notify the
|
||||
client of the EXPUNGE. This can result in ambiguity if the client
|
||||
issues a FETCH, STORE or SEARCH operation on a message that has been
|
||||
EXPUNGED.
|
||||
|
||||
|
||||
4.1. Fetching of expunged messages
|
||||
|
||||
Following are some strategies an IMAP server may choose to use when
|
||||
dealing with a FETCH command on expunged messages.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Informational [Page 5]
|
||||
|
||||
RFC 2180 IMAP4 Multi-Accessed Mailbox Practice July 1997
|
||||
|
||||
|
||||
Consider the following scenario:
|
||||
|
||||
- Client #1 and Client #2 have mailbox FOO selected.
|
||||
- There are 7 messages in the mailbox.
|
||||
- Messages 4:7 are marked for deletion.
|
||||
- Client #1 issues an EXPUNGE, to expunge messages 4:7
|
||||
|
||||
|
||||
4.1.1. The server MAY allow the EXPUNGE of a multi-accessed mailbox but
|
||||
keep the messages available to satisfy subsequent FETCH commands
|
||||
until it is able to send an EXPUNGE response to each client.
|
||||
|
||||
In some cases, the behavior of keeping "ghosted" messages may not be
|
||||
desirable. For example if a message contained offensive or sensitive
|
||||
information, one might prefer to instantaneously remove all access to
|
||||
the information, regardless of whether another client is in the midst
|
||||
of accessing it.
|
||||
|
||||
Example: (Building upon the scenario outlined in 4.1.)
|
||||
|
||||
<Client #2 is still able to access the expunged messages because the
|
||||
server has kept a 'ghosted' copy of the messages until it is able to
|
||||
notify client #2 of the EXPUNGE>
|
||||
|
||||
C2: B001 FETCH 4:7 RFC822
|
||||
S2: * 4 FETCH RFC822 . . . (RFC822 info returned)
|
||||
S2: * 5 FETCH RFC822 . . . (RFC822 info returned)
|
||||
S2: * 6 FETCH RFC822 . . . (RFC822 info returned)
|
||||
S2: * 7 FETCH RFC822 . . . (RFC822 info returned)
|
||||
S2: B001 OK FETCH Completed
|
||||
|
||||
<Client #2 issues a command where it can get notified of the EXPUNGE>
|
||||
|
||||
C2: B002 NOOP
|
||||
S2: * 4 EXPUNGE
|
||||
S2: * 4 EXPUNGE
|
||||
S2: * 4 EXPUNGE
|
||||
S2: * 4 EXPUNGE
|
||||
S2: * 3 EXISTS
|
||||
S2: B002 OK NOOP Complete
|
||||
|
||||
<Client #2 no longer has access to the expunged messages>
|
||||
|
||||
C2: B003 FETCH 4:7 RFC822
|
||||
S2: B003 NO Messages 4:7 are no longer available.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Informational [Page 6]
|
||||
|
||||
RFC 2180 IMAP4 Multi-Accessed Mailbox Practice July 1997
|
||||
|
||||
|
||||
4.1.2 The server MAY allow the EXPUNGE of a multi-accessed mailbox,
|
||||
and on subsequent FETCH commands return FETCH responses only for
|
||||
non-expunged messages and a tagged NO.
|
||||
|
||||
After receiving a tagged NO FETCH response, the client SHOULD issue a
|
||||
NOOP command so that it will be informed of any pending EXPUNGE
|
||||
responses. The client may then either reissue the failed FETCH
|
||||
command, or by examining the EXPUNGE response from the NOOP and the
|
||||
FETCH response from the FETCH, determine that the FETCH failed
|
||||
because of pending expunges.
|
||||
|
||||
Example: (Building upon the scenario outlined in 4.1.)
|
||||
|
||||
<Client #2 attempts to FETCH a mix of expunged and non-expunged
|
||||
messages. A FETCH response is returned only for then non-expunged
|
||||
messages along with a tagged NO>
|
||||
|
||||
C2: B001 FETCH 3:5 ENVELOPE
|
||||
S2: * 3 FETCH ENVELOPE . . . (ENVELOPE info returned)
|
||||
S2: B001 NO Some of the requested messages no longer exist
|
||||
|
||||
<Upon receiving a tagged NO FETCH response, Client #2 issues a NOOP
|
||||
to be informed of any pending EXPUNGE responses>
|
||||
|
||||
C2: B002 NOOP
|
||||
S2: * 4 EXPUNGE
|
||||
S2: * 4 EXPUNGE
|
||||
S2: * 4 EXPUNGE
|
||||
S2: * 4 EXPUNGE
|
||||
S2: * 3 EXISTS
|
||||
S2: B002 OK NOOP Completed.
|
||||
|
||||
<By receiving a FETCH response for message 3, and an EXPUNGE response
|
||||
that indicates messages 4:7 have been expunged, the client does not
|
||||
need to re-issue the FETCH>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Informational [Page 7]
|
||||
|
||||
RFC 2180 IMAP4 Multi-Accessed Mailbox Practice July 1997
|
||||
|
||||
|
||||
4.1.3 The server MAY allow the EXPUNGE of a multi-accessed mailbox, and
|
||||
on subsequent FETCH commands return the usual FETCH responses for
|
||||
non-expunged messages, "NIL FETCH Responses" for expunged
|
||||
messages, and a tagged OK response.
|
||||
|
||||
If all of the messages in the subsequent FETCH command have been
|
||||
expunged, the server SHOULD return only a tagged NO. In this case,
|
||||
the client SHOULD issue a NOOP command so that it will be informed of
|
||||
any pending EXPUNGE responses. The client may then either reissue
|
||||
the failed FETCH command, or by examining the EXPUNGE response from
|
||||
the NOOP, determine that the FETCH failed because of pending
|
||||
expunges.
|
||||
|
||||
"NIL FETCH responses" are a representation of empty data as
|
||||
appropriate for the FETCH argument specified.
|
||||
|
||||
Example:
|
||||
|
||||
* 1 FETCH (ENVELOPE (NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL))
|
||||
* 1 FETCH (FLAGS ())
|
||||
* 1 FETCH (INTERNALDATE "00-Jan-0000 00:00:00 +0000")
|
||||
* 1 FETCH (RFC822 "")
|
||||
* 1 FETCH (RFC822.HEADER "")
|
||||
* 1 FETCH (RFC822.TEXT "")
|
||||
* 1 FETCH (RFC822.SIZE 0)
|
||||
* 1 FETCH (BODY ("TEXT" "PLAIN" NIL NIL NIL "7BIT" 0 0)
|
||||
* 1 FETCH (BODYSTRUCTURE ("TEXT" "PLAIN" NIL NIL NIL "7BIT" 0 0)
|
||||
* 1 FETCH (BODY[<section>] "")
|
||||
* 1 FETCH (BODY[<section>]<partial> "")
|
||||
|
||||
In some cases, a client may not be able to distinguish between "NIL
|
||||
FETCH responses" received because a message was expunged and those
|
||||
received because the data actually was NIL. For example, a * 5
|
||||
FETCH (FLAGS ()) response could be received if no flags were set on
|
||||
message 5, or because message 5 was expunged. In a case of potential
|
||||
ambiguity, the client SHOULD issue a command such as NOOP to force
|
||||
the sending of the EXPUNGE responses to resolve any ambiguity.
|
||||
|
||||
Example: (Building upon the scenario outlined in 4.1.)
|
||||
|
||||
<Client #2 attempts to access a mix of expunged and non-expunged
|
||||
messages. Normal data is returned for non-expunged message, "NIL
|
||||
FETCH responses" are returned for expunged messages>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Informational [Page 8]
|
||||
|
||||
RFC 2180 IMAP4 Multi-Accessed Mailbox Practice July 1997
|
||||
|
||||
|
||||
C2: B002 FETCH 3:5 ENVELOPE
|
||||
S2: * 3 FETCH ENVELOPE . . . (ENVELOPE info returned)
|
||||
S2: * 4 FETCH ENVELOPE (NIL NIL NIL NIL NIL NIL NIL NIL
|
||||
NIL NIL)
|
||||
S2: * 5 FETCH ENVELOPE (NIL NIL NIL NIL NIL NIL NIL NIL
|
||||
NIL NIL)
|
||||
S2: B002 OK FETCH Completed
|
||||
|
||||
<Client #2 attempts to FETCH only expunged messages and receives a
|
||||
tagged NO response>
|
||||
|
||||
C2: B002 FETCH 4:7 ENVELOPE
|
||||
S2: B002 NO Messages 4:7 have been expunged.
|
||||
|
||||
|
||||
4.1.4 To avoid the situation altogether, the server MAY fail the
|
||||
EXPUNGE of a multi-accessed mailbox
|
||||
|
||||
In some cases, this behavior may not be practical. For example, if a
|
||||
large number of clients are accessing a shared mailbox, the window in
|
||||
which no clients have the mailbox accessed may be small or non-
|
||||
existent, effectively rendering the message unexpungeable.
|
||||
|
||||
|
||||
4.2. Storing of expunged messages
|
||||
|
||||
Following are some strategies an IMAP server may choose to use when
|
||||
dealing with a STORE command on expunged messages.
|
||||
|
||||
|
||||
4.2.1 If the ".SILENT" suffix is used, and the STORE completed
|
||||
successfully for all the non-expunged messages, the server SHOULD
|
||||
return a tagged OK.
|
||||
|
||||
Example: (Building upon the scenario outlined in 4.1.)
|
||||
|
||||
<Client #2 tries to silently STORE flags on expunged and non-
|
||||
expunged messages. The server sets the flags on the non-expunged
|
||||
messages and returns OK>
|
||||
|
||||
C2: B001 STORE 1:7 +FLAGS.SILENT (\SEEN)
|
||||
S2: B001 OK
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Informational [Page 9]
|
||||
|
||||
RFC 2180 IMAP4 Multi-Accessed Mailbox Practice July 1997
|
||||
|
||||
|
||||
4.2.2. If the ".SILENT" suffix is not used, and only expunged messages
|
||||
are referenced, the server SHOULD return only a tagged NO.
|
||||
|
||||
Example: (Building upon the scenario outlined in 4.1.)
|
||||
|
||||
<Client #2 tries to STORE flags only on expunged messages>
|
||||
|
||||
C2: B001 STORE 5:7 +FLAGS (\SEEN)
|
||||
S2: B001 NO Messages have been expunged
|
||||
|
||||
|
||||
4.2.3. If the ".SILENT" suffix is not used, and a mixture of expunged
|
||||
and non-expunged messages are referenced, the server MAY set the
|
||||
flags and return a FETCH response for the non-expunged messages
|
||||
along with a tagged NO.
|
||||
|
||||
After receiving a tagged NO STORE response, the client SHOULD issue a
|
||||
NOOP command so that it will be informed of any pending EXPUNGE
|
||||
responses. The client may then either reissue the failed STORE
|
||||
command, or by examining the EXPUNGE responses from the NOOP and
|
||||
FETCH responses from the STORE, determine that the STORE failed
|
||||
because of pending expunges.
|
||||
|
||||
Example: (Building upon the scenario outlined in 4.1.)
|
||||
|
||||
<Client #2 tries to STORE flags on a mixture of expunged and non-
|
||||
expunged messages>
|
||||
|
||||
C2: B001 STORE 1:7 +FLAGS (\SEEN)
|
||||
S2: * FETCH 1 FLAGS (\SEEN)
|
||||
S2: * FETCH 2 FLAGS (\SEEN)
|
||||
S2: * FETCH 3 FLAGS (\SEEN)
|
||||
S2: B001 NO Some of the messages no longer exist.
|
||||
|
||||
C2: B002 NOOP
|
||||
S2: * 4 EXPUNGE
|
||||
S2: * 4 EXPUNGE
|
||||
S2: * 4 EXPUNGE
|
||||
S2: * 4 EXPUNGE
|
||||
S2: * 3 EXISTS
|
||||
S2: B002 OK NOOP Completed.
|
||||
|
||||
<By receiving FETCH responses for messages 1:3, and an EXPUNGE
|
||||
response that indicates messages 4:7 have been expunged, the client
|
||||
does not need to re-issue the STORE>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Informational [Page 10]
|
||||
|
||||
RFC 2180 IMAP4 Multi-Accessed Mailbox Practice July 1997
|
||||
|
||||
|
||||
4.2.4. If the ".SILENT" suffix is not used, and a mixture of expunged
|
||||
and non-expunged messages are referenced, the server MAY return
|
||||
an untagged NO and not set any flags.
|
||||
|
||||
After receiving a tagged NO STORE response, the client SHOULD issue a
|
||||
NOOP command so that it will be informed of any pending EXPUNGE
|
||||
responses. The client would then re-issue the STORE command after
|
||||
updating its message list per any EXPUNGE response.
|
||||
|
||||
If a large number of clients are accessing a shared mailbox, the
|
||||
window in which there are no pending expunges may be small or non-
|
||||
existent, effectively disallowing a client from setting the flags on
|
||||
all messages at once.
|
||||
|
||||
Example: (Building upon the scenario outlined in 4.1.)
|
||||
|
||||
<Client #2 tries to STORE flags on a mixture of expunged and non-
|
||||
expunged messages>
|
||||
|
||||
C2: B001 STORE 1:7 +FLAGS (\SEEN)
|
||||
S2: B001 NO Some of the messages no longer exist.
|
||||
|
||||
<Client #2 issues a NOOP to be informed of the EXPUNGED messages>
|
||||
|
||||
C2: B002 NOOP
|
||||
S2: * 4 EXPUNGE
|
||||
S2: * 4 EXPUNGE
|
||||
S2: * 4 EXPUNGE
|
||||
S2: * 4 EXPUNGE
|
||||
S2: * 3 EXISTS
|
||||
S2: B002 OK NOOP Completed.
|
||||
|
||||
<Client #2 updates its message list and re-issues the STORE on only
|
||||
those messages that have not been expunged>
|
||||
|
||||
C2: B003 STORE 1:3 +FLAGS (\SEEN) S2: * FETCH 1 FLAGS
|
||||
(\SEEN) S2: * FETCH 2 FLAGS (\SEEN) S2: * FETCH 3 FLAGS
|
||||
(\SEEN) S2: B003 OK STORE Completed
|
||||
|
||||
|
||||
4.3. Searching of expunged messages
|
||||
|
||||
A server MAY simply not return a search response for messages that
|
||||
have been expunged and it has not been able to inform the client
|
||||
about. If a client was expecting a particular message to be returned
|
||||
in a search result, and it was not, the client SHOULD issue a NOOP
|
||||
command to see if the message was expunged by another client.
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Informational [Page 11]
|
||||
|
||||
RFC 2180 IMAP4 Multi-Accessed Mailbox Practice July 1997
|
||||
|
||||
|
||||
4.4 Copying of expunged messages
|
||||
|
||||
COPY is the only IMAP4 sequence number command that is safe to allow
|
||||
an EXPUNGE response on. This is because a client is not permitted to
|
||||
cascade several COPY commands together. A client is required to wait
|
||||
and confirm that the copy worked before issuing another one.
|
||||
|
||||
4.4.1 The server MAY disallow the COPY of messages in a multi-access
|
||||
mailbox that contains expunged messages.
|
||||
|
||||
Pending EXPUNGE response(s) MUST be returned to the COPY command.
|
||||
|
||||
Example:
|
||||
|
||||
C: A001 COPY 2,4,6,8 FRED
|
||||
S: * 4 EXPUNGE
|
||||
S: A001 NO COPY rejected, because some of the requested
|
||||
messages were expunged
|
||||
|
||||
Note: Non of the above messages are copied because if a COPY command
|
||||
is unsuccessful, the server MUST restore the destination mailbox to
|
||||
its state before the COPY attempt.
|
||||
|
||||
|
||||
4.4.2 The server MAY allow the COPY of messages in a multi-access
|
||||
mailbox that contains expunged messages.
|
||||
|
||||
Pending EXPUNGE response(s) MUST be returned to the COPY command.
|
||||
Messages that are copied are messages corresponding to sequence
|
||||
numbers before any EXPUNGE response.
|
||||
|
||||
Example:
|
||||
|
||||
C: A001 COPY 2,4,6,8 FRED
|
||||
S: * 3 EXPUNGE
|
||||
S: A001 OK COPY completed
|
||||
|
||||
In the above example, the messages that are copied to FRED are
|
||||
messages 2,4,6,8 at the start of the COPY command. These are
|
||||
equivalent to messages 2,3,5,7 at the end of the COPY command. The
|
||||
EXPUNGE response can't take place until after the messages from the
|
||||
COPY command are identified (because of the "no expunge while no
|
||||
commands in progress" rule).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Informational [Page 12]
|
||||
|
||||
RFC 2180 IMAP4 Multi-Accessed Mailbox Practice July 1997
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
C: A001 COPY 2,4,6,8 FRED
|
||||
S: * 4 EXPUNGE
|
||||
S: A001 OK COPY completed
|
||||
|
||||
In the above example, message 4 was copied before it was expunged,
|
||||
and MUST appear in the destination mailbox FRED.
|
||||
|
||||
|
||||
5. Security Considerations
|
||||
|
||||
This document describes behavior of servers that use the IMAP4
|
||||
protocol, and as such, has the same security considerations as
|
||||
described in [RFC-2060].
|
||||
|
||||
In particular, some described server behavior does not allow for the
|
||||
immediate deletion of information when a mailbox is accessed by
|
||||
multiple clients. This may be a consideration when dealing with
|
||||
sensitive information where immediate deletion would be preferred.
|
||||
|
||||
|
||||
6. References
|
||||
|
||||
[RFC-2060], Crispin, M., "Internet Message Access Protocol - Version
|
||||
4rev1", RFC 2060, University of Washington, December 1996.
|
||||
|
||||
[RFC-2119], Bradner, S., "Key words for use in RFCs to Indicate
|
||||
Requirement Levels", RFC 2119, Harvard University, March 1997.
|
||||
|
||||
|
||||
7. Acknowledgments
|
||||
|
||||
This document is the result of discussions on the IMAP4 mailing list
|
||||
and is meant to reflect consensus of this group. In particular,
|
||||
Raymond Cheng, Mark Crispin, Jim Evans, Erik Forsberg, Steve Hole,
|
||||
Mark Keasling, Barry Leiba, Syd Logan, John Mani, Pat Moran, Larry
|
||||
Osterman, Chris Newman, Bart Schaefer, Vladimir Vulovic, and Jack De
|
||||
Winter were active participants in this discussion or made
|
||||
suggestions to this document.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Informational [Page 13]
|
||||
|
||||
RFC 2180 IMAP4 Multi-Accessed Mailbox Practice July 1997
|
||||
|
||||
|
||||
8. Author's Address
|
||||
|
||||
Mike Gahrns
|
||||
Microsoft
|
||||
One Microsoft Way
|
||||
Redmond, WA, 98072
|
||||
|
||||
Phone: (206) 936-9833
|
||||
EMail: mikega@microsoft.com
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Informational [Page 14]
|
||||
|
|
@ -1,899 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group C. Newman
|
||||
Request for Comments: 2192 Innosoft
|
||||
Category: Standards Track September 1997
|
||||
|
||||
|
||||
IMAP URL Scheme
|
||||
|
||||
|
||||
Status of this memo
|
||||
|
||||
This document specifies an Internet standards track protocol for
|
||||
the Internet community, and requests discussion and suggestions for
|
||||
improvements. Please refer to the current edition of the "Internet
|
||||
Official Protocol Standards" (STD 1) for the standardization state
|
||||
and status of this protocol. Distribution of this memo is
|
||||
unlimited.
|
||||
|
||||
|
||||
Abstract
|
||||
|
||||
IMAP [IMAP4] is a rich protocol for accessing remote message
|
||||
stores. It provides an ideal mechanism for accessing public
|
||||
mailing list archives as well as private and shared message stores.
|
||||
This document defines a URL scheme for referencing objects on an
|
||||
IMAP server.
|
||||
|
||||
|
||||
1. Conventions used in this document
|
||||
|
||||
The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY"
|
||||
in this document are to be interpreted as defined in "Key words for
|
||||
use in RFCs to Indicate Requirement Levels" [KEYWORDS].
|
||||
|
||||
|
||||
2. IMAP scheme
|
||||
|
||||
The IMAP URL scheme is used to designate IMAP servers, mailboxes,
|
||||
messages, MIME bodies [MIME], and search programs on Internet hosts
|
||||
accessible using the IMAP protocol.
|
||||
|
||||
The IMAP URL follows the common Internet scheme syntax as defined
|
||||
in RFC 1738 [BASIC-URL] except that clear text passwords are not
|
||||
permitted. If :<port> is omitted, the port defaults to 143.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 1]
|
||||
|
||||
RFC 2192 IMAP URL Scheme September 1997
|
||||
|
||||
|
||||
An IMAP URL takes one of the following forms:
|
||||
|
||||
imap://<iserver>/
|
||||
imap://<iserver>/<enc_list_mailbox>;TYPE=<list_type>
|
||||
imap://<iserver>/<enc_mailbox>[uidvalidity][?<enc_search>]
|
||||
imap://<iserver>/<enc_mailbox>[uidvalidity]<iuid>[isection]
|
||||
|
||||
The first form is used to refer to an IMAP server, the second form
|
||||
refers to a list of mailboxes, the third form refers to the
|
||||
contents of a mailbox or a set of messages resulting from a search,
|
||||
and the final form refers to a specific message or message part.
|
||||
Note that the syntax here is informal. The authoritative formal
|
||||
syntax for IMAP URLs is defined in section 11.
|
||||
|
||||
|
||||
3. IMAP User Name and Authentication Mechanism
|
||||
|
||||
A user name and/or authentication mechanism may be supplied. They
|
||||
are used in the "LOGIN" or "AUTHENTICATE" commands after making the
|
||||
connection to the IMAP server. If no user name or authentication
|
||||
mechanism is supplied, the user name "anonymous" is used with the
|
||||
"LOGIN" command and the password is supplied as the Internet e-mail
|
||||
address of the end user accessing the resource. If the URL doesn't
|
||||
supply a user name, the program interpreting the IMAP URL SHOULD
|
||||
request one from the user if necessary.
|
||||
|
||||
An authentication mechanism can be expressed by adding
|
||||
";AUTH=<enc_auth_type>" to the end of the user name. When such an
|
||||
<enc_auth_type> is indicated, the client SHOULD request appropriate
|
||||
credentials from that mechanism and use the "AUTHENTICATE" command
|
||||
instead of the "LOGIN" command. If no user name is specified, one
|
||||
SHOULD be obtained from the mechanism or requested from the user as
|
||||
appropriate.
|
||||
|
||||
The string ";AUTH=*" indicates that the client SHOULD select an
|
||||
appropriate authentication mechanism. It MAY use any mechanism
|
||||
listed in the CAPABILITY command or use an out of band security
|
||||
service resulting in a PREAUTH connection. If no user name is
|
||||
specified and no appropriate authentication mechanisms are
|
||||
available, the client SHOULD fall back to anonymous login as
|
||||
described above. This allows a URL which grants read-write access
|
||||
to authorized users, and read-only anonymous access to other users.
|
||||
|
||||
If a user name is included with no authentication mechanism, then
|
||||
";AUTH=*" is assumed.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 2]
|
||||
|
||||
RFC 2192 IMAP URL Scheme September 1997
|
||||
|
||||
|
||||
Since URLs can easily come from untrusted sources, care must be
|
||||
taken when resolving a URL which requires or requests any sort of
|
||||
authentication. If authentication credentials are supplied to the
|
||||
wrong server, it may compromise the security of the user's account.
|
||||
The program resolving the URL should make sure it meets at least
|
||||
one of the following criteria in this case:
|
||||
|
||||
(1) The URL comes from a trusted source, such as a referral server
|
||||
which the client has validated and trusts according to site policy.
|
||||
Note that user entry of the URL may or may not count as a trusted
|
||||
source, depending on the experience level of the user and site
|
||||
policy.
|
||||
(2) Explicit local site policy permits the client to connect to the
|
||||
server in the URL. For example, if the client knows the site
|
||||
domain name, site policy may dictate that any hostname ending in
|
||||
that domain is trusted.
|
||||
(3) The user confirms that connecting to that domain name with the
|
||||
specified credentials and/or mechanism is permitted.
|
||||
(4) A mechanism is used which validates the server before passing
|
||||
potentially compromising client credentials.
|
||||
(5) An authentication mechanism is used which will not reveal
|
||||
information to the server which could be used to compromise future
|
||||
connections.
|
||||
|
||||
URLs which do not include a user name must be treated with extra
|
||||
care, since they are more likely to compromise the user's primary
|
||||
account. A URL containing ";AUTH=*" must also be treated with
|
||||
extra care since it might fall back on a weaker security mechanism.
|
||||
Finally, clients are discouraged from using a plain text password
|
||||
as a fallback with ";AUTH=*" unless the connection has strong
|
||||
encryption (e.g. a key length of greater than 56 bits).
|
||||
|
||||
A program interpreting IMAP URLs MAY cache open connections to an
|
||||
IMAP server for later re-use. If a URL contains a user name, only
|
||||
connections authenticated as that user may be re-used. If a URL
|
||||
does not contain a user name or authentication mechanism, then only
|
||||
an anonymous connection may be re-used. If a URL contains an
|
||||
authentication mechanism without a user name, then any non-
|
||||
anonymous connection may be re-used.
|
||||
|
||||
Note that if unsafe or reserved characters such as " " or ";" are
|
||||
present in the user name or authentication mechanism, they MUST be
|
||||
encoded as described in RFC 1738 [BASIC-URL].
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 3]
|
||||
|
||||
RFC 2192 IMAP URL Scheme September 1997
|
||||
|
||||
|
||||
4. IMAP server
|
||||
|
||||
An IMAP URL referring to an IMAP server has the following form:
|
||||
|
||||
imap://<iserver>/
|
||||
|
||||
A program interpreting this URL would issue the standard set of
|
||||
commands it uses to present a view of the contents of an IMAP
|
||||
server. This is likely to be semanticly equivalent to one of the
|
||||
following URLs:
|
||||
|
||||
imap://<iserver>/;TYPE=LIST
|
||||
imap://<iserver>/;TYPE=LSUB
|
||||
|
||||
The program interpreting this URL SHOULD use the LSUB form if it
|
||||
supports mailbox subscriptions.
|
||||
|
||||
|
||||
5. Lists of mailboxes
|
||||
|
||||
An IMAP URL referring to a list of mailboxes has the following
|
||||
form:
|
||||
|
||||
imap://<iserver>/<enc_list_mailbox>;TYPE=<list_type>
|
||||
|
||||
The <list_type> may be either "LIST" or "LSUB", and is case
|
||||
insensitive. The field ";TYPE=<list_type>" MUST be included.
|
||||
|
||||
The <enc_list_mailbox> is any argument suitable for the
|
||||
list_mailbox field of the IMAP [IMAP4] LIST or LSUB commands. The
|
||||
field <enc_list_mailbox> may be omitted, in which case the program
|
||||
interpreting the IMAP URL may use "*" or "%" as the
|
||||
<enc_list_mailbox>. The program SHOULD use "%" if it supports a
|
||||
hierarchical view, otherwise it SHOULD use "*".
|
||||
|
||||
Note that if unsafe or reserved characters such as " " or "%" are
|
||||
present in <enc_list_mailbox> they MUST be encoded as described in
|
||||
RFC 1738 [BASIC-URL]. If the character "/" is present in
|
||||
enc_list_mailbox, it SHOULD NOT be encoded.
|
||||
|
||||
|
||||
6. Lists of messages
|
||||
|
||||
An IMAP URL referring to a list of messages has the following form:
|
||||
|
||||
imap://<iserver>/<enc_mailbox>[uidvalidity][?<enc_search>]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 4]
|
||||
|
||||
RFC 2192 IMAP URL Scheme September 1997
|
||||
|
||||
|
||||
The <enc_mailbox> field is used as the argument to the IMAP4
|
||||
"SELECT" command. Note that if unsafe or reserved characters such
|
||||
as " ", ";", or "?" are present in <enc_mailbox> they MUST be
|
||||
encoded as described in RFC 1738 [BASIC-URL]. If the character "/"
|
||||
is present in enc_mailbox, it SHOULD NOT be encoded.
|
||||
|
||||
The [uidvalidity] field is optional. If it is present, it MUST be
|
||||
the argument to the IMAP4 UIDVALIDITY status response at the time
|
||||
the URL was created. This SHOULD be used by the program
|
||||
interpreting the IMAP URL to determine if the URL is stale.
|
||||
|
||||
The [?<enc_search>] field is optional. If it is not present, the
|
||||
contents of the mailbox SHOULD be presented by the program
|
||||
interpreting the URL. If it is present, it SHOULD be used as the
|
||||
arguments following an IMAP4 SEARCH command with unsafe characters
|
||||
such as " " (which are likely to be present in the <enc_search>)
|
||||
encoded as described in RFC 1738 [BASIC-URL].
|
||||
|
||||
|
||||
7. A specific message or message part
|
||||
|
||||
An IMAP URL referring to a specific message or message part has the
|
||||
following form:
|
||||
|
||||
imap://<iserver>/<enc_mailbox>[uidvalidity]<iuid>[isection]
|
||||
|
||||
The <enc_mailbox> and [uidvalidity] are as defined above.
|
||||
|
||||
If [uidvalidity] is present in this form, it SHOULD be used by the
|
||||
program interpreting the URL to determine if the URL is stale.
|
||||
|
||||
The <iuid> refers to an IMAP4 message UID, and SHOULD be used as
|
||||
the <set> argument to the IMAP4 "UID FETCH" command.
|
||||
|
||||
The [isection] field is optional. If not present, the URL refers
|
||||
to the entire Internet message as returned by the IMAP command "UID
|
||||
FETCH <uid> BODY.PEEK[]". If present, the URL refers to the object
|
||||
returned by a "UID FETCH <uid> BODY.PEEK[<section>]" command. The
|
||||
type of the object may be determined with a "UID FETCH <uid>
|
||||
BODYSTRUCTURE" command and locating the appropriate part in the
|
||||
resulting BODYSTRUCTURE. Note that unsafe characters in [isection]
|
||||
MUST be encoded as described in [BASIC-URL].
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 5]
|
||||
|
||||
RFC 2192 IMAP URL Scheme September 1997
|
||||
|
||||
|
||||
8. Relative IMAP URLs
|
||||
|
||||
Relative IMAP URLs are permitted and are resolved according to the
|
||||
rules defined in RFC 1808 [REL-URL] with one exception. In IMAP
|
||||
URLs, parameters are treated as part of the normal path with
|
||||
respect to relative URL resolution. This is believed to be the
|
||||
behavior of the installed base and is likely to be documented in a
|
||||
future revision of the relative URL specification.
|
||||
|
||||
The following observations are also important:
|
||||
|
||||
The <iauth> grammar element is considered part of the user name for
|
||||
purposes of resolving relative IMAP URLs. This means that unless a
|
||||
new login/server specification is included in the relative URL, the
|
||||
authentication mechanism is inherited from a base IMAP URL.
|
||||
|
||||
URLs always use "/" as the hierarchy delimiter for the purpose of
|
||||
resolving paths in relative URLs. IMAP4 permits the use of any
|
||||
hierarchy delimiter in mailbox names. For this reason, relative
|
||||
mailbox paths will only work if the mailbox uses "/" as the
|
||||
hierarchy delimiter. Relative URLs may be used on mailboxes which
|
||||
use other delimiters, but in that case, the entire mailbox name
|
||||
MUST be specified in the relative URL or inherited as a whole from
|
||||
the base URL.
|
||||
|
||||
The base URL for a list of mailboxes or messages which was referred
|
||||
to by an IMAP URL is always the referring IMAP URL itself. The
|
||||
base URL for a message or message part which was referred to by an
|
||||
IMAP URL may be more complicated to determine. The program
|
||||
interpreting the relative URL will have to check the headers of the
|
||||
MIME entity and any enclosing MIME entities in order to locate the
|
||||
"Content-Base" and "Content-Location" headers. These headers are
|
||||
used to determine the base URL as defined in [HTTP]. For example,
|
||||
if the referring IMAP URL contains a "/;SECTION=1.2" parameter,
|
||||
then the MIME headers for section 1.2, for section 1, and for the
|
||||
enclosing message itself SHOULD be checked in that order for
|
||||
"Content-Base" or "Content-Location" headers.
|
||||
|
||||
|
||||
9. Multinational Considerations
|
||||
|
||||
IMAP4 [IMAP4] section 5.1.3 includes a convention for encoding
|
||||
non-US-ASCII characters in IMAP mailbox names. Because this
|
||||
convention is private to IMAP, it is necessary to convert IMAP's
|
||||
encoding to one that can be more easily interpreted by a URL
|
||||
display program. For this reason, IMAP's modified UTF-7 encoding
|
||||
for mailboxes MUST be converted to UTF-8 [UTF8]. Since 8-bit
|
||||
characters are not permitted in URLs, the UTF-8 characters are
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 6]
|
||||
|
||||
RFC 2192 IMAP URL Scheme September 1997
|
||||
|
||||
|
||||
encoded as required by the URL specification [BASIC-URL]. Sample
|
||||
code is included in Appendix A to demonstrate this conversion.
|
||||
|
||||
|
||||
10. Examples
|
||||
|
||||
The following examples demonstrate how an IMAP4 client program
|
||||
might translate various IMAP4 URLs into a series of IMAP4 commands.
|
||||
Commands sent from the client to the server are prefixed with "C:",
|
||||
and responses sent from the server to the client are prefixed with
|
||||
"S:".
|
||||
|
||||
The URL:
|
||||
|
||||
<imap://minbari.org/gray-council;UIDVALIDITY=385759045/;UID=20>
|
||||
|
||||
Results in the following client commands:
|
||||
|
||||
<connect to minbari.org, port 143>
|
||||
C: A001 LOGIN ANONYMOUS sheridan@babylon5.org
|
||||
C: A002 SELECT gray-council
|
||||
<client verifies the UIDVALIDITY matches>
|
||||
C: A003 UID FETCH 20 BODY.PEEK[]
|
||||
|
||||
The URL:
|
||||
|
||||
<imap://michael@minbari.org/users.*;type=list>
|
||||
|
||||
Results in the following client commands:
|
||||
|
||||
<client requests password from user>
|
||||
<connect to minbari.org imap server, activate strong encryption>
|
||||
C: A001 LOGIN MICHAEL zipper
|
||||
C: A002 LIST "" users.*
|
||||
|
||||
The URL:
|
||||
|
||||
<imap://psicorp.org/~peter/%E6%97%A5%E6%9C%AC%E8%AA%9E/
|
||||
%E5%8F%B0%E5%8C%97>
|
||||
|
||||
Results in the following client commands:
|
||||
|
||||
<connect to psicorp.org, port 143>
|
||||
C: A001 LOGIN ANONYMOUS bester@psycop.psicorp.org
|
||||
C: A002 SELECT ~peter/&ZeVnLIqe-/&U,BTFw-
|
||||
<commands the client uses for viewing the contents of a mailbox>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 7]
|
||||
|
||||
RFC 2192 IMAP URL Scheme September 1997
|
||||
|
||||
|
||||
The URL:
|
||||
|
||||
<imap://;AUTH=KERBEROS_V4@minbari.org/gray-council/;uid=20/
|
||||
;section=1.2>
|
||||
|
||||
Results in the following client commands:
|
||||
|
||||
<connect to minbari.org, port 143>
|
||||
C: A001 AUTHENTICATE KERBEROS_V4
|
||||
<authentication exchange>
|
||||
C: A002 SELECT gray-council
|
||||
C: A003 UID FETCH 20 BODY.PEEK[1.2]
|
||||
|
||||
If the following relative URL is located in that body part:
|
||||
|
||||
<;section=1.4>
|
||||
|
||||
This could result in the following client commands:
|
||||
|
||||
C: A004 UID FETCH 20 (BODY.PEEK[1.2.MIME]
|
||||
BODY.PEEK[1.MIME]
|
||||
BODY.PEEK[HEADER.FIELDS (Content-Base Content-Location)])
|
||||
<Client looks for Content-Base or Content-Location headers in
|
||||
result. If no such headers, then it does the following>
|
||||
C: A005 UID FETCH 20 BODY.PEEK[1.4]
|
||||
|
||||
The URL:
|
||||
|
||||
<imap://;AUTH=*@minbari.org/gray%20council?SUBJECT%20shadows>
|
||||
|
||||
Could result in the following:
|
||||
|
||||
<connect to minbari.org, port 143>
|
||||
C: A001 CAPABILITY
|
||||
S: * CAPABILITY IMAP4rev1 AUTH=GSSAPI
|
||||
S: A001 OK
|
||||
C: A002 AUTHENTICATE GSSAPI
|
||||
<authentication exchange>
|
||||
S: A002 OK user lennier authenticated
|
||||
C: A003 SELECT "gray council"
|
||||
...
|
||||
C: A004 SEARCH SUBJECT shadows
|
||||
S: * SEARCH 8 10 13 14 15 16
|
||||
S: A004 OK SEARCH completed
|
||||
C: A005 FETCH 8,10,13:16 ALL
|
||||
...
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 8]
|
||||
|
||||
RFC 2192 IMAP URL Scheme September 1997
|
||||
|
||||
|
||||
NOTE: In this final example, the client has implementation
|
||||
dependent choices. The authentication mechanism could be anything,
|
||||
including PREAUTH. And the final FETCH command could fetch more or
|
||||
less information about the messages, depending on what it wishes to
|
||||
display to the user.
|
||||
|
||||
|
||||
11. Security Considerations
|
||||
|
||||
Security considerations discussed in the IMAP specification [IMAP4]
|
||||
and the URL specification [BASIC-URL] are relevant. Security
|
||||
considerations related to authenticated URLs are discussed in
|
||||
section 3 of this document.
|
||||
|
||||
Many email clients store the plain text password for later use
|
||||
after logging into an IMAP server. Such clients MUST NOT use a
|
||||
stored password in response to an IMAP URL without explicit
|
||||
permission from the user to supply that password to the specified
|
||||
host name.
|
||||
|
||||
|
||||
12. ABNF for IMAP URL scheme
|
||||
|
||||
This uses ABNF as defined in RFC 822 [IMAIL]. Terminals from the
|
||||
BNF for IMAP [IMAP4] and URLs [BASIC-URL] are also used. Strings
|
||||
are not case sensitive and free insertion of linear-white-space is
|
||||
not permitted.
|
||||
|
||||
achar = uchar / "&" / "=" / "~"
|
||||
; see [BASIC-URL] for "uchar" definition
|
||||
|
||||
bchar = achar / ":" / "@" / "/"
|
||||
|
||||
enc_auth_type = 1*achar
|
||||
; encoded version of [IMAP-AUTH] "auth_type"
|
||||
|
||||
enc_list_mailbox = 1*bchar
|
||||
; encoded version of [IMAP4] "list_mailbox"
|
||||
|
||||
enc_mailbox = 1*bchar
|
||||
; encoded version of [IMAP4] "mailbox"
|
||||
|
||||
enc_search = 1*bchar
|
||||
; encoded version of search_program below
|
||||
|
||||
enc_section = 1*bchar
|
||||
; encoded version of section below
|
||||
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 9]
|
||||
|
||||
RFC 2192 IMAP URL Scheme September 1997
|
||||
|
||||
|
||||
enc_user = 1*achar
|
||||
; encoded version of [IMAP4] "userid"
|
||||
|
||||
imapurl = "imap://" iserver "/" [ icommand ]
|
||||
|
||||
iauth = ";AUTH=" ( "*" / enc_auth_type )
|
||||
|
||||
icommand = imailboxlist / imessagelist / imessagepart
|
||||
|
||||
imailboxlist = [enc_list_mailbox] ";TYPE=" list_type
|
||||
|
||||
imessagelist = enc_mailbox [ "?" enc_search ] [uidvalidity]
|
||||
|
||||
imessagepart = enc_mailbox [uidvalidity] iuid [isection]
|
||||
|
||||
isection = "/;SECTION=" enc_section
|
||||
|
||||
iserver = [iuserauth "@"] hostport
|
||||
; See [BASIC-URL] for "hostport" definition
|
||||
|
||||
iuid = "/;UID=" nz_number
|
||||
; See [IMAP4] for "nz_number" definition
|
||||
|
||||
iuserauth = enc_user [iauth] / [enc_user] iauth
|
||||
|
||||
list_type = "LIST" / "LSUB"
|
||||
|
||||
search_program = ["CHARSET" SPACE astring SPACE]
|
||||
search_key *(SPACE search_key)
|
||||
; IMAP4 literals may not be used
|
||||
; See [IMAP4] for "astring" and "search_key"
|
||||
|
||||
section = section_text / (nz_number *["." nz_number]
|
||||
["." (section_text / "MIME")])
|
||||
; See [IMAP4] for "section_text" and "nz_number"
|
||||
|
||||
uidvalidity = ";UIDVALIDITY=" nz_number
|
||||
; See [IMAP4] for "nz_number" definition
|
||||
|
||||
13. References
|
||||
|
||||
[BASIC-URL] Berners-Lee, Masinter, McCahill, "Uniform Resource
|
||||
Locators (URL)", RFC 1738, CERN, Xerox Corporation, University of
|
||||
Minnesota, December 1994.
|
||||
|
||||
<ftp://ds.internic.net/rfc/rfc1738.txt>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 10]
|
||||
|
||||
RFC 2192 IMAP URL Scheme September 1997
|
||||
|
||||
|
||||
[IMAP4] Crispin, M., "Internet Message Access Protocol - Version
|
||||
4rev1", RFC 2060, University of Washington, December 1996.
|
||||
|
||||
<ftp://ds.internic.net/rfc/rfc2060.txt>
|
||||
|
||||
[IMAP-AUTH] Myers, J., "IMAP4 Authentication Mechanism", RFC 1731,
|
||||
Carnegie-Mellon University, December 1994.
|
||||
|
||||
<ftp://ds.internic.net/rfc/rfc1731.txt>
|
||||
|
||||
[HTTP] Fielding, Gettys, Mogul, Frystyk, Berners-Lee, "Hypertext
|
||||
Transfer Protocol -- HTTP/1.1", RFC 2068, UC Irvine, DEC, MIT/LCS,
|
||||
January 1997.
|
||||
|
||||
<ftp://ds.internic.net/rfc/rfc2068.txt>
|
||||
|
||||
[IMAIL] Crocker, "Standard for the Format of ARPA Internet Text
|
||||
Messages", STD 11, RFC 822, University of Delaware, August 1982.
|
||||
|
||||
<ftp://ds.internic.net/rfc/rfc822.txt>
|
||||
|
||||
[KEYWORDS] Bradner, "Key words for use in RFCs to Indicate
|
||||
Requirement Levels", RFC 2119, Harvard University, March 1997.
|
||||
|
||||
<ftp://ds.internic.net/rfc/rfc2119.txt>
|
||||
|
||||
[MIME] Freed, N., Borenstein, N., "Multipurpose Internet Mail
|
||||
Extensions", RFC 2045, Innosoft, First Virtual, November 1996.
|
||||
|
||||
<ftp://ds.internic.net/rfc/rfc2045.txt>
|
||||
|
||||
[REL-URL] Fielding, "Relative Uniform Resource Locators", RFC 1808,
|
||||
UC Irvine, June 1995.
|
||||
|
||||
<ftp://ds.internic.net/rfc/rfc1808.txt>
|
||||
|
||||
[UTF8] Yergeau, F. "UTF-8, a transformation format of Unicode and
|
||||
ISO 10646", RFC 2044, Alis Technologies, October 1996.
|
||||
|
||||
<ftp://ds.internic.net/rfc/rfc2044.txt>
|
||||
|
||||
14. Author's Address
|
||||
|
||||
Chris Newman
|
||||
Innosoft International, Inc.
|
||||
1050 Lakes Drive
|
||||
West Covina, CA 91790 USA
|
||||
EMail: chris.newman@innosoft.com
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 11]
|
||||
|
||||
RFC 2192 IMAP URL Scheme September 1997
|
||||
|
||||
|
||||
Appendix A. Sample code
|
||||
|
||||
Here is sample C source code to convert between URL paths and IMAP
|
||||
mailbox names, taking into account mapping between IMAP's modified UTF-7
|
||||
[IMAP4] and hex-encoded UTF-8 which is more appropriate for URLs. This
|
||||
code has not been rigorously tested nor does it necessarily behave
|
||||
reasonably with invalid input, but it should serve as a useful example.
|
||||
This code just converts the mailbox portion of the URL and does not deal
|
||||
with parameters, query or server components of the URL.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* hexadecimal lookup table */
|
||||
static char hex[] = "0123456789ABCDEF";
|
||||
|
||||
/* URL unsafe printable characters */
|
||||
static char urlunsafe[] = " \"#%&+:;<=>?@[\\]^`{|}";
|
||||
|
||||
/* UTF7 modified base64 alphabet */
|
||||
static char base64chars[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
|
||||
#define UNDEFINED 64
|
||||
|
||||
/* UTF16 definitions */
|
||||
#define UTF16MASK 0x03FFUL
|
||||
#define UTF16SHIFT 10
|
||||
#define UTF16BASE 0x10000UL
|
||||
#define UTF16HIGHSTART 0xD800UL
|
||||
#define UTF16HIGHEND 0xDBFFUL
|
||||
#define UTF16LOSTART 0xDC00UL
|
||||
#define UTF16LOEND 0xDFFFUL
|
||||
|
||||
/* Convert an IMAP mailbox to a URL path
|
||||
* dst needs to have roughly 4 times the storage space of src
|
||||
* Hex encoding can triple the size of the input
|
||||
* UTF-7 can be slightly denser than UTF-8
|
||||
* (worst case: 8 octets UTF-7 becomes 9 octets UTF-8)
|
||||
*/
|
||||
void MailboxToURL(char *dst, char *src)
|
||||
{
|
||||
unsigned char c, i, bitcount;
|
||||
unsigned long ucs4, utf16, bitbuf;
|
||||
unsigned char base64[256], utf8[6];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 12]
|
||||
|
||||
RFC 2192 IMAP URL Scheme September 1997
|
||||
|
||||
|
||||
/* initialize modified base64 decoding table */
|
||||
memset(base64, UNDEFINED, sizeof (base64));
|
||||
for (i = 0; i < sizeof (base64chars); ++i) {
|
||||
base64[base64chars[i]] = i;
|
||||
}
|
||||
|
||||
/* loop until end of string */
|
||||
while (*src != '\0') {
|
||||
c = *src++;
|
||||
/* deal with literal characters and &- */
|
||||
if (c != '&' || *src == '-') {
|
||||
if (c < ' ' || c > '~' || strchr(urlunsafe, c) != NULL) {
|
||||
/* hex encode if necessary */
|
||||
dst[0] = '%';
|
||||
dst[1] = hex[c >> 4];
|
||||
dst[2] = hex[c & 0x0f];
|
||||
dst += 3;
|
||||
} else {
|
||||
/* encode literally */
|
||||
*dst++ = c;
|
||||
}
|
||||
/* skip over the '-' if this is an &- sequence */
|
||||
if (c == '&') ++src;
|
||||
} else {
|
||||
/* convert modified UTF-7 -> UTF-16 -> UCS-4 -> UTF-8 -> HEX */
|
||||
bitbuf = 0;
|
||||
bitcount = 0;
|
||||
ucs4 = 0;
|
||||
while ((c = base64[(unsigned char) *src]) != UNDEFINED) {
|
||||
++src;
|
||||
bitbuf = (bitbuf << 6) | c;
|
||||
bitcount += 6;
|
||||
/* enough bits for a UTF-16 character? */
|
||||
if (bitcount >= 16) {
|
||||
bitcount -= 16;
|
||||
utf16 = (bitcount ? bitbuf >> bitcount
|
||||
: bitbuf) & 0xffff;
|
||||
/* convert UTF16 to UCS4 */
|
||||
if
|
||||
(utf16 >= UTF16HIGHSTART && utf16 <= UTF16HIGHEND) {
|
||||
ucs4 = (utf16 - UTF16HIGHSTART) << UTF16SHIFT;
|
||||
continue;
|
||||
} else if
|
||||
(utf16 >= UTF16LOSTART && utf16 <= UTF16LOEND) {
|
||||
ucs4 += utf16 - UTF16LOSTART + UTF16BASE;
|
||||
} else {
|
||||
ucs4 = utf16;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 13]
|
||||
|
||||
RFC 2192 IMAP URL Scheme September 1997
|
||||
|
||||
|
||||
/* convert UTF-16 range of UCS4 to UTF-8 */
|
||||
if (ucs4 <= 0x7fUL) {
|
||||
utf8[0] = ucs4;
|
||||
i = 1;
|
||||
} else if (ucs4 <= 0x7ffUL) {
|
||||
utf8[0] = 0xc0 | (ucs4 >> 6);
|
||||
utf8[1] = 0x80 | (ucs4 & 0x3f);
|
||||
i = 2;
|
||||
} else if (ucs4 <= 0xffffUL) {
|
||||
utf8[0] = 0xe0 | (ucs4 >> 12);
|
||||
utf8[1] = 0x80 | ((ucs4 >> 6) & 0x3f);
|
||||
utf8[2] = 0x80 | (ucs4 & 0x3f);
|
||||
i = 3;
|
||||
} else {
|
||||
utf8[0] = 0xf0 | (ucs4 >> 18);
|
||||
utf8[1] = 0x80 | ((ucs4 >> 12) & 0x3f);
|
||||
utf8[2] = 0x80 | ((ucs4 >> 6) & 0x3f);
|
||||
utf8[3] = 0x80 | (ucs4 & 0x3f);
|
||||
i = 4;
|
||||
}
|
||||
/* convert utf8 to hex */
|
||||
for (c = 0; c < i; ++c) {
|
||||
dst[0] = '%';
|
||||
dst[1] = hex[utf8[c] >> 4];
|
||||
dst[2] = hex[utf8[c] & 0x0f];
|
||||
dst += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* skip over trailing '-' in modified UTF-7 encoding */
|
||||
if (*src == '-') ++src;
|
||||
}
|
||||
}
|
||||
/* terminate destination string */
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
/* Convert hex coded UTF-8 URL path to modified UTF-7 IMAP mailbox
|
||||
* dst should be about twice the length of src to deal with non-hex
|
||||
* coded URLs
|
||||
*/
|
||||
void URLtoMailbox(char *dst, char *src)
|
||||
{
|
||||
unsigned int utf8pos, utf8total, i, c, utf7mode, bitstogo, utf16flag;
|
||||
unsigned long ucs4, bitbuf;
|
||||
unsigned char hextab[256];
|
||||
|
||||
/* initialize hex lookup table */
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 14]
|
||||
|
||||
RFC 2192 IMAP URL Scheme September 1997
|
||||
|
||||
|
||||
memset(hextab, 0, sizeof (hextab));
|
||||
for (i = 0; i < sizeof (hex); ++i) {
|
||||
hextab[hex[i]] = i;
|
||||
if (isupper(hex[i])) hextab[tolower(hex[i])] = i;
|
||||
}
|
||||
|
||||
utf7mode = 0;
|
||||
utf8total = 0;
|
||||
bitstogo = 0;
|
||||
while ((c = *src) != '\0') {
|
||||
++src;
|
||||
/* undo hex-encoding */
|
||||
if (c == '%' && src[0] != '\0' && src[1] != '\0') {
|
||||
c = (hextab[src[0]] << 4) | hextab[src[1]];
|
||||
src += 2;
|
||||
}
|
||||
/* normal character? */
|
||||
if (c >= ' ' && c <= '~') {
|
||||
/* switch out of UTF-7 mode */
|
||||
if (utf7mode) {
|
||||
if (bitstogo) {
|
||||
*dst++ = base64chars[(bitbuf << (6 - bitstogo)) & 0x3F];
|
||||
}
|
||||
*dst++ = '-';
|
||||
utf7mode = 0;
|
||||
}
|
||||
*dst++ = c;
|
||||
/* encode '&' as '&-' */
|
||||
if (c == '&') {
|
||||
*dst++ = '-';
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* switch to UTF-7 mode */
|
||||
if (!utf7mode) {
|
||||
*dst++ = '&';
|
||||
utf7mode = 1;
|
||||
}
|
||||
/* Encode US-ASCII characters as themselves */
|
||||
if (c < 0x80) {
|
||||
ucs4 = c;
|
||||
utf8total = 1;
|
||||
} else if (utf8total) {
|
||||
/* save UTF8 bits into UCS4 */
|
||||
ucs4 = (ucs4 << 6) | (c & 0x3FUL);
|
||||
if (++utf8pos < utf8total) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 15]
|
||||
|
||||
RFC 2192 IMAP URL Scheme September 1997
|
||||
|
||||
|
||||
} else {
|
||||
utf8pos = 1;
|
||||
if (c < 0xE0) {
|
||||
utf8total = 2;
|
||||
ucs4 = c & 0x1F;
|
||||
} else if (c < 0xF0) {
|
||||
utf8total = 3;
|
||||
ucs4 = c & 0x0F;
|
||||
} else {
|
||||
/* NOTE: can't convert UTF8 sequences longer than 4 */
|
||||
utf8total = 4;
|
||||
ucs4 = c & 0x03;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* loop to split ucs4 into two utf16 chars if necessary */
|
||||
utf8total = 0;
|
||||
do {
|
||||
if (ucs4 >= UTF16BASE) {
|
||||
ucs4 -= UTF16BASE;
|
||||
bitbuf = (bitbuf << 16) | ((ucs4 >> UTF16SHIFT)
|
||||
+ UTF16HIGHSTART);
|
||||
ucs4 = (ucs4 & UTF16MASK) + UTF16LOSTART;
|
||||
utf16flag = 1;
|
||||
} else {
|
||||
bitbuf = (bitbuf << 16) | ucs4;
|
||||
utf16flag = 0;
|
||||
}
|
||||
bitstogo += 16;
|
||||
/* spew out base64 */
|
||||
while (bitstogo >= 6) {
|
||||
bitstogo -= 6;
|
||||
*dst++ = base64chars[(bitstogo ? (bitbuf >> bitstogo)
|
||||
: bitbuf)
|
||||
& 0x3F];
|
||||
}
|
||||
} while (utf16flag);
|
||||
}
|
||||
/* if in UTF-7 mode, finish in ASCII */
|
||||
if (utf7mode) {
|
||||
if (bitstogo) {
|
||||
*dst++ = base64chars[(bitbuf << (6 - bitstogo)) & 0x3F];
|
||||
}
|
||||
*dst++ = '-';
|
||||
}
|
||||
/* tie off string */
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 16]
|
||||
|
|
@ -1,507 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group M. Gahrns
|
||||
Request for Comments: 2193 Microsoft
|
||||
Category: Standards Track September 1997
|
||||
|
||||
|
||||
IMAP4 Mailbox Referrals
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This document specifies an Internet standards track protocol for the
|
||||
Internet community, and requests discussion and suggestions for
|
||||
improvements. Please refer to the current edition of the "Internet
|
||||
Official Protocol Standards" (STD 1) for the standardization state
|
||||
and status of this protocol. Distribution of this memo is unlimited.
|
||||
|
||||
1. Abstract
|
||||
|
||||
When dealing with large amounts of users, messages and geographically
|
||||
dispersed IMAP4 [RFC-2060] servers, it is often desirable to
|
||||
distribute messages amongst different servers within an organization.
|
||||
For example an administrator may choose to store user's personal
|
||||
mailboxes on a local IMAP4 server, while storing shared mailboxes
|
||||
remotely on another server. This type of configuration is common
|
||||
when it is uneconomical to store all data centrally due to limited
|
||||
bandwidth or disk resources.
|
||||
|
||||
Mailbox referrals allow clients to seamlessly access mailboxes that
|
||||
are distributed across several IMAP4 servers.
|
||||
|
||||
A referral mechanism can provide efficiencies over the alternative
|
||||
"proxy method", in which the local IMAP4 server contacts the remote
|
||||
server on behalf of the client, and then transfers the data from the
|
||||
remote server to itself, and then on to the client. The referral
|
||||
mechanism's direct client connection to the remote server is often a
|
||||
more efficient use of bandwidth, and does not require the local
|
||||
server to impersonate the client when authenticating to the remote
|
||||
server.
|
||||
|
||||
2. Conventions used in this document
|
||||
|
||||
In examples, "C:" and "S:" indicate lines sent by the client and
|
||||
server respectively.
|
||||
|
||||
A home server, is an IMAP4 server that contains the user's inbox.
|
||||
|
||||
A remote mailbox is a mailbox that is not hosted on the user's home
|
||||
server.
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Standards Track [Page 1]
|
||||
|
||||
RFC 2193 IMAP4 Mailbox Referrals September 1997
|
||||
|
||||
|
||||
A remote server is a server that contains remote mailboxes.
|
||||
|
||||
A shared mailbox, is a mailbox that multiple users have access to.
|
||||
|
||||
An IMAP mailbox referral is when the server directs the client to
|
||||
another IMAP mailbox.
|
||||
|
||||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
|
||||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
|
||||
document are to be interpreted as described in [RFC-2119].
|
||||
|
||||
3. Introduction and Overview
|
||||
|
||||
IMAP4 servers that support this extension MUST list the keyword
|
||||
MAILBOX-REFERRALS in their CAPABILITY response. No client action is
|
||||
needed to invoke the MAILBOX-REFERRALS capability in a server.
|
||||
|
||||
A MAILBOX-REFERRALS capable IMAP4 server MUST NOT return referrals
|
||||
that result in a referrals loop.
|
||||
|
||||
A referral response consists of a tagged NO response and a REFERRAL
|
||||
response code. The REFERRAL response code MUST contain as an
|
||||
argument a one or more valid URLs separated by a space as defined in
|
||||
[RFC-1738]. If a server replies with multiple URLs for a particular
|
||||
object, they MUST all be of the same type. In this case, the URL MUST
|
||||
be an IMAP URL as defined in [RFC-2192]. A client that supports the
|
||||
REFERRALS extension MUST be prepared for a URL of any type, but it
|
||||
need only be able to process IMAP URLs.
|
||||
|
||||
A server MAY respond with multiple IMAP mailbox referrals if there is
|
||||
more than one replica of the mailbox. This allows the implementation
|
||||
of a load balancing or failover scheme. How a server keeps multiple
|
||||
replicas of a mailbox in sync is not addressed by this document.
|
||||
|
||||
If the server has a preferred order in which the client should
|
||||
attempt to access the URLs, the preferred URL SHOULD be listed in the
|
||||
first, with the remaining URLs presented in descending order of
|
||||
preference. If multiple referrals are given for a mailbox, a server
|
||||
should be aware that there are synchronization issues for a client if
|
||||
the UIDVALIDITY of the referred mailboxes are different.
|
||||
|
||||
An IMAP mailbox referral may be given in response to an IMAP command
|
||||
that specifies a mailbox as an argument.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Standards Track [Page 2]
|
||||
|
||||
RFC 2193 IMAP4 Mailbox Referrals September 1997
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
A001 NO [REFERRAL IMAP://user;AUTH=*@SERVER2/REMOTE]Remote Mailbox
|
||||
|
||||
NOTE: user;AUTH=* is specified as required by [RFC-2192] to avoid a
|
||||
client falling back to anonymous login.
|
||||
|
||||
Remote mailboxes and their inferiors, that are accessible only via
|
||||
referrals SHOULD NOT appear in LIST and LSUB responses issued against
|
||||
the user's home server. They MUST appear in RLIST and RLSUB
|
||||
responses issued against the user's home server. Hierarchy referrals,
|
||||
in which a client would be required to connect to the remote server
|
||||
to issue a LIST to discover the inferiors of a mailbox are not
|
||||
addressed in this document.
|
||||
|
||||
For example, if shared mailboxes were only accessible via referrals
|
||||
on a remote server, a RLIST "" "#SHARED/%" command would return the
|
||||
same response if issued against the user's home server or the remote
|
||||
server.
|
||||
|
||||
Note: Mailboxes that are available on the user's home server do not
|
||||
need to be available on the remote server. In addition, there may be
|
||||
additional mailboxes available on the remote server, but they will
|
||||
not accessible to the client via referrals unless they appear in the
|
||||
LIST response to the RLIST command against the user's home server.
|
||||
|
||||
A MAILBOX-REFERRALS capable client will issue the RLIST and RLSUB
|
||||
commands in lieu of LIST and LSUB. The RLIST and RLSUB commands
|
||||
behave identically to their LIST and LSUB counterparts, except remote
|
||||
mailboxes are returned in addition to local mailboxes in the LIST and
|
||||
LSUB responses. This avoids displaying to a non MAILBOX-REFERRALS
|
||||
enabled client inaccessible remote mailboxes.
|
||||
|
||||
4.1. SELECT, EXAMINE, DELETE, SUBSCRIBE, UNSUBSCRIBE, STATUS and APPEND
|
||||
Referrals
|
||||
|
||||
An IMAP4 server MAY respond to the SELECT, EXAMINE, DELETE,
|
||||
SUBSCRIBE, UNSUBSCRIBE, STATUS or APPEND command with one or more
|
||||
IMAP mailbox referrals to indicate to the client that the mailbox is
|
||||
hosted on a remote server.
|
||||
|
||||
When a client processes an IMAP mailbox referral, it will open a new
|
||||
connection or use an existing connection to the remote server so that
|
||||
it is able to issue the commands necessary to process the remote
|
||||
mailbox.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Standards Track [Page 3]
|
||||
|
||||
RFC 2193 IMAP4 Mailbox Referrals September 1997
|
||||
|
||||
|
||||
Example: <IMAP4 connection to home server>
|
||||
|
||||
C: A001 DELETE "SHARED/FOO"
|
||||
S: A001 NO [REFERRAL IMAP://user;AUTH=*@SERVER2/SHARED/FOO]
|
||||
Remote mailbox. Try SERVER2.
|
||||
|
||||
<Client established a second connection to SERVER2 and
|
||||
issues the DELETE command on the referred mailbox>
|
||||
|
||||
S: * OK IMAP4rev1 server ready
|
||||
C: B001 AUTHENTICATE KERBEROS_V4
|
||||
<authentication exchange>
|
||||
S: B001 OK user is authenticated
|
||||
|
||||
C: B002 DELETE "SHARED/FOO"
|
||||
S: B002 OK DELETE completed
|
||||
|
||||
Example: <IMAP4 connection to home server>
|
||||
|
||||
C: A001 SELECT REMOTE
|
||||
S: A001 NO [REFERRAL IMAP://user;AUTH=*@SERVER2/REMOTE
|
||||
IMAP://user;AUTH=*@SERVER3/REMOTE] Remote mailbox.
|
||||
Try SERVER2 or SERVER3.
|
||||
|
||||
<Client opens second connection to remote server, and
|
||||
issues the commands needed to process the items in the
|
||||
remote mailbox>
|
||||
|
||||
S: * OK IMAP4rev1 server ready
|
||||
C: B001 AUTHENTICATE KERBEROS_V4
|
||||
<authentication exchange>
|
||||
S: B001 OK user is authenticated
|
||||
|
||||
C: B002 SELECT REMOTE
|
||||
S: * 12 EXISTS
|
||||
S: * 1 RECENT
|
||||
S: * OK [UNSEEN 10] Message 10 is first unseen
|
||||
S: * OK [UIDVALIDITY 123456789]
|
||||
S: * FLAGS (Answered Flagged Deleted Seen Draft)
|
||||
S: * OK [PERMANENTFLAGS (Answered Deleted Seen ]
|
||||
S: B002 OK [READ-WRITE] Selected completed
|
||||
|
||||
C: B003 FETCH 10:12 RFC822
|
||||
S: * 10 FETCH . . .
|
||||
S: * 11 FETCH . . .
|
||||
S: * 12 FETCH . . .
|
||||
S: B003 OK FETCH Completed
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Standards Track [Page 4]
|
||||
|
||||
RFC 2193 IMAP4 Mailbox Referrals September 1997
|
||||
|
||||
|
||||
<Client is finished processing the REMOTE mailbox and
|
||||
wants to process a mailbox on its home server>
|
||||
|
||||
C: B004 LOGOUT
|
||||
S: * BYE IMAP4rev1 server logging out
|
||||
S: B004 OK LOGOUT Completed
|
||||
|
||||
<Client continues with first connection>
|
||||
|
||||
C: A002 SELECT INBOX
|
||||
S: * 16 EXISTS
|
||||
S: * 2 RECENT
|
||||
S: * OK [UNSEEN 10] Message 10 is first unseen
|
||||
S: * OK [UIDVALIDITY 123456789]
|
||||
S: * FLAGS (Answered Flagged Deleted Seen Draft)
|
||||
S: * OK [PERMANENTFLAGS (Answered Deleted Seen ]
|
||||
S: A002 OK [READ-WRITE] Selected completed
|
||||
|
||||
4.2. CREATE Referrals
|
||||
|
||||
An IMAP4 server MAY respond to the CREATE command with one or more
|
||||
IMAP mailbox referrals, if it wishes to direct the client to issue
|
||||
the CREATE against another server. The server can employ any means,
|
||||
such as examining the hierarchy of the specified mailbox name, in
|
||||
determining which server the mailbox should be created on.
|
||||
|
||||
Example:
|
||||
|
||||
C: A001 CREATE "SHARED/FOO"
|
||||
S: A001 NO [REFERRAL IMAP://user;AUTH=*@SERVER2/SHARED/FOO]
|
||||
Mailbox should be created on remote server
|
||||
|
||||
Alternatively, because a home server is required to maintain a
|
||||
listing of referred remote mailboxes, a server MAY allow the creation
|
||||
of a mailbox that will ultimately reside on a remote server against
|
||||
the home server, and provide referrals on subsequent commands that
|
||||
manipulate the mailbox.
|
||||
|
||||
Example:
|
||||
|
||||
C: A001 CREATE "SHARED/FOO"
|
||||
S: A001 OK CREATE succeeded
|
||||
|
||||
C: A002 SELECT "SHARED/FOO"
|
||||
S: A002 NO [REFERRAL IMAP://user;AUTH=*@SERVER2/SHARED/FOO]
|
||||
Remote mailbox. Try SERVER2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Standards Track [Page 5]
|
||||
|
||||
RFC 2193 IMAP4 Mailbox Referrals September 1997
|
||||
|
||||
|
||||
4.3. RENAME Referrals
|
||||
|
||||
An IMAP4 server MAY respond to the RENAME command with one or more
|
||||
pairs of IMAP mailbox referrals. In each pair of IMAP mailbox
|
||||
referrals, the first one is an URL to the existing mailbox name and
|
||||
the second is an URL to the requested new mailbox name.
|
||||
|
||||
If within an IMAP mailbox referral pair, the existing and new mailbox
|
||||
URLs are on different servers, the remote servers are unable to
|
||||
perform the RENAME operation. To achieve the same behavior of
|
||||
server RENAME, the client MAY issue the constituent CREATE, FETCH,
|
||||
APPEND, and DELETE commands against both servers.
|
||||
|
||||
If within an IMAP mailbox referral pair, the existing and new mailbox
|
||||
URLs are on the same server it is an indication that the currently
|
||||
connected server is unable to perform the operation. The client can
|
||||
simply re-issue the RENAME command on the remote server.
|
||||
|
||||
Example:
|
||||
|
||||
C: A001 RENAME FOO BAR
|
||||
S: A001 NO [REFERRAL IMAP://user;AUTH=*@SERVER1/FOO
|
||||
IMAP://user;AUTH=*@SERVER2/BAR] Unable to rename mailbox
|
||||
across servers
|
||||
|
||||
Since the existing and new mailbox names are on different servers,
|
||||
the client would be required to make a connection to both servers and
|
||||
issue the constituent commands require to achieve the RENAME.
|
||||
|
||||
Example:
|
||||
|
||||
C: A001 RENAME FOO BAR
|
||||
S: A001 NO [REFERRAL IMAP://user;AUTH=*@SERVER2/FOO
|
||||
IMAP://user;AUTH=*@SERVER2/BAR] Unable to rename mailbox
|
||||
located on SERVER2
|
||||
|
||||
Since both the existing and new mailbox are on the same remote
|
||||
server, the client can simply make a connection to the remote server
|
||||
and re-issue the RENAME command.
|
||||
|
||||
4.4. COPY Referrals
|
||||
|
||||
An IMAP4 server MAY respond to the COPY command with one or more IMAP
|
||||
mailbox referrals. This indicates that the destination mailbox is on
|
||||
a remote server. To achieve the same behavior of a server COPY, the
|
||||
client MAY issue the constituent FETCH and APPEND commands against
|
||||
both servers.
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Standards Track [Page 6]
|
||||
|
||||
RFC 2193 IMAP4 Mailbox Referrals September 1997
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
C: A001 COPY 1 "SHARED/STUFF"
|
||||
S: A001 NO [REFERRAL IMAP://user;AUTH=*@SERVER2/SHARED/STUFF]
|
||||
Unable to copy message(s) to SERVER2.
|
||||
|
||||
5.1 RLIST command
|
||||
|
||||
Arguments: reference name
|
||||
mailbox name with possible wildcards
|
||||
|
||||
Responses: untagged responses: LIST
|
||||
|
||||
Result: OK - RLIST Completed
|
||||
NO - RLIST Failure
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
The RLIST command behaves identically to its LIST counterpart, except
|
||||
remote mailboxes are returned in addition to local mailboxes in the
|
||||
LIST responses.
|
||||
|
||||
5.2 RLSUB Command
|
||||
|
||||
Arguments: reference name
|
||||
mailbox name with possible wildcards
|
||||
|
||||
Responses: untagged responses: LSUB
|
||||
|
||||
Result: OK - RLSUB Completed
|
||||
NO - RLSUB Failure
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
The RLSUB command behaves identically to its LSUB counterpart, except
|
||||
remote mailboxes are returned in addition to local mailboxes in the
|
||||
LSUB responses.
|
||||
|
||||
6. Formal Syntax
|
||||
|
||||
The following syntax specification uses the augmented Backus-Naur
|
||||
Form (BNF) as described in [ABNF].
|
||||
|
||||
list_mailbox = <list_mailbox> as defined in [RFC-2060]
|
||||
|
||||
mailbox = <mailbox> as defined in [RFC-2060]
|
||||
|
||||
mailbox_referral = <tag> SPACE "NO" SPACE
|
||||
<referral_response_code> (text / text_mime2)
|
||||
; See [RFC-2060] for <tag>, text and text_mime2 definition
|
||||
|
||||
|
||||
|
||||
Gahrns Standards Track [Page 7]
|
||||
|
||||
RFC 2193 IMAP4 Mailbox Referrals September 1997
|
||||
|
||||
|
||||
referral_response_code = "[" "REFERRAL" 1*(SPACE <url>) "]"
|
||||
; See [RFC-1738] for <url> definition
|
||||
|
||||
rlist = "RLIST" SPACE mailbox SPACE list_mailbox
|
||||
|
||||
rlsub = "RLSUB" SPACE mailbox SPACE list_mailbox
|
||||
|
||||
6. Security Considerations
|
||||
|
||||
The IMAP4 referral mechanism makes use of IMAP URLs, and as such,
|
||||
have the same security considerations as general internet URLs [RFC-
|
||||
1738], and in particular IMAP URLs [RFC-2192].
|
||||
|
||||
With the MAILBOX-REFERRALS capability, it is potentially easier to
|
||||
write a rogue server that injects a bogus referral response that
|
||||
directs a user to an incorrect mailbox. Although referrals reduce
|
||||
the effort to write such a server, the referral response makes
|
||||
detection of the intrusion easier.
|
||||
|
||||
7. References
|
||||
|
||||
[RFC-2060], Crispin, M., "Internet Message Access Protocol - Version
|
||||
4rev1", RFC 2060, University of Washington, December 1996.
|
||||
|
||||
[RFC-2192], Newman, C., "IMAP URL Scheme", RFC 2192, Innosoft,
|
||||
September 1997.
|
||||
|
||||
[RFC-1738], Berners-Lee, T., Masinter, L., and M. McCahill, "Uniform
|
||||
Resource Locators (URL)", RFC 1738, CERN, Xerox Corporation,
|
||||
University of Minnesota, December 1994.
|
||||
|
||||
[RFC-2119], Bradner, S., "Key words for use in RFCs to Indicate
|
||||
Requirement Levels", RFC 2119, Harvard University, March 1997.
|
||||
|
||||
[ABNF], DRUMS working group, Dave Crocker Editor, "Augmented BNF for
|
||||
Syntax Specifications: ABNF", Work in Progress, Internet Mail
|
||||
Consortium, April 1997.
|
||||
|
||||
8. Acknowledgments
|
||||
|
||||
Many valuable suggestions were received from private discussions and
|
||||
the IMAP4 mailing list. In particular, Raymond Cheng, Mark Crispin,
|
||||
Mark Keasling, Chris Newman and Larry Osterman made significant
|
||||
contributions to this document.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Standards Track [Page 8]
|
||||
|
||||
RFC 2193 IMAP4 Mailbox Referrals September 1997
|
||||
|
||||
|
||||
9. Author's Address
|
||||
|
||||
Mike Gahrns
|
||||
Microsoft
|
||||
One Microsoft Way
|
||||
Redmond, WA, 98072
|
||||
|
||||
Phone: (206) 936-9833
|
||||
EMail: mikega@microsoft.com
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Standards Track [Page 9]
|
||||
|
|
@ -1,283 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group J. Klensin
|
||||
Request for Comments: 2195 R. Catoe
|
||||
Category: Standards Track P. Krumviede
|
||||
Obsoletes: 2095 MCI
|
||||
September 1997
|
||||
|
||||
|
||||
IMAP/POP AUTHorize Extension for Simple Challenge/Response
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This document specifies an Internet standards track protocol for the
|
||||
Internet community, and requests discussion and suggestions for
|
||||
improvements. Please refer to the current edition of the "Internet
|
||||
Official Protocol Standards" (STD 1) for the standardization state
|
||||
and status of this protocol. Distribution of this memo is unlimited.
|
||||
|
||||
Abstract
|
||||
|
||||
While IMAP4 supports a number of strong authentication mechanisms as
|
||||
described in RFC 1731, it lacks any mechanism that neither passes
|
||||
cleartext, reusable passwords across the network nor requires either
|
||||
a significant security infrastructure or that the mail server update
|
||||
a mail-system-wide user authentication file on each mail access.
|
||||
This specification provides a simple challenge-response
|
||||
authentication protocol that is suitable for use with IMAP4. Since
|
||||
it utilizes Keyed-MD5 digests and does not require that the secret be
|
||||
stored in the clear on the server, it may also constitute an
|
||||
improvement on APOP for POP3 use as specified in RFC 1734.
|
||||
|
||||
1. Introduction
|
||||
|
||||
Existing Proposed Standards specify an AUTHENTICATE mechanism for the
|
||||
IMAP4 protocol [IMAP, IMAP-AUTH] and a parallel AUTH mechanism for
|
||||
the POP3 protocol [POP3-AUTH]. The AUTHENTICATE mechanism is
|
||||
intended to be extensible; the four methods specified in [IMAP-AUTH]
|
||||
are all fairly powerful and require some security infrastructure to
|
||||
support. The base POP3 specification [POP3] also contains a
|
||||
lightweight challenge-response mechanism called APOP. APOP is
|
||||
associated with most of the risks associated with such protocols: in
|
||||
particular, it requires that both the client and server machines have
|
||||
access to the shared secret in cleartext form. CRAM offers a method
|
||||
for avoiding such cleartext storage while retaining the algorithmic
|
||||
simplicity of APOP in using only MD5, though in a "keyed" method.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Klensin, Catoe & Krumviede Standards Track [Page 1]
|
||||
|
||||
RFC 2195 IMAP/POP AUTHorize Extension September 1997
|
||||
|
||||
|
||||
At present, IMAP [IMAP] lacks any facility corresponding to APOP.
|
||||
The only alternative to the strong mechanisms identified in [IMAP-
|
||||
AUTH] is a presumably cleartext username and password, supported
|
||||
through the LOGIN command in [IMAP]. This document describes a
|
||||
simple challenge-response mechanism, similar to APOP and PPP CHAP
|
||||
[PPP], that can be used with IMAP (and, in principle, with POP3).
|
||||
|
||||
This mechanism also has the advantage over some possible alternatives
|
||||
of not requiring that the server maintain information about email
|
||||
"logins" on a per-login basis. While mechanisms that do require such
|
||||
per-login history records may offer enhanced security, protocols such
|
||||
as IMAP, which may have several connections between a given client
|
||||
and server open more or less simultaneous, may make their
|
||||
implementation particularly challenging.
|
||||
|
||||
2. Challenge-Response Authentication Mechanism (CRAM)
|
||||
|
||||
The authentication type associated with CRAM is "CRAM-MD5".
|
||||
|
||||
The data encoded in the first ready response contains an
|
||||
presumptively arbitrary string of random digits, a timestamp, and the
|
||||
fully-qualified primary host name of the server. The syntax of the
|
||||
unencoded form must correspond to that of an RFC 822 'msg-id'
|
||||
[RFC822] as described in [POP3].
|
||||
|
||||
The client makes note of the data and then responds with a string
|
||||
consisting of the user name, a space, and a 'digest'. The latter is
|
||||
computed by applying the keyed MD5 algorithm from [KEYED-MD5] where
|
||||
the key is a shared secret and the digested text is the timestamp
|
||||
(including angle-brackets).
|
||||
|
||||
This shared secret is a string known only to the client and server.
|
||||
The `digest' parameter itself is a 16-octet value which is sent in
|
||||
hexadecimal format, using lower-case ASCII characters.
|
||||
|
||||
When the server receives this client response, it verifies the digest
|
||||
provided. If the digest is correct, the server should consider the
|
||||
client authenticated and respond appropriately.
|
||||
|
||||
Keyed MD5 is chosen for this application because of the greater
|
||||
security imparted to authentication of short messages. In addition,
|
||||
the use of the techniques described in [KEYED-MD5] for precomputation
|
||||
of intermediate results make it possible to avoid explicit cleartext
|
||||
storage of the shared secret on the server system by instead storing
|
||||
the intermediate results which are known as "contexts".
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Klensin, Catoe & Krumviede Standards Track [Page 2]
|
||||
|
||||
RFC 2195 IMAP/POP AUTHorize Extension September 1997
|
||||
|
||||
|
||||
CRAM does not support a protection mechanism.
|
||||
|
||||
Example:
|
||||
|
||||
The examples in this document show the use of the CRAM mechanism with
|
||||
the IMAP4 AUTHENTICATE command [IMAP-AUTH]. The base64 encoding of
|
||||
the challenges and responses is part of the IMAP4 AUTHENTICATE
|
||||
command, not part of the CRAM specification itself.
|
||||
|
||||
S: * OK IMAP4 Server
|
||||
C: A0001 AUTHENTICATE CRAM-MD5
|
||||
S: + PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2UucmVzdG9uLm1jaS5uZXQ+
|
||||
C: dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw
|
||||
S: A0001 OK CRAM authentication successful
|
||||
|
||||
In this example, the shared secret is the string
|
||||
'tanstaaftanstaaf'. Hence, the Keyed MD5 digest is produced by
|
||||
calculating
|
||||
|
||||
MD5((tanstaaftanstaaf XOR opad),
|
||||
MD5((tanstaaftanstaaf XOR ipad),
|
||||
<1896.697170952@postoffice.reston.mci.net>))
|
||||
|
||||
where ipad and opad are as defined in the keyed-MD5 Work in
|
||||
Progress [KEYED-MD5] and the string shown in the challenge is the
|
||||
base64 encoding of <1896.697170952@postoffice.reston.mci.net>. The
|
||||
shared secret is null-padded to a length of 64 bytes. If the
|
||||
shared secret is longer than 64 bytes, the MD5 digest of the
|
||||
shared secret is used as a 16 byte input to the keyed MD5
|
||||
calculation.
|
||||
|
||||
This produces a digest value (in hexadecimal) of
|
||||
|
||||
b913a602c7eda7a495b4e6e7334d3890
|
||||
|
||||
The user name is then prepended to it, forming
|
||||
|
||||
tim b913a602c7eda7a495b4e6e7334d3890
|
||||
|
||||
Which is then base64 encoded to meet the requirements of the IMAP4
|
||||
AUTHENTICATE command (or the similar POP3 AUTH command), yielding
|
||||
|
||||
dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Klensin, Catoe & Krumviede Standards Track [Page 3]
|
||||
|
||||
RFC 2195 IMAP/POP AUTHorize Extension September 1997
|
||||
|
||||
|
||||
3. References
|
||||
|
||||
[CHAP] Lloyd, B., and W. Simpson, "PPP Authentication Protocols",
|
||||
RFC 1334, October 1992.
|
||||
|
||||
[IMAP] Crispin, M., "Internet Message Access Protocol - Version
|
||||
4rev1", RFC 2060, University of Washington, December 1996.
|
||||
|
||||
[IMAP-AUTH] Myers, J., "IMAP4 Authentication Mechanisms",
|
||||
RFC 1731, Carnegie Mellon, December 1994.
|
||||
|
||||
[KEYED-MD5] Krawczyk, Bellare, Canetti, "HMAC: Keyed-Hashing for
|
||||
Message Authentication", RFC 2104, February 1997.
|
||||
|
||||
[MD5] Rivest, R., "The MD5 Message Digest Algorithm",
|
||||
RFC 1321, MIT Laboratory for Computer Science, April 1992.
|
||||
|
||||
[POP3] Myers, J., and M. Rose, "Post Office Protocol - Version 3",
|
||||
STD 53, RFC 1939, Carnegie Mellon, May 1996.
|
||||
|
||||
[POP3-AUTH] Myers, J., "POP3 AUTHentication command", RFC 1734,
|
||||
Carnegie Mellon, December, 1994.
|
||||
|
||||
4. Security Considerations
|
||||
|
||||
It is conjectured that use of the CRAM authentication mechanism
|
||||
provides origin identification and replay protection for a session.
|
||||
Accordingly, a server that implements both a cleartext password
|
||||
command and this authentication type should not allow both methods of
|
||||
access for a given user.
|
||||
|
||||
While the saving, on the server, of "contexts" (see section 2) is
|
||||
marginally better than saving the shared secrets in cleartext as is
|
||||
required by CHAP [CHAP] and APOP [POP3], it is not sufficient to
|
||||
protect the secrets if the server itself is compromised.
|
||||
Consequently, servers that store the secrets or contexts must both be
|
||||
protected to a level appropriate to the potential information value
|
||||
in user mailboxes and identities.
|
||||
|
||||
As the length of the shared secret increases, so does the difficulty
|
||||
of deriving it.
|
||||
|
||||
While there are now suggestions in the literature that the use of MD5
|
||||
and keyed MD5 in authentication procedures probably has a limited
|
||||
effective lifetime, the technique is now widely deployed and widely
|
||||
understood. It is believed that this general understanding may
|
||||
assist with the rapid replacement, by CRAM-MD5, of the current uses
|
||||
of permanent cleartext passwords in IMAP. This document has been
|
||||
|
||||
|
||||
|
||||
Klensin, Catoe & Krumviede Standards Track [Page 4]
|
||||
|
||||
RFC 2195 IMAP/POP AUTHorize Extension September 1997
|
||||
|
||||
|
||||
deliberately written to permit easy upgrading to use SHA (or whatever
|
||||
alternatives emerge) when they are considered to be widely available
|
||||
and adequately safe.
|
||||
|
||||
Even with the use of CRAM, users are still vulnerable to active
|
||||
attacks. An example of an increasingly common active attack is 'TCP
|
||||
Session Hijacking' as described in CERT Advisory CA-95:01 [CERT95].
|
||||
|
||||
See section 1 above for additional discussion.
|
||||
|
||||
5. Acknowledgements
|
||||
|
||||
This memo borrows ideas and some text liberally from [POP3] and
|
||||
[RFC-1731] and thanks are due the authors of those documents. Ran
|
||||
Atkinson made a number of valuable technical and editorial
|
||||
contributions to the document.
|
||||
|
||||
6. Authors' Addresses
|
||||
|
||||
John C. Klensin
|
||||
MCI Telecommunications
|
||||
800 Boylston St, 7th floor
|
||||
Boston, MA 02199
|
||||
USA
|
||||
|
||||
EMail: klensin@mci.net
|
||||
Phone: +1 617 960 1011
|
||||
|
||||
Randy Catoe
|
||||
MCI Telecommunications
|
||||
2100 Reston Parkway
|
||||
Reston, VA 22091
|
||||
USA
|
||||
|
||||
EMail: randy@mci.net
|
||||
Phone: +1 703 715 7366
|
||||
|
||||
Paul Krumviede
|
||||
MCI Telecommunications
|
||||
2100 Reston Parkway
|
||||
Reston, VA 22091
|
||||
USA
|
||||
|
||||
EMail: paul@mci.net
|
||||
Phone: +1 703 715 7251
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Klensin, Catoe & Krumviede Standards Track [Page 5]
|
||||
|
|
@ -1,283 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group M. Gahrns
|
||||
Request for Comments: 2221 Microsoft
|
||||
Category: Standards Track October 1997
|
||||
|
||||
|
||||
IMAP4 Login Referrals
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This document specifies an Internet standards track protocol for the
|
||||
Internet community, and requests discussion and suggestions for
|
||||
improvements. Please refer to the current edition of the "Internet
|
||||
Official Protocol Standards" (STD 1) for the standardization state
|
||||
and status of this protocol. Distribution of this memo is unlimited.
|
||||
|
||||
Copyright Notice
|
||||
|
||||
Copyright (C) The Internet Society (1997). All Rights Reserved.
|
||||
|
||||
1. Abstract
|
||||
|
||||
When dealing with large amounts of users and many IMAP4 [RFC-2060]
|
||||
servers, it is often necessary to move users from one IMAP4 server to
|
||||
another. For example, hardware failures or organizational changes
|
||||
may dictate such a move.
|
||||
|
||||
Login referrals allow clients to transparently connect to an
|
||||
alternate IMAP4 server, if their home IMAP4 server has changed.
|
||||
|
||||
A referral mechanism can provide efficiencies over the alternative
|
||||
'proxy method', in which the local IMAP4 server contacts the remote
|
||||
server on behalf of the client, and then transfers the data from the
|
||||
remote server to itself, and then on to the client. The referral
|
||||
mechanism's direct client connection to the remote server is often a
|
||||
more efficient use of bandwidth, and does not require the local
|
||||
server to impersonate the client when authenticating to the remote
|
||||
server.
|
||||
|
||||
2. Conventions used in this document
|
||||
|
||||
In examples, "C:" and "S:" indicate lines sent by the client and
|
||||
server respectively.
|
||||
|
||||
A home server, is an IMAP4 server that contains the user's inbox.
|
||||
|
||||
A remote server is a server that contains remote mailboxes.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Standards Track [Page 1]
|
||||
|
||||
RFC 2221 IMAP4 Login Referrals October 1997
|
||||
|
||||
|
||||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
|
||||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
|
||||
document are to be interpreted as described in [RFC-2119].
|
||||
|
||||
3. Introduction and Overview
|
||||
|
||||
IMAP4 servers that support this extension MUST list the keyword
|
||||
LOGIN-REFERRALS in their CAPABILITY response. No client action is
|
||||
needed to invoke the LOGIN-REFERRALS capability in a server.
|
||||
|
||||
A LOGIN-REFERRALS capable IMAP4 server SHOULD NOT return a referral
|
||||
to a server that will return a referral. A client MUST NOT follow
|
||||
more than 10 levels of referral without consulting the user.
|
||||
|
||||
A LOGIN-REFERRALS response code MUST contain as an argument a valid
|
||||
IMAP server URL as defined in [IMAP-URL].
|
||||
|
||||
A home server referral consists of either a tagged NO or OK, or an
|
||||
untagged BYE response that contains a LOGIN-REFERRALS response code.
|
||||
|
||||
Example: A001 NO [REFERRAL IMAP://user;AUTH=*@SERVER2/] Remote Server
|
||||
|
||||
NOTE: user;AUTH=* is specified as required by [IMAP-URL] to avoid a
|
||||
client falling back to anonymous login.
|
||||
|
||||
4. Home Server Referrals
|
||||
|
||||
A home server referral may be returned in response to an AUTHENTICATE
|
||||
or LOGIN command, or it may appear in the connection startup banner.
|
||||
If a server returns a home server referral in a tagged NO response,
|
||||
that server does not contain any mailboxes that are accessible to the
|
||||
user. If a server returns a home server referral in a tagged OK
|
||||
response, it indicates that the user's personal mailboxes are
|
||||
elsewhere, but the server contains public mailboxes which are
|
||||
readable by the user. After receiving a home server referral, the
|
||||
client can not make any assumptions as to whether this was a
|
||||
permanent or temporary move of the user.
|
||||
|
||||
4.1. LOGIN and AUTHENTICATE Referrals
|
||||
|
||||
An IMAP4 server MAY respond to a LOGIN or AUTHENTICATE command with a
|
||||
home server referral if it wishes to direct the user to another IMAP4
|
||||
server.
|
||||
|
||||
Example: C: A001 LOGIN MIKE PASSWORD
|
||||
S: A001 NO [REFERRAL IMAP://MIKE@SERVER2/] Specified user
|
||||
is invalid on this server. Try SERVER2.
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Standards Track [Page 2]
|
||||
|
||||
RFC 2221 IMAP4 Login Referrals October 1997
|
||||
|
||||
|
||||
Example: C: A001 LOGIN MATTHEW PASSWORD
|
||||
S: A001 OK [REFERRAL IMAP://MATTHEW@SERVER2/] Specified
|
||||
user's personal mailboxes located on Server2, but
|
||||
public mailboxes are available.
|
||||
|
||||
Example: C: A001 AUTHENTICATE GSSAPI
|
||||
<authentication exchange>
|
||||
S: A001 NO [REFERRAL IMAP://user;AUTH=GSSAPI@SERVER2/]
|
||||
Specified user is invalid on this server. Try
|
||||
SERVER2.
|
||||
|
||||
4.2. BYE at connection startup referral
|
||||
|
||||
An IMAP4 server MAY respond with an untagged BYE and a REFERRAL
|
||||
response code that contains an IMAP URL to a home server if it is not
|
||||
willing to accept connections and wishes to direct the client to
|
||||
another IMAP4 server.
|
||||
|
||||
Example: S: * BYE [REFERRAL IMAP://user;AUTH=*@SERVER2/] Server not
|
||||
accepting connections. Try SERVER2
|
||||
|
||||
5. Formal Syntax
|
||||
|
||||
The following syntax specification uses the augmented Backus-Naur
|
||||
Form (BNF) as described in [ABNF].
|
||||
|
||||
This amends the "resp_text_code" element of the IMAP4 grammar
|
||||
described in [RFC-2060]
|
||||
|
||||
resp_text_code =/ "REFERRAL" SPACE <imapurl>
|
||||
; See [IMAP-URL] for definition of <imapurl>
|
||||
; See [RFC-2060] for base definition of resp_text_code
|
||||
|
||||
6. Security Considerations
|
||||
|
||||
The IMAP4 login referral mechanism makes use of IMAP URLs, and as
|
||||
such, have the same security considerations as general internet URLs
|
||||
[RFC-1738], and in particular IMAP URLs [IMAP-URL].
|
||||
|
||||
A server MUST NOT give a login referral if authentication for that
|
||||
user fails. This is to avoid revealing information about the user's
|
||||
account to an unauthorized user.
|
||||
|
||||
With the LOGIN-REFERRALS capability, it is potentially easier to
|
||||
write a rogue 'password catching' server that collects login data and
|
||||
then refers the client to their actual IMAP4 server. Although
|
||||
referrals reduce the effort to write such a server, the referral
|
||||
response makes detection of the intrusion easier.
|
||||
|
||||
|
||||
|
||||
Gahrns Standards Track [Page 3]
|
||||
|
||||
RFC 2221 IMAP4 Login Referrals October 1997
|
||||
|
||||
|
||||
7. References
|
||||
|
||||
[RFC-2060], Crispin, M., "Internet Message Access Protocol - Version
|
||||
4rev1", RFC 2060, December 1996.
|
||||
|
||||
[IMAP-URL], Newman, C., "IMAP URL Scheme", RFC 2192, Innosoft,
|
||||
September 1997.
|
||||
|
||||
[RFC-1738], Berners-Lee, T., Masinter, L. and M. McCahill, "Uniform
|
||||
Resource Locators (URL)", RFC 1738, December 1994.
|
||||
|
||||
[RFC-2119], Bradner, S., "Key words for use in RFCs to Indicate
|
||||
Requirement Levels", RFC 2119, March 1997.
|
||||
|
||||
[ABNF], DRUMS working group, Dave Crocker Editor, "Augmented BNF for
|
||||
Syntax Specifications: ABNF", Work in Progress.
|
||||
|
||||
8. Acknowledgments
|
||||
|
||||
Many valuable suggestions were received from private discussions and
|
||||
the IMAP4 mailing list. In particular, Raymond Cheng, Mark Crispin,
|
||||
Mark Keasling Chris Newman and Larry Osterman made significant
|
||||
contributions to this document.
|
||||
|
||||
9. Author's Address
|
||||
|
||||
Mike Gahrns
|
||||
Microsoft
|
||||
One Microsoft Way
|
||||
Redmond, WA, 98072
|
||||
|
||||
Phone: (206) 936-9833
|
||||
EMail: mikega@microsoft.com
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Standards Track [Page 4]
|
||||
|
||||
RFC 2221 IMAP4 Login Referrals October 1997
|
||||
|
||||
|
||||
10. Full Copyright Statement
|
||||
|
||||
Copyright (C) The Internet Society (1997). All Rights Reserved.
|
||||
|
||||
This document and translations of it may be copied and furnished to
|
||||
others, and derivative works that comment on or otherwise explain it
|
||||
or assist in its implmentation may be prepared, copied, published
|
||||
andand distributed, in whole or in part, without restriction of any
|
||||
kind, provided that the above copyright notice and this paragraph are
|
||||
included on all such copies and derivative works. However, this
|
||||
document itself may not be modified in any way, such as by removing
|
||||
the copyright notice or references to the Internet Society or other
|
||||
Internet organizations, except as needed for the purpose of
|
||||
developing Internet standards in which case the procedures for
|
||||
copyrights defined in the Internet Standards process must be
|
||||
followed, or as required to translate it into languages other than
|
||||
English.
|
||||
|
||||
The limited permissions granted above are perpetual and will not be
|
||||
revoked by the Internet Society or its successors or assigns.
|
||||
|
||||
This document and the information contained herein is provided on an
|
||||
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
|
||||
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
|
||||
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
|
||||
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE."
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns Standards Track [Page 5]
|
||||
|
|
@ -1,899 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group J. Myers
|
||||
Request for Comments: 2222 Netscape Communications
|
||||
Category: Standards Track October 1997
|
||||
|
||||
|
||||
Simple Authentication and Security Layer (SASL)
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This document specifies an Internet standards track protocol for the
|
||||
Internet community, and requests discussion and suggestions for
|
||||
improvements. Please refer to the current edition of the "Internet
|
||||
Official Protocol Standards" (STD 1) for the standardization state
|
||||
and status of this protocol. Distribution of this memo is unlimited.
|
||||
|
||||
Copyright Notice
|
||||
|
||||
Copyright (C) The Internet Society (1997). All Rights Reserved.
|
||||
|
||||
Table of Contents
|
||||
|
||||
1. Abstract .............................................. 2
|
||||
2. Organization of this Document ......................... 2
|
||||
2.1. How to Read This Document ............................. 2
|
||||
2.2. Conventions Used in this Document ..................... 2
|
||||
2.3. Examples .............................................. 3
|
||||
3. Introduction and Overview ............................. 3
|
||||
4. Profiling requirements ................................ 4
|
||||
5. Specific issues ....................................... 5
|
||||
5.1. Client sends data first ............................... 5
|
||||
5.2. Server returns success with additional data ........... 5
|
||||
5.3. Multiple authentications .............................. 5
|
||||
6. Registration procedures ............................... 6
|
||||
6.1. Comments on SASL mechanism registrations .............. 6
|
||||
6.2. Location of Registered SASL Mechanism List ............ 6
|
||||
6.3. Change Control ........................................ 7
|
||||
6.4. Registration Template ................................. 7
|
||||
7. Mechanism definitions ................................. 8
|
||||
7.1. Kerberos version 4 mechanism .......................... 8
|
||||
7.2. GSSAPI mechanism ...................................... 9
|
||||
7.2.1 Client side of authentication protocol exchange ....... 9
|
||||
7.2.2 Server side of authentication protocol exchange ....... 10
|
||||
7.2.3 Security layer ........................................ 11
|
||||
7.3. S/Key mechanism ....................................... 11
|
||||
7.4. External mechanism .................................... 12
|
||||
8. References ............................................ 13
|
||||
9. Security Considerations ............................... 13
|
||||
10. Author's Address ...................................... 14
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 1]
|
||||
|
||||
RFC 2222 SASL October 1997
|
||||
|
||||
|
||||
Appendix A. Relation of SASL to Transport Security .......... 15
|
||||
Full Copyright Statement .................................... 16
|
||||
|
||||
1. Abstract
|
||||
|
||||
This document describes a method for adding authentication support to
|
||||
connection-based protocols. To use this specification, a protocol
|
||||
includes a command for identifying and authenticating a user to a
|
||||
server and for optionally negotiating protection of subsequent
|
||||
protocol interactions. If its use is negotiated, a security layer is
|
||||
inserted between the protocol and the connection. This document
|
||||
describes how a protocol specifies such a command, defines several
|
||||
mechanisms for use by the command, and defines the protocol used for
|
||||
carrying a negotiated security layer over the connection.
|
||||
|
||||
2. Organization of this Document
|
||||
|
||||
2.1. How to Read This Document
|
||||
|
||||
This document is written to serve two different audiences, protocol
|
||||
designers using this specification to support authentication in their
|
||||
protocol, and implementors of clients or servers for those protocols
|
||||
using this specification.
|
||||
|
||||
The sections "Introduction and Overview", "Profiling requirements",
|
||||
and "Security Considerations" cover issues that protocol designers
|
||||
need to understand and address in profiling this specification for
|
||||
use in a specific protocol.
|
||||
|
||||
Implementors of a protocol using this specification need the
|
||||
protocol-specific profiling information in addition to the
|
||||
information in this document.
|
||||
|
||||
2.2. Conventions Used in this Document
|
||||
|
||||
In examples, "C:" and "S:" indicate lines sent by the client and
|
||||
server respectively.
|
||||
|
||||
The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY"
|
||||
in this document are to be interpreted as defined in "Key words for
|
||||
use in RFCs to Indicate Requirement Levels" [RFC 2119].
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 2]
|
||||
|
||||
RFC 2222 SASL October 1997
|
||||
|
||||
|
||||
2.3. Examples
|
||||
|
||||
Examples in this document are for the IMAP profile [RFC 2060] of this
|
||||
specification. The base64 encoding of challenges and responses, as
|
||||
well as the "+ " preceding the responses are part of the IMAP4
|
||||
profile, not part of the SASL specification itself.
|
||||
|
||||
3. Introduction and Overview
|
||||
|
||||
The Simple Authentication and Security Layer (SASL) is a method for
|
||||
adding authentication support to connection-based protocols. To use
|
||||
this specification, a protocol includes a command for identifying and
|
||||
authenticating a user to a server and for optionally negotiating a
|
||||
security layer for subsequent protocol interactions.
|
||||
|
||||
The command has a required argument identifying a SASL mechanism.
|
||||
SASL mechanisms are named by strings, from 1 to 20 characters in
|
||||
length, consisting of upper-case letters, digits, hyphens, and/or
|
||||
underscores. SASL mechanism names must be registered with the IANA.
|
||||
Procedures for registering new SASL mechanisms are given in the
|
||||
section "Registration procedures"
|
||||
|
||||
If a server supports the requested mechanism, it initiates an
|
||||
authentication protocol exchange. This consists of a series of
|
||||
server challenges and client responses that are specific to the
|
||||
requested mechanism. The challenges and responses are defined by the
|
||||
mechanisms as binary tokens of arbitrary length. The protocol's
|
||||
profile then specifies how these binary tokens are then encoded for
|
||||
transfer over the connection.
|
||||
|
||||
After receiving the authentication command or any client response, a
|
||||
server may issue a challenge, indicate failure, or indicate
|
||||
completion. The protocol's profile specifies how the server
|
||||
indicates which of the above it is doing.
|
||||
|
||||
After receiving a challenge, a client may issue a response or abort
|
||||
the exchange. The protocol's profile specifies how the client
|
||||
indicates which of the above it is doing.
|
||||
|
||||
During the authentication protocol exchange, the mechanism performs
|
||||
authentication, transmits an authorization identity (frequently known
|
||||
as a userid) from the client to server, and negotiates the use of a
|
||||
mechanism-specific security layer. If the use of a security layer is
|
||||
agreed upon, then the mechanism must also define or negotiate the
|
||||
maximum cipher-text buffer size that each side is able to receive.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 3]
|
||||
|
||||
RFC 2222 SASL October 1997
|
||||
|
||||
|
||||
The transmitted authorization identity may be different than the
|
||||
identity in the client's authentication credentials. This permits
|
||||
agents such as proxy servers to authenticate using their own
|
||||
credentials, yet request the access privileges of the identity for
|
||||
which they are proxying. With any mechanism, transmitting an
|
||||
authorization identity of the empty string directs the server to
|
||||
derive an authorization identity from the client's authentication
|
||||
credentials.
|
||||
|
||||
If use of a security layer is negotiated, it is applied to all
|
||||
subsequent data sent over the connection. The security layer takes
|
||||
effect immediately following the last response of the authentication
|
||||
exchange for data sent by the client and the completion indication
|
||||
for data sent by the server. Once the security layer is in effect,
|
||||
the protocol stream is processed by the security layer into buffers
|
||||
of cipher-text. Each buffer is transferred over the connection as a
|
||||
stream of octets prepended with a four octet field in network byte
|
||||
order that represents the length of the following buffer. The length
|
||||
of the cipher-text buffer must be no larger than the maximum size
|
||||
that was defined or negotiated by the other side.
|
||||
|
||||
4. Profiling requirements
|
||||
|
||||
In order to use this specification, a protocol definition must supply
|
||||
the following information:
|
||||
|
||||
1. A service name, to be selected from the IANA registry of "service"
|
||||
elements for the GSSAPI host-based service name form [RFC 2078].
|
||||
|
||||
2. A definition of the command to initiate the authentication
|
||||
protocol exchange. This command must have as a parameter the
|
||||
mechanism name being selected by the client.
|
||||
|
||||
The command SHOULD have an optional parameter giving an initial
|
||||
response. This optional parameter allows the client to avoid a
|
||||
round trip when using a mechanism which is defined to have the
|
||||
client send data first. When this initial response is sent by the
|
||||
client and the selected mechanism is defined to have the server
|
||||
start with an initial challenge, the command fails. See section
|
||||
5.1 of this document for further information.
|
||||
|
||||
3. A definition of the method by which the authentication protocol
|
||||
exchange is carried out, including how the challenges and
|
||||
responses are encoded, how the server indicates completion or
|
||||
failure of the exchange, how the client aborts an exchange, and
|
||||
how the exchange method interacts with any line length limits in
|
||||
the protocol.
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 4]
|
||||
|
||||
RFC 2222 SASL October 1997
|
||||
|
||||
|
||||
4. Identification of the octet where any negotiated security layer
|
||||
starts to take effect, in both directions.
|
||||
|
||||
5. A specification of how the authorization identity passed from the
|
||||
client to the server is to be interpreted.
|
||||
|
||||
5. Specific issues
|
||||
|
||||
5.1. Client sends data first
|
||||
|
||||
Some mechanisms specify that the first data sent in the
|
||||
authentication protocol exchange is from the client to the server.
|
||||
|
||||
If a protocol's profile permits the command which initiates an
|
||||
authentication protocol exchange to contain an initial client
|
||||
response, this parameter SHOULD be used with such mechanisms.
|
||||
|
||||
If the initial client response parameter is not given, or if a
|
||||
protocol's profile does not permit the command which initiates an
|
||||
authentication protocol exchange to contain an initial client
|
||||
response, then the server issues a challenge with no data. The
|
||||
client's response to this challenge is then used as the initial
|
||||
client response. (The server then proceeds to send the next
|
||||
challenge, indicates completion, or indicates failure.)
|
||||
|
||||
5.2. Server returns success with additional data
|
||||
|
||||
Some mechanisms may specify that server challenge data be sent to the
|
||||
client along with an indication of successful completion of the
|
||||
exchange. This data would, for example, authenticate the server to
|
||||
the client.
|
||||
|
||||
If a protocol's profile does not permit this server challenge to be
|
||||
returned with a success indication, then the server issues the server
|
||||
challenge without an indication of successful completion. The client
|
||||
then responds with no data. After receiving this empty response, the
|
||||
server then indicates successful completion.
|
||||
|
||||
5.3. Multiple authentications
|
||||
|
||||
Unless otherwise stated by the protocol's profile, only one
|
||||
successful SASL negotiation may occur in a protocol session. In this
|
||||
case, once an authentication protocol exchange has successfully
|
||||
completed, further attempts to initiate an authentication protocol
|
||||
exchange fail.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 5]
|
||||
|
||||
RFC 2222 SASL October 1997
|
||||
|
||||
|
||||
In the case that a profile explicitly permits multiple successful
|
||||
SASL negotiations to occur, then in no case may multiple security
|
||||
layers be simultaneously in effect. If a security layer is in effect
|
||||
and a subsequent SASL negotiation selects no security layer, the
|
||||
original security layer remains in effect. If a security layer is in
|
||||
effect and a subsequent SASL negotiation selects a second security
|
||||
layer, then the second security layer replaces the first.
|
||||
|
||||
6. Registration procedures
|
||||
|
||||
Registration of a SASL mechanism is done by filling in the template
|
||||
in section 6.4 and sending it in to iana@isi.edu. IANA has the right
|
||||
to reject obviously bogus registrations, but will perform no review
|
||||
of clams made in the registration form.
|
||||
|
||||
There is no naming convention for SASL mechanisms; any name that
|
||||
conforms to the syntax of a SASL mechanism name can be registered.
|
||||
|
||||
While the registration procedures do not require it, authors of SASL
|
||||
mechanisms are encouraged to seek community review and comment
|
||||
whenever that is feasible. Authors may seek community review by
|
||||
posting a specification of their proposed mechanism as an internet-
|
||||
draft. SASL mechanisms intended for widespread use should be
|
||||
standardized through the normal IETF process, when appropriate.
|
||||
|
||||
6.1. Comments on SASL mechanism registrations
|
||||
|
||||
Comments on registered SASL mechanisms should first be sent to the
|
||||
"owner" of the mechanism. Submitters of comments may, after a
|
||||
reasonable attempt to contact the owner, request IANA to attach their
|
||||
comment to the SASL mechanism registration itself. If IANA approves
|
||||
of this the comment will be made accessible in conjunction with the
|
||||
SASL mechanism registration itself.
|
||||
|
||||
6.2. Location of Registered SASL Mechanism List
|
||||
|
||||
SASL mechanism registrations will be posted in the anonymous FTP
|
||||
directory "ftp://ftp.isi.edu/in-notes/iana/assignments/sasl-
|
||||
mechanisms/" and all registered SASL mechanisms will be listed in the
|
||||
periodically issued "Assigned Numbers" RFC [currently STD 2, RFC
|
||||
1700]. The SASL mechanism description and other supporting material
|
||||
may also be published as an Informational RFC by sending it to "rfc-
|
||||
editor@isi.edu" (please follow the instructions to RFC authors [RFC
|
||||
2223]).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 6]
|
||||
|
||||
RFC 2222 SASL October 1997
|
||||
|
||||
|
||||
6.3. Change Control
|
||||
|
||||
Once a SASL mechanism registration has been published by IANA, the
|
||||
author may request a change to its definition. The change request
|
||||
follows the same procedure as the registration request.
|
||||
|
||||
The owner of a SASL mechanism may pass responsibility for the SASL
|
||||
mechanism to another person or agency by informing IANA; this can be
|
||||
done without discussion or review.
|
||||
|
||||
The IESG may reassign responsibility for a SASL mechanism. The most
|
||||
common case of this will be to enable changes to be made to
|
||||
mechanisms where the author of the registration has died, moved out
|
||||
of contact or is otherwise unable to make changes that are important
|
||||
to the community.
|
||||
|
||||
SASL mechanism registrations may not be deleted; mechanisms which are
|
||||
no longer believed appropriate for use can be declared OBSOLETE by a
|
||||
change to their "intended use" field; such SASL mechanisms will be
|
||||
clearly marked in the lists published by IANA.
|
||||
|
||||
The IESG is considered to be the owner of all SASL mechanisms which
|
||||
are on the IETF standards track.
|
||||
|
||||
6.4. Registration Template
|
||||
|
||||
To: iana@iana.org
|
||||
Subject: Registration of SASL mechanism X
|
||||
|
||||
SASL mechanism name:
|
||||
|
||||
Security considerations:
|
||||
|
||||
Published specification (optional, recommended):
|
||||
|
||||
Person & email address to contact for further information:
|
||||
|
||||
Intended usage:
|
||||
|
||||
(One of COMMON, LIMITED USE or OBSOLETE)
|
||||
|
||||
Author/Change controller:
|
||||
|
||||
(Any other information that the author deems interesting may be
|
||||
added below this line.)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 7]
|
||||
|
||||
RFC 2222 SASL October 1997
|
||||
|
||||
|
||||
7. Mechanism definitions
|
||||
|
||||
The following mechanisms are hereby defined.
|
||||
|
||||
7.1. Kerberos version 4 mechanism
|
||||
|
||||
The mechanism name associated with Kerberos version 4 is
|
||||
"KERBEROS_V4".
|
||||
|
||||
The first challenge consists of a random 32-bit number in network
|
||||
byte order. The client responds with a Kerberos ticket and an
|
||||
authenticator for the principal "service.hostname@realm", where
|
||||
"service" is the service name specified in the protocol's profile,
|
||||
"hostname" is the first component of the host name of the server with
|
||||
all letters in lower case, and where "realm" is the Kerberos realm of
|
||||
the server. The encrypted checksum field included within the
|
||||
Kerberos authenticator contains the server provided challenge in
|
||||
network byte order.
|
||||
|
||||
Upon decrypting and verifying the ticket and authenticator, the
|
||||
server verifies that the contained checksum field equals the original
|
||||
server provided random 32-bit number. Should the verification be
|
||||
successful, the server must add one to the checksum and construct 8
|
||||
octets of data, with the first four octets containing the incremented
|
||||
checksum in network byte order, the fifth octet containing a bit-mask
|
||||
specifying the security layers supported by the server, and the sixth
|
||||
through eighth octets containing, in network byte order, the maximum
|
||||
cipher-text buffer size the server is able to receive. The server
|
||||
must encrypt using DES ECB mode the 8 octets of data in the session
|
||||
key and issue that encrypted data in a second challenge. The client
|
||||
considers the server authenticated if the first four octets of the
|
||||
un-encrypted data is equal to one plus the checksum it previously
|
||||
sent.
|
||||
|
||||
The client must construct data with the first four octets containing
|
||||
the original server-issued checksum in network byte order, the fifth
|
||||
octet containing the bit-mask specifying the selected security layer,
|
||||
the sixth through eighth octets containing in network byte order the
|
||||
maximum cipher-text buffer size the client is able to receive, and
|
||||
the following octets containing the authorization identity. The
|
||||
client must then append from one to eight zero-valued octets so that
|
||||
the length of the data is a multiple of eight octets. The client must
|
||||
then encrypt using DES PCBC mode the data with the session key and
|
||||
respond with the encrypted data. The server decrypts the data and
|
||||
verifies the contained checksum. The server must verify that the
|
||||
principal identified in the Kerberos ticket is authorized to connect
|
||||
as that authorization identity. After this verification, the
|
||||
authentication process is complete.
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 8]
|
||||
|
||||
RFC 2222 SASL October 1997
|
||||
|
||||
|
||||
The security layers and their corresponding bit-masks are as follows:
|
||||
|
||||
1 No security layer
|
||||
2 Integrity (krb_mk_safe) protection
|
||||
4 Privacy (krb_mk_priv) protection
|
||||
|
||||
Other bit-masks may be defined in the future; bits which are not
|
||||
understood must be negotiated off.
|
||||
|
||||
EXAMPLE: The following are two Kerberos version 4 login scenarios to
|
||||
the IMAP4 protocol (note that the line breaks in the sample
|
||||
authenticators are for editorial clarity and are not in real
|
||||
authenticators)
|
||||
|
||||
S: * OK IMAP4 Server
|
||||
C: A001 AUTHENTICATE KERBEROS_V4
|
||||
S: + AmFYig==
|
||||
C: BAcAQU5EUkVXLkNNVS5FRFUAOCAsho84kLN3/IJmrMG+25a4DT
|
||||
+nZImJjnTNHJUtxAA+o0KPKfHEcAFs9a3CL5Oebe/ydHJUwYFd
|
||||
WwuQ1MWiy6IesKvjL5rL9WjXUb9MwT9bpObYLGOKi1Qh
|
||||
S: + or//EoAADZI=
|
||||
C: DiAF5A4gA+oOIALuBkAAmw==
|
||||
S: A001 OK Kerberos V4 authentication successful
|
||||
|
||||
|
||||
S: * OK IMAP4 Server
|
||||
C: A001 AUTHENTICATE KERBEROS_V4
|
||||
S: + gcfgCA==
|
||||
C: BAcAQU5EUkVXLkNNVS5FRFUAOCAsho84kLN3/IJmrMG+25a4DT
|
||||
+nZImJjnTNHJUtxAA+o0KPKfHEcAFs9a3CL5Oebe/ydHJUwYFd
|
||||
WwuQ1MWiy6IesKvjL5rL9WjXUb9MwT9bpObYLGOKi1Qh
|
||||
S: A001 NO Kerberos V4 authentication failed
|
||||
|
||||
7.2. GSSAPI mechanism
|
||||
|
||||
The mechanism name associated with all mechanisms employing the
|
||||
GSSAPI [RFC 2078] is "GSSAPI".
|
||||
|
||||
7.2.1 Client side of authentication protocol exchange
|
||||
|
||||
The client calls GSS_Init_sec_context, passing in 0 for
|
||||
input_context_handle (initially) and a targ_name equal to output_name
|
||||
from GSS_Import_Name called with input_name_type of
|
||||
GSS_C_NT_HOSTBASED_SERVICE and input_name_string of
|
||||
"service@hostname" where "service" is the service name specified in
|
||||
the protocol's profile, and "hostname" is the fully qualified host
|
||||
name of the server. The client then responds with the resulting
|
||||
output_token. If GSS_Init_sec_context returns GSS_S_CONTINUE_NEEDED,
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 9]
|
||||
|
||||
RFC 2222 SASL October 1997
|
||||
|
||||
|
||||
then the client should expect the server to issue a token in a
|
||||
subsequent challenge. The client must pass the token to another call
|
||||
to GSS_Init_sec_context, repeating the actions in this paragraph.
|
||||
|
||||
When GSS_Init_sec_context returns GSS_S_COMPLETE, the client takes
|
||||
the following actions: If the last call to GSS_Init_sec_context
|
||||
returned an output_token, then the client responds with the
|
||||
output_token, otherwise the client responds with no data. The client
|
||||
should then expect the server to issue a token in a subsequent
|
||||
challenge. The client passes this token to GSS_Unwrap and interprets
|
||||
the first octet of resulting cleartext as a bit-mask specifying the
|
||||
security layers supported by the server and the second through fourth
|
||||
octets as the maximum size output_message to send to the server. The
|
||||
client then constructs data, with the first octet containing the
|
||||
bit-mask specifying the selected security layer, the second through
|
||||
fourth octets containing in network byte order the maximum size
|
||||
output_message the client is able to receive, and the remaining
|
||||
octets containing the authorization identity. The client passes the
|
||||
data to GSS_Wrap with conf_flag set to FALSE, and responds with the
|
||||
generated output_message. The client can then consider the server
|
||||
authenticated.
|
||||
|
||||
7.2.2 Server side of authentication protocol exchange
|
||||
|
||||
The server passes the initial client response to
|
||||
GSS_Accept_sec_context as input_token, setting input_context_handle
|
||||
to 0 (initially). If GSS_Accept_sec_context returns
|
||||
GSS_S_CONTINUE_NEEDED, the server returns the generated output_token
|
||||
to the client in challenge and passes the resulting response to
|
||||
another call to GSS_Accept_sec_context, repeating the actions in this
|
||||
paragraph.
|
||||
|
||||
When GSS_Accept_sec_context returns GSS_S_COMPLETE, the client takes
|
||||
the following actions: If the last call to GSS_Accept_sec_context
|
||||
returned an output_token, the server returns it to the client in a
|
||||
challenge and expects a reply from the client with no data. Whether
|
||||
or not an output_token was returned (and after receipt of any
|
||||
response from the client to such an output_token), the server then
|
||||
constructs 4 octets of data, with the first octet containing a bit-
|
||||
mask specifying the security layers supported by the server and the
|
||||
second through fourth octets containing in network byte order the
|
||||
maximum size output_token the server is able to receive. The server
|
||||
must then pass the plaintext to GSS_Wrap with conf_flag set to FALSE
|
||||
and issue the generated output_message to the client in a challenge.
|
||||
The server must then pass the resulting response to GSS_Unwrap and
|
||||
interpret the first octet of resulting cleartext as the bit-mask for
|
||||
the selected security layer, the second through fourth octets as the
|
||||
maximum size output_message to send to the client, and the remaining
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 10]
|
||||
|
||||
RFC 2222 SASL October 1997
|
||||
|
||||
|
||||
octets as the authorization identity. The server must verify that
|
||||
the src_name is authorized to authenticate as the authorization
|
||||
identity. After these verifications, the authentication process is
|
||||
complete.
|
||||
|
||||
7.2.3 Security layer
|
||||
|
||||
The security layers and their corresponding bit-masks are as follows:
|
||||
|
||||
1 No security layer
|
||||
2 Integrity protection.
|
||||
Sender calls GSS_Wrap with conf_flag set to FALSE
|
||||
4 Privacy protection.
|
||||
Sender calls GSS_Wrap with conf_flag set to TRUE
|
||||
|
||||
Other bit-masks may be defined in the future; bits which are not
|
||||
understood must be negotiated off.
|
||||
|
||||
7.3. S/Key mechanism
|
||||
|
||||
The mechanism name associated with S/Key [RFC 1760] using the MD4
|
||||
digest algorithm is "SKEY".
|
||||
|
||||
The client sends an initial response with the authorization identity.
|
||||
|
||||
The server then issues a challenge which contains the decimal
|
||||
sequence number followed by a single space and the seed string for
|
||||
the indicated authorization identity. The client responds with the
|
||||
one-time-password, as either a 64-bit value in network byte order or
|
||||
encoded in the "six English words" format.
|
||||
|
||||
The server must verify the one-time-password. After this
|
||||
verification, the authentication process is complete.
|
||||
|
||||
S/Key authentication does not provide for any security layers.
|
||||
|
||||
EXAMPLE: The following are two S/Key login scenarios in the IMAP4
|
||||
protocol.
|
||||
|
||||
S: * OK IMAP4 Server
|
||||
C: A001 AUTHENTICATE SKEY
|
||||
S: +
|
||||
C: bW9yZ2Fu
|
||||
S: + OTUgUWE1ODMwOA==
|
||||
C: Rk9VUiBNQU5OIFNPT04gRklSIFZBUlkgTUFTSA==
|
||||
S: A001 OK S/Key authentication successful
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 11]
|
||||
|
||||
RFC 2222 SASL October 1997
|
||||
|
||||
|
||||
S: * OK IMAP4 Server
|
||||
C: A001 AUTHENTICATE SKEY
|
||||
S: +
|
||||
C: c21pdGg=
|
||||
S: + OTUgUWE1ODMwOA==
|
||||
C: BsAY3g4gBNo=
|
||||
S: A001 NO S/Key authentication failed
|
||||
|
||||
The following is an S/Key login scenario in an IMAP4-like protocol
|
||||
which has an optional "initial response" argument to the AUTHENTICATE
|
||||
command.
|
||||
|
||||
S: * OK IMAP4-Like Server
|
||||
C: A001 AUTHENTICATE SKEY bW9yZ2Fu
|
||||
S: + OTUgUWE1ODMwOA==
|
||||
C: Rk9VUiBNQU5OIFNPT04gRklSIFZBUlkgTUFTSA==
|
||||
S: A001 OK S/Key authentication successful
|
||||
|
||||
7.4. External mechanism
|
||||
|
||||
The mechanism name associated with external authentication is
|
||||
"EXTERNAL".
|
||||
|
||||
The client sends an initial response with the authorization identity.
|
||||
|
||||
The server uses information, external to SASL, to determine whether
|
||||
the client is authorized to authenticate as the authorization
|
||||
identity. If the client is so authorized, the server indicates
|
||||
successful completion of the authentication exchange; otherwise the
|
||||
server indicates failure.
|
||||
|
||||
The system providing this external information may be, for example,
|
||||
IPsec or TLS.
|
||||
|
||||
If the client sends the empty string as the authorization identity
|
||||
(thus requesting the authorization identity be derived from the
|
||||
client's authentication credentials), the authorization identity is
|
||||
to be derived from authentication credentials which exist in the
|
||||
system which is providing the external authentication.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 12]
|
||||
|
||||
RFC 2222 SASL October 1997
|
||||
|
||||
|
||||
8. References
|
||||
|
||||
[RFC 2060] Crispin, M., "Internet Message Access Protocol - Version
|
||||
4rev1", RFC 2060, December 1996.
|
||||
|
||||
[RFC 2078] Linn, J., "Generic Security Service Application Program
|
||||
Interface, Version 2", RFC 2078, January 1997.
|
||||
|
||||
[RFC 2119] Bradner, S., "Key words for use in RFCs to Indicate
|
||||
Requirement Levels", RFC 2119, March 1997.
|
||||
|
||||
[RFC 2223] Postel, J., and J. Reynolds, "Instructions to RFC
|
||||
Authors", RFC 2223, October 1997.
|
||||
|
||||
[RFC 1760] Haller, N., "The S/Key One-Time Password System", RFC
|
||||
1760, February 1995.
|
||||
|
||||
[RFC 1700] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2,
|
||||
RFC 1700, October 1994.
|
||||
|
||||
9. Security Considerations
|
||||
|
||||
Security issues are discussed throughout this memo.
|
||||
|
||||
The mechanisms that support integrity protection are designed such
|
||||
that the negotiation of the security layer and authorization identity
|
||||
is integrity protected. When the client selects a security layer
|
||||
with at least integrity protection, this protects against an active
|
||||
attacker hijacking the connection and modifying the authentication
|
||||
exchange to negotiate a plaintext connection.
|
||||
|
||||
When a server or client supports multiple authentication mechanisms,
|
||||
each of which has a different security strength, it is possible for
|
||||
an active attacker to cause a party to use the least secure mechanism
|
||||
supported. To protect against this sort of attack, a client or
|
||||
server which supports mechanisms of different strengths should have a
|
||||
configurable minimum strength that it will use. It is not sufficient
|
||||
for this minimum strength check to only be on the server, since an
|
||||
active attacker can change which mechanisms the client sees as being
|
||||
supported, causing the client to send authentication credentials for
|
||||
its weakest supported mechanism.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 13]
|
||||
|
||||
RFC 2222 SASL October 1997
|
||||
|
||||
|
||||
The client's selection of a SASL mechanism is done in the clear and
|
||||
may be modified by an active attacker. It is important for any new
|
||||
SASL mechanisms to be designed such that an active attacker cannot
|
||||
obtain an authentication with weaker security properties by modifying
|
||||
the SASL mechanism name and/or the challenges and responses.
|
||||
|
||||
Any protocol interactions prior to authentication are performed in
|
||||
the clear and may be modified by an active attacker. In the case
|
||||
where a client selects integrity protection, it is important that any
|
||||
security-sensitive protocol negotiations be performed after
|
||||
authentication is complete. Protocols should be designed such that
|
||||
negotiations performed prior to authentication should be either
|
||||
ignored or revalidated once authentication is complete.
|
||||
|
||||
10. Author's Address
|
||||
|
||||
John G. Myers
|
||||
Netscape Communications
|
||||
501 E. Middlefield Road
|
||||
Mail Stop MV-029
|
||||
Mountain View, CA 94043-4042
|
||||
|
||||
EMail: jgmyers@netscape.com
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 14]
|
||||
|
||||
RFC 2222 SASL October 1997
|
||||
|
||||
|
||||
Appendix A. Relation of SASL to Transport Security
|
||||
|
||||
Questions have been raised about the relationship between SASL and
|
||||
various services (such as IPsec and TLS) which provide a secured
|
||||
connection.
|
||||
|
||||
Two of the key features of SASL are:
|
||||
|
||||
1. The separation of the authorization identity from the identity in
|
||||
the client's credentials. This permits agents such as proxy
|
||||
servers to authenticate using their own credentials, yet request
|
||||
the access privileges of the identity for which they are proxying.
|
||||
|
||||
2. Upon successful completion of an authentication exchange, the
|
||||
server knows the authorization identity the client wishes to use.
|
||||
This allows servers to move to a "user is authenticated" state in
|
||||
the protocol.
|
||||
|
||||
These features are extremely important to some application protocols,
|
||||
yet Transport Security services do not always provide them. To
|
||||
define SASL mechanisms based on these services would be a very messy
|
||||
task, as the framing of these services would be redundant with the
|
||||
framing of SASL and some method of providing these important SASL
|
||||
features would have to be devised.
|
||||
|
||||
Sometimes it is desired to enable within an existing connection the
|
||||
use of a security service which does not fit the SASL model. (TLS is
|
||||
an example of such a service.) This can be done by adding a command,
|
||||
for example "STARTTLS", to the protocol. Such a command is outside
|
||||
the scope of SASL, and should be different from the command which
|
||||
starts a SASL authentication protocol exchange.
|
||||
|
||||
In certain situations, it is reasonable to use SASL underneath one of
|
||||
these Transport Security services. The transport service would
|
||||
secure the connection, either service would authenticate the client,
|
||||
and SASL would negotiate the authorization identity. The SASL
|
||||
negotiation would be what moves the protocol from "unauthenticated"
|
||||
to "authenticated" state. The "EXTERNAL" SASL mechanism is
|
||||
explicitly intended to handle the case where the transport service
|
||||
secures the connection and authenticates the client and SASL
|
||||
negotiates the authorization identity.
|
||||
|
||||
When using SASL underneath a sufficiently strong Transport Security
|
||||
service, a SASL security layer would most likely be redundant. The
|
||||
client and server would thus probably want to negotiate off the use
|
||||
of a SASL security layer.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 15]
|
||||
|
||||
RFC 2222 SASL October 1997
|
||||
|
||||
|
||||
Full Copyright Statement
|
||||
|
||||
Copyright (C) The Internet Society (1997). All Rights Reserved.
|
||||
|
||||
This document and translations of it may be copied and furnished to
|
||||
others, and derivative works that comment on or otherwise explain it
|
||||
or assist in its implmentation may be prepared, copied, published
|
||||
andand distributed, in whole or in part, without restriction of any
|
||||
kind, provided that the above copyright notice and this paragraph are
|
||||
included on all such copies and derivative works. However, this
|
||||
document itself may not be modified in any way, such as by removing
|
||||
the copyright notice or references to the Internet Society or other
|
||||
Internet organizations, except as needed for the purpose of
|
||||
developing Internet standards in which case the procedures for
|
||||
copyrights defined in the Internet Standards process must be
|
||||
followed, or as required to translate it into languages other than
|
||||
English.
|
||||
|
||||
The limited permissions granted above are perpetual and will not be
|
||||
revoked by the Internet Society or its successors or assigns.
|
||||
|
||||
This document and the information contained herein is provided on an
|
||||
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
|
||||
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
|
||||
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
|
||||
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 16]
|
||||
|
|
@ -1,787 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group D. Crocker, Ed.
|
||||
Request for Comments: 2234 Internet Mail Consortium
|
||||
Category: Standards Track P. Overell
|
||||
Demon Internet Ltd.
|
||||
November 1997
|
||||
|
||||
|
||||
Augmented BNF for Syntax Specifications: ABNF
|
||||
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This document specifies an Internet standards track protocol for the
|
||||
Internet community, and requests discussion and suggestions for
|
||||
improvements. Please refer to the current edition of the "Internet
|
||||
Official Protocol Standards" (STD 1) for the standardization state
|
||||
and status of this protocol. Distribution of this memo is unlimited.
|
||||
|
||||
Copyright Notice
|
||||
|
||||
Copyright (C) The Internet Society (1997). All Rights Reserved.
|
||||
|
||||
TABLE OF CONTENTS
|
||||
|
||||
1. INTRODUCTION .................................................. 2
|
||||
|
||||
2. RULE DEFINITION ............................................... 2
|
||||
2.1 RULE NAMING .................................................. 2
|
||||
2.2 RULE FORM .................................................... 3
|
||||
2.3 TERMINAL VALUES .............................................. 3
|
||||
2.4 EXTERNAL ENCODINGS ........................................... 5
|
||||
|
||||
3. OPERATORS ..................................................... 5
|
||||
3.1 CONCATENATION RULE1 RULE2 ............................. 5
|
||||
3.2 ALTERNATIVES RULE1 / RULE2 ................................... 6
|
||||
3.3 INCREMENTAL ALTERNATIVES RULE1 =/ RULE2 .................... 6
|
||||
3.4 VALUE RANGE ALTERNATIVES %C##-## ........................... 7
|
||||
3.5 SEQUENCE GROUP (RULE1 RULE2) ................................. 7
|
||||
3.6 VARIABLE REPETITION *RULE .................................... 8
|
||||
3.7 SPECIFIC REPETITION NRULE .................................... 8
|
||||
3.8 OPTIONAL SEQUENCE [RULE] ..................................... 8
|
||||
3.9 ; COMMENT .................................................... 8
|
||||
3.10 OPERATOR PRECEDENCE ......................................... 9
|
||||
|
||||
4. ABNF DEFINITION OF ABNF ....................................... 9
|
||||
|
||||
5. SECURITY CONSIDERATIONS ....................................... 10
|
||||
|
||||
|
||||
|
||||
|
||||
Crocker & Overell Standards Track [Page 1]
|
||||
|
||||
RFC 2234 ABNF for Syntax Specifications November 1997
|
||||
|
||||
|
||||
6. APPENDIX A - CORE ............................................. 11
|
||||
6.1 CORE RULES ................................................... 11
|
||||
6.2 COMMON ENCODING .............................................. 12
|
||||
|
||||
7. ACKNOWLEDGMENTS ............................................... 12
|
||||
|
||||
8. REFERENCES .................................................... 13
|
||||
|
||||
9. CONTACT ....................................................... 13
|
||||
|
||||
10. FULL COPYRIGHT STATEMENT ..................................... 14
|
||||
|
||||
1. INTRODUCTION
|
||||
|
||||
Internet technical specifications often need to define a format
|
||||
syntax and are free to employ whatever notation their authors deem
|
||||
useful. Over the years, a modified version of Backus-Naur Form
|
||||
(BNF), called Augmented BNF (ABNF), has been popular among many
|
||||
Internet specifications. It balances compactness and simplicity,
|
||||
with reasonable representational power. In the early days of the
|
||||
Arpanet, each specification contained its own definition of ABNF.
|
||||
This included the email specifications, RFC733 and then RFC822 which
|
||||
have come to be the common citations for defining ABNF. The current
|
||||
document separates out that definition, to permit selective
|
||||
reference. Predictably, it also provides some modifications and
|
||||
enhancements.
|
||||
|
||||
The differences between standard BNF and ABNF involve naming rules,
|
||||
repetition, alternatives, order-independence, and value ranges.
|
||||
Appendix A (Core) supplies rule definitions and encoding for a core
|
||||
lexical analyzer of the type common to several Internet
|
||||
specifications. It is provided as a convenience and is otherwise
|
||||
separate from the meta language defined in the body of this document,
|
||||
and separate from its formal status.
|
||||
|
||||
2. RULE DEFINITION
|
||||
|
||||
2.1 Rule Naming
|
||||
|
||||
The name of a rule is simply the name itself; that is, a sequence of
|
||||
characters, beginning with an alphabetic character, and followed by
|
||||
a combination of alphabetics, digits and hyphens (dashes).
|
||||
|
||||
NOTE: Rule names are case-insensitive
|
||||
|
||||
The names <rulename>, <Rulename>, <RULENAME> and <rUlENamE> all refer
|
||||
to the same rule.
|
||||
|
||||
|
||||
|
||||
|
||||
Crocker & Overell Standards Track [Page 2]
|
||||
|
||||
RFC 2234 ABNF for Syntax Specifications November 1997
|
||||
|
||||
|
||||
Unlike original BNF, angle brackets ("<", ">") are not required.
|
||||
However, angle brackets may be used around a rule name whenever their
|
||||
presence will facilitate discerning the use of a rule name. This is
|
||||
typically restricted to rule name references in free-form prose, or
|
||||
to distinguish partial rules that combine into a string not separated
|
||||
by white space, such as shown in the discussion about repetition,
|
||||
below.
|
||||
|
||||
2.2 Rule Form
|
||||
|
||||
A rule is defined by the following sequence:
|
||||
|
||||
name = elements crlf
|
||||
|
||||
where <name> is the name of the rule, <elements> is one or more rule
|
||||
names or terminal specifications and <crlf> is the end-of- line
|
||||
indicator, carriage return followed by line feed. The equal sign
|
||||
separates the name from the definition of the rule. The elements
|
||||
form a sequence of one or more rule names and/or value definitions,
|
||||
combined according to the various operators, defined in this
|
||||
document, such as alternative and repetition.
|
||||
|
||||
For visual ease, rule definitions are left aligned. When a rule
|
||||
requires multiple lines, the continuation lines are indented. The
|
||||
left alignment and indentation are relative to the first lines of the
|
||||
ABNF rules and need not match the left margin of the document.
|
||||
|
||||
2.3 Terminal Values
|
||||
|
||||
Rules resolve into a string of terminal values, sometimes called
|
||||
characters. In ABNF a character is merely a non-negative integer.
|
||||
In certain contexts a specific mapping (encoding) of values into a
|
||||
character set (such as ASCII) will be specified.
|
||||
|
||||
Terminals are specified by one or more numeric characters with the
|
||||
base interpretation of those characters indicated explicitly. The
|
||||
following bases are currently defined:
|
||||
|
||||
b = binary
|
||||
|
||||
d = decimal
|
||||
|
||||
x = hexadecimal
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crocker & Overell Standards Track [Page 3]
|
||||
|
||||
RFC 2234 ABNF for Syntax Specifications November 1997
|
||||
|
||||
|
||||
Hence:
|
||||
|
||||
CR = %d13
|
||||
|
||||
CR = %x0D
|
||||
|
||||
respectively specify the decimal and hexadecimal representation of
|
||||
[US-ASCII] for carriage return.
|
||||
|
||||
A concatenated string of such values is specified compactly, using a
|
||||
period (".") to indicate separation of characters within that value.
|
||||
Hence:
|
||||
|
||||
CRLF = %d13.10
|
||||
|
||||
ABNF permits specifying literal text string directly, enclosed in
|
||||
quotation-marks. Hence:
|
||||
|
||||
command = "command string"
|
||||
|
||||
Literal text strings are interpreted as a concatenated set of
|
||||
printable characters.
|
||||
|
||||
NOTE: ABNF strings are case-insensitive and
|
||||
the character set for these strings is us-ascii.
|
||||
|
||||
Hence:
|
||||
|
||||
rulename = "abc"
|
||||
|
||||
and:
|
||||
|
||||
rulename = "aBc"
|
||||
|
||||
will match "abc", "Abc", "aBc", "abC", "ABc", "aBC", "AbC" and "ABC".
|
||||
|
||||
To specify a rule which IS case SENSITIVE,
|
||||
specify the characters individually.
|
||||
|
||||
For example:
|
||||
|
||||
rulename = %d97 %d98 %d99
|
||||
|
||||
or
|
||||
|
||||
rulename = %d97.98.99
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crocker & Overell Standards Track [Page 4]
|
||||
|
||||
RFC 2234 ABNF for Syntax Specifications November 1997
|
||||
|
||||
|
||||
will match only the string which comprises only lowercased
|
||||
characters, abc.
|
||||
|
||||
2.4 External Encodings
|
||||
|
||||
External representations of terminal value characters will vary
|
||||
according to constraints in the storage or transmission environment.
|
||||
Hence, the same ABNF-based grammar may have multiple external
|
||||
encodings, such as one for a 7-bit US-ASCII environment, another for
|
||||
a binary octet environment and still a different one when 16-bit
|
||||
Unicode is used. Encoding details are beyond the scope of ABNF,
|
||||
although Appendix A (Core) provides definitions for a 7-bit US-ASCII
|
||||
environment as has been common to much of the Internet.
|
||||
|
||||
By separating external encoding from the syntax, it is intended that
|
||||
alternate encoding environments can be used for the same syntax.
|
||||
|
||||
3. OPERATORS
|
||||
|
||||
3.1 Concatenation Rule1 Rule2
|
||||
|
||||
A rule can define a simple, ordered string of values -- i.e., a
|
||||
concatenation of contiguous characters -- by listing a sequence of
|
||||
rule names. For example:
|
||||
|
||||
foo = %x61 ; a
|
||||
|
||||
bar = %x62 ; b
|
||||
|
||||
mumble = foo bar foo
|
||||
|
||||
So that the rule <mumble> matches the lowercase string "aba".
|
||||
|
||||
LINEAR WHITE SPACE: Concatenation is at the core of the ABNF
|
||||
parsing model. A string of contiguous characters (values) is
|
||||
parsed according to the rules defined in ABNF. For Internet
|
||||
specifications, there is some history of permitting linear white
|
||||
space (space and horizontal tab) to be freelyPand
|
||||
implicitlyPinterspersed around major constructs, such as
|
||||
delimiting special characters or atomic strings.
|
||||
|
||||
NOTE: This specification for ABNF does not
|
||||
provide for implicit specification of linear white
|
||||
space.
|
||||
|
||||
Any grammar which wishes to permit linear white space around
|
||||
delimiters or string segments must specify it explicitly. It is
|
||||
often useful to provide for such white space in "core" rules that are
|
||||
|
||||
|
||||
|
||||
Crocker & Overell Standards Track [Page 5]
|
||||
|
||||
RFC 2234 ABNF for Syntax Specifications November 1997
|
||||
|
||||
|
||||
then used variously among higher-level rules. The "core" rules might
|
||||
be formed into a lexical analyzer or simply be part of the main
|
||||
ruleset.
|
||||
|
||||
3.2 Alternatives Rule1 / Rule2
|
||||
|
||||
Elements separated by forward slash ("/") are alternatives.
|
||||
Therefore,
|
||||
|
||||
foo / bar
|
||||
|
||||
will accept <foo> or <bar>.
|
||||
|
||||
NOTE: A quoted string containing alphabetic
|
||||
characters is special form for specifying alternative
|
||||
characters and is interpreted as a non-terminal
|
||||
representing the set of combinatorial strings with the
|
||||
contained characters, in the specified order but with
|
||||
any mixture of upper and lower case..
|
||||
|
||||
3.3 Incremental Alternatives Rule1 =/ Rule2
|
||||
|
||||
It is sometimes convenient to specify a list of alternatives in
|
||||
fragments. That is, an initial rule may match one or more
|
||||
alternatives, with later rule definitions adding to the set of
|
||||
alternatives. This is particularly useful for otherwise- independent
|
||||
specifications which derive from the same parent rule set, such as
|
||||
often occurs with parameter lists. ABNF permits this incremental
|
||||
definition through the construct:
|
||||
|
||||
oldrule =/ additional-alternatives
|
||||
|
||||
So that the rule set
|
||||
|
||||
ruleset = alt1 / alt2
|
||||
|
||||
ruleset =/ alt3
|
||||
|
||||
ruleset =/ alt4 / alt5
|
||||
|
||||
is the same as specifying
|
||||
|
||||
ruleset = alt1 / alt2 / alt3 / alt4 / alt5
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crocker & Overell Standards Track [Page 6]
|
||||
|
||||
RFC 2234 ABNF for Syntax Specifications November 1997
|
||||
|
||||
|
||||
3.4 Value Range Alternatives %c##-##
|
||||
|
||||
A range of alternative numeric values can be specified compactly,
|
||||
using dash ("-") to indicate the range of alternative values. Hence:
|
||||
|
||||
DIGIT = %x30-39
|
||||
|
||||
is equivalent to:
|
||||
|
||||
DIGIT = "0" / "1" / "2" / "3" / "4" / "5" / "6" /
|
||||
|
||||
"7" / "8" / "9"
|
||||
|
||||
Concatenated numeric values and numeric value ranges can not be
|
||||
specified in the same string. A numeric value may use the dotted
|
||||
notation for concatenation or it may use the dash notation to specify
|
||||
one value range. Hence, to specify one printable character, between
|
||||
end of line sequences, the specification could be:
|
||||
|
||||
char-line = %x0D.0A %x20-7E %x0D.0A
|
||||
|
||||
3.5 Sequence Group (Rule1 Rule2)
|
||||
|
||||
Elements enclosed in parentheses are treated as a single element,
|
||||
whose contents are STRICTLY ORDERED. Thus,
|
||||
|
||||
elem (foo / bar) blat
|
||||
|
||||
which matches (elem foo blat) or (elem bar blat).
|
||||
|
||||
elem foo / bar blat
|
||||
|
||||
matches (elem foo) or (bar blat).
|
||||
|
||||
NOTE: It is strongly advised to use grouping
|
||||
notation, rather than to rely on proper reading of
|
||||
"bare" alternations, when alternatives consist of
|
||||
multiple rule names or literals.
|
||||
|
||||
Hence it is recommended that instead of the above form, the form:
|
||||
|
||||
(elem foo) / (bar blat)
|
||||
|
||||
be used. It will avoid misinterpretation by casual readers.
|
||||
|
||||
The sequence group notation is also used within free text to set off
|
||||
an element sequence from the prose.
|
||||
|
||||
|
||||
|
||||
|
||||
Crocker & Overell Standards Track [Page 7]
|
||||
|
||||
RFC 2234 ABNF for Syntax Specifications November 1997
|
||||
|
||||
|
||||
3.6 Variable Repetition *Rule
|
||||
|
||||
The operator "*" preceding an element indicates repetition. The full
|
||||
form is:
|
||||
|
||||
<a>*<b>element
|
||||
|
||||
where <a> and <b> are optional decimal values, indicating at least
|
||||
<a> and at most <b> occurrences of element.
|
||||
|
||||
Default values are 0 and infinity so that *<element> allows any
|
||||
number, including zero; 1*<element> requires at least one;
|
||||
3*3<element> allows exactly 3 and 1*2<element> allows one or two.
|
||||
|
||||
3.7 Specific Repetition nRule
|
||||
|
||||
A rule of the form:
|
||||
|
||||
<n>element
|
||||
|
||||
is equivalent to
|
||||
|
||||
<n>*<n>element
|
||||
|
||||
That is, exactly <N> occurrences of <element>. Thus 2DIGIT is a
|
||||
2-digit number, and 3ALPHA is a string of three alphabetic
|
||||
characters.
|
||||
|
||||
3.8 Optional Sequence [RULE]
|
||||
|
||||
Square brackets enclose an optional element sequence:
|
||||
|
||||
[foo bar]
|
||||
|
||||
is equivalent to
|
||||
|
||||
*1(foo bar).
|
||||
|
||||
3.9 ; Comment
|
||||
|
||||
A semi-colon starts a comment that continues to the end of line.
|
||||
This is a simple way of including useful notes in parallel with the
|
||||
specifications.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crocker & Overell Standards Track [Page 8]
|
||||
|
||||
RFC 2234 ABNF for Syntax Specifications November 1997
|
||||
|
||||
|
||||
3.10 Operator Precedence
|
||||
|
||||
The various mechanisms described above have the following precedence,
|
||||
from highest (binding tightest) at the top, to lowest and loosest at
|
||||
the bottom:
|
||||
|
||||
Strings, Names formation
|
||||
Comment
|
||||
Value range
|
||||
Repetition
|
||||
Grouping, Optional
|
||||
Concatenation
|
||||
Alternative
|
||||
|
||||
Use of the alternative operator, freely mixed with concatenations can
|
||||
be confusing.
|
||||
|
||||
Again, it is recommended that the grouping operator be used to
|
||||
make explicit concatenation groups.
|
||||
|
||||
4. ABNF DEFINITION OF ABNF
|
||||
|
||||
This syntax uses the rules provided in Appendix A (Core).
|
||||
|
||||
rulelist = 1*( rule / (*c-wsp c-nl) )
|
||||
|
||||
rule = rulename defined-as elements c-nl
|
||||
; continues if next line starts
|
||||
; with white space
|
||||
|
||||
rulename = ALPHA *(ALPHA / DIGIT / "-")
|
||||
|
||||
defined-as = *c-wsp ("=" / "=/") *c-wsp
|
||||
; basic rules definition and
|
||||
; incremental alternatives
|
||||
|
||||
elements = alternation *c-wsp
|
||||
|
||||
c-wsp = WSP / (c-nl WSP)
|
||||
|
||||
c-nl = comment / CRLF
|
||||
; comment or newline
|
||||
|
||||
comment = ";" *(WSP / VCHAR) CRLF
|
||||
|
||||
alternation = concatenation
|
||||
*(*c-wsp "/" *c-wsp concatenation)
|
||||
|
||||
|
||||
|
||||
|
||||
Crocker & Overell Standards Track [Page 9]
|
||||
|
||||
RFC 2234 ABNF for Syntax Specifications November 1997
|
||||
|
||||
|
||||
concatenation = repetition *(1*c-wsp repetition)
|
||||
|
||||
repetition = [repeat] element
|
||||
|
||||
repeat = 1*DIGIT / (*DIGIT "*" *DIGIT)
|
||||
|
||||
element = rulename / group / option /
|
||||
char-val / num-val / prose-val
|
||||
|
||||
group = "(" *c-wsp alternation *c-wsp ")"
|
||||
|
||||
option = "[" *c-wsp alternation *c-wsp "]"
|
||||
|
||||
char-val = DQUOTE *(%x20-21 / %x23-7E) DQUOTE
|
||||
; quoted string of SP and VCHAR
|
||||
without DQUOTE
|
||||
|
||||
num-val = "%" (bin-val / dec-val / hex-val)
|
||||
|
||||
bin-val = "b" 1*BIT
|
||||
[ 1*("." 1*BIT) / ("-" 1*BIT) ]
|
||||
; series of concatenated bit values
|
||||
; or single ONEOF range
|
||||
|
||||
dec-val = "d" 1*DIGIT
|
||||
[ 1*("." 1*DIGIT) / ("-" 1*DIGIT) ]
|
||||
|
||||
hex-val = "x" 1*HEXDIG
|
||||
[ 1*("." 1*HEXDIG) / ("-" 1*HEXDIG) ]
|
||||
|
||||
prose-val = "<" *(%x20-3D / %x3F-7E) ">"
|
||||
; bracketed string of SP and VCHAR
|
||||
without angles
|
||||
; prose description, to be used as
|
||||
last resort
|
||||
|
||||
|
||||
5. SECURITY CONSIDERATIONS
|
||||
|
||||
Security is truly believed to be irrelevant to this document.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crocker & Overell Standards Track [Page 10]
|
||||
|
||||
RFC 2234 ABNF for Syntax Specifications November 1997
|
||||
|
||||
|
||||
6. APPENDIX A - CORE
|
||||
|
||||
This Appendix is provided as a convenient core for specific grammars.
|
||||
The definitions may be used as a core set of rules.
|
||||
|
||||
6.1 Core Rules
|
||||
|
||||
Certain basic rules are in uppercase, such as SP, HTAB, CRLF,
|
||||
DIGIT, ALPHA, etc.
|
||||
|
||||
ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
|
||||
|
||||
BIT = "0" / "1"
|
||||
|
||||
CHAR = %x01-7F
|
||||
; any 7-bit US-ASCII character,
|
||||
excluding NUL
|
||||
|
||||
CR = %x0D
|
||||
; carriage return
|
||||
|
||||
CRLF = CR LF
|
||||
; Internet standard newline
|
||||
|
||||
CTL = %x00-1F / %x7F
|
||||
; controls
|
||||
|
||||
DIGIT = %x30-39
|
||||
; 0-9
|
||||
|
||||
DQUOTE = %x22
|
||||
; " (Double Quote)
|
||||
|
||||
HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
|
||||
|
||||
HTAB = %x09
|
||||
; horizontal tab
|
||||
|
||||
LF = %x0A
|
||||
; linefeed
|
||||
|
||||
LWSP = *(WSP / CRLF WSP)
|
||||
; linear white space (past newline)
|
||||
|
||||
OCTET = %x00-FF
|
||||
; 8 bits of data
|
||||
|
||||
SP = %x20
|
||||
|
||||
|
||||
|
||||
Crocker & Overell Standards Track [Page 11]
|
||||
|
||||
RFC 2234 ABNF for Syntax Specifications November 1997
|
||||
|
||||
|
||||
; space
|
||||
|
||||
VCHAR = %x21-7E
|
||||
; visible (printing) characters
|
||||
|
||||
WSP = SP / HTAB
|
||||
; white space
|
||||
|
||||
6.2 Common Encoding
|
||||
|
||||
Externally, data are represented as "network virtual ASCII", namely
|
||||
7-bit US-ASCII in an 8-bit field, with the high (8th) bit set to
|
||||
zero. A string of values is in "network byte order" with the
|
||||
higher-valued bytes represented on the left-hand side and being sent
|
||||
over the network first.
|
||||
|
||||
7. ACKNOWLEDGMENTS
|
||||
|
||||
The syntax for ABNF was originally specified in RFC 733. Ken L.
|
||||
Harrenstien, of SRI International, was responsible for re-coding the
|
||||
BNF into an augmented BNF that makes the representation smaller and
|
||||
easier to understand.
|
||||
|
||||
This recent project began as a simple effort to cull out the portion
|
||||
of RFC 822 which has been repeatedly cited by non-email specification
|
||||
writers, namely the description of augmented BNF. Rather than simply
|
||||
and blindly converting the existing text into a separate document,
|
||||
the working group chose to give careful consideration to the
|
||||
deficiencies, as well as benefits, of the existing specification and
|
||||
related specifications available over the last 15 years and therefore
|
||||
to pursue enhancement. This turned the project into something rather
|
||||
more ambitious than first intended. Interestingly the result is not
|
||||
massively different from that original, although decisions such as
|
||||
removing the list notation came as a surprise.
|
||||
|
||||
The current round of specification was part of the DRUMS working
|
||||
group, with significant contributions from Jerome Abela , Harald
|
||||
Alvestrand, Robert Elz, Roger Fajman, Aviva Garrett, Tom Harsch, Dan
|
||||
Kohn, Bill McQuillan, Keith Moore, Chris Newman , Pete Resnick and
|
||||
Henning Schulzrinne.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crocker & Overell Standards Track [Page 12]
|
||||
|
||||
RFC 2234 ABNF for Syntax Specifications November 1997
|
||||
|
||||
|
||||
8. REFERENCES
|
||||
|
||||
[US-ASCII] Coded Character Set--7-Bit American Standard Code for
|
||||
Information Interchange, ANSI X3.4-1986.
|
||||
|
||||
[RFC733] Crocker, D., Vittal, J., Pogran, K., and D. Henderson,
|
||||
"Standard for the Format of ARPA Network Text Message," RFC 733,
|
||||
November 1977.
|
||||
|
||||
[RFC822] Crocker, D., "Standard for the Format of ARPA Internet Text
|
||||
Messages", STD 11, RFC 822, August 1982.
|
||||
|
||||
9. CONTACT
|
||||
|
||||
David H. Crocker Paul Overell
|
||||
|
||||
Internet Mail Consortium Demon Internet Ltd
|
||||
675 Spruce Dr. Dorking Business Park
|
||||
Sunnyvale, CA 94086 USA Dorking
|
||||
Surrey, RH4 1HN
|
||||
UK
|
||||
|
||||
Phone: +1 408 246 8253
|
||||
Fax: +1 408 249 6205
|
||||
EMail: dcrocker@imc.org paulo@turnpike.com
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crocker & Overell Standards Track [Page 13]
|
||||
|
||||
RFC 2234 ABNF for Syntax Specifications November 1997
|
||||
|
||||
|
||||
10. Full Copyright Statement
|
||||
|
||||
Copyright (C) The Internet Society (1997). All Rights Reserved.
|
||||
|
||||
This document and translations of it may be copied and furnished to
|
||||
others, and derivative works that comment on or otherwise explain it
|
||||
or assist in its implementation may be prepared, copied, published
|
||||
and distributed, in whole or in part, without restriction of any
|
||||
kind, provided that the above copyright notice and this paragraph are
|
||||
included on all such copies and derivative works. However, this
|
||||
document itself may not be modified in any way, such as by removing
|
||||
the copyright notice or references to the Internet Society or other
|
||||
Internet organizations, except as needed for the purpose of
|
||||
developing Internet standards in which case the procedures for
|
||||
copyrights defined in the Internet Standards process must be
|
||||
followed, or as required to translate it into languages other than
|
||||
English.
|
||||
|
||||
The limited permissions granted above are perpetual and will not be
|
||||
revoked by the Internet Society or its successors or assigns.
|
||||
|
||||
This document and the information contained herein is provided on an
|
||||
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
|
||||
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
|
||||
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
|
||||
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Crocker & Overell Standards Track [Page 14]
|
||||
|
|
@ -1,283 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group C. Newman
|
||||
Request for Comments: 2245 Innosoft
|
||||
Category: Standards Track November 1997
|
||||
|
||||
|
||||
Anonymous SASL Mechanism
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This document specifies an Internet standards track protocol for the
|
||||
Internet community, and requests discussion and suggestions for
|
||||
improvements. Please refer to the current edition of the "Internet
|
||||
Official Protocol Standards" (STD 1) for the standardization state
|
||||
and status of this protocol. Distribution of this memo is unlimited.
|
||||
|
||||
Copyright Notice
|
||||
|
||||
Copyright (C) The Internet Society (1997). All Rights Reserved.
|
||||
|
||||
Abstract
|
||||
|
||||
It is common practice on the Internet to permit anonymous access to
|
||||
various services. Traditionally, this has been done with a plain
|
||||
text password mechanism using "anonymous" as the user name and
|
||||
optional trace information, such as an email address, as the
|
||||
password. As plaintext login commands are not permitted in new IETF
|
||||
protocols, a new way to provide anonymous login is needed within the
|
||||
context of the SASL [SASL] framework.
|
||||
|
||||
1. Conventions Used in this Document
|
||||
|
||||
The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY"
|
||||
in this document are to be interpreted as defined in "Key words for
|
||||
use in RFCs to Indicate Requirement Levels" [KEYWORDS].
|
||||
|
||||
2. Anonymous SASL mechanism
|
||||
|
||||
The mechanism name associated with anonymous access is "ANONYMOUS".
|
||||
The mechanism consists of a single message from the client to the
|
||||
server. The client sends optional trace information in the form of a
|
||||
human readable string. The trace information should take one of
|
||||
three forms: an Internet email address, an opaque string which does
|
||||
not contain the '@' character and can be interpreted by the system
|
||||
administrator of the client's domain, or nothing. For privacy
|
||||
reasons, an Internet email address should only be used with
|
||||
permission from the user.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 1]
|
||||
|
||||
RFC 2245 Anonymous SASL Mechanism November 1997
|
||||
|
||||
|
||||
A server which permits anonymous access will announce support for the
|
||||
ANONYMOUS mechanism, and allow anyone to log in using that mechanism,
|
||||
usually with restricted access.
|
||||
|
||||
The formal grammar for the client message using Augmented BNF [ABNF]
|
||||
follows.
|
||||
|
||||
message = [email / token]
|
||||
|
||||
TCHAR = %x20-3F / %x41-7E
|
||||
;; any printable US-ASCII character except '@'
|
||||
|
||||
email = addr-spec
|
||||
;; as defined in [IMAIL], except with no free
|
||||
;; insertion of linear-white-space, and the
|
||||
;; local-part MUST either be entirely enclosed in
|
||||
;; quotes or entirely unquoted
|
||||
|
||||
token = 1*255TCHAR
|
||||
|
||||
3. Example
|
||||
|
||||
|
||||
Here is a sample anonymous login between an IMAP client and server.
|
||||
In this example, "C:" and "S:" indicate lines sent by the client and
|
||||
server respectively. If such lines are wrapped without a new "C:" or
|
||||
"S:" label, then the wrapping is for editorial clarity and is not
|
||||
part of the command.
|
||||
|
||||
Note that this example uses the IMAP profile [IMAP4] of SASL. The
|
||||
base64 encoding of challenges and responses, as well as the "+ "
|
||||
preceding the responses are part of the IMAP4 profile, not part of
|
||||
SASL itself. Newer profiles of SASL will include the client message
|
||||
with the AUTHENTICATE command itself so the extra round trip below
|
||||
(the server response with an empty "+ ") can be eliminated.
|
||||
|
||||
In this example, the user's opaque identification token is "sirhc".
|
||||
|
||||
S: * OK IMAP4 server ready
|
||||
C: A001 CAPABILITY
|
||||
S: * CAPABILITY IMAP4 IMAP4rev1 AUTH=CRAM-MD5 AUTH=ANONYMOUS
|
||||
S: A001 OK done
|
||||
C: A002 AUTHENTICATE ANONYMOUS
|
||||
S: +
|
||||
C: c2lyaGM=
|
||||
S: A003 OK Welcome, trace information has been logged.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 2]
|
||||
|
||||
RFC 2245 Anonymous SASL Mechanism November 1997
|
||||
|
||||
|
||||
4. Security Considerations
|
||||
|
||||
The anonymous mechanism grants access to information by anyone. For
|
||||
this reason it should be disabled by default so the administrator can
|
||||
make an explicit decision to enable it.
|
||||
|
||||
If the anonymous user has any write privileges, a denial of service
|
||||
attack is possible by filling up all available space. This can be
|
||||
prevented by disabling all write access by anonymous users.
|
||||
|
||||
If anonymous users have read and write access to the same area, the
|
||||
server can be used as a communication mechanism to anonymously
|
||||
exchange information. Servers which accept anonymous submissions
|
||||
should implement the common "drop box" model which forbids anonymous
|
||||
read access to the area where anonymous submissions are accepted.
|
||||
|
||||
If the anonymous user can run many expensive operations (e.g., an
|
||||
IMAP SEARCH BODY command), this could enable a denial of service
|
||||
attack. Servers are encouraged to limit the number of anonymous
|
||||
users and reduce their priority or limit their resource usage.
|
||||
|
||||
If there is no idle timeout for the anonymous user and there is a
|
||||
limit on the number of anonymous users, a denial of service attack is
|
||||
enabled. Servers should implement an idle timeout for anonymous
|
||||
users.
|
||||
|
||||
The trace information is not authenticated so it can be falsified.
|
||||
This can be used as an attempt to get someone else in trouble for
|
||||
access to questionable information. Administrators trying to trace
|
||||
abuse need to realize this information may be falsified.
|
||||
|
||||
A client which uses the user's correct email address as trace
|
||||
information without explicit permission may violate that user's
|
||||
privacy. Information about who accesses an anonymous archive on a
|
||||
sensitive subject (e.g., sexual abuse) has strong privacy needs.
|
||||
Clients should not send the email address without explicit permission
|
||||
of the user and should offer the option of supplying no trace token
|
||||
-- thus only exposing the source IP address and time. Anonymous
|
||||
proxy servers could enhance this privacy, but would have to consider
|
||||
the resulting potential denial of service attacks.
|
||||
|
||||
Anonymous connections are susceptible to man in the middle attacks
|
||||
which view or alter the data transferred. Clients and servers are
|
||||
encouraged to support external integrity and encryption mechanisms.
|
||||
|
||||
Protocols which fail to require an explicit anonymous login are more
|
||||
susceptible to break-ins given certain common implementation
|
||||
techniques. Specifically, Unix servers which offer user login may
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 3]
|
||||
|
||||
RFC 2245 Anonymous SASL Mechanism November 1997
|
||||
|
||||
|
||||
initially start up as root and switch to the appropriate user id
|
||||
after an explicit login command. Normally such servers refuse all
|
||||
data access commands prior to explicit login and may enter a
|
||||
restricted security environment (e.g., the Unix chroot function) for
|
||||
anonymous users. If anonymous access is not explicitly requested,
|
||||
the entire data access machinery is exposed to external security
|
||||
attacks without the chance for explicit protective measures.
|
||||
Protocols which offer restricted data access should not allow
|
||||
anonymous data access without an explicit login step.
|
||||
|
||||
5. References
|
||||
|
||||
[ABNF] Crocker, D. and P. Overell, "Augmented BNF for Syntax
|
||||
Specifications: ABNF", RFC 2234, November 1997.
|
||||
|
||||
[IMAIL] Crocker, D., "Standard for the Format of Arpa Internet Text
|
||||
Messages", STD 11, RFC 822, August 1982.
|
||||
|
||||
[IMAP4] Crispin, M., "Internet Message Access Protocol - Version
|
||||
4rev1", RFC 2060, December 1996.
|
||||
|
||||
[KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate
|
||||
Requirement Levels", RFC 2119, March 1997.
|
||||
|
||||
[SASL] Myers, J., "Simple Authentication and Security Layer (SASL)",
|
||||
RFC 2222, October 1997.
|
||||
|
||||
6. Author's Address
|
||||
|
||||
Chris Newman
|
||||
Innosoft International, Inc.
|
||||
1050 Lakes Drive
|
||||
West Covina, CA 91790 USA
|
||||
|
||||
Email: chris.newman@innosoft.com
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 4]
|
||||
|
||||
RFC 2245 Anonymous SASL Mechanism November 1997
|
||||
|
||||
|
||||
7. Full Copyright Statement
|
||||
|
||||
Copyright (C) The Internet Society (1997). All Rights Reserved.
|
||||
|
||||
This document and translations of it may be copied and furnished to
|
||||
others, and derivative works that comment on or otherwise explain it
|
||||
or assist in its implementation may be prepared, copied, published
|
||||
and distributed, in whole or in part, without restriction of any
|
||||
kind, provided that the above copyright notice and this paragraph are
|
||||
included on all such copies and derivative works. However, this
|
||||
document itself may not be modified in any way, such as by removing
|
||||
the copyright notice or references to the Internet Society or other
|
||||
Internet organizations, except as needed for the purpose of
|
||||
developing Internet standards in which case the procedures for
|
||||
copyrights defined in the Internet Standards process must be
|
||||
followed, or as required to translate it into languages other than
|
||||
English.
|
||||
|
||||
The limited permissions granted above are perpetual and will not be
|
||||
revoked by the Internet Society or its successors or assigns.
|
||||
|
||||
This document and the information contained herein is provided on an
|
||||
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
|
||||
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
|
||||
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
|
||||
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Newman Standards Track [Page 5]
|
||||
|
|
@ -1,563 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group M. Gahrns
|
||||
Request for Comments: 2342 Microsoft
|
||||
Category: Standards Track C. Newman
|
||||
Innosoft
|
||||
May 1998
|
||||
|
||||
|
||||
IMAP4 Namespace
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This document specifies an Internet standards track protocol for the
|
||||
Internet community, and requests discussion and suggestions for
|
||||
improvements. Please refer to the current edition of the "Internet
|
||||
Official Protocol Standards" (STD 1) for the standardization state
|
||||
and status of this protocol. Distribution of this memo is unlimited.
|
||||
|
||||
Copyright Notice
|
||||
|
||||
Copyright (C) The Internet Society (1998). All Rights Reserved.
|
||||
|
||||
1. Abstract
|
||||
|
||||
IMAP4 [RFC-2060] does not define a default server namespace. As a
|
||||
result, two common namespace models have evolved:
|
||||
|
||||
The "Personal Mailbox" model, in which the default namespace that is
|
||||
presented consists of only the user's personal mailboxes. To access
|
||||
shared mailboxes, the user must use an escape mechanism to reach
|
||||
another namespace.
|
||||
|
||||
The "Complete Hierarchy" model, in which the default namespace that
|
||||
is presented includes the user's personal mailboxes along with any
|
||||
other mailboxes they have access to.
|
||||
|
||||
These two models, create difficulties for certain client operations.
|
||||
This document defines a NAMESPACE command that allows a client to
|
||||
discover the prefixes of namespaces used by a server for personal
|
||||
mailboxes, other users' mailboxes, and shared mailboxes. This allows
|
||||
a client to avoid much of the manual user configuration that is now
|
||||
necessary when mixing and matching IMAP4 clients and servers.
|
||||
|
||||
2. Conventions used in this document
|
||||
|
||||
In examples, "C:" and "S:" indicate lines sent by the client and
|
||||
server respectively. If such lines are wrapped without a new "C:" or
|
||||
"S:" label, then the wrapping is for editorial clarity and is not
|
||||
part of the command.
|
||||
|
||||
|
||||
|
||||
Gahrns & Newman Standards Track [Page 1]
|
||||
|
||||
RFC 2342 IMAP4 Namespace May 1998
|
||||
|
||||
|
||||
Personal Namespace: A namespace that the server considers within the
|
||||
personal scope of the authenticated user on a particular connection.
|
||||
Typically, only the authenticated user has access to mailboxes in
|
||||
their Personal Namespace. It is the part of the namespace that
|
||||
belongs to the user that is allocated for mailboxes. If an INBOX
|
||||
exists for a user, it MUST appear within the user's personal
|
||||
namespace. In the typical case, there SHOULD be only one Personal
|
||||
Namespace on a server.
|
||||
|
||||
Other Users' Namespace: A namespace that consists of mailboxes from
|
||||
the Personal Namespaces of other users. To access mailboxes in the
|
||||
Other Users' Namespace, the currently authenticated user MUST be
|
||||
explicitly granted access rights. For example, it is common for a
|
||||
manager to grant to their secretary access rights to their mailbox.
|
||||
In the typical case, there SHOULD be only one Other Users' Namespace
|
||||
on a server.
|
||||
|
||||
Shared Namespace: A namespace that consists of mailboxes that are
|
||||
intended to be shared amongst users and do not exist within a user's
|
||||
Personal Namespace.
|
||||
|
||||
The namespaces a server uses MAY differ on a per-user basis.
|
||||
|
||||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
|
||||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
|
||||
document are to be interpreted as described in [RFC-2119].
|
||||
|
||||
3. Introduction and Overview
|
||||
|
||||
Clients often attempt to create mailboxes for such purposes as
|
||||
maintaining a record of sent messages (e.g. "Sent Mail") or
|
||||
temporarily saving messages being composed (e.g. "Drafts"). For
|
||||
these clients to inter-operate correctly with the variety of IMAP4
|
||||
servers available, the user must enter the prefix of the Personal
|
||||
Namespace used by the server. Using the NAMESPACE command, a client
|
||||
is able to automatically discover this prefix without manual user
|
||||
configuration.
|
||||
|
||||
In addition, users are often required to manually enter the prefixes
|
||||
of various namespaces in order to view the mailboxes located there.
|
||||
For example, they might be required to enter the prefix of #shared to
|
||||
view the shared mailboxes namespace. The NAMESPACE command allows a
|
||||
client to automatically discover the namespaces that are available on
|
||||
a server. This allows a client to present the available namespaces to
|
||||
the user in what ever manner it deems appropriate. For example, a
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns & Newman Standards Track [Page 2]
|
||||
|
||||
RFC 2342 IMAP4 Namespace May 1998
|
||||
|
||||
|
||||
client could choose to initially display only personal mailboxes, or
|
||||
it may choose to display the complete list of mailboxes available,
|
||||
and initially position the user at the root of their Personal
|
||||
Namespace.
|
||||
|
||||
A server MAY choose to make available to the NAMESPACE command only a
|
||||
subset of the complete set of namespaces the server supports. To
|
||||
provide the ability to access these namespaces, a client SHOULD allow
|
||||
the user the ability to manually enter a namespace prefix.
|
||||
|
||||
4. Requirements
|
||||
|
||||
IMAP4 servers that support this extension MUST list the keyword
|
||||
NAMESPACE in their CAPABILITY response.
|
||||
|
||||
The NAMESPACE command is valid in the Authenticated and Selected
|
||||
state.
|
||||
|
||||
5. NAMESPACE Command
|
||||
|
||||
Arguments: none
|
||||
|
||||
Response: an untagged NAMESPACE response that contains the prefix
|
||||
and hierarchy delimiter to the server's Personal
|
||||
Namespace(s), Other Users' Namespace(s), and Shared
|
||||
Namespace(s) that the server wishes to expose. The
|
||||
response will contain a NIL for any namespace class
|
||||
that is not available. Namespace_Response_Extensions
|
||||
MAY be included in the response.
|
||||
Namespace_Response_Extensions which are not on the IETF
|
||||
standards track, MUST be prefixed with an "X-".
|
||||
|
||||
Result: OK - Command completed
|
||||
NO - Error: Can't complete command
|
||||
BAD - argument invalid
|
||||
|
||||
Example 5.1:
|
||||
===========
|
||||
|
||||
< A server that supports a single personal namespace. No leading
|
||||
prefix is used on personal mailboxes and "/" is the hierarchy
|
||||
delimiter.>
|
||||
|
||||
C: A001 NAMESPACE
|
||||
S: * NAMESPACE (("" "/")) NIL NIL
|
||||
S: A001 OK NAMESPACE command completed
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns & Newman Standards Track [Page 3]
|
||||
|
||||
RFC 2342 IMAP4 Namespace May 1998
|
||||
|
||||
|
||||
Example 5.2:
|
||||
===========
|
||||
|
||||
< A user logged on anonymously to a server. No personal mailboxes
|
||||
are associated with the anonymous user and the user does not have
|
||||
access to the Other Users' Namespace. No prefix is required to
|
||||
access shared mailboxes and the hierarchy delimiter is "." >
|
||||
|
||||
C: A001 NAMESPACE
|
||||
S: * NAMESPACE NIL NIL (("" "."))
|
||||
S: A001 OK NAMESPACE command completed
|
||||
|
||||
Example 5.3:
|
||||
===========
|
||||
|
||||
< A server that contains a Personal Namespace and a single Shared
|
||||
Namespace. >
|
||||
|
||||
C: A001 NAMESPACE
|
||||
S: * NAMESPACE (("" "/")) NIL (("Public Folders/" "/"))
|
||||
S: A001 OK NAMESPACE command completed
|
||||
|
||||
Example 5.4:
|
||||
===========
|
||||
|
||||
< A server that contains a Personal Namespace, Other Users'
|
||||
Namespace and multiple Shared Namespaces. Note that the hierarchy
|
||||
delimiter used within each namespace can be different. >
|
||||
|
||||
C: A001 NAMESPACE
|
||||
S: * NAMESPACE (("" "/")) (("~" "/")) (("#shared/" "/")
|
||||
("#public/" "/")("#ftp/" "/")("#news." "."))
|
||||
S: A001 OK NAMESPACE command completed
|
||||
|
||||
The prefix string allows a client to do things such as automatically
|
||||
creating personal mailboxes or LISTing all available mailboxes within
|
||||
a namespace.
|
||||
|
||||
Example 5.5:
|
||||
===========
|
||||
|
||||
< A server that supports only the Personal Namespace, with a
|
||||
leading prefix of INBOX to personal mailboxes and a hierarchy
|
||||
delimiter of ".">
|
||||
|
||||
C: A001 NAMESPACE
|
||||
S: * NAMESPACE (("INBOX." ".")) NIL NIL
|
||||
S: A001 OK NAMESPACE command completed
|
||||
|
||||
|
||||
|
||||
Gahrns & Newman Standards Track [Page 4]
|
||||
|
||||
RFC 2342 IMAP4 Namespace May 1998
|
||||
|
||||
|
||||
< Automatically create a mailbox to store sent items.>
|
||||
|
||||
C: A002 CREATE "INBOX.Sent Mail"
|
||||
S: A002 OK CREATE command completed
|
||||
|
||||
Although typically a server will support only a single Personal
|
||||
Namespace, and a single Other User's Namespace, circumstances exist
|
||||
where there MAY be multiples of these, and a client MUST be prepared
|
||||
for them. If a client is configured such that it is required to
|
||||
create a certain mailbox, there can be circumstances where it is
|
||||
unclear which Personal Namespaces it should create the mailbox in.
|
||||
In these situations a client SHOULD let the user select which
|
||||
namespaces to create the mailbox in.
|
||||
|
||||
Example 5.6:
|
||||
===========
|
||||
|
||||
< In this example, a server supports 2 Personal Namespaces. In
|
||||
addition to the regular Personal Namespace, the user has an
|
||||
additional personal namespace to allow access to mailboxes in an
|
||||
MH format mailstore. >
|
||||
|
||||
< The client is configured to save a copy of all mail sent by the
|
||||
user into a mailbox called 'Sent Mail'. Furthermore, after a
|
||||
message is deleted from a mailbox, the client is configured to
|
||||
move that message to a mailbox called 'Deleted Items'.>
|
||||
|
||||
< Note that this example demonstrates how some extension flags can
|
||||
be passed to further describe the #mh namespace. >
|
||||
|
||||
C: A001 NAMESPACE
|
||||
S: * NAMESPACE (("" "/")("#mh/" "/" "X-PARAM" ("FLAG1" "FLAG2")))
|
||||
NIL NIL
|
||||
S: A001 OK NAMESPACE command completed
|
||||
|
||||
< It is desired to keep only one copy of sent mail. It is unclear
|
||||
which Personal Namespace the client should use to create the 'Sent
|
||||
Mail' mailbox. The user is prompted to select a namespace and
|
||||
only one 'Sent Mail' mailbox is created. >
|
||||
|
||||
C: A002 CREATE "Sent Mail"
|
||||
S: A002 OK CREATE command completed
|
||||
|
||||
< The client is designed so that it keeps two 'Deleted Items'
|
||||
mailboxes, one for each namespace. >
|
||||
|
||||
C: A003 CREATE "Delete Items"
|
||||
S: A003 OK CREATE command completed
|
||||
|
||||
|
||||
|
||||
Gahrns & Newman Standards Track [Page 5]
|
||||
|
||||
RFC 2342 IMAP4 Namespace May 1998
|
||||
|
||||
|
||||
C: A004 CREATE "#mh/Deleted Items"
|
||||
S: A004 OK CREATE command completed
|
||||
|
||||
The next level of hierarchy following the Other Users' Namespace
|
||||
prefix SHOULD consist of <username>, where <username> is a user name
|
||||
as per the IMAP4 LOGIN or AUTHENTICATE command.
|
||||
|
||||
A client can construct a LIST command by appending a "%" to the Other
|
||||
Users' Namespace prefix to discover the Personal Namespaces of other
|
||||
users that are available to the currently authenticated user.
|
||||
|
||||
In response to such a LIST command, a server SHOULD NOT return user
|
||||
names that have not granted access to their personal mailboxes to the
|
||||
user in question.
|
||||
|
||||
A server MAY return a LIST response containing only the names of
|
||||
users that have explicitly granted access to the user in question.
|
||||
|
||||
Alternatively, a server MAY return NO to such a LIST command,
|
||||
requiring that a user name be included with the Other Users'
|
||||
Namespace prefix before listing any other user's mailboxes.
|
||||
|
||||
Example 5.7:
|
||||
===========
|
||||
|
||||
< A server that supports providing a list of other user's
|
||||
mailboxes that are accessible to the currently logged on user. >
|
||||
|
||||
C: A001 NAMESPACE
|
||||
S: * NAMESPACE (("" "/")) (("Other Users/" "/")) NIL
|
||||
S: A001 OK NAMESPACE command completed
|
||||
|
||||
C: A002 LIST "" "Other Users/%"
|
||||
S: * LIST () "/" "Other Users/Mike"
|
||||
S: * LIST () "/" "Other Users/Karen"
|
||||
S: * LIST () "/" "Other Users/Matthew"
|
||||
S: * LIST () "/" "Other Users/Tesa"
|
||||
S: A002 OK LIST command completed
|
||||
|
||||
Example 5.8:
|
||||
===========
|
||||
|
||||
< A server that does not support providing a list of other user's
|
||||
mailboxes that are accessible to the currently logged on user.
|
||||
The mailboxes are listable if the client includes the name of the
|
||||
other user with the Other Users' Namespace prefix. >
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns & Newman Standards Track [Page 6]
|
||||
|
||||
RFC 2342 IMAP4 Namespace May 1998
|
||||
|
||||
|
||||
C: A001 NAMESPACE
|
||||
S: * NAMESPACE (("" "/")) (("#Users/" "/")) NIL
|
||||
S: A001 OK NAMESPACE command completed
|
||||
|
||||
< In this example, the currently logged on user has access to the
|
||||
Personal Namespace of user Mike, but the server chose to suppress
|
||||
this information in the LIST response. However, by appending the
|
||||
user name Mike (received through user input) to the Other Users'
|
||||
Namespace prefix, the client is able to get a listing of the
|
||||
personal mailboxes of user Mike. >
|
||||
|
||||
C: A002 LIST "" "#Users/%"
|
||||
S: A002 NO The requested item could not be found.
|
||||
|
||||
C: A003 LIST "" "#Users/Mike/%"
|
||||
S: * LIST () "/" "#Users/Mike/INBOX"
|
||||
S: * LIST () "/" "#Users/Mike/Foo"
|
||||
S: A003 OK LIST command completed.
|
||||
|
||||
A prefix string might not contain a hierarchy delimiter, because
|
||||
in some cases it is not needed as part of the prefix.
|
||||
|
||||
Example 5.9:
|
||||
===========
|
||||
|
||||
< A server that allows access to the Other Users' Namespace by
|
||||
prefixing the others' mailboxes with a '~' followed by <username>,
|
||||
where <username> is a user name as per the IMAP4 LOGIN or
|
||||
AUTHENTICATE command.>
|
||||
|
||||
C: A001 NAMESPACE
|
||||
S: * NAMESPACE (("" "/")) (("~" "/")) NIL
|
||||
S: A001 OK NAMESPACE command completed
|
||||
|
||||
< List the mailboxes for user mark >
|
||||
|
||||
C: A002 LIST "" "~mark/%"
|
||||
S: * LIST () "/" "~mark/INBOX"
|
||||
S: * LIST () "/" "~mark/foo"
|
||||
S: A002 OK LIST command completed
|
||||
|
||||
Historical convention has been to start all namespaces with the "#"
|
||||
character. Namespaces that include the "#" character are not IMAP
|
||||
URL [IMAP-URL] friendly requiring the "#" character to be represented
|
||||
as %23 when within URLs. As such, server implementers MAY instead
|
||||
consider using namespace prefixes that do not contain the "#"
|
||||
character.
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns & Newman Standards Track [Page 7]
|
||||
|
||||
RFC 2342 IMAP4 Namespace May 1998
|
||||
|
||||
|
||||
6. Formal Syntax
|
||||
|
||||
The following syntax specification uses the augmented Backus-Naur
|
||||
Form (BNF) as described in [ABNF].
|
||||
|
||||
atom = <atom>
|
||||
; <atom> as defined in [RFC-2060]
|
||||
|
||||
Namespace = nil / "(" 1*( "(" string SP (<"> QUOTED_CHAR <"> /
|
||||
nil) *(Namespace_Response_Extension) ")" ) ")"
|
||||
|
||||
Namespace_Command = "NAMESPACE"
|
||||
|
||||
Namespace_Response_Extension = SP string SP "(" string *(SP string)
|
||||
")"
|
||||
|
||||
Namespace_Response = "*" SP "NAMESPACE" SP Namespace SP Namespace SP
|
||||
Namespace
|
||||
|
||||
; The first Namespace is the Personal Namespace(s)
|
||||
; The second Namespace is the Other Users' Namespace(s)
|
||||
; The third Namespace is the Shared Namespace(s)
|
||||
|
||||
nil = <nil>
|
||||
; <nil> as defined in [RFC-2060]
|
||||
|
||||
QUOTED_CHAR = <QUOTED_CHAR>
|
||||
; <QUOTED_CHAR> as defined in [RFC-2060]
|
||||
|
||||
string = <string>
|
||||
; <string> as defined in [RFC-2060]
|
||||
; Note that the namespace prefix is to a mailbox and following
|
||||
; IMAP4 convention, any international string in the NAMESPACE
|
||||
; response MUST be of modified UTF-7 format as described in
|
||||
; [RFC-2060].
|
||||
|
||||
7. Security Considerations
|
||||
|
||||
In response to a LIST command containing an argument of the Other
|
||||
Users' Namespace prefix, a server SHOULD NOT list users that have not
|
||||
granted list access to their personal mailboxes to the currently
|
||||
authenticated user. Providing such a list, could compromise security
|
||||
by potentially disclosing confidential information of who is located
|
||||
on the server, or providing a starting point of a list of user
|
||||
accounts to attack.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns & Newman Standards Track [Page 8]
|
||||
|
||||
RFC 2342 IMAP4 Namespace May 1998
|
||||
|
||||
|
||||
8. References
|
||||
|
||||
[RFC-2060], Crispin, M., "Internet Message Access Protocol Version
|
||||
4rev1", RFC 2060, December 1996.
|
||||
|
||||
[RFC-2119], Bradner, S., "Key words for use in RFCs to Indicate
|
||||
Requirement Levels", BCP 14, RFC 2119, March 1997.
|
||||
|
||||
[ABNF] Crocker, D., Editor, and P. Overell, "Augmented BNF for Syntax
|
||||
Specifications: ABNF", RFC 2234, November 1997.
|
||||
|
||||
[IMAP-URL], Newman, C., "IMAP URL Scheme", RFC 2192, September 1997.
|
||||
|
||||
9. Acknowledgments
|
||||
|
||||
Many people have participated in the discussion of IMAP namespaces on
|
||||
the IMAP mailing list. In particular, the authors would like to
|
||||
thank Mark Crispin for many of the concepts relating to the Personal
|
||||
Namespace and accessing the Personal Namespace of other users, Steve
|
||||
Hole for summarizing the two namespace models, John Myers and Jack De
|
||||
Winter for their work in a preceding effort trying to define a
|
||||
standardized personal namespace, and Larry Osterman for his review
|
||||
and collaboration on this document.
|
||||
|
||||
11. Authors' Addresses
|
||||
|
||||
Mike Gahrns
|
||||
Microsoft
|
||||
One Microsoft Way
|
||||
Redmond, WA, 98072, USA
|
||||
|
||||
Phone: (425) 936-9833
|
||||
EMail: mikega@microsoft.com
|
||||
|
||||
|
||||
Chris Newman
|
||||
Innosoft International, Inc.
|
||||
1050 East Garvey Ave. South
|
||||
West Covina, CA, 91790, USA
|
||||
|
||||
EMail: chris.newman@innosoft.com
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns & Newman Standards Track [Page 9]
|
||||
|
||||
RFC 2342 IMAP4 Namespace May 1998
|
||||
|
||||
|
||||
12. Full Copyright Statement
|
||||
|
||||
Copyright (C) The Internet Society (1998). All Rights Reserved.
|
||||
|
||||
This document and translations of it may be copied and furnished to
|
||||
others, and derivative works that comment on or otherwise explain it
|
||||
or assist in its implementation may be prepared, copied, published
|
||||
and distributed, in whole or in part, without restriction of any
|
||||
kind, provided that the above copyright notice and this paragraph are
|
||||
included on all such copies and derivative works. However, this
|
||||
document itself may not be modified in any way, such as by removing
|
||||
the copyright notice or references to the Internet Society or other
|
||||
Internet organizations, except as needed for the purpose of
|
||||
developing Internet standards in which case the procedures for
|
||||
copyrights defined in the Internet Standards process must be
|
||||
followed, or as required to translate it into languages other than
|
||||
English.
|
||||
|
||||
The limited permissions granted above are perpetual and will not be
|
||||
revoked by the Internet Society or its successors or assigns.
|
||||
|
||||
This document and the information contained herein is provided on an
|
||||
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
|
||||
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
|
||||
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
|
||||
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Gahrns & Newman Standards Track [Page 10]
|
||||
|
|
@ -1,339 +0,0 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group J. Myers
|
||||
Request for Comments: 2359 Netscape Communications
|
||||
Category: Standards Track June 1998
|
||||
|
||||
|
||||
IMAP4 UIDPLUS extension
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This document specifies an Internet standards track protocol for the
|
||||
Internet community, and requests discussion and suggestions for
|
||||
improvements. Please refer to the current edition of the "Internet
|
||||
Official Protocol Standards" (STD 1) for the standardization state
|
||||
and status of this protocol. Distribution of this memo is unlimited.
|
||||
|
||||
Copyright Notice
|
||||
|
||||
Copyright (C) The Internet Society (1998). All Rights Reserved.
|
||||
|
||||
IESG NOTE
|
||||
|
||||
The IMAP extension described here assumes a particular means of using
|
||||
IMAP to support disconnected operation. However, this means of
|
||||
supporting disconnected operation is not yet documented. Also, there
|
||||
are multiple theories about how best to do disconnected operation in
|
||||
IMAP, and as yet, there is no consensus on which one should be
|
||||
adopted as a standard.
|
||||
|
||||
This document is being approved as a Proposed Standard because it
|
||||
does not appear to have technical flaws in itelf. However, approval
|
||||
of this document as a Proposed Standard should not be considered an
|
||||
IETF endorsement of any particular means of doing disconnected
|
||||
operation in IMAP.
|
||||
|
||||
Table of Contents
|
||||
|
||||
1. Abstract .............................................. 2
|
||||
2. Conventions Used in this Document ..................... 2
|
||||
3. Introduction and Overview ............................. 2
|
||||
4. Features .............................................. 2
|
||||
4.1. UID EXPUNGE Command ................................... 2
|
||||
4.2. APPENDUID response code ............................... 3
|
||||
4.3. COPYUID response code ................................. 4
|
||||
5. Formal Syntax ......................................... 4
|
||||
6. References ............................................ 4
|
||||
7. Security Considerations ............................... 5
|
||||
8. Author's Address ...................................... 5
|
||||
9. Full Copyright Statement .............................. 6
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 1]
|
||||
|
||||
RFC 2359 IMAP4 UIDPLUS extension June 1998
|
||||
|
||||
|
||||
1. Abstract
|
||||
|
||||
The UIDPLUS extension of the Internet Message Access Protocol [IMAP4]
|
||||
provides a set of features intended to reduce the amount of time and
|
||||
resources used by some client operations. The features in UIDPLUS
|
||||
are primarily intended for disconnected-use clients.
|
||||
|
||||
2. Conventions Used in this Document
|
||||
|
||||
In examples, "C:" and "S:" indicate lines sent by the client and
|
||||
server respectively.
|
||||
|
||||
The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY"
|
||||
in this document are to be interpreted as defined in "Key words for
|
||||
use in RFCs to Indicate Requirement Levels" [KEYWORDS].
|
||||
|
||||
3. Introduction and Overview
|
||||
|
||||
The UIDPLUS extension is present in any IMAP4 server implementation
|
||||
which returns "UIDPLUS" as one of the supported capabilities to the
|
||||
CAPABILITY command. The UIDPLUS extension contains one additional
|
||||
command and additional data returned with successful APPEND and COPY
|
||||
commands.
|
||||
|
||||
Clients that wish to use the new command in UIDPLUS must of course
|
||||
first test for the presence of the extension by issuing a CAPABILITY
|
||||
command. Each of the features in UIDPLUS are optimizations; clients
|
||||
can provide the same functionality, albeit more slowly, by using
|
||||
commands in the base protocol. With each feature, this document
|
||||
recommends a fallback approach to take when the UIDPLUS extension is
|
||||
not supported by the server.
|
||||
|
||||
4. Features
|
||||
|
||||
4.1. UID EXPUNGE Command
|
||||
|
||||
Arguments: message set
|
||||
|
||||
Data: untagged responses: EXPUNGE
|
||||
|
||||
Result: OK - expunge completed
|
||||
NO - expunge failure (e.g. permission denied)
|
||||
BAD - command unknown or arguments invalid
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 2]
|
||||
|
||||
RFC 2359 IMAP4 UIDPLUS extension June 1998
|
||||
|
||||
|
||||
The UID EXPUNGE command permanently removes from the currently
|
||||
selected mailbox all messages that both have the \Deleted flag set
|
||||
and have a UID that is included in the specified message set. If
|
||||
a message either does not have the \Deleted flag set or is has a
|
||||
UID that is not included in the specified message set, it is not
|
||||
affected.
|
||||
|
||||
This command may be used to ensure that a replayed EXPUNGE command
|
||||
does not remove any messages that have been marked as \Deleted
|
||||
between the time that the user requested the expunge operation and
|
||||
the time the server processes the command.
|
||||
|
||||
If the server does not support the UIDPLUS capability, the client
|
||||
should fall back to using the STORE command to temporarily remove
|
||||
the \Deleted flag from messages it does not want to remove. The
|
||||
client could alternatively fall back to using the EXPUNGE command,
|
||||
risking the unintended removal of some messages.
|
||||
|
||||
Example: C: A003 UID EXPUNGE 3000:3002
|
||||
S: * 3 EXPUNGE
|
||||
S: * 3 EXPUNGE
|
||||
S: * 3 EXPUNGE
|
||||
S: A003 OK UID EXPUNGE completed
|
||||
|
||||
4.2. APPENDUID response code
|
||||
|
||||
Successful APPEND commands return an APPENDUID response code in the
|
||||
tagged OK response. The APPENDUID response code contains as
|
||||
arguments the UIDVALIDITY of the destination mailbox and the UID
|
||||
assigned to the appended message.
|
||||
|
||||
If the server does not support the UIDPLUS capability, the client can
|
||||
only discover this information by selecting the destination mailbox
|
||||
and issuing FETCH commands.
|
||||
|
||||
Example: C: A003 APPEND saved-messages (\Seen) {310}
|
||||
C: Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)
|
||||
C: From: Fred Foobar <foobar@Blurdybloop.COM>
|
||||
C: Subject: afternoon meeting
|
||||
C: To: mooch@owatagu.siam.edu
|
||||
C: Message-Id: <B27397-0100000@Blurdybloop.COM>
|
||||
C: MIME-Version: 1.0
|
||||
C: Content-Type: TEXT/PLAIN; CHARSET=US-ASCII
|
||||
C:
|
||||
C: Hello Joe, do you think we can meet at 3:30 tomorrow?
|
||||
C:
|
||||
S: A003 OK [APPENDUID 38505 3955] APPEND completed
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 3]
|
||||
|
||||
RFC 2359 IMAP4 UIDPLUS extension June 1998
|
||||
|
||||
|
||||
4.3. COPYUID response code
|
||||
|
||||
Successful COPY and UID COPY commands return a COPYUID response code
|
||||
in the tagged OK response whenever at least one message was copied.
|
||||
The COPYUID response code contains as an argument the UIDVALIDITY of
|
||||
the appended-to mailbox, a message set containing the UIDs of the
|
||||
messages copied to the destination mailbox, in the order they were
|
||||
copied, and a message containing the UIDs assigned to the copied
|
||||
messages, in the order they were assigned. Neither of the message
|
||||
sets may contain extraneous UIDs or the symbol '*'.
|
||||
|
||||
If the server does not support the UIDPLUS capability, the client can
|
||||
only discover this information by selecting the destination mailbox
|
||||
and issuing FETCH commands.
|
||||
|
||||
Example: C: A003 COPY 2:4 MEETING
|
||||
S: A003 OK [COPYUID 38505 304,319:320 3956:3958] Done
|
||||
C: A003 UID COPY 305:310 MEETING
|
||||
S: A003 OK Done
|
||||
|
||||
5. Formal Syntax
|
||||
|
||||
The following syntax specification uses the augmented Backus-Naur
|
||||
Form (BNF) notation as specified in [RFC-822] as modified by [IMAP4].
|
||||
Non-terminals referenced but not defined below are as defined by
|
||||
[IMAP4].
|
||||
|
||||
Except as noted otherwise, all alphabetic characters are case-
|
||||
insensitive. The use of upper or lower case characters to define
|
||||
token strings is for editorial clarity only. Implementations MUST
|
||||
accept these strings in a case-insensitive fashion.
|
||||
|
||||
resp_code_apnd ::= "APPENDUID" SPACE nz_number SPACE uniqueid
|
||||
|
||||
resp_code_copy ::= "COPYUID" SPACE nz_number SPACE set SPACE set
|
||||
|
||||
uid_expunge ::= "UID" SPACE "EXPUNGE" SPACE set
|
||||
|
||||
6. References
|
||||
|
||||
[IMAP4] Crispin, M., "Internet Message Access Protocol -
|
||||
Version 4rev1", RFC 2060, December 1996.
|
||||
|
||||
[KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate
|
||||
Requirement Levels", BCP 14, RFC 2119, March 1997.
|
||||
|
||||
[RFC-822] Crocker, D., "Standard for the Format of ARPA Internet
|
||||
Text Messages", STD 11, RFC 822, August 1982.
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 4]
|
||||
|
||||
RFC 2359 IMAP4 UIDPLUS extension June 1998
|
||||
|
||||
|
||||
7. Security Considerations
|
||||
|
||||
There are no known security issues with this extension.
|
||||
|
||||
8. Author's Address
|
||||
|
||||
John Gardiner Myers
|
||||
Netscape Communications
|
||||
501 East Middlefield Road
|
||||
Mail Stop MV-029
|
||||
Mountain View, CA 94043
|
||||
|
||||
EMail: jgmyers@netscape.com
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 5]
|
||||
|
||||
RFC 2359 IMAP4 UIDPLUS extension June 1998
|
||||
|
||||
|
||||
9. Full Copyright Statement
|
||||
|
||||
Copyright (C) The Internet Society (1998). All Rights Reserved.
|
||||
|
||||
This document and translations of it may be copied and furnished to
|
||||
others, and derivative works that comment on or otherwise explain it
|
||||
or assist in its implementation may be prepared, copied, published
|
||||
and distributed, in whole or in part, without restriction of any
|
||||
kind, provided that the above copyright notice and this paragraph are
|
||||
included on all such copies and derivative works. However, this
|
||||
document itself may not be modified in any way, such as by removing
|
||||
the copyright notice or references to the Internet Society or other
|
||||
Internet organizations, except as needed for the purpose of
|
||||
developing Internet standards in which case the procedures for
|
||||
copyrights defined in the Internet Standards process must be
|
||||
followed, or as required to translate it into languages other than
|
||||
English.
|
||||
|
||||
The limited permissions granted above are perpetual and will not be
|
||||
revoked by the Internet Society or its successors or assigns.
|
||||
|
||||
This document and the information contained herein is provided on an
|
||||
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
|
||||
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
|
||||
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
|
||||
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Myers Standards Track [Page 6]
|
||||
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,21 +0,0 @@
|
|||
COPYRIGHT
|
||||
|
||||
Copyright 1999, 2000, 2001, 2002 , 2003 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:
|
||||
|
||||
|
||||
a) the "Artistic License" which comes with this Kit, or
|
||||
|
||||
b) the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 1, or (at your option) any later version.
|
||||
|
||||
|
||||
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.
|
||||
|
|
@ -1,172 +0,0 @@
|
|||
#!/usr/local/bin/perl
|
||||
#$Id: build_dist.pl,v 19991216.7 2003/06/12 21:38:29 dkernen Exp $
|
||||
|
||||
use Mail::IMAPClient;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<build_dist.pl> accepts the name of a target folder as an argument. It
|
||||
then opens that folder and rummages through all the mail files in it, looking
|
||||
for "Reply-to:" headers (or "From:" headers, where there is no "Reply-to:").
|
||||
It then appends a message into the folder containing all of the addresses in
|
||||
thus found as a list of recipients. This message can be used to conveniently
|
||||
drag and drop names into an address book, distribution list, or e-mail message,
|
||||
using the GUI client of choice.
|
||||
|
||||
The email appended to the folder specified in the I<-f> option will have the
|
||||
subject "buid_dist.pl I<folder> Output".
|
||||
|
||||
=head1 SYNTAX
|
||||
|
||||
b<build_dist.pl> I<-h>
|
||||
|
||||
b<build_dist.pl> I<-s servername -u username -p password -f folder [ -d ]>
|
||||
|
||||
=over 4
|
||||
|
||||
=item -f The folder name to process.
|
||||
|
||||
=item -s The servername of the IMAP server
|
||||
|
||||
=item -u The user to log in as
|
||||
|
||||
=item -p The password for the user specified in the I<-u> option
|
||||
|
||||
=item -d Tells the IMAP client to turn on debugging info
|
||||
|
||||
=item -h Prints out this document
|
||||
|
||||
=back
|
||||
|
||||
B<NOTE:> You can supply defaults for the above options by updating the script.
|
||||
|
||||
=cut
|
||||
|
||||
use Getopt::Std;
|
||||
|
||||
getopts('s:u:p:f:d');
|
||||
|
||||
# Update the following to supply defaults:
|
||||
|
||||
$opt_f ||= "default folder";
|
||||
$opt_s ||= "default server";
|
||||
$opt_u ||= "default user";
|
||||
$opt_p ||= "default password"; # security risk: use with caution!
|
||||
|
||||
# Let the compiler know we're serious about these two variables:
|
||||
$opt_h = $opt_h or $opt_d = $opt_d ;
|
||||
|
||||
exec "perldoc $0" if $opt_h;
|
||||
|
||||
my $imap = Mail::IMAPClient->new(
|
||||
Server => $opt_s ,
|
||||
User => $opt_u ,
|
||||
Password=> $opt_p ,
|
||||
Debug => $opt_d||0 ,
|
||||
) or die "can't connect to server\n";
|
||||
|
||||
$imap->select($opt_f);
|
||||
|
||||
my @msgs = $imap->search("NOT SUBJECT",qq("buid_dist.pl $opt_f Output"));
|
||||
my %list;
|
||||
foreach my $m (@msgs) {
|
||||
|
||||
my $ref = $imap->parse_headers($m,"Reply-to","From");
|
||||
|
||||
warn "Couldn't get recipient address from msg#$m\n"
|
||||
unless scalar(@{$ref->{'Reply-to'}}) ||
|
||||
scalar(@{$ref->{'From'}}) ;
|
||||
|
||||
my $from = scalar(@{$ref->{'Reply-to'}}) ?
|
||||
$ref->{'Reply-to'}[0] :
|
||||
$ref->{'From'}[0] ;
|
||||
|
||||
my $addr = $from;
|
||||
$addr =~ s/.*<//;
|
||||
$addr =~ s/[\<\>]//g;
|
||||
$list{$addr} = $from unless exists $list{$addr};
|
||||
}
|
||||
|
||||
$append = <<"EOMSG";
|
||||
To: ${\(join(",",values %list))}
|
||||
From: $opt_u\@$opt_s
|
||||
Date: ${\($imap->Rfc822_date(time))}
|
||||
Subject: build_dist.pl $opt_f Output
|
||||
|
||||
The above note was never actually sent to the following people:
|
||||
|
||||
${\(join("\n",keys %list))}
|
||||
|
||||
Interesting, eh?
|
||||
|
||||
Love,
|
||||
$opt_u
|
||||
|
||||
EOMSG
|
||||
|
||||
$imap->append($opt_f,$append) or warn "Couldn't append the message.";
|
||||
|
||||
$imap->logout;
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
David J. Kernen
|
||||
|
||||
The Kernen Group, Inc.
|
||||
|
||||
imap@kernengroup.com
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
This example and Mail::IMAPClient are Copyright (c) 2003
|
||||
by The Kernen Group, Inc. All rights reserved.
|
||||
|
||||
This example is distributed with Mail::IMAPClient and
|
||||
subject to the same licensing requirements as Mail::IMAPClient.
|
||||
|
||||
imtest is a utility distributed with Cyrus IMAP server,
|
||||
Copyright (c) 1994-2000 Carnegie Mellon University.
|
||||
All rights reserved.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
# $Id: build_dist.pl,v 19991216.7 2003/06/12 21:38:29 dkernen Exp $
|
||||
# $Log: build_dist.pl,v $
|
||||
# Revision 19991216.7 2003/06/12 21:38:29 dkernen
|
||||
#
|
||||
# Preparing 2.2.8
|
||||
# Added Files: COPYRIGHT
|
||||
# Modified Files: Parse.grammar
|
||||
# Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
# Parse.grammar Parse.pod
|
||||
# range.t
|
||||
# Thread.grammar
|
||||
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
|
||||
# rfc2221.txt rfc2359.txt rfc2683.txt
|
||||
#
|
||||
# Revision 19991216.6 2000/12/11 21:58:50 dkernen
|
||||
#
|
||||
# Modified Files:
|
||||
# build_dist.pl build_ldif.pl copy_folder.pl find_dup_msgs.pl
|
||||
# imap_to_mbox.pl populate_mailbox.pl
|
||||
# to add CVS data
|
||||
#
|
||||
# Revision 19991216.5 1999/12/16 17:19:09 dkernen
|
||||
# Bring up to same level
|
||||
#
|
||||
# Revision 19991124.3 1999/12/16 17:14:22 dkernen
|
||||
# Incorporate changes for exists method performance enhancement
|
||||
#
|
||||
# Revision 19991124.02 1999/11/24 17:46:16 dkernen
|
||||
# More fixes to t/basic.t
|
||||
#
|
||||
# Revision 19991124.01 1999/11/24 16:51:46 dkernen
|
||||
# Changed t/basic.t to test for UIDPLUS before trying UID cmds
|
||||
#
|
||||
# Revision 1.8 1999/11/23 17:51:05 dkernen
|
||||
# Committing version 1.06 distribution copy
|
||||
#
|
|
@ -1,235 +0,0 @@
|
|||
#!/usr/local/bin/perl
|
||||
#$Id: build_ldif.pl,v 19991216.11 2003/06/12 21:38:30 dkernen Exp $
|
||||
use Mail::IMAPClient;
|
||||
use MIME::Lite;
|
||||
use Data::Dumper;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<build_ldif.pl> accepts the name of a target folder as an argument. It
|
||||
then opens that folder and rummages through all the mail files in it, looking
|
||||
for "Reply-to:" headers (or "From:" headers, where there is no "Reply-to:").
|
||||
It then prints to STDOUT a file in ldif format containing entries for all of
|
||||
the addresses that it finds. It also appends a message into the specified folder containing
|
||||
all of the addresses in both the B<To:> field of the message header and in an
|
||||
LDIF-format attachment.
|
||||
|
||||
B<build_ldif.pl> requires B<MIME::Lite>.
|
||||
|
||||
=head1 SYNTAX
|
||||
|
||||
B<build_ldif.pl> I<-h>
|
||||
|
||||
B<build_ldif.pl> I<-s servername -u username -p password -f folder [ -d ]>
|
||||
|
||||
=over 4
|
||||
|
||||
=item -f The folder name to process.
|
||||
|
||||
=item -s The servername of the IMAP server
|
||||
|
||||
=item -t Include "To" and "Cc" fields as well as "From"
|
||||
|
||||
=item -u The user to log in as
|
||||
|
||||
=item -p The password for the user specified in the I<-u> option
|
||||
|
||||
=item -d Tells the IMAP client to turn on debugging info
|
||||
|
||||
=item -n Suppress delivering message to folder
|
||||
|
||||
=item -h Prints out this document
|
||||
|
||||
=back
|
||||
|
||||
B<NOTE:> You can supply defaults for the above options by updating the script.
|
||||
|
||||
=cut
|
||||
|
||||
use Getopt::Std;
|
||||
|
||||
getopts('hs:u:p:f:dtn');
|
||||
|
||||
# Update the following to supply defaults:
|
||||
|
||||
$opt_f ||= "default folder";
|
||||
$opt_s ||= "default server";
|
||||
$opt_u ||= "default user";
|
||||
$opt_p ||= "default password"; # security risk: use with caution!
|
||||
|
||||
# Let the compiler know we're serious about these variables:
|
||||
$opt_0 = ( $opt_h or $opt_d or $opt_t or $opt_n or $opt_0);
|
||||
|
||||
exec "perldoc $0" if $opt_h;
|
||||
|
||||
my $imap = Mail::IMAPClient->new(
|
||||
Server => $opt_s ,
|
||||
User => $opt_u ,
|
||||
Password=> $opt_p ,
|
||||
Debug => $opt_d||0 ,
|
||||
) or die "can't connect to server\n";
|
||||
|
||||
$imap->select($opt_f); $imap->expunge;
|
||||
|
||||
my @msgs = $imap->search("NOT SUBJECT",qq("buid_ldif.pl $opt_f Output"));
|
||||
my %list;
|
||||
foreach my $m (@msgs) {
|
||||
|
||||
my $ref = $imap->parse_headers($m,"Reply-to","From");
|
||||
|
||||
warn "Couldn't get recipient address from msg#$m\n"
|
||||
unless scalar(@{$ref->{'Reply-to'}}) ||
|
||||
scalar(@{$ref->{'From'}}) ;
|
||||
|
||||
my $from = scalar(@{$ref->{'Reply-to'}}) ?
|
||||
$ref->{'Reply-to'}[0] :
|
||||
$ref->{'From'}[0] ;
|
||||
my $name = $from ;
|
||||
|
||||
$name =~ s/<.*// ;
|
||||
if ($name =~ /\@/) {
|
||||
$name = $from ;
|
||||
$name =~ s/\@.*//; ;
|
||||
}
|
||||
$name =~ s/\"//g ;
|
||||
$name =~ s/^\s+|\s+$//g ;
|
||||
my $addr = $from ;
|
||||
$addr =~ s/.*<// ;
|
||||
$addr =~ s/[\<\>]//g ;
|
||||
$list{lc($addr)} = [ $addr, $name ]
|
||||
unless exists $list{lc($addr)} ;
|
||||
if ($opt_t) { # Do "To" and "Cc", too
|
||||
my $ref = $imap->parse_headers($m,"To","Cc") ;
|
||||
my @array = ( @{$ref->{To}} , @{$ref->{Cc}} ) ;
|
||||
my @members = () ;
|
||||
foreach my $text (@array) {
|
||||
while ( $text =~ / "([^"\\]*(\\.[^"\\]*)*"[^,]*),? |
|
||||
([^",]+),? |
|
||||
,
|
||||
/gx
|
||||
) {
|
||||
push @members, defined($1)?$1:$3 ;
|
||||
}
|
||||
}
|
||||
foreach my $to (@members) {
|
||||
|
||||
my $name = $to ;
|
||||
|
||||
$name =~ s/<.*// ;
|
||||
if ($name =~ /\@/) {
|
||||
$name = $to ;
|
||||
$name =~ s/\@.*//; ;
|
||||
}
|
||||
$name =~ s/\"//g ;
|
||||
$name =~ s/^\s+|\s+$//g ;
|
||||
my $addr = $to ;
|
||||
$addr =~ s/.*<// ;
|
||||
$addr =~ s/[\<\>]//g ;
|
||||
$list{lc($addr)} = [ $addr, $name ]
|
||||
unless exists $list{lc($addr)} ;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
my $text = join "",map {
|
||||
qq{dn: cn="} . $list{$_}[1] .
|
||||
qq{", mail=$list{$_}[0]\n} .
|
||||
qq{cn: } . $list{$_}[1] . qq{\n} .
|
||||
qq{mail: $list{$_}[0]\n} .
|
||||
qq{objectclass: top\nobjectclass: person\n\n};
|
||||
} keys %list ;
|
||||
|
||||
# Create a new multipart message:
|
||||
my $msg = MIME::Lite->new(
|
||||
From => $opt_u,
|
||||
map({ ("To" => $list{$_}[0]) } keys %list),
|
||||
Subject => "LDIF file from $opt_f",
|
||||
Type =>'TEXT',
|
||||
Data =>"Attached is the LDIF file of addresses from folder $opt_f."
|
||||
);
|
||||
$msg->attach( Type =>'text/ldif',
|
||||
Filename => "$opt_f.ldif",
|
||||
Data => $text ,
|
||||
);
|
||||
print $text;
|
||||
$imap->append($opt_f, $msg->as_string) unless $opt_n;
|
||||
print Dumper($imap) if $opt_d;
|
||||
$imap->logout;
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
David J. Kernen
|
||||
|
||||
The Kernen Group, Inc.
|
||||
|
||||
imap@kernengroup.com
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
This example and Mail::IMAPClient are Copyright (c) 1999,2003
|
||||
by The Kernen Group, Inc. All rights reserved.
|
||||
|
||||
This example is distributed with Mail::IMAPClient and
|
||||
subject to the same licensing requirements as Mail::IMAPClient.
|
||||
|
||||
imtest is a utility distributed with Cyrus IMAP server,
|
||||
Copyright (c) 1994-2000 Carnegie Mellon University.
|
||||
All rights reserved.
|
||||
|
||||
=cut
|
||||
|
||||
# $Id: build_ldif.pl,v 19991216.11 2003/06/12 21:38:30 dkernen Exp $
|
||||
# $Log: build_ldif.pl,v $
|
||||
# Revision 19991216.11 2003/06/12 21:38:30 dkernen
|
||||
#
|
||||
# Preparing 2.2.8
|
||||
# Added Files: COPYRIGHT
|
||||
# Modified Files: Parse.grammar
|
||||
# Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
# Parse.grammar Parse.pod
|
||||
# range.t
|
||||
# Thread.grammar
|
||||
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
|
||||
# rfc2221.txt rfc2359.txt rfc2683.txt
|
||||
#
|
||||
# Revision 19991216.10 2002/05/24 15:47:18 dkernen
|
||||
# Misc fixes
|
||||
#
|
||||
# Revision 19991216.9 2000/12/11 21:58:51 dkernen
|
||||
#
|
||||
# Modified Files:
|
||||
# build_dist.pl build_ldif.pl copy_folder.pl find_dup_msgs.pl
|
||||
# imap_to_mbox.pl populate_mailbox.pl
|
||||
# to add CVS data
|
||||
#
|
||||
# Revision 19991216.8 2000/03/02 19:57:13 dkernen
|
||||
#
|
||||
# Modified Files: build_ldif.pl -- to support new option to all "To:" and "Cc:" to be included in ldif file
|
||||
#
|
||||
# Revision 19991216.7 2000/02/21 16:16:10 dkernen
|
||||
#
|
||||
# Modified Files: build_ldif.pl -- to allow for "To:" and "Cc:" header handling and
|
||||
# to handle quoted names in headers
|
||||
#
|
||||
# Revision 19991216.6 1999/12/28 13:56:59 dkernen
|
||||
# Fixed -h option (help).
|
||||
#
|
||||
# Revision 19991216.5 1999/12/16 17:19:10 dkernen
|
||||
# Bring up to same level
|
||||
#
|
||||
# Revision 19991124.3 1999/12/16 17:14:24 dkernen
|
||||
# Incorporate changes for exists method performance enhancement
|
||||
#
|
||||
# Revision 19991124.02 1999/11/24 17:46:18 dkernen
|
||||
# More fixes to t/basic.t
|
||||
#
|
||||
# Revision 19991124.01 1999/11/24 16:51:48 dkernen
|
||||
# Changed t/basic.t to test for UIDPLUS before trying UID cmds
|
||||
#
|
||||
# Revision 1.8 1999/11/23 17:51:05 dkernen
|
||||
# Committing version 1.06 distribution copy
|
||||
#
|
|
@ -1,64 +0,0 @@
|
|||
#!/usr/local/bin/perl
|
||||
|
||||
use Mail::IMAPClient;
|
||||
use IO::File;
|
||||
#
|
||||
# Example that will also clean out your test account if interrupted 'make test'
|
||||
# runs have left junk folders there. Run from installation dir, installation/examples
|
||||
# subdir, or supply full path to the test.txt file (created during 'perl Makefile.PL'
|
||||
# and left in the installation dir until 'make clean').
|
||||
# If you 've already run 'make clean' or said no to extended tests,
|
||||
# then you don't have the file anyway; re-run 'perl Makefile.PL', reply 'y' to the
|
||||
# extended tests prompt, then supply the test account's credentials as prompted.
|
||||
# Then try this again.
|
||||
#
|
||||
if ( -f "./test.txt" ) {
|
||||
$configFile = "./test.txt"
|
||||
} elsif ( -f "../test.txt" ) {
|
||||
$configFile = "../test.txt"
|
||||
} elsif ( $ARGV[0] and -f "$ARGV[0]" ) {
|
||||
$configFile = $ARGV[0];
|
||||
} else {
|
||||
print STDERR "Can't find test.txt. Please run this from the installation directory ",
|
||||
"or supply the full path to test.txt as an argument on the command line.\n";
|
||||
}
|
||||
my $fh = IO::File->new("./test.txt") or die "./test.txt: $!\n";
|
||||
while (my $input = <$fh>) {
|
||||
chomp $input;
|
||||
my($k,$v) = split(/=/,$input,2);
|
||||
$conf{$k}=$v;
|
||||
}
|
||||
my $imap = Mail::IMAPClient->new(Server=>$conf{server},User=>$conf{user},
|
||||
Password=>$conf{passed}) or die "Connecting to $conf{server}: $! $@\n";
|
||||
|
||||
for my $f ( grep(/^IMAPClient_/,$imap->folders) ) {
|
||||
print "Deleting $f\n";
|
||||
$imap->select($f);
|
||||
$imap->delete_messages(@{$imap->messages}) ;
|
||||
$imap->close($f);
|
||||
$imap->delete($f);
|
||||
}
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
David J. Kernen
|
||||
|
||||
The Kernen Group, Inc.
|
||||
|
||||
imap@kernengroup.com
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
This example and Mail::IMAPClient are Copyright (c) 2003
|
||||
by The Kernen Group, Inc. All rights reserved.
|
||||
|
||||
This example is distributed with Mail::IMAPClient and
|
||||
subject to the same licensing requirements as Mail::IMAPClient.
|
||||
|
||||
imtest is a utility distributed with Cyrus IMAP server,
|
||||
Copyright (c) 1994-2000 Carnegie Mellon University.
|
||||
All rights reserved.
|
||||
|
||||
=cut
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
#!/usr/local/bin/perl
|
||||
#$Id: copy_folder.pl,v 19991216.3 2003/06/12 21:38:30 dkernen Exp $
|
||||
++$|;
|
||||
use Getopt::Std;
|
||||
use Mail::IMAPClient;
|
||||
use vars qw/$opt_r $opt_h $opt_t $opt_f/;
|
||||
|
||||
getopts("t:f:F:N:rh");
|
||||
if ( $opt_h ) {
|
||||
print &usage;
|
||||
exit;
|
||||
}
|
||||
|
||||
my($to_id,$to_pass,$thost) = $opt_t =~ m{
|
||||
([^/]+) # everything up to / is the id
|
||||
/ # then a slash
|
||||
([^@]+) # then everything up to @ is pswd
|
||||
@ # then an @-sign
|
||||
(.*) # then everything else is the host
|
||||
}x ;
|
||||
my($from_id,$from_pass,$fhost) =
|
||||
$opt_f =~ m{
|
||||
([^/]+) # everything up to / is the id
|
||||
/ # then a slash
|
||||
([^@]+) # then everything up to @ is pswd
|
||||
@ # then an @-sign
|
||||
(.*) # then everything else is the host
|
||||
}x ;
|
||||
$to_id and $from_id and $to_pass and $from_pass and $thost and $fhost
|
||||
or die "Error: Must specify -t and -f (to and from)\n" . &usage;
|
||||
$opt_F or
|
||||
die "Error: Must specify '-F folder' or how will I know what folder to copy?\n" .
|
||||
&usage ;
|
||||
|
||||
$opt_N ||= $opt_F;
|
||||
|
||||
|
||||
print "Copying folder $opt_F from $from_id\@$fhost to ${to_id}'s $opt_N folder on $thost.\n";
|
||||
|
||||
my ($from) = Mail::IMAPClient->new( Server => $fhost,
|
||||
User => $from_id,
|
||||
Password=> $from_pass,
|
||||
Fast_IO => 1,
|
||||
Uid => 1,
|
||||
Debug => 0,
|
||||
);
|
||||
|
||||
|
||||
my ($to) = Mail::IMAPClient->new( Server => $thost,
|
||||
User => $to_id,
|
||||
Password=> $to_pass,
|
||||
Fast_IO => 1,
|
||||
Uid => 1,
|
||||
Debug => 0,
|
||||
);
|
||||
|
||||
my @folders = $opt_r ? @{$from->folders($opt_F)} : ( $opt_F ) ;
|
||||
|
||||
foreach my $fold (@folders) {
|
||||
print "Processing folder $fold\n";
|
||||
$from->select($fold);
|
||||
if ($opt_F ne $opt_N) {
|
||||
$fold =~s/^$opt_F/$opt_N/o;
|
||||
}
|
||||
unless ($to->exists($fold)) {
|
||||
$to->create($fold) or warn "Couldn't create $fold\n" and next;
|
||||
}
|
||||
$to->select($fold);
|
||||
my @msgs = $from->search("ALL");
|
||||
# my %flaghash = $from->flags(\@msgs);
|
||||
foreach $msg (@msgs) {
|
||||
print "Processing message $msg in folder $fold.\n";
|
||||
my $string = $from->message_string($msg);
|
||||
# print "String = $string\n";
|
||||
my $new_id = $to->append($fold,$string)
|
||||
or warn "Couldn't append msg #$msg to target folder $fold.\n";
|
||||
|
||||
$to->store($new_id,"+FLAGS (" . join(" ",@{$from->flags($msg)}) . ")");
|
||||
}
|
||||
}
|
||||
|
||||
sub usage {
|
||||
return "Syntax:\n\t$0 -t to_id/to_pass\@to.host -f from_id/from_pass\@from.host \\\n" .
|
||||
"\t\t-F folder [-N New_Folder] [-r]\n".
|
||||
"\tor\n\t$0 -h\n\n".
|
||||
"\twhere:\n\t\t".
|
||||
"to_id\t\tis the id to recieve the folder\n\t\t".
|
||||
"to_pass\t\tis the password for to_id\n\t\t".
|
||||
"from\t\tis the uid who currently has the folder\n\t\t".
|
||||
"from_pass\tis the password for from_id\n\t\t".
|
||||
"to.host\t\tis the optional host where the 'to' uid has a mailbox\n\t\t".
|
||||
"from.host\tis the optional host where the 'from' uid has a mailbox\n\t\t".
|
||||
"folder\t\tis the folder to copy from\n\t\t".
|
||||
"New_Folder\tis the folder to copy to (defaults to 'folder')\n\t\t".
|
||||
"-h\t\tprints this help message\n\t\t".
|
||||
"-r\t\tspecifies a recursive copy (only works on systems that support the idea " .
|
||||
"\n\t\t\t\tof recursive folders)\n\t\t".
|
||||
"\n"
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
David J. Kernen
|
||||
|
||||
The Kernen Group, Inc.
|
||||
|
||||
imap@kernengroup.com
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
This example and Mail::IMAPClient are Copyright (c) 1999,2000,2003
|
||||
by The Kernen Group, Inc. All rights reserved.
|
||||
|
||||
This example is distributed with Mail::IMAPClient and
|
||||
subject to the same licensing requirements as Mail::IMAPClient.
|
||||
|
||||
imtest is a utility distributed with Cyrus IMAP server,
|
||||
Copyright (c) 1994-2000 Carnegie Mellon University.
|
||||
All rights reserved.
|
||||
|
||||
=cut
|
||||
|
||||
# History:
|
||||
# $Log: copy_folder.pl,v $
|
||||
# Revision 19991216.3 2003/06/12 21:38:30 dkernen
|
||||
#
|
||||
# Preparing 2.2.8
|
||||
# Added Files: COPYRIGHT
|
||||
# Modified Files: Parse.grammar
|
||||
# Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
# Parse.grammar Parse.pod
|
||||
# range.t
|
||||
# Thread.grammar
|
||||
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
|
||||
# rfc2221.txt rfc2359.txt rfc2683.txt
|
||||
#
|
||||
# Revision 19991216.2 2000/12/11 21:58:51 dkernen
|
||||
#
|
||||
# Modified Files:
|
||||
# build_dist.pl build_ldif.pl copy_folder.pl find_dup_msgs.pl
|
||||
# imap_to_mbox.pl populate_mailbox.pl
|
||||
# to add CVS data
|
||||
#
|
|
@ -1,111 +0,0 @@
|
|||
#!/usr/local/bin/perl
|
||||
#$Id
|
||||
|
||||
use Mail::IMAPClient; # available from http://search.cpan.org/search?mode=module&query=IMAPClient
|
||||
use IO::File;
|
||||
use Getopt::Std;
|
||||
use vars qw/ $opt_d $opt_s $opt_p $opt_u $opt_P $opt_h /;
|
||||
|
||||
&getopts('d:s:u:p:P:h'); # -d days_to_keep -u cyrys_user -p cyrus_pswd -s cyrus_server -P port
|
||||
|
||||
my $days_to_keep = $opt_d||365; # Delete msgs older than -d arg or 365 days
|
||||
my $cutoff = time - ( $days_to_keep * 24 * 60 * 60 ) ; # time - arg * 24 * 60 * 60 = cutoff date in seconds
|
||||
|
||||
# Change the following line (or replace it with something better):
|
||||
$opt_h and die help()."\n";
|
||||
my $h = $opt_s || "localhost" ;
|
||||
my $u = $opt_u || "cyrys" ;
|
||||
my $p = $opt_p or die "Unable to continue. No password provided.\n" . help();
|
||||
|
||||
my $imap = Mail::IMAPClient->new(
|
||||
Server => "$h",
|
||||
User => "$u", # $u,
|
||||
Password=> "$p", # $p,
|
||||
Uid => 1, # True value
|
||||
Port => $opt_P||143, # imapd
|
||||
Debug => 0, # Make true to debug
|
||||
Buffer => 4096*10, # True value; decrease on machines w/little memory
|
||||
Fast_io => 1, # True value
|
||||
Timeout => 30, # True value
|
||||
# Debug_fh=> IO::File->new(">out.db"), # fhandle
|
||||
)
|
||||
or die "$@";
|
||||
my $mcnt = my $fcnt = 0;
|
||||
print "Deleting messages older than ",$imap->Rfc2060_date($cutoff),"\n";
|
||||
for my $f ( $imap->folders ) {
|
||||
print "Expiring $f\n";
|
||||
unless ($imap->select($f) ) {
|
||||
$imap->setacl($f,$u,"lrswipcda") or warn "Cannot setacl for $f: $@\n" and next;
|
||||
$imap->select($f) or warn "Cannot select $f: $@" and next;
|
||||
}
|
||||
my @expired = $imap->search("SENTBEFORE",$imap->Rfc2060_date($cutoff));
|
||||
next unless @expired;
|
||||
$mcnt += scalar(@expired); $fcnt ++;
|
||||
print "Deleting ",scalar(@expired)," messages from $f\n";
|
||||
$imap->delete_message(@expired);
|
||||
$imap->expunge;
|
||||
$imap->close;
|
||||
}
|
||||
$imap->logout;
|
||||
print "Deleted a total of $mcnt messages in $fcnt folders.\n";
|
||||
exit;
|
||||
|
||||
|
||||
sub help {
|
||||
return <<"EOHELP";
|
||||
|
||||
Usage:
|
||||
|
||||
$0 [ -d days_to_keep ] [ -s mail_server ] [ -u cyrus_admin_id ] -p cyrus_password
|
||||
$0 -h
|
||||
|
||||
-h -- prints this here help message
|
||||
-d days_to_keep -- $0 will delete messages older than "days_to_keep". (Default is 365)
|
||||
-s mail_server -- hostname or IP Address of IMAP mail server (defaults to "localhost")
|
||||
-u cyrus_admin_id -- user name of Unix account that owns Cyrus server (defaults to "cyrus")
|
||||
-p cyrus_password -- password for the "cyrus_admin_id" user account (no default)
|
||||
-P cyrus_port -- port where the cyrus imapd daemon is listening (defaults to value from
|
||||
/etc/services or '143')
|
||||
|
||||
EOHELP
|
||||
|
||||
}
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
David J. Kernen
|
||||
|
||||
The Kernen Group, Inc.
|
||||
|
||||
imap@kernengroup.com
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
This example and Mail::IMAPClient are Copyright (c) 2003
|
||||
by The Kernen Group, Inc. All rights reserved.
|
||||
|
||||
This example is distributed with Mail::IMAPClient and
|
||||
subject to the same licensing requirements as Mail::IMAPClient.
|
||||
|
||||
imtest is a utility distributed with Cyrus IMAP server,
|
||||
Copyright (c) 1994-2000 Carnegie Mellon University.
|
||||
All rights reserved.
|
||||
|
||||
=cut
|
||||
|
||||
#$Log: cyrus_expire.pl,v $
|
||||
#Revision 19991216.2 2003/06/12 21:38:31 dkernen
|
||||
#
|
||||
#Preparing 2.2.8
|
||||
#Added Files: COPYRIGHT
|
||||
#Modified Files: Parse.grammar
|
||||
#Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
# Parse.grammar Parse.pod
|
||||
# range.t
|
||||
# Thread.grammar
|
||||
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
|
||||
# rfc2221.txt rfc2359.txt rfc2683.txt
|
||||
#
|
|
@ -1,85 +0,0 @@
|
|||
#!/usr/local/bin/perl
|
||||
#$Id: cyrus_expunge.pl,v 19991216.3 2003/06/12 21:38:31 dkernen Exp $
|
||||
|
||||
use Mail::IMAPClient;
|
||||
use IO::File;
|
||||
|
||||
# Change the following line (or replace it with something better):
|
||||
my($h,$u,$p) = ('cyrus_host','cyrus_admin_id','cyrus_admin_pswd');
|
||||
|
||||
my $imap = Mail::IMAPClient->new( Server => "$h", # imap host
|
||||
User => "$u", # $u,
|
||||
Password=> "$p", # $p,
|
||||
Uid => 1, # True value
|
||||
Port => 143, # Cyrus
|
||||
Debug => 0, # True value
|
||||
Buffer => 4096*10, # True value
|
||||
Fast_io => 1, # True value
|
||||
Timeout => 30, # True value
|
||||
# Debug_fh=> IO::File->new(">out.db"), # fhandle
|
||||
)
|
||||
or die "$@";
|
||||
|
||||
for my $f ( $imap->folders ) {
|
||||
print "Expunging $f\n";
|
||||
unless ($imap->select($f) ) {
|
||||
$imap->setacl($f,$u,"lrswipcda") or warn "Cannot setacl for $f: $@\n" and next;
|
||||
$imap->select($f) or warn "Cannot select $f: $@" and next;
|
||||
}
|
||||
$imap->expunge;
|
||||
}
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
David J. Kernen
|
||||
|
||||
The Kernen Group, Inc.
|
||||
|
||||
imap@kernengroup.com
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
This example and Mail::IMAPClient are Copyright (c) 2003
|
||||
by The Kernen Group, Inc. All rights reserved.
|
||||
|
||||
This example is distributed with Mail::IMAPClient and
|
||||
subject to the same licensing requirements as Mail::IMAPClient.
|
||||
|
||||
imtest is a utility distributed with Cyrus IMAP server,
|
||||
Copyright (c) 1994-2000 Carnegie Mellon University.
|
||||
All rights reserved.
|
||||
|
||||
=cut
|
||||
|
||||
#
|
||||
#$Log: cyrus_expunge.pl,v $
|
||||
#Revision 19991216.3 2003/06/12 21:38:31 dkernen
|
||||
#
|
||||
#Preparing 2.2.8
|
||||
#Added Files: COPYRIGHT
|
||||
#Modified Files: Parse.grammar
|
||||
#Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
# Parse.grammar Parse.pod
|
||||
# range.t
|
||||
# Thread.grammar
|
||||
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
|
||||
# rfc2221.txt rfc2359.txt rfc2683.txt
|
||||
#
|
||||
#Revision 1.1 2003/06/12 21:38:14 dkernen
|
||||
#
|
||||
#Preparing 2.2.8
|
||||
#Added Files: COPYRIGHT
|
||||
#Modified Files: Parse.grammar
|
||||
#Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
# Parse.grammar Parse.pod
|
||||
# range.t
|
||||
# Thread.grammar
|
||||
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
|
||||
# rfc2221.txt rfc2359.txt rfc2683.txt
|
||||
#
|
||||
#
|
|
@ -1,217 +0,0 @@
|
|||
#!/usr/local/bin/perl
|
||||
# $Id: find_dup_msgs.pl,v 19991216.5 2003/06/12 21:38:32 dkernen Exp $
|
||||
|
||||
use Mail::IMAPClient;
|
||||
use Mozilla::LDAP::Conn;
|
||||
use Getopt::Std;
|
||||
use vars qw/$rootdn $opt_a/;
|
||||
use Data::Dumper;
|
||||
|
||||
# It then connects to a user's mailhost and rummages around,
|
||||
# looking for duplicate messages.
|
||||
# It will optionally delete messages that are duplicates (based on
|
||||
# msg-id header and number of bytes).
|
||||
# For help, enter:
|
||||
# find_dup_msgs.pl -h
|
||||
#
|
||||
|
||||
getopts('ahdtvf:F:u:s:p:P:');
|
||||
|
||||
if ( $opt_h ) {
|
||||
print STDERR &usage;
|
||||
exit;
|
||||
}
|
||||
|
||||
my $uid = $opt_u or die &usage;
|
||||
$opt_s||='localhost';
|
||||
$opt_p or die &usage;
|
||||
$opt_P||=143;
|
||||
|
||||
$opt_t and
|
||||
$opt_d and
|
||||
die "ERROR: Don't specify -d and -t together.\n" . &usage;
|
||||
|
||||
|
||||
my($pu,$pp) = get_admin();
|
||||
|
||||
print "Connecting to $host:$opt_P\n" if $opt_v;
|
||||
my $imap = Imap->new( Server => $opt_s,
|
||||
User => $opt_u,
|
||||
Password=> $opt_p,
|
||||
Port => $opt_P,
|
||||
Fast_io => 1,
|
||||
) or die "couldn't connect to $host port $opt_P: $!\n";
|
||||
|
||||
my %folders; my %counts;
|
||||
|
||||
FOLDER: foreach my $f ( $opt_F ? $opt_F : $imap->folders ) {
|
||||
next if $opt_t and $f eq 'Trash';
|
||||
$folders{$f} = 0;
|
||||
$counts{$f} = $imap->message_count($f);
|
||||
print "Processing folder $f\n" if $opt_v;
|
||||
unless ( $imap->select($f)) {
|
||||
warn "Error selecting $f: " . $imap->LastError . "\n";
|
||||
next FOLDER;
|
||||
}
|
||||
my @msgs = $imap->search("ALL");
|
||||
my %hash = ();
|
||||
MESSAGE: foreach my $m (@msgs) {
|
||||
my $mid;
|
||||
if ($opt_a) {
|
||||
my $h = $imap->parse_headers(
|
||||
$m,"Date","Subject","From","Message-ID"
|
||||
) or next MESSAGE;
|
||||
$mid = "$h->{'Date'}[0]$;$h->{'Subject'}[0]$;".
|
||||
"$h->{'From'}[0]$;$h->{'Message-ID'}[0]";
|
||||
|
||||
} else {
|
||||
$mid = $imap->parse_headers(
|
||||
$m,
|
||||
"Message-ID"
|
||||
)->{'Message-ID'}[0]
|
||||
or next MESSAGE;
|
||||
}
|
||||
my $size = $imap->size($m);
|
||||
if ( exists $hash{$mid} and $hash{$mid} == $size ) {
|
||||
if ($opt_f) {
|
||||
open F,">>$opt_f" or
|
||||
die "can't open $opt_f: $!\n";
|
||||
print F $imap->message_string($m),
|
||||
"___END OF SAVED MESSAGE___","\n";
|
||||
close F;
|
||||
}
|
||||
$imap->move("Trash",$m) if $opt_t;
|
||||
$imap->delete_message($m) if $opt_d;
|
||||
$folders{$f}++;
|
||||
print "Found a duplicate in ${f}; key = $mid\n" if $opt_v;
|
||||
|
||||
} else {
|
||||
|
||||
$hash{$mid} = $size;
|
||||
}
|
||||
}
|
||||
print "$f hash:\n",Data::Dumper::Dumper(\%hash) if $opt_v;
|
||||
$imap->expunge if ($opt_t or $opt_d);
|
||||
}
|
||||
|
||||
my $total; my $totms;
|
||||
map { $total += $_} values %folders;
|
||||
map { $totms += $_ } values %counts;
|
||||
print "Found $total duplicate messages in ${uid}'s mailbox. ",
|
||||
"The breakdown is:\n",
|
||||
"\tFolder\tNumber of Duplicates\tNumber of Msgs in Folder\n",
|
||||
"\t------\t--------------------\t------------------------\n",
|
||||
map { "\t$_\t$folders{$_}\t$counts{$_}\n" } keys %folders,
|
||||
"\tTOTAL\t$total\t$totms\n"
|
||||
;
|
||||
|
||||
|
||||
sub usage {
|
||||
return "Usage:\n" .
|
||||
"\t$0 [-d|-t] [-v] [-f filename] [-a] [-P port] \\\n".
|
||||
"\t\t-s server -u user -p password\n\n" .
|
||||
"\t-a\t\tdo an especially aggressive search for duplicates\n".
|
||||
"\t-d\t\tdelete duplicates (default is to just report them)\n".
|
||||
"\t-f file\t\tsave deleted messages in file named 'file'\n" .
|
||||
"\t-F fldr\t\tOnly check the folder named 'fldr' (default is to check all folders)\n" .
|
||||
"\t-h\t\tprint this help message (all other options are ignored)\n" .
|
||||
"\t-p password\tspecify the target user's password\n" .
|
||||
"\t-P port\t\tspecify the port to connect to (default is 143)\n" .
|
||||
"\t-s server\tspecify the target mail server\n" .
|
||||
"\t-u uid\t\tspecify the target user\n" .
|
||||
"\t-t\t\tmove deleted messages to trash folder\n" .
|
||||
"\t-v\t\tprint verbose status messages while processing\n".
|
||||
"\n" ;
|
||||
}
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
David J. Kernen
|
||||
|
||||
The Kernen Group, Inc.
|
||||
|
||||
imap@kernengroup.com
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
This example and Mail::IMAPClient are Copyright (c) 2003
|
||||
by The Kernen Group, Inc. All rights reserved.
|
||||
|
||||
This example is distributed with Mail::IMAPClient and
|
||||
subject to the same licensing requirements as Mail::IMAPClient.
|
||||
|
||||
imtest is a utility distributed with Cyrus IMAP server,
|
||||
Copyright (c) 1994-2000 Carnegie Mellon University.
|
||||
All rights reserved.
|
||||
|
||||
=cut
|
||||
|
||||
# History:
|
||||
# $Log: find_dup_msgs.pl,v $
|
||||
# Revision 19991216.5 2003/06/12 21:38:32 dkernen
|
||||
#
|
||||
# Preparing 2.2.8
|
||||
# Added Files: COPYRIGHT
|
||||
# Modified Files: Parse.grammar
|
||||
# Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
# Parse.grammar Parse.pod
|
||||
# range.t
|
||||
# Thread.grammar
|
||||
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
|
||||
# rfc2221.txt rfc2359.txt rfc2683.txt
|
||||
#
|
||||
# Revision 1.1 2003/06/12 21:38:14 dkernen
|
||||
#
|
||||
# Preparing 2.2.8
|
||||
# Added Files: COPYRIGHT
|
||||
# Modified Files: Parse.grammar
|
||||
# Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
# Parse.grammar Parse.pod
|
||||
# range.t
|
||||
# Thread.grammar
|
||||
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
|
||||
# rfc2221.txt rfc2359.txt rfc2683.txt
|
||||
#
|
||||
# Revision 19991216.4 2002/08/23 14:34:51 dkernen
|
||||
#
|
||||
# Modified Files: Changes IMAPClient.pm Makefile Makefile.PL test.txt for version 2.2.0
|
||||
# Added Files: Makefile Makefile.PL Parse.grammar Parse.pm Parse.pod version 2.2.0
|
||||
# Added Files: parse.t for version 2.2.0
|
||||
# Added Files: bodystructure.t for 2.2.0
|
||||
# Modified Files: find_dup_msgs.pl for v2.2.0
|
||||
#
|
||||
# Revision 1.6 2001/03/08 19:00:35 dkernen
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
# Modified Files:
|
||||
# copy_folder.pl delete_mailbox.pl find_dup_msgs.pl
|
||||
# mbox_check.pl process_orphans.pl rename_id.pl
|
||||
# scratch_indexes.pl
|
||||
# to get ready for nsusmsg02 upgrade
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
# Revision 1.5 2000/11/01 15:51:58 dkernen
|
||||
#
|
||||
# Modified Files: copy_folder.pl find_dup_msgs.pl restore_mbox.pl
|
||||
#
|
||||
# Revision 1.4 2000/04/13 21:17:18 dkernen
|
||||
#
|
||||
# Modified Files: find_dup_msgs.pl - to add -a switch (for aggressive dup search)
|
||||
# Added Files: copy_folder.pl - a utility for copying a folder from one user's
|
||||
# mailbox to another's
|
||||
#
|
||||
# Revision 1.3 2000/03/14 16:40:21 dkernen
|
||||
#
|
||||
# Modified Files: find_dup_msgs.pl -- to skip msgs with no message-id
|
||||
#
|
||||
# Revision 1.2 2000/03/13 19:05:50 dkernen
|
||||
#
|
||||
# Modified Files:
|
||||
# delete_mailbox.pl find_dup_msgs.pl restore_mbox.pl -- to add cvs comments
|
||||
# find_dup_msgs.pl -- to fix bug that occurred when -t (move-to-trash) switch is used
|
||||
#
|
|
@ -1,154 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
# (c) 1999 Thomas Stromberg, Research Triangle Commerce, Inc.
|
||||
# This software is protected by the BSD License. No rights reserved anyhow.
|
||||
# <tstromberg@rtci.com>
|
||||
|
||||
# DESC: Reads a users IMAP folders, and converts them to mbox
|
||||
# Good for an interim switch-over from say, Exchange to Cyrus IMAP.
|
||||
|
||||
# $Header: /usr/CvsRepository/Mail/IMAPClient/examples/imap_to_mbox.pl,v 19991216.7 2002/08/23 13:29:48 dkernen Exp $
|
||||
|
||||
# TODO:
|
||||
# -----
|
||||
# lsub instead of list option
|
||||
# correct header printing From
|
||||
|
||||
|
||||
use Mail::IMAPClient; # a nice set of perl libs for imap
|
||||
use Getopt::Std; # for the command-line overrides. good for user
|
||||
use File::Path; # create full file paths. (yummy!)
|
||||
use File::Basename; # find a nice basename for a folder.
|
||||
$| = 1;
|
||||
|
||||
# Config for the imap migration kit.
|
||||
|
||||
getopts('u:p:P:s:i:f::b:dh');
|
||||
|
||||
if ($opt_h) {
|
||||
# print help here
|
||||
}
|
||||
|
||||
$SERVER = $opt_s || 'mailhost';
|
||||
$USER = $opt_u || 'userid';
|
||||
$PASSWORD = $opt_p || 'password';
|
||||
$PORT = $opt_P || '143';
|
||||
$INBOX_PATH = $opt_i || "./mail/$USER";
|
||||
$FOLDERS_PATH = $opt_f || "./folders/$USER";
|
||||
$DONT_MOVE = $opt_m || '.mailboxlist|Trash|INBOXIIMAP|mlbxl';
|
||||
$READ_DELIMITER = $opt_r || '/';
|
||||
$WRITE_DELIMITER= $opt_w || '/';
|
||||
$BANNED_CHARS = $opt_b || '.|^|%';
|
||||
$DEBUG = $opt_d || "0";
|
||||
|
||||
|
||||
## do our magic tricks ######################################
|
||||
&connect_imap;
|
||||
&find_folders;
|
||||
|
||||
|
||||
sub connect_imap {
|
||||
$imap = Mail::IMAPClient->new(
|
||||
Server => "$SERVER",
|
||||
User => "$USER",
|
||||
Password => "$PASSWORD",
|
||||
Port => "$PORT",
|
||||
Debug => "$DEBUG",
|
||||
Uid => '0',
|
||||
Clear => '1',
|
||||
)
|
||||
|| die ("Could not connect to $SERVER:$PORT with $USER: $! $?\n");
|
||||
};
|
||||
|
||||
sub find_folders {
|
||||
my (@folders, $folder, $message_count, $new_folder, $path);
|
||||
|
||||
@folders = $imap->folders;
|
||||
push(@folders, "INBOX");
|
||||
foreach $folder (@folders) {
|
||||
$message_count = $imap->message_count($folder);
|
||||
if (! $message_count) {
|
||||
print("* $folder is empty, skipping.\n");
|
||||
next;
|
||||
}
|
||||
if ($folder =~ /$DONT_MOVE/) {
|
||||
print("! $folder matches DONT_MOVE ruleset, skipping\n");
|
||||
next;
|
||||
}
|
||||
|
||||
$new_folder = $folder;
|
||||
$new_folder =~ s/\./_/g;
|
||||
$new_folder =~ s/$READ_DELIMITER/$WRITE_DELIMITER/g;
|
||||
if ($new_folder eq "INBOX") {
|
||||
$path = "$INBOX_PATH";
|
||||
} else {
|
||||
$path = "$FOLDERS_PATH/$new_folder";
|
||||
}
|
||||
|
||||
printf("x %4i %-45.45s => %s", $message_count, $folder, $path);
|
||||
&write_folder($folder, $path, 1, $message_count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub write_folder {
|
||||
my($folder, $newpath, $first_message, $last_message) = @_;
|
||||
my($msg_header, $msg_body);
|
||||
|
||||
$imap->select($folder) || print("Could not examine $folder: $!");
|
||||
$new_dir = dirname($newpath);
|
||||
$new_file = basename($newpath);
|
||||
mkpath("$new_dir", 0700) unless -d "$new_dir";
|
||||
open(mbox, ">$newpath");
|
||||
|
||||
for ($i=$first_message; $i<$last_message+1; ++$i) {
|
||||
if ( ($i / 25) == int($i / 25) ) { print("."); }
|
||||
$msg_header = $imap->fetch($i, "FAST") || print("Could not fetch header $i from $folder\n");
|
||||
$msg_rfc822 = $imap->fetch($i, "RFC822") || print("Could not fetch RFC822 $i from $folder\n");
|
||||
undef $start;
|
||||
foreach (@$msg_rfc822) {
|
||||
if (($_ =~ /: /) && (! $message)) { ++$message; print(mbox "From imap\@to.mbox Wed Oct 27 17:02:53 1999\n");}
|
||||
if (/^\)\r/) { undef $message; print(mbox "\n\n");}
|
||||
next unless $message;
|
||||
$_ =~ s/\r$//;
|
||||
print(mbox "$_");
|
||||
|
||||
}
|
||||
}
|
||||
close(mbox);
|
||||
print("\n");
|
||||
}
|
||||
|
||||
# $Id: imap_to_mbox.pl,v 19991216.7 2002/08/23 13:29:48 dkernen Exp $
|
||||
# $Log: imap_to_mbox.pl,v $
|
||||
# Revision 19991216.7 2002/08/23 13:29:48 dkernen
|
||||
#
|
||||
# Modified Files: Changes IMAPClient.pm INSTALL MANIFEST Makefile Makefile.PL README Todo test.txt
|
||||
# Made changes to create version 2.1.6.
|
||||
# Modified Files:
|
||||
# imap_to_mbox.pl populate_mailbox.pl
|
||||
# Added Files:
|
||||
# cleanTest.pl migrate_mbox.pl
|
||||
#
|
||||
# Revision 19991216.6 2000/12/11 21:58:52 dkernen
|
||||
#
|
||||
# Modified Files:
|
||||
# build_dist.pl build_ldif.pl copy_folder.pl find_dup_msgs.pl
|
||||
# imap_to_mbox.pl populate_mailbox.pl
|
||||
# to add CVS data
|
||||
#
|
||||
# Revision 19991216.5 1999/12/16 17:19:12 dkernen
|
||||
# Bring up to same level
|
||||
#
|
||||
# Revision 19991124.3 1999/12/16 17:14:25 dkernen
|
||||
# Incorporate changes for exists method performance enhancement
|
||||
#
|
||||
# Revision 19991124.02 1999/11/24 17:46:19 dkernen
|
||||
# More fixes to t/basic.t
|
||||
#
|
||||
# Revision 19991124.01 1999/11/24 16:51:49 dkernen
|
||||
# Changed t/basic.t to test for UIDPLUS before trying UID cmds
|
||||
#
|
||||
# Revision 1.3 1999/11/23 17:51:06 dkernen
|
||||
# Committing version 1.06 distribution copy
|
||||
#
|
||||
|
|
@ -1,226 +0,0 @@
|
|||
#!/usr/local/bin/perl
|
||||
|
||||
use Sys::Hostname;
|
||||
use Mail::IMAPClient;
|
||||
use IPC::Open3;
|
||||
use IO::Socket::UNIX;
|
||||
use IO::Socket;
|
||||
use Socket;
|
||||
use Getopt::Std;
|
||||
&getopts('ha:df:i:o:p:r:m:u:x:w:p:s:');
|
||||
|
||||
if ($opt_h) {
|
||||
print <<" HELP";
|
||||
$0 -- uses imtest to connect and authenticate to imap server
|
||||
|
||||
Options:
|
||||
-h print this help message
|
||||
|
||||
-a auth authenticate as user 'auth'. This value is passed as the '-a' value
|
||||
to imtest and defaults to whatever you supplied for -u.
|
||||
-d turn on Mail::IMAPClient debugging
|
||||
-f file write Mail::IMAPClient debugging info to file 'file'
|
||||
-m mech use authentication mechanism "mech"; default is to not supply -m to
|
||||
imtest
|
||||
-i path path to imtest executable; default is to let your shell find it via the
|
||||
PATH environmental variable.
|
||||
-p port port on mail server to connect to (default is 143)
|
||||
-r rlm Use realm 'rlm' (default is name of mail server)
|
||||
-s srvr Name of IMAP mail server (default is the localhost's hostname)
|
||||
-u usr Use 'usr' as the user id (required)
|
||||
-w pswd Use 'pswd' as the password for 'usr' (required)
|
||||
-x path Path to Unix socket (fifo). Default is '/tmp/$0.sock'.
|
||||
-o 'ops' Pass the string 'ops' directy to imtest as additional options.
|
||||
This is how you get "other" imtest options passed to imtest. (I only
|
||||
included switches for options that are either really common or useful
|
||||
to the IMAPClient object as well as to imtest.)
|
||||
|
||||
Many of these switches have the same function here as with imtest. I added a
|
||||
few extras though!
|
||||
|
||||
Example:
|
||||
$0 -o '-k 128 -l 128' -s imapmail -u test -w testpswd \
|
||||
-i /usr/local/src/cyrus/cyrus-imapd-2.1.11/imtest/ \
|
||||
-m DIGEST-MD5
|
||||
|
||||
It's a good idea to test your options by running imtest from the command line
|
||||
(but without the -x switch) first. Once you have it working by hand you should
|
||||
be able to get it to work from this script (or one remarkably like it) without
|
||||
too much bloodshed.
|
||||
|
||||
HELP
|
||||
exit;
|
||||
}
|
||||
|
||||
$opt_u and $opt_w or die "No userid/password credentials supplied. I hate that.\n";
|
||||
$opt_a ||= $opt_u;
|
||||
|
||||
if ($opt_i ) {
|
||||
$opt_i =~ m#^[/\.]# or $opt_i = "./$opt_i";
|
||||
$opt_i =~ m#imtest$# or ( -x $opt_i and -f $opt_i )
|
||||
or $opt_i .= ( $opt_i =~ m#/$# ? "imtest" : "/imtest") ;
|
||||
-x $opt_i and -f $opt_i or die "Cannot find executable $opt_i\n";
|
||||
}
|
||||
|
||||
|
||||
$opt_p ||= 143;
|
||||
$opt_s ||= hostname;
|
||||
$opt_r ||= $opt_s;
|
||||
$opt_x ||= "/tmp/$0.sock";
|
||||
|
||||
|
||||
my($rfh,$wfh,$efh) ;
|
||||
|
||||
|
||||
my($imt) = ($opt_i ? "$opt_i " : "imtest ") .
|
||||
($opt_m ? "-m $opt_m ":"" ) .
|
||||
qq(-r $opt_r -a $opt_a -u $opt_u ).
|
||||
qq(-x $opt_x -w $opt_w -p $opt_p $opt_s);
|
||||
|
||||
open3($wfh,$rfh,$efh,$imt);
|
||||
|
||||
my $line;
|
||||
|
||||
until ($line =~ /^Security strength factor:/i ) {
|
||||
$line = <$rfh> or die "EOF\n";
|
||||
print STDERR "Prolog: $line" if $opt_d;
|
||||
}
|
||||
sleep 5;
|
||||
my $sock = IO::Socket::UNIX->new("$opt_x")
|
||||
or warn "No socket: $!\n" and exit;
|
||||
|
||||
print STDERR "<<<END OF PROLOG>>>\n" if $opt_d;
|
||||
my $imap = Mail::IMAPClient->new;
|
||||
$imap->Prewritemethod(\&Mail::IMAPClient::Strip_cr);
|
||||
$imap->User("$opt_u");
|
||||
$imap->Server("$opt_s");
|
||||
$imap->Port("$opt_p");
|
||||
$imap->Debug($opt_d);
|
||||
$imap->Debug_fh($opt_f||\*STDERR);
|
||||
$imap->State($imap->Connected);
|
||||
$imap->Socket($sock);
|
||||
|
||||
# Your code goes here:
|
||||
|
||||
$imap->Select("INBOX");
|
||||
for my $m (@{$imap->search("TEXT SUBJECT")} ) {
|
||||
print "Message $m:\t",$imap->subject($m),"\n";
|
||||
}
|
||||
# You should have finished your code by about here
|
||||
$imap->logout;
|
||||
|
||||
print STDERR "<<<END>>>\n" if $opt_d;
|
||||
|
||||
exit;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
imtestExample.pl -- uses imtest to connect and authenticate to imap server
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
=head2 Options
|
||||
|
||||
=over 4
|
||||
|
||||
=item -h
|
||||
|
||||
print this help message
|
||||
|
||||
=item -a auth
|
||||
|
||||
authenticate as user 'auth'. This value is passed as the '-a' value
|
||||
to imtest and defaults to whatever you supplied for -u.
|
||||
|
||||
=item -d
|
||||
|
||||
turn on Mail::IMAPClient debugging
|
||||
|
||||
=item -f file
|
||||
|
||||
write Mail::IMAPClient debugging info to file 'file'
|
||||
|
||||
=item -m mech
|
||||
|
||||
use authentication mechanism "mech"; default is to not supply -m to
|
||||
imtest
|
||||
|
||||
=item -i path
|
||||
|
||||
path to imtest executable; default is to let your shell find it via the
|
||||
PATH environmental variable.
|
||||
|
||||
=item -p port
|
||||
|
||||
port on mail server to connect to (default is 143)
|
||||
|
||||
=item -r rlm
|
||||
|
||||
Use realm 'rlm' (default is name of mail server)
|
||||
|
||||
=item -s srvr
|
||||
|
||||
Name of IMAP mail server (default is the localhost's hostname)
|
||||
|
||||
=item -u usr
|
||||
|
||||
Use 'usr' as the user id (required)
|
||||
|
||||
=item -w pswd
|
||||
|
||||
Use 'pswd' as the password for 'usr' (required)
|
||||
|
||||
=item -x path
|
||||
|
||||
Path to Unix socket (fifo). Default is '/tmp/$0.sock'.
|
||||
|
||||
=item -o 'ops'
|
||||
|
||||
Pass the string 'ops' directy to imtest as additional options.
|
||||
This is how you get "other" imtest options passed to imtest. (I only
|
||||
included switches for options that are either really common or useful
|
||||
to the IMAPClient object as well as to imtest.)
|
||||
|
||||
Many of these switches have the same function here as with imtest. I added a
|
||||
few extras though!
|
||||
|
||||
=back
|
||||
|
||||
Example:
|
||||
|
||||
imtestExample.pl -o '-k 128 -l 128' -s imapmail -u test -w testpswd \
|
||||
-i /usr/local/src/cyrus/cyrus-imapd-2.1.11/imtest/ \
|
||||
-m DIGEST-MD5
|
||||
|
||||
It's a good idea to test your options by running imtest from the command line
|
||||
(but without the -x switch) first. Once you have it working by hand you should
|
||||
be able to get it to work from this script (or one remarkably like it) without
|
||||
too much bloodshed.
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
David J. Kernen
|
||||
|
||||
The Kernen Group, Inc.
|
||||
|
||||
imap@kernengroup.com
|
||||
|
||||
Based on a suggestion by Tara L. Andrews.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
This example and Mail::IMAPClient are Copyright (c) 2003
|
||||
by The Kernen Group, Inc. All rights reserved.
|
||||
|
||||
This example is distributed with Mail::IMAPClient and
|
||||
subject to the same licensing requirements as Mail::IMAPClient.
|
||||
|
||||
imtest is a utility distributed with Cyrus IMAP server,
|
||||
Copyright (c) 1994-2000 Carnegie Mellon University.
|
||||
All rights reserved.
|
||||
|
||||
=cut
|
||||
|
|
@ -1,326 +0,0 @@
|
|||
#!/usr/local/bin/perl
|
||||
#$Id: migrate_mail2.pl,v 19991216.4 2003/06/12 21:38:33 dkernen Exp $
|
||||
#
|
||||
# An example of how to migrate from a Netscape server
|
||||
# (which uses a slash as a separator and which does
|
||||
# not allow subfolders under the INBOX, only next to it)
|
||||
# to a Cyrus server (which uses a dot (.) as a separator
|
||||
# and which requires subfolders to be under "INBOX").
|
||||
# There are also some allowed-character differences taken
|
||||
# into account but this is by no means complete AFAIK.
|
||||
#
|
||||
# This is an example. If you are doing mail migrations
|
||||
# then this may in fact be a very helpful example but
|
||||
# it is unlikely to work 100% correctly as-is.
|
||||
# A good place to start is by testing a rather large-volume
|
||||
# transfer of actual mail from the source server with the
|
||||
# -v option turned on and redirect output to a file for
|
||||
# perusal. Examine the output carefully for unexpected
|
||||
# results, such as a number of messages being skipped because
|
||||
# they're already in the target folder when you know darn
|
||||
# well this is the first time you ran the script. This
|
||||
# would indicate an incompatibility with the logic for
|
||||
# detecting duplicates, unless for some reason the source
|
||||
# mailbox contains a lot of duplicate messages to begin with.
|
||||
# (The latter case is an example of why you should use an
|
||||
# actual mailbox stuffed with actual mail for test; if you
|
||||
# generate test messages and then test migrating those you
|
||||
# will only prove that your test messages are migratable.
|
||||
#
|
||||
# Also, you may need to play with the rules
|
||||
# for translating folder names based on what kind of
|
||||
# names your target server and source server support.
|
||||
#
|
||||
# You may also need to play with the logic that determines
|
||||
# whether or not a message has already been migrated,
|
||||
# especially if your source server has messages that
|
||||
# did not come from an SMTP gateway or something like that.
|
||||
#
|
||||
# Some servers allow folders to contain mail and subfolders,
|
||||
# some allow folders to only contain either mail or subfolders.
|
||||
# If you are migrating from a "mixed use" type to a "single use"
|
||||
# type server then you'll have to figure out how to deal
|
||||
# with this. (This script deals with this by creating folders like
|
||||
# "/blah_mail", "/blah/blah_mail", and "/blah/blah/blah_mail"
|
||||
# to hold mail if the source folder contains mail and subfolders
|
||||
# and the target server supports only single-use folders.
|
||||
# You may not choose a different strategy.)
|
||||
#
|
||||
# Finally, it's possible that in some server-to-server
|
||||
# copies, the source server supports messages that the
|
||||
# target server considers unacceptable. For example, some
|
||||
# but not all IMAP servers flat out refuse to accept
|
||||
# messages with "base newlines", which is to say messages
|
||||
# whose lines are match the pattern /[^\r]\n$/. There is
|
||||
# no logic in this script that deals with the situation;
|
||||
# you will have to identify it if it exists and figure
|
||||
# out how you want to handle it.
|
||||
#
|
||||
# This is probably not an exhaustive list of issues you'll
|
||||
# face in a migration, but it's a start.
|
||||
#
|
||||
# If you're just migrating from an old version to a newer
|
||||
# version of the same server then you'll probably have
|
||||
# a much easier time of it.
|
||||
#
|
||||
#
|
||||
|
||||
use Mail::IMAPClient;
|
||||
use Data::Dumper;
|
||||
use IO::File;
|
||||
use File::Basename ;
|
||||
use Getopt::Std;
|
||||
use strict;
|
||||
use vars qw/ $opt_B $opt_D $opt_T $opt_U
|
||||
$opt_W $opt_b $opt_d $opt_h
|
||||
$opt_t $opt_u $opt_w $opt_v
|
||||
$opt_s $opt_S $opt_W $opt_p
|
||||
$opt_P $opt_f $opt_F $opt_m
|
||||
$opt_M
|
||||
/;
|
||||
|
||||
getopts('vs:S:u:U:dDb:B:f:F:w:W:p:P:t:T:hm:M:');
|
||||
|
||||
if ( $opt_h ) {
|
||||
print STDERR <<"HELP";
|
||||
|
||||
$0 - an example script demonstrating the use of the Mail::IMAPClient's
|
||||
migrate method.
|
||||
|
||||
Syntax:
|
||||
$0 -s source_server -u source_user -w source_password -p source_port \
|
||||
-d debug_source -f source_debugging_file -b source_buffsize \
|
||||
-t source_timeout -m source_auth_mechanism \
|
||||
-S target_server -U target_user -W target_password -P target_port \
|
||||
-D debug_target -F target_debugging_file -B target_buffsize \
|
||||
-T target_timeout -M target_auth_mechanism \
|
||||
-v
|
||||
|
||||
where "source" refers to the "copied from" mailbox, target is the
|
||||
"copied to" mailbox, and -v turns on verbose output.
|
||||
Authentication mechanisms default to "PLAIN".
|
||||
|
||||
HELP
|
||||
exit;
|
||||
}
|
||||
$opt_v and ++$|;
|
||||
print "$0: Started at ",scalar(localtime),"\n" if $opt_v;
|
||||
|
||||
$opt_p||=143;
|
||||
$opt_P||=143;
|
||||
|
||||
# Make a connection to the source mailbox:
|
||||
my $imap = Mail::IMAPClient->new(
|
||||
Server => $opt_s,
|
||||
User => $opt_u,
|
||||
Password=> $opt_w,
|
||||
Uid => 1,
|
||||
Port => $opt_p,
|
||||
Debug => $opt_d||0,
|
||||
Buffer => $opt_b||4096,
|
||||
Fast_io => 1,
|
||||
( $opt_m ? ( Authmechanism => $opt_m) : () ),
|
||||
Timeout => $opt_t,
|
||||
($opt_f ? ( Debug_fh=>IO::File->new(">$opt_f" )) : ()),
|
||||
) or die "$@";
|
||||
|
||||
# Make a connection to the target mailbox:
|
||||
my $imap2 = Mail::IMAPClient->new(
|
||||
Server => $opt_S,
|
||||
User => $opt_U,
|
||||
Password=> $opt_W,
|
||||
Port => $opt_P,
|
||||
Uid => 1,
|
||||
Debug => $opt_D||0,
|
||||
( $opt_M ? ( Authmechanism => $opt_M) : () ),
|
||||
($opt_F ? ( Debug_fh=>IO::File->new(">$opt_F")) : ()),
|
||||
Buffer => $opt_B||4096,
|
||||
Fast_io => 1,
|
||||
Timeout => $opt_T, # True value
|
||||
) or die "$@";
|
||||
|
||||
# Turn off buffering on debug files:
|
||||
$imap->Debug_fh->autoflush;
|
||||
$imap2->Debug_fh->autoflush;
|
||||
|
||||
# Get folder hierarchy separator characters from source and target:
|
||||
my $sep1 = $imap->separator;
|
||||
my $sep2 = $imap2->separator;
|
||||
|
||||
# Find out if source and target support subfolders inside INBOX:
|
||||
my $inferiorFlag1 = $imap->is_parent("INBOX");
|
||||
my $inferiorFlag2 = $imap2->is_parent("INBOX");
|
||||
|
||||
# Set up a test folders to see if the source and target support mixed-use
|
||||
# folders (i.e. folders with both subfolders and mail messages):
|
||||
my $testFolder1 = "Migrate_Test_$$" ; # Ex: Migrate_Test_1234
|
||||
$testFolder1 = $inferiorFlag2 ?
|
||||
"INBOX" . $sep2 . $testFolder1 :
|
||||
$testFolder1 ;
|
||||
|
||||
# The following folder will be a subfolder of $testFolder1:
|
||||
my $testFolder2 = "Migrate_Test_$$" . $sep2 . "Migrate_test_subfolder_$$" ;
|
||||
$testFolder2 = $inferiorFlag2 ? "INBOX" . $sep2 . $testFolder2 : $testFolder2 ;
|
||||
|
||||
$imap2->create($testFolder2) ; # Create the subfolder first; RFC2060 dictates that
|
||||
# the parent folder should be created at the same time
|
||||
|
||||
|
||||
# The following line inspired the selectable method. It was also made obsolete by it,
|
||||
# but I'm leaving it as is to demonstrate use of lower-level method calls:
|
||||
my $mixedUse2 = grep(/NoSelect/i,$imap2->list("",$testFolder1))? 0 : 1;
|
||||
|
||||
# Repeat the above with the source mailbox:
|
||||
$testFolder2 = "Migrate_Test_$$" . $sep1 . "Migrate_test_subfolder_$$" ;
|
||||
$testFolder2 = $inferiorFlag1 ? "INBOX" . $sep1 . $testFolder1 : $testFolder1 ;
|
||||
|
||||
$imap->create($testFolder2) ;
|
||||
|
||||
my $mixedUse1 = grep(/NoSelect/i,$imap->list("",$testFolder1))? 0 : 1;
|
||||
|
||||
print "Imap host $opt_s:$opt_p uses a '$sep1' as a separator and ",
|
||||
( defined($inferiorFlag1) ? "allows " : "does not allow "),
|
||||
"children in the INBOX. It supports ",
|
||||
($mixedUse1?"mixed use ":"single use "), "folders.\n" if $opt_v;
|
||||
|
||||
print "Imap host $opt_S:$opt_P uses a '$sep2' as a separator and ",
|
||||
( defined($inferiorFlag2) ? "allows " : "does not allow "),
|
||||
"children in the INBOX. It supports ",
|
||||
($mixedUse2?"mixed use ":"single use "), "folders.\n" if $opt_v;
|
||||
|
||||
for ($testFolder1,$testFolder2) {$imap->delete($_); $imap2->delete($_);}
|
||||
|
||||
my($totalMsgs, $totalBytes) = (0,0);
|
||||
|
||||
# Now we will migrate the folder. Here we are doing one message at a time
|
||||
# so that we can do more granular status reporting and error checking.
|
||||
# A lazier way would be to do all the messages in one migrate method call
|
||||
# (specifying "ALL" as the message number) but then we wouldn't be able
|
||||
# to print out which message we were migrating and it would be a little
|
||||
# bit tougher to control checking for duplicates and stuff like that.
|
||||
# We could also check the size of the message on the target right after
|
||||
# the migrate as an extra safety check if we wanted to but I didn't bother
|
||||
# here. (I saved as an exercise for the reader. Yeah! That's it! An exercise!)
|
||||
|
||||
# Iterate over all the folders in the source mailbox:
|
||||
for my $f ($imap->folders) {
|
||||
# Select the folder on the source side:
|
||||
$imap->select($f) ;
|
||||
|
||||
# Massage the foldername into an acceptable target-side foldername:
|
||||
my $targF = "";
|
||||
my $srcF = $f;
|
||||
$srcF =~ s/^INBOX$sep1//i;
|
||||
if ( $inferiorFlag2 ) {
|
||||
$targF = $srcF eq "INBOX" ? "INBOX" : "INBOX.$f" ;
|
||||
} else {
|
||||
$targF = $srcF ;
|
||||
}
|
||||
|
||||
$targF =~ s/$sep1/$sep2/go unless $sep1 eq $sep2;
|
||||
$targF =~ tr/#\$\& '"/\@\@+_/;
|
||||
if ( $imap->is_parent($f) and !$mixedUse2 ) {
|
||||
$targF .= "_mail" ;
|
||||
}
|
||||
print "Migrating folder $f to $targF\n" if $opt_v;
|
||||
|
||||
# Create the (massaged) folder on the target side:
|
||||
unless ( $imap2->exists($targF) ) {
|
||||
$imap2->create($imap2->Massage($targF))
|
||||
or warn "Cannot create $targF on " . $imap2->Server . ": $@\n" and next;
|
||||
}
|
||||
|
||||
# ... and select it
|
||||
$imap2->select($imap2->Massage($targF))
|
||||
or warn "Cannot select $targF on " . $imap2->Server . ": $@\n" and next;
|
||||
|
||||
# now that we know the target folder is selectable, we can close it again:
|
||||
$imap2->close;
|
||||
my $count = 0;
|
||||
my $expectedTotal = $imap->message_count($f) ;
|
||||
|
||||
# Now start iterating over all the messages on the source side...
|
||||
for my $msg ($imap->messages) {
|
||||
++$count;
|
||||
my $h = "";
|
||||
# Get some basic info about the message:
|
||||
eval { $h = ($imap->parse_headers($msg,"Message-id")||{})->{'Message-id'}[0]};
|
||||
my $tsize = $imap->size($msg);
|
||||
my $ret = 0 ; my $h2 = [];
|
||||
|
||||
# Make sure we didn't already migrate the message in a previous pass:
|
||||
$imap2->select($targF);
|
||||
if ( $tsize and $h and $h2 = $imap2->search(
|
||||
HEADER => 'Message-id' => $imap2->Quote($h),
|
||||
NOT => SMALLER => $tsize,
|
||||
NOT => LARGER => $tsize
|
||||
)
|
||||
) {
|
||||
print
|
||||
"Skipping $f/$msg to $targF. ",
|
||||
"One or more messages (" ,join(", ",@$h2),
|
||||
") with the same size and message id ($h) ",
|
||||
"is already on the server. ",
|
||||
"\n"
|
||||
if $opt_v;
|
||||
$imap2->close;
|
||||
|
||||
} else {
|
||||
|
||||
print
|
||||
"Migrating $f/$msg to $targF. ",
|
||||
"Message #$count of $expectedTotal has ",
|
||||
$tsize , " bytes.",
|
||||
"\n" if $opt_v;
|
||||
$imap2->close;
|
||||
|
||||
# Migrate the message:
|
||||
my $ret = $imap->migrate($imap2,$msg,"$targF") ;
|
||||
$ret and ( $totalMsgs++ , $totalBytes += $tsize);
|
||||
$ret or warn "Cannot migrate $f/$msg to $targF on " . $imap2->Server . ": $@\n" ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print "$0: Finished migrating $totalMsgs messages and $totalBytes bytes at ",scalar(localtime),"\n"
|
||||
if $opt_v;
|
||||
exit;
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
David J. Kernen
|
||||
|
||||
The Kernen Group, Inc.
|
||||
|
||||
imap@kernengroup.com
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
This example and Mail::IMAPClient are Copyright (c) 2003
|
||||
by The Kernen Group, Inc. All rights reserved.
|
||||
|
||||
This example is distributed with Mail::IMAPClient and
|
||||
subject to the same licensing requirements as Mail::IMAPClient.
|
||||
|
||||
imtest is a utility distributed with Cyrus IMAP server,
|
||||
Copyright (c) 1994-2000 Carnegie Mellon University.
|
||||
All rights reserved.
|
||||
|
||||
=cut
|
||||
|
||||
#$Log: migrate_mail2.pl,v $
|
||||
#Revision 19991216.4 2003/06/12 21:38:33 dkernen
|
||||
#
|
||||
#Preparing 2.2.8
|
||||
#Added Files: COPYRIGHT
|
||||
#Modified Files: Parse.grammar
|
||||
#Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
# Parse.grammar Parse.pod
|
||||
# range.t
|
||||
# Thread.grammar
|
||||
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
|
||||
# rfc2221.txt rfc2359.txt rfc2683.txt
|
||||
#
|
|
@ -1,131 +0,0 @@
|
|||
#!/usr/local/bin/perl
|
||||
#
|
||||
# This is an example demonstrating the use of the migrate method.
|
||||
# Note that the migrate method is considered experimental and should
|
||||
# be used with caution.
|
||||
#
|
||||
#$Id: migrate_mbox.pl,v 19991216.2 2003/06/12 21:38:33 dkernen Exp $
|
||||
#
|
||||
|
||||
use Mail::IMAPClient;
|
||||
use IO::File;
|
||||
use File::Basename ;
|
||||
use Getopt::Std;
|
||||
use warnings;
|
||||
use vars qw/$opt_h $opt_H
|
||||
$opt_s $opt_u $opt_p $opt_d $opt_b $opt_o
|
||||
$opt_S $opt_U $opt_P $opt_D $opt_B $opt_O
|
||||
/;
|
||||
|
||||
getopts('Hhs:S:u:U:p:P:d:D:b:B:o:O:');
|
||||
if ($opt_h or $opt_H ) {
|
||||
print << "HELP";
|
||||
|
||||
|
||||
Usage:
|
||||
|
||||
$0 -[h|H] -- prints this message
|
||||
|
||||
Lower-case options are for source server; upper-case options are for the target server.
|
||||
|
||||
$0 -s server -S server -u uid -U uid -p passwd -P passwd \
|
||||
-b buffersize -B buffersize -o debugFile -O debugFile > error_file
|
||||
|
||||
All uppercase options except -O default to the lowercase option that was specified.
|
||||
If you don't specify any uppercase options at all then God help you, I don't know
|
||||
what will happen.
|
||||
|
||||
Always capture STDERR so that you'll be able to resolve any problems that come up.
|
||||
|
||||
|
||||
HELP
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
my $imap = Mail::IMAPClient->new(
|
||||
Server => $opt_s,
|
||||
User => $opt_u,
|
||||
Password=> $opt_p,
|
||||
Uid => 1,
|
||||
Debug => $opt_d,
|
||||
Buffer => $opt_b||4096,
|
||||
Fast_io => 1,
|
||||
Timeout => 160, # True value
|
||||
Debug_fh=> (
|
||||
$opt_o ? IO::File->new(">$opt_o")||die "can't open $opt_o: $!\n" : undef )
|
||||
) or die "Error opening source connection: $@\n";
|
||||
|
||||
my $imap2 = Mail::IMAPClient->new(
|
||||
Server => $opt_S||$opt_s,
|
||||
User => $opt_U||$opt_u,
|
||||
Password=> $opt_P||$opt_p,
|
||||
Uid => 1,
|
||||
Debug => $opt_D||$opt_d,
|
||||
Buffer => $opt_B||$opt_b||4096,
|
||||
Fast_io => 1,
|
||||
Timeout => 160,
|
||||
Debug_fh=> (
|
||||
$opt_O ? IO::File->new(">$opt_O")||die "can't open $opt_O: $!\n" : undef )
|
||||
) or die "Error opening target connection: $@\n";
|
||||
|
||||
|
||||
$imap->Debug_fh->autoflush;
|
||||
$imap2->Debug_fh->autoflush;
|
||||
|
||||
for my $f ($imap->folders) { $imap->select($f) ; $imap->migrate($imap2,"ALL") ;}
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
David J. Kernen
|
||||
|
||||
The Kernen Group, Inc.
|
||||
|
||||
imap@kernengroup.com
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
This example and Mail::IMAPClient are Copyright (c) 2003
|
||||
by The Kernen Group, Inc. All rights reserved.
|
||||
|
||||
This example is distributed with Mail::IMAPClient and
|
||||
subject to the same licensing requirements as Mail::IMAPClient.
|
||||
|
||||
imtest is a utility distributed with Cyrus IMAP server,
|
||||
Copyright (c) 1994-2000 Carnegie Mellon University.
|
||||
All rights reserved.
|
||||
|
||||
=cut
|
||||
|
||||
#
|
||||
#$Log: migrate_mbox.pl,v $
|
||||
#Revision 19991216.2 2003/06/12 21:38:33 dkernen
|
||||
#
|
||||
#Preparing 2.2.8
|
||||
#Added Files: COPYRIGHT
|
||||
#Modified Files: Parse.grammar
|
||||
#Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
# Parse.grammar Parse.pod
|
||||
# range.t
|
||||
# Thread.grammar
|
||||
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
|
||||
# rfc2221.txt rfc2359.txt rfc2683.txt
|
||||
#
|
||||
#Revision 1.1 2003/06/12 21:38:15 dkernen
|
||||
#
|
||||
#Preparing 2.2.8
|
||||
#Added Files: COPYRIGHT
|
||||
#Modified Files: Parse.grammar
|
||||
#Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
# Parse.grammar Parse.pod
|
||||
# range.t
|
||||
# Thread.grammar
|
||||
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
|
||||
# rfc2221.txt rfc2359.txt rfc2683.txt
|
||||
#
|
||||
#
|
|
@ -1,319 +0,0 @@
|
|||
#!/usr/local/bin/perl
|
||||
#$Id: populate_mailbox.pl,v 19991216.8 2003/06/12 21:38:34 dkernen Exp $ #
|
||||
use Time::Local ;
|
||||
use FileHandle ;
|
||||
use File::Copy ;
|
||||
use Mail::IMAPClient;
|
||||
use Sys::Hostname ;
|
||||
#
|
||||
my $default_user = 'default' ;
|
||||
my $default_pswd = 'default' ;
|
||||
#
|
||||
#########################################################################
|
||||
# ARGS: DATE = YYYYMMDDHHMM (defaults to current system date) #
|
||||
# UID = IMAP account id (defaults to $default_user) #
|
||||
# PSWD = uid's password (defaults to $default_pswd) #
|
||||
# HOST = Target host (defaults to localhost) #
|
||||
# CLEAN = 1 (defaults to 0; used to clean out mailbox 1st) #
|
||||
# CLEANONLY= 1 (defaults to 0; if 1 then only CLEAN is done) #
|
||||
# DOMAIN = x.com (no default) the mail domain for UID's address #
|
||||
# #
|
||||
# EG: populate_mailbox.pl DATE=200001010100 UID=testuser #
|
||||
# #
|
||||
#########################################################################
|
||||
#
|
||||
(my($x)= join(" ",@ARGV)) ;
|
||||
$x=~s~=~ ~g ;
|
||||
chomp($x) ;
|
||||
#
|
||||
my %hash = split(/\s+/, $x) if $x ;
|
||||
#
|
||||
while (my ($k,$v) = each %hash ) {
|
||||
$hash{uc $k} = $v ;
|
||||
}
|
||||
|
||||
while (my ($k,$v) = each %hash ) {
|
||||
delete $hash{$k} if $k =~ tr/[a-z]// ;
|
||||
}
|
||||
;
|
||||
$hash{UID} ||= "$default_user" ;
|
||||
$hash{PSWD} ||= "$default_pswd" ;
|
||||
$hash{HOST} ||= hostname ;
|
||||
#
|
||||
while (my ($k,$v) = each %hash ) {
|
||||
print "Running with $k set to $v\n" ;
|
||||
}
|
||||
#
|
||||
my $domain = $hash{DOMAIN} or die "No mail domain provided.\n" ;
|
||||
my $now = seconds($hash{DATE}) || time ;
|
||||
#
|
||||
my $six = $now - ( 6 * 24 * 60 * 60 ) ;
|
||||
my $seven = $now - ( 7 * 24 * 60 * 60 ) ;
|
||||
my $notthirty = $now - ( 29 * 24 * 60 * 60 ) ;
|
||||
my $thirty = $now - ( 30 * 24 * 60 * 60 ) ;
|
||||
my $notsixty = $now - ( 59 * 24 * 60 * 60 ) ;
|
||||
my $sixty = $now - ( 60 * 24 * 60 * 60 ) ;
|
||||
my $notd365 = $now - ( 364 * 24 * 60 * 60 ) ;
|
||||
my $d365 = $now - ( 365 * 24 * 60 * 60 ) ;
|
||||
#
|
||||
$hash{SUBJECTS} = [ "Sixty days old", "Less than sixty days old" ,
|
||||
"365 days old", "Less than 365 days old" ,
|
||||
"Trash/Incinerator -- 7 days old" ,
|
||||
"Sent -- 29 days old" ,
|
||||
"Sent -- 30 days old" ,
|
||||
"Trash -- 6 days old" ,
|
||||
] ;
|
||||
$hash{FOLDERS} = [ "Sent", "INBOX", "Trash" ,
|
||||
"365_folder", "Trash/Incinerator" ,
|
||||
"not_365_folder" ,
|
||||
] ;
|
||||
#
|
||||
&clean_mailbox if $hash{CLEANONLY} || $hash{CLEAN} ;
|
||||
exit if $hash{CLEANONLY} ;
|
||||
#
|
||||
#send to: date: subject: #
|
||||
#-------- --- ----- --------- #
|
||||
sendmail( $hash{UID}, $sixty, "Sixty days old" ) ;
|
||||
sendmail( $hash{UID}, $notsixty, "Less than sixty days old") ;
|
||||
sendmail( $hash{UID}, $d365, "365 days old" ) ;
|
||||
sendmail( $hash{UID}, $notd365, "Less than 365 days old" ) ;
|
||||
#
|
||||
populate_trash("Trash/Incinerator",$hash{UID}, $seven, 7 ) ;
|
||||
populate_trash( "Trash" , $hash{UID}, $six, 6 ) ;
|
||||
populate_trash( "Sent" , $hash{UID}, $thirty, 30 ) ;
|
||||
populate_trash( "Sent" , $hash{UID}, $notthirty, 29 ) ;
|
||||
#
|
||||
movemail( "365 days old" ,
|
||||
"365_folder" ) ;
|
||||
#
|
||||
movemail( "Less than 365 days old" ,
|
||||
"not_365_folder" ) ;
|
||||
#
|
||||
exit ;
|
||||
#
|
||||
#
|
||||
sub seconds {
|
||||
my $d = shift or return undef ;
|
||||
my($yy,$moy,$dom,$hr,$min) =
|
||||
#
|
||||
$d =~ m! ^ # anchor at start #
|
||||
(\d\d\d\d) # year #
|
||||
(\d\d) # month #
|
||||
(\d\d) # day #
|
||||
(\d\d) # hour #
|
||||
(\d\d) # minute #
|
||||
!x ;
|
||||
#
|
||||
return timegm(0,$min,$hr,$dom,$moy-1,($yy>99?$yy-1900:$yy)) ;
|
||||
}
|
||||
#
|
||||
sub sendmail {
|
||||
#
|
||||
my($to,$date,$subject) = @_ ;
|
||||
my $text = <<EOTEXT ;
|
||||
To: $to\@$hash{DOMAIN}
|
||||
Date: @{[&rfc822_date($date)]}
|
||||
Subject: $subject
|
||||
|
||||
Dear mail tester,
|
||||
|
||||
This is a test message to test mail for messages \l$subject.
|
||||
|
||||
I hope you like it!
|
||||
|
||||
Love,
|
||||
The E-Mail Engineering Team
|
||||
|
||||
EOTEXT
|
||||
#
|
||||
for (my $x = 0; $x < 10 ; $x ++ ) {
|
||||
my $imap = Mail::IMAPClient->new (
|
||||
Server => $hash{HOST} ,
|
||||
User => $hash{UID} ,
|
||||
Password=> $hash{PSWD} )
|
||||
or die "can't connect: $!\n" ;
|
||||
#
|
||||
$imap->append("INBOX",$text) ;
|
||||
$imap->logout ;
|
||||
}
|
||||
}
|
||||
#
|
||||
sub populate_trash {
|
||||
my $where = shift ;
|
||||
my $to = shift ;
|
||||
my $date = shift ;
|
||||
my $d = shift ;
|
||||
#
|
||||
my($ss,$min,$hr,$day,$mon,$year)=gmtime($date) ;
|
||||
$mon++ ;
|
||||
$year += 1900 ;
|
||||
my $fn =sprintf("%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d" ,
|
||||
$year,$mon,$day,$hr,$min,$ss ) ;
|
||||
my $x = 0 ;
|
||||
my $subject = "$where -- $d days old" ;
|
||||
while ($x++ < 10) {
|
||||
my $fh ;
|
||||
$fh .= "Date: @{[&rfc822_date($date)]}\n" ;
|
||||
$fh .= <<EOTRAH ;
|
||||
Subject: $subject
|
||||
|
||||
This note was put in the $where folder $d days ago. (My how time flies!)
|
||||
I hope you enjoyed testing with it!
|
||||
|
||||
EOTRAH
|
||||
my $imap = Mail::IMAPClient->new (
|
||||
Server => $hash{HOST} ,
|
||||
User => $hash{UID} ,
|
||||
Password=> $hash{PSWD} )
|
||||
or die "can't connect: $!\n" ;
|
||||
$imap->append($where, $fh) ;
|
||||
#
|
||||
}
|
||||
#
|
||||
}
|
||||
#
|
||||
sub movemail {
|
||||
#
|
||||
my ($subj,$fold) = @_ ;
|
||||
my $fh = Mail::IMAPClient->new (
|
||||
Debug => 0 ,
|
||||
Server => $hash{HOST} ,
|
||||
User => $hash{UID} ,
|
||||
Password => $hash{PSWD} ,
|
||||
)
|
||||
;
|
||||
#
|
||||
$fh->select("inbox") or die "cannot open inbox: $!\n" ;
|
||||
#
|
||||
foreach my $f ($fh->search(qq(SUBJECT "$subj")) ) {
|
||||
#
|
||||
$fh->move($fold,$f) ;
|
||||
#
|
||||
}
|
||||
#
|
||||
}
|
||||
#
|
||||
sub clean_mailbox {
|
||||
#
|
||||
my $fh =Mail::IMAPClient->new (
|
||||
Debug => 0 ,
|
||||
Server => $hash{HOST} ,
|
||||
User => $hash{UID} ,
|
||||
Password => $hash{PSWD} ,
|
||||
)
|
||||
;
|
||||
for my $x (@{$hash{FOLDERS}}) {
|
||||
my @msgs ;
|
||||
$fh->create($x) unless $fh->exists($x) ;
|
||||
$fh->select($x) ;
|
||||
for my $s (@{$hash{SUBJECTS}}) {
|
||||
push @msgs, $fh->search(qq(SUBJECT "$s")) ;
|
||||
}
|
||||
$fh->delete_message(@msgs) if scalar(@msgs) ;
|
||||
$fh->expunge ;
|
||||
}
|
||||
}
|
||||
#
|
||||
sub rfc822_date {
|
||||
#Date: Fri, 09 Jul 1999 13:10:55 -0400 #
|
||||
my $date = shift ;
|
||||
my @date = localtime($date) ;
|
||||
my @dow = qw{ Sun Mon Tue Wed Thu Fri Sat } ;
|
||||
my @mnt = qw{ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec} ;
|
||||
#
|
||||
return sprintf (
|
||||
"%s, %2.2d %s %4.4s %2.2d:%2.2d:%2.2d -0400" ,
|
||||
$dow[$date[6]] ,
|
||||
$date[3] ,
|
||||
$mnt[$date[4]] ,
|
||||
$date[5]+=1900 ,
|
||||
$date[2] ,
|
||||
$date[1] ,
|
||||
$date[0] )
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
David J. Kernen
|
||||
|
||||
The Kernen Group, Inc.
|
||||
|
||||
imap@kernengroup.com
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
This example and Mail::IMAPClient are Copyright (c) 2003
|
||||
by The Kernen Group, Inc. All rights reserved.
|
||||
|
||||
This example is distributed with Mail::IMAPClient and
|
||||
subject to the same licensing requirements as Mail::IMAPClient.
|
||||
|
||||
imtest is a utility distributed with Cyrus IMAP server,
|
||||
Copyright (c) 1994-2000 Carnegie Mellon University.
|
||||
All rights reserved.
|
||||
|
||||
=cut
|
||||
|
||||
# $Id: populate_mailbox.pl,v 19991216.8 2003/06/12 21:38:34 dkernen Exp $
|
||||
# $Log: populate_mailbox.pl,v $
|
||||
# Revision 19991216.8 2003/06/12 21:38:34 dkernen
|
||||
#
|
||||
# Preparing 2.2.8
|
||||
# Added Files: COPYRIGHT
|
||||
# Modified Files: Parse.grammar
|
||||
# Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
# Parse.grammar Parse.pod
|
||||
# range.t
|
||||
# Thread.grammar
|
||||
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
|
||||
# rfc2221.txt rfc2359.txt rfc2683.txt
|
||||
#
|
||||
# Revision 1.1 2003/06/12 21:38:16 dkernen
|
||||
#
|
||||
# Preparing 2.2.8
|
||||
# Added Files: COPYRIGHT
|
||||
# Modified Files: Parse.grammar
|
||||
# Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
# Parse.grammar Parse.pod
|
||||
# range.t
|
||||
# Thread.grammar
|
||||
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
|
||||
# rfc2221.txt rfc2359.txt rfc2683.txt
|
||||
#
|
||||
# Revision 19991216.7 2002/08/23 13:29:49 dkernen
|
||||
#
|
||||
# Modified Files: Changes IMAPClient.pm INSTALL MANIFEST Makefile Makefile.PL README Todo test.txt
|
||||
# Made changes to create version 2.1.6.
|
||||
# Modified Files:
|
||||
# imap_to_mbox.pl populate_mailbox.pl
|
||||
# Added Files:
|
||||
# cleanTest.pl migrate_mbox.pl
|
||||
#
|
||||
# Revision 19991216.6 2000/12/11 21:58:53 dkernen
|
||||
#
|
||||
# Modified Files:
|
||||
# build_dist.pl build_ldif.pl copy_folder.pl find_dup_msgs.pl
|
||||
# imap_to_mbox.pl populate_mailbox.pl
|
||||
# to add CVS data
|
||||
#
|
||||
# Revision 19991216.5 1999/12/16 17:19:15 dkernen
|
||||
# Bring up to same level
|
||||
#
|
||||
# Revision 19991124.3 1999/12/16 17:14:26 dkernen
|
||||
# Incorporate changes for exists method performance enhancement
|
||||
#
|
||||
# Revision 19991124.02 1999/11/24 17:46:21 dkernen
|
||||
# More fixes to t/basic.t
|
||||
#
|
||||
# Revision 19991124.01 1999/11/24 16:51:51 dkernen
|
||||
# Changed t/basic.t to test for UIDPLUS before trying UID cmds
|
||||
#
|
||||
# Revision 1.4 1999/11/23 17:51:06 dkernen
|
||||
# Committing version 1.06 distribution copy
|
||||
#
|
|
@ -1,88 +0,0 @@
|
|||
#!/usr/local/bin/perl
|
||||
#$Id: sharedFolder.pl,v 19991216.1 2003/06/12 21:38:35 dkernen Exp $
|
||||
|
||||
use Mail::IMAPClient;
|
||||
use Getopt::Std;
|
||||
use File::Basename;
|
||||
getopts('s:u:p:f:dh');
|
||||
|
||||
if ($opt_h) {
|
||||
|
||||
print STDERR "$0 -- example of how to select shared folder\n",
|
||||
"\n\nUsage:\n",
|
||||
"\t-s server -- specify name or ip address of mail server\n",
|
||||
"\t-u userid -- specify login name of authenticating user\n",
|
||||
"\t-p passwd -- specify login password of authenticating user\n",
|
||||
"\t-f folder -- specify shared folder to access (i.e. '-f frank/INBOX')\n",
|
||||
"\t-h display this help message\n\n";
|
||||
"\t-d turn on debugging output\n\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
my $server = $opt_s or die "No server name specified\n";
|
||||
my $user = $opt_u or die "No user name specified\n";
|
||||
my $pass = $opt_p or die "No password specified\n";
|
||||
my $folder = $opt_f or die "No shared folder specified\n";
|
||||
|
||||
chomp $pass;
|
||||
my $imap = Mail::IMAPClient->new(Server=>$server,User=>$user,Password=>$pass,Debug=>$opt_d)
|
||||
or die "Can't connect to $user\@$server: $@ $!\n";
|
||||
|
||||
my($prefix,$prefSep) = @{$imap->namespace->[1][0]}
|
||||
or die "Can't get shared folder namespace or separator: $@\n";
|
||||
|
||||
|
||||
my $target = $prefix .
|
||||
( $prefix =~ /\Q$prefSep\E$/ || $opt_f =~ /^\Q$prefSep/ ? "" : $prefSep ) .
|
||||
$opt_f ;
|
||||
|
||||
print "Selecting $target\n";
|
||||
|
||||
$imap->select($target)
|
||||
or die "Cannot select $target: $@\n";
|
||||
|
||||
print "Ok: $target has ", $imap->message_count($target)," messages.\n";
|
||||
|
||||
$imap->logout;
|
||||
exit;
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
David J. Kernen
|
||||
|
||||
The Kernen Group, Inc.
|
||||
|
||||
imap@kernengroup.com
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
This example and Mail::IMAPClient are Copyright (c) 2003
|
||||
by The Kernen Group, Inc. All rights reserved.
|
||||
|
||||
This example is distributed with Mail::IMAPClient and
|
||||
subject to the same licensing requirements as Mail::IMAPClient.
|
||||
|
||||
imtest is a utility distributed with Cyrus IMAP server,
|
||||
Copyright (c) 1994-2000 Carnegie Mellon University.
|
||||
All rights reserved.
|
||||
|
||||
=cut
|
||||
|
||||
#
|
||||
#$Log: sharedFolder.pl,v $
|
||||
#Revision 19991216.1 2003/06/12 21:38:35 dkernen
|
||||
#
|
||||
#Preparing 2.2.8
|
||||
#Added Files: COPYRIGHT
|
||||
#Modified Files: Parse.grammar
|
||||
#Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
# Parse.grammar Parse.pod
|
||||
# range.t
|
||||
# Thread.grammar
|
||||
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
|
||||
# rfc2221.txt rfc2359.txt rfc2683.txt
|
||||
#
|
||||
#
|
|
@ -1 +0,0 @@
|
|||
&parse_options("NonStop=1 LineInfo=mail_imapclient_db.out");
|
|
@ -1,808 +0,0 @@
|
|||
# Before `make install' is performed this script should be runnable with
|
||||
# `make test'. After `make install' it should work as `perl test.pl'
|
||||
# $Id: basic.t,v 19991216.27 2003/06/12 21:38:35 dkernen Exp $
|
||||
######################### We start with some black magic to print on failure.
|
||||
|
||||
# Change 1..1 below to 1..last_test_to_print .
|
||||
|
||||
END {print "not ok 1\n" unless $main::loaded;}
|
||||
use Mail::IMAPClient;
|
||||
|
||||
######################### End of black magic.
|
||||
|
||||
|
||||
my $test = 0;
|
||||
my %parms;
|
||||
my $imap;
|
||||
my @tests;
|
||||
my $uid;
|
||||
$fast||=0;
|
||||
$range||=0;
|
||||
$uidplus||=0;
|
||||
$authmech||=0;
|
||||
use vars qw/*TMP $imap/;
|
||||
|
||||
BEGIN {
|
||||
$^W++;
|
||||
# $ARGV[0]||=1;
|
||||
my $target; my $sep; my $target2;
|
||||
|
||||
push @tests, sub { $test++ } ; # Dummy test 1
|
||||
push @tests, sub { # 2
|
||||
if (ref($imap)) {
|
||||
print "ok ",++$test,"\n"; # ok 2
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
};
|
||||
|
||||
push @tests, sub { # 3
|
||||
if ($sep = $imap->separator) {
|
||||
print "ok ",++$test,"\n"; # ok 3
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
};
|
||||
|
||||
push @tests, sub { # 4
|
||||
my $isparent;
|
||||
$isparent = $imap->is_parent(INBOX);
|
||||
if (defined($isparent)) {
|
||||
$target = "INBOX${sep}IMAPClient_$$";
|
||||
$target2 = "INBOX${sep}IMAPClient_2_$$";
|
||||
print "ok ",++$test,"\n"; # ok 4
|
||||
} else {
|
||||
$target = "IMAPClient_$$";
|
||||
$target2 = "IMAPClient_2_$$";
|
||||
print "ok ",++$test,"\n"; # ok 4
|
||||
}
|
||||
# print "target is $target\n";
|
||||
};
|
||||
|
||||
|
||||
push @tests, sub { # 5
|
||||
if ( eval { $imap->select('inbox') } ) {
|
||||
print "ok ",++$test,"\n"; # ok 5
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
# print $imap->History,"\n";
|
||||
}
|
||||
};
|
||||
|
||||
push @tests, sub { # 6
|
||||
if ( eval { $imap->create("$target") } ) {
|
||||
print "ok ",++$test,"\n"; # ok 6
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
};
|
||||
push @tests,
|
||||
sub { return "dummy test 8" },
|
||||
sub { return "dummy test 9" };
|
||||
|
||||
push @tests, sub { # 7,8,9
|
||||
if (defined($imap->is_parent($target))) { #7
|
||||
if ( eval { $imap->create(qq($target${sep}has "quotes")) } ) {
|
||||
print "ok ",++$test,"\n"; # ok 7
|
||||
} else {
|
||||
if ($imap->LastError =~ /NO Invalid.*name/) {
|
||||
print "ok ",++$test,
|
||||
" $parms{server} doesn't support quotes in folder names--",
|
||||
"skipping next 2 tests\n"; # ok 7
|
||||
print "ok ", ++$test," (skipped)\n"; # ok 8
|
||||
print "ok ", ++$test," (skipped)\n"; # ok 9
|
||||
return;
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
print "ok ", ++$test," (skipped)\n"; # ok 8
|
||||
print "ok ", ++$test," (skipped)\n"; # ok 9
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
if ( eval { $imap->select(qq($target${sep}has "quotes")) } ) { #8
|
||||
print "ok ",++$test,"\n"; # ok 8
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
$imap->close;
|
||||
$imap->select('inbox');
|
||||
if ( eval { $imap->delete(qq($target${sep}has "quotes")) } ) { #9
|
||||
print "ok ",++$test,"\n"; # ok 9
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
} else {
|
||||
print "ok ",++$test,"\n"; # ok 7
|
||||
print "ok ",++$test,"\n"; # ok 8
|
||||
print "ok ",++$test,"\n"; # ok 9
|
||||
}
|
||||
};
|
||||
|
||||
push @tests, sub { # 10
|
||||
# print $db $imap->Report;
|
||||
if ( eval { $imap->exists("$target") } ) {
|
||||
print "ok ",++$test,"\n";
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
};
|
||||
|
||||
push @tests, sub { # 11
|
||||
if ( eval { $imap->create($target2) } ) {
|
||||
print "ok ",++$test,"\n";
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
}, sub { # 12
|
||||
if ( eval { $imap->exists($target2) } ) {
|
||||
print "ok ",++$test,"\n";
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
};
|
||||
|
||||
push @tests, sub { # 13
|
||||
if ( eval { $uid = $imap->append("$target",&testmsg)} ) {
|
||||
print "ok ",++$test,"\n";
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
};
|
||||
|
||||
push @tests, sub { # 14
|
||||
if ( eval { $imap->select("$target") } ) {
|
||||
print "ok ",++$test,"\n";
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
};
|
||||
{
|
||||
my $size; my $string; my $target;
|
||||
my $file = "./test_message_to_file";
|
||||
push @tests, sub { # 15, 16, 17, 18, 19
|
||||
$target = ref($uid) ? ($imap->search("ALL"))[0] : $uid;
|
||||
if ( eval { $size = $imap->size($target) } ) { # 15 test size
|
||||
print "ok ",++$test,"\n"; #15
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
}, sub {
|
||||
if ( eval { $string = $imap->message_string($target) } ) { # 16 test message_string
|
||||
print "ok ",++$test,"\n"; #16
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
}, sub {
|
||||
if ( $size == length($string) ) { # 17 test size = length of string
|
||||
print "ok ",++$test,"\n"; #17
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
};
|
||||
push @tests, sub {
|
||||
eval { $imap->message_to_file($file,$target)};
|
||||
if ( $@ ) { # 18 test message_to_file success
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
} else {
|
||||
print "ok ",++$test,"\n"; #18
|
||||
}
|
||||
};
|
||||
push @tests, sub {
|
||||
my $array_ref = ""; # 19 test for proper search failure
|
||||
eval { $array_ref = $imap->search("HEADER","Message-id","NOT_A_MESSAGE_ID")};
|
||||
if ( $array_ref ) { # should have returned undef
|
||||
print "not ok ",++$test,"(arrayref=$array_ref)\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
} else {
|
||||
print "ok ",++$test,"\n"; #19
|
||||
}
|
||||
};
|
||||
push @tests, sub {
|
||||
if ( -s $file == $size ) { # 20 test message_to_file size
|
||||
print "ok ",++$test,"\n"; #20
|
||||
} else {
|
||||
print "not ok ",++$test,"\n"; #20
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
unlink "$file" or warn "$! unlinking $file\n";
|
||||
};
|
||||
} # wrap up closure
|
||||
|
||||
push @tests, sub { # 21, 22, 23, 24, 25 26, 27
|
||||
my @unseen; my @seen;
|
||||
if ( eval { @seen = $imap->seen } ) { # 21 test seen's success
|
||||
print "ok ",++$test,"\n"; #21
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
if ( @seen == 1 ) { # 22 test seen's results
|
||||
print "ok ",++$test,"\n"; #22
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
|
||||
if ( eval { $imap->deny_seeing(\@seen) } ) { # 23 test deny_seeing's success
|
||||
print "ok ",++$test,"\n"; #23
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
if ( eval { @unseen = $imap->unseen } ) { # 24 test unseen's success
|
||||
print "ok ",++$test,"\n"; #24
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
|
||||
if ( @unseen == 1 ) { # 25 test deny_seeing's and unseen's results
|
||||
print "ok ",++$test,"\n"; #25
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
if ( eval { $imap->see(\@seen) } ) { # 26 test see's success
|
||||
print "ok ",++$test,"\n"; #26
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
if ( @seen == 1 ) { # 27 test seen's and see's success
|
||||
print "ok ",++$test,"\n"; #27
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
eval { $imap->deny_seeing(@seen) };
|
||||
my $subject;
|
||||
eval { $imap->Peek(1) };
|
||||
eval { $subject = $imap->parse_headers($seen[0],"Subject")->{Subject}[0] };
|
||||
if ( join("",$imap->flags($seen[0])) =~ /\\Seen/i ) { # 28 test "Peek = 1"
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
} else {
|
||||
print "ok ",++$test,"\n"; #28
|
||||
}
|
||||
eval { $imap->deny_seeing(@seen) };
|
||||
eval { $imap->Peek(0) };
|
||||
eval { $subject = $imap->parse_headers($seen[0],"Subject")->{Subject}[0] };
|
||||
if ( join("",$imap->flags($seen[0])) =~ /\\Seen/i ) { # 29 test "Peek = 0"
|
||||
print "ok ",++$test,"\n"; #29
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
eval { $imap->deny_seeing(@seen) };
|
||||
eval { $imap->Peek(undef) };
|
||||
eval { $subject = $imap->parse_headers($seen[0],"Subject")->{Subject}[0] };
|
||||
if ( join("",$imap->flags($seen[0])) =~ /\\Seen/i ) { # 30 test "Peek = undef"
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
} else {
|
||||
print "ok ",++$test,"\n"; #30
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
# Add dummy tests to come up to right number of test routines:
|
||||
push @tests, sub { 22 }, sub { 23 } , sub { 24 }, sub { 25 }, sub { 26 }, sub {27},
|
||||
sub {28}, sub {29}, sub {30};
|
||||
|
||||
push @tests, sub { # 31
|
||||
if ( eval { my $uid2 = $imap->copy($target2,1)} ) {
|
||||
print "ok ",++$test,"\n"; #31
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
push @tests, sub { # 32
|
||||
my @res;
|
||||
if ( eval { @res = $imap->fetch(1,"RFC822.TEXT") } ) {
|
||||
print "ok ",++$test,"\n"; #32
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
};
|
||||
|
||||
push @tests, sub { # 33
|
||||
my $h;
|
||||
if ( eval { $h = $imap->parse_headers(1,"Subject")
|
||||
and $h->{Subject}[0] =~ /^Testing from pid/o } ) {
|
||||
print "ok ",++$test,"\n"; #33
|
||||
} else {
|
||||
use Data::Dumper;
|
||||
print Dumper($h);
|
||||
print "$h->{Subject}[0] \n";
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
print $imap->Results;
|
||||
}
|
||||
};
|
||||
|
||||
my @hits = ();
|
||||
push @tests, sub { # 34
|
||||
$imap->select("$target");
|
||||
eval { @hits = $imap->search('SUBJECT','Testing') } ;
|
||||
if ( scalar(@hits) == 1 ) {
|
||||
print "ok ",++$test,"\n"; #34
|
||||
} else {
|
||||
print "not ok ",++$test,"\n"; #34
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
print "Found ",scalar(@hits),
|
||||
" hits (",join(", ",@hits),")-- expected 2\n";
|
||||
}
|
||||
};
|
||||
|
||||
push @tests, sub { # 35, 36
|
||||
if ( $imap->delete_message(@hits) ) {
|
||||
print "ok ",++$test,"\n"; #35
|
||||
my $flaghash = $imap->flags(\@hits);
|
||||
my $flagflag = 0;
|
||||
foreach my $v ( values %$flaghash ) {
|
||||
foreach my $f (@$v) { $flagflag++ if $f =~ /\\Deleted/}
|
||||
}
|
||||
if ( $flagflag == scalar(@hits) ) {
|
||||
print "ok ", ++$test,"\n"; #36
|
||||
} else {
|
||||
print "not ok ", ++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
} else {
|
||||
print "not ok ",++$test,"\n"; #35
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
print "not ok ",++$test,"\n"; #36
|
||||
}
|
||||
}, sub { return "Dummy test 35"} ;
|
||||
|
||||
push @tests, sub { # 37
|
||||
eval {
|
||||
my @nohits = $imap->search(qq(SUBJECT "Productioning")) ;
|
||||
unless ( scalar(@nohits) ) {
|
||||
print "ok ",++$test,"\n"; #37
|
||||
} else {
|
||||
print "not ok ",++$test," (",scalar(@nohits),")\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
push @tests, sub { # 38, 39
|
||||
if ( $imap->restore_message(@hits) ) {
|
||||
print "ok ",++$test,"\n"; #38
|
||||
my $flaghash = $imap->flags(\@hits);
|
||||
my $flagflag = scalar(@hits);
|
||||
foreach my $v ( values %$flaghash ) {
|
||||
foreach my $f (@$v) { $flagflag-- if $f =~ /\\Deleted/}
|
||||
}
|
||||
if ( $flagflag == scalar(@hits) ) {
|
||||
print "ok ", ++$test,"\n"; #39
|
||||
} else {
|
||||
print "not ok ", ++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
}
|
||||
} else {
|
||||
print "not ok ",++$test,"\n"; #38
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
print "not ok ",++$test,"\n"; #39
|
||||
}
|
||||
}, sub { $imap->delete_message(@hits) } ; # dummy 39
|
||||
push @tests, sub { # 40
|
||||
$imap->select($target2);
|
||||
if ( $imap->delete_message(scalar($imap->search("ALL")))
|
||||
and $imap->close and
|
||||
$imap->delete($target2)
|
||||
) {
|
||||
print "ok ",++$test,"\n"; #40
|
||||
|
||||
} else {
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
print $imap->Report;
|
||||
}
|
||||
};
|
||||
push @tests, sub { # 41
|
||||
eval {
|
||||
$imap->select("INBOX");
|
||||
$@ = ""; # clear $@
|
||||
@hits = $imap->search( "BEFORE",
|
||||
Mail::IMAPClient::Rfc2060_date(time),
|
||||
"UNDELETED"
|
||||
) ;
|
||||
|
||||
} ;
|
||||
if ($@ ) {
|
||||
$@ =~ s/\r\n$//;
|
||||
print "not ok ",++$test, " ($@)\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
} else {
|
||||
print "ok ",++$test,"\n"; #41
|
||||
}
|
||||
};
|
||||
# Test migrate method
|
||||
{ # start new scope for these tests
|
||||
my($im2,$migtarget);
|
||||
push @tests, sub { # 42
|
||||
eval {
|
||||
|
||||
$im2 = Mail::IMAPClient->new(
|
||||
Server => "$parms{server}"||"localhost",
|
||||
Port => "$parms{port}" || '143',
|
||||
User => "$parms{user}" || scalar(getpwuid($<)),
|
||||
( $authmech ? ( Authmechanism => $authmech) :
|
||||
( $parms{authmechanism} eq "LOGIN" ? () :
|
||||
( Authmechanism => $parms{authmechanism}||undef ) )
|
||||
),
|
||||
Password=> "$parms{passed}"|| scalar(getpwuid($<)),
|
||||
Clear => 0,
|
||||
Timeout => 30,
|
||||
Debug => $ARGV[0],
|
||||
Debug_fh => ($ARGV[0]?IO::File->new(">./imap2.debug"):undef),
|
||||
Fast_IO => $fast,
|
||||
Uid => $uidplus,
|
||||
) or
|
||||
print STDERR "\nCannot log into $parms{server} as $parms{user}. ",
|
||||
"Are server/user/password correct?\n"
|
||||
and die ;
|
||||
my $source = $target;
|
||||
$imap->select($source) or die "cannot select source $source: $@";
|
||||
for (1...5) { $imap->append($source,&testmsg)};
|
||||
$imap->close; $imap->select($source);
|
||||
$migtarget = "${target}_mirror";
|
||||
$im2->create($migtarget) or die "can't create $migtarget: $@" ;
|
||||
$im2->select($migtarget) or die "can't select $migtarget: $@";
|
||||
$imap->migrate($im2,scalar($imap->search("ALL")),$migtarget)
|
||||
or die "couldn't migrate: $@";
|
||||
$im2->close; $im2->select($migtarget) or die "can't select $migtarget: $@";
|
||||
} ;
|
||||
if ( $@ ) {
|
||||
$@=~s/\r\n$//;
|
||||
print "not ok ",++$test," ($@)\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
} else {
|
||||
print "ok ",++$test,"\n"; #42
|
||||
}
|
||||
}, # 43
|
||||
sub {
|
||||
my($total_bytes1,$total_bytes2) ;
|
||||
eval {
|
||||
for ($imap->search("ALL")) { my $s = $imap->size($_); $total_bytes1 += $s; print "Size of msg $_ is $s\n" if $ARGV[0]};
|
||||
for ( $im2->search("ALL")) { my $s = $im2->size($_); $total_bytes2 += $s; print "Size of msg $_ is $s\n" if $ARGV[0]};
|
||||
};
|
||||
for ($total_bytes1,$total_bytes2) { $_||=0};
|
||||
if ($@) {
|
||||
$@=~s/\r\n$//;
|
||||
print "not ok ",++$test," ($@)\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
} elsif ( $total_bytes1 != $total_bytes2 ) {
|
||||
print "not ok ",++$test," (source has $total_bytes1 bytes and ",
|
||||
"target has $total_bytes2)\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
} else {
|
||||
print "ok ",++$test,"\n"; #43
|
||||
$im2->select($migtarget);
|
||||
$im2->delete_message(@{$im2->messages}) if $im2->message_count;
|
||||
$im2->close;
|
||||
$im2->delete($migtarget);
|
||||
}
|
||||
$im2->logout;
|
||||
}; # end of the anonysub and push
|
||||
} # end of migrate method tests' scope
|
||||
|
||||
push @tests, sub { # 44
|
||||
if ( $imap->has_capability("IDLE") ) {
|
||||
eval {
|
||||
my $idle = $imap->idle;
|
||||
sleep 1;
|
||||
$imap->done($idle);
|
||||
} ;
|
||||
if ($@) {
|
||||
print "not ok ",++$test,"\n$@\n";
|
||||
} else {
|
||||
print "ok ",++$test,"\n"; #44
|
||||
}
|
||||
} else {
|
||||
print "ok (skipped)",++$test,"\n";
|
||||
}
|
||||
};
|
||||
push @tests, sub { # 45
|
||||
$imap->select('inbox');
|
||||
if ( $imap->rename($target,"${target}NEW") ) {
|
||||
|
||||
print "ok ",++$test,"\n"; #45
|
||||
$imap->close;
|
||||
$imap->select("${target}NEW") ;
|
||||
$imap->delete_message(@{$imap->messages}) if $imap->message_count;
|
||||
$imap->close;
|
||||
$imap->delete("${target}NEW") ;
|
||||
|
||||
} else {
|
||||
|
||||
print "not ok ",++$test,"\n";
|
||||
print STDERR "\nTest $test failed:\n$@\n";
|
||||
$imap->delete_message(@{$imap->messages})
|
||||
if $imap->message_count;
|
||||
$imap->close;
|
||||
$imap->delete("$target") ;
|
||||
}
|
||||
} ;
|
||||
#push @tests, sub { "commented out #46" } ;
|
||||
|
||||
|
||||
if (open TST,"./test.txt" ) {
|
||||
while (defined(my $l = <TST>)) {
|
||||
chomp $l;
|
||||
my($p,$v)=split(/=/,$l);
|
||||
for($p,$v) { s/(?:^\s+)|(?:\s+$)//g; }
|
||||
$parms{$p}=$v if $v;
|
||||
}
|
||||
close TST;
|
||||
}
|
||||
|
||||
if ( -f "./test.txt"
|
||||
and %parms
|
||||
and length $parms{server}
|
||||
and length $parms{user}
|
||||
and length $parms{passed}
|
||||
) {
|
||||
print "1..${\(scalar @tests)}\n"; # update here if adding test to existing sub
|
||||
} else {
|
||||
print "1..1\n";
|
||||
}
|
||||
|
||||
$main::loaded = 1;
|
||||
print "ok 1\n";
|
||||
$| = 1;
|
||||
unless ( -f "./test.txt" ) { exit;}
|
||||
|
||||
}
|
||||
|
||||
=begin debugging
|
||||
|
||||
$db = IO::File->new(">/tmp/de.bug");
|
||||
local *TMP = $db ;
|
||||
open(STDERR,">&TMP");
|
||||
select(((select($db),$|=1))[0]);
|
||||
|
||||
=end debugging
|
||||
|
||||
=cut
|
||||
|
||||
exit unless %parms
|
||||
and length $parms{server}
|
||||
and length $parms{user}
|
||||
and length $parms{passed} ;
|
||||
|
||||
# print "Uid=$uidplus and Fast = $fast\n";
|
||||
|
||||
eval { $imap = Mail::IMAPClient->new(
|
||||
Server => "$parms{server}"||"localhost",
|
||||
Port => "$parms{port}" || '143',
|
||||
User => "$parms{user}" || scalar(getpwuid($<)),
|
||||
( $authmech ? ( Authmechanism => $authmech) :
|
||||
( $parms{authmechanism}&&$parms{authmechanism} eq "LOGIN" ? () :
|
||||
( Authmechanism => $parms{authmechanism}||undef) )
|
||||
),
|
||||
Password=> "$parms{passed}"|| scalar(getpwuid($<)),
|
||||
Clear => 0,
|
||||
Timeout => 30,
|
||||
Debug => $ARGV[0],
|
||||
Debug_fh => ($ARGV[0]?IO::File->new(">imap1.debug"):undef),
|
||||
Fast_IO => $fast,
|
||||
Uid => $uidplus,
|
||||
Range => $range,
|
||||
) or
|
||||
print STDERR "\nCannot log into $parms{server} as $parms{user}. Are server/user/password correct?\n"
|
||||
and exit
|
||||
} ;
|
||||
|
||||
$imap->Debug_fh and $imap->Debug_fh->autoflush();
|
||||
for my $test (@tests) { $test->(); }
|
||||
#print $db $imap->Report,"\n";
|
||||
|
||||
sub testmsg {
|
||||
my $m = qq{Date: @{[$imap->Rfc822_date(time)]}
|
||||
To: <$parms{user}\@$parms{server}>
|
||||
From: Perl <$parms{user}\@$parms{server}>
|
||||
Subject: Testing from pid $$
|
||||
|
||||
This is a test message generated by $0 during a 'make test' as part of the installation of
|
||||
that nifty Mail::IMAPClient module from CPAN. Like all things perl, it's
|
||||
way cool.
|
||||
|
||||
};
|
||||
|
||||
return $m;
|
||||
}
|
||||
|
||||
# History:
|
||||
# $Log: basic.t,v $
|
||||
# Revision 19991216.27 2003/06/12 21:38:35 dkernen
|
||||
#
|
||||
# Preparing 2.2.8
|
||||
# Added Files: COPYRIGHT
|
||||
# Modified Files: Parse.grammar
|
||||
# Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
# Parse.grammar Parse.pod
|
||||
# range.t
|
||||
# Thread.grammar
|
||||
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
|
||||
# rfc2221.txt rfc2359.txt rfc2683.txt
|
||||
#
|
||||
# Revision 19991216.26 2002/12/13 18:08:50 dkernen
|
||||
# Made changes for version 2.2.6 (see Changes file for more info)
|
||||
#
|
||||
# Revision 19991216.25 2002/11/08 15:49:05 dkernen
|
||||
#
|
||||
# Modified Files: Changes
|
||||
# IMAPClient.pm
|
||||
# MessageSet.pm
|
||||
# t/basic.t
|
||||
#
|
||||
# Revision 19991216.24 2002/10/23 20:46:09 dkernen
|
||||
#
|
||||
# Modified Files: Changes IMAPClient.pm MANIFEST Makefile.PL
|
||||
# Added Files: Makefile.PL MessageSet.pm
|
||||
# Added Files: range.t
|
||||
# Modified Files: basic.t
|
||||
#
|
||||
# Revision 19991216.23 2002/09/26 17:56:58 dkernen
|
||||
#
|
||||
# Modified Files:
|
||||
# BUG_REPORTS Changes IMAPClient.pm INSTALL_perl5.80 MANIFEST
|
||||
# Makefile.PL for version 2.2.3. See the Changes file for details.
|
||||
# Modified Files: BodyStructure.pm -- cosmetic changes to pod doc
|
||||
# Modified Files:
|
||||
# migrate_mail2.pl -- fixed a small little bug and added a feature
|
||||
# Modified Files: basic.t -- to add tests for idle/done
|
||||
#
|
||||
# Revision 19991216.22 2002/08/30 20:48:52 dkernen
|
||||
#
|
||||
# #
|
||||
# Modified Files:
|
||||
# Changes IMAPClient.pm MANIFEST Makefile Makefile.PL README
|
||||
# Todo test.txt
|
||||
# BodyStructure/Parse/Makefile
|
||||
# BodyStructure/Parse/Parse.pm
|
||||
# BodyStructure/Parse/Parse.pod
|
||||
# BodyStructure/Parse/t/parse.t
|
||||
# t/basic.t
|
||||
# for version 2.2.1
|
||||
# #
|
||||
#
|
||||
# Revision 19991216.21 2002/08/23 13:29:59 dkernen
|
||||
#
|
||||
# Modified Files: Changes IMAPClient.pm INSTALL MANIFEST Makefile Makefile.PL README Todo test.txt
|
||||
# Made changes to create version 2.1.6.
|
||||
# Modified Files:
|
||||
# imap_to_mbox.pl populate_mailbox.pl
|
||||
# Added Files:
|
||||
# cleanTest.pl migrate_mbox.pl
|
||||
# Modified Files: basic.t
|
||||
#
|
||||
# Revision 19991216.20 2001/02/07 20:20:43 dkernen
|
||||
#
|
||||
# Modified Files: Changes IMAPClient.pm MANIFEST Makefile test.txt -- up to version 2.1.0
|
||||
# Added Files: cyrus_expunge.pl -- a new example script
|
||||
# Modified Files: basic.t -- to close folders before trying to delete them
|
||||
# Added Files: uidfast.t -- a new test suite
|
||||
#
|
||||
# Revision 19991216.19 2001/01/09 19:24:37 dkernen
|
||||
#
|
||||
# Modified Files:
|
||||
# Changes IMAPClient.pm Makefile test.txt -- to add Phil Lobbe's patch.
|
||||
#
|
||||
# Revision 19991216.18 2000/12/20 19:37:02 dkernen
|
||||
#
|
||||
# ---------------------------------------------------------------------------------
|
||||
# Modified Files: IMAPClient.pm -- added bug fix to I/O engine, also cleaned up doc
|
||||
# Changes -- documented same
|
||||
# ---------------------------------------------------------------------------------
|
||||
#
|
||||
# Revision 19991216.17 2000/11/10 22:08:15 dkernen
|
||||
#
|
||||
# Modified Files: Changes IMAPClient.pm Makefile t/basic.t -- to add Peek parm and to make several bug fixes
|
||||
#
|
||||
# Revision 19991216.16 2000/10/30 21:04:11 dkernen
|
||||
#
|
||||
# Modified Files: Changes IMAPClient.pm -- to update documentation
|
||||
# Modified Files: basic.t -- added tests for message_to_string.
|
||||
#
|
||||
# Revision 19991216.15 2000/10/30 18:40:50 dkernen
|
||||
#
|
||||
# Modified Files: Changes IMAPClient.pm INSTALL MANIFEST Makefile README test.txt -- for 2.0.1
|
||||
# Added Files:
|
||||
# rfc1731.txt rfc1732.txt rfc1733.txt rfc2061.txt rfc2062.txt
|
||||
# rfc2086.txt rfc2087.txt rfc2088.txt rfc2177.txt rfc2180.txt
|
||||
# rfc2192.txt rfc2193.txt rfc2195.txt rfc2221.txt rfc2222.txt
|
||||
# rfc2234.txt rfc2245.txt rfc2342.txt rfc2359.txt rfc2683.txt
|
||||
#
|
||||
# Revision 19991216.14 2000/10/27 14:43:59 dkernen
|
||||
#
|
||||
# Modified Files: Changes IMAPClient.pm Todo -- major rewrite of I/O et al.
|
||||
# Modified Files: basic.t fast_io.t uidplus.t -- more tests in basic.t. Other
|
||||
# tests just "do basic.t" with different options set.
|
||||
#
|
||||
# Revision 19991216.13 2000/07/10 20:54:19 dkernen
|
||||
#
|
||||
# Modified Files: Changes IMAPClient.pm MANIFEST Makefile README
|
||||
# Modified Files: find_dup_msgs.pl
|
||||
# : Modified Files: basic.t fast_io.t
|
||||
#
|
||||
# Revision 19991216.12 2000/06/23 19:08:40 dkernen
|
||||
#
|
||||
# Modified Files:
|
||||
# Changes IMAPClient.pm Makefile test.txt -- for v1.16
|
||||
# Modified Files: basic.t -- to remove uidplus tests and to make copy test copy to different folder
|
||||
# Added Files: uidplus.t -- moved all uidplus tests here
|
||||
#
|
||||
# Revision 19991216.11 2000/06/21 21:07:44 dkernen
|
||||
#
|
||||
# Modified Files: Changes IMAPClient.pm Makefile
|
||||
# Modified Files: basic.t
|
||||
#
|
||||
# Revision 19991216.10 2000/04/27 18:00:15 dkernen
|
||||
# Modified Files: basic.t
|
||||
#
|
||||
# Revision 19991216.9 2000/03/10 16:04:39 dkernen
|
||||
#
|
||||
# Renamed .test file to test.txt to support weird platforms that don't support filenames
|
||||
# beginning with a dot.
|
||||
#
|
||||
# Modified Files: Changes INSTALL MANIFEST Makefile Makefile.PL
|
||||
#
|
||||
# Added Files: test.txt test_template.txt
|
||||
#
|
||||
# Removed Files: .test .test_template Makefile.old
|
||||
#
|
||||
# Revision 19991216.8 2000/03/02 19:59:15 dkernen
|
||||
#
|
||||
# Modified Files: build_ldif.pl -- to support new option to all "To:" and "Cc:" to be included in ldif file
|
||||
# Modified Files: basic.t -- to work better with UW IMAP server
|
||||
#
|
||||
# Revision 19991216.7 2000/01/12 18:58:05 dkernen
|
||||
# *** empty log message ***
|
||||
#
|
||||
# Revision 19991216.6 1999/12/28 13:57:22 dkernen
|
||||
# tested with v1.08
|
||||
#
|
||||
# Revision 19991216.5 1999/12/16 17:19:17 dkernen
|
||||
# Bring up to same level
|
||||
#
|
||||
# Revision 19991124.7 1999/12/16 17:14:27 dkernen
|
||||
# Incorporate changes for exists method performance enhancement
|
||||
#
|
||||
# Revision 19991124.6 1999/12/01 22:11:06 dkernen
|
||||
# Enhance support for UID and add tests to t/basic for same
|
||||
#
|
||||
# Revision 19991124.5 1999/11/30 20:41:55 dkernen
|
||||
# Bring CVS repository up to latest level
|
||||
#
|
||||
# Revision 19991124.4 1999/11/24 19:58:45 dkernen
|
||||
#
|
||||
# Modified Files:
|
||||
# basic.t - to add $Id and $Log data in comments
|
||||
#
|
|
@ -1,106 +0,0 @@
|
|||
# Before `make install' is performed this script should be runnable with
|
||||
# `make test'. After `make install' it should work as `perl test.pl'
|
||||
# $Id: cram-md5.t,v 19991216.1 2003/06/12 21:38:36 dkernen Exp $
|
||||
######################### We start with some black magic to print on failure.
|
||||
|
||||
# Change 1..1 below to 1..last_test_to_print .
|
||||
|
||||
use Mail::IMAPClient;
|
||||
|
||||
######################### End of black magic.
|
||||
|
||||
|
||||
my $test = 0;
|
||||
my %parms;
|
||||
my $imap;
|
||||
my @tests;
|
||||
my $uid;
|
||||
|
||||
=begin debugging
|
||||
|
||||
$db = IO::File->new(">/tmp/de.bug");
|
||||
local *TMP = $db ;
|
||||
open(STDERR,">&TMP");
|
||||
select(((select($db),$|=1))[0]);
|
||||
|
||||
=end debugging
|
||||
|
||||
=cut
|
||||
|
||||
if (open TST,"./test.txt" ) {
|
||||
while (defined(my $l = <TST>)) {
|
||||
chomp $l;
|
||||
my($p,$v)=split(/=/,$l);
|
||||
for($p,$v) { s/(?:^\s+)|(?:\s+$)//g; }
|
||||
$parms{$p}=$v if $v;
|
||||
}
|
||||
close TST;
|
||||
} else {
|
||||
|
||||
print "1..1\n";
|
||||
print "ok 1 (skipped)\n";
|
||||
exit;
|
||||
}
|
||||
exit unless %parms
|
||||
and length $parms{server}
|
||||
and length $parms{user}
|
||||
and length $parms{passed} ;
|
||||
|
||||
eval { $imap = Mail::IMAPClient->new(
|
||||
Server => "$parms{server}"||"localhost",
|
||||
Port => "$parms{port}" || '143',
|
||||
Clear => 0,
|
||||
Timeout => 30,
|
||||
Debug => $ARGV[0],
|
||||
Debug_fh => $ARGV[0]?IO::File->new(">imap1.debug"):undef,
|
||||
Fast_IO => 1,
|
||||
Uid => 1,
|
||||
Authmechanism => $parms{authmechanism}||undef,
|
||||
) or
|
||||
print STDERR "\nCannot connect to $parms{server} to get capabilities. ",
|
||||
"Are server/user/password correct?\n"
|
||||
and exit
|
||||
} ;
|
||||
|
||||
$imap->Debug_fh and $imap->Debug_fh->autoflush();
|
||||
if ( $imap->has_capability("AUTH=CRAM-MD5") ) {
|
||||
$authmech = "CRAM-MD5";
|
||||
$authmech = "CRAM-MD5";
|
||||
do "./t/basic.t";
|
||||
} else {
|
||||
print "1..1\n";
|
||||
print "ok 1 (skipped)\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
# History:
|
||||
# $Log: cram-md5.t,v $
|
||||
# Revision 19991216.1 2003/06/12 21:38:36 dkernen
|
||||
#
|
||||
# Preparing 2.2.8
|
||||
# Added Files: COPYRIGHT
|
||||
# Modified Files: Parse.grammar
|
||||
# Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
# Parse.grammar Parse.pod
|
||||
# range.t
|
||||
# Thread.grammar
|
||||
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
|
||||
# rfc2221.txt rfc2359.txt rfc2683.txt
|
||||
#
|
||||
# Revision 1.1 2003/06/12 21:38:17 dkernen
|
||||
#
|
||||
# Preparing 2.2.8
|
||||
# Added Files: COPYRIGHT
|
||||
# Modified Files: Parse.grammar
|
||||
# Added Files: Makefile.old
|
||||
# Makefile.PL Todo sample.perldb
|
||||
# BodyStructure.pm
|
||||
# Parse.grammar Parse.pod
|
||||
# range.t
|
||||
# Thread.grammar
|
||||
# draft-crispin-imapv-17.txt rfc1731.txt rfc2060.txt rfc2062.txt
|
||||
# rfc2221.txt rfc2359.txt rfc2683.txt
|
||||
#
|
||||
#
|
|
@ -1,2 +0,0 @@
|
|||
$fast++; $fast++;
|
||||
do "./t/basic.t";
|
|
@ -1,3 +0,0 @@
|
|||
$fast++; $fast++;
|
||||
$range++; $range++;
|
||||
do "./t/basic.t";
|
|
@ -1,3 +0,0 @@
|
|||
$uid++; $uid++;
|
||||
$fast_io++; $fast_io++;
|
||||
do "./t/basic.t";
|
|
@ -1,2 +0,0 @@
|
|||
$uid++; $uid++;
|
||||
do "./t/basic.t";
|
|
@ -1,5 +0,0 @@
|
|||
server=imap.server.hostname
|
||||
user=username
|
||||
passed=password
|
||||
port=143
|
||||
authmechanism=LOGIN
|
1
W/TIME
1
W/TIME
|
@ -1,3 +1,4 @@
|
|||
120 Fixed Scott issue, took long time (all messages list) even with --useuid --delete --nousecache --maxage 1
|
||||
240 Fixed long names in invoices. + january invoices.
|
||||
180 Release 1.476 --addheader
|
||||
15 Added start and end dates in the final statistics.
|
||||
|
|
Binary file not shown.
6
W/livredor
Normal file
6
W/livredor
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
|
||||
=== Christian Burger, 18 february 2013 ===
|
||||
The tool was extremely useful during my email migration
|
||||
from one provider to the other and it worked like a charm.
|
||||
It's just great!
|
93
W/paypal_reply/bnc_col_prep.txt
Normal file
93
W/paypal_reply/bnc_col_prep.txt
Normal file
|
@ -0,0 +1,93 @@
|
|||
Date
|
||||
Code journal
|
||||
Nom journal
|
||||
Cte tresorerie associe
|
||||
Reference
|
||||
Libelle
|
||||
Montant TTC
|
||||
non utilise
|
||||
Code tiers
|
||||
Pointage tiers
|
||||
Compte ventilation 1
|
||||
Libelle ventilation 1
|
||||
Code TVA 1
|
||||
Compte analytique 1
|
||||
Montant depense 1
|
||||
Montant recette 1
|
||||
Montant TVA 1
|
||||
Compte TVA 1
|
||||
Compte ventilation 2
|
||||
Libelle ventilation 2
|
||||
Code TVA 2
|
||||
Compte analytique 2
|
||||
Montant depense 2
|
||||
Montant recette 2
|
||||
Montant TVA 2
|
||||
Compte TVA 2
|
||||
Compte ventilation 3
|
||||
Libelle ventilation 3
|
||||
Code TVA 3
|
||||
Compte analytique 3
|
||||
Montant depense 3
|
||||
Montant recette 3
|
||||
Montant TVA 3
|
||||
Compte TVA 3
|
||||
Compte ventilation 4
|
||||
Libelle ventilation 4
|
||||
Code TVA 4
|
||||
Compte analytique 4
|
||||
Montant depense 4
|
||||
Montant recette 4
|
||||
Montant TVA 4
|
||||
Compte TVA 4
|
||||
Compte ventilation 5
|
||||
Libelle ventilation 5
|
||||
Code TVA 5
|
||||
Compte analytique 5
|
||||
Montant depense 5
|
||||
Montant recette 5
|
||||
Montant TVA 5
|
||||
Compte TVA 5
|
||||
Compte ventilation 6
|
||||
Libelle ventilation 6
|
||||
Code TVA 6
|
||||
Compte analytique 6
|
||||
Montant depense 6
|
||||
Montant recette 6
|
||||
Montant TVA 6
|
||||
Compte TVA 6
|
||||
Compte ventilation 7
|
||||
Libelle ventilation 7
|
||||
Code TVA 7
|
||||
Compte analytique 7
|
||||
Montant depense 7
|
||||
Montant recette 7
|
||||
Montant TVA 7
|
||||
Compte TVA 7
|
||||
Compte ventilation 8
|
||||
Libelle ventilation 8
|
||||
Code TVA 8
|
||||
Compte analytique 8
|
||||
Montant depense 8
|
||||
Montant recette 8
|
||||
Montant TVA 8
|
||||
Compte TVA 8
|
||||
Compte ventilation 9
|
||||
Libelle ventilation 9
|
||||
Code TVA 9
|
||||
Compte analytique 9
|
||||
Montant depense 9
|
||||
Montant recette 9
|
||||
Montant TVA 9
|
||||
Compte TVA 9
|
||||
Compte ventilation 10
|
||||
Libelle ventilation 10
|
||||
Code TVA 1
|
||||
Compte analytique 10
|
||||
Montant depense 10
|
||||
Montant recette 10
|
||||
Montant TVA 10
|
||||
Compte TVA 10
|
||||
Pointage
|
||||
Divers
|
||||
Verrou
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
# $Id: memo,v 1.12 2012/11/02 07:49:37 gilles Exp gilles $
|
||||
# $Id: memo,v 1.13 2013/02/08 15:01:18 gilles Exp gilles $
|
||||
|
||||
|
||||
echo paypal_bilan_todo
|
||||
|
@ -28,8 +28,107 @@ Europe a un autre assujetti : Article 262 ter => Exoneration
|
|||
EOF
|
||||
}
|
||||
|
||||
echo paypal_bilan_bncexport2
|
||||
paypal_bilan_bncexport2() {
|
||||
# DID output diff between paypal_bilan_1.66 and 1.67
|
||||
(
|
||||
#set -x
|
||||
perl -c /g/public_html/imapsync/W/paypal_reply/paypal_bilan || return 1
|
||||
/g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.66 --bnc --debug --details --debug_invoice --first_in 147 \
|
||||
--avoid_numbers '292 293 643 644 731 732
|
||||
1093 1330 1331 1332 1333 1334 1652 1653
|
||||
2131 2132 2295 2296 2297 2298' \
|
||||
/g/paypal/paypal_201?_??_complet.csv \
|
||||
> /g/var/paypal_bilan/tests/paypal_invoice.out1 2>&1
|
||||
|
||||
/g/public_html/imapsync/W/paypal_reply/paypal_bilan --bnc --debug --details --debug_invoice --first_in 147 \
|
||||
--avoid_numbers '292 293 643 644 731 732
|
||||
1093 1330 1331 1332 1333 1334 1652 1653
|
||||
2131 2132 2295 2296 2297 2298' \
|
||||
/g/paypal/paypal_201?_??_complet.csv \
|
||||
> /g/var/paypal_bilan/tests/paypal_invoice.out2 2>&1
|
||||
|
||||
echo diff /g/var/paypal_bilan/tests/paypal_invoice.out1 /g/var/paypal_bilan/tests/paypal_invoice.out2
|
||||
diff /g/var/paypal_bilan/tests/paypal_invoice.out1 /g/var/paypal_bilan/tests/paypal_invoice.out2
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
echo paypal_bilan_bncexport
|
||||
paypal_bilan_bncexport() {
|
||||
# DID output diff between paypal_bilan_1.66 and 1.67
|
||||
(
|
||||
#set -x
|
||||
perl -c /g/public_html/imapsync/W/paypal_reply/paypal_bilan || return 1
|
||||
/g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.66 --bnc --debug --debug_csv --details --debug_invoice --first_in 147 \
|
||||
--avoid_numbers '292 293 643 644 731 732
|
||||
1093 1330 1331 1332 1333 1334 1652 1653
|
||||
2131 2132 2295 2296 2297 2298' \
|
||||
/g/paypal/paypal_201?_??_complet.csv \
|
||||
> /g/var/paypal_bilan/tests/paypal_invoice.out1 2>&1
|
||||
|
||||
/g/public_html/imapsync/W/paypal_reply/paypal_bilan --bnc --debug --debug_csv --details --debug_invoice --first_in 147 \
|
||||
--avoid_numbers '292 293 643 644 731 732
|
||||
1093 1330 1331 1332 1333 1334 1652 1653
|
||||
2131 2132 2295 2296 2297 2298' \
|
||||
/g/paypal/paypal_201?_??_complet.csv \
|
||||
> /g/var/paypal_bilan/tests/paypal_invoice.out2 2>&1
|
||||
|
||||
echo diff /g/var/paypal_bilan/tests/paypal_invoice.out1 /g/var/paypal_bilan/tests/paypal_invoice.out2
|
||||
diff /g/var/paypal_bilan/tests/paypal_invoice.out1 /g/var/paypal_bilan/tests/paypal_invoice.out2
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
#echo paypal_bilan_tva_prestation_de_service_fix_date
|
||||
paypal_bilan_tva_prestation_de_service_fix_date() {
|
||||
# DID output diff between paypal_bilan_1.65 and 1.64
|
||||
(
|
||||
#set -x
|
||||
/g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.64 --bnc --debug --debug_invoice --first_in 147 \
|
||||
--avoid_numbers '292 293 643 644 731 732
|
||||
1093 1330 1331 1332 1333 1334 1652 1653
|
||||
2131 2132 2295 2296 2297 2298' \
|
||||
/g/paypal/paypal_201?_??_complet.csv \
|
||||
> /g/var/paypal_bilan/tests/paypal_invoice.out1 2>&1
|
||||
|
||||
/g/public_html/imapsync/W/paypal_reply/paypal_bilan --bnc --debug --debug_invoice --first_in 147 \
|
||||
--avoid_numbers '292 293 643 644 731 732
|
||||
1093 1330 1331 1332 1333 1334 1652 1653
|
||||
2131 2132 2295 2296 2297 2298' \
|
||||
/g/paypal/paypal_201?_??_complet.csv \
|
||||
> /g/var/paypal_bilan/tests/paypal_invoice.out2 2>&1
|
||||
|
||||
echo diff /g/var/paypal_bilan/tests/paypal_invoice.out1 /g/var/paypal_bilan/tests/paypal_invoice.out2
|
||||
diff /g/var/paypal_bilan/tests/paypal_invoice.out1 /g/var/paypal_bilan/tests/paypal_invoice.out2
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
#echo paypal_bilan_tva_prestation_de_service
|
||||
paypal_bilan_tva_prestation_de_service() {
|
||||
# DID output diff between paypal_bilan_1.63 and 1.64
|
||||
(
|
||||
#set -x
|
||||
/g/public_html/imapsync/W/paypal_reply/paypal_bilan_1.63 --bnc --debug --debug_invoice --first_in 147 \
|
||||
--avoid_numbers '292 293 643 644 731 732
|
||||
1093 1330 1331 1332 1333 1334 1652 1653
|
||||
2131 2132 2295 2296 2297 2298' \
|
||||
/g/paypal/paypal_201?_??_complet.csv \
|
||||
> /g/var/paypal_bilan/tests/paypal_invoice.out1 2>&1
|
||||
|
||||
/g/public_html/imapsync/W/paypal_reply/paypal_bilan --bnc --debug --debug_invoice --first_in 147 \
|
||||
--avoid_numbers '292 293 643 644 731 732
|
||||
1093 1330 1331 1332 1333 1334 1652 1653
|
||||
2131 2132 2295 2296 2297 2298' \
|
||||
/g/paypal/paypal_201?_??_complet.csv \
|
||||
> /g/var/paypal_bilan/tests/paypal_invoice.out2 2>&1
|
||||
|
||||
echo diff /g/var/paypal_bilan/tests/paypal_invoice.out1 /g/var/paypal_bilan/tests/paypal_invoice.out2
|
||||
diff /g/var/paypal_bilan/tests/paypal_invoice.out1 /g/var/paypal_bilan/tests/paypal_invoice.out2
|
||||
)
|
||||
}
|
||||
|
||||
echo paypal_bilan_invoice_00000
|
||||
paypal_bilan_invoice_00000() {
|
||||
# DID output diff between paypal_bilan_1.62 and 1.63
|
||||
(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# $Id: paypal_bilan,v 1.62 2012/12/06 18:45:02 gilles Exp gilles $
|
||||
# $Id: paypal_bilan,v 1.66 2013/03/26 19:50:20 gilles Exp gilles $
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
@ -13,7 +13,7 @@ use Test::More 'no_plan' ;
|
|||
|
||||
die unless (utf8_supported_charset('ISO-8859-1'));
|
||||
|
||||
my $rcs = '$Id: paypal_bilan,v 1.62 2012/12/06 18:45:02 gilles Exp gilles $ ' ;
|
||||
my $rcs = '$Id: paypal_bilan,v 1.66 2013/03/26 19:50:20 gilles Exp gilles $ ' ;
|
||||
$rcs =~ m/,v (\d+\.\d+)/ ;
|
||||
my $VERSION = ($1) ? $1: "UNKNOWN" ;
|
||||
|
||||
|
@ -26,6 +26,7 @@ my $total_TVA_EUR = 0 ;
|
|||
|
||||
my $total_HT_EUR_sup = 0 ;
|
||||
my $total_TVA_EUR_sup = 0 ;
|
||||
my $total_HT_EUR_sup_exo = 0 ;
|
||||
|
||||
my $total_eur_received = 0 ;
|
||||
my $total_eur_invoice = 0 ;
|
||||
|
@ -86,10 +87,9 @@ if ( $tests ) {
|
|||
|
||||
|
||||
my @files = @ARGV ;
|
||||
my %action_of_invoice ;
|
||||
my %action_invoice ;
|
||||
|
||||
my %invoice_paypal ;
|
||||
#$invoice_paypal{ $first_invoice } = 1 ;
|
||||
|
||||
my @invoices_wanted = split( /\s+/, $invoices ) if $invoices ;
|
||||
|
||||
|
@ -99,33 +99,23 @@ my %avoid_numbers ;
|
|||
|
||||
#print "@invoices\n" ;
|
||||
|
||||
my @actions ;
|
||||
|
||||
foreach my $file ( @files ) {
|
||||
|
||||
my @actions = parse_file( $file ) ;
|
||||
my @actions_file = parse_file( $file ) ;
|
||||
push( @actions, @actions_file ) ;
|
||||
}
|
||||
|
||||
foreach my $action (@actions) {
|
||||
my %action = %$action ;
|
||||
#print $action->{ Nom }, "\n" ;
|
||||
my( $Date, $Heure, $Fuseau_horaire, $Nom, $Type, $Etat,
|
||||
$Devise, $Montant, $Numero_davis_de_reception, $Solde,
|
||||
$Pays, $Nom_Option_1, $Valeur_Option_1, $Hors_taxe, $Titre_de_l_objet, $Nom_Option_2, $Option_2_Valeur )
|
||||
= @action{ ( 'Date', 'Heure', 'Fuseau horaire', 'Nom', 'Type', 'Etat',
|
||||
'Devise', 'Montant', "Numéro d'avis de réception", 'Solde',
|
||||
'Pays', 'Nom Option 1', 'Valeur Option 1', 'Hors taxe', "Titre de l'objet", 'Nom Option 2', 'Option 2 Valeur') } ;
|
||||
#print "$Nom\n" ;
|
||||
( $Etat ) = @action{ ( 'Etat' ) } || @action{ ( 'État' ) } ;
|
||||
( $Hors_taxe ) = @action{ ( 'Hors taxe' ) } || @action{ ( 'Avant commission' ) } ;
|
||||
my $invoice = 'NONE' ;
|
||||
$Montant = $action->{ Net } if not defined $Montant;
|
||||
compute_line($action, $invoice, $Date, $Heure, $Fuseau_horaire, $Nom, $Type, $Etat,
|
||||
$Devise, $Montant, $Numero_davis_de_reception, $Solde,
|
||||
$Pays, $Nom_Option_1, $Valeur_Option_1, $Hors_taxe, $Titre_de_l_objet ) ;
|
||||
foreach my $action (@actions) {
|
||||
# compute_line() adds $action->{ 'invoice' } if needed
|
||||
compute_line( $action ) ;
|
||||
|
||||
# index by invoice number
|
||||
$action_of_invoice{ $action->{ 'invoice' } } = $action ;
|
||||
}
|
||||
delete $action_of_invoice{ 'NONE' } ;
|
||||
$action_invoice{ $action->{ 'invoice' } } = $action ;
|
||||
}
|
||||
delete $action_invoice{ 'NONE' } ;
|
||||
|
||||
|
||||
my $last_invoice ;
|
||||
my @invoice_paypal = sort { $a <=> $b } keys %invoice_paypal ;
|
||||
|
@ -141,7 +131,7 @@ my %invoice_not_sent ;
|
|||
|
||||
foreach my $invoice ( @invoices_wanted ) {
|
||||
|
||||
my $action = $action_of_invoice{ $invoice } ;
|
||||
my $action = $action_invoice{ $invoice } ;
|
||||
next if ! $action ;
|
||||
my $email_address = $action->{ "De l'adresse email" } ;
|
||||
|
||||
|
@ -186,6 +176,7 @@ $total_TVA_EUR = sprintf('%2.2f', $total_TVA_EUR) ;
|
|||
|
||||
$total_HT_EUR_sup = sprintf('%2.2f', $total_HT_EUR_sup) ;
|
||||
$total_TVA_EUR_sup = sprintf('%2.2f', $total_TVA_EUR_sup) ;
|
||||
$total_HT_EUR_sup_exo = sprintf('%2.2f', $total_HT_EUR_sup_exo) ;
|
||||
|
||||
$total_eur = sprintf('%2.2f', $total_eur) ;
|
||||
|
||||
|
@ -195,6 +186,7 @@ print "EUR total HT assuj $total_HT_EUR_ass\n" ;
|
|||
print "EUR total TVA $total_TVA_EUR\n" ;
|
||||
print "EUR total HT sup $total_HT_EUR_sup\n" ;
|
||||
print "EUR total TVA sup $total_TVA_EUR_sup\n" ;
|
||||
print "EUR total HT sup exo $total_HT_EUR_sup_exo\n" ;
|
||||
print "Nb invoice $nb_invoice ( from $first_invoice_paypal to $last_invoice )\n" ;
|
||||
print "Nb invoice canceled ($nb_invoice_canceled) @invoice_canceled\n" ;
|
||||
print "Nb invoice suspended ($nb_invoice_suspended) @invoice_suspended\n" ;
|
||||
|
@ -202,9 +194,9 @@ print "Nb invoice refund ($nb_invoice_refund) @invoice_refund\n" ;
|
|||
print "Nb invoice sent $nb_invoice_sent\n" ;
|
||||
print "Have to send invoices @invoice_not_sent\n" if ( @invoice_not_sent ) ;
|
||||
|
||||
my $total_eur2 = $total_HT_EUR_exo + $total_HT_EUR_ass + $total_TVA_EUR + $total_HT_EUR_sup + $total_TVA_EUR_sup ;
|
||||
my $total_eur2 = $total_HT_EUR_exo + $total_HT_EUR_ass + $total_TVA_EUR + $total_HT_EUR_sup + $total_TVA_EUR_sup + $total_HT_EUR_sup_exo ;
|
||||
$total_eur2 = sprintf('%2.2f', $total_eur2) ;
|
||||
print "$total_eur != $total_eur2 = $total_HT_EUR_exo + $total_HT_EUR_ass + $total_TVA_EUR + $total_HT_EUR_sup + $total_TVA_EUR_sup\n"
|
||||
print "$total_eur != $total_eur2 = $total_HT_EUR_exo + $total_HT_EUR_ass + $total_TVA_EUR + $total_HT_EUR_sup + $total_TVA_EUR_sup + $total_HT_EUR_sup_exo\n"
|
||||
if ( $total_eur != $total_eur2 ) ;
|
||||
|
||||
sub parse_one_line_io {
|
||||
|
@ -370,21 +362,45 @@ sub tests_next_invoice {
|
|||
}
|
||||
|
||||
|
||||
sub tests_exportbnc {
|
||||
ok( 1 == 1, '1 == 1' ) ;
|
||||
|
||||
}
|
||||
|
||||
sub tests {
|
||||
tests_next_invoice( ) ;
|
||||
#tests_half( ) ;
|
||||
tests_cut( ) ;
|
||||
tests_invoice_00000( ) ;
|
||||
tests_exportbnc( ) ;
|
||||
}
|
||||
|
||||
sub compute_line {
|
||||
my( $action, $invoice, $Date, $Heure, $Fuseau_horaire, $Nom, $Type, $Etat,
|
||||
$Devise, $Montant, $Numero_davis_de_reception, $Solde,
|
||||
$Pays, $Nom_Option_1, $Valeur_Option_1, $Hors_taxe_paypal, $Titre_de_l_objet ) = @_ ;
|
||||
|
||||
$debug and print( "-" x 60, "\n",
|
||||
my $action = shift ;
|
||||
my %action = %$action ;
|
||||
|
||||
my( $Date, $Heure, $Fuseau_horaire, $Nom, $Type, $Etat,
|
||||
$Devise, $Montant, $Numero_davis_de_reception, $Solde,
|
||||
$Pays, $Nom_Option_1, $Valeur_Option_1, $Hors_taxe_paypal, $Titre_de_l_objet, $Nom_Option_2, $Option_2_Valeur,
|
||||
$Impact_sur_le_solde )
|
||||
= @action{ ( 'Date', 'Heure', 'Fuseau horaire', 'Nom', 'Type', 'Etat',
|
||||
'Devise', 'Montant', "Numéro d'avis de réception", 'Solde',
|
||||
'Pays', 'Nom Option 1', 'Valeur Option 1', 'Hors taxe', "Titre de l'objet", 'Nom Option 2', 'Option 2 Valeur',
|
||||
'Impact sur le solde') } ;
|
||||
#print "[$Option_2_Valeur] [$Impact_sur_le_solde]\n" ;
|
||||
#next;
|
||||
( $Etat ) = @action{ ( 'Etat' ) } || @action{ ( 'État' ) } ;
|
||||
( $Hors_taxe_paypal ) = @action{ ( 'Hors taxe' ) } || @action{ ( 'Avant commission' ) } ;
|
||||
$Impact_sur_le_solde ||= '' ;
|
||||
|
||||
my $invoice = 'NONE' ;
|
||||
$Montant = $action->{ 'Net' } if not defined $Montant;
|
||||
|
||||
|
||||
$debug and print( "#" x 78, "\n",
|
||||
"[$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] ",
|
||||
"[$Devise] [$Hors_taxe_paypal] [$Montant] [$Numero_davis_de_reception] [$Solde]\n",
|
||||
"[$Devise] [$Hors_taxe_paypal] [$Montant] [$Numero_davis_de_reception] [$Solde] [$Impact_sur_le_solde] ",
|
||||
"[$Pays] [$Nom_Option_1] [$Valeur_Option_1] [$Titre_de_l_objet]\n" ) ;
|
||||
|
||||
$Montant =~ s/[^0-9-,.]//g ;
|
||||
|
@ -394,13 +410,13 @@ sub compute_line {
|
|||
|
||||
my $MontantEUR;
|
||||
my( $montant_HT_EUR_exo, $montant_HT_EUR_ass, $montant_TVA_EUR ) ;
|
||||
my( $montant_HT_EUR_sup, $montant_TVA_EUR_sup ) ;
|
||||
my( $montant_HT_EUR_sup, $montant_TVA_EUR_sup, $montant_HT_EUR_sup_exo ) ;
|
||||
|
||||
if ( $bnc ) {
|
||||
$MontantEUR = $Montant ;
|
||||
$MontantEUR = sprintf( "%.4f", $Montant/$usdeur ) if ($Devise eq 'USD') ;
|
||||
print( "\n", "=" x 60, "\n" ) ;
|
||||
print( "[$Date] [$Nom] [$Type] [$Etat] [$Devise] [$Hors_taxe_paypal] [$Montant] [EUR $MontantEUR]\n",
|
||||
print( "[$Date] [$Nom] [$Type] [$Etat] [$Devise] [$Hors_taxe_paypal] [$Montant] [EUR $MontantEUR] [$Impact_sur_le_solde]\n",
|
||||
"[$Pays] [$Nom_Option_1] [$Valeur_Option_1] [$Titre_de_l_objet]\n" ) ;
|
||||
}
|
||||
|
||||
|
@ -415,15 +431,16 @@ sub compute_line {
|
|||
$Montant2_usd = $Hors_taxe_paypal ;
|
||||
$total_usd_received += $Montant ;
|
||||
$total_usd_invoice += $Montant2_usd ;
|
||||
( $montant_HT_EUR_exo, $montant_HT_EUR_ass, $montant_TVA_EUR, $montant_HT_EUR_sup, $montant_TVA_EUR_sup )
|
||||
= tva_line( $Devise, $Montant2_usd, $Pays, $Nom_Option_1, $Valeur_Option_1, $Titre_de_l_objet ) ;
|
||||
( $montant_HT_EUR_exo, $montant_HT_EUR_ass, $montant_TVA_EUR,
|
||||
$montant_HT_EUR_sup, $montant_TVA_EUR_sup, $montant_HT_EUR_sup_exo )
|
||||
= tva_line( $Devise, $Montant2_usd, $Pays, $Nom_Option_1, $Valeur_Option_1, $Titre_de_l_objet, $Date ) ;
|
||||
$total_HT_EUR_exo += $montant_HT_EUR_exo ;
|
||||
$total_HT_EUR_ass += $montant_HT_EUR_ass ;
|
||||
$total_TVA_EUR += $montant_TVA_EUR ;
|
||||
#$invoice = $first_invoice + $nb_invoice ;
|
||||
|
||||
$invoice = next_invoice( ) ;
|
||||
$nb_invoice++ ;
|
||||
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ;
|
||||
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde] [$Impact_sur_le_solde]\n" ) ;
|
||||
|
||||
}
|
||||
|
||||
|
@ -438,19 +455,19 @@ sub compute_line {
|
|||
$Montant2_eur = $Hors_taxe_paypal ;
|
||||
$total_eur_received += $Montant ;
|
||||
$total_eur_invoice += $Montant2_eur ;
|
||||
( $montant_HT_EUR_exo, $montant_HT_EUR_ass, $montant_TVA_EUR, $montant_HT_EUR_sup, $montant_TVA_EUR_sup )
|
||||
= tva_line( $Devise, $Montant2_eur, $Pays, $Nom_Option_1, $Valeur_Option_1, $Titre_de_l_objet ) ;
|
||||
( $montant_HT_EUR_exo, $montant_HT_EUR_ass, $montant_TVA_EUR,
|
||||
$montant_HT_EUR_sup, $montant_TVA_EUR_sup, $montant_HT_EUR_sup_exo )
|
||||
= tva_line( $Devise, $Montant2_eur, $Pays, $Nom_Option_1, $Valeur_Option_1, $Titre_de_l_objet, $Date ) ;
|
||||
$total_HT_EUR_exo += $montant_HT_EUR_exo ;
|
||||
$total_HT_EUR_ass += $montant_HT_EUR_ass ;
|
||||
$total_TVA_EUR += $montant_TVA_EUR ;
|
||||
$total_HT_EUR_sup += $montant_HT_EUR_sup ;
|
||||
$total_TVA_EUR_sup += $montant_TVA_EUR_sup ;
|
||||
$total_HT_EUR_sup_exo += $montant_HT_EUR_sup_exo ;
|
||||
|
||||
|
||||
#$invoice = $first_invoice + $nb_invoice ;
|
||||
$invoice = next_invoice( ) ;
|
||||
$nb_invoice++ ;
|
||||
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ;
|
||||
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde] [$Impact_sur_le_solde]\n" ) ;
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -463,7 +480,7 @@ sub compute_line {
|
|||
$nb_invoice_refund++;
|
||||
$invoice_refund{ $invoice }++ ;
|
||||
|
||||
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ;
|
||||
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde] [$Impact_sur_le_solde]\n" ) ;
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -476,7 +493,7 @@ sub compute_line {
|
|||
$nb_invoice_canceled++;
|
||||
$invoice_canceled{ $invoice }++ ;
|
||||
|
||||
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ;
|
||||
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde] [$Impact_sur_le_solde]\n" ) ;
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -489,7 +506,7 @@ sub compute_line {
|
|||
$nb_invoice_suspended++;
|
||||
$invoice_suspended{ $invoice }++ ;
|
||||
|
||||
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ;
|
||||
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde] [$Impact_sur_le_solde]\n" ) ;
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -499,22 +516,57 @@ sub compute_line {
|
|||
) {
|
||||
$invoice = next_invoice( ) ;
|
||||
$nb_invoice++ ;
|
||||
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde]\n" ) ;
|
||||
$print_details and print ( "[$invoice] [$Date] [$Heure] [$Fuseau_horaire] [$Nom] [$Type] [$Etat] [$Devise] [$Montant] [$Numero_davis_de_reception] [$Solde] [$Impact_sur_le_solde]\n" ) ;
|
||||
}
|
||||
|
||||
$action->{ 'invoice' } = $invoice ;
|
||||
if ( $bnc ) {
|
||||
my $FR_flag = '' ;
|
||||
$FR_flag = ' FR' if $Pays eq 'France' ;
|
||||
my $IND_flag = '' ;
|
||||
$IND_flag = ' IND' if ('imapsync usage' eq $Nom_Option_1 and 'individual' eq $Valeur_Option_1 ) ;
|
||||
my $FR_flag = FR_flag( $Pays ) ;
|
||||
my $IND_flag = IND_flag( $Nom_Option_1, $Valeur_Option_1 ) ;
|
||||
my $SUPPORT_flag = SUPPORT_flag( $Titre_de_l_objet ) ;
|
||||
my $BNC_output = BNC_output( $invoice, $FR_flag, $IND_flag, $SUPPORT_flag,
|
||||
$Nom, $Date, $MontantEUR, $Devise, $Titre_de_l_objet, $Impact_sur_le_solde, $Type ) ;
|
||||
print $BNC_output ;
|
||||
}
|
||||
}
|
||||
|
||||
sub BNC_output {
|
||||
# FE 1359 FR IND imapsync Bougon Edouard
|
||||
# [12/01/2012] FR IND 28.73 EUR
|
||||
my( $invoice, $FR_flag, $IND_flag, $SUPPORT_flag,
|
||||
$Nom, $Date, $MontantEUR, $Devise, $Titre_de_l_objet, $Impact_sur_le_solde, $Type ) = @_ ;
|
||||
|
||||
my $BNC_output ;
|
||||
|
||||
if ( 'NONE' eq $invoice ) {
|
||||
$BNC_output = "[$Date] $MontantEUR $Devise $Nom $Titre_de_l_objet [$Impact_sur_le_solde] [$Type]\n" ;
|
||||
}else{
|
||||
$BNC_output =
|
||||
"FE $invoice$FR_flag$IND_flag imapsync$SUPPORT_flag $Nom\n"
|
||||
. "[$Date]$FR_flag$IND_flag $MontantEUR $Devise \n" ;
|
||||
}
|
||||
return( $BNC_output ) ;
|
||||
}
|
||||
|
||||
sub SUPPORT_flag {
|
||||
my $Titre_de_l_objet = shift ;
|
||||
my $SUPPORT_flag = '' ;
|
||||
$SUPPORT_flag = ' support' if ( 'imapsync support' eq $Titre_de_l_objet ) ;
|
||||
#print "FE $invoice$FR_flag$IND_flag\n" ;
|
||||
#printf( "%.2f [EUR %.2f]\n", $Montant, $MontantEUR ) ;
|
||||
print "FE $invoice$FR_flag$IND_flag imapsync$SUPPORT_flag $Nom\n" ;
|
||||
print "[$Date]$FR_flag$IND_flag $MontantEUR $Devise \n" ;
|
||||
}
|
||||
}
|
||||
|
||||
sub IND_flag {
|
||||
my( $Nom_Option_1, $Valeur_Option_1 ) = @_ ;
|
||||
my $IND_flag = '' ;
|
||||
$IND_flag = ' IND' if ('imapsync usage' eq $Nom_Option_1 and 'individual' eq $Valeur_Option_1 ) ;
|
||||
return( $IND_flag ) ;
|
||||
}
|
||||
|
||||
sub FR_flag {
|
||||
my $Pays = shift ;
|
||||
my $FR_flag = '' ;
|
||||
|
||||
$FR_flag = ' FR' if $Pays eq 'France' ;
|
||||
return( $FR_flag ) ;
|
||||
}
|
||||
|
||||
sub build_invoice {
|
||||
|
@ -522,7 +574,7 @@ sub build_invoice {
|
|||
|
||||
return if ! $invoice ;
|
||||
|
||||
my $action = $action_of_invoice{ $invoice } ;
|
||||
my $action = $action_invoice{ $invoice } ;
|
||||
my $refund = '' ;
|
||||
$refund = 'REFUND ' if $invoice_refund{ $invoice } ;
|
||||
my %action = %$action if $action ;
|
||||
|
@ -692,8 +744,8 @@ sub description_stuff {
|
|||
|
||||
my ( $descriptionFR, $descriptionEN ) ;
|
||||
if ( 'software' eq $object_type ) {
|
||||
$descriptionFR = 'Logiciel imapsync. Tous droits cédés.' ;
|
||||
$descriptionEN = '(Imapsync software. All rights conceded.)' ;
|
||||
$descriptionFR = 'Logiciel imapsync. TOUS droits cédés, autorisés.' ;
|
||||
$descriptionEN = '(Imapsync software. ALL rights conceded, allowed.)' ;
|
||||
}
|
||||
|
||||
my ( $usageFR, $usageEN ) ;
|
||||
|
@ -999,10 +1051,13 @@ sub date_aaaa_mm_jj {
|
|||
|
||||
|
||||
sub tva_line {
|
||||
my( $Devise, $Montant2, $Pays, $Nom_Option_1, $Valeur_Option_1, $Titre_de_l_objet ) = @_ ;
|
||||
my( $Devise, $Montant2, $Pays, $Nom_Option_1, $Valeur_Option_1, $Titre_de_l_objet, $Date ) = @_ ;
|
||||
my( $montant_HT_EUR_exo, $montant_HT_EUR_ass, $montant_TVA_EUR ) = ( 0, 0, 0 ) ;
|
||||
|
||||
my( $montant_HT_EUR_sup, $montant_TVA_EUR_sup ) = ( 0, 0 ) ;
|
||||
my( $montant_HT_EUR_sup, $montant_TVA_EUR_sup, $montant_HT_EUR_sup_exo ) = ( 0, 0, 0 ) ;
|
||||
|
||||
|
||||
my $date_aaaa_mm_jj = date_aaaa_mm_jj( $Date ) ;
|
||||
|
||||
$Montant2 = $Montant2/$usdeur if 'USD' eq $Devise ;
|
||||
|
||||
|
@ -1026,13 +1081,21 @@ sub tva_line {
|
|||
}
|
||||
|
||||
if ( 'imapsync support' eq $Titre_de_l_objet ) {
|
||||
#print "ZZZZ $Titre_de_l_objet $Montant2\n" ;
|
||||
if (
|
||||
( 'imapsync usage' eq $Nom_Option_1 and 'individual' eq $Valeur_Option_1 )
|
||||
or
|
||||
( 'France' eq $Pays )
|
||||
or
|
||||
( '2013_02_19' gt $date_aaaa_mm_jj )
|
||||
) {
|
||||
$montant_HT_EUR_sup = $Montant2 / 1.196 ;
|
||||
$montant_TVA_EUR_sup = $Montant2 / 1.196 * 0.196 ;
|
||||
}else{
|
||||
$montant_HT_EUR_sup_exo = $Montant2 ;
|
||||
}
|
||||
|
||||
|
||||
return( $montant_HT_EUR_exo, $montant_HT_EUR_ass, $montant_TVA_EUR, $montant_HT_EUR_sup, $montant_TVA_EUR_sup ) ;
|
||||
}
|
||||
return( $montant_HT_EUR_exo, $montant_HT_EUR_ass, $montant_TVA_EUR,
|
||||
$montant_HT_EUR_sup, $montant_TVA_EUR_sup, $montant_HT_EUR_sup_exo ) ;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1062,8 +1125,6 @@ sub tva_stuff {
|
|||
if ( ( 'individual' eq $clientTypeEN)
|
||||
or
|
||||
( 'France' eq $Pays )
|
||||
or
|
||||
( 'imapsync support' eq $Titre_de_l_objet )
|
||||
) {
|
||||
$priceHT = sprintf('%2.2f', $Hors_taxe/1.196) ;
|
||||
$tvaFR = '19,60\%';
|
||||
|
@ -1080,8 +1141,8 @@ sub tva_stuff {
|
|||
$priceTVA = 'néant (none)' ;
|
||||
$priceTTC = $priceHT ;
|
||||
$HTorTTC = 'HT' ;
|
||||
$messageTVAFR = 'Exonération de TVA, articles 262 1-2 et ter du Code Général des Impôts';
|
||||
$messageTVAEN = '(VAT tax-exempt, articles 262 1-2 and ter of French General Tax Code)';
|
||||
$messageTVAFR = 'Exonération de TVA, articles 259 et 262 du Code Général des Impôts';
|
||||
$messageTVAEN = '(VAT tax-exempt, articles 259 and 262 of French General Tax Code)';
|
||||
}
|
||||
foreach my $price ( $priceHT, $priceTVA, $priceTTC, $priceTTCusd ) {
|
||||
#print "[$price]\n" ;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue