updated on Thu Jan 26 16:09:46 UTC 2012
[aur-mirror.git] / mutt-great-dane / mutt-write_postponed.patch
blobd25760d146f6153217150d44b37d3b6f40acc8ea
1 Create mutt_write_postponed, de-bastardize mutt_write_fcc
3 This patch breaks the postponement code out of mutt_write_fcc. To
4 prevent duplicating lots of code between the functions, there are
5 a couple of new static functions: mutt_start_message and
6 mutt_finish_message.
8 In the process, a few bugs are fixed:
10 * Calculate lines and content-length prior to mx_open_new_message.
11 That way the error path doesn't have to abort a partly written
12 message, removing this questionable line of code:
13 mx_commit_message (msg, &f); /* XXX - really? */
15 * Call set_noconv_flags in the error path of mutt_write_postponed.
16 Previously it was only called in the success path.
18 * Don't write "Status: RO" on postponed messages.
20 Signed-off-by: Aron Griffis <agriffis@n01se.net>
22 diff -r 962bfe47cc13 -r bffd60d2ac16 compose.c
23 --- a/compose.c Mon Apr 27 18:53:40 2009 -0400
24 +++ b/compose.c Tue Apr 28 11:17:28 2009 -0400
25 @@ -1203,7 +1203,7 @@
26 if (msg->content->next)
27 msg->content = mutt_make_multipart (msg->content);
29 - if (mutt_write_fcc (fname, msg, NULL, 0, NULL) < 0)
30 + if (mutt_write_fcc (fname, msg) < 0)
31 msg->content = mutt_remove_multipart (msg->content);
32 else
33 mutt_message _("Message written.");
34 diff -r 962bfe47cc13 -r bffd60d2ac16 protos.h
35 --- a/protos.h Mon Apr 27 18:53:40 2009 -0400
36 +++ b/protos.h Tue Apr 28 11:17:28 2009 -0400
37 @@ -362,7 +362,8 @@
38 void mutt_update_num_postponed (void);
39 int mutt_wait_filter (pid_t);
40 int mutt_which_case (const char *);
41 -int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int, char *);
42 +int mutt_write_fcc (const char *path, HEADER *hdr);
43 +int mutt_write_postponed (const char *path, HEADER *hdr, const char *msgid, char *fcc);
44 int mutt_write_mime_body (BODY *, FILE *);
45 int mutt_write_mime_header (BODY *, FILE *);
46 int mutt_write_one_header (FILE *fp, const char *tag, const char *value, const char *pfx, int wraplen, int flags);
47 diff -r 962bfe47cc13 -r bffd60d2ac16 send.c
48 --- a/send.c Mon Apr 27 18:53:40 2009 -0400
49 +++ b/send.c Tue Apr 28 11:17:28 2009 -0400
50 @@ -1553,7 +1540,7 @@
51 mutt_prepare_envelope (msg->env, 0);
52 mutt_env_to_idna (msg->env, NULL, NULL); /* Handle bad IDNAs the next time. */
54 - if (!Postponed || mutt_write_fcc (NONULL (Postponed), msg, (cur && (flags & SENDREPLY)) ? cur->env->message_id : NULL, 1, fcc) < 0)
55 + if (!Postponed || mutt_write_postponed (NONULL (Postponed), msg, (cur && (flags & SENDREPLY)) ? cur->env->message_id : NULL, fcc) < 0)
57 msg->content = mutt_remove_multipart (msg->content);
58 decode_descriptions (msg->content);
59 @@ -1735,7 +1722,7 @@
60 * message was first postponed.
62 msg->received = time (NULL);
63 - if (mutt_write_fcc (fcc, msg, NULL, 0, NULL) == -1)
64 + if (mutt_write_fcc (fcc, msg) == -1)
67 * Error writing FCC, we should abort sending.
68 diff -r 962bfe47cc13 -r bffd60d2ac16 sendlib.c
69 --- a/sendlib.c Mon Apr 27 18:53:40 2009 -0400
70 +++ b/sendlib.c Tue Apr 28 11:17:28 2009 -0400
71 @@ -2503,6 +2505,165 @@
72 rfc2047_decode (&env->x_label);
75 +static int count_length_lines (FILE *fp, LOFF_T *content_lengthp, int *linesp)
77 + char sasha[LONG_STRING];
78 + int lines = 0;
80 + /* count the number of lines */
81 + while (fgets (sasha, sizeof (sasha), fp) != NULL)
82 + lines++;
83 + if (ferror (fp))
84 + return -1;
86 + *linesp = lines;
87 + *content_lengthp = (LOFF_T) ftello (fp);
89 + return 0;
92 +/* state maintained between mutt_start_message and
93 + * mutt_finish_message, opaque to callers.
94 + */
95 +struct mutt_message_handle
97 + FILE *tempfp;
98 + char tempfile[_POSIX_PATH_MAX];
99 + LOFF_T content_length;
100 + int lines;
101 + struct stat st;
102 + int passthru;
105 +static struct mutt_message_handle *
106 +mutt_start_message (const char *path, HEADER *hdr,
107 + CONTEXT *ctxp, MESSAGE **msgp, int passthru)
109 + struct mutt_message_handle *mh;
111 + if (mx_open_mailbox (path, M_APPEND | M_QUIET, ctxp) == NULL)
113 + dprint (1, (debugfile, "mutt_start_message: unable to open mailbox %s"
114 + "in append-mode, aborting.\n", path));
115 + return NULL;
118 + mh = safe_calloc (1, sizeof (*mh));
119 + mh->passthru = passthru;
121 + if (ctxp->magic == M_MMDF || ctxp->magic == M_MBOX)
123 + /* remember new mail status before appending message */
124 + stat (path, &mh->st);
126 + if (!passthru) {
127 + /* need to add a Content-Length field to avoid problems
128 + * where a line in the message body begins with "From "
129 + */
130 + mutt_mktemp (mh->tempfile, sizeof (mh->tempfile));
131 + mh->tempfp = safe_fopen (mh->tempfile, "w+");
132 + if (!mh->tempfp)
134 + mutt_perror (mh->tempfile);
135 + dprint (1, (debugfile, "mutt_start_message: failed "
136 + "to open tempfile, aborting.\n"));
137 + goto error_out;
140 + mutt_write_mime_body (hdr->content, mh->tempfp);
142 + /* make sure the last line ends with a newline. Emacs doesn't ensure
143 + * this will happen, and it can cause problems parsing the mailbox
144 + * later.
145 + */
146 + fseek (mh->tempfp, -1, 2);
147 + if (fgetc (mh->tempfp) != '\n')
149 + fseek (mh->tempfp, 0, 2);
150 + fputc ('\n', mh->tempfp);
152 + if (fflush (mh->tempfp) || ferror (mh->tempfp))
154 + dprint (1, (debugfile, "mutt_start_message: failed "
155 + "to write tempfile, aborting.\n"));
156 + goto error_out;
159 + rewind (mh->tempfp);
161 + if (count_length_lines (mh->tempfp, &mh->content_length, &mh->lines))
163 + mutt_perror (mh->tempfile);
164 + dprint (1, (debugfile, "mutt_start_message: failed "
165 + "to count message length, aborting.\n"));
166 + goto error_out;
171 + if ((*msgp = mx_open_new_message (ctxp, hdr, M_ADD_FROM)) == NULL)
173 + dprint (1, (debugfile, "mutt_start_message: mx_open_new_message "
174 + "failed in %s, aborting.\n", path));
175 + goto error_out;
177 + return mh;
179 +error_out:
180 + /* error message already provided, just clean up */
181 + if (mh->tempfp)
183 + safe_fclose (&mh->tempfp);
184 + unlink (mh->tempfile);
186 + FREE (&mh);
187 + mx_close_mailbox (ctxp, NULL);
188 + return NULL;
191 +static int mutt_finish_message (struct mutt_message_handle *mh,
192 + const char *path, HEADER *hdr,
193 + CONTEXT *ctxp, MESSAGE **msgp, int skip_buffy)
195 + int ret = 0;
197 + if (mh->tempfp)
199 + fprintf ((*msgp)->fp, "Content-Length: " OFF_T_FMT "\n", mh->content_length);
200 + fprintf ((*msgp)->fp, "Lines: %d\n\n", mh->lines); /* NOTE double newline */
202 + /* copy the body */
203 + rewind (mh->tempfp);
204 + ret = mutt_copy_stream (mh->tempfp, (*msgp)->fp);
205 + if (safe_fclose (&mh->tempfp))
206 + ret = -1;
208 + /* if there was an error, leave the temp version */
209 + if (!ret)
210 + unlink (mh->tempfile);
212 + else
214 + if (!mh->passthru)
216 + fputc ('\n', (*msgp)->fp); /* finish off the header */
217 + ret = mutt_write_mime_body (hdr->content, (*msgp)->fp);
219 + skip_buffy = 1; /* only needed for file-based mailboxes */
222 + ret |= mx_commit_message (*msgp, ctxp);
223 + mx_close_message (msgp);
224 + mx_close_mailbox (ctxp, NULL);
226 + if (!skip_buffy)
227 + mutt_buffy_cleanup (path, &mh->st);
229 + FREE (&mh);
231 + return ret;
234 static int _mutt_bounce_message (FILE *fp, HEADER *h, ADDRESS *to, const char *resent_from,
235 ADDRESS *env_from)
237 @@ -2664,81 +2823,60 @@
241 -int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int post, char *fcc)
242 +int mutt_write_fcc (const char *path, HEADER *hdr)
244 + struct mutt_message_handle *mh;
245 CONTEXT f;
246 MESSAGE *msg;
247 - char tempfile[_POSIX_PATH_MAX];
248 - FILE *tempfp = NULL;
249 - int r, need_buffy_cleanup = 0;
250 - struct stat st;
251 - char buf[SHORT_STRING];
253 - if (post)
254 - set_noconv_flags (hdr->content, 1);
256 - if (mx_open_mailbox (path, M_APPEND | M_QUIET, &f) == NULL)
257 + hdr->read = 1; /* make sure to put it in the `cur' directory (maildir) */
259 + mh = mutt_start_message (path, hdr, &f, &msg, 0);
260 + if (!mh)
261 + return -1;
263 + mutt_write_rfc822_header (msg->fp, hdr->env, hdr->content, 0, 0);
264 + fprintf (msg->fp, "Status: RO\n");
266 + return mutt_finish_message (mh, path, hdr, &f, &msg, 0);
269 +int mutt_write_postponed (const char *path, HEADER *hdr, const char *msgid, char *fcc)
271 + struct mutt_message_handle *mh;
272 + CONTEXT f;
273 + MESSAGE *msg;
274 + int ret;
276 + hdr->read = 0; /* make sure to put it in the `new' directory (maildir) */
277 + set_noconv_flags (hdr->content, 1);
279 + mh = mutt_start_message (path, hdr, &f, &msg, 0);
280 + if (!mh)
282 - dprint (1, (debugfile, "mutt_write_fcc(): unable to open mailbox %s in append-mode, aborting.\n",
283 - path));
284 - return (-1);
285 + set_noconv_flags (hdr->content, 0);
286 + return -1;
289 - /* We need to add a Content-Length field to avoid problems where a line in
290 - * the message body begins with "From "
291 - */
292 - if (f.magic == M_MMDF || f.magic == M_MBOX)
294 - mutt_mktemp (tempfile, sizeof (tempfile));
295 - if ((tempfp = safe_fopen (tempfile, "w+")) == NULL)
297 - mutt_perror (tempfile);
298 - mx_close_mailbox (&f, NULL);
299 - return (-1);
301 - /* remember new mail status before appending message */
302 - need_buffy_cleanup = 1;
303 - stat (path, &st);
305 + mutt_write_rfc822_header (msg->fp, hdr->env, hdr->content, -1, 0);
307 - hdr->read = !post; /* make sure to put it in the `cur' directory (maildir) */
308 - if ((msg = mx_open_new_message (&f, hdr, M_ADD_FROM)) == NULL)
310 - mx_close_mailbox (&f, NULL);
311 - return (-1);
314 - /* post == 1 => postpone message. Set mode = -1 in mutt_write_rfc822_header()
315 - * post == 0 => Normal mode. Set mode = 0 in mutt_write_rfc822_header()
316 - * */
317 - mutt_write_rfc822_header (msg->fp, hdr->env, hdr->content, post ? -post : 0, 0);
319 - /* (postponment) if this was a reply of some sort, <msgid> contians the
320 + /* if this was a reply of some sort, <msgid> contains the
321 * Message-ID: of message replied to. Save it using a special X-Mutt-
322 * header so it can be picked up if the message is recalled at a later
323 * point in time. This will allow the message to be marked as replied if
324 * the same mailbox is still open.
326 - if (post && msgid)
327 + if (msgid)
328 fprintf (msg->fp, "X-Mutt-References: %s\n", msgid);
330 - /* (postponment) save the Fcc: using a special X-Mutt- header so that
331 + /* save the Fcc: using a special X-Mutt- header so that
332 * it can be picked up when the message is recalled
334 - if (post && fcc)
335 + if (fcc)
336 fprintf (msg->fp, "X-Mutt-Fcc: %s\n", fcc);
338 - if (f.magic == M_MMDF || f.magic == M_MBOX)
339 - fprintf (msg->fp, "Status: RO\n");
341 - /* mutt_write_rfc822_header() only writes out a Date: header with
342 - * mode == 0, i.e. _not_ postponment; so write out one ourself */
343 - if (post)
344 - fprintf (msg->fp, "%s", mutt_make_date (buf, sizeof (buf)));
346 - /* (postponment) if the mail is to be signed or encrypted, save this info */
347 - if ((WithCrypto & APPLICATION_PGP)
348 - && post && (hdr->security & APPLICATION_PGP))
349 + /* if the mail is to be signed or encrypted, save this info */
350 + if ((WithCrypto & APPLICATION_PGP) && (hdr->security & APPLICATION_PGP))
352 fputs ("X-Mutt-PGP: ", msg->fp);
353 if (hdr->security & ENCRYPT)
354 @@ -2754,9 +2898,8 @@
355 fputc ('\n', msg->fp);
358 - /* (postponment) if the mail is to be signed or encrypted, save this info */
359 - if ((WithCrypto & APPLICATION_SMIME)
360 - && post && (hdr->security & APPLICATION_SMIME))
361 + /* if the mail is to be signed or encrypted, save this info */
362 + if ((WithCrypto & APPLICATION_SMIME) && (hdr->security & APPLICATION_SMIME))
364 fputs ("X-Mutt-SMIME: ", msg->fp);
365 if (hdr->security & ENCRYPT) {
366 @@ -2775,84 +2718,20 @@
369 #ifdef MIXMASTER
370 - /* (postponement) if the mail is to be sent through a mixmaster
371 + /* if the mail is to be sent through a mixmaster
372 * chain, save that information
375 - if (post && hdr->chain && hdr->chain)
376 + if (hdr->chain)
378 LIST *p;
380 fputs ("X-Mutt-Mix:", msg->fp);
381 for (p = hdr->chain; p; p = p->next)
382 fprintf (msg->fp, " %s", (char *) p->data);
384 fputc ('\n', msg->fp);
386 #endif
388 - if (tempfp)
390 - char sasha[LONG_STRING];
391 - int lines = 0;
393 - mutt_write_mime_body (hdr->content, tempfp);
395 - /* make sure the last line ends with a newline. Emacs doesn't ensure
396 - * this will happen, and it can cause problems parsing the mailbox
397 - * later.
398 - */
399 - fseek (tempfp, -1, 2);
400 - if (fgetc (tempfp) != '\n')
402 - fseek (tempfp, 0, 2);
403 - fputc ('\n', tempfp);
406 - fflush (tempfp);
407 - if (ferror (tempfp))
409 - dprint (1, (debugfile, "mutt_write_fcc(): %s: write failed.\n", tempfile));
410 - safe_fclose (&tempfp);
411 - unlink (tempfile);
412 - mx_commit_message (msg, &f); /* XXX - really? */
413 - mx_close_message (&msg);
414 - mx_close_mailbox (&f, NULL);
415 - return -1;
418 - /* count the number of lines */
419 - rewind (tempfp);
420 - while (fgets (sasha, sizeof (sasha), tempfp) != NULL)
421 - lines++;
422 - fprintf (msg->fp, "Content-Length: " OFF_T_FMT "\n", (LOFF_T) ftello (tempfp));
423 - fprintf (msg->fp, "Lines: %d\n\n", lines);
425 - /* copy the body and clean up */
426 - rewind (tempfp);
427 - r = mutt_copy_stream (tempfp, msg->fp);
428 - if (fclose (tempfp) != 0)
429 - r = -1;
430 - /* if there was an error, leave the temp version */
431 - if (!r)
432 - unlink (tempfile);
434 - else
436 - fputc ('\n', msg->fp); /* finish off the header */
437 - r = mutt_write_mime_body (hdr->content, msg->fp);
440 - if (mx_commit_message (msg, &f) != 0)
441 - r = -1;
442 - mx_close_message (&msg);
443 - mx_close_mailbox (&f, NULL);
445 - if (!post && need_buffy_cleanup)
446 - mutt_buffy_cleanup (path, &st);
448 - if (post)
449 - set_noconv_flags (hdr->content, 0);
451 - return r;
452 + ret = mutt_finish_message (mh, path, hdr, &f, &msg, 0);
453 + set_noconv_flags (hdr->content, 0);
454 + return ret;