summaryrefslogtreecommitdiff
path: root/core/s-nail/maildir.patch
blob: d9b16c348f99d1b052c95d8cb3b5201209c21718 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
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