-/*
- * uid.c -- UIDL handling for POP3 servers without LAST
+/**
+ * \file uid.c -- UIDL handling for POP3 servers without LAST
*
* For license terms, see the file COPYING in this directory.
*/
#include "fetchmail.h"
#include "i18n.h"
+#include "sdump.h"
/*
* Machinery for handling UID lists live here. This is mainly to support
* the lotus notes case.
* So we start looking for the '@' after which the
* host will follow with the ' ' seperator finaly id.
+ *
+ * XXX FIXME: There is a case this code cannot handle:
+ * the user name cannot have blanks after a '@'.
*/
if ((delimp1 = strchr(user, '@')) != NULL &&
(id = strchr(delimp1,' ')) != NULL)
id = id + strspn(id, " ");
delimp1++; /* but what if there is only white space ?!? */
- saveddelim1 = *delimp1; /* save char after token */
+ /* we have at least one @, else we are not in this branch */
+ saveddelim1 = *delimp1; /* save char after token */
*delimp1 = '\0'; /* delimit token with \0 */
- if (id != NULL)
- {
- /* now remove trailing white space chars from id */
- if ((delimp2 = strpbrk(id, " \t\n")) != NULL ) {
- saveddelim2 = *delimp2;
- *delimp2 = '\0';
- }
- atsign = strrchr(user, '@');
- if (atsign) {
- *atsign = '\0';
- host = atsign + 1;
- }
- for (ctl = hostlist; ctl; ctl = ctl->next) {
- if (strcasecmp(host, ctl->server.queryname) == 0
+ /* now remove trailing white space chars from id */
+ if ((delimp2 = strpbrk(id, " \t\n")) != NULL ) {
+ saveddelim2 = *delimp2;
+ *delimp2 = '\0';
+ }
+
+ atsign = strrchr(user, '@');
+ /* we have at least one @, else we are not in this branch */
+ *atsign = '\0';
+ host = atsign + 1;
+
+ /* find proper list and save it */
+ for (ctl = hostlist; ctl; ctl = ctl->next) {
+ if (strcasecmp(host, ctl->server.queryname) == 0
&& strcasecmp(user, ctl->remotename) == 0) {
-
- save_str(&ctl->oldsaved, id, UID_SEEN);
- break;
- }
+ save_str(&ctl->oldsaved, id, UID_SEEN);
+ break;
}
- /*
- * If it's not in a host we're querying,
- * save it anyway. Otherwise we'd lose UIDL
- * information any time we queried an explicit
- * subset of hosts.
- */
- if (ctl == (struct query *)NULL) {
- /* restore string */
- *delimp1 = saveddelim1;
- *atsign = '@';
- if (delimp2 != NULL) {
- *delimp2 = saveddelim2;
- }
- save_str(&scratchlist, buf, UID_SEEN);
+ }
+ /*
+ * If it's not in a host we're querying,
+ * save it anyway. Otherwise we'd lose UIDL
+ * information any time we queried an explicit
+ * subset of hosts.
+ */
+ if (ctl == (struct query *)NULL) {
+ /* restore string */
+ *delimp1 = saveddelim1;
+ *atsign = '@';
+ if (delimp2 != NULL) {
+ *delimp2 = saveddelim2;
}
+ save_str(&scratchlist, buf, UID_SEEN);
}
}
}
{
report_build(stdout, GT_("Old UID list from %s:"),
ctl->server.pollname);
- for (idp = ctl->oldsaved; idp; idp = idp->next)
- report_build(stdout, " %s", (char *)idp->id);
+ for (idp = ctl->oldsaved; idp; idp = idp->next) {
+ char *t = sdump(idp->id, strlen(idp->id));
+ report_build(stdout, " %s", t);
+ free(t);
+ }
if (!idp)
report_build(stdout, GT_(" <empty>"));
report_complete(stdout, "\n");
if (uidlcount)
{
report_build(stdout, GT_("Scratch list of UIDs:"));
- for (idp = scratchlist; idp; idp = idp->next)
- report_build(stdout, " %s", (char *)idp->id);
+ for (idp = scratchlist; idp; idp = idp->next) {
+ char *t = sdump(idp->id, strlen(idp->id));
+ report_build(stdout, " %s", t);
+ free(t);
+ }
if (!idp)
report_build(stdout, GT_(" <empty>"));
report_complete(stdout, "\n");
continue;
*end = (struct idlist *)xmalloc(sizeof(struct idlist));
- (*end)->id = (unsigned char *)str;
+ (*end)->id = str;
(*end)->val.status.mark = status;
(*end)->val.status.num = 0;
(*end)->next = NULL;
struct idlist *walk;
if (caseblind) {
for( walk = *idl; walk; walk = walk->next )
- if( strcasecmp( str, (char *)walk->id) == 0 )
+ if( strcasecmp( str, walk->id) == 0 )
return walk;
} else {
for( walk = *idl; walk; walk = walk->next )
- if( strcmp( str, (char *)walk->id) == 0 )
+ if( strcmp( str, walk->id) == 0 )
return walk;
}
return NULL;
}
-int str_nr_in_list( struct idlist **idl, const char *str )
- /* return the position of str in idl */
+/** return the position of first occurrence of \a str in \a idl */
+int str_nr_in_list(struct idlist **idl, const char *str)
{
int nr;
struct idlist *walk;
- if ( !str )
+
+ if (!str)
return -1;
- for( walk = *idl, nr = 0; walk; nr ++, walk = walk->next )
- if( strcmp( str, walk->id) == 0 )
+ for (walk = *idl, nr = 0; walk; nr ++, walk = walk->next)
+ if (strcmp(str, walk->id) == 0)
return nr;
return -1;
}
report_build(stdout, GT_("Merged UID list from %s:"), ctl->server.pollname);
else
report_build(stdout, GT_("New UID list from %s:"), ctl->server.pollname);
- for (idp = dofastuidl ? ctl->oldsaved : ctl->newsaved; idp; idp = idp->next)
- report_build(stdout, " %s = %d", (char *)idp->id, idp->val.status.mark);
+ for (idp = dofastuidl ? ctl->oldsaved : ctl->newsaved; idp; idp = idp->next) {
+ char *t = sdump(idp->id, strlen(idp->id));
+ report_build(stdout, " %s = %d", t, idp->val.status.mark);
+ free(t);
+ }
if (!idp)
report_build(stdout, GT_(" <empty>"));
report_complete(stdout, "\n");
/* this is now a merged list! the mails which were seen in this
* poll are marked here. */
report_build(stdout, GT_("Merged UID list from %s:"), ctl->server.pollname);
- for (idp = ctl->oldsaved; idp; idp = idp->next)
- report_build(stdout, " %s = %d", (char *)idp->id, idp->val.status.mark);
+ for (idp = ctl->oldsaved; idp; idp = idp->next) {
+ char *t = sdump(idp->id, strlen(idp->id));
+ report_build(stdout, " %s = %d", t, idp->val.status.mark);
+ free(t);
+ }
if (!idp)
report_build(stdout, GT_(" <empty>"));
report_complete(stdout, "\n");
/* either nuke the file or write updated last-seen IDs */
if (!idcount && !scratchlist)
{
- if (outlevel >= O_DEBUG)
- report(stdout, GT_("Deleting fetchids file.\n"));
+ if (outlevel >= O_DEBUG) {
+ if (access(idfile, F_OK) == 0)
+ report(stdout, GT_("Deleting fetchids file.\n"));
+ }
if (unlink(idfile) && errno != ENOENT)
report(stderr, GT_("Error deleting %s: %s\n"), idfile, strerror(errno));
} else {
- char *newnam = xmalloc(strlen(idfile) + 2);
+ char *newnam = (char *)xmalloc(strlen(idfile) + 2);
strcpy(newnam, idfile);
strcat(newnam, "_");
if (outlevel >= O_DEBUG)
if (idp->val.status.mark == UID_SEEN
|| idp->val.status.mark == UID_DELETED)
fprintf(tmpfp, "%s@%s %s\n",
- ctl->remotename, ctl->server.queryname, (char *)idp->id);
+ ctl->remotename, ctl->server.queryname, idp->id);
}
for (idp = scratchlist; idp; idp = idp->next)
fputs(idp->id, tmpfp);