Fix uip/whom.c for C89 compatibility
[mmh] / uip / mhshowsbr.c
index 2b69c19..c7923c8 100644 (file)
 #include <fcntl.h>
 #include <h/signals.h>
 #include <errno.h>
-#include <setjmp.h>
 #include <signal.h>
 #include <h/tws.h>
 #include <h/mime.h>
 #include <h/mhparse.h>
 #include <h/utils.h>
 #include <sys/wait.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sysexits.h>
 
 extern int debugsw;
 
 int nolist   = 0;
 char *formsw = NULL;
-pid_t xpid = 0;
 
 
 /* mhparse.c */
@@ -35,8 +36,8 @@ void content_error(char *, CT, char *, ...);
 void flush_errors(void);
 
 /* mhlistsbr.c */
-int list_switch(CT, int, int, int, int);
-int list_content(CT, int, int, int, int);
+int list_switch(CT, int, int, int);
+int list_content(CT, int, int, int);
 
 /*
 ** prototypes
@@ -51,7 +52,7 @@ static void show_single_message(CT, char *);
 static void DisplayMsgHeader(CT, char *);
 static int show_switch(CT, int);
 static int show_content(CT, int);
-static int show_content_aux2(CT, int, char *, char *, int, int, int, int);
+static int show_content_aux2(CT, int, char *, char *, int, int, int);
 static int show_text(CT, int);
 static int show_multi(CT, int);
 static int show_multi_internal(CT, int);
@@ -75,7 +76,7 @@ show_all_messages(CT *cts)
        ** for showing headers of MIME messages.
        */
        if (!formsw)
-               formsw = getcpy(etcpath("mhl.headers"));
+               formsw = mh_xstrdup(etcpath("mhl.headers"));
 
        /*
        ** If form is "mhl.null", suppress display of header.
@@ -86,9 +87,16 @@ show_all_messages(CT *cts)
        for (ctp = cts; *ctp; ctp++) {
                ct = *ctp;
 
-               /* if top-level type is ok, then display message */
-               if (type_ok(ct, 1))
-                       show_single_message(ct, formsw);
+               if (!type_ok(ct, 1)) {  /* top-level type */
+                       continue;
+               }
+               if (cts[1]) {
+                       if (ctp != cts) {
+                               printf("\n\n");
+                       }
+                       printf(">>> Message %s\n\n", ct->c_file);
+               }
+               show_single_message(ct, formsw);
        }
 }
 
@@ -100,9 +108,6 @@ show_all_messages(CT *cts)
 static void
 show_single_message(CT ct, char *form)
 {
-       sigset_t set, oset;
-       int status;
-
        /*
        ** Allow user executable bit so that temporary directories created by
        ** the viewer (e.g., lynx) are going to be accessible
@@ -115,8 +120,6 @@ show_single_message(CT ct, char *form)
        */
        if (form)
                DisplayMsgHeader(ct, form);
-       else
-               xpid = 0;
 
        /* Show the body of the message */
        show_switch(ct, 0);
@@ -128,23 +131,6 @@ show_single_message(CT ct, char *form)
        if (ct->c_ceclosefnx)
                (*ct->c_ceclosefnx) (ct);
 
-       /* block a few signals */
-       sigemptyset(&set);
-       sigaddset(&set, SIGHUP);
-       sigaddset(&set, SIGINT);
-       sigaddset(&set, SIGQUIT);
-       sigaddset(&set, SIGTERM);
-       sigprocmask(SIG_BLOCK, &set, &oset);
-
-       while (wait(&status) != NOTOK) {
-               pidcheck(status);
-               continue;
-       }
-
-       /* reset the signal mask */
-       sigprocmask(SIG_SETMASK, &oset, &set);
-
-       xpid = 0;
        flush_errors();
 }
 
@@ -171,18 +157,18 @@ DisplayMsgHeader(CT ct, char *form)
 
        switch (child_id = fork()) {
        case NOTOK:
-               adios("fork", "unable to");
+               adios(EX_OSERR, "fork", "unable to");
                /* NOTREACHED */
 
        case OK:
                execvp("mhl", vec);
                fprintf(stderr, "unable to exec ");
                perror("mhl");
-               _exit(-1);
+               _exit(EX_OSERR);
                /* NOTREACHED */
 
        default:
-               xpid = -child_id;
+               pidcheck(pidwait(child_id, NOTOK));
                break;
        }
 }
