aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--driver.c19
-rw-r--r--etrn.c3
-rw-r--r--fetchmail.h3
-rw-r--r--imap.c50
-rw-r--r--pop2.c1
-rw-r--r--pop3.c1
6 files changed, 66 insertions, 11 deletions
diff --git a/driver.c b/driver.c
index 4dfd0865..afe303c2 100644
--- a/driver.c
+++ b/driver.c
@@ -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)
diff --git a/etrn.c b/etrn.c
index 12ee2f20..cba25269 100644
--- a/etrn.c
+++ b/etrn.c
@@ -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 */
diff --git a/imap.c b/imap.c
index 035942f7..8e675b61 100644
--- a/imap.c
+++ b/imap.c
@@ -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 */
diff --git a/pop2.c b/pop2.c
index 1f04a4ce..51ddd295 100644
--- a/pop2.c
+++ b/pop2.c
@@ -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 */
diff --git a/pop3.c b/pop3.c
index a6443835..600d9917 100644
--- a/pop3.c
+++ b/pop3.c
@@ -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 */