Hi

Reply to mime messages is an old problem. I have an idea to workaround
or fix this. Instand of adding mime to mhl, repl could also first decode
mime before pipe the mail to mhl. This can be done by mhshow.

I have attached a patch for this.

This approatch has currently two problems:

* mhshow can be configured to display parts in a graphical programm. This
  can lead to unexpected behavior on repl (i.e. start plaing musik).

I belive there are two options to fixed this problem. First the -textonly
swtich can be used. In some probably uncommon setups (i.e. text to speech)
this still can lead to problems.

The secound option is a bit more complex. Instand of only depending on
the programm name the config can be extended to also depend on the
calling programm. So you can config diffrent options depending on which
nmh programm called another nmh programm. This could be done by (ab)using
argv[0].

* mhshow display string can contain '%l' which leads to a listing prior
  to displaying content. This listing is contained in the draft.

To fix this I would suggest to remove the '%l' from the display string
escapes and create a switch for that. Then you can't enable/disable this
per part.

What do you think about this patch? Did I missed some problems?

Philipp
From 34d2763d73edf12e4b4cfb45e063e1ffa19519c3 Mon Sep 17 00:00:00 2001
From: Philipp Takacs <phil...@bureaucracy.de>
Date: Sat, 5 Feb 2022 12:21:35 +0100
Subject: [PATCH] repl: pipe mail through mhshow

When reply to a MIME message the mhshow will decode the mime message
before mhl will get it to create a reply draft. This makes it more
convinient to reply to a MIME message.

Problems:

* mhshow can be configured to display parts in a graphical programm. This
  can lead to unexpected behavior on repl (i.e. start plaing musik).

* mhshow display string can contain '%l' which leads to a listing prior
  to displaying content. This listing is contained in the draft.
---
 uip/replsbr.c | 106 ++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 76 insertions(+), 30 deletions(-)

diff --git a/uip/replsbr.c b/uip/replsbr.c
index ef4925ae..2dce085e 100644
--- a/uip/replsbr.c
+++ b/uip/replsbr.c
@@ -436,6 +436,10 @@ replfilter (FILE *in, FILE *out, char *filter, int fmtproc)
     char *errstr;
     char **arglist;
     int argnum;
+    int mailpipe[2];
+    char *mhshow;
+    char **mhshowargs;
+    int mshowargnum;
 
     if (filter == NULL)
 	return;
@@ -447,48 +451,90 @@ replfilter (FILE *in, FILE *out, char *filter, int fmtproc)
     lseek(fileno(in), 0, SEEK_SET);
 
     arglist = argsplit(mhlproc, &mhl, &argnum);
+    mhshowargs = argsplit(showmimeproc, &mhshow, &mshowargnum);
 
     switch (pid = fork()) {
 	case NOTOK:
 	    adios ("fork", "unable to");
 
 	case OK:
-	    dup2 (fileno (in), fileno (stdin));
-	    dup2 (fileno (out), fileno (stdout));
-
-	    /*
-	     * We're not allocating the memory for the extra arguments,
-	     * because we never call arglist_free().  But if we ever change
-	     * that be sure to use getcpy() for the extra arguments.
-	     */
-	    arglist[argnum++] = "-form";
-	    arglist[argnum++] = filter;
-	    arglist[argnum++] = "-noclear";
-
-	    switch (fmtproc) {
-	    case 1:
-		arglist[argnum++] = "-fmtproc";
-		arglist[argnum++] = formatproc;
-		break;
-	    case 0:
-		arglist[argnum++] = "-nofmtproc";
-		break;
+
+	    if (pipe(mailpipe) == -1) {
+		adios("pipe", "can't create pipe");
 	    }
 
-	    arglist[argnum++] = NULL;
+	    switch (pid = fork()) {
+		case NOTOK:
+		    adios ("fork", "unable to");
+
+		case OK:
+		    dup2 (fileno (in), fileno (stdin));
+		    dup2 (mailpipe[1], fileno (stdout));
+		    close(fileno(in));
+		    close(fileno(out));
+		    close(mailpipe[0]);
+		    close(mailpipe[1]);
+
+		    mhshowargs[argnum++] = "-file";
+		    mhshowargs[argnum++] = "-";
+		    mhshowargs[argnum++] = "-concat";
+		    mhshowargs[argnum++] = NULL;
+
+		    execvp (mhshow, mhshowargs);
+		    errstr = strerror(errno);
+		    if (write(2, "unable to exec ", 15) < 0  ||
+			write(2, mhshow, strlen(mhshow)) < 0  ||
+			write(2, ": ", 2) < 0  ||
+			write(2, errstr, strlen(errstr)) < 0  ||
+			write(2, "\n", 1) < 0) {
+			advise ("stderr", "write");
+		    }
+		    _exit(1);
+		default:
+		    dup2 (mailpipe[0], fileno (stdin));
+		    dup2 (fileno (out), fileno (stdout));
+		    close(fileno(in));
+		    close(fileno(out));
+		    close(mailpipe[0]);
+		    close(mailpipe[1]);
+
+		    /*
+		     * We're not allocating the memory for the extra arguments,
+		     * because we never call arglist_free().  But if we ever change
+		     * that be sure to use getcpy() for the extra arguments.
+		     */
+		    arglist[argnum++] = "-nomoreproc";
+		    arglist[argnum++] = "-form";
+		    arglist[argnum++] = filter;
+		    arglist[argnum++] = "-noclear";
+
+		    switch (fmtproc) {
+			case 1:
+			    arglist[argnum++] = "-fmtproc";
+			    arglist[argnum++] = formatproc;
+			    break;
+			case 0:
+			    arglist[argnum++] = "-nofmtproc";
+			    break;
+		    }
+
+		    arglist[argnum++] = NULL;
 
-	    execvp (mhl, arglist);
-	    errstr = strerror(errno);
-	    if (write(2, "unable to exec ", 15) < 0  ||
-		write(2, mhlproc, strlen(mhlproc)) < 0  ||
-		write(2, ": ", 2) < 0  ||
-		write(2, errstr, strlen(errstr)) < 0  ||
-		write(2, "\n", 1) < 0) {
-		advise ("stderr", "write");
+		    execvp (mhl, arglist);
+		    errstr = strerror(errno);
+		    if (write(2, "unable to exec ", 15) < 0  ||
+			write(2, mhlproc, strlen(mhlproc)) < 0  ||
+			write(2, ": ", 2) < 0  ||
+			write(2, errstr, strlen(errstr)) < 0  ||
+			write(2, "\n", 1) < 0) {
+			advise ("stderr", "write");
+		    }
+		    _exit(1);
 	    }
-	    _exit(1);
 
 	default:
+	    close(fileno(in));
+	    close(fileno(out));
 	    if (pidXwait (pid, mhl))
 		done (1);
 	    fseek (out, 0L, SEEK_END);
-- 
2.30.2

Reply via email to