#include <h/fmt_scan.h>
#include <h/tws.h>
#include <h/utils.h>
-#include <setjmp.h>
#include <signal.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <locale.h>
+#include <sysexits.h>
/*
** MAJOR BUG:
#define QUOTE '\\'
-static struct swit mhlswitches[] = {
+static struct swit switches[] = {
#define FORMSW 0
{ "form formfile", 0 },
#define WIDTHSW 1
{ "width columns", 0 },
-#define SLEEPSW 2
- { "sleep seconds", 0 },
-#define VERSIONSW 3
+#define VERSIONSW 2
{ "Version", 0 },
-#define HELPSW 4
+#define HELPSW 3
{ "help", 0 },
-#define FORW1SW 5
+#define FORW1SW 4
{ "forward", -7 },
-#define FORW2SW 6
+#define FORW2SW 5
{ "forwall", -7 },
-#define DGSTSW 7
- { "digest list", -6 },
-#define VOLUMSW 8
- { "volume number", -6 },
-#define ISSUESW 9
- { "issue number", -5 },
-#define NBODYSW 10
+#define NBODYSW 6
{ "nobody", -6 },
{ NULL, 0 }
};
+char *version=VERSION;
+
#define NOCOMPONENT 0x000001 /* don't show component name */
#define UPPERCASE 0x000002 /* display in all upper case */
#define CENTER 0x000004 /* center line */
static int forwflg = 0;
static int forwall = 0;
-static int sleepsw = NOTOK;
-
-static char *digest = NULL;
-static int volume = 0;
-static int issue = 0;
-
static int exitstat = 0;
static int mhldebug = 0;
static int num_ignores = 0;
static char *ignores[MAXARGS];
-static jmp_buf env;
-static jmp_buf mhlenv;
-
-static char delim3[] =
-"\n----------------------------------------------------------------------\n\n";
-static char delim4[] = "\n------------------------------\n\n";
-
-static FILE *(*mhl_action) () = (FILE *(*) ()) 0;
-
+volatile sig_atomic_t eflag = 0;
/*
** Redefine a couple of functions.
** These are undefined later in the code.
*/
-#define adios mhladios
-#define done mhldone
/*
** prototypes
static void putstr(char *);
static void putch(char);
static void intrser(int);
-static void mhladios(char *, char *, ...);
-static void mhldone(int);
int sc_width(void); /* from termsbr.c */
char buf[BUFSIZ], *files[MAXARGS];
char **argp, **arguments;
-#ifdef LOCALE
setlocale(LC_ALL, "");
-#endif
-
invo_name = mhbasename(argv[0]);
/* read user profile/context */
while ((cp = *argp++)) {
if (*cp == '-') {
- switch (smatch(++cp, mhlswitches)) {
+ switch (smatch(++cp, switches)) {
case AMBIGSW:
- ambigsw(cp, mhlswitches);
- done(1);
+ ambigsw(cp, switches);
+ exit(EX_USAGE);
case UNKWNSW:
- adios(NULL, "-%s unknown\n", cp);
+ adios(EX_USAGE, NULL, "-%s unknown\n", cp);
case HELPSW:
snprintf(buf, sizeof(buf), "%s [switches] [files ...]", invo_name);
- print_help(buf, mhlswitches, 1);
- done(1);
+ print_help(buf, switches, 1);
+ exit(argc == 2 ? EX_OK : EX_USAGE);
case VERSIONSW:
print_version(invo_name);
- done(1);
+ exit(argc == 2 ? EX_OK : EX_USAGE);
case FORMSW:
if (!(form = *argp++) || *form == '-')
- adios(NULL, "missing argument to %s",
+ adios(EX_USAGE, NULL, "missing argument to %s",
argp[-2]);
continue;
- case SLEEPSW:
- if (!(cp = *argp++) || *cp == '-')
- adios(NULL, "missing argument to %s",
- argp[-2]);
- sleepsw = atoi(cp); /* ZERO ok! */
- continue;
-
case WIDTHSW:
if (!(cp = *argp++) || *cp == '-')
- adios(NULL, "missing argument to %s",
+ adios(EX_USAGE, NULL, "missing argument to %s",
argp[-2]);
if ((width = atoi(cp)) < 1)
- adios(NULL, "bad argument %s %s",
- argp[-2], cp);
- continue;
-
- case DGSTSW:
- if (!(digest = *argp++) ||
- *digest == '-')
- adios(NULL, "missing argument to %s",
- argp[-2]);
- continue;
- case ISSUESW:
- if (!(cp = *argp++) || *cp == '-')
- adios(NULL, "missing argument to %s",
- argp[-2]);
- if ((issue = atoi(cp)) < 1)
- adios(NULL, "bad argument %s %s",
- argp[-2], cp);
- continue;
- case VOLUMSW:
- if (!(cp = *argp++) || *cp == '-')
- adios(NULL, "missing argument to %s",
- argp[-2]);
- if ((volume = atoi(cp)) < 1)
- adios(NULL, "bad argument %s %s",
+ adios(EX_USAGE, NULL, "bad argument %s %s",
argp[-2], cp);
continue;
}
if (forwall) {
- if (digest) {
- printf("%s", delim4);
- if (volume == 0) {
- snprintf(buf, sizeof(buf),
- "End of %s Digest\n", digest);
- } else {
- snprintf(buf, sizeof(buf), "End of %s Digest [Volume %d Issue %d]\n", digest, volume, issue);
- }
- i = strlen(buf);
- for (cp = buf + i; i > 1; i--)
- *cp++ = '*';
- *cp++ = '\n';
- *cp = 0;
- printf("%s", buf);
- } else
- printf("\n------- End of Forwarded Message%s\n\n",
+ printf("\n------- End of Forwarded Message%s\n\n",
vecp > 1 ? "s" : "");
}
fflush(stdout);
if (ferror(stdout)) {
- adios("output", "error writing");
+ adios(EX_IOERR, "output", "error writing");
}
return exitstat;
}
if ((fp = fopen(etcpath(file), "r")) == NULL)
- adios(file, "unable to open format file");
+ adios(EX_IOERR, file, "unable to open format file");
if (fstat(fileno(fp), &st) != NOTOK) {
mtime = st.st_mtime;
int n = 0;
/* split the fields */
- tmparray = brkstring(getcpy(++parptr), ",",
+ tmparray = brkstring(mh_xstrdup(++parptr), ",",
NULL);
/*
** copy pointers to split fields
parptr = bp;
while (*parptr) {
if (evalvar(&global))
- adios(NULL, "format file syntax error: %s", bp);
+ adios(EX_CONFIG, NULL, "format file syntax error: %s", bp);
if (*parptr)
parptr++;
}
while (*parptr == ':' || *parptr == ',') {
parptr++;
if (evalvar(c1))
- adios(NULL, "format file syntax error: %s", bp);
+ adios(EX_CONFIG, NULL, "format file syntax error: %s", bp);
}
if (!c1->c_fstr && global.c_fstr) {
if ((c1->c_flags & DATEFMT) &&
(global.c_flags & DATEFMT)) {
- c1->c_fstr = getcpy(global.c_fstr);
+ c1->c_fstr = mh_xstrdup(global.c_fstr);
} else if ((c1->c_flags & ADDRFMT) &&
(global.c_flags & ADDRFMT)) {
- c1->c_fstr = getcpy(global.c_fstr);
+ c1->c_fstr = mh_xstrdup(global.c_fstr);
}
}
continue;
default:
- adios(NULL, "format file syntax error: %s", bp);
+ adios(EX_CONFIG, NULL, "format file syntax error: %s", bp);
}
}
fclose(fp);
return 1;
cp = concat("=", cp, NULL);
fmtstr = new_fs(cp, NULL);
- free(cp);
- c1->c_fstr = getcpy(fmtstr);
+ mh_free0(&cp);
+ c1->c_fstr = mh_xstrdup(fmtstr);
c1->c_flags |= FORMAT;
return 0;
}
char *fmtstr;
fmtstr = new_fs("=%(decode{text})", NULL);
- c1->c_fstr = getcpy(fmtstr);
+ c1->c_fstr = mh_xstrdup(fmtstr);
c1->c_flags |= FORMAT;
return 0;
}
}
c = *parptr;
*parptr = 0;
- *s = getcpy(cp);
+ *s = mh_xstrdup(cp);
if ((*parptr = c) == '"')
parptr++;
return 0;
FILE *fp = NULL;
struct mcomp *c1;
- switch (setjmp(env)) {
- case OK:
- if (fname) {
- fp = mhl_action ? (*mhl_action) (fname) :
- fopen(fname, "r");
- if (fp == NULL) {
- advise(fname, "unable to open");
- exitstat++;
- return;
- }
- } else {
- fname = "(stdin)";
- fp = stdin;
- }
- SIGNAL(SIGINT, intrser);
- mhlfile(fp, fname, ofilen, ofilec);
- /* FALL THROUGH! */
- default:
- SIGNAL(SIGINT, SIG_IGN);
- if (mhl_action == NULL && fp != stdin)
- fclose(fp);
- if (holder.c_text) {
- free(holder.c_text);
- holder.c_text = NULL;
+ if (fname) {
+ fp = fopen(fname, "r");
+ if (fp == NULL) {
+ advise(fname, "unable to open");
+ exitstat++;
+ return;
}
- free_queue(&msghd, &msgtl);
- for (c1 = fmthd; c1; c1 = c1->c_next)
- c1->c_flags &= ~HDROUTPUT;
- break;
+ } else {
+ fname = "(stdin)";
+ fp = stdin;
}
+ SIGNAL(SIGINT, intrser);
+ mhlfile(fp, fname, ofilen, ofilec);
+
+ SIGNAL(SIGINT, SIG_IGN);
+ if (fp != stdin)
+ fclose(fp);
+ if (holder.c_text) {
+ mh_free0(&(holder.c_text));
+ }
+ free_queue(&msghd, &msgtl);
+ for (c1 = fmthd; c1; c1 = c1->c_next)
+ c1->c_flags &= ~HDROUTPUT;
}
static void
mhlfile(FILE *fp, char *mname, int ofilen, int ofilec)
{
- int state;
+ enum state state;
+ struct field f = {{0}};
struct mcomp *c1, *c2, *c3;
- char **ip, name[NAMESZ], buf[BUFSIZ];
+ char **ip;
if (forwall) {
- if (digest)
- printf("%s", ofilen == 1 ? delim3 : delim4);
- else {
- printf("\n-------");
- if (ofilen == 1)
- printf(" Forwarded Message%s",
- ofilec > 1 ? "s" : "");
- else
- printf(" Message %d", ofilen);
- printf("\n\n");
+ printf("\n-------");
+ if (ofilen == 1) {
+ printf(" Forwarded Message%s", ofilec > 1 ? "s" : "");
+ } else {
+ printf(" Message %d", ofilen);
}
+ printf("\n\n");
} else if (ofilec > 1) {
if (ofilen > 1) {
printf("\n\n\n");
printf(">>> %s\n\n", mname);
}
- for (state = FLD;;) {
- switch (state = m_getfld(state, name, buf, sizeof(buf), fp)) {
- case FLD:
- case FLDPLUS:
+ for (state = FLD2; !eflag; ) {
+ switch (state = m_getfld2(state, &f, fp)) {
+ case FLD2:
for (ip = ignores; *ip; ip++)
- if (!mh_strcasecmp(name, *ip)) {
- while (state == FLDPLUS)
- state = m_getfld(state, name, buf, sizeof(buf), fp);
+ if (mh_strcasecmp(f.name, *ip)==0) {
break;
}
- if (*ip)
+ if (*ip) {
continue;
+ }
for (c2 = fmthd; c2; c2 = c2->c_next)
- if (!mh_strcasecmp(c2->c_name, name))
+ if (mh_strcasecmp(c2->c_name, f.name)==0) {
break;
+ }
c1 = NULL;
if (!((c3 = c2 ? c2 : &global)->c_flags & SPLIT))
for (c1 = msghd; c1; c1 = c1->c_next)
- if (!mh_strcasecmp(c1->c_name,
- c3->c_name)) {
- c1->c_text = mcomp_add(c1->c_flags, buf, c1->c_text);
+ if (mh_strcasecmp(c1->c_name,
+ c3->c_name)==0) {
+ c1->c_text = mcomp_add(c1->c_flags, f.value, c1->c_text);
break;
}
- if (c1 == NULL)
- c1 = add_queue(&msghd, &msgtl, name, buf, 0);
- while (state == FLDPLUS) {
- state = m_getfld(state, name, buf,
- sizeof(buf), fp);
- c1->c_text = add(buf, c1->c_text);
+ if (c1 == NULL) {
+ c1 = add_queue(&msghd, &msgtl, f.name, f.value, 0);
}
- if (c2 == NULL)
+ if (c2 == NULL) {
c1->c_flags |= EXTRA;
+ }
continue;
- case BODY:
- case FILEEOF:
+ case BODY2:
+ case FILEEOF2:
column = 0;
for (c1 = fmthd; c1; c1 = c1->c_next) {
if (c1->c_flags & CLEARTEXT) {
putcomp(c1, c1, ONECOMP);
continue;
}
- if (!mh_strcasecmp(c1->c_name, "messagename")) {
+ if (mh_strcasecmp(c1->c_name, "messagename")==0) {
holder.c_text = concat("(Message ",
mname, ")\n", NULL);
putcomp(c1, &holder, ONECOMP);
- free(holder.c_text);
- holder.c_text = NULL;
+ mh_free0(&(holder.c_text));
continue;
}
- if (!mh_strcasecmp(c1->c_name, "extras")) {
- for (c2 = msghd; c2; c2 = c2->c_next)
- if (c2->c_flags & EXTRA)
+ if (mh_strcasecmp(c1->c_name, "extras")==0) {
+ for (c2 = msghd; c2; c2 = c2->c_next) {
+ if (c2->c_flags & EXTRA) {
putcomp(c1, c2, TWOCOMP);
+ }
+ }
continue;
}
- if (dobody && !mh_strcasecmp(c1->c_name, "body")) {
- holder.c_text = mh_xmalloc(sizeof(buf));
- strncpy(holder.c_text, buf, sizeof(buf));
- while (state == BODY) {
+ if (dobody && mh_strcasecmp(c1->c_name, "body")==0) {
+ holder.c_text = mh_xstrdup(f.value);
+ while (state == BODY2) {
putcomp(c1, &holder, BODYCOMP);
- state = m_getfld(state, name, holder.c_text, sizeof(buf), fp);
+ state = m_getfld2(state, &f, fp);
+ free(holder.c_text);
+ holder.c_text = mh_xstrdup(f.value);
}
- free(holder.c_text);
- holder.c_text = NULL;
+ mh_free0(&(holder.c_text));
continue;
}
- for (c2 = msghd; c2; c2 = c2->c_next)
- if (!mh_strcasecmp(c2->c_name,
- c1->c_name)) {
+ for (c2 = msghd; c2; c2 = c2->c_next) {
+ if (mh_strcasecmp(c2->c_name,
+ c1->c_name)==0) {
putcomp(c1, c2, ONECOMP);
- if (!(c1->c_flags & SPLIT))
+ if (!(c1->c_flags & SPLIT)) {
break;
+ }
}
+ }
}
return;
- case LENERR:
- case FMTERR:
+ case LENERR2:
+ case FMTERR2:
+ case IOERR2:
advise(NULL, "format error in message %s", mname);
exitstat++;
return;
default:
- adios(NULL, "getfld() returned %d", state);
+ adios(EX_SOFTWARE, NULL, "getfld() returned %d", state);
}
}
}
fmt_scan(c1->c_fmt, buffer, sizeof(buffer) - 1, dat);
/* Don't need to append a newline, dctime() already did */
- c2->c_text = getcpy(buffer);
+ c2->c_text = mh_xstrdup(buffer);
- free(ap);
+ mh_free0(&ap);
return;
}
(q = &pq)->pq_next = NULL;
while ((cp = getname(ap))) {
- if ((p = (struct pqpair *)
- calloc((size_t) 1, sizeof(*p))) == NULL)
- adios(NULL, "unable to allocate pqpair memory");
+ p = mh_xcalloc(1, sizeof(*p));
if ((mp = getm(cp, NULL, 0, AD_NAME, error)) == NULL) {
- p->pq_text = getcpy(cp);
- p->pq_error = getcpy(error);
+ p->pq_text = mh_xstrdup(cp);
+ p->pq_error = mh_xstrdup(error);
} else {
- p->pq_text = getcpy(mp->m_text);
+ p->pq_text = mh_xstrdup(mp->m_text);
mnfree(mp);
}
q = (q->pq_next = p);
c2->c_text = add(buffer, c2->c_text);
}
- free(p->pq_text);
+ mh_free0(&(p->pq_text));
if (p->pq_error)
- free(p->pq_error);
+ mh_free0(&(p->pq_error));
q = p->pq_next;
- free((char *) p);
+ mh_free0(&p);
}
c2->c_text = add("\n", c2->c_text);
{
struct mcomp *c1;
- if ((c1 = (struct mcomp *) calloc((size_t) 1, sizeof(*c1))) == NULL)
- adios(NULL, "unable to allocate comp memory");
+ c1 = mh_xcalloc(1, sizeof(*c1));
c1->c_flags = flags & ~INIT;
- if ((c1->c_name = name ? getcpy(name) : NULL))
+ if ((c1->c_name = name ? mh_xstrdup(name) : NULL))
c1->c_flags |= mcomp_flags(c1->c_name);
- c1->c_text = text ? getcpy(text) : NULL;
+ c1->c_text = text ? mh_xstrdup(text) : NULL;
if (flags & INIT) {
if (global.c_ovtxt)
- c1->c_ovtxt = getcpy(global.c_ovtxt);
+ c1->c_ovtxt = mh_xstrdup(global.c_ovtxt);
c1->c_offset = global.c_offset;
c1->c_ovoff = global. c_ovoff;
c1->c_width = 0;
for (c1 = *head; c1; c1 = c2) {
c2 = c1->c_next;
if (c1->c_name)
- free(c1->c_name);
+ mh_free0(&(c1->c_name));
if (c1->c_text)
- free(c1->c_text);
+ mh_free0(&(c1->c_text));
if (c1->c_ovtxt)
- free(c1->c_ovtxt);
+ mh_free0(&(c1->c_ovtxt));
if (c1->c_fstr)
- free(c1->c_fstr);
+ mh_free0(&(c1->c_fstr));
if (c1->c_fmt)
- free((char *) c1->c_fmt);
- free((char *) c1);
+ mh_free0(&(c1->c_fmt));
+ mh_free0(&c1);
}
*head = *tail = NULL;
if ((ovtxt = c1->c_ovtxt ? c1->c_ovtxt : global.c_ovtxt) == NULL)
ovtxt = "";
if (wid < ovoff + strlen(ovtxt) + 5)
- adios(NULL, "component: %s width(%d) too small for overflow(%d)", c1->c_name, wid, ovoff + strlen(ovtxt) + 5);
+ adios(EX_SOFTWARE, NULL, "component: %s width(%d) too small for overflow(%d)", c1->c_name, wid, ovoff + strlen(ovtxt) + 5);
onelp = NULL;
if (c1->c_flags & CLEARTEXT) {
static void
intrser(int i)
{
- discard(stdout);
- putchar('\n');
- longjmp(env, DONE);
-}
-
-
-#undef adios
-#undef done
-
-static void
-mhladios(char *what, char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- advertise(what, NULL, fmt, ap);
- va_end(ap);
- mhldone(1);
-}
-
-
-static void
-mhldone(int status)
-{
- exitstat = status;
- if (mhl_action)
- longjmp(mhlenv, DONE);
- else
- done(exitstat);
+ eflag = 1;
}