@@ -230,7 +216,7 @@ show_switch(CT ct, int alternate)
                break;
 
        default:
-               adios(NULL, "unknown content type %d", ct->c_type);
+               adios(EX_DATAERR, NULL, "unknown content type %d", ct->c_type);
                break;
        }
 
@@ -249,13 +235,13 @@ show_content(CT ct, int alternate)
        CI ci = &ct->c_ctinfo;
 
        /* Check for mhshow-show-type/subtype */
-       snprintf(buffer, sizeof(buffer), "%s-show-%s/%s",
-                               invo_name, ci->ci_type, ci->ci_subtype);
+       snprintf(buffer, sizeof(buffer), "mhshow-show-%s/%s",
+                               ci->ci_type, ci->ci_subtype);
        if ((cp = context_find(buffer)) && *cp != '\0')
                return show_content_aux(ct, alternate, cp, NULL);
 
        /* Check for mhshow-show-type */
-       snprintf(buffer, sizeof(buffer), "%s-show-%s", invo_name, ci->ci_type);
+       snprintf(buffer, sizeof(buffer), "mhshow-show-%s", ci->ci_type);
        if ((cp = context_find(buffer)) && *cp != '\0')
                return show_content_aux(ct, alternate, cp, NULL);
 
@@ -264,7 +250,7 @@ show_content(CT ct, int alternate)
 
        /* complain if we are not a part of a multipart/alternative */
        if (!alternate)
-               content_error(NULL, ct, "don't know how to display content");
+               return show_content_aux(ct, alternate, "%l", NULL);
 
        return NOTOK;
 }
@@ -273,12 +259,11 @@ show_content(CT ct, int alternate)
 /*
 ** Parse the display string for displaying generic content
 */
-
 int
 show_content_aux(CT ct, int alternate, char *cp, char *cracked)
 {
        int fd, len, buflen, quoted;
-       int xstdin, xlist, xtty;
+       int xstdin, xlist;
        char *bp, *pp, *file, buffer[BUFSIZ];
        CI ci = &ct->c_ctinfo;
 
@@ -298,7 +283,6 @@ show_content_aux(CT ct, int alternate, char *cp, char *cracked)
 
        xlist  = 0;
        xstdin = 0;
-       xtty   = 0;
 
        if (cracked) {
                strncpy(buffer, cp, sizeof(buffer));
@@ -335,6 +319,12 @@ show_content_aux(CT ct, int alternate, char *cp, char *cracked)
                                }
                                break;
 
+                       case 'c':
+                               /* insert charset */
+                               strncpy(bp, ct->c_charset ? ct->c_charset :
+                                               "US-ASCII", buflen);
+                               break;
+
                        case 'd':
                                /* insert content description */
                                if (ct->c_descr) {
@@ -342,19 +332,13 @@ show_content_aux(CT ct, int alternate, char *cp, char *cracked)
 
                                        s = trimcpy(ct->c_descr);
                                        strncpy(bp, s, buflen);
-                                       free(s);
+                                       mh_free0(&s);
                                }
                                break;
 
-                       case 'e':
-                               /* exclusive execution */
-                               xtty = 1;
-                               break;
-
                        case 'F':
-                               /* %e, %f, and stdin is terminal not content */
+                               /* %f, and stdin is terminal not content */
                                xstdin = 1;
-                               xtty = 1;
                                /* and fall... */
 
                        case 'f':
@@ -373,7 +357,6 @@ show_content_aux(CT ct, int alternate, char *cp, char *cracked)
                                pp = bp;
                                break;
 
-                       case 'p':
                        case 'l':
                                /*
                                ** display listing prior to displaying content
@@ -446,41 +429,20 @@ raw:
                }
        }
 
-       if (buflen <= 0 || (ct->c_termproc &&
-                       (size_t)buflen <= strlen(ct->c_termproc))) {
-               /*
-               ** content_error would provide a more useful error message
-               ** here, except that if we got overrun, it probably would
-               ** too.
-               */
-               fprintf(stderr, "Buffer overflow constructing show command!\n");
-               return NOTOK;
-       }
-
-       /* use charset string to modify display method */
-       if (ct->c_termproc) {
-               char term[BUFSIZ];
-
-               strncpy(term, buffer, sizeof(term));
-               snprintf(buffer, sizeof(buffer), ct->c_termproc, term);
-       }
-
 got_command:
        return show_content_aux2(ct, alternate, cracked, buffer,
-                       fd, xlist, xstdin, xtty);
+                       fd, xlist, xstdin);
 }
 
 
 /*
 ** Routine to actually display the content
 */
