aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--driver.c6
-rw-r--r--fetchmail.h6
-rw-r--r--pop3.c46
-rw-r--r--uid.c24
4 files changed, 63 insertions, 19 deletions
diff --git a/driver.c b/driver.c
index 4a18403f..cfe4e8eb 100644
--- a/driver.c
+++ b/driver.c
@@ -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 *);
diff --git a/pop3.c b/pop3.c
index 2edbb907..592a5c7c 100644
--- a/pop3.c
+++ b/pop3.c
@@ -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)
diff --git a/uid.c b/uid.c
index 01b8999c..a8da788d 100644
--- a/uid.c
+++ b/uid.c
@@ -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)