From 975e68699e4a3486f75fcd7f22ca5205549cf43c Mon Sep 17 00:00:00 2001 From: "Steffen (Daode) Nurpmeso" Date: Sat, 26 Nov 2016 16:49:31 +0100 Subject: [PATCH] (BWDIC!) Only rm sysboxes, unless *posix* (Walter A. Iglesias, trondd).. I think it is pretty weird behaviour to implicitly remove empty mailbox files, especially so since we don't remove empty Maildir etc. boxes, but only MBOX files. The old Heirloom code had an *emptybox* variable which restricted the standard *keep* variable for secondary and MBOX files, making that responsible solely for system boxes. But that is not standard conformant, so i obsoleted it in, i think, early 2015. Coming back to this after seeing a thread of Walter Alejandro and trondd on misc@openbsd.org, i think the only sane behaviour is not to remove any file by default. However, we need to for system boxes, so let's just keep the *keep*<->sysbox relationship, but never remove any other MBOX mailbox unless *posix* is set, in which case *keep* will also cover those. In v15 we should have "VFS" and should be able to cover also other mailbox types. Maybe at that time we will add a *keep-other* or whatever to reintroduce explicit behaviour, but the other way around, as in *rm-secondary*, would be better. Or such. --- nail.1 | 25 ++++++++++++++------- nail.h | 1 - nail.rc | 3 ++- quit.c | 78 ++++++++++++++++++++++++++++++----------------------------------- 4 files changed, 55 insertions(+), 52 deletions(-) diff --git a/nail.1 b/nail.1 index aa1ddf4c..234abe51 100644 --- a/nail.1 +++ b/nail.1 @@ -687,11 +687,15 @@ that would otherwise occur (see .Sx "Message states" ) , and .Va keep -to not remove empty files in order not to mangle file permissions when -files eventually get recreated (\*(UA actively manages the file mode -creation mask via -.Va umask -upon program startup). +to not remove empty system (MBOX) mailbox files in order not to mangle +file permissions when files eventually get recreated; be aware that +\*(UA will (try to) remove all empty (MBOX) mailbox files unless this +variable is set in case +.Va posix +.Pf ( Ev POSIXLY_CORRECT ) +mode has been enabled. +The file mode creation mask is explicitly managed via +.Va umask . . .Pp It also enables @@ -6863,12 +6867,17 @@ Be sure to quote the value if it contains spaces or tabs. . .Mx .It Va keep -\*(BO If set, an empty mailbox file is not removed. +\*(BO If set, an empty system (MBOX) mailbox file is not removed. +Note that, in conjunction with +.Va posix +(and, thus, +.Ev POSIXLY_CORRECT ) +any empty file will be removed unless this variable is set. This may improve the interoperability with other mail user agents when using a common folder directory, and prevents malicious users from creating fake mailboxes in a world-writable spool directory. -Note this only applies to local regular (MBOX) files, other mailbox -types will never be removed. +\*(ID Only local regular (MBOX) files are covered, Maildir or other +mailbox types will never be removed, even if empty. . .Mx .It Va keep-content-length diff --git a/nail.h b/nail.h index 93273231..fa42bd65 100644 --- a/nail.h +++ b/nail.h @@ -1513,7 +1513,6 @@ ok_b_autothread, ok_v_EDITOR, /* {env=1,defval=VAL_EDITOR} */ ok_b_editalong, ok_b_editheaders, -ok_b_emptybox, ok_b_emptystart, ok_v_encoding, ok_v_escape, diff --git a/nail.rc b/nail.rc index 69f035a0..427591e1 100644 --- a/nail.rc +++ b/nail.rc @@ -111,7 +111,8 @@ set mime-counter-evidence=0xE # if the value contains an equal sign "=", see the manual for more #set mimetypes-load-control -# Do not remove empty mail folders. +# Do not remove empty (MBOX) system mailboxes (or _no_ empty (MBOX) mailbox +# at all if $POSIXLY_CORRECT / *posix* are set!). # This may be relevant for privacy since other users could otherwise create # them with different permissions set keep diff --git a/quit.c b/quit.c index 8c653f79..96a6732b 100644 --- a/quit.c +++ b/quit.c @@ -45,8 +45,7 @@ enum quitflags { QUITFLAG_HOLD = 1<<0, QUITFLAG_KEEP = 1<<1, QUITFLAG_KEEPSAVE = 1<<2, - QUITFLAG_APPEND = 1<<3, - QUITFLAG_EMPTYBOX = 1<<4 + QUITFLAG_APPEND = 1<<3 }; struct quitnames { @@ -58,8 +57,7 @@ static struct quitnames const _quitnames[] = { {QUITFLAG_HOLD, ok_b_hold}, {QUITFLAG_KEEP, ok_b_keep}, {QUITFLAG_KEEPSAVE, ok_b_keepsave}, - {QUITFLAG_APPEND, ok_b_append}, - {QUITFLAG_EMPTYBOX, ok_b_emptybox} /* TODO obsolete emptybox */ + {QUITFLAG_APPEND, ok_b_append} }; static char _mboxname[PATH_MAX]; /* Name of mbox */ @@ -76,9 +74,6 @@ static int writeback(FILE *res, FILE *obuf); * the temporary. Save any new stuff appended to the file */ static bool_t edstop(void); -/* Remove "mailname", unless *keep* says otherwise; force truncation, then */ -static void _demail(void); - static void _alter(char const *name) /* TODO error handling */ { @@ -202,7 +197,6 @@ edstop(void) /* TODO oh my god */ } if ((ibuf = Zopen(mailname, "r")) == NULL) { n_perr(mailname, 0); - Fclose(obuf); goto jleave; } @@ -213,16 +207,17 @@ edstop(void) /* TODO oh my god */ Fclose(ibuf); ibuf = obuf; fflush_rewind(obuf); + /*obuf = NULL;*/ } printf(_("%s "), n_shexp_quote_cp(displayname, FAL0)); fflush(stdout); if ((obuf = Zopen(mailname, "r+")) == NULL) { - n_perr(mailname, 0); + int e = errno; + n_perr(n_shexp_quote_cp(mailname, FAL0), e); goto jleave; } - n_file_lock(fileno(obuf), FLT_WRITE, 0,0, UIZ_MAX); /* TODO ign. lock err! */ ftrunc(obuf); @@ -233,8 +228,8 @@ edstop(void) /* TODO oh my god */ continue; ++c; if (sendmp(mp, obuf, NULL, NULL, SEND_MBOX, NULL) < 0) { - n_perr(mailname, 0); srelax_rele(); + n_err(_("Failed to finalize %s\n"), n_shexp_quote_cp(mailname, FAL0)); goto jleave; } srelax(); @@ -248,32 +243,35 @@ edstop(void) /* TODO oh my god */ } fflush(obuf); if (ferror(obuf)) { - n_perr(mailname, 0); + n_err(_("Failed to finalize %s\n"), n_shexp_quote_cp(mailname, FAL0)); goto jleave; } - Fclose(obuf); - if (gotcha && !ok_blook(keep) && !ok_blook(emptybox)/* TODO obsolete eb*/) { - bool_t rms; + if(gotcha){ + /* Non-system boxes are never removed except forced via POSIX mode */ +#ifdef HAVE_FTRUNCATE + ftruncate(fileno(obuf), 0); +#else + int fd; - if ((rms = n_path_rm(mailname)) == TRU1) - printf((ok_blook(bsdcompat) || ok_blook(bsdmsgs)) - ? _("removed\n") : _("removed.\n")); - else { - int e = errno; + if((fd = open(mailname, (O_WRONLY | O_CREAT | n_O_NOFOLLOW | O_TRUNC), + 0600)) != -1) + close(fd); +#endif - printf(_("removal error (ignored)\n")); - n_err(_("Error removing %s (ignored):"), - n_shexp_quote_cp(mailname, FAL0)); /* TODO */ - n_perr(NULL, e); /* TODO */ - } + if(ok_blook(posix) && !ok_blook(keep) && n_path_rm(mailname)) + fputs(_("removed\n"), stdout); + else + fputs(_("truncated\n"), stdout); } else - printf((ok_blook(bsdcompat) || ok_blook(bsdmsgs)) - ? _("complete\n") : _("updated.\n")); + fputs((ok_blook(bsdcompat) || ok_blook(bsdmsgs)) + ? _("complete\n") : _("updated.\n"), stdout); fflush(stdout); rv = TRU1; jleave: + if (obuf != NULL) + Fclose(obuf); if (ibuf != NULL) Fclose(ibuf); if(!rv){ @@ -289,20 +287,6 @@ j_leave: return rv; } -static void -_demail(void) /* TODO error handling */ -{ - NYD2_ENTER; - if (ok_blook(keep) || n_path_rm(mailname) <= FAL0) { - /* TODO demail(): try use f?truncate(2) instead?! */ - int fd = open(mailname, (O_WRONLY | O_CREAT | n_O_NOFOLLOW | O_TRUNC), - 0600); - if (fd >= 0) - close(fd); - } - NYD2_LEAVE; -} - FL bool_t quit(bool_t hold_sigs_on) { @@ -456,7 +440,17 @@ jcream: _alter(mailname); rv = TRU1; } else { - _demail(); +#ifdef HAVE_FTRUNCATE + ftruncate(fileno(fbuf), 0); +#else + int fd; + + if((fd = open(mailname, (O_WRONLY | O_CREAT | n_O_NOFOLLOW | O_TRUNC), + 0600)) != -1) + close(fd); +#endif + if(!ok_blook(keep)) + n_path_rm(mailname); rv = TRU1; } jleave: -- 2.11.4.GIT