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