aboutsummaryrefslogtreecommitdiffstats
path: root/pop3.c
diff options
context:
space:
mode:
Diffstat (limited to 'pop3.c')
-rw-r--r--pop3.c175
1 files changed, 106 insertions, 69 deletions
diff --git a/pop3.c b/pop3.c
index 480b4fd7..412c3e34 100644
--- a/pop3.c
+++ b/pop3.c
@@ -151,62 +151,87 @@ struct hostrec *queryctl;
int *countp;
int *firstp;
{
- int ok;
- char buf [POPBUFSIZE+1];
+ int ok;
+ char buf [POPBUFSIZE+1];
- /* get the total message count */
- gen_send(socket, "STAT");
- ok = pop3_ok(buf,socket);
- if (ok == 0)
- sscanf(buf,"%d %*d", countp);
- else
- return(ok);
-
- /*
- * Ask for number of last message retrieved.
- * Newer, RFC-1760-conformant POP servers may not have the LAST command.
- * Therefore we don't croak if we get a nonzero return. Instead, send
- * UIDL and try to find the last received ID stored for this host in
- * the list we get back.
- */
- *firstp = 1;
- use_uidl = 0;
- if (*countp > 0 && !queryctl->fetchall) {
- char id [IDLEN+1];
- int num;
-
- /* try LAST first */
- gen_send(socket,"LAST");
+ /* get the total message count */
+ gen_send(socket, "STAT");
ok = pop3_ok(buf,socket);
- if (ok == 0 && sscanf(buf, "%d", firstp) == 0)
- return(PS_ERROR);
-
- use_uidl = (ok != 0);
-
- /* otherwise, if we have a stored last ID for this host,
- * send UIDL and search the returned list for it
- */
- if (use_uidl && queryctl->lastid[0]) {
- gen_send("UIDL");
- if ((ok = pop3_ok(buf, socket)) == 0) {
- while (SockGets(socket, buf, sizeof(buf)) >= 0) {
- if (outlevel == O_VERBOSE)
- fprintf(stderr,"%s\n",buf);
- if (strcmp(buf, ".\n") == 0) {
- break;
+ if (ok == 0)
+ sscanf(buf,"%d %*d", countp);
+ else
+ return(ok);
+
+ /*
+ * Ask for number of last message retrieved.
+ * Newer, RFC-1760-conformant POP servers may not have the LAST command.
+ * Therefore we don't croak if we get a nonzero return. Instead, send
+ * UIDL and try to find the last received ID stored for this host in
+ * the list we get back.
+ */
+ *firstp = 1;
+ use_uidl = 0;
+ if (*countp > 0 && !queryctl->fetchall) {
+ char id [IDLEN+1];
+ int num;
+
+ /* try LAST first */
+ gen_send(socket,"LAST");
+ ok = pop3_ok(buf,socket);
+ if (ok == 0 && sscanf(buf, "%d", &num) == 0)
+ return(PS_ERROR);
+
+ use_uidl = (ok != 0);
+
+ if (!use_uidl)
+ *firstp = num + 1;
+ else
+ {
+ /* grab the mailbox's UID list */
+ gen_send(socket, "UIDL");
+ if ((ok = pop3_ok(buf, socket)) == 0) {
+ while (SockGets(socket, buf, sizeof(buf)) >= 0) {
+ if (outlevel == O_VERBOSE)
+ fprintf(stderr,"%s\n",buf);
+ if (strcmp(buf, ".\n") == 0) {
+ break;
+ }
+ if (sscanf(buf, "%d %s\n", &num, id) == 2)
+ save_uid(&queryctl->mailbox, num, id);
+ }
}
- if (sscanf(buf, "%d %s\n", &num, id) == 2)
- if (strcmp(id, queryctl->lastid) == 0)
- *firstp = num;
- }
- }
+ }
}
- if (ok == 0)
- (*firstp)++;
- }
+ return(0);
+}
+
+static pop3_is_old(socket, queryctl, number)
+/* check a given message for age by UID */
+int socket;
+struct hostrec *queryctl;
+int number;
+{
+ if (!use_uidl)
+ return(0);
+ else
+ {
+ char buf [POPBUFSIZE+1];
+ int ok;
+
+ gen_send(socket, "UIDL %d", number);
+ if ((ok = pop3_ok(socket, buf)) != 0)
+ return(ok);
+ else
+ {
+ char id[IDLEN+1];
- return(0);
+ if (sscanf(buf, "%*d %s", id) == 2)
+ return(uid_in_list(&queryctl->saved, id));
+ else
+ return(0);
+ }
+ }
}
static int pop3_fetch(socket, number, limit, lenp)
@@ -223,25 +248,36 @@ int *lenp;
return(gen_transact(socket, "RETR %d", number));
}
-static pop3_trail(socket, queryctl, number)
-/* update the last-seen field for this host */
+static pop3_delete(socket, queryctl, number)
+/* delete a given message */
int socket;
struct hostrec *queryctl;
int number;
{
- if (!use_uidl)
- return(0);
- else
+ int ok;
+
+ /* send the deletion request */
+ if ((ok = gen_transact(socket, "DELE %d", number)) != 0)
+ return(ok);
+
+ /* we may need to nuke the message's UID out of the mailbox list */
+ if (use_uidl)
{
char buf [POPBUFSIZE+1];
- int ok;
+ /*
+ * This isn't strictly necessary. We should probably just
+ * stash the UID result from the last is_old call.
+ */
gen_send(socket, "UIDL %d", number);
if ((ok = pop3_ok(socket, buf)) != 0)
return(ok);
else
{
- sscanf(buf, "%*d %s", queryctl->lastid);
+ char id[IDLEN+1];
+
+ if (sscanf(buf, "%*d %s", id) == 2)
+ delete_uid(&queryctl->mailbox, id);
return(0);
}
}
@@ -249,18 +285,19 @@ int number;
static struct method pop3 =
{
- "POP3", /* Post Office Protocol v3 */
- 110, /* standard POP3 port */
- 0, /* this is not a tagged protocol */
- 1, /* this uses a message delimiter */
- pop3_ok, /* parse command response */
- pop3_getauth, /* get authorization */
- pop3_getrange, /* query range of messages */
- pop3_fetch, /* request given message */
- pop3_trail, /* eat message trailer */
- "DELE %d", /* set POP3 delete flag */
- NULL, /* the POP3 expunge command */
- "QUIT", /* the POP3 exit command */
+ "POP3", /* Post Office Protocol v3 */
+ 110, /* standard POP3 port */
+ 0, /* this is not a tagged protocol */
+ 1, /* this uses a message delimiter */
+ pop3_ok, /* parse command response */
+ pop3_getauth, /* get authorization */
+ pop3_getrange, /* query range of messages */
+ pop3_is_old, /* check for age by UID */
+ pop3_fetch, /* request given message */
+ NULL, /* no message trailer */
+ pop3_delete, /* how to delete a message */
+ NULL, /* no POP3 expunge command */
+ "QUIT", /* the POP3 exit command */
};
int doPOP3 (queryctl)