(create_filter,print_exit_status)
(get_pager): New function (run_mailcap): Pipe file contents to the command if its invocation does not contain %s. Use pager if `copiousoutput' is specified in mailcap
Showing
1 changed file
with
129 additions
and
39 deletions
... | @@ -20,12 +20,14 @@ | ... | @@ -20,12 +20,14 @@ |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #include <mimeview.h> | 22 | #include <mimeview.h> |
23 | #include <sys/types.h> | ||
23 | #include <sys/stat.h> | 24 | #include <sys/stat.h> |
25 | #include <sys/wait.h> | ||
24 | 26 | ||
25 | const char *program_version = "mimeview (" PACKAGE_STRING ")"; | 27 | const char *program_version = "mimeview (" PACKAGE_STRING ")"; |
26 | static char doc[] = N_("GNU mimeview -- display MIME files\ | 28 | static char doc[] = N_("GNU mimeview -- display files, using mailcap mechanism.\ |
27 | Default mime.types file is ") SYSCONFDIR "/cups/mime.types" | 29 | Default mime.types file is ") DEFAULT_CUPS_CONFDIR "/mime.types" |
28 | N_("\nDebug flags are:\n\ | 30 | N_("\n\nDebug flags are:\n\ |
29 | g - Mime.types parser traces\n\ | 31 | g - Mime.types parser traces\n\ |
30 | l - Mime.types lexical analyzer traces\n\ | 32 | l - Mime.types lexical analyzer traces\n\ |
31 | 0-9 - Set debugging level\n"); | 33 | 0-9 - Set debugging level\n"); |
... | @@ -47,7 +49,7 @@ static struct argp_option options[] = { | ... | @@ -47,7 +49,7 @@ static struct argp_option options[] = { |
47 | int debug_level; /* Debugging level set by --debug option */ | 49 | int debug_level; /* Debugging level set by --debug option */ |
48 | static int dry_run; /* Dry run mode */ | 50 | static int dry_run; /* Dry run mode */ |
49 | static char *metamail; /* Name of metamail program, if requested */ | 51 | static char *metamail; /* Name of metamail program, if requested */ |
50 | static char *mimetypes_config = SYSCONFDIR "/cups"; | 52 | static char *mimetypes_config = DEFAULT_CUPS_CONFDIR; |
51 | 53 | ||
52 | char *mimeview_file; /* Name of the file to view */ | 54 | char *mimeview_file; /* Name of the file to view */ |
53 | FILE *mimeview_fp; /* Its descriptor */ | 55 | FILE *mimeview_fp; /* Its descriptor */ |
... | @@ -164,13 +166,14 @@ close_file () | ... | @@ -164,13 +166,14 @@ close_file () |
164 | 166 | ||
165 | static struct obstack expand_stack; | 167 | static struct obstack expand_stack; |
166 | 168 | ||
167 | static void | 169 | static int |
168 | expand_string (char **pstr, const char *filename, const char *type) | 170 | expand_string (char **pstr, const char *filename, const char *type) |
169 | { | 171 | { |
170 | char *p; | 172 | char *p; |
171 | size_t namelen = strlen (filename); | 173 | size_t namelen = strlen (filename); |
172 | size_t typelen = strlen (type); | 174 | size_t typelen = strlen (type); |
173 | 175 | int rc = 0; | |
176 | |||
174 | for (p = *pstr; *p; ) | 177 | for (p = *pstr; *p; ) |
175 | { | 178 | { |
176 | switch (p[0]) | 179 | switch (p[0]) |
... | @@ -181,6 +184,7 @@ expand_string (char **pstr, const char *filename, const char *type) | ... | @@ -181,6 +184,7 @@ expand_string (char **pstr, const char *filename, const char *type) |
181 | case 's': | 184 | case 's': |
182 | obstack_grow (&expand_stack, filename, namelen); | 185 | obstack_grow (&expand_stack, filename, namelen); |
183 | p += 2; | 186 | p += 2; |
187 | rc = 1; | ||
184 | break; | 188 | break; |
185 | 189 | ||
186 | case 't': | 190 | case 't': |
... | @@ -236,6 +240,7 @@ expand_string (char **pstr, const char *filename, const char *type) | ... | @@ -236,6 +240,7 @@ expand_string (char **pstr, const char *filename, const char *type) |
236 | obstack_1grow (&expand_stack, 0); | 240 | obstack_1grow (&expand_stack, 0); |
237 | free (*pstr); | 241 | free (*pstr); |
238 | *pstr = obstack_finish (&expand_stack); | 242 | *pstr = obstack_finish (&expand_stack); |
243 | return rc; | ||
239 | } | 244 | } |
240 | 245 | ||
241 | static int | 246 | static int |
... | @@ -336,16 +341,97 @@ dump_mailcap_entry (mu_mailcap_entry_t entry) | ... | @@ -336,16 +341,97 @@ dump_mailcap_entry (mu_mailcap_entry_t entry) |
336 | printf ("\n"); | 341 | printf ("\n"); |
337 | } | 342 | } |
338 | 343 | ||
344 | pid_t | ||
345 | create_filter (char *cmd, int outfd, int *infd) | ||
346 | { | ||
347 | pid_t pid; | ||
348 | int lp[2]; | ||
349 | |||
350 | if (infd) | ||
351 | pipe (lp); | ||
352 | |||
353 | pid = fork (); | ||
354 | if (pid == -1) | ||
355 | { | ||
356 | if (infd) | ||
357 | { | ||
358 | close (lp[0]); | ||
359 | close (lp[1]); | ||
360 | } | ||
361 | mu_error ("fork: %s", mu_strerror (errno)); | ||
362 | return -1; | ||
363 | } | ||
364 | |||
365 | if (pid == 0) | ||
366 | { | ||
367 | /* Child process */ | ||
368 | int argc; | ||
369 | char **argv; | ||
370 | |||
371 | argcv_get (cmd, "", NULL, &argc, &argv); | ||
372 | |||
373 | /* Create input channel: */ | ||
374 | if (lp[0] != 0) | ||
375 | dup2 (lp[0], 0); | ||
376 | close (lp[1]); | ||
377 | |||
378 | /* Create output channel */ | ||
379 | if (outfd != -1 && outfd != 1) | ||
380 | dup2 (outfd, 1); | ||
381 | |||
382 | execvp (argv[0], argv); | ||
383 | mu_error (_("Cannot execute `%s': %s"), cmd, mu_strerror (errno)); | ||
384 | _exit (127); | ||
385 | } | ||
386 | |||
387 | /* Master process */ | ||
388 | if (infd) | ||
389 | { | ||
390 | *infd = lp[1]; | ||
391 | close (lp[0]); | ||
392 | } | ||
393 | return pid; | ||
394 | } | ||
395 | |||
396 | void | ||
397 | print_exit_status (int status) | ||
398 | { | ||
399 | if (WIFEXITED (status)) | ||
400 | printf (_("Command exited with status %d\n"), WEXITSTATUS(status)); | ||
401 | else if (WIFSIGNALED (status)) | ||
402 | printf(_("Command terminated on signal %d\n"), WTERMSIG(status)); | ||
403 | else | ||
404 | printf (_("Command terminated")); | ||
405 | } | ||
406 | |||
407 | static char * | ||
408 | get_pager () | ||
409 | { | ||
410 | char *pager = getenv ("MIMEVIEW_PAGER"); | ||
411 | if (!pager) | ||
412 | { | ||
413 | pager = getenv ("METAMAIL_PAGER"); | ||
414 | if (!pager) | ||
415 | { | ||
416 | pager = getenv ("PAGER"); | ||
417 | if (!pager) | ||
418 | pager = "more"; | ||
419 | } | ||
420 | } | ||
421 | return pager; | ||
422 | } | ||
423 | |||
339 | int | 424 | int |
340 | run_mailcap (mu_mailcap_entry_t entry, const char *type) | 425 | run_mailcap (mu_mailcap_entry_t entry, const char *type) |
341 | { | 426 | { |
342 | char *view_command; | 427 | char *view_command; |
343 | size_t size; | 428 | size_t size; |
344 | int flag; | 429 | int flag; |
345 | int status; | 430 | int status; |
346 | int argc; | 431 | int fd; |
347 | char **argv; | 432 | int *pfd = NULL; |
348 | /* pid_t pager = -1; */ | 433 | int outfd = -1; |
434 | pid_t pid, pager_pid; | ||
349 | 435 | ||
350 | if (debug_level > 1) | 436 | if (debug_level > 1) |
351 | dump_mailcap_entry (entry); | 437 | dump_mailcap_entry (entry); |
... | @@ -357,42 +443,46 @@ run_mailcap (mu_mailcap_entry_t entry, const char *type) | ... | @@ -357,42 +443,46 @@ run_mailcap (mu_mailcap_entry_t entry, const char *type) |
357 | 443 | ||
358 | /* NOTE: We don't create temporary file for %s, we just use | 444 | /* NOTE: We don't create temporary file for %s, we just use |
359 | mimeview_file instead */ | 445 | mimeview_file instead */ |
360 | expand_string (&view_command, mimeview_file, type); | 446 | if (expand_string (&view_command, mimeview_file, type)) |
447 | pfd = NULL; | ||
448 | else | ||
449 | pfd = &fd; | ||
361 | DEBUG (0, (_("Executing %s...\n"), view_command)); | 450 | DEBUG (0, (_("Executing %s...\n"), view_command)); |
362 | 451 | ||
363 | if (dry_run) | 452 | if (dry_run) |
364 | return 0; | 453 | return 0; |
365 | 454 | ||
366 | status = argcv_get (view_command, "", NULL, &argc, &argv); | 455 | flag = 0; |
367 | free (view_command); | 456 | if (mu_mailcap_entry_copiousoutput (entry, &flag) == 0 && flag) |
368 | if (status) | 457 | pager_pid = create_filter (get_pager (), -1, &outfd); |
369 | { | ||
370 | mu_error (_("Cannot parse command line: %s"), mu_strerror (status)); | ||
371 | return 1; | ||
372 | } | ||
373 | 458 | ||
374 | /* | 459 | pid = create_filter (view_command, outfd, pfd); |
375 | if (mu_mailcap_entry_copiousoutput (entry, &flag) == 0 && flag) | 460 | if (pid > 0) |
376 | pager = open_pager (); | ||
377 | */ | ||
378 | |||
379 | if (pager <= 0) | ||
380 | { | 461 | { |
381 | if (mu_spawnvp (argv[0], argv, &status)) | 462 | if (pfd) |
382 | mu_error (_("Cannot execute command: %s"), mu_strerror (status)); | ||
383 | |||
384 | if (debug_level) | ||
385 | { | 463 | { |
386 | if (WIFEXITED (status)) | 464 | char buf[512]; |
387 | printf (_("Command exited with status %d\n"), WEXITSTATUS(status)); | 465 | size_t n; |
388 | else if (WIFSIGNALED (status)) | 466 | |
389 | printf(_("Command terminated on signal %d\n"), WTERMSIG(status)); | 467 | fseek (mimeview_fp, 0, SEEK_SET); |
390 | else | 468 | while ((n = fread (buf, 1, sizeof buf, mimeview_fp)) > 0) |
391 | printf (_("Command terminated")); | 469 | { |
470 | write (fd, buf, n); | ||
471 | } | ||
472 | free (buf); | ||
473 | close (fd); | ||
392 | } | 474 | } |
475 | |||
476 | while (waitpid (pid, &status, 0) < 0) | ||
477 | if (errno != EINTR) | ||
478 | { | ||
479 | mu_error ("waitpid: %s", mu_strerror (errno)); | ||
480 | break; | ||
481 | } | ||
482 | if (debug_level) | ||
483 | print_exit_status (status); | ||
393 | } | 484 | } |
394 | argcv_free (argc, argv); | 485 | free (view_command); |
395 | /* close_pager (pager); */ | ||
396 | } | 486 | } |
397 | 487 | ||
398 | void | 488 | void | ... | ... |
-
Please register or sign in to post a comment