-
 static int
 show_content_aux2(CT ct, int alternate, char *cracked,
-       char *buffer, int fd, int xlist, int xstdin, int xtty)
+       char *buffer, int fd, int xlist, int xstdin)
 {
        pid_t child_id;
-       char *vec[4], exec[BUFSIZ + sizeof "exec "];
 
        if (debugsw || cracked) {
                fflush(stdout);
@@ -496,27 +458,13 @@ show_content_aux2(CT ct, int alternate, char *cracked,
                        fprintf(stderr, " using command %s\n", buffer);
        }
 
-       if (xpid < 0 || (xtty && xpid)) {
-               if (xpid < 0)
-                       xpid = -xpid;
-               pidcheck(pidwait(xpid, NOTOK));
-               xpid = 0;
-       }
-
        if (xlist) {
                if (ct->c_type == CT_MULTIPART)
-                       list_content(ct, -1, 1, 0, 0);
+                       list_content(ct, -1, 0, 0);
                else
-                       list_switch(ct, -1, 1, 0, 0);
+                       list_switch(ct, -1, 0, 0);
        }
 
-       snprintf(exec, sizeof(exec), "exec %s", buffer);
-
-       vec[0] = "/bin/sh";
-       vec[1] = "-c";
-       vec[2] = exec;
-       vec[3] = NULL;
-
        fflush(stdout);
 
        switch (child_id = fork()) {
@@ -531,10 +479,10 @@ show_content_aux2(CT ct, int alternate, char *cracked,
                if (!xstdin)
                        dup2(fd, 0);
                close(fd);
-               execvp("/bin/sh", vec);
+               execlp("/bin/sh", "/bin/sh", "-c", buffer, NULL);
                fprintf(stderr, "unable to exec ");
                perror("/bin/sh");
-               _exit(-1);
+               _exit(EX_OSERR);
                /* NOTREACHED */
 
        default:
@@ -558,13 +506,13 @@ show_text(CT ct, int alternate)
        CI ci = &ct->c_ctinfo;
 
        /* Check for mhshow-show-type/subtype */
-       snprintf(buffer, sizeof(buffer), "%s-show-%s/%s",
-                       invo_name, ci->ci_type, ci->ci_subtype);
+       snprintf(buffer, sizeof(buffer), "mhshow-show-%s/%s",
+                       ci->ci_type, ci->ci_subtype);
        if ((cp = context_find(buffer)) && *cp != '\0')
                return show_content_aux(ct, alternate, cp, NULL);
 
        /* Check for mhshow-show-type */
-       snprintf(buffer, sizeof(buffer), "%s-show-%s", invo_name, ci->ci_type);
+       snprintf(buffer, sizeof(buffer), "mhshow-show-%s", ci->ci_type);
        if ((cp = context_find(buffer)) && *cp != '\0')
                return show_content_aux(ct, alternate, cp, NULL);
 
@@ -573,9 +521,14 @@ show_text(CT ct, int alternate)
        ** if it is not a text part of a multipart/alternative
        */
        if (!alternate || ct->c_subtype == TEXT_PLAIN) {
-               snprintf(buffer, sizeof(buffer), "%%p%s '%%F'", defaultpager);
-               cp = (ct->c_showproc = getcpy(buffer));
-               return show_content_aux(ct, alternate, cp, NULL);
+               if (ct->c_charset && !is_native_charset(ct->c_charset)) {
+                       snprintf(buffer, sizeof(buffer), "%%liconv -f '%s'",
+                                       ct->c_charset);
+               } else {
+                       snprintf(buffer, sizeof(buffer), "%%lcat");
+               }
+               ct->c_showproc = mh_xstrdup(buffer);
+               return show_content_aux(ct, alternate, ct->c_showproc, NULL);
        }
 
        return NOTOK;
@@ -593,13 +546,13 @@ show_multi(CT ct, int alternate)
        CI ci = &ct->c_ctinfo;
 
        /* Check for mhshow-show-type/subtype */
-       snprintf(buffer, sizeof(buffer), "%s-show-%s/%s",
-                       invo_name, ci->ci_type, ci->ci_subtype);
+       snprintf(buffer, sizeof(buffer), "mhshow-show-%s/%s",
+                       ci->ci_type, ci->ci_subtype);
        if ((cp = context_find(buffer)) && *cp != '\0')
                return show_multi_aux(ct, alternate, cp);
 
        /* Check for mhshow-show-type */
-       snprintf(buffer, sizeof(buffer), "%s-show-%s", invo_name, ci->ci_type);
+       snprintf(buffer, sizeof(buffer), "mhshow-show-%s", ci->ci_type);
        if ((cp = context_find(buffer)) && *cp != '\0')
                return show_multi_aux(ct, alternate, cp);
 
@@ -706,7 +659,7 @@ static int
 show_multi_aux(CT ct, int alternate, char *cp)
 {
        int len, buflen, quoted;
-       int xlist, xtty;
+       int xlist;
        char *bp, *pp, *file, buffer[BUFSIZ];
        struct multipart *m = (struct multipart *) ct->c_ctparams;
        struct part *part;
@@ -728,7 +681,7 @@ show_multi_aux(CT ct, int alternate, char *cp)
                                return NOTOK;
 
                        /* I'm not sure if this is necessary? */
-                       p->c_storage = getcpy(file);
+                       p->c_storage = mh_xstrdup(file);
 
                        if (p->c_showproc && strcmp(p->c_showproc, "true")==0)
                                return (alternate ? DONE : OK);
@@ -737,7 +690,6 @@ show_multi_aux(CT ct, int alternate, char *cp)
        }
 
        xlist = 0;
-       xtty = 0;
 
        /* get buffer ready to go */
        bp = buffer;
@@ -768,6 +720,12 @@ show_multi_aux(CT ct, int alternate, char *cp)
                                }
                                break;
 
+                       case 'c':
+                               /* insert charset */
+                               strncpy(bp, ct->c_charset ? ct->c_charset :
+                                               "US-ASCII", buflen);
+                               break;
+
                        case 'd':
                                /* insert content description */
                                if (ct->c_descr) {
@@ -775,20 +733,11 @@ show_multi_aux(CT ct, int alternate, char *cp)
 
                                        s = trimcpy(ct->c_descr);
                                        strncpy(bp, s, buflen);
-                                       free(s);
+                                       mh_free0(&s);
                                }
                                break;
 
-                       case 'e':
-                               /* exclusive execution */
-                               xtty = 1;
-                               break;
-
                        case 'F':
-                               /* %e and %f */
-                               xtty = 1;
-                               /* and fall... */
-
                        case 'f':
                                /* insert filename(s) containing content */
                        {
@@ -814,7 +763,6 @@ show_multi_aux(CT ct, int alternate, char *cp)
                        }
                        break;
 
-                       case 'p':
                        case 'l':
                                /*
                                ** display listing prior to displaying content
@@ -887,27 +835,8 @@ raw:
                }
        }
 
-       if (buflen <= 0 || (ct->c_termproc &&
-                       (size_t)buflen <= strlen(ct->c_termproc))) {
-               /*
-               ** content_error would provide a more useful error message
-               ** here, except that if we got overrun, it probably would
-               ** too.
-               */
-               fprintf(stderr, "Buffer overflow constructing show command!\n");
-               return NOTOK;
-       }
-
-       /* use charset string to modify display method */
-       if (ct->c_termproc) {
-               char term[BUFSIZ];
-
-               strncpy(term, buffer, sizeof(term));
-               snprintf(buffer, sizeof(buffer), ct->c_termproc, term);
-       }
-
        return show_content_aux2(ct, alternate, NULL, buffer,
-                       NOTOK, xlist, 0, xtty);
+                       NOTOK, xlist, 0);
 }
 
 
