]> diplodocus.org Git - nmh/blobdiff - uip/mhlsbr.c
getpass.c: Move interface to own file.
[nmh] / uip / mhlsbr.c
index df0e24bf101ebf63a44cd49767acebf3a2e55135..0fbdc6cd6546fe3fc0865ba35b15dbcbee552730 100644 (file)
@@ -5,12 +5,28 @@
  * complete copyright information.
  */
 
-#include <h/mh.h>
-#include <h/signals.h>
-#include <h/addrsbr.h>
-#include <h/fmt_scan.h>
-#include <h/tws.h>
-#include <h/utils.h>
+#include "h/mh.h"
+#include "sbr/r1bindex.h"
+#include "sbr/snprintb.h"
+#include "sbr/copyip.h"
+#include "sbr/discard.h"
+#include "sbr/trimcpy.h"
+#include "sbr/vfgets.h"
+#include "sbr/check_charset.h"
+#include "sbr/getcpy.h"
+#include "sbr/brkstring.h"
+#include "sbr/ambigsw.h"
+#include "sbr/pidstatus.h"
+#include "sbr/print_version.h"
+#include "sbr/print_help.h"
+#include "sbr/arglist.h"
+#include "sbr/error.h"
+#include "h/signals.h"
+#include "h/addrsbr.h"
+#include "h/fmt_scan.h"
+#include "h/tws.h"
+#include "h/done.h"
+#include "h/utils.h"
 #include "sbr/m_popen.h"
 #include <setjmp.h>
 #include <sys/types.h>
