X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=uid.c;h=8e51bb3289f0c5c72026d5e60c89ef3657428a2d;hb=30abdc40501b9675ead72fa59ae138fc4336de47;hp=54d415894f96bdba3f38ed1bec3a834a0ec1cb80;hpb=73b592a0450107cfb62ec95e910bd064c20d186d;p=~andy%2Ffetchmail diff --git a/uid.c b/uid.c index 54d41589..8e51bb32 100644 --- a/uid.c +++ b/uid.c @@ -7,6 +7,7 @@ #include "config.h" #include +#include #if defined(STDC_HEADERS) #include #include @@ -44,6 +45,8 @@ * Each time a message is fetched, we can check its UID against the * `oldsaved' list to see if it is old. * + * Each time a message-id is seen, we mark it with MARK_SEEN. + * * Each time a message is deleted, we mark its id UID_DELETED in the * `newsaved' member. When we want to assert that an expunge has been * done on the server, we call expunge_uid() to register that all @@ -52,13 +55,9 @@ * At the end of the query, the `newsaved' member becomes the * `oldsaved' list. The old `oldsaved' list is freed. * - * At the end of the fetchmail run, non-EXPUNGED members of all + * At the end of the fetchmail run, seen and non-EXPUNGED members of all * current `oldsaved' lists are flushed out to the .fetchids file to - * be picked up by the next run. (The UID_EXPUNGED test means that a - * message marked UID_DELETED may still have its ID go to disk if - * there has been no intervening expunge operation. This typically - * comes up if the query was aborted by a line hit before a quit or - * expunge was sent to the server.) If there are no un-expunged + * be picked up by the next run. If there are no un-expunged * messages, the file is deleted. * * Note: all comparisons are caseblind! @@ -94,14 +93,14 @@ void initialize_saved_lists(struct query *hostlist, const char *idfile) strcasecmp(host, ctl->server.truename) == 0 && strcasecmp(user, ctl->remotename) == 0) { - save_str(&ctl->oldsaved, UID_KEPT, id); + save_str(&ctl->oldsaved, id, UID_UNSEEN); break; } } /* if it's not in a host we're querying, save it anyway */ if (ctl == (struct query *)NULL) - save_str(&scratchlist, UID_KEPT, buf); + save_str(&scratchlist, buf, UID_SEEN); } } fclose(tmpfp); @@ -109,7 +108,7 @@ void initialize_saved_lists(struct query *hostlist, const char *idfile) } #endif /* POP3_ENABLE */ -struct idlist *save_str(struct idlist **idl, int num, const char *str) +struct idlist *save_str(struct idlist **idl, const char *str, flag status) /* save a number/UID pair on the given UID list */ { struct idlist **end; @@ -119,7 +118,7 @@ struct idlist *save_str(struct idlist **idl, int num, const char *str) continue; *end = (struct idlist *)xmalloc(sizeof(struct idlist)); - (*end)->val.num = num; + (*end)->val.status.mark = status; (*end)->id = str ? xstrdup(str) : (char *)NULL; (*end)->next = NULL; @@ -195,8 +194,8 @@ int str_nr_in_list( struct idlist **idl, const char *str ) return -1; } -int str_nr_last_in_list( struct idlist **idl, const char *str ) - /* return the last position of str in idl */ +int str_nr_last_in_list( struct idlist **idl, const char *str) +/* return the last position of str in idl */ { int nr, ret = -1; struct idlist *walk; @@ -208,16 +207,28 @@ int str_nr_last_in_list( struct idlist **idl, const char *str ) return ret; } -int count_list( struct idlist **idl ) - /* count the number of elements in the list */ +void str_set_mark( struct idlist **idl, const char *str, const flag val) +/* update the mark on an of an id to given value */ +{ + int nr; + struct idlist *walk; + if (!str) + return; + for(walk = *idl, nr = 0; walk; nr ++, walk = walk->next) + if (strcasecmp(str, walk->id) == 0) + walk->val.status.mark = val; +} + +int count_list( struct idlist **idl) +/* count the number of elements in the list */ { if( !*idl ) return 0; return 1 + count_list( &(*idl)->next ); } -char* str_from_nr_list( struct idlist **idl, int number ) - /* return the number'th string in idl */ +char *str_from_nr_list(struct idlist **idl, int number) +/* return the number'th string in idl */ { if( !*idl || number < 0) return 0; @@ -232,7 +243,7 @@ char *str_find(struct idlist **idl, int number) { if (*idl == (struct idlist *) 0) return((char *) 0); - else if (number == (*idl)->val.num) + else if (number == (*idl)->val.status.num) return((*idl)->id); else return(str_find(&(*idl)->next, number)); @@ -252,37 +263,23 @@ char *idpair_find(struct idlist **idl, const char *id) int delete_str(struct idlist **idl, int num) /* delete given message from given list */ { -#ifdef HARD_DELETE /* not used */ - if (*idl == (struct idlist *)NULL) - return(0); - else if ((*idl)->val.num == num) - { - struct idlist *next = (*idl)->next; - - free ((*idl)->id); - free(*idl); - *idl = next; - return(1); - } - else - return(delete_str(&(*idl)->next, num)); -#else struct idlist *idp; for (idp = *idl; idp; idp = idp->next) - if (idp->val.num == num) + if (idp->val.status.num == num) { - idp->val.num = UID_DELETED; + idp->val.status.mark = UID_DELETED; return(1); } return(0); -#endif /* HARD_DELETE */ } void append_str_list(struct idlist **idl, struct idlist **nidl) /* append nidl to idl (does not copy *) */ { - if ((*idl) == (struct idlist *)NULL) + if ((*nidl) == (struct idlist *)NULL) + return; + else if ((*idl) == (struct idlist *)NULL) *idl = *nidl; else if ((*idl)->next == (struct idlist *)NULL) (*idl)->next = *nidl; @@ -297,8 +294,8 @@ void expunge_uids(struct query *ctl) struct idlist *idl; for (idl = ctl->newsaved; idl; idl = idl->next) - if (idl->val.num == UID_DELETED) - idl->val.num = UID_EXPUNGED; + if (idl->val.status.mark == UID_DELETED) + idl->val.status.mark = UID_EXPUNGED; } void update_str_lists(struct query *ctl) @@ -331,7 +328,8 @@ void write_saved_lists(struct query *hostlist, const char *idfile) if ((tmpfp = fopen(idfile, "w")) != (FILE *)NULL) { for (ctl = hostlist; ctl; ctl = ctl->next) { for (idp = ctl->oldsaved; idp; idp = idp->next) - if (idp->val.num != UID_EXPUNGED) + if (idp->val.status.mark == UID_SEEN + || idp->val.status.mark == UID_DELETED) fprintf(tmpfp, "%s@%s %s\n", ctl->remotename, ctl->server.truename, idp->id); }