(mail_decode): Implemented new variable
`metamail' that turns on use of metamail program for displaying MIME messages. (run_metamail): New function
Showing
1 changed file
with
117 additions
and
5 deletions
... | @@ -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 | } | ... | ... |
-
Please register or sign in to post a comment