diff options
-rw-r--r-- | driver.c | 6 | ||||
-rw-r--r-- | fetchmail.h | 6 | ||||
-rw-r--r-- | pop3.c | 46 | ||||
-rw-r--r-- | uid.c | 24 |
4 files changed, 63 insertions, 19 deletions
@@ -712,9 +712,13 @@ struct method *proto; * on a protocol error or had delivery refused by the SMTP * server (unlikely -- I've never seen it) or we've seen * `accepted for delivery' and the message is shipped. - * It's safe to delete the message on the server now. + * It's safe to mark the message seen and delete it on the + * server now. */ + /* nuke it from the unseen-messages list */ + delete_uid(&queryctl->unseen, num); + /* maybe we delete this message now? */ if (protocol->delete && !queryctl->keep diff --git a/fetchmail.h b/fetchmail.h index 8c4ee3a3..5a146ce8 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -87,8 +87,8 @@ struct hostrec int norewrite; int skip; - /* current, previous state of mailbox (initially from .fetchids) */ - struct idlist *saved, *current; + /* unseen, previous state of mailbox (initially from .fetchids) */ + struct idlist *saved, *unseen; /* internal use */ int active; @@ -148,7 +148,7 @@ int doIMAP (struct hostrec *); void initialize_saved_lists(struct hostrec *, char *); void save_uid(struct idlist **, int, char *); void free_uid_list(struct idlist **); -int delete_uid(struct idlist **, char *); +int delete_uid(struct idlist **, int); int uid_in_list(struct idlist **, char *); void update_uid_lists(struct hostrec *); void write_saved_lists(struct hostrec *, char *); @@ -149,8 +149,29 @@ int *countp; gen_send(socket,"LAST"); ok = pop3_ok(socket, buf); - if (ok == 0 && sscanf(buf, "%d", &last) == 0) - return(PS_ERROR); + if (ok == 0) + { + if (sscanf(buf, "%d", &last) == 0) + return(PS_ERROR); + } + else + { + int num; + + /* 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->unseen, num, id); + } + } + } } return(0); @@ -161,7 +182,26 @@ int socket; struct hostrec *queryctl; int num; { - return (num <= last); + if (!queryctl->saved) + return (num <= last); + else + { + char buf [POPBUFSIZE+1]; + int ok; + + gen_send(socket, "UIDL %d", num); + if ((ok = pop3_ok(socket, buf)) != 0) + return(ok); + else + { + char id[IDLEN+1]; + + if (sscanf(buf, "%*d %s", id) == 2) + return(uid_in_list(&queryctl->saved, id)); + else + return(0); + } + } } static int pop3_fetch(socket, number, lenp) @@ -44,9 +44,9 @@ * file and hangs off the host's `saved' member. * * Early in the query, during the execution of the protocol-specific - * getrange code, the driver expects that the host's `listed' member + * getrange code, the driver expects that the host's `unseen' member * will be filled with a list of UIDs and message numbers representing - * the current mailbox state. If this list is empty, the server did + * the unseen mailbox state. If this list is empty, the server did * not respond to the request for a UID listing. * * Each time a message is fetched, we can check its UID against the @@ -54,10 +54,10 @@ * (and possibly deleted). It should be downloaded anyway if --all * is on. It should not be deleted if --keep is on. * - * Each time a message is deleted, we remove its id from the `listed' + * Each time a message is read, we remove its id from the `unseen' * member. * - * At the end of the query, whatever remains in the `listed' member + * At the end of the query, whatever remains in the `unseen' member * (because it was not deleted) becomes the `saved' list. The old * `saved' list is freed. */ @@ -76,7 +76,7 @@ char *idfile; /* make sure lists are initially empty */ for (hostp = hostlist; hostp; hostp = hostp->next) - hostp->saved = hostp->current = (struct idlist *)NULL; + hostp->saved = hostp->unseen = (struct idlist *)NULL; /* let's get stored message UIDs from previous queries */ if ((tmpfp = fopen(idfile, "r")) != (FILE *)NULL) { @@ -145,14 +145,14 @@ char *str; return(uid_in_list(&(*idl)->next, str)); } -int delete_uid(idl, str) -/* delete given UID from given list */ +int delete_uid(idl, num) +/* delete given message from given list */ struct idlist **idl; -char *str; +int num; { if (*idl == (struct idlist *)NULL) return(0); - else if (strcmp((*idl)->id, str) == 0) + else if ((*idl)->num == num) { struct idlist *next = (*idl)->next; @@ -162,7 +162,7 @@ char *str; return(1); } else - return(delete_uid(&(*idl)->next, str)); + return(delete_uid(&(*idl)->next, num)); return(0); } @@ -171,10 +171,10 @@ void update_uid_lists(hostp) struct hostrec *hostp; { /* - * Replace `saved' list with `current' list as modified by deletions. + * Replace `saved' list with `unseen' list as modified by deletions. */ free_uid_list(&hostp->saved); - hostp->saved = hostp->current; + hostp->saved = hostp->unseen; } void write_saved_lists(hostlist, idfile) |