"Eric S. Raymond" <esr(_at_)thyrsus(_dot_)com> writes:
Yes, I am interested in these patches.
The automake switch has been sent in private mail, the accelerator patch
is also reflected here in case somebody else is interested:
diff -Nru a/fetchmail.h b/fetchmail.h
--- a/fetchmail.h Fri Feb 28 15:58:36 2003
+++ b/fetchmail.h Fri Feb 28 15:58:36 2003
@@ -313,6 +313,7 @@
unsigned int uid; /* UID of user to deliver to */
struct idlist *skipped; /* messages skipped on the mail server */
struct idlist *oldsaved, *newsaved;
+ struct idlist **oldsavedend;
char *lastid; /* last Message-ID seen on this connection */
char *thisid; /* Message-ID of current message */
@@ -513,14 +514,14 @@
struct idlist *copy_str_list(struct idlist *idl);
void save_str_pair(struct idlist **, const char *, const char *);
void free_str_pair_list(struct idlist **);
-int delete_str(struct idlist **, int);
+int delete_str(struct idlist **, long);
int str_in_list(struct idlist **, const char *, const flag);
int str_nr_in_list(struct idlist **, const char *);
int str_nr_last_in_list(struct idlist **, const char *);
void str_set_mark( struct idlist **, const char *, const flag);
int count_list( struct idlist **idl );
-char *str_from_nr_list( struct idlist **idl, int number );
-char *str_find(struct idlist **, int);
+char *str_from_nr_list( struct idlist **idl, long number );
+char *str_find(struct idlist **, long);
char *idpair_find(struct idlist **, const char *);
void append_str_list(struct idlist **, struct idlist **);
void expunge_uids(struct query *);
diff -Nru a/uid.c b/uid.c
--- a/uid.c Fri Feb 28 15:58:36 2003
+++ b/uid.c Fri Feb 28 15:58:36 2003
@@ -23,8 +23,8 @@
/*
* Machinery for handling UID lists live here. This is mainly to support
- * RFC1725-conformant POP3 servers without a LAST command, but may also be
- * useful for making the IMAP4 querying logic UID-oriented, if a future
+ * RFC1725/RFC1939-conformant POP3 servers without a LAST command, but may also
+ * be useful for making the IMAP4 querying logic UID-oriented, if a future
* revision of IMAP forces me to.
*
* These functions are also used by the rest of the code to maintain
@@ -39,7 +39,7 @@
* This list is initially set up by initialize_saved_list() from the
* .fetchids file.
*
- * Early in the query, during the execution of the protocol-specific
+ * Early in the query, during the execution of the protocol-specific
* getrange code, the driver expects that the host's `newsaved' member
* will be filled with a list of UIDs and message numbers representing
* the mailbox state. If this list is empty, the server did
@@ -63,7 +63,7 @@
* be picked up by the next run. If there are no un-expunged
* messages, the file is deleted.
*
- * Note: some comparisons (those used for DNS address lists) are caseblind!
+ * Note: some comparisons (those used for DNS address lists) are caseblind!
*/
/* UIDs associated with un-queried hosts */
@@ -78,8 +78,12 @@
struct query *ctl;
/* make sure lists are initially empty */
- for (ctl = hostlist; ctl; ctl = ctl->next)
- ctl->skipped = ctl->oldsaved = ctl->newsaved = (struct idlist *)NULL;
+ for (ctl = hostlist; ctl; ctl = ctl->next) {
+ ctl->skipped = (struct idlist *)NULL;
+ ctl->oldsaved = (struct idlist *)NULL;
+ ctl->newsaved = (struct idlist *)NULL;
+ ctl->oldsavedend = &ctl->oldsaved;
+ }
errno = 0;
@@ -91,13 +95,13 @@
* that all implementations of lstat() will return ENOTDIR
* rather than plain ENOENT in this case...
*/
- if (lstat(idfile, &statbuf) < 0) {
- if (errno == ENOTDIR)
- {
- report(stderr, GT_("lstat: %s: %s\n"), idfile, strerror(errno));
- exit(PS_IOERR);
+ if (lstat(idfile, &statbuf) < 0) {
+ if (errno == ENOTDIR)
+ {
+ report(stderr, GT_("lstat: %s: %s\n"), idfile, strerror(errno));
+ exit(PS_IOERR);
+ }
}
- }
/* let's get stored message UIDs from previous queries */
if ((tmpfp = fopen(idfile, "r")) != (FILE *)NULL)
@@ -231,7 +235,11 @@
}
#endif /* POP3_ENABLE */
-struct idlist *save_str(struct idlist **idl, const char *str, flag status)
+/* return a pointer to the last element of the list to help the quick,
+ * constant-time addition to the list, NOTE: this function does not dup
+ * the string, the caller must do that. */
+/*(_at_)shared@*/ struct idlist **save_str_quick(/*(_at_)shared@*/ struct
idlist **idl,
+ /*(_at_)only@*/ char *str, flag status)
/* save a number/UID pair on the given UID list */
{
struct idlist **end;
@@ -242,10 +250,17 @@
*end = (struct idlist *)xmalloc(sizeof(struct idlist));
(*end)->val.status.mark = status;
- (*end)->id = str ? xstrdup(str) : (char *)NULL;
+ (*end)->id = (unsigned char *)str;
(*end)->next = NULL;
- return(*end);
+ return end;
+}
+
+/* return the end list element for direct modification */
+struct idlist *save_str(struct idlist **idl, const char *str, flag st)
+{
+ return *save_str_quick(idl, str ? xstrdup(str) : NULL,
+ st);
}
void free_str_list(struct idlist **idl)
@@ -296,14 +311,17 @@
int str_in_list(struct idlist **idl, const char *str, const flag caseblind)
/* is a given ID in the given list? (comparison may be caseblind) */
{
- if (*idl == (struct idlist *)NULL || str == (char *) NULL)
- return(0);
- else if (!caseblind && strcmp(str, (*idl)->id) == 0)
- return(1);
- else if (caseblind && strcasecmp(str, (*idl)->id) == 0)
- return(1);
- else
- return(str_in_list(&(*idl)->next, str, caseblind));
+ struct idlist *walk;
+ if (caseblind) {
+ for( walk = *idl; walk; walk = walk->next )
+ if( strcasecmp( str, (char *)walk->id) == 0 )
+ return 1;
+ } else {
+ for( walk = *idl; walk; walk = walk->next )
+ if( strcmp( str, (char *)walk->id) == 0 )
+ return 1;
+ }
+ return 0;
}
int str_nr_in_list( struct idlist **idl, const char *str )
@@ -352,7 +370,7 @@
return 1 + count_list( &(*idl)->next );
}
-char *str_from_nr_list(struct idlist **idl, int number)
+/*(_at_)null@*/ char *str_from_nr_list(struct idlist **idl, long number)
/* return the number'th string in idl */
{
if( !*idl || number < 0)
@@ -362,8 +380,8 @@
return str_from_nr_list(&(*idl)->next, number-1);
}
-
-char *str_find(struct idlist **idl, int number)
+
+char *str_find(struct idlist **idl, long number)
/* return the id of the given number in the given list. */
{
if (*idl == (struct idlist *) 0)
@@ -385,7 +403,7 @@
return(idpair_find(&(*idl)->next, id));
}
-int delete_str(struct idlist **idl, int num)
+int delete_str(struct idlist **idl, long num)
/* delete given message from given list */
{
struct idlist *idp;
@@ -487,7 +505,7 @@
void write_saved_lists(struct query *hostlist, const char *idfile)
/* perform end-of-run write of seen-messages list */
{
- int idcount;
+ long idcount;
FILE *tmpfp;
struct query *ctl;
struct idlist *idp;
@@ -495,10 +513,10 @@
/* if all lists are empty, nuke the file */
idcount = 0;
for (ctl = hostlist; ctl; ctl = ctl->next) {
- for (idp = ctl->oldsaved; idp; idp = idp->next)
- if (idp->val.status.mark == UID_SEEN
- || idp->val.status.mark == UID_DELETED)
- idcount++;
+ for (idp = ctl->oldsaved; idp; idp = idp->next)
+ if (idp->val.status.mark == UID_SEEN
+ || idp->val.status.mark == UID_DELETED)
+ idcount++;
}
/* either nuke the file or write updated last-seen IDs */
@@ -512,6 +530,7 @@
{
if (outlevel >= O_DEBUG)
report(stdout, GT_("Writing fetchids file.\n"));
+ /* FIXME: do not overwrite the old idfile */
if ((tmpfp = fopen(idfile, "w")) != (FILE *)NULL) {
for (ctl = hostlist; ctl; ctl = ctl->next) {
for (idp = ctl->oldsaved; idp; idp = idp->next)
--
Matthias Andree