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