diff options
Diffstat (limited to 'uid.c')
-rw-r--r-- | uid.c | 38 |
1 files changed, 28 insertions, 10 deletions
@@ -134,7 +134,7 @@ void initialize_saved_lists(struct query *hostlist, const char *idfile) if (lstat(idfile, &statbuf) < 0) { if (errno == ENOTDIR) { - report(stderr, GT_("lstat: %s: %s\n"), idfile, strerror(errno)); + report(stderr, "lstat: %s: %s\n", idfile, strerror(errno)); exit(PS_IOERR); } } @@ -292,8 +292,7 @@ void initialize_saved_lists(struct query *hostlist, const char *idfile) /* 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); + return *save_str_quick(idl, str ? xstrdup(str) : NULL, st); } void free_str_list(struct idlist **idl) @@ -538,11 +537,12 @@ void uid_swap_lists(struct query *ctl) if (ctl->newsaved) { /* old state of mailbox may now be irrelevant */ + struct idlist **temp = &ctl->oldsaved; if (outlevel >= O_DEBUG) report(stdout, GT_("swapping UID lists\n")); - free_str_list(&ctl->oldsaved); ctl->oldsaved = ctl->newsaved; ctl->newsaved = (struct idlist *) NULL; + free_str_list(temp); } /* in fast uidl, there is no need to swap lists: the old state of * mailbox cannot be discarded! */ @@ -608,14 +608,17 @@ void write_saved_lists(struct query *hostlist, const char *idfile) { if (outlevel >= O_DEBUG) report(stdout, GT_("Deleting fetchids file.\n")); - unlink(idfile); - } - else - { + if (unlink(idfile)) + report(stderr, GT_("Error deleting %s: %s\n"), strerror(errno)); + } else { + char *newnam = xmalloc(strlen(idfile) + 2); + strcpy(newnam, idfile); + strcat(newnam, "_"); 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) { + (void)unlink(newnam); /* remove file/link first */ + if ((tmpfp = fopen(newnam, "w")) != (FILE *)NULL) { + int errflg; for (ctl = hostlist; ctl; ctl = ctl->next) { for (idp = ctl->oldsaved; idp; idp = idp->next) if (idp->val.status.mark == UID_SEEN @@ -625,8 +628,23 @@ void write_saved_lists(struct query *hostlist, const char *idfile) } for (idp = scratchlist; idp; idp = idp->next) fputs(idp->id, tmpfp); + fflush(tmpfp); + errflg = ferror(tmpfp); fclose(tmpfp); + /* if we could write successfully, move into place; + * otherwise, drop */ + if (errflg) { + report(stderr, GT_("Error writing to fetchids file %s, old file left in place.\n"), newnam); + unlink(newnam); + } else { + if (rename(newnam, idfile)) { + report(stderr, GT_("Cannot rename fetchids file %s to %s: %s\n"), newnam, idfile, strerror(errno)); + } + } + } else { + report(stderr, GT_("Cannot open fetchids file %s for writing: %s\n"), newnam, strerror(errno)); } + free(newnam); } } #endif /* POP3_ENABLE */ |