@@ -922,13 +851,13 @@ show_message_rfc822(CT ct, int alternate)
        CI ci = &ct->c_ctinfo;
 
        /* Check for mhshow-show-type/subtype */
-       snprintf(buffer, sizeof(buffer), "%s-show-%s/%s",
-                               invo_name, ci->ci_type, ci->ci_subtype);
+       snprintf(buffer, sizeof(buffer), "mhshow-show-%s/%s",
+                               ci->ci_type, ci->ci_subtype);
        if ((cp = context_find(buffer)) && *cp != '\0')
                return show_content_aux(ct, alternate, cp, NULL);
 
        /* Check for mhshow-show-type */
-       snprintf(buffer, sizeof(buffer), "%s-show-%s", invo_name, ci->ci_type);
+       snprintf(buffer, sizeof(buffer), "mhshow-show-%s", ci->ci_type);
        if ((cp = context_find(buffer)) && *cp != '\0')
                return show_content_aux(ct, alternate, cp, NULL);
 
@@ -937,13 +866,13 @@ show_message_rfc822(CT ct, int alternate)
 
        /* default method for message/rfc822 */
        if (ct->c_subtype == MESSAGE_RFC822) {
-               cp = (ct->c_showproc = getcpy("%pshow -file '%F'"));
+               cp = (ct->c_showproc = mh_xstrdup("%lshow -file %F"));
                return show_content_aux(ct, alternate, cp, NULL);
        }
 
        /* complain if we are not a part of a multipart/alternative */
        if (!alternate)
