Andreas Krennmair:
[apps/madmutt.git] / headers.c
1 /* 
2  * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
3  * 
4  *     This program is free software; you can redistribute it and/or modify
5  *     it under the terms of the GNU General Public License as published by
6  *     the Free Software Foundation; either version 2 of the License, or
7  *     (at your option) any later version.
8  * 
9  *     This program is distributed in the hope that it will be useful,
10  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *     GNU General Public License for more details.
13  * 
14  *     You should have received a copy of the GNU General Public License
15  *     along with this program; if not, write to the Free Software
16  *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
17  */
18
19 #include "mutt.h"
20 #include "mutt_crypt.h"
21 #include "mutt_idna.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,
30                         char *fcc,
31                         size_t fcclen)
32 {
33   char path[_POSIX_PATH_MAX];   /* tempfile used to edit headers + body */
34   char buffer[LONG_STRING];
35   char *p;
36   FILE *ifp, *ofp;
37   int i, keep;
38   ENVELOPE *n;
39   time_t mtime;
40   struct stat st;
41   LIST *cur, **last = NULL, *tmp;
42
43   mutt_mktemp (path);
44   if ((ofp = safe_fopen (path, "w")) == NULL)
45   {
46     mutt_perror (path);
47     return;
48   }
49   
50   mutt_env_to_local (msg->env);
51   mutt_write_rfc822_header (ofp, msg->env, NULL, 1, 0);
52   fputc ('\n', ofp);    /* tie off the header. */
53
54   /* now copy the body of the message. */
55   if ((ifp = fopen (body, "r")) == NULL)
56   {
57     mutt_perror (body);
58     return;
59   }
60
61   mutt_copy_stream (ifp, ofp);
62
63   fclose (ifp);
64   fclose (ofp);
65
66   if (stat (path, &st) == -1)
67   {
68     mutt_perror (path);
69     return;
70   }
71
72   mtime = mutt_decrease_mtime (path, &st);
73
74   mutt_edit_file (editor, path);
75   stat (path, &st);
76   if (mtime == st.st_mtime)
77   {
78     dprint (1, (debugfile, "ci_edit_headers(): temp file was not modified.\n"));
79     /* the file has not changed! */
80     mutt_unlink (path);
81     return;
82   }
83
84   mutt_unlink (body);
85   mutt_free_list (&msg->env->userhdrs);
86
87   /* Read the temp file back in */
88   if ((ifp = fopen (path, "r")) == NULL)
89   {
90     mutt_perror (path);
91     return;
92   }
93   
94   if ((ofp = safe_fopen (body, "w")) == NULL)
95   {
96     /* intentionally leak a possible temporary file here */
97     fclose (ifp);
98     mutt_perror (body);
99     return;
100   }
101   
102   n = mutt_read_rfc822_header (ifp, NULL, 1, 0);
103   while ((i = fread (buffer, 1, sizeof (buffer), ifp)) > 0)
104     fwrite (buffer, 1, i, ofp);
105   fclose (ofp);
106   fclose (ifp);
107   mutt_unlink (path);
108
109   /* restore old info. */
110   n->references = msg->env->references;
111   msg->env->references = NULL;
112
113   mutt_free_envelope (&msg->env);
114   msg->env = n; n = NULL;
115
116   if (!msg->env->in_reply_to)
117 #ifdef USE_NNTP
118   if (!option (OPTNEWSSEND))
119 #endif
120     mutt_free_list (&msg->env->references);
121
122   mutt_expand_aliases_env (msg->env);
123
124   /* search through the user defined headers added to see if either a 
125    * fcc: or attach-file: field was specified.  
126    */
127
128   cur = msg->env->userhdrs;
129   last = &msg->env->userhdrs;
130   while (cur)
131   {
132     keep = 1;
133
134     /* keep track of whether or not we see the in-reply-to field.  if we did
135      * not, remove the references: field later so that we can generate a new
136      * message based upon this one.
137      */
138     if (fcc && ascii_strncasecmp ("fcc:", cur->data, 4) == 0)
139     {
140       p = cur->data + 4;
141       SKIPWS (p);
142       if (*p)
143       {
144         strfcpy (fcc, p, fcclen);
145         mutt_pretty_mailbox (fcc);
146       }
147       keep = 0;
148     }
149     else if (ascii_strncasecmp ("attach:", cur->data, 7) == 0)
150     {
151       BODY *body;
152       BODY *parts;
153       char *q;
154
155       p = cur->data + 7;
156       SKIPWS (p);
157       if (*p)
158       {
159         if ((q = strpbrk (p, " \t")))
160         {
161           mutt_substrcpy (path, p, q, sizeof (path));
162           SKIPWS (q);
163         }
164         else
165           strfcpy (path, p, sizeof (path));
166         mutt_expand_path (path, sizeof (path));
167         if ((body = mutt_make_file_attach (path)))
168         {
169           body->description = safe_strdup (q);
170           for (parts = msg->content; parts->next; parts = parts->next) ;
171           parts->next = body;
172         }
173         else
174         {
175           mutt_pretty_mailbox (path);
176           mutt_error (_("%s: unable to attach file"), path);
177         }
178       }
179       keep = 0;
180     }
181
182
183     else if ((WithCrypto & APPLICATION_PGP)
184              &&ascii_strncasecmp ("pgp:", cur->data, 4) == 0)
185     {
186       msg->security = mutt_parse_crypt_hdr (cur->data + 4, 0);
187       if (msg->security)
188         msg->security |= APPLICATION_PGP;
189       keep = 0;
190     }
191
192     if (keep)
193     {
194       last = &cur->next;
195       cur  = cur->next;
196     }
197     else
198     {
199       tmp       = cur;
200       *last     = cur->next;
201       cur       = cur->next;
202       tmp->next = NULL;
203       mutt_free_list (&tmp);
204     }
205   }
206 }