void maildir_purge(const char *maildir, unsigned nage) { char *m=malloc(strlen(maildir)+sizeof("/cur")); char *p; int adjustquota; int nfiles; long nbytes; int nfiles2; long nbytes2; p=strrchr(maildir, '/'); if (p) ++p; else p="."; adjustquota=maildirquota_countfolder(p); if (!m) return; strcat(strcpy(m, maildir), "/cur"); dopurge(m, nage, &nfiles, &nbytes); strcat(strcpy(m, maildir), "/new"); dopurge(m, nage, &nfiles2, &nbytes2); free(m); nfiles += nfiles2; nbytes += nbytes2; if (adjustquota && nfiles > 0) maildir_quota_deleted(maildir, -nbytes, -nfiles); }
static long deliver(int fdin, const char *dir, long s, int auto_create, int quota_warn_percent, const char *pfix, const char *newquota) { struct maildir_tmpcreate_info createInfo; char buf[BUFSIZ]; int n; long ss=0; int fd; maildir_tmpcreate_init(&createInfo); createInfo.maildir=dir; createInfo.uniq=pfix; createInfo.msgsize=s; createInfo.doordie=1; while ((fd=maildir_tmpcreate_fd(&createInfo)) < 0) { if (errno == ENOENT && auto_create && maildir_mkdir(dir) == 0) { auto_create=0; continue; } perror(dir); exit(EX_TEMPFAIL); } while ((n=read(fdin, buf, sizeof(buf))) > 0) { char *p=buf; ss += n; while (n) { int l; if ((l=write(fd, p, n)) < 0) { close(fd); unlink(createInfo.tmpname); perror(createInfo.tmpname); exit(EX_IOERR); } p += l; n -= l; } } close(fd); if (n < 0) { unlink(createInfo.tmpname); perror(createInfo.tmpname); exit(EX_IOERR); } if (s != ss) { char *qq; struct maildirsize info; if (s) *strrchr(createInfo.newname, ',')=0; /* Zap incorrect size */ qq=malloc(strlen(createInfo.newname)+100); if (!qq) { unlink(createInfo.tmpname); perror(createInfo.tmpname); exit(EX_OSERR); } sprintf(qq, "%s,S=%ld", createInfo.newname, ss-s); free(createInfo.newname); createInfo.newname=qq; if (maildirquota_countfolder(dir)) { if (maildir_quota_add_start(dir, &info, ss-s, 1, newquota)) { unlink(createInfo.tmpname); printf("Mail quota exceeded.\n"); exit(EX_NOPERM); } maildir_quota_add_end(&info, ss-s, 1); } } if (maildir_movetmpnew(createInfo.tmpname, createInfo.newname)) { unlink(createInfo.tmpname); perror(createInfo.tmpname); exit(EX_IOERR); } maildir_tmpcreate_free(&createInfo); if (quota_warn_percent >= 0) maildir_deliver_quota_warning(dir, quota_warn_percent); return (ss); }
int reflag_filename(struct imapscanmessageinfo *mi, struct imapflags *flags, int fd) { char *p, *q, *r; int rc=0; struct imapflags old_flags; struct stat stat_buf; get_message_flags(mi, 0, &old_flags); p=get_reflagged_filename(mi->filename, flags); q=malloc(strlen(current_mailbox)+strlen(mi->filename)+sizeof("/cur/")); r=malloc(strlen(current_mailbox)+strlen(p)+sizeof("/cur/")); if (!q || !r) write_error_exit(0); strcat(strcat(strcpy(q, current_mailbox), "/cur/"), mi->filename); strcat(strcat(strcpy(r, current_mailbox), "/cur/"), p); if (strcmp(q, r)) { if (maildirquota_countfolder(current_mailbox) && old_flags.deleted != flags->deleted && fstat(fd, &stat_buf) == 0) { struct maildirsize quotainfo; int64_t nbytes; unsigned long unbytes; int nmsgs=1; if (maildir_parsequota(mi->filename, &unbytes) == 0) nbytes=unbytes; else nbytes=stat_buf.st_size; if ( flags->deleted ) { nbytes= -nbytes; nmsgs= -nmsgs; } if ( maildir_quota_delundel_start(current_mailbox, "ainfo, nbytes, nmsgs)) rc= -1; else maildir_quota_delundel_end("ainfo, nbytes, nmsgs); } if (rc == 0) rename(q, r); #if SMAP snapshot_needed(); #endif } free(q); free(r); free(mi->filename); mi->filename=p; #if 0 if (is_sharedsubdir(current_mailbox)) maildir_shared_updateflags(current_mailbox, p); #endif return (rc); }
int main(int argc, char **argv) { const char *dir; struct stat stat_buf; int auto_create = 0; int quota_warn_percent = -1; int i; const char *quota=NULL; for (i=1; i<argc; i++) { if (strcmp(argv[i], "-c") == 0) { auto_create = 1; continue; } if (strcmp(argv[i], "-w") == 0 && argc - i > 1) { quota_warn_percent = atoi(argv[i+1]); ++i; continue; } break; } if (i >= argc || quota_warn_percent < -1 || quota_warn_percent > 100) { fprintf(stderr, "Usage: %s [-c] [-w percent] maildir\n", argv[0]); exit(73); } dir=argv[i]; ++i; if (i < argc) quota=argv[i]; if (fstat(0, &stat_buf) == 0 && S_ISREG(stat_buf.st_mode) && stat_buf.st_size > 0) { struct maildirsize info; int doquota=maildirquota_countfolder(dir); if (doquota && maildir_quota_add_start(dir, &info, stat_buf.st_size, 1, quota)) { if (quota_warn_percent >= 0) maildir_deliver_quota_warning(dir, quota_warn_percent); printf("Mail quota exceeded.\n"); exit(77); } deliver(0, dir, stat_buf.st_size, auto_create, quota_warn_percent, NULL, quota); if (doquota) maildir_quota_add_end(&info, stat_buf.st_size, 1); exit(0); } deliver(0, dir, 0, auto_create, quota_warn_percent, NULL, quota); exit(0); }