mhshow: Automatically invoke (one) pager for the whole message, if on TTY.
authormarkus schnalke <meillo@marmaro.de>
Sat, 14 Apr 2012 17:59:54 +0000 (19:59 +0200)
committermarkus schnalke <meillo@marmaro.de>
Sat, 14 Apr 2012 17:59:54 +0000 (19:59 +0200)
Mhshow used to invoke the pager for each of the text/plain parts
independently. Now, we invoke it once for the whole message.
Remember: We serialize!
(Mhl(1) invokes a pager too, currently, but not much longer.)

man/mhshow.man1
uip/mhshow.c

index 79975ef..ecd2e9d 100644 (file)
@@ -118,6 +118,14 @@ non\-empty, then
 will remove each of the messages shown
 from each sequence named by the profile entry.
 .SS "Showing the Contents"
 will remove each of the messages shown
 from each sequence named by the profile entry.
 .SS "Showing the Contents"
+.B Mhshow
+prints messages in a convenient representation.
+If
+.B mhshow
+is outputting to a terminal, then
+a pager will be placed between the terminal and
+.BR mhshow .
+.PP
 The headers of each message are displayed with
 .B mhl
 using the standard format file
 The headers of each message are displayed with
 .B mhl
 using the standard format file
@@ -366,7 +374,7 @@ installation.
 ^Current\-Folder:~^To find the default current folder
 ^Unseen\-Sequence:~^To name sequences denoting unseen messages
 ^mhshow-show-<type>*~^Template for displaying contents
 ^Current\-Folder:~^To find the default current folder
 ^Unseen\-Sequence:~^To name sequences denoting unseen messages
 ^mhshow-show-<type>*~^Template for displaying contents
-^Pager:~^Default program to display text/plain content
+^Pager:~^Program to use as interactive front\-end
 .fi
 
 .SH "SEE ALSO"
 .fi
 
 .SH "SEE ALSO"
index 53f96f2..c323867 100644 (file)
@@ -79,6 +79,8 @@ void freects_done(int) NORETURN;
 ** static prototypes
 */
 static void pipeser(int);
 ** static prototypes
 */
 static void pipeser(int);
+static void m_popen(char *);
+static void m_pclose(void);
 
 
 int
 
 
 int
@@ -92,6 +94,7 @@ main(int argc, char **argv)
        struct msgs *mp = NULL;
        CT ct, *ctp;
        FILE *fp;
        struct msgs *mp = NULL;
        CT ct, *ctp;
        FILE *fp;
+       int ontty = 0;
 
        done=freects_done;
 
 
        done=freects_done;
 
@@ -313,11 +316,19 @@ main(int argc, char **argv)
                }
        }
 
                }
        }
 
+       if ((ontty = isatty(fileno(stdout)))) {
+               m_popen(defaultpager);
+       }
+
        /*
        ** Show the message content
        */
        show_all_messages(cts);
 
        /*
        ** Show the message content
        */
        show_all_messages(cts);
 
+       if (ontty) {
+               m_pclose();
+       }
+
        /* Now free all the structures for the content */
        for (ctp = cts; *ctp; ctp++)
                free_content(*ctp);
        /* Now free all the structures for the content */
        for (ctp = cts; *ctp; ctp++)
                free_content(*ctp);
@@ -351,3 +362,68 @@ pipeser(int i)
        done(1);
        /* NOTREACHED */
 }
        done(1);
        /* NOTREACHED */
 }
+
+
+static int m_pid = NOTOK;
+static int sd = NOTOK;
+
+
+static void
+m_popen(char *name)
+{
+       int pd[2];
+
+       if ((sd = dup(fileno(stdout))) == NOTOK)
+               adios("standard output", "unable to dup()");
+
+       if (pipe(pd) == NOTOK)
+               adios("pipe", "unable to");
+
+       switch (m_pid = fork()) {
+       case NOTOK:
+               adios("fork", "unable to");
+
+       case OK:
+               SIGNAL(SIGINT, SIG_DFL);
+               SIGNAL(SIGQUIT, SIG_DFL);
+
+               close(pd[1]);
+               if (pd[0] != fileno(stdin)) {
+                       dup2(pd[0], fileno(stdin));
+                       close(pd[0]);
+               }
+               execlp(name, mhbasename(name), NULL);
+               fprintf(stderr, "unable to exec ");
+               perror(name);
+               _exit(-1);
+
+       default:
+               close(pd[0]);
+               if (pd[1] != fileno(stdout)) {
+                       dup2(pd[1], fileno(stdout));
+                       close(pd[1]);
+               }
+       }
+}
+
+
+void
+m_pclose(void)
+{
+       if (m_pid == NOTOK)
+               return;
+
+       if (sd != NOTOK) {
+               fflush(stdout);
+               if (dup2(sd, fileno(stdout)) == NOTOK)
+                       adios("standard output", "unable to dup2()");
+
+               clearerr(stdout);
+               close(sd);
+               sd = NOTOK;
+       } else
+               fclose(stdout);
+
+       pidwait(m_pid, OK);
+       m_pid = NOTOK;
+}