* 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>
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;
static int issue = 0;
static int exitstat = 0;
-static int mhldebug = 0;
+static bool mhldebug;
static int filesize = 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
*/
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);
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;
argp = arguments;
if ((cp = getenv ("MHLDEBUG")) && *cp)
- mhldebug++;
+ mhldebug = true;
while ((cp = *argp++)) {
if (*cp == '-') {
mhladios (NULL, "missing argument to %s", argp[-2]);
continue;
case NPROGSW:
- nomore++;
+ nomore = true;
continue;
case FMTPROCSW:
continue;
case FORW2SW:
- forwall++;
+ forwall = true;
/* FALLTHRU */
case FORW1SW:
- forwflg++;
+ forwflg = true;
clearflg = -1;/* XXX */
continue;
continue;
case NBODYSW:
- dobody = 0;
+ dobody = false;
continue;
}
}
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);
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)) {
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++;
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;
if (digest)
fputs(ofilen == 1 ? delim3 : delim4, stdout);
else {
- printf ("\n-------");
+ fputs("\n-------", stdout);
if (ofilen == 1)
printf (" Forwarded Message%s", PLURALS(ofilec));
else
break;
case ISTTY:
- strncpy (buf, "\n", sizeof(buf));
if (ofilec > 1) {
if (SOprintf ("Press <return> to list \"%s\"...", mname)) {
if (ofilen > 1)
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 ();
}
for (ap = pairs; ap->p_name; ap++)
if (!strcasecmp (ap->p_name, name))
- return (ap->p_flags);
+ return ap->p_flags;
return 0;
}
{
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;
* 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;
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);
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);
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';
}
if (!spc) {
*cp++ = ' ';
- spc++;
+ spc = true;
}
}
else {
*cp++ = *onelp;
- spc = 0;
+ spc = false;
}
*cp = 0;
static void
putch (char ch, unsigned long flags)
{
- char buf[BUFSIZ];
-
if (llim == 0)
return;
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;
}
}
+/* 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)
mhldone (int status)
{
exitstat = status;
- if (mhl_action)
- longjmp (mhlenv, DONE);
done (exitstat);
}
*/
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");
}
/*
*/
_exit(0);
case -1:
- adios(NULL, "Unable to fork for filter writer process");
+ die("Unable to fork for filter writer process");
break;
}
break;
case -1:
- adios(NULL, "Unable to fork format program");
+ die("Unable to fork format program");
}
/*
}
if (cc < 0) {
- adios(NULL, "reading from formatproc");
+ die("reading from formatproc");
}
/*