remove old pile of crap and cruft
[apps/madmutt.git] / editmsg.c
1 /*
2  * Copyright notice from original mutt:
3  * Copyright (C) 1999-2000 Thomas Roessler <roessler@does-not-exist.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 /* simple, editor-based message editing */
11
12 #include <lib-lib/lib-lib.h>
13 #include <lib-ui/curses.h>
14 #include <lib-mx/mx.h>
15
16 #include "mutt.h"
17 #include "copy.h"
18
19 /*
20  * return value:
21  * 
22  * 1    message not modified
23  * 0    message edited successfully
24  * -1   error
25  */
26
27 static int edit_one_message (CONTEXT * ctx, HEADER * cur)
28 {
29   char tmp[_POSIX_PATH_MAX];
30   char buff[STRING];
31   int omagic;
32   int oerrno;
33   int rc;
34
35   unsigned short o_read;
36   unsigned short o_old;
37
38   int of, cf;
39
40   CONTEXT tmpctx;
41   MESSAGE *msg;
42
43   FILE *fp = NULL;
44
45   struct stat sb;
46   time_t mtime = 0;
47   ssize_t size = 0;
48
49   mutt_mktemp (tmp);
50
51   omagic = DefaultMagic;
52   DefaultMagic = M_MBOX;
53
54   rc = (mx_open_mailbox (tmp, M_NEWFOLDER, &tmpctx) == NULL) ? -1 : 0;
55
56   DefaultMagic = omagic;
57
58   if (rc == -1) {
59     mutt_error (_("could not create temporary folder: %s"), strerror (errno));
60     return -1;
61   }
62
63   rc = mutt_append_message (&tmpctx, ctx, cur, 0, CH_NOLEN |
64                             ((ctx->magic == M_MBOX
65                               || ctx->magic == M_MMDF) ? 0 : CH_NOSTATUS));
66   oerrno = errno;
67
68   mx_close_mailbox (&tmpctx, NULL);
69
70   if (rc == -1) {
71     mutt_error (_("could not write temporary mail folder: %s"),
72                 strerror (oerrno));
73     goto bail;
74   }
75
76   if (stat (tmp, &sb) == 0) {
77     mtime = sb.st_mtime;
78     size = sb.st_size;
79   }
80
81   /*
82    * 2002-09-05 me@sigpipe.org
83    * The file the user is going to edit is not a real mbox, so we need to
84    * truncate the last newline in the temp file, which is logically part of
85    * the message separator, and not the body of the message.  If we fail to
86    * remove it, the message will grow by one line each time the user edits
87    * the message.
88    */
89   if (size != 0 && truncate (tmp, --size) == -1) {
90     mutt_error (_("could not truncate temporary mail folder: %s"),
91                 strerror (errno));
92     goto bail;
93   }
94
95   mutt_edit_file(tmp);
96
97   if ((rc = stat (tmp, &sb)) == -1) {
98     mutt_error (_("Can't stat %s: %s"), tmp, strerror (errno));
99     goto bail;
100   }
101
102   if (sb.st_size == 0) {
103     mutt_message (_("Message file is empty!"));
104     rc = 1;
105     goto bail;
106   }
107
108   if (sb.st_mtime == mtime && sb.st_size == size) {
109     mutt_message (_("Message not modified!"));
110     rc = 1;
111     goto bail;
112   }
113
114   if ((fp = fopen (tmp, "r")) == NULL) {
115     rc = -1;
116     mutt_error (_("Can't open message file: %s"), strerror (errno));
117     goto bail;
118   }
119
120   if (mx_open_mailbox (ctx->path, M_APPEND, &tmpctx) == NULL) {
121     rc = -1;
122     mutt_error (_("Can't append to folder: %s"), strerror (errno));
123     goto bail;
124   }
125
126   of = 0;
127   cf = ((tmpctx.magic == M_MBOX || tmpctx.magic == M_MMDF) ? 0 : CH_NOSTATUS);
128
129   if (fgets (buff, sizeof (buff), fp) && is_from (buff, NULL, 0, NULL)) {
130     if (tmpctx.magic == M_MBOX || tmpctx.magic == M_MMDF)
131       cf = CH_FROM | CH_FORCE_FROM;
132   }
133   else
134     of = M_ADD_FROM;
135
136   /* 
137    * XXX - we have to play games with the message flags to avoid
138    * problematic behaviour with maildir folders.
139    *
140    */
141
142   o_read = cur->read;
143   o_old = cur->old;
144   cur->read = cur->old = 0;
145   msg = mx_open_new_message (&tmpctx, cur, of);
146   cur->read = o_read;
147   cur->old = o_old;
148
149   if (msg == NULL) {
150     mutt_error (_("Can't append to folder: %s"), strerror (errno));
151     mx_close_mailbox (&tmpctx, NULL);
152     goto bail;
153   }
154
155   if ((rc =
156        mutt_copy_hdr (fp, msg->fp, 0, sb.st_size, CH_NOLEN | cf,
157                       NULL)) == 0) {
158     fputc ('\n', msg->fp);
159     rc = mutt_copy_stream (fp, msg->fp);
160   }
161
162   rc = mx_commit_message (msg, &tmpctx);
163   mx_close_message (&msg);
164
165   mx_close_mailbox (&tmpctx, NULL);
166
167 bail:
168   m_fclose(&fp);
169
170   if (rc >= 0)
171     unlink (tmp);
172
173   if (rc == 0) {
174     mutt_set_flag (Context, cur, M_DELETE, 1);
175     mutt_set_flag (Context, cur, M_READ, 1);
176
177     if (option (OPTDELETEUNTAG))
178       mutt_set_flag (Context, cur, M_TAG, 0);
179   }
180   else if (rc == -1)
181     mutt_message (_("Error. Preserving temporary file: %s"), tmp);
182
183
184   return rc;
185 }
186
187 int mutt_edit_message (CONTEXT * ctx, HEADER * hdr)
188 {
189   int i, j;
190
191   if (hdr)
192     return edit_one_message (ctx, hdr);
193
194
195   for (i = 0; i < ctx->vcount; i++) {
196     j = ctx->v2r[i];
197     if (ctx->hdrs[j]->tagged) {
198       if (edit_one_message (ctx, ctx->hdrs[j]) == -1)
199         return -1;
200     }
201   }
202
203   return 0;
204 }