-               content_error(NULL, ct, "don't know how to display content");
+               return show_content_aux(ct, alternate, "%l", NULL);
 
        return NOTOK;
 }
@@ -956,31 +885,45 @@ show_message_rfc822(CT ct, int alternate)
 static int
 show_partial(CT ct, int alternate)
 {
-       content_error(NULL, ct,
-               "in order to display this message, you must reassemble it");
+       show_content_aux(ct, alternate, "%l", NULL);
+       puts("in order to display this message, you must reassemble it");
        return NOTOK;
 }
 
 
 /*
-** Show content of type "message/external".
-**
-** THE ERROR CHECKING IN THIS ONE IS NOT DONE YET.
+** Show how to retrieve content of type "message/external".
 */
-
 static int
 show_external(CT ct, int alternate)
 {
-       struct exbody *e = (struct exbody *) ct->c_ctparams;
-       CT p = e->eb_content;
-
-       if (!type_ok(p, 0))
-               return OK;
-
-       return show_switch(p, alternate);
-
-#if 0
-       content_error(NULL, p, "don't know how to display content");
-       return NOTOK;
-#endif
+       char **ap, **ep;
+       char *msg;
+       FILE *fp;
+       char buf[BUFSIZ];
+
+       msg = add("You need to fetch the contents yourself:\n", NULL);
+       ap = ct->c_ctinfo.ci_attrs;
+       ep = ct->c_ctinfo.ci_values;
+       for (; *ap; ap++, ep++) {
+               msg = add(concat("\t", *ap, ": ", *ep, NULL), msg);
+       }
+       if (!(fp = fopen(ct->c_file, "r"))) {
+               adios(EX_IOERR, ct->c_file, "unable to open");
+       }
+       fseek(fp, ct->c_begin, SEEK_SET);
+       while (!feof(fp) && ftell(fp) < ct->c_end) {
+               if (!fgets(buf, sizeof buf, fp)) {
+                       adios(EX_IOERR, ct->c_file, "unable to read");
+               }
+               *strchr(buf, '\n') = '\0';
+               if (!*buf) {
+                       continue;  /* skip empty lines */
+               }
+               msg = add(concat("\t", buf, "\n", NULL), msg);
+       }
+       fclose(fp);
+       show_content_aux(ct, alternate, "%l", NULL);
+       fputs(msg, stdout);
+       return OK;
 }