From 563631fd4ea09d7ca739eb97f1fd48239a0e48ed Mon Sep 17 00:00:00 2001 From: CHTEKK Date: Sat, 21 Apr 2007 22:42:21 +0000 Subject: Fully fix indent on the whole maildir.c file. Trash quota counting fixed in previous commit. svn path=/; revision=36 --- vda/postfix-2.4.0-vda-ng.patch | 557 ++++++++++++++++++++++++----------------- 1 file changed, 331 insertions(+), 226 deletions(-) diff --git a/vda/postfix-2.4.0-vda-ng.patch b/vda/postfix-2.4.0-vda-ng.patch index badb25b..ff39d2d 100644 --- a/vda/postfix-2.4.0-vda-ng.patch +++ b/vda/postfix-2.4.0-vda-ng.patch @@ -345,12 +345,13 @@ diff -Nru postfix-2.4.0/src/virtual/mailbox.c postfix-2.4.0-vda/src/virtual/mail * Cleanup. diff -Nru postfix-2.4.0/src/virtual/maildir.c postfix-2.4.0-vda/src/virtual/maildir.c --- postfix-2.4.0/src/virtual/maildir.c 2006-06-26 14:59:19.000000000 +0200 -+++ postfix-2.4.0-vda/src/virtual/maildir.c 2007-04-22 00:10:17.000000000 +0200 -@@ -63,10 +63,339 @@ ++++ postfix-2.4.0-vda/src/virtual/maildir.c 2007-04-22 00:41:22.000000000 +0200 +@@ -63,28 +63,382 @@ #include #include +/* Patch library. */ ++ +#include /* opendir(3), stat(2) */ +#include /* stat(2) */ +#include /* opendir(3) */ @@ -369,7 +370,9 @@ diff -Nru postfix-2.4.0/src/virtual/maildir.c postfix-2.4.0-vda/src/virtual/mail #include "virtual.h" +-/* deliver_maildir - delivery to maildir-style mailbox */ +/* Maildirsize maximal size. */ ++ +#define SIZEFILE_MAX 5120 + +/* @@ -581,7 +584,8 @@ diff -Nru postfix-2.4.0/src/virtual/maildir.c postfix-2.4.0-vda/src/virtual/mail + sum += (long) statbuf.st_size; + (*countptr)++; + } -+ } else if ((statbuf.st_mode & S_IFDIR) != 0) { ++ } ++ else if ((statbuf.st_mode & S_IFDIR) != 0) { + sum += check_dir_size(vstring_str(buffer), countptr); + } + vstring_free(buffer); @@ -619,7 +623,8 @@ diff -Nru postfix-2.4.0/src/virtual/maildir.c postfix-2.4.0-vda/src/virtual/mail + + return(ret); +} -+ + +-int deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr) +/* Check if maildirfilter file is up-to-date compared to SQL, (re)write it if not. */ +static long sql2file(char *filename, char *user) +{ @@ -667,13 +672,15 @@ diff -Nru postfix-2.4.0/src/virtual/maildir.c postfix-2.4.0-vda/src/virtual/mail + msg_info("%s: updating filter file: %s", myname, filename); + write(filterfile, filter_sqlres, strlen(filter_sqlres)); + close(filterfile); -+ } else { ++ } ++ else { + msg_warn("%s: can't create filter file: %s", myname, filename); + retval = 0; + } + } + } -+ } else { ++ } ++ else { + if (stat(filename, &statbuf) == 0) + retval = (long) statbuf.st_mtime; + if (msg_verbose) @@ -683,13 +690,34 @@ diff -Nru postfix-2.4.0/src/virtual/maildir.c postfix-2.4.0-vda/src/virtual/mail + return(retval); +} + - /* deliver_maildir - delivery to maildir-style mailbox */ - - int deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr) -@@ -86,6 +415,27 @@ - struct stat st; - struct timeval starttime; - ++/* deliver_maildir - delivery to maildir-style mailbox */ ++int deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr) + { + const char *myname = "deliver_maildir"; +- char *newdir; +- char *tmpdir; +- char *curdir; +- char *tmpfile; +- char *newfile; ++ char *newdir; ++ char *tmpdir; ++ char *curdir; ++ char *tmpfile; ++ char *newfile; + DSN_BUF *why = state.msg_attr.why; + VSTRING *buf; + VSTREAM *dst; +- int mail_copy_status; +- int deliver_status; +- int copy_flags; +- struct stat st; +- struct timeval starttime; ++ int mail_copy_status; ++ int deliver_status; ++ int copy_flags; ++ struct stat st; ++ struct timeval starttime; ++ + /* Maildir Quota. */ + const char *limit_res; /* Limit from map. */ + char *sizefilename = (char *) 0; @@ -708,19 +736,44 @@ diff -Nru postfix-2.4.0/src/virtual/maildir.c postfix-2.4.0-vda/src/virtual/mail + VSTRING *fltstr; + VSTREAM *tmpfilter; + DICT *FILTERS; -+ long sqlmtime; -+ int cmd_len; -+ ++ long sqlmtime; ++ int cmd_len; + GETTIMEOFDAY(&starttime); +@@ -93,15 +447,14 @@ + */ + state.level++; + if (msg_verbose) +- MSG_LOG_STATE(myname, state); ++ MSG_LOG_STATE(myname, state); + /* -@@ -117,9 +467,74 @@ - copy_flags = MAIL_COPY_TOFILE | MAIL_COPY_RETURN_PATH - | MAIL_COPY_DELIVERED | MAIL_COPY_ORIG_RCPT; + * Don't deliver trace-only requests. + */ + if (DEL_REQ_TRACE_ONLY(state.request->flags)) { +- dsb_simple(why, "2.0.0", "delivers to maildir"); +- return (sent(BOUNCE_FLAGS(state.request), +- SENT_ATTR(state.msg_attr))); ++ dsb_simple(why, "2.0.0", "delivers to maildir"); ++ return (sent(BOUNCE_FLAGS(state.request), SENT_ATTR(state.msg_attr))); + } -- newdir = concatenate(usr_attr.mailbox, "new/", (char *) 0); -- tmpdir = concatenate(usr_attr.mailbox, "tmp/", (char *) 0); -- curdir = concatenate(usr_attr.mailbox, "cur/", (char *) 0); + /* +@@ -109,17 +462,81 @@ + * attribute to reflect the final recipient. + */ + if (vstream_fseek(state.msg_attr.fp, state.msg_attr.offset, SEEK_SET) < 0) +- msg_fatal("seek message file %s: %m", VSTREAM_PATH(state.msg_attr.fp)); ++ msg_fatal("seek message file %s: %m", VSTREAM_PATH(state.msg_attr.fp)); + state.msg_attr.delivered = state.msg_attr.rcpt.address; + mail_copy_status = MAIL_COPY_STAT_WRITE; + buf = vstring_alloc(100); + +- copy_flags = MAIL_COPY_TOFILE | MAIL_COPY_RETURN_PATH +- | MAIL_COPY_DELIVERED | MAIL_COPY_ORIG_RCPT; ++ copy_flags = MAIL_COPY_TOFILE | MAIL_COPY_RETURN_PATH | MAIL_COPY_DELIVERED | MAIL_COPY_ORIG_RCPT; ++ + /* + * Concatenate the maildir suffix (if set). + */ @@ -771,7 +824,10 @@ diff -Nru postfix-2.4.0/src/virtual/maildir.c postfix-2.4.0-vda/src/virtual/mail + /* There is no limit in the maps. Set n to 0. */ + n = 0; + } -+ + +- newdir = concatenate(usr_attr.mailbox, "new/", (char *) 0); +- tmpdir = concatenate(usr_attr.mailbox, "tmp/", (char *) 0); +- curdir = concatenate(usr_attr.mailbox, "cur/", (char *) 0); + /* + * Check quota before delivering the mail. + */ @@ -792,22 +848,41 @@ diff -Nru postfix-2.4.0/src/virtual/maildir.c postfix-2.4.0-vda/src/virtual/mail /* * Create and write the file as the recipient, so that file quota work. -@@ -178,6 +593,7 @@ - (unsigned long) starttime.tv_sec, var_pid, get_hostname()); +@@ -174,46 +591,278 @@ + * [...] + */ + set_eugid(usr_attr.uid, usr_attr.gid); +- vstring_sprintf(buf, "%lu.P%d.%s", +- (unsigned long) starttime.tv_sec, var_pid, get_hostname()); ++ vstring_sprintf(buf, "%lu.P%d.%s", (unsigned long) starttime.tv_sec, var_pid, get_hostname()); tmpfile = concatenate(tmpdir, STR(buf), (char *) 0); newfile = 0; + bkpnewfile = 0; if ((dst = vstream_fopen(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == 0 - && (errno != ENOENT - || make_dirs(tmpdir, 0700) < 0 -@@ -200,17 +616,251 @@ - (unsigned long) starttime.tv_usec, - get_hostname()); - newfile = concatenate(newdir, STR(buf), (char *) 0); -+ bkpnewfile = concatenate(STR(buf), (char *) 0); /* Will need it later, if we MOVE to other folders. */ - if ((mail_copy_status = mail_copy(COPY_ATTR(state.msg_attr), - dst, copy_flags, "\n", - why)) == 0) { +- && (errno != ENOENT +- || make_dirs(tmpdir, 0700) < 0 +- || (dst = vstream_fopen(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == 0)) { +- dsb_simple(why, mbox_dsn(errno, "4.2.0"), +- "create maildir file %s: %m", tmpfile); +- } else if (fstat(vstream_fileno(dst), &st) < 0) { +- +- /* +- * Coverity 200604: file descriptor leak in code that never executes. +- * Code replaced by msg_fatal(), as it is not worthwhile to continue +- * after an impossible error condition. +- */ +- msg_fatal("fstat %s: %m", tmpfile); +- } else { +- vstring_sprintf(buf, "%lu.V%lxI%lxM%lu.%s", +- (unsigned long) starttime.tv_sec, +- (unsigned long) st.st_dev, +- (unsigned long) st.st_ino, +- (unsigned long) starttime.tv_usec, +- get_hostname()); +- newfile = concatenate(newdir, STR(buf), (char *) 0); +- if ((mail_copy_status = mail_copy(COPY_ATTR(state.msg_attr), +- dst, copy_flags, "\n", +- why)) == 0) { - if (sane_link(tmpfile, newfile) < 0 - && (errno != ENOENT - || (make_dirs(curdir, 0700), make_dirs(newdir, 0700)) < 0 @@ -816,251 +891,280 @@ diff -Nru postfix-2.4.0/src/virtual/maildir.c postfix-2.4.0-vda/src/virtual/mail - "create maildir file %s: %m", newfile); - mail_copy_status = MAIL_COPY_STAT_WRITE; - } -+ +- } +- if (unlink(tmpfile) < 0) +- msg_warn("remove %s: %m", tmpfile); ++ && (errno != ENOENT ++ || make_dirs(tmpdir, 0700) < 0 ++ || (dst = vstream_fopen(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == 0)) { ++ dsb_simple(why, mbox_dsn(errno, "4.2.0"), "create maildir file %s: %m", tmpfile); ++ } ++ else if (fstat(vstream_fileno(dst), &st) < 0) { + /* -+ * Add a ",S=" to the newly written file according to the -+ * Maildir++ specifications: http://www.inter7.com/courierimap/README.maildirquota.html -+ * This needs a stat(2) of the tempfile and modification of the -+ * name of the file. ++ * Coverity 200604: file descriptor leak in code that never executes. ++ * Code replaced by msg_fatal(), as it is not worthwhile to continue ++ * after an impossible error condition. + */ -+ if (stat(tmpfile, &statbuf) == 0) { -+ if (n != 0) { -+ saved_size += (long) statbuf.st_size; -+ saved_count++; -+ } -+ if (var_virt_maildir_extended) { -+ /* Append the size of the file to newfile. */ -+ vstring_sprintf(buf, ",S=%ld", (long) statbuf.st_size); -+ newfile = concatenate(newfile, STR(buf), (char *) 0); ++ msg_fatal("fstat %s: %m", tmpfile); ++ } ++ else { ++ vstring_sprintf(buf, "%lu.V%lxI%lxM%lu.%s", ++ (unsigned long) starttime.tv_sec, ++ (unsigned long) st.st_dev, ++ (unsigned long) st.st_ino, ++ (unsigned long) starttime.tv_usec, ++ get_hostname()); ++ newfile = concatenate(newdir, STR(buf), (char *) 0); ++ bkpnewfile = concatenate(STR(buf), (char *) 0); /* Will need it later, if we MOVE to other folders. */ ++ ++ if ((mail_copy_status = mail_copy(COPY_ATTR(state.msg_attr), dst, copy_flags, "\n", why)) == 0) { ++ /* ++ * Add a ",S=" to the newly written file according to the ++ * Maildir++ specifications: http://www.inter7.com/courierimap/README.maildirquota.html ++ * This needs a stat(2) of the tempfile and modification of the ++ * name of the file. ++ */ ++ if (stat(tmpfile, &statbuf) == 0) { ++ if (n != 0) { ++ saved_size += (long) statbuf.st_size; ++ saved_count++; ++ } ++ if (var_virt_maildir_extended) { ++ /* Append the size of the file to newfile. */ ++ vstring_sprintf(buf, ",S=%ld", (long) statbuf.st_size); ++ newfile = concatenate(newfile, STR(buf), (char *) 0); ++ } + } -+ } + -+ /* -+ * Now we have the maildir size in saved_size, compare it to the max -+ * quota value and eventually issue a message that we've overdrawn it. -+ */ -+ if (saved_size > n) { -+ mail_copy_status = MAIL_COPY_STAT_WRITE; -+ if (((long) statbuf.st_size > n) || (var_virt_overquota_bounce)) -+ errno = EFBIG; -+ else -+ errno = EDQUOT; -+ } -+ else { -+ /* Maildirfilter code by rk@demiurg.net. */ -+ if (var_virt_maildir_filter) { -+ if (msg_verbose) -+ msg_info("%s: loading DICT filters", myname); ++ /* ++ * Now we have the maildir size in saved_size, compare it to the max ++ * quota value and eventually issue a message that we've overdrawn it. ++ */ ++ if (saved_size > n) { ++ mail_copy_status = MAIL_COPY_STAT_WRITE; ++ if (((long) statbuf.st_size > n) || (var_virt_overquota_bounce)) ++ errno = EFBIG; ++ else ++ errno = EDQUOT; ++ } ++ else { ++ /* Maildirfilter code by rk@demiurg.net. */ ++ if (var_virt_maildir_filter) { ++ if (msg_verbose) ++ msg_info("%s: loading DICT filters", myname); + +#define STREQUAL(x,y,l) (strncasecmp((x), (y), (l)) == 0 && (y)[l] == 0) +#define MAIL_COPY_STAT_REJECT (1<<3) +#define MAIL_COPY_STAT_DISCARD (1<<4) + -+ /* Read filters. */ -+ filtername = concatenate("regexp:", usr_attr.mailbox, "maildirfilter", (char *) 0); -+ sqlmtime = sql2file(strchr(filtername, '/'), state.msg_attr.user); -+ -+ /* Check if this filter is already registered as dictionary. */ -+ if (msg_verbose) -+ msg_info("%s: checking DICT filters for %s", myname, filtername); ++ /* Read filters. */ ++ filtername = concatenate("regexp:", usr_attr.mailbox, "maildirfilter", (char *) 0); ++ sqlmtime = sql2file(strchr(filtername, '/'), state.msg_attr.user); + -+ if ((FILTERS = dict_handle(filtername))) { ++ /* Check if this filter is already registered as dictionary. */ + if (msg_verbose) -+ msg_info("%s: DICT filter found", myname); ++ msg_info("%s: checking DICT filters for %s", myname, filtername); + -+ /* -+ * If we have mtime in our DICT structure, check it against sqlmtime -+ * and reload the filters if they differ. -+ */ -+ if (FILTERS->mtime > 0 && sqlmtime > 0 && sqlmtime != FILTERS->mtime) { ++ if ((FILTERS = dict_handle(filtername))) { + if (msg_verbose) -+ msg_info("%s: reloading DICT filters (dict_mtime=%ld != sql_mtime=%ld)", -+ myname, FILTERS->mtime, sqlmtime); ++ msg_info("%s: DICT filter found", myname); + -+ dict_unregister(filtername); -+ FILTERS = dict_open(filtername, O_RDONLY, DICT_FLAG_LOCK); -+ dict_register(filtername, FILTERS); -+ FILTERS->mtime = sqlmtime; -+ } -+ } -+ else { -+ if (sqlmtime > 0) { -+ /* Registering filter as new dictionary. */ -+ if (msg_verbose) -+ msg_info("%s: loading DICT filters from %s (mtime=%ld)", -+ myname, filtername, sqlmtime); ++ /* ++ * If we have mtime in our DICT structure, check it against sqlmtime ++ * and reload the filters if they differ. ++ */ ++ if (FILTERS->mtime > 0 && sqlmtime > 0 && sqlmtime != FILTERS->mtime) { ++ if (msg_verbose) ++ msg_info("%s: reloading DICT filters (dict_mtime=%ld != sql_mtime=%ld)", ++ myname, FILTERS->mtime, sqlmtime); + -+ FILTERS = dict_open(filtername, O_RDONLY, DICT_FLAG_LOCK); -+ dict_register(filtername, FILTERS); -+ FILTERS->mtime = sqlmtime; ++ dict_unregister(filtername); ++ FILTERS = dict_open(filtername, O_RDONLY, DICT_FLAG_LOCK); ++ dict_register(filtername, FILTERS); ++ FILTERS->mtime = sqlmtime; ++ } + } -+ } -+ -+ if (FILTERS && (tmpfilter = vstream_fopen(tmpfile, O_RDONLY, 0))) { -+ fltstr = vstring_alloc(1024); -+ header = (char *) malloc(8192); /* !!!INSECURE!!! See 7168-hack below. */ -+ header[0] = 0; -+ vstring_get_nonl_bound(fltstr, tmpfilter, 1023); -+ header = concatenate(header, STR(fltstr), (char *) 0); -+ -+ while(!vstream_feof(tmpfilter) && fltstr->vbuf.data[0] && strlen(header) < 7168 ) { -+ vstring_get_nonl_bound(fltstr, tmpfilter, 1023); -+ /* Glue multiline headers, replacing leading TAB with space. */ -+ if (msg_verbose) -+ msg_info("%s: fltstr value: %s", myname, STR(fltstr)); ++ else { ++ if (sqlmtime > 0) { ++ /* Registering filter as new dictionary. */ ++ if (msg_verbose) ++ msg_info("%s: loading DICT filters from %s (mtime=%ld)", ++ myname, filtername, sqlmtime); + -+ if (fltstr->vbuf.data[0] == ' ' || fltstr->vbuf.data[0] == '\t' ) { -+ if (fltstr->vbuf.data[0] == '\t') -+ fltstr->vbuf.data[0] = ' '; -+ header = concatenate(header, STR(fltstr), (char *) 0); -+ } -+ else { -+ header = concatenate(header, "\n", STR(fltstr), (char *) 0); ++ FILTERS = dict_open(filtername, O_RDONLY, DICT_FLAG_LOCK); ++ dict_register(filtername, FILTERS); ++ FILTERS->mtime = sqlmtime; + } + } + -+ if (msg_verbose) -+ msg_info("%s: checking filter CMD for %s", myname, filtername); ++ if (FILTERS && (tmpfilter = vstream_fopen(tmpfile, O_RDONLY, 0))) { ++ fltstr = vstring_alloc(1024); ++ header = (char *) malloc(8192); /* !!!INSECURE!!! See 7168-hack below. */ ++ header[0] = 0; ++ vstring_get_nonl_bound(fltstr, tmpfilter, 1023); ++ header = concatenate(header, STR(fltstr), (char *) 0); + -+ /* Check whole header part with regexp maps. */ -+ if ((value = dict_get(FILTERS, lowercase(header))) != 0) { -+ if (msg_verbose) -+ msg_info("%s: preparing filter CMD", myname); ++ while(!vstream_feof(tmpfilter) && fltstr->vbuf.data[0] && strlen(header) < 7168 ) { ++ vstring_get_nonl_bound(fltstr, tmpfilter, 1023); ++ /* Glue multiline headers, replacing leading TAB with space. */ ++ if (msg_verbose) ++ msg_info("%s: fltstr value: %s", myname, STR(fltstr)); + -+ cmd_text = value + strcspn(value, " \t"); -+ cmd_len = cmd_text - value; -+ while (*cmd_text && ISSPACE(*cmd_text)) -+ cmd_text++; ++ if (fltstr->vbuf.data[0] == ' ' || fltstr->vbuf.data[0] == '\t' ) { ++ if (fltstr->vbuf.data[0] == '\t') ++ fltstr->vbuf.data[0] = ' '; ++ header = concatenate(header, STR(fltstr), (char *) 0); ++ } ++ else { ++ header = concatenate(header, "\n", STR(fltstr), (char *) 0); ++ } ++ } + + if (msg_verbose) -+ msg_info("%s: executing filter CMD", myname); ++ msg_info("%s: checking filter CMD for %s", myname, filtername); + -+ if (STREQUAL(value, "REJECT", cmd_len)) { ++ /* Check whole header part with regexp maps. */ ++ if ((value = dict_get(FILTERS, lowercase(header))) != 0) { + if (msg_verbose) -+ msg_info("%s: executing filter CMD REJECT", myname); ++ msg_info("%s: preparing filter CMD", myname); + -+ mail_copy_status = MAIL_COPY_STAT_REJECT; -+ vstring_sprintf(why->reason, "%s", cmd_text); -+ dsb_simple(why, "5.0.0", "User filter - REJECT"); -+ } ++ cmd_text = value + strcspn(value, " \t"); ++ cmd_len = cmd_text - value; ++ while (*cmd_text && ISSPACE(*cmd_text)) ++ cmd_text++; + -+ if (STREQUAL(value, "DISCARD", cmd_len)) { + if (msg_verbose) -+ msg_info("%s: executing filter CMD DISCARD", myname); ++ msg_info("%s: executing filter CMD", myname); + -+ mail_copy_status = MAIL_COPY_STAT_DISCARD; -+ vstring_sprintf(why->reason, "%s", cmd_text); -+ dsb_simple(why, "5.0.0", "User filter - DISCARD"); -+ } ++ if (STREQUAL(value, "REJECT", cmd_len)) { ++ if (msg_verbose) ++ msg_info("%s: executing filter CMD REJECT", myname); + -+ if (STREQUAL(value, "MOVE", cmd_len)) { -+ if (msg_verbose) -+ msg_info("%s: executing filter CMD MOVE", myname); ++ mail_copy_status = MAIL_COPY_STAT_REJECT; ++ vstring_sprintf(why->reason, "%s", cmd_text); ++ dsb_simple(why, "5.0.0", "User filter - REJECT"); ++ } + -+ strcut((char *) cmd_text, " "); -+ strcut((char *) cmd_text, "\t"); -+ strcut((char *) cmd_text, "/"); -+ strcut((char *) cmd_text, ".."); ++ if (STREQUAL(value, "DISCARD", cmd_len)) { ++ if (msg_verbose) ++ msg_info("%s: executing filter CMD DISCARD", myname); + -+ if (*var_virt_maildir_suffix == 0) { -+ newfile = concatenate(usr_attr.mailbox, (char *) 0); -+ } -+ else { -+ newfile = concatenate(usr_attr.mailbox, var_virt_maildir_suffix, (char *) 0); ++ mail_copy_status = MAIL_COPY_STAT_DISCARD; ++ vstring_sprintf(why->reason, "%s", cmd_text); ++ dsb_simple(why, "5.0.0", "User filter - DISCARD"); + } + -+ if (cmd_text[0] != '.') { -+ newfile = concatenate(newfile, ".", (char *) 0); ++ if (STREQUAL(value, "MOVE", cmd_len)) { ++ if (msg_verbose) ++ msg_info("%s: executing filter CMD MOVE", myname); ++ ++ strcut((char *) cmd_text, " "); ++ strcut((char *) cmd_text, "\t"); ++ strcut((char *) cmd_text, "/"); ++ strcut((char *) cmd_text, ".."); ++ ++ if (*var_virt_maildir_suffix == 0) { ++ newfile = concatenate(usr_attr.mailbox, (char *) 0); ++ } ++ else { ++ newfile = concatenate(usr_attr.mailbox, var_virt_maildir_suffix, (char *) 0); ++ } ++ ++ if (cmd_text[0] != '.') { ++ newfile = concatenate(newfile, ".", (char *) 0); ++ } ++ newdir = concatenate(newfile, cmd_text, "/", "new/", (char *) 0); ++ tmpdir = concatenate(newfile, cmd_text, "/", "tmp/", (char *) 0); ++ curdir = concatenate(newfile, cmd_text, "/", "cur/", (char *) 0); ++ newfile = concatenate(newfile, cmd_text, "/", "new/", bkpnewfile, (char *) 0); + } -+ newdir = concatenate(newfile, cmd_text, "/", "new/", (char *) 0); -+ tmpdir = concatenate(newfile, cmd_text, "/", "tmp/", (char *) 0); -+ curdir = concatenate(newfile, cmd_text, "/", "cur/", (char *) 0); -+ newfile = concatenate(newfile, cmd_text, "/", "new/", bkpnewfile, (char *) 0); -+ } -+ -+ if (STREQUAL(value, "LOG", cmd_len) || STREQUAL(value, "WARN", cmd_len)) { -+ msg_warn("%s: header check warning: %s", myname, cmd_text); -+ } + -+ if (STREQUAL(value, "INFO", cmd_len)) { -+ msg_info("%s: header check info: %s", myname, cmd_text); -+ } -+ -+ if (msg_verbose) -+ msg_info("%s: exiting filter CMD", myname); -+ } /* End-Of-Check */ ++ if (STREQUAL(value, "LOG", cmd_len) || STREQUAL(value, "WARN", cmd_len)) { ++ msg_warn("%s: header check warning: %s", myname, cmd_text); ++ } + -+ myfree(header); -+ vstring_free(fltstr); -+ vstream_fclose(tmpfilter); -+ } -+ myfree(filtername); -+ } /* End-Of-Maildirfilter */ -+ -+ /* Deliver to curdir. */ -+ if (mail_copy_status == 0) { -+ if (sane_link(tmpfile, newfile) < 0 -+ && (errno != ENOENT -+ || (make_dirs(curdir, 0700), make_dirs(newdir, 0700), make_dirs(tmpdir,0700)) < 0 -+ || sane_link(tmpfile, newfile) < 0)) { -+ dsb_simple(why, mbox_dsn(errno, "4.2.0"), "create maildir file %s: %m", newfile); -+ mail_copy_status = MAIL_COPY_STAT_WRITE; -+ } ++ if (STREQUAL(value, "INFO", cmd_len)) { ++ msg_info("%s: header check info: %s", myname, cmd_text); ++ } + -+ if (var_virt_create_maildirsize) { -+ time(&tm); ++ if (msg_verbose) ++ msg_info("%s: exiting filter CMD", myname); ++ } /* End-Of-Check */ + -+ if (*var_virt_maildir_suffix == 0) { -+ sizefilename = concatenate(usr_attr.mailbox, "maildirsize", (char *) 0); -+ } -+ else { -+ sizefilename = concatenate(usr_attr.mailbox, var_virt_maildir_suffix, (char *) 0); -+ sizefilename = concatenate(sizefilename, "maildirsize", (char *) 0); ++ myfree(header); ++ vstring_free(fltstr); ++ vstream_fclose(tmpfilter); + } + -+ /* Check if the quota in the file is the same as the current one, if not, delete the file. */ -+ sizefile = vstream_fopen(sizefilename, O_RDONLY, 0); -+ if (sizefile) { -+ filequota = vstring_alloc(128); -+ vstring_get_null_bound(filequota, sizefile, 127); -+ vstream_fclose(sizefile); -+ if (atol(vstring_export(filequota)) != n) -+ unlink(sizefilename); ++ myfree(filtername); ++ } /* End-Of-Maildirfilter */ ++ ++ /* Deliver to curdir. */ ++ if (mail_copy_status == 0) { ++ if (sane_link(tmpfile, newfile) < 0 ++ && (errno != ENOENT ++ || (make_dirs(curdir, 0700), make_dirs(newdir, 0700), make_dirs(tmpdir,0700)) < 0 ++ || sane_link(tmpfile, newfile) < 0)) { ++ dsb_simple(why, mbox_dsn(errno, "4.2.0"), "create maildir file %s: %m", newfile); ++ mail_copy_status = MAIL_COPY_STAT_WRITE; + } + -+ /* Open maildirsize file to append this transaction. */ -+ sizefile = vstream_fopen(sizefilename, O_WRONLY | O_APPEND, 0640); ++ if (var_virt_create_maildirsize) { ++ time(&tm); + -+ /* If the open fails (maildirsize doesn't exist), or it's too large, or too old, overwrite it. */ -+ if(!sizefile || (stat(sizefilename, &sizefile_stat) < 0) || (sizefile_stat.st_size > SIZEFILE_MAX) || (sizefile_stat.st_mtime + 30*60 < tm)) { -+ /* If the file exists, sizefile has been opened above, so close it first. */ -+ if (sizefile) { -+ vstream_fclose(sizefile); -+ sizefile = vstream_fopen(sizefilename, O_WRONLY | O_TRUNC, 0640); ++ if (*var_virt_maildir_suffix == 0) { ++ sizefilename = concatenate(usr_attr.mailbox, "maildirsize", (char *) 0); + } + else { -+ sizefile = vstream_fopen(sizefilename, O_WRONLY | O_CREAT, 0640); ++ sizefilename = concatenate(usr_attr.mailbox, var_virt_maildir_suffix, (char *) 0); ++ sizefilename = concatenate(sizefilename, "maildirsize", (char *) 0); + } + -+ /* If the creation worked, write to the file, otherwise just give up. */ ++ /* Check if the quota in the file is the same as the current one, if not, delete the file. */ ++ sizefile = vstream_fopen(sizefilename, O_RDONLY, 0); + if (sizefile) { -+ vstream_fprintf(sizefile, "%ldS\n%ld %ld\n", n, saved_size, saved_count); ++ filequota = vstring_alloc(128); ++ vstring_get_null_bound(filequota, sizefile, 127); ++ vstream_fclose(sizefile); ++ if (atol(vstring_export(filequota)) != n) ++ unlink(sizefilename); ++ } ++ ++ /* Open maildirsize file to append this transaction. */ ++ sizefile = vstream_fopen(sizefilename, O_WRONLY | O_APPEND, 0640); ++ ++ /* If the open fails (maildirsize doesn't exist), or it's too large, or too old, overwrite it. */ ++ if(!sizefile || (stat(sizefilename, &sizefile_stat) < 0) || (sizefile_stat.st_size > SIZEFILE_MAX) || (sizefile_stat.st_mtime + 15*60 < tm)) { ++ /* If the file exists, sizefile has been opened above, so close it first. */ ++ if (sizefile) { ++ vstream_fclose(sizefile); ++ sizefile = vstream_fopen(sizefilename, O_WRONLY | O_TRUNC, 0640); ++ } ++ else { ++ sizefile = vstream_fopen(sizefilename, O_WRONLY | O_CREAT, 0640); ++ } ++ ++ /* If the creation worked, write to the file, otherwise just give up. */ ++ if (sizefile) { ++ vstream_fprintf(sizefile, "%ldS\n%ld %ld\n", n, saved_size, saved_count); ++ vstream_fclose(sizefile); ++ } ++ } ++ else { ++ /* We opened maildirsize, so let's just append this transaction and close it. */ ++ vstream_fprintf(sizefile, "%ld 1\n", (long) statbuf.st_size); + vstream_fclose(sizefile); + } -+ } -+ else { -+ /* We opened maildirsize, so let's just append this transaction and close it. */ -+ vstream_fprintf(sizefile, "%ld 1\n", (long) statbuf.st_size); -+ vstream_fclose(sizefile); + } + } + } + } -+ - } - if (unlink(tmpfile) < 0) - msg_warn("remove %s: %m", tmpfile); -@@ -223,31 +873,56 @@ ++ if (unlink(tmpfile) < 0) ++ msg_warn("remove %s: %m", tmpfile); + } + set_eugid(var_owner_uid, var_owner_gid); + +@@ -223,31 +872,57 @@ * location possibly under user control. */ if (mail_copy_status & MAIL_COPY_STAT_CORRUPT) { @@ -1083,7 +1187,7 @@ diff -Nru postfix-2.4.0/src/virtual/maildir.c postfix-2.4.0-vda/src/virtual/mail - deliver_status = sent(BOUNCE_FLAGS(state.request), - SENT_ATTR(state.msg_attr)); + deliver_status = DEL_STAT_DEFER; -+ } + } + else if (mail_copy_status != 0) { + if (errno == EACCES) { + msg_warn("maildir access problem for UID/GID=%lu/%lu: %s", @@ -1118,7 +1222,7 @@ diff -Nru postfix-2.4.0/src/virtual/maildir.c postfix-2.4.0-vda/src/virtual/mail + deliver_status = + (STR(why->status)[0] == '4' ? defer_append : bounce_append) + (BOUNCE_FLAGS(state.request), BOUNCE_ATTR(state.msg_attr)); - } ++ } + else { + dsb_simple(why, "2.0.0", "delivered to maildir"); + deliver_status = sent(BOUNCE_FLAGS(state.request), SENT_ATTR(state.msg_attr)); @@ -1134,6 +1238,7 @@ diff -Nru postfix-2.4.0/src/virtual/maildir.c postfix-2.4.0-vda/src/virtual/mail if (newfile) - myfree(newfile); + myfree(newfile); ++ return (deliver_status); } diff -Nru postfix-2.4.0/src/virtual/virtual.c postfix-2.4.0-vda/src/virtual/virtual.c -- cgit v1.2.3-65-gdbad