Rocco Rutte:
[apps/madmutt.git] / headers.c
1 /*
2  * Copyright notice from original mutt:
3  * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
4  *
5  * This file is part of mutt-ng, see http://www.muttng.org/.
6  * It's licensed under the GNU General Public License,
7  * please see the file GPL in the top level source directory.
8  */
9
10 #if HAVE_CONFIG_H
11 # include "config.h"
12 #endif
13
14 #include "mutt.h"
15 #include "mutt_crypt.h"
16 #include "mutt_idna.h"
17
18 #include "lib/intl.h"
19 #include "lib/debug.h"
20
21 #include <sys/stat.h>
22 #include <string.h>
23 #include <ctype.h>
24
25 void mutt_edit_headers (const char *editor,
26                         const char *body,
27                         HEADER * msg, char *fcc, size_t fcclen)
28 {
29   char path[_POSIX_PATH_MAX];   /* tempfile used to edit headers + body */
30   char buffer[LONG_STRING];
31   char *p;
32   FILE *ifp, *ofp;
33   int i, keep;
34   ENVELOPE *n;
35   time_t mtime;
36   struct stat st;
37   LIST *cur, **last = NULL, *tmp;
38
39   mutt_mktemp (path);
40   if ((ofp = safe_fopen (path, "w")) == NULL) {
41     mutt_perror (path);
42     return;
43   }
44
45   mutt_env_to_local (msg->env);
46   mutt_write_rfc822_header (ofp, msg->env, NULL, 1, 0);
47   fputc ('\n', ofp);            /* tie off the header. */
48
49   /* now copy the body of the message. */
50   if ((ifp = fopen (body, "r")) == NULL) {
51     mutt_perror (body);
52     return;
53   }
54
55   mutt_copy_stream (ifp, ofp);
56
57   fclose (ifp);
58   fclose (ofp);
59
60   if (stat (path, &st) == -1) {
61     mutt_perror (path);
62     return;
63   }
64
65   mtime = mutt_decrease_mtime (path, &st);
66
67   mutt_edit_file (editor, path);
68   stat (path, &st);
69   if (mtime == st.st_mtime) {
70     debug_print (1, ("temp file was not modified.\n"));
71     /* the file has not changed! */
72     mutt_unlink (path);
73     return;
74   }
75
76   mutt_unlink (body);
77   mutt_free_list (&msg->env->userhdrs);
78
79   /* Read the temp file back in */
80   if ((ifp = fopen (path, "r")) == NULL) {
81     mutt_perror (path);
82     return;
83   }
84
85   if ((ofp = safe_fopen (body, "w")) == NULL) {
86     /* intentionally leak a possible temporary file here */
87     fclose (ifp);
88     mutt_perror (body);
89     return;
90   }
91
92   n = mutt_read_rfc822_header (ifp, NULL, 1, 0);
93   while ((i = fread (buffer, 1, sizeof (buffer), ifp)) > 0)
94     fwrite (buffer, 1, i, ofp);
95   fclose (ofp);
96   fclose (ifp);
97   mutt_unlink (path);
98
99   /* restore old info. */
100   n->references = msg->env->references;
101   msg->env->references = NULL;
102
103   mutt_free_envelope (&msg->env);
104   msg->env = n;
105   n = NULL;
106
107   if (!msg->env->in_reply_to)
108 #ifdef USE_NNTP
109     if (!option (OPTNEWSSEND))
110 #endif
111       mutt_free_list (&msg->env->references);
112
113   mutt_expand_aliases_env (msg->env);
114
115   /* search through the user defined headers added to see if either a 
116    * fcc: or attach-file: field was specified.  
117    */
118
119   cur = msg->env->userhdrs;
120   last = &msg->env->userhdrs;
121   while (cur) {
122     keep = 1;
123
124     /* keep track of whether or not we see the in-reply-to field.  if we did
125      * not, remove the references: field later so that we can generate a new
126      * message based upon this one.
127      */
128     if (fcc && ascii_strncasecmp ("fcc:", cur->data, 4) == 0) {
129       p = cur->data + 4;
130       SKIPWS (p);
131       if (*p) {
132         strfcpy (fcc, p, fcclen);
133         mutt_pretty_mailbox (fcc);
134       }
135       keep = 0;
136     }
137     else if (ascii_strncasecmp ("attach:", cur->data, 7) == 0) {
138       BODY *body;
139       BODY *parts;
140       char *q;
141
142       p = cur->data + 7;
143       SKIPWS (p);
144       if (*p) {
145         if ((q = strpbrk (p, " \t"))) {
146           str_substrcpy (path, p, q, sizeof (path));
147           SKIPWS (q);
148         }
149         else
150           strfcpy (path, p, sizeof (path));
151         mutt_expand_path (path, sizeof (path));
152         if ((body = mutt_make_file_attach (path))) {
153           body->description = str_dup (q);
154           for (parts = msg->content; parts->next; parts = parts->next);
155           parts->next = body;
156         }
157         else {
158           mutt_pretty_mailbox (path);
159           mutt_error (_("%s: unable to attach file"), path);
160         }
161       }
162       keep = 0;
163     }
164
165
166     else if ((WithCrypto & APPLICATION_PGP)
167              && ascii_strncasecmp ("pgp:", cur->data, 4) == 0) {
168       msg->security = mutt_parse_crypt_hdr (cur->data + 4, 0);
169       if (msg->security)
170         msg->security |= APPLICATION_PGP;
171       keep = 0;
172     }
173
174     if (keep) {
175       last = &cur->next;
176       cur = cur->next;
177     }
178     else {
179       tmp = cur;
180       *last = cur->next;
181       cur = cur->next;
182       tmp->next = NULL;
183       mutt_free_list (&tmp);
184     }
185   }
186 }