Commit 986fc6f1 986fc6f13b5f61f46195fd1bc399b6e089c90a6c by Sergey Poznyakoff

(mail_decode): Implemented new variable

`metamail' that turns on use of metamail program for
displaying MIME messages.
(run_metamail): New function
1 parent 194e1c4e
...@@ -34,6 +34,7 @@ static int display_message __P ((message_t, msgset_t *msgset, void *closure)); ...@@ -34,6 +34,7 @@ static int display_message __P ((message_t, msgset_t *msgset, void *closure));
34 static int display_message0 __P ((FILE *, message_t, const msgset_t *, int)); 34 static int display_message0 __P ((FILE *, message_t, const msgset_t *, int));
35 static int mailcap_lookup __P ((const char *)); 35 static int mailcap_lookup __P ((const char *));
36 static int get_content_encoding __P ((header_t hdr, char **value)); 36 static int get_content_encoding __P ((header_t hdr, char **value));
37 static void run_metamail __P((const char *mailcap, message_t mesg));
37 38
38 int 39 int
39 mail_decode (int argc, char **argv) 40 mail_decode (int argc, char **argv)
...@@ -58,7 +59,8 @@ display_message (message_t mesg, msgset_t *msgset, void *arg) ...@@ -58,7 +59,8 @@ display_message (message_t mesg, msgset_t *msgset, void *arg)
58 FILE *out; 59 FILE *out;
59 size_t lines = 0; 60 size_t lines = 0;
60 struct decode_closure *closure = arg; 61 struct decode_closure *closure = arg;
61 int pagelines = util_get_crt (); 62 int pagelines = util_getenv (NULL, "metamail", Mail_env_string, 0) == 0 ?
63 0 : util_get_crt ();
62 attribute_t attr = NULL; 64 attribute_t attr = NULL;
63 65
64 message_get_attribute (mesg, &attr); 66 message_get_attribute (mesg, &attr);
...@@ -154,9 +156,10 @@ display_message0 (FILE *out, message_t mesg, const msgset_t *msgset, ...@@ -154,9 +156,10 @@ display_message0 (FILE *out, message_t mesg, const msgset_t *msgset,
154 { 156 {
155 size_t nparts = 0; 157 size_t nparts = 0;
156 header_t hdr = NULL; 158 header_t hdr = NULL;
157 char *type; 159 const char *type;
158 char *encoding; 160 char *encoding;
159 int ismime = 0; 161 int ismime = 0;
162 char *tmp;
160 163
161 message_get_header (mesg, &hdr); 164 message_get_header (mesg, &hdr);
162 util_get_content_type (hdr, &type); 165 util_get_content_type (hdr, &type);
...@@ -166,7 +169,7 @@ display_message0 (FILE *out, message_t mesg, const msgset_t *msgset, ...@@ -166,7 +169,7 @@ display_message0 (FILE *out, message_t mesg, const msgset_t *msgset,
166 if (ismime) 169 if (ismime)
167 { 170 {
168 unsigned int j; 171 unsigned int j;
169 172
170 message_get_num_parts (mesg, &nparts); 173 message_get_num_parts (mesg, &nparts);
171 174
172 for (j = 1; j <= nparts; j++) 175 for (j = 1; j <= nparts; j++)
...@@ -189,10 +192,14 @@ display_message0 (FILE *out, message_t mesg, const msgset_t *msgset, ...@@ -189,10 +192,14 @@ display_message0 (FILE *out, message_t mesg, const msgset_t *msgset,
189 if (message_unencapsulate (mesg, &submsg, NULL) == 0) 192 if (message_unencapsulate (mesg, &submsg, NULL) == 0)
190 display_message0 (out, submsg, msgset, select_hdr); 193 display_message0 (out, submsg, msgset, select_hdr);
191 } 194 }
195 else if (util_getenv (&tmp, "metamail", Mail_env_string, 0) == 0)
196 {
197 run_metamail (tmp, mesg);
198 }
192 else if (mailcap_lookup (type)) 199 else if (mailcap_lookup (type))
193 { 200 {
194 /* FIXME: lookup .mailcap and do the appropriate action when 201 /* FIXME: lookup .mailcap and do the appropriate action when
195 an match engry is find. */ 202 an match engry is found. */
196 /* Do something, spawn a process etc .... */ 203 /* Do something, spawn a process etc .... */
197 } 204 }
198 else /*if (strncasecmp (type, "text/plain", strlen ("text/plain")) == 0 205 else /*if (strncasecmp (type, "text/plain", strlen ("text/plain")) == 0
...@@ -266,9 +273,114 @@ get_content_encoding (header_t hdr, char **value) ...@@ -266,9 +273,114 @@ get_content_encoding (header_t hdr, char **value)
266 return 0; 273 return 0;
267 } 274 }
268 275
269
270 static int 276 static int
271 mailcap_lookup (const char *type ARG_UNUSED) 277 mailcap_lookup (const char *type ARG_UNUSED)
272 { 278 {
273 return 0; 279 return 0;
274 } 280 }
281
282 /* Run `metamail' program MAILCAP_CMD on the message MESG */
283 static void
284 run_metamail (const char *mailcap_cmd, message_t mesg)
285 {
286 pid_t pid;
287 struct sigaction ignore;
288 struct sigaction saveintr;
289 struct sigaction savequit;
290 sigset_t chldmask;
291 sigset_t savemask;
292
293 ignore.sa_handler = SIG_IGN; /* ignore SIGINT and SIGQUIT */
294 ignore.sa_flags = 0;
295 sigemptyset (&ignore.sa_mask);
296 if (sigaction (SIGINT, &ignore, &saveintr) < 0)
297 {
298 util_error ("sigaction: %s", strerror (errno));
299 return;
300 }
301 if (sigaction (SIGQUIT, &ignore, &savequit) < 0)
302 {
303 util_error ("sigaction: %s", strerror (errno));
304 sigaction (SIGINT, &saveintr, NULL);
305 return;
306 }
307
308 sigemptyset (&chldmask); /* now block SIGCHLD */
309 sigaddset (&chldmask, SIGCHLD);
310
311 if (sigprocmask (SIG_BLOCK, &chldmask, &savemask) < 0)
312 {
313 sigaction (SIGINT, &saveintr, NULL);
314 sigaction (SIGQUIT, &savequit, NULL);
315 return;
316 }
317
318 pid = fork ();
319 if (pid < 0)
320 {
321 util_error ("fork: %s", strerror (errno));
322 }
323 else if (pid == 0)
324 {
325 /* Child process */
326 int status;
327 stream_t stream;
328
329 do /* Fake loop to avoid gotos */
330 {
331 stream_t pstr;
332 char buffer[512];
333 size_t n;
334
335 setenv ("METAMAIL_PAGER", getenv ("PAGER"), 0);
336
337 status = message_get_stream (mesg, &stream);
338 if (status)
339 {
340 mu_error ("message_get_stream: %s", mu_strerror (status));
341 break;
342 }
343
344 status = prog_stream_create (&pstr, mailcap_cmd, MU_STREAM_WRITE);
345 if (status)
346 {
347 mu_error ("prog_stream_create: %s", mu_strerror (status));
348 break;
349 }
350
351 status = stream_open (pstr);
352 if (status)
353 {
354 mu_error ("stream_open: %s", mu_strerror (status));
355 break;
356 }
357
358 while (stream_sequential_read (stream,
359 buffer, sizeof buffer - 1,
360 &n) == 0
361 && n > 0)
362 stream_sequential_write (pstr, buffer, n);
363
364 stream_close (pstr);
365 stream_destroy (&pstr, stream_get_owner (pstr));
366 exit (0);
367 }
368 while (0);
369
370 abort ();
371 }
372 else
373 {
374 int status;
375 /* Master process */
376
377 while (waitpid (pid, &status, 0) < 0)
378 if (errno != EINTR)
379 break;
380 }
381
382 /* Restore the signal handlers */
383 sigaction (SIGINT, &saveintr, NULL);
384 sigaction (SIGQUIT, &savequit, NULL);
385 sigprocmask (SIG_SETMASK, &savemask, NULL);
386 }
......