Commit a0c3ece9 a0c3ece9706c04e3db5882f8e774c7001a5d542a by Sergey Poznyakoff

(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
1 parent fec2e991
...@@ -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
......