diff options
-rw-r--r-- | driver.c | 19 | ||||
-rw-r--r-- | etrn.c | 3 | ||||
-rw-r--r-- | fetchmail.h | 3 | ||||
-rw-r--r-- | imap.c | 50 | ||||
-rw-r--r-- | pop2.c | 1 | ||||
-rw-r--r-- | pop3.c | 1 |
6 files changed, 66 insertions, 11 deletions
@@ -427,11 +427,12 @@ int smtp_open(struct query *ctl) return(ctl->smtp_socket); } -static int gen_readmsg(sock, len, delimited, ctl, realname) +static int gen_readmsg(sock, len, delimited, num, ctl, realname) /* read message content and ship to SMTP or MDA */ int sock; /* to which the server is connected */ long len; /* length of message */ int delimited; /* does the protocol use a message delimiter? */ +int num; /* message number we're fetching */ struct query *ctl; /* query control record */ char *realname; /* real name of host */ { @@ -1027,6 +1028,19 @@ char *realname; /* real name of host */ SockWrite(ctl->smtp_socket, "\r\n", 2); } + + /* + * If we're using IMAP4 or something else that can fetch headers + * separately from bodies, it's time to grab the body now. This + * fetch may be skipped if we got an anti-spam or other error + * response from SMTP above. + */ + if (protocol->fetch_body) + { + (protocol->trail)(sock, ctl, -1); + (protocol->fetch_body)(sock, ctl, num, &remaining); + } + /* * Body processing starts here */ @@ -1483,7 +1497,7 @@ const struct method *proto; /* protocol method table */ else { /* request a message */ - ok = (protocol->fetch)(sock, ctl, num, &len); + ok = (protocol->fetch_headers)(sock, ctl, num, &len); if (ok != 0) goto cleanUp; set_timeout(ctl->server.timeout); @@ -1503,6 +1517,7 @@ const struct method *proto; /* protocol method table */ ok = gen_readmsg(sock, len, protocol->delimited, + num, ctl, realname); if (ok == PS_TRANSIENT) @@ -100,7 +100,8 @@ const static struct method etrn = etrn_getrange, /* initialize message sending */ NULL, /* we cannot get a list of sizes */ NULL, /* how do we tell a message is old? */ - NULL, /* request given message */ + NULL, /* no way to fetch headers */ + NULL, /* no way to fetch body */ NULL, /* no message trailer */ NULL, /* how to delete a message */ "QUIT", /* the ETRN exit command */ diff --git a/fetchmail.h b/fetchmail.h index 879112db..252b19ff 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -145,7 +145,8 @@ struct method int (*getrange)(); /* get message range to fetch */ int (*getsizes)(); /* get sizes of messages */ int (*is_old)(); /* check for old message */ - int (*fetch)(); /* fetch a given message */ + int (*fetch_headers)(); /* fetch FROM headera given message */ + int (*fetch_body)(); /* fetch a given message */ int (*trail)(); /* eat trailer of a message */ int (*delete)(); /* delete method */ char *exit_cmd; /* exit command */ @@ -185,7 +185,42 @@ static int imap_is_old(int sock, struct query *ctl, int number) return(seen); } -static int imap_fetch(int sock, struct query *ctl, int number, int *lenp) +static int imap_fetch_headers(int sock, struct query *ctl, int number, int *lenp) +/* request nth message */ +{ + char buf [POPBUFSIZE+1]; + int num; + + /* expunges change the fetch numbers */ + number -= deletecount; + + switch (imap_version) + { + case IMAP4rev1: /* RFC 2060 */ + gen_send(sock, "FETCH %d BODY[HEADER]", number); + break; + + default: /* RFC 1176 */ + gen_send(sock, "FETCH %d RFC822.HEADER", number); + break; + } + + /* looking for FETCH response */ + do { + int ok; + + if ((ok = gen_recv(sock, buf, sizeof(buf)))) + return(ok); + } while + (sscanf(buf+2, "%d FETCH (%*s {%d}", &num, lenp) != 2); + + if (num != number) + return(PS_ERROR); + else + return(PS_SUCCESS); +} + +static int imap_fetch_body(int sock, struct query *ctl, int number, int *lenp) /* request nth message */ { char buf [POPBUFSIZE+1]; @@ -208,20 +243,20 @@ static int imap_fetch(int sock, struct query *ctl, int number, int *lenp) { case IMAP4rev1: /* RFC 2060 */ if (!ctl->keep) - gen_send(sock, "FETCH %d BODY.PEEK[]", number); + gen_send(sock, "FETCH %d BODY.PEEK[TEXT]", number); else - gen_send(sock, "FETCH %d BODY", number); + gen_send(sock, "FETCH %d BODY[TEXT]", number); break; case IMAP4: /* RFC 1730 */ if (!ctl->keep) - gen_send(sock, "FETCH %d RFC822.PEEK", number); + gen_send(sock, "FETCH %d RFC822.TEXT.PEEK", number); else - gen_send(sock, "FETCH %d RFC822", number); + gen_send(sock, "FETCH %d RFC822.TEXT", number); break; default: /* RFC 1176 */ - gen_send(sock, "FETCH %d RFC822", number); + gen_send(sock, "FETCH %d RFC822.TEXT", number); break; } @@ -295,7 +330,8 @@ const static struct method imap = imap_getrange, /* query range of messages */ imap_getsizes, /* grab message sizes */ imap_is_old, /* no UID check */ - imap_fetch, /* request given message */ + imap_fetch_headers, /* request given message headers */ + imap_fetch_body, /* request given message body */ imap_trail, /* eat message trailer */ imap_delete, /* delete the message */ "LOGOUT", /* the IMAP exit command */ @@ -125,6 +125,7 @@ const static struct method pop2 = NULL, /* no way to get sizes */ NULL, /* messages are always new */ pop2_fetch, /* request given message */ + NULL, /* no way to fetch body alone */ pop2_trail, /* eat message trailer */ NULL, /* no POP2 delete method */ "QUIT", /* the POP2 exit command */ @@ -274,6 +274,7 @@ const static struct method pop3 = pop3_getsizes, /* we can get a list of sizes */ pop3_is_old, /* how do we tell a message is old? */ pop3_fetch, /* request given message */ + NULL, /* no way to fetch body alone */ NULL, /* no message trailer */ pop3_delete, /* how to delete a message */ "QUIT", /* the POP3 exit command */ |