Don't do a shell `exec' on mhshow-show-* contents to make `foo; bar' possible.
[mmh] / uip / mhshowsbr.c
index 75633b7..e2cde4d 100644 (file)
@@ -9,7 +9,6 @@
 #include <h/mh.h>
 #include <fcntl.h>
 #include <h/signals.h>
-#include <h/md5.h>
 #include <errno.h>
 #include <setjmp.h>
 #include <signal.h>
@@ -336,6 +335,13 @@ show_content_aux(CT ct, int alternate, char *cp, char *cracked)
                                }
                                break;
 
+                       case 'c':
+                               /* insert charset */
+                               if (ct->c_charset) {
+                                       strncpy(bp, ct->c_charset, buflen);
+                               }
+                               break;
+
                        case 'd':
                                /* insert content description */
                                if (ct->c_descr) {
@@ -447,25 +453,6 @@ 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);
@@ -481,7 +468,6 @@ show_content_aux2(CT ct, int alternate, char *cracked,
        char *buffer, int fd, int xlist, int xstdin, int xtty)
 {
        pid_t child_id;
-       char *vec[4], exec[BUFSIZ + sizeof "exec "];
 
        if (debugsw || cracked) {
                fflush(stdout);
@@ -511,13 +497,6 @@ show_content_aux2(CT ct, int alternate, char *cracked,
                        list_switch(ct, -1, 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()) {
@@ -532,7 +511,7 @@ 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);
@@ -574,7 +553,12 @@ 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);
+               if (!check_charset(ct->c_charset, strlen(ct->c_charset))) {
+                       snprintf(buffer, sizeof(buffer), "%%liconv -f '%s'",
+                                       ct->c_charset);
+               } else {
+                       snprintf(buffer, sizeof(buffer), "%%lcat");
+               }
                cp = (ct->c_showproc = getcpy(buffer));
                return show_content_aux(ct, alternate, cp, NULL);
        }
@@ -769,6 +753,13 @@ show_multi_aux(CT ct, int alternate, char *cp)
                                }
                                break;
 
+                       case 'c':
+                               /* insert charset */
+                               if (ct->c_charset) {
+                                       strncpy(bp, ct->c_charset, buflen);
+                               }
+                               break;
+
                        case 'd':
                                /* insert content description */
                                if (ct->c_descr) {
@@ -888,25 +879,6 @@ 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);
 }
@@ -964,24 +936,34 @@ show_partial(CT ct, int alternate)
 
 
 /*
-** 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:", NULL);
+       ap = ct->c_ctinfo.ci_attrs;
+       ep = ct->c_ctinfo.ci_values;
+       for (; *ap; ap++, ep++) {
+               msg = add(concat("\n\t", *ap, ": ", *ep, NULL), msg);
+       }
+       if (!(fp = fopen(ct->c_file, "r"))) {
+               adios(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(ct->c_file, "unable to read");
+               }
+               *strchr(buf, '\n') = '\0';
+               msg = add(concat("\n\t", buf, NULL), msg);
+       }
+       fclose(fp);
+       content_error(NULL, ct, msg);
+       return OK;
 }