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