From 192bcbb0ddce0d8737923c7bb41c5b836a357458 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 7 Aug 1997 19:24:53 +0000 Subject: Deal with X-IMAP header properly. svn path=/trunk/; revision=1244 --- NEWS | 4 ++++ driver.c | 21 +++++++++++++++++---- etrn.c | 1 + fetchmail.h | 2 ++ imap.c | 14 ++++++++++++++ pop2.c | 1 + pop3.c | 14 ++++++++++++++ 7 files changed, 53 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index be19e8c0..ad54d873 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,10 @@ ------------------------------------------------------------------------------ fetchmail-4.0.8 () * Fixed core dump bug in UID handling introduced by the 4.0.6 change. +* Retrieval code for POP3 & older IMAP versions now skips X-IMAP message + used by UW IMAP4rev1 server to store UIDs. + +There are 260 people on the fetchmail-friends list. fetchmail-4.0.7 (Tue Aug 5 22:47:11 EDT 1997) * Fixed a minor bug in handling of DNS errors in multidrop mode. diff --git a/driver.c b/driver.c index 224a941c..853f5bfa 100644 --- a/driver.c +++ b/driver.c @@ -502,12 +502,13 @@ static int stuffline(struct query *ctl, char *buf, flag delimited) return(n); } -static int readheaders(sock, len, ctl, realname) +static int readheaders(sock, len, ctl, realname, num) /* read message headers and ship to SMTP or MDA */ int sock; /* to which the server is connected */ long len; /* length of message */ struct query *ctl; /* query control record */ char *realname; /* real name of host */ +int num; /* index of message */ { char buf[MSGBUFSIZE+1], return_path[MSGBUFSIZE+1]; int from_offs, ctt_offs, env_offs, addressoffs[128], next_address; @@ -585,6 +586,10 @@ char *realname; /* real name of host */ break; } + /* maybe this is a special message that holds mailbox annotations? */ + if (protocol->retain_hdr && protocol->retain_hdr(num, line)) + return(PS_RETAINED); + /* * This code prevents fetchmail from becoming an accessory after * the fact to upstream sendmails with the `E' option on. This @@ -1536,6 +1541,7 @@ const struct method *proto; /* protocol method table */ && (ctl->fetchall || force_retrieval || !(protocol->is_old && (protocol->is_old)(sock,ctl,num))); flag suppress_delete = FALSE; flag suppress_forward = FALSE; + flag retained = FALSE; /* we may want to reject this message if it's old */ if (!fetch_it) @@ -1581,8 +1587,10 @@ const struct method *proto; /* protocol method table */ * Read the message headers and ship them to the * output sink. */ - ok = readheaders(sock, len, ctl, realname); - if (ok == PS_TRANSIENT) + ok = readheaders(sock, len, ctl, realname, num); + if (ok == PS_RETAINED) + suppress_forward = retained = TRUE; + else if (ok == PS_TRANSIENT) suppress_delete = suppress_forward = TRUE; else if (ok == PS_REFUSED) suppress_forward = TRUE; @@ -1679,7 +1687,12 @@ const struct method *proto; /* protocol method table */ */ /* maybe we delete this message now? */ - if (protocol->delete + if (retained) + { + if (outlevel > O_SILENT) + error_complete(0, 0, " retained"); + } + else if (protocol->delete && !suppress_delete && (fetch_it ? !ctl->keep : ctl->flush)) { diff --git a/etrn.c b/etrn.c index c0f6fea1..36a2e037 100644 --- a/etrn.c +++ b/etrn.c @@ -163,6 +163,7 @@ const static struct method etrn = NULL, /* no way to fetch body */ NULL, /* no message trailer */ NULL, /* how to delete a message */ + NULL, /* no retained-header check */ "QUIT", /* the ETRN exit command */ }; diff --git a/fetchmail.h b/fetchmail.h index f5632c2d..0db3f4b3 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -42,6 +42,7 @@ #define PS_UNDEFINED 11 /* something I hadn't thought of */ #define PS_TRANSIENT 12 /* transient failure (internal use) */ #define PS_REFUSED 13 /* mail refused (internal use) */ +#define PS_RETAINED 24 /* message retained (internal use) */ /* output noise level */ #define O_SILENT 0 /* mute, max squelch, etc. */ @@ -168,6 +169,7 @@ struct method int (*fetch_body)(); /* fetch a given message */ int (*trail)(); /* eat trailer of a message */ int (*delete)(); /* delete method */ + flag (*retain_hdr)(); /* if this returns TRUE, retain message */ char *exit_cmd; /* exit command */ }; diff --git a/imap.c b/imap.c index 3234b3b5..f1d5a225 100644 --- a/imap.c +++ b/imap.c @@ -620,6 +620,19 @@ static int imap_delete(int sock, struct query *ctl, int number) return(PS_SUCCESS); } +static flag imap_retain_check(int num, char *buf) +/* is this a special message that should be retained? */ +{ + /* + * The University of Washington IMAP server (the reference + * implementation of IMAP4 written by Mark Crispin) relies + * on being able to keep base-UID information in a special + * message at the head of the mailbox. This message should + * neither be deleted nor forwarded. + */ + return (num == 1 && !strncasecmp(buf, "X-IMAP:", 7)); +} + const static struct method imap = { "IMAP", /* Internet Message Access Protocol */ @@ -636,6 +649,7 @@ const static struct method imap = imap_fetch_body, /* request given message body */ imap_trail, /* eat message trailer */ imap_delete, /* delete the message */ + imap_retain_check, /* leave this message alone? */ "LOGOUT", /* the IMAP exit command */ }; diff --git a/pop2.c b/pop2.c index dbb37284..170c07ac 100644 --- a/pop2.c +++ b/pop2.c @@ -130,6 +130,7 @@ const static struct method pop2 = NULL, /* no way to fetch body alone */ pop2_trail, /* eat message trailer */ NULL, /* no POP2 delete method */ + NULL, /* no retained-header check */ "QUIT", /* the POP2 exit command */ }; diff --git a/pop3.c b/pop3.c index 59f1da7e..e5e26299 100644 --- a/pop3.c +++ b/pop3.c @@ -342,6 +342,19 @@ static int pop3_delete(int sock, struct query *ctl, int number) return(gen_transact(sock, "DELE %d", number)); } +static flag pop3_retain_check(int num, char *buf) +/* is this a special message that should be retained? */ +{ + /* + * The University of Washington IMAP server (the reference + * implementation of IMAP4 written by Mark Crispin) relies + * on being able to keep base-UID information in a special + * message at the head of the mailbox. This message should + * neither be deleted nor forwarded. + */ + return (num == 1 && !strncasecmp(buf, "X-IMAP:", 7)); +} + const static struct method pop3 = { "POP3", /* Post Office Protocol v3 */ @@ -358,6 +371,7 @@ const static struct method pop3 = NULL, /* no way to fetch body alone */ NULL, /* no message trailer */ pop3_delete, /* how to delete a message */ + pop3_retain_check, /* try not to nuke an IMAP4rev header message */ "QUIT", /* the POP3 exit command */ }; -- cgit v1.2.3