static int savepop3dlist(struct msglist **a, size_t cnt, unsigned long uid) { FILE *fp; size_t i; struct maildir_tmpcreate_info createInfo; maildir_tmpcreate_init(&createInfo); createInfo.uniq="pop3"; createInfo.doordie=1; if ((fp=maildir_tmpcreate_fp(&createInfo)) == NULL) { maildir_tmpcreate_free(&createInfo); return -1; } fprintf(fp, "/2 %lu %lu\n", uid, uidv); for (i=0; i<cnt; i++) { char *p=a[i]->filename; char *q; if ((q=strrchr(p, '/')) != NULL) p=q+1; fprintf(fp, "%s %lu %lu:%lu\n", p, (unsigned long)a[i]->size, a[i]->uid.n, a[i]->uid.uidv); } if (fflush(fp) || ferror(fp)) { fclose(fp); unlink(createInfo.tmpname); maildir_tmpcreate_free(&createInfo); return -1; } if (fclose(fp) || rename(createInfo.tmpname, POP3DLIST) < 0) { unlink(createInfo.tmpname); maildir_tmpcreate_free(&createInfo); return -1; } maildir_tmpcreate_free(&createInfo); return 0; }
void write_sqconfig(const char *dir, const char *configfile, const char *val) { char *p=malloc(strlen(dir) + strlen(configfile) + 2); struct maildir_tmpcreate_info createInfo; FILE *fp; if (!p) enomem(); strcat(strcat(strcpy(p, dir), "/"), configfile); if (!val) { unlink(p); free(p); return; } maildir_tmpcreate_init(&createInfo); createInfo.maildir=dir; createInfo.uniq="config"; createInfo.doordie=1; fp=maildir_tmpcreate_fp(&createInfo); if (!fp) enomem(); free(createInfo.newname); createInfo.newname=p; fprintf(fp, "%s\n", val); fflush(fp); if (ferror(fp)) eio("Error after write:",p); fclose(fp); /* Note - umask should already turn off the 077 bits, but ** just in case someone screwed up previously, I'll fix it ** myself */ chmod(createInfo.tmpname, 0600); rename(createInfo.tmpname, createInfo.newname); maildir_tmpcreate_free(&createInfo); }
static int savemessage(const char *extension, const char *sender, const char *receipient, FILE *f, const char *name, const char *ufromline, const char *dtline, const char *rpline, const char *quota) { FILE *delivf; char buf[BUFSIZ]; int c; static unsigned counter=0; struct stat stat_buf; struct maildirsize quotainfo; struct maildir_tmpcreate_info createInfo; umask(077); if ((delivf=fopen(name, "a")) != 0) { /* Ok, perhaps this is a mailbox */ struct ll_mail *ll=ll_mail_alloc(name); fclose(delivf); if (!ll) { delivery_error(name); /* I Give up */ } while ((mbox_fd=ll_mail_open(ll)) < 0) { switch (errno) { case EEXIST: case EAGAIN: sleep(5); continue; break; } delivery_error(name); } delivf=fdopen(mbox_fd, "w"); if (delivf == NULL || fseek(delivf, 0L, SEEK_END) < 0 || (mbox_size=ftell(delivf)) == (off_t)-1) { if (delivf) fclose(delivf); close(mbox_fd); ll_mail_free(ll); delivery_error(name); /* I Give up */ } signal(SIGHUP, truncmbox); signal(SIGINT, truncmbox); signal(SIGQUIT, truncmbox); signal(SIGTERM, truncmbox); fprintf(delivf, "%s\n%s\n%s\n", ufromline, dtline, rpline); while (fgets(buf, sizeof(buf), f) != 0) { char *q=buf; while (*q == '>') q++; if (strncmp(q, "From ", 5) == 0) putc('>', delivf); fprintf(delivf, "%s", buf); if (strchr(buf, '\n') == 0) { while ((c=getc(f)) >= 0) { putc(c, delivf); if (c == '\n') break; } } } if ( ferror(f) || fflush(delivf) || ferror(delivf) #if EXPLICITSYNC || fsync(fileno(delivf)) #endif || (signal(SIGHUP, SIG_DFL), signal(SIGINT, SIG_DFL), signal(SIGQUIT, SIG_DFL), signal(SIGTERM, SIG_DFL), fclose(delivf)) ) { #if HAVE_FTRUNCATE if (ftruncate(mbox_fd, mbox_size) < 0) ; /* ignore */ #endif close(mbox_fd); ll_mail_free(ll); delivery_error("mailbox.close"); } close(mbox_fd); ll_mail_free(ll); return (0); } if (fstat(fileno(f), &stat_buf)) { delivery_error("stat"); return (-1); } stat_buf.st_size += strlen(dtline) + strlen(rpline) + 2; if (maildir_quota_add_start(name, "ainfo, stat_buf.st_size, 1, quota && *quota != 0 ? quota:NULL)) { errno=ENOSPC; delivery_error("out of memory."); } maildir_closequotafile("ainfo); /* For now. */ sprintf(buf, "%u", ++counter); maildir_tmpcreate_init(&createInfo); createInfo.maildir=name; createInfo.uniq=buf; createInfo.msgsize=stat_buf.st_size; createInfo.doordie=1; if ((delivf=maildir_tmpcreate_fp(&createInfo)) == NULL) { snprintf(buf, BUFSIZ-1, "maildir.open: %s: %s", name, strerror(errno)); buf[BUFSIZ-1] = 0; delivery_error(buf); return (-1); } fprintf(delivf, "%s\n%s\n", dtline, rpline); { char buffer[BUFSIZ]; int n; while ((n=fread(buffer, 1, sizeof(buffer), f)) > 0) if (fwrite(buffer, 1, n, delivf) != n) break; } if ( ferror(f) || fflush(delivf) || ferror(delivf) #if EXPLICITSYNC || fsync(fileno(delivf)) #endif || fclose(delivf) || (delivf=0, maildir_movetmpnew(createInfo.tmpname, createInfo.newname))) { snprintf(buf, BUFSIZ-1, "maildir.close: %s: %s", name, strerror(errno)); buf[BUFSIZ-1] = 0; if (delivf) fclose(delivf); unlink(createInfo.newname); delivery_error(buf); return (-1); } #if EXPLICITDIRSYNC { int fd; strcpy(strrchr(createInfo.newname, '/')+1, "."); fd=open(createInfo.newname, O_RDONLY); if (fd >= 0) { fsync(fd); close(fd); } } #endif maildir_tmpcreate_free(&createInfo); maildir_quota_deleted(name, stat_buf.st_size, 1); return (0); }
int maildir_filter_importmaildirfilter(const char *maildir) { const char *p=maildir_filter_config(maildir, "MAILDIRFILTER"); char *maildirfilter; FILE *i, *o; struct maildir_tmpcreate_info createInfo; if (!p) return (-1); if (!*p) { errno=ENOENT; return (-1); } maildirfilter=maildir_filter_config_maildirfilter(maildir); if (!maildirfilter) return (-1); maildir_tmpcreate_init(&createInfo); createInfo.maildir=maildir; createInfo.uniq="maildirfilter-tmp"; createInfo.doordie=1; if ((o=maildir_tmpcreate_fp(&createInfo)) == NULL) { free(maildirfilter); return (-1); } strcat(strcpy(createInfo.newname, maildir), "/maildirfilter.tmp"); /* We enough we have enough mem: .uniq */ if ((i=fopen(maildirfilter, "r")) == 0) { struct maildirfilter mf; if (errno != ENOENT) { fclose(o); unlink(createInfo.tmpname); maildir_tmpcreate_free(&createInfo); free(maildirfilter); return (-1); } memset(&mf, 0, sizeof(mf)); fclose(o); unlink(createInfo.tmpname); unlink(createInfo.newname); maildir_filter_savemaildirfilter(&mf, maildir, ""); /* write out a blank one */ } else { char buf[BUFSIZ]; int n; while ((n=fread(buf, 1, sizeof(buf), i)) > 0) if (fwrite(buf, 1, n, o) != n) { fclose(o); fclose(i); unlink(createInfo.tmpname); maildir_tmpcreate_free(&createInfo); free(maildirfilter); return (-1); } if (fflush(o)) { fclose(o); fclose(i); unlink(createInfo.tmpname); maildir_tmpcreate_free(&createInfo); free(maildirfilter); return (-1); } fclose(o); fclose(i); if (chmod(createInfo.tmpname, 0600) || rename(createInfo.tmpname, createInfo.newname)) { unlink(createInfo.tmpname); maildir_tmpcreate_free(&createInfo); free(maildirfilter); return (-1); } } maildir_tmpcreate_free(&createInfo); free(maildirfilter); return (0); }