@@ -259,9 +275,9 @@ static char *addrcomps[] = {
 static int bellflg   = 0;
 static int clearflg  = 0;
 static int dashstuff = 0;
-static int dobody    = 1;
-static int forwflg   = 0;
-static int forwall   = 0;
+static bool dobody = true;
+static bool forwflg;
+static bool forwall;
 
 static int sleepsw = NOTOK;
 
@@ -270,7 +286,7 @@ static int volume = 0;
 static int issue = 0;
 
 static int exitstat = 0;
-static int mhldebug = 0;
+static bool mhldebug;
 
 static int filesize = 0;
 
@@ -298,14 +314,11 @@ static int num_ignores = 0;
 static char *ignores[MAXARGS];
 
 static  jmp_buf env;
-static  jmp_buf mhlenv;
 
 static char delim3[] =         /* from forw.c */
     "\n----------------------------------------------------------------------\n\n";
 static char delim4[] = "\n------------------------------\n\n";
 
-static FILE *(*mhl_action)(char *);
-
 /*
  * prototypes
  */
@@ -325,6 +338,7 @@ static void putcomp (struct mcomp *, struct mcomp *, int);
 static char *oneline (char *, unsigned long);
 static void putstr (char *, unsigned long);
 static void putch (char, unsigned long);
+static bool linefeed_typed(void);
 static void intrser (int);
 static void pipeser (int);
 static void quitser (int);
@@ -339,7 +353,8 @@ static void compile_filterargs (void);
 int
 mhl (int argc, char **argv)
 {
-    int length = 0, nomore = 0;
+    int length = 0;
+    bool nomore = false;
     unsigned int i, vecp = 0;
     int width = 0;
     char *cp, *folder = NULL, *form = NULL;
@@ -353,7 +368,7 @@ mhl (int argc, char **argv)
     argp = arguments;
 
     if ((cp = getenv ("MHLDEBUG")) && *cp)
-       mhldebug++;
+       mhldebug = true;
 
     while ((cp = *argp++)) {
        if (*cp == '-') {
@@ -406,7 +421,7 @@ mhl (int argc, char **argv)
                        mhladios (NULL, "missing argument to %s", argp[-2]);
                    continue;
                case NPROGSW:
-                   nomore++;
+                   nomore = true;
                    continue;
 
                case FMTPROCSW:
@@ -448,10 +463,10 @@ mhl (int argc, char **argv)
                    continue;
 
                case FORW2SW: 
-                   forwall++;
+                   forwall = true;
                    /* FALLTHRU */
                case FORW1SW: 
-                   forwflg++;
+                   forwflg = true;
                    clearflg = -1;/* XXX */
                    continue;
 
@@ -463,7 +478,7 @@ mhl (int argc, char **argv)
                    continue;
 
                case NBODYSW: 
-                   dobody = 0;
+                   dobody = false;
                    continue;
            }
        }
@@ -475,12 +490,8 @@ mhl (int argc, char **argv)
 
     if (isatty (fileno (stdout))) {
        if (!nomore && moreproc && *moreproc != '\0') {
-           if (mhl_action) {
-               SIGNAL (SIGINT, SIG_IGN);
-               SIGNAL2 (SIGQUIT, quitser);
-           }
            SIGNAL2 (SIGPIPE, pipeser);
-           m_popen (moreproc, mhl_action != NULL);
+           m_popen(moreproc, false);
            ontty = PITTY;
        } else {
            SIGNAL (SIGINT, SIG_IGN);
@@ -747,7 +758,7 @@ evalvar (struct mcomp *c1)
     if (!strcasecmp (name, "length"))
        return ptoi (name, &c1->c_length);
     if (!strcasecmp (name, "nodashstuffing"))
-       return (dashstuff = -1);
+       return dashstuff = -1;
 
     for (ap = triples; ap->t_name; ap++)
        if (!strcasecmp (ap->t_name, name)) {
@@ -879,7 +890,7 @@ process (char *folder, char *fname, int ofilen, int ofilec)
     switch (setjmp (env)) {
        case OK: 
            if (fname) {
-               fp = mhl_action ? (*mhl_action) (fname) : fopen (fname, "r");
+               fp = fopen(fname, "r");
                if (fp == NULL) {
                    advise (fname, "unable to open");
                    exitstat++;
@@ -911,7 +922,7 @@ process (char *folder, char *fname, int ofilen, int ofilec)
        default:
            if (ontty != PITTY)
                SIGNAL (SIGINT, SIG_IGN);
-           if (mhl_action == NULL && fp != stdin && fp != NULL)
+           if (fp != stdin && fp != NULL)
                fclose (fp);
             free(holder.c_text);
             holder.c_text = NULL;
@@ -938,7 +949,7 @@ mhlfile (FILE *fp, char *mname, int ofilen, int ofilec)
        if (digest)
            fputs(ofilen == 1 ? delim3 : delim4, stdout);
        else {
-           printf ("\n-------");
+           fputs("\n-------", stdout);
            if (ofilen == 1)
                printf (" Forwarded Message%s", PLURALS(ofilec));
            else
@@ -960,7 +971,6 @@ mhlfile (FILE *fp, char *mname, int ofilen, int ofilec)
                break;
 
            case ISTTY: 
-               strncpy (buf, "\n", sizeof(buf));
                if (ofilec > 1) {
                    if (SOprintf ("Press <return> to list \"%s\"...", mname)) {
                        if (ofilen > 1)
@@ -968,12 +978,8 @@ mhlfile (FILE *fp, char *mname, int ofilen, int ofilec)
                        printf ("Press <return> to list \"%s\"...", mname);
                    }
                    fflush (stdout);
-                   buf[0] = 0;
-                   if (read (fileno (stdout), buf, sizeof(buf)) < 0) {
-                       advise ("stdout", "read");
-                   }
                }
-               if (strchr(buf, '\n')) {
+                if (ofilec == 1 || linefeed_typed()) {
                    if ((global.c_flags & CLEARSCR))
                        nmh_clear_screen ();
                }
@@ -1111,7 +1117,7 @@ mcomp_flags (char *name)
 
     for (ap = pairs; ap->p_name; ap++)
        if (!strcasecmp (ap->p_name, name))
-           return (ap->p_flags);
+           return ap->p_flags;
 
     return 0;
 }
@@ -1277,7 +1283,8 @@ putcomp (struct mcomp *c1, struct mcomp *c2, int flag)
 {
     char *text; /* c1's text, or the name as a fallback. */
     char *trimmed_prefix;
-    int count, cchdr;
+    int count;
+    bool cchdr;
     char *cp;
     const int utf8 = strcasecmp(get_charset(), "UTF-8") == 0;
 
@@ -1292,7 +1299,7 @@ putcomp (struct mcomp *c1, struct mcomp *c2, int flag)
      * blank lines. */
     trimmed_prefix = rtrim(mh_xstrdup(FENDNULL(text)));
 
-    cchdr = 0;
+    cchdr = false;
     lm = 0;
     llim = c1->c_length ? c1->c_length : -1;
     wid = c1->c_width ? c1->c_width : global.c_width;
@@ -1335,7 +1342,7 @@ putcomp (struct mcomp *c1, struct mcomp *c2, int flag)
            if (!(c1->c_flags & SPLIT))
                c1->c_flags |= HDROUTPUT;
 
-       cchdr++;
+       cchdr = true;
        if ((count = c1->c_cwidth - strlen(text) - 2) > 0)
            while (count--)
                putstr (" ", c1->c_flags);
@@ -1354,7 +1361,7 @@ putcomp (struct mcomp *c1, struct mcomp *c2, int flag)
        if (!(c1->c_flags & SPLIT))
            c2->c_flags |= HDROUTPUT;
 
-       cchdr++;
+       cchdr = true;
        if ((count = c1->c_cwidth - strlen (c2->c_name) - 2) > 0)
            while (count--)
                putstr (" ", c1->c_flags);
@@ -1407,18 +1414,18 @@ putcomp (struct mcomp *c1, struct mcomp *c2, int flag)
 static char *
 oneline (char *stuff, unsigned long flags)
 {
-    int spc;
+    bool spc;
     char *cp, *ret;
 
     if (onelp == NULL)
        onelp = stuff;
     if (*onelp == 0)
-       return (onelp = NULL);
+       return onelp = NULL;
 
     ret = onelp;
     term = 0;
     if (flags & COMPRESS) {
-       for (spc = 1, cp = ret; *onelp; onelp++)
+       for (spc = true, cp = ret; *onelp; onelp++)
            if (isspace ((unsigned char) *onelp)) {
                if (*onelp == '\n' && (!onelp[1] || (flags & ADDRFMT))) {
                    term = '\n';
@@ -1427,12 +1434,12 @@ oneline (char *stuff, unsigned long flags)
                }
                 if (!spc) {
                     *cp++ = ' ';
-                    spc++;
+                    spc = true;
                 }
            }
            else {
                *cp++ = *onelp;
-               spc = 0;
+               spc = false;
            }
 
        *cp = 0;
@@ -1507,8 +1514,6 @@ putstr (char *string, unsigned long flags)
 static void
 putch (char ch, unsigned long flags)
 {
-    char buf[BUFSIZ];
-
     if (llim == 0)
        return;
 
@@ -1523,11 +1528,7 @@ putch (char ch, unsigned long flags)
            if (global.c_flags & BELL)
                putchar ('\007');
            fflush (stdout);
-           buf[0] = 0;
-           if (read (fileno (stdout), buf, sizeof(buf)) < 0) {
-               advise ("stdout", "read");
-           }
-           if (strchr(buf, '\n')) {
+            if (linefeed_typed()) {
                if (global.c_flags & CLEARSCR)
                    nmh_clear_screen ();
                row = 0;
@@ -1597,6 +1598,34 @@ putch (char ch, unsigned long flags)
     }
 }
 
+/* linefeed_typed() makes a single read(2) from stdin and returns true
+ * if a linefeed character is amongst the characters read.
+ * A read error is treated as if linefeed wasn't typed.
+ *
+ * Typing on a TTY can cause read() to return data without typing Enter
+ * by using the TTY's EOF character instead, normally ASCII EOT, Ctrl-D.
+ * The linefeed can also be escaped with the TTY's LNEXT character,
+ * normally ASCII SYN, Ctrl-V, by typing Ctrl-V Ctrl-J.
+ * It's not possible to distinguish between the user typing a buffer's
+ * worth of characters and then EOT, or more than the buffer can hold.
+ * Either way, the result depends on ASCII LF, either from typing Enter
+ * or an escaped Ctrl-J, being amongst the read characters.
+ */
+static bool
+linefeed_typed(void)
+{
+    char buf[128];
+    ssize_t n;
+
+    n = read(0, buf, sizeof buf);
+    if (n == -1) {
+        advise("stdin", "read");
+        return false; /* Treat as EOF. */
+    }
+
+    return memchr(buf, '\n', n);
+}
+
 
 static void
 intrser (int i)
@@ -1645,8 +1674,6 @@ static void
 mhldone (int status)
 {
     exitstat = status;
-    if (mhl_action)
-       longjmp (mhlenv, DONE);
     done (exitstat);
 }
 
@@ -1733,11 +1760,11 @@ filterbody (struct mcomp *c1, char *buf, int bufsz, int state,
      */
 
     if (pipe(fdinput) < 0) {
-       adios(NULL, "Unable to create input pipe");
+       die("Unable to create input pipe");
     }
 
     if (pipe(fdoutput) < 0) {
-       adios(NULL, "Unable to create output pipe");
+       die("Unable to create output pipe");
     }
 
     /*
@@ -1792,7 +1819,7 @@ filterbody (struct mcomp *c1, char *buf, int bufsz, int state,
         */
        _exit(0);
     case -1:
-       adios(NULL, "Unable to fork for filter writer process");
+       die("Unable to fork for filter writer process");
        break;
     }
 
@@ -1867,7 +1894,7 @@ filterbody (struct mcomp *c1, char *buf, int bufsz, int state,
        break;
 
     case -1:
-       adios(NULL, "Unable to fork format program");
+       die("Unable to fork format program");
     }
 
     /*
@@ -1890,7 +1917,7 @@ filterbody (struct mcomp *c1, char *buf, int bufsz, int state,
     }
 
     if (cc < 0) {
-       adios(NULL, "reading from formatproc");
+       die("reading from formatproc");
     }
 
     /*