int do_copy_quota_calc(unsigned long n, int byuid, void *voidptr) { struct copyquotainfo *info=(struct copyquotainfo *)voidptr; const char *filename; unsigned long nbytes; struct stat stat_buf; int fd; struct imapflags flags; char *ff; --n; fd=imapscan_openfile(current_mailbox, ¤t_maildir_info, n); if (fd < 0) return (0); filename=current_maildir_info.msgs[n].filename; get_message_flags(¤t_maildir_info.msgs[n], NULL, &flags); (void)acl_flags_adjust(info->acls, &flags); ff=get_reflagged_filename(filename, &flags); if (maildirquota_countfile(ff)) { if (maildir_parsequota(ff, &nbytes)) { if (fstat(fd, &stat_buf) < 0) { close(fd); free(ff); return (0); } nbytes=stat_buf.st_size; } info->nbytes += nbytes; info->nfiles += 1; } close(fd); free(ff); return (0); }
static void cleanup() { unsigned i; int64_t deleted_bytes=0; int64_t deleted_messages=0; for (i=0; i<msglist_cnt; i++) if (msglist_a[i]->isdeleted) { unsigned long un=0; const char *filename=msglist_a[i]->filename; if (maildirquota_countfile(filename)) { if (maildir_parsequota(filename, &un)) { struct stat stat_buf; if (stat(filename, &stat_buf) == 0) un=stat_buf.st_size; } } if (unlink(msglist_a[i]->filename)) un=0; if (un) { deleted_bytes -= un; deleted_messages -= 1; } } if (deleted_messages < 0) maildir_quota_deleted(".", deleted_bytes, deleted_messages); return; }
static int dosendmsg(const char *origdraft) { pid_t pid; const char *returnaddr; int pipefd1[2]; char *filename; const char *line; char *draftmessage; int isgpgerr; unsigned long filesize; struct stat stat_buf; int dsn; if (tokencheck()) /* Duplicate submission - message was already sent */ { sendmsg_done(); return (1); } if (strcmp(cgi("form"), "doattach") == 0) { /* When called from the attachment window, we do NOT create ** a new draft message */ draftmessage=strdup(origdraft); } else draftmessage=newmsg_createdraft(origdraft); if (!draftmessage) enomem(); filename=newmsg_createsentmsg(draftmessage, &isgpgerr, 1); if (!filename) { char *draftbase=maildir_basename(draftmessage); if (isgpgerr) { cgi_put("draftmessage", draftbase); output_form("gpgerr.html"); } else { http_redirect_argss("&form=newmsg&pos=%s" "&draft=%s&error=quota", cgi("pos"), draftbase); } free(draftmessage); free(draftbase); return (1); } if (pipe(pipefd1) != 0) { cgi_put("foldermsg", "ERROR: pipe() failed."); maildir_msgpurgefile(SENT, filename); free(filename); free(draftmessage); return (0); } returnaddr=login_returnaddr(); dsn= *cgi("dsn") != 0; pid=fork(); if (pid < 0) { cgi_put("foldermsg", "ERROR: fork() failed."); close(pipefd1[0]); close(pipefd1[1]); maildir_msgpurgefile(SENT, filename); free(filename); free(draftmessage); return (0); } if (pid == 0) { static const char noexec[]="ERROR: Unable to execute sendit.sh.\n"; static const char nofile[]="ERROR: Temp file not available - probably exceeded quota.\n"; char *tmpfile=maildir_find(SENT, filename); int fd; if (!tmpfile) { fwrite((char*)nofile, 1, sizeof(nofile)-1, stderr); _exit(1); } close(0); fd=maildir_safeopen(tmpfile, O_RDONLY, 0); close(1); close(2); dup(pipefd1[1]); dup(pipefd1[1]); close(pipefd1[0]); close(pipefd1[1]); if (dsn) putenv("DSN=-Nsuccess,delay,fail"); else putenv("DSN="); if (fd == 0) execl(SENDITSH, "sendit.sh", returnaddr, sqwebmail_mailboxid, NULL); fwrite(noexec, 1, sizeof(noexec)-1, stderr); _exit(1); } close(pipefd1[1]); line=geterrbuf(pipefd1[0]); close(pipefd1[0]); if (waitfor(pid)) { if (!*line) line="Unable to send message.\n"; } else line=""; if (*line == 0) /* Succesfully sent message */ { if (*draftmessage) { char *base=maildir_basename(draftmessage); char *draftfile=maildir_find(DRAFTS, base); free(base); /* Remove draft file */ if (draftfile) { char *replytofolder=0, *replytomsg=0; char *header, *value; FILE *fp; int x; fp=0; x=maildir_safeopen(draftfile, O_RDONLY, 0); if ( maildir_parsequota(draftfile, &filesize)) { if (x < 0 || fstat(x, &stat_buf)) stat_buf.st_size=0; filesize=stat_buf.st_size; } if (x >= 0) if ((fp=fdopen(x, "r")) == 0) close(x); /* First, look for a message that we should ** mark as replied */ while (fp && (header=maildir_readheader(fp, &value, 0)) != 0) { if (strcmp(header,"x-reply-to-folder") == 0 && !replytofolder) { replytofolder=strdup(value); if (!replytofolder) enomem(); } if (strcmp(header,"x-reply-to-msg") == 0 && !replytomsg) { replytomsg=strdup(value); if (!replytomsg) enomem(); } if (replytofolder && replytomsg) break; } if (fp) fclose(fp); if (replytofolder && replytomsg) maildir_markreplied(replytofolder, replytomsg); if (replytofolder) free(replytofolder); if (replytomsg) free(replytomsg); maildir_quota_deleted(".", -(long)filesize, -1); unlink(draftfile); free(draftfile); } } tokensave(); if (*cgi("fcc") == 0) { unsigned long filesize=0; char *tmpfile=maildir_find(SENT, filename); if (tmpfile) { maildir_parsequota(tmpfile, &filesize); unlink(tmpfile); maildir_quota_deleted(".", -(long)filesize,-1); free(tmpfile); } } free(filename); free(draftmessage); sendmsg_done(); return (1); } if (stat(filename, &stat_buf) == 0) maildir_quota_deleted(".", -(long)stat_buf.st_size, -1); maildir_msgpurgefile(SENT, filename); free(filename); { char *draftbase=maildir_basename(draftmessage); http_redirect_argsss("&form=newmsg&pos=%s&draft=%s&foldermsg=%s", cgi("pos"), draftbase, line); free(draftmessage); free(draftbase); } return (1); }
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); }