summaryrefslogtreecommitdiff
path: root/core/s-nail/maildir.patch
diff options
context:
space:
mode:
Diffstat (limited to 'core/s-nail/maildir.patch')
-rw-r--r--core/s-nail/maildir.patch253
1 files changed, 253 insertions, 0 deletions
diff --git a/core/s-nail/maildir.patch b/core/s-nail/maildir.patch
new file mode 100644
index 000000000..d9b16c348
--- /dev/null
+++ b/core/s-nail/maildir.patch
@@ -0,0 +1,253 @@
+s-nail-14_5_2-maildir.patch, 2014-02-10:
+
+Apply:
+ $ cd s-nail-14.5.2
+ $ patch -bu < s-nail-14_5_2-maildir.patch
+
+Description:
+ To overcome a general design problem of the Berkeley Mail codebase
+ i once added realpath(3) calls to be able to resolve the path of
+ a mailbox file: like that changing a directory wouldn't cause the
+ program to "hang" because the (relatively) opened mailbox became
+ inaccessible. (Again: the real solution will take many years.)
+
+ My first KISS solution to one aspect of the general problem was
+ [3adf33ee] (schdir(): realpath() local files before leaving CWD..,
+ 2013-01-08), and it should possibly have worked with maildir boxes,
+ because we'd only did anything once the user actively used the `chdir'
+ command (and who does), but Christos Zoulas from NetBSD actually forced
+ me to do more (after i've reported the general Berkeley bug), and that
+ led to the current code, which always calls realpath(3).
+ Anyway, i wasn't in the position to reflect the impact of doing so at
+ that time. And the entire codebase needs to be reworked anyway. (:(
+
+ Anyway -- this patch is an adjusted combination of the [1c2563b]
+ (lex.c:_update_mailname(): continue if realname() fails.., 2014-02-10)
+ and [13f325f] (Avoid "cannot canonicalize" maildir warning.., 2014-02-10)
+ changesets that have been pushed to [master], and make maildir mailboxes
+ usable again.
+
+Notes:
+ The patch is so large because it was cherry-picked from [crawl] onto
+ [master] and (thus) includes the very large [nyd] topic branch style-and-
+ much-more changes. Sorry for that.
+
+ lex.c | 11 +++--
+ maildir.c | 152 +++++++++++++++++++++++++++++++++-----------------------------
+ 2 files changed, 87 insertions(+), 76 deletions(-)
+
+diff --git a/lex.c b/lex.c
+index 922faf8..3b3b3cc 100644
+--- a/lex.c
++++ b/lex.c
+@@ -164,7 +164,7 @@ _update_mailname(char const *name)
+ {
+ char tbuf[MAXPATHLEN], *mailp, *dispp;
+ size_t i, j;
+- bool_t rv;
++ bool_t rv = TRU1;
+
+ /* Don't realpath(3) if it's only an update request */
+ if (name != NULL) {
+@@ -174,9 +174,10 @@ _update_mailname(char const *name)
+ if (realpath(name, mailname) == NULL) {
+ fprintf(stderr, tr(151, "Can't canonicalize `%s'\n"), name);
+ rv = FAL0;
+- goto jleave;
++ goto jdocopy;
+ }
+ } else
++jdocopy:
+ #endif
+ n_strlcpy(mailname, name, sizeof(mailname));
+ }
+@@ -197,9 +198,10 @@ _update_mailname(char const *name)
+
+ /* We want to see the name of the folder .. on the screen */
+ i = strlen(mailp);
+- if ((rv = (i < sizeof(displayname) - 1)))
++ if (i < sizeof(displayname) - 1)
+ memcpy(dispp, mailp, i + 1);
+ else {
++ rv = FAL0;
+ /* Avoid disrupting multibyte sequences (if possible) */
+ #ifndef HAVE_C90AMEND1
+ j = sizeof(displayname) / 3 - 1;
+@@ -212,9 +214,6 @@ _update_mailname(char const *name)
+ snprintf(dispp, sizeof(displayname), "%.*s...%s",
+ (int)j, mailp, mailp + i);
+ }
+-#ifdef HAVE_REALPATH
+-jleave:
+-#endif
+ return rv;
+ }
+
+diff --git a/maildir.c b/maildir.c
+index 32180bd..3d45f77 100644
+--- a/maildir.c
++++ b/maildir.c
+@@ -1,5 +1,5 @@
+ /*@ S-nail - a mail user agent derived from Berkeley Mail.
+- *@ Maildir folder support.
++ *@ Maildir folder support. FIXME rewrite - why do we chdir(2)??
+ *
+ * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
+ * Copyright (c) 2012 - 2014 Steffen "Daode" Nurpmeso <sdaoden@users.sf.net>.
+@@ -101,75 +101,87 @@ jleave: ;
+ FL int
+ maildir_setfile(char const * volatile name, int nmail, int isedit)
+ {
+- sighandler_type volatile saveint;
+- struct cw cw;
+- int i = -1, omsgCount;
+-
+- (void)&saveint;
+- (void)&i;
+- omsgCount = msgCount;
+- if (cwget(&cw) == STOP) {
+- fprintf(stderr, "Fatal: Cannot open current directory\n");
+- return -1;
+- }
+- if (!nmail)
+- quit();
+- saveint = safe_signal(SIGINT, SIG_IGN);
+- if (chdir(name) < 0) {
+- fprintf(stderr, "Cannot change directory to \"%s\".\n", name);
+- cwrelse(&cw);
+- return -1;
+- }
+- if (!nmail) {
+- edit = (isedit != 0);
+- if (mb.mb_itf) {
+- fclose(mb.mb_itf);
+- mb.mb_itf = NULL;
+- }
+- if (mb.mb_otf) {
+- fclose(mb.mb_otf);
+- mb.mb_otf = NULL;
+- }
+- initbox(name);
+- mb.mb_type = MB_MAILDIR;
+- }
+- _maildir_table = NULL;
+- if (sigsetjmp(_maildir_jmp, 1) == 0) {
+- if (nmail)
+- mktable();
+- if (saveint != SIG_IGN)
+- safe_signal(SIGINT, maildircatch);
+- i = maildir_setfile1(name, nmail, omsgCount);
+- }
+- if (nmail && _maildir_table != NULL)
+- free(_maildir_table);
+- safe_signal(SIGINT, saveint);
+- if (i < 0) {
+- mb.mb_type = MB_VOID;
+- *mailname = '\0';
+- msgCount = 0;
+- }
+- if (cwret(&cw) == STOP) {
+- fputs("Fatal: Cannot change back to current directory.\n",
+- stderr);
+- abort();
+- }
+- cwrelse(&cw);
+- setmsize(msgCount);
+- if (nmail && mb.mb_sorted && msgCount > omsgCount) {
+- mb.mb_threaded = 0;
+- sort((void *)-1);
+- }
+- if (!nmail)
+- sawcom = FAL0;
+- if (!nmail && !edit && msgCount == 0) {
+- if (mb.mb_type == MB_MAILDIR && !ok_blook(emptystart))
+- fprintf(stderr, "No mail at %s\n", name);
+- return 1;
+- }
+- if (nmail && msgCount > omsgCount)
+- newmailinfo(omsgCount);
+- return 0;
++ sighandler_type volatile saveint;
++ struct cw cw;
++ int i = -1, omsgCount;
++
++ /* TODO ince we have a VOID box... */
++ omsgCount = msgCount;
++ if (cwget(&cw) == STOP) {
++ fprintf(stderr, "Cannot open current directory");
++ goto jleave;
++ }
++
++ if (!nmail)
++ quit();
++
++ saveint = safe_signal(SIGINT, SIG_IGN);
++
++ if (!nmail) {
++ edit = (isedit != 0);
++ if (mb.mb_itf) {
++ fclose(mb.mb_itf);
++ mb.mb_itf = NULL;
++ }
++ if (mb.mb_otf) {
++ fclose(mb.mb_otf);
++ mb.mb_otf = NULL;
++ }
++ initbox(name);
++ mb.mb_type = MB_MAILDIR;
++ }
++
++ if (chdir(name) < 0) {
++ fprintf(stderr, "Cannot change directory to \"%s\".\n", name);/*TODO tr*/
++ mb.mb_type = MB_VOID;
++ *mailname = '\0';
++ msgCount = 0;
++ cwrelse(&cw);
++ safe_signal(SIGINT, saveint);
++ goto jleave;
++ }
++
++ _maildir_table = NULL;
++ if (sigsetjmp(_maildir_jmp, 1) == 0) {
++ if (nmail)
++ mktable();
++ if (saveint != SIG_IGN)
++ safe_signal(SIGINT, &maildircatch);
++ i = maildir_setfile1(name, nmail, omsgCount);
++ }
++ if (nmail && _maildir_table != NULL)
++ free(_maildir_table);
++
++ safe_signal(SIGINT, saveint);
++
++ if (i < 0) {
++ mb.mb_type = MB_VOID;
++ *mailname = '\0';
++ msgCount = 0;
++ }
++
++ if (cwret(&cw) == STOP)
++ panic("Cannot change back to current directory.");/* TODO tr */
++ cwrelse(&cw);
++
++ setmsize(msgCount);
++ if (nmail && mb.mb_sorted && msgCount > omsgCount) {
++ mb.mb_threaded = 0;
++ sort((void*)-1);
++ }
++ if (!nmail)
++ sawcom = FAL0;
++ if (!nmail && !edit && msgCount == 0) {
++ if (mb.mb_type == MB_MAILDIR /* XXX ?? */ && !ok_blook(emptystart))
++ fprintf(stderr, tr(258, "No mail at %s\n"), name);
++ i = 1;
++ goto jleave;
++ }
++ if (nmail && msgCount > omsgCount)
++ newmailinfo(omsgCount);
++ i = 0;
++jleave:
++ return i;
+ }
+
+ static int