** terminating NULL.
*/
- #define LENERR (-2) /* Name too long error from getfld */
- #define FMTERR (-3) /* Message Format error */
- #define FLD 0 /* Field returned */
- #define FLDPLUS 1 /* Field returned with more to come */
- #define BODY 3 /* Body returned with more to come */
- #define FILEEOF 5 /* Reached end of input file */
-
- extern int msg_count; /* m_getfld() indicators (That's a hack!) */
+ /* m_getfld2() returned data */
+ struct field {
+ char name[NAMESZ];
+ size_t namelen;
+ char *value;
+ size_t valuelen;
+ size_t alloclen;
+ };
+
+ /* m_getfld2() states */
+ enum state {
+ LENERR2 = -2, /* Line too long */
+ FMTERR2 = -3, /* Format error in message */
+ IOERR2 = -1, /* Read error */
+ FLD2 = 0, /* Header field returned */
+ BODY2, /* Body line returned */
+ FILEEOF2, /* Reached end of input file */
+ };
#define NOUSE 0 /* draft being re-used */
extern char *rcvdistcomps;
extern char *replcomps;
extern char *replgroupcomps;
+extern char *scanformat;
extern char *sendmail;
extern char *seq_all;
extern char *seq_beyond;
int getanswer(char *);
char **getarguments(char *, int, char **, int);
char *get_charset();
-char *getcpy(char *);
char *getcurfol(void);
char *getdeffol(void);
int lkclose(int, char*);
char *m_backup(char *);
int m_convert(struct msgs *, char *);
char *m_draft(char *);
- int m_getfld(int, unsigned char *, unsigned char *, int, FILE *);
+ enum state m_getfld2(enum state, struct field *, FILE *);
int m_gmprot(void);
char *m_name(int);
int m_putenv(char *, char *);
error.c execprog.c ext_hook.c folder_addmsg.c folder_delmsgs.c \
folder_free.c folder_read.c \
folder_realloc.c gans.c getans.c getanswer.c \
- getarguments.c getcpy.c \
+ getarguments.c \
fmt_addr.c fmt_compile.c fmt_new.c fmt_rfc2047.c \
fmt_scan.c lock_file.c m_atoi.c \
- m_convert.c m_draft.c m_getfld.c m_gmprot.c \
+ m_convert.c m_draft.c m_getfld2.c m_gmprot.c \
m_name.c \
makedir.c mts.c norm_charmap.c \
path.c pidwait.c pidstatus.c \
void
readconfig(struct node **npp, FILE *ib, char *file, int ctx)
{
- int state;
- char *cp;
- char name[NAMESZ], field[BUFSIZ];
+ enum state state;
+ struct field f = {{0}};
struct node *np;
struct procstr *ps;
return;
}
- for (state = FLD;;) {
- switch (state = m_getfld(state, name, field, sizeof(field),
- ib)) {
- case FLD:
- case FLDPLUS:
+ for (state = FLD2;;) {
+ switch (state = m_getfld2(state, &f, ib)) {
+ case FLD2:
- np = (struct node *) mh_xmalloc(sizeof(*np));
+ np = mh_xcalloc(1, sizeof(*np));
*npp = np;
*(npp = &np->n_next) = NULL;
- np->n_name = mh_xstrdup(name);
- if (state == FLDPLUS) {
- cp = mh_xstrdup(field);
- while (state == FLDPLUS) {
- state = m_getfld(state, name, field,
- sizeof(field), ib);
- cp = add(field, cp);
- }
- np->n_field = trimcpy(cp);
- mh_free0(&cp);
- } else {
- np->n_field = trimcpy(field);
- }
- np->n_name = getcpy(f.name);
++ np->n_name = mh_xstrdup(f.name);
+ np->n_field = trimcpy(f.value);
np->n_context = ctx;
/*
** Now scan the list of `procs' and link in
** the field value to the global variable.
*/
- for (ps = procs; ps->procname; ps++)
+ for (ps = procs; ps->procname; ps++) {
if (mh_strcasecmp(np->n_name,
ps->procname) == 0) {
*ps->procnaddr = np->n_field;
break;
}
+ }
continue;
- case BODY:
+ case BODY2:
adios(EX_CONFIG, NULL, "no blank lines are permitted in %s",
file);
- case FILEEOF:
+ case FILEEOF2:
break;
default:
** Initialize the list of sequence names. Go ahead and
** add the cur sequence to the list of sequences.
*/
- mp->msgattrs[0] = getcpy(seq_cur);
+ mp->msgattrs[0] = mh_xstrdup(seq_cur);
mp->msgattrs[1] = NULL;
make_all_public(mp); /* initially, make all public */
static void
seq_public(struct msgs *mp)
{
- int state;
- char *cp, seqfile[PATH_MAX];
- char name[NAMESZ], field[BUFSIZ];
+ enum state state;
+ struct field f = {{0}};
+ char seqfile[PATH_MAX];
FILE *fp;
/*
return;
/* Use m_getfld to scan sequence file */
- for (state = FLD;;) {
- switch (state = m_getfld(state, name, field, sizeof(field),
- fp)) {
- case FLD:
- case FLDPLUS:
- if (state == FLDPLUS) {
- cp = mh_xstrdup(field);
- while (state == FLDPLUS) {
- state = m_getfld(state, name, field,
- sizeof(field), fp);
- cp = add(field, cp);
- }
- seq_init(mp, mh_xstrdup(name), trimcpy(cp));
- mh_free0(&cp);
- } else {
- seq_init(mp, mh_xstrdup(name), trimcpy(field));
- }
+ for (state = FLD2;;) {
+ switch (state = m_getfld2(state, &f, fp)) {
+ case FLD2:
- seq_init(mp, getcpy(f.name), trimcpy(f.value));
++ seq_init(mp, mh_xstrdup(f.name), trimcpy(f.value));
continue;
- case BODY:
+ case BODY2:
adios(EX_CONFIG, NULL, "no blank lines are permitted in %s",
seqfile);
- /* fall */
+ /* FALL */
- case FILEEOF:
+ case FILEEOF2:
break;
default:
adios(EX_CONFIG, NULL, "%s is poorly formatted", seqfile);
}
- break; /* break from for loop */
+ break;
}
lkfclose(fp, seqfile);
(j = strlen(np->n_name) - plen) > alen &&
*(np->n_name + j) == '-' &&
strcmp(mp->foldpath, np->n_name + j + 1)==0) {
- cp = getcpy(np->n_name + alen);
+ cp = mh_xstrdup(np->n_name + alen);
*(cp + j - alen) = '\0';
- if ((i = seq_init(mp, cp, getcpy(np->n_field))) != -1)
+ if ((i = seq_init(mp, cp, mh_xstrdup(np->n_field))) != -1)
make_seq_private(mp, i);
}
}
/* Return error, if too many sequences */
if (i >= NUMATTRS) {
- free(name);
- free(field);
+ mh_free0(&name);
+ mh_free0(&field);
return -1;
}
** name string. Else add it to the list of sequence names.
*/
if (mp->msgattrs[i]) {
- free(name);
+ mh_free0(&name);
} else {
mp->msgattrs[i] = name;
mp->msgattrs[i + 1] = NULL;
}
}
- free(field); /* free string containing message ranges */
+ mh_free0(&field); /* free string containing message ranges */
return i;
}
adios(EX_OSERR, NULL, "atexit failed");
}
- /*
- ** absolutely the first thing we do is save our privileges,
- ** and drop them if we can.
- */
+ /*
+ ** absolutely the first thing we do is save our privileges,
+ ** and drop them if we can.
+ */
SAVEGROUPPRIVS();
TRYDROPGROUPPRIVS();
setlocale(LC_ALL, "");
invo_name = mhbasename(argv[0]);
- /* read user profile/context */
context_read();
arguments = getarguments(invo_name, argc, argv, 1);
case AUDSW:
if (!(cp = *argp++) || *cp == '-')
adios(EX_USAGE, NULL, "missing argument to %s", argp[-2]);
- audfile = getcpy(expanddir(cp));
+ audfile = mh_xstrdup(expanddir(cp));
continue;
case NAUDSW:
audfile = NULL;
if (!(cp = *argp++) || *cp == '-')
adios(EX_USAGE, NULL, "missing argument to %s",
argp[-2]);
- from = getcpy(expanddir(cp));
+ from = mh_xstrdup(expanddir(cp));
/*
** If the truncate file is in default state,
if (folder)
adios(EX_USAGE, NULL, "only one folder at a time!");
else
- folder = getcpy(expandfol(cp));
+ folder = mh_xstrdup(expandfol(cp));
} else {
adios(EX_USAGE, NULL, "usage: %s [+folder] [switches]",
invo_name);
if (chdir(maildir) == NOTOK)
adios(EX_OSERR, maildir, "unable to change directory to");
- /* read folder and create message structure */
if (!(mp = folder_read(folder)))
adios(EX_IOERR, NULL, "unable to read folder %s", folder);
dtimenow(), from);
}
- /* Get new format string */
- fmtstr = new_fs(form, FORMAT);
+ /* Set format string */
+ fmtstr = new_fs(form, scanformat);
if (noisy) {
printf("Incorporating new mail into %s...\n\n", folder);
fflush(stdout);
}
+ /* check if readable and nonempty */
+ if (!fgets(buf, sizeof(buf), in)) {
+ if (ferror(in)) {
+ advise("read", "unable to");
+ incerr = SCNFAT;
+ } else {
+ incerr = SCNEOF;
+ }
+ goto giveup;
+ }
+ if (strncmp("From ", buf, 5)!=0) {
+ advise(NULL, "not in mbox format");
+ incerr = SCNFAT;
+ goto giveup;
+ }
+
/*
** Get the mail from file (usually mail spool)
*/
- thisisanmbox(in);
hghnum = msgnum = mp->hghmsg;
for (;;) {
/*
*/
break;
}
+ giveup:;
- free(maildir_copy);
+ mh_free0(&maildir_copy);
if (incerr < 0) { /* error */
if (locked) {
fclose(in); in = NULL;
}
- seq_setunseen(mp, 1); /* add new msgs to unseen sequences */
- seq_save(mp); /* synchronize sequences */
- context_save(); /* save the context file */
+ seq_setunseen(mp, 1);
+ seq_save(mp);
+ context_save();
return 0;
}
if ((cp = context_find(nmhstorage)) && *cp)
tmp = concat(cp, "/", invo_name, NULL);
else
- tmp = getcpy(toabsdir(invo_name));
+ tmp = mh_xstrdup(toabsdir(invo_name));
/* Check if we have a file to process */
if (!compfile)
static CT
build_mime(char *infile)
{
- int compnum, state;
- char buf[BUFSIZ], name[NAMESZ];
+ enum state state;
+ struct field f = {{0}};
+ int compnum;
+ char buf[BUFSIZ];
char *cp, *np, *vp;
struct multipart *m;
struct part **pp;
umask(~m_gmprot());
/* open the composition draft */
- if ((in = fopen(infile, "r")) == NULL)
+ if ((in = fopen(infile, "r")) == NULL) {
adios(EX_IOERR, infile, "unable to open for reading");
+ }
/*
** Allocate space for primary (outside) content
*/
- ct = (CT) mh_xcalloc(1, sizeof(*ct));
+ ct = mh_xcalloc(1, sizeof(*ct));
/*
** Allocate structure for handling decoded content
** draft into the linked list of header fields for
** the new MIME message.
*/
- for (compnum = 1, state = FLD;;) {
- switch (state = m_getfld(state, name, buf, sizeof(buf), in)) {
- case FLD:
- case FLDPLUS:
+ for (compnum = 1, state = FLD2;;) {
+ switch (state = m_getfld2(state, &f, in)) {
+ case FLD2:
compnum++;
/* abort if draft has Mime-Version header field */
- if (!mh_strcasecmp(name, VRSN_FIELD))
+ if (!mh_strcasecmp(f.name, VRSN_FIELD)) {
adios(EX_CONFIG, NULL, "draft shouldn't contain %s: field", VRSN_FIELD);
+ }
/*
** abort if draft has Content-Transfer-Encoding
** header field
*/
- if (!mh_strcasecmp(name, ENCODING_FIELD))
+ if (!mh_strcasecmp(f.name, ENCODING_FIELD)) {
adios(EX_CONFIG, NULL, "draft shouldn't contain %s: field", ENCODING_FIELD);
+ }
/* ignore any Content-Type fields in the header */
- if (!mh_strcasecmp(name, TYPE_FIELD)) {
- while (state == FLDPLUS)
- state = m_getfld(state, name, buf,
- sizeof(buf), in);
+ if (!mh_strcasecmp(f.name, TYPE_FIELD)) {
continue;
}
- /* get copies of the buffers */
- np = mh_xstrdup(name);
- vp = mh_xstrdup(buf);
-
- /* if necessary, get rest of field */
- while (state == FLDPLUS) {
- state = m_getfld(state, name, buf,
- sizeof(buf), in);
- vp = add(buf, vp); /* add to prev value */
- }
-
- /* Now add the header data to the list */
- add_header(ct, np, vp);
+ /* add the header data to the list */
- add_header(ct, getcpy(f.name), getcpy(f.value));
++ add_header(ct, mh_xstrdup(f.name), mh_xstrdup(f.value));
continue;
- case FILEEOF:
+ case BODY2:
+ fseek(in, (long) (-strlen(f.value)), SEEK_CUR);
+ break;
+
+ case FILEEOF2:
adios(EX_CONFIG, NULL, "draft has empty body -- no directives!");
/* NOTREACHED */
- case BODY:
- fseek(in, (long) (-strlen(buf)), SEEK_CUR);
- break;
-
- case LENERR:
- case FMTERR:
+ case LENERR2:
+ case FMTERR2:
+ case IOERR2:
adios(EX_CONFIG, NULL, "message format error in component #%d",
compnum);
** Now add the MIME-Version header field
** to the list of header fields.
*/
- np = getcpy(VRSN_FIELD);
+ np = mh_xstrdup(VRSN_FIELD);
vp = concat(" ", VRSN_VALUE, "\n", NULL);
add_header(ct, np, vp);
}
ct->c_type = CT_MULTIPART;
ct->c_subtype = MULTI_MIXED;
- ct->c_file = getcpy(infile);
+ ct->c_file = mh_xstrdup(infile);
- m = mh_xcalloc(1, sizeof(*m));
+ m = (struct multipart *) mh_xcalloc(1, sizeof(*m));
ct->c_ctparams = (void *) m;
pp = &m->mp_parts;
if (!p)
continue;
- part = (struct part *) mh_xcalloc(1, sizeof(*part));
+ part = mh_xcalloc(1, sizeof(*part));
*pp = part;
pp = &part->mp_next;
part->mp_part = p;
{
CE ce;
- ce = (CE) mh_xcalloc(1, sizeof(*ce));
+ ce = mh_xcalloc(1, sizeof(*ce));
ct->c_cefile = ce;
ct->c_ceopenfnx = open7Bit; /* since unencoded */
}
/* allocate basic Content structure */
- ct = (CT) mh_xcalloc(1, sizeof(*ct));
+ ct = mh_xcalloc(1, sizeof(*ct));
*ctp = ct;
/* allocate basic structure for handling decoded content */
adios(EX_CANTCREAT, "mhbuild", "unable to create temporary file");
/* use a temp file to collect the plain text lines */
- ce->ce_file = getcpy(cp);
+ ce->ce_file = mh_xstrdup(cp);
ce->ce_unlink = 1;
if (buf[0] == '#' && buf[1] == '<') {
continue;
if (!*cp)
adios(EX_DATAERR, NULL, "empty pipe command for #%s directive", ci->ci_type);
- cp = getcpy(cp);
- free(ci->ci_magic);
+ cp = mh_xstrdup(cp);
+ mh_free0(&(ci->ci_magic));
ci->ci_magic = cp;
} else {
/* record filename of decoded contents */
exit(EX_CONFIG);
}
}
- ci->ci_magic = getcpy(cp);
+ ci->ci_magic = mh_xstrdup(cp);
return OK;
}
if (folder)
adios(EX_USAGE, NULL, "only one folder per #forw directive");
else
- folder = getcpy(expandfol(cp));
+ folder = mh_xstrdup(expandfol(cp));
}
}
/* else, use the current folder */
if (!folder)
- folder = getcpy(getcurfol());
+ folder = mh_xstrdup(getcurfol());
if (!(mp = folder_read(folder)))
adios(EX_IOERR, NULL, "unable to read folder %s", folder);
if (!m_convert(mp, cp))
exit(EX_USAGE);
}
- free(folder);
+ mh_free0(&folder);
free_ctinfo(ct);
/*
ct->c_type = CT_MULTIPART;
ct->c_subtype = MULTI_DIGEST;
- m = (struct multipart *) mh_xcalloc(1, sizeof(*m));
+ m = mh_xcalloc(1, sizeof(*m));
ct->c_ctparams = (void *) m;
pp = &m->mp_parts;
CT p;
CE pe;
- p = (CT) mh_xcalloc(1, sizeof(*p));
+ p = mh_xcalloc(1, sizeof(*p));
init_decoded_content(p);
pe = p->c_cefile;
if (get_ctinfo("message/rfc822", p, 0)
snprintf(buffer, sizeof(buffer),
"%s/%d", mp->foldpath,
msgnum);
- pe->ce_file = getcpy(buffer);
+ pe->ce_file = mh_xstrdup(buffer);
- part = (struct part *) mh_xcalloc(1, sizeof(*part));
+ part = mh_xcalloc(1, sizeof(*part));
*pp = part;
pp = &part->mp_next;
part->mp_part = p;
msgnum = mp->lowsel;
snprintf(buffer, sizeof(buffer), "%s/%d",
mp->foldpath, msgnum);
- ce->ce_file = getcpy(buffer);
+ ce->ce_file = mh_xstrdup(buffer);
}
folder_free(mp); /* free folder/message structure */
ct->c_type = CT_MULTIPART;
ct->c_subtype = vrsn;
- m = (struct multipart *) mh_xcalloc(1, sizeof(*m));
+ m = mh_xcalloc(1, sizeof(*m));
ct->c_ctparams = (void *) m;
pp = &m->mp_parts;
if (!p)
continue;
- part = (struct part *) mh_xcalloc(1, sizeof(*part));
+ part = mh_xcalloc(1, sizeof(*part));
*pp = part;
pp = &part->mp_next;
part->mp_part = p;
snprintf(msgid, sizeof(msgid), "<%d.%ld.%%d@%s>\n",
(int) getpid(), (long) clock, LocalName());
partno = 0;
- msgfmt = getcpy(msgid);
+ msgfmt = mh_xstrdup(msgid);
}
snprintf(msgid, sizeof(msgid), msgfmt, top ? 0 : ++partno);
- ct->c_id = getcpy(msgid);
+ ct->c_id = mh_xstrdup(msgid);
}
CT p = part->mp_part;
sprintf(pp, "%d", partnum);
- p->c_partno = getcpy(partnam);
+ p->c_partno = mh_xstrdup(partnam);
if (compose_content(p) == NOTOK)
return NOTOK;
}
if (tfile == NULL) {
adios(EX_CANTCREAT, "mhbuild", "unable to create temporary file");
}
- ce->ce_file = getcpy(tfile);
+ ce->ce_file = mh_xstrdup(tfile);
ce->ce_unlink = 1;
xstdout = 0;
NULL);
} else {
t->tx_charset = CHARSET_USASCII;
- *ap = getcpy("charset=us-ascii");
+ *ap = mh_xstrdup("charset=us-ascii");
}
cp = strchr(*ap++, '=');
ep = ci->ci_values;
snprintf(buffer, sizeof(buffer), "boundary=%s%d",
prefix, level++);
- cp = strchr(*ap++ = getcpy(buffer), '=');
+ cp = strchr(*ap++ = mh_xstrdup(buffer), '=');
*ap = NULL;
*cp++ = '\0';
*ep = cp;
/*
** output the content type and subtype
*/
- np = getcpy(TYPE_FIELD);
+ np = mh_xstrdup(TYPE_FIELD);
vp = concat(" ", ci->ci_type, "/", ci->ci_subtype, NULL);
/* keep track of length of line */
** output the Content-ID
*/
if (ct->c_id) {
- np = getcpy(ID_FIELD);
+ np = mh_xstrdup(ID_FIELD);
vp = concat(" ", ct->c_id, NULL);
add_header(ct, np, vp);
}
** output the Content-Description
*/
if (ct->c_descr) {
- np = getcpy(DESCR_FIELD);
+ np = mh_xstrdup(DESCR_FIELD);
vp = concat(" ", ct->c_descr, NULL);
if (encode_rfc2047(DESCR_FIELD, &vp, NULL)) {
adios(EX_DATAERR, NULL, "Unable to encode %s header", DESCR_FIELD);
** output the Content-Disposition
*/
if (ct->c_dispo) {
- np = getcpy(DISPO_FIELD);
+ np = mh_xstrdup(DISPO_FIELD);
vp = concat(" ", ct->c_dispo, NULL);
add_header(ct, np, vp);
}
if (ct->c_type == CT_MESSAGE)
adios(EX_DATAERR, NULL, "internal error, invalid encoding");
- np = getcpy(ENCODING_FIELD);
+ np = mh_xstrdup(ENCODING_FIELD);
vp = concat(" ", "8bit", "\n", NULL);
add_header(ct, np, vp);
break;
if (ct->c_type == CT_MESSAGE || ct->c_type == CT_MULTIPART)
adios(EX_DATAERR, NULL, "internal error, invalid encoding");
- np = getcpy(ENCODING_FIELD);
+ np = mh_xstrdup(ENCODING_FIELD);
vp = concat(" ", "quoted-printable", "\n", NULL);
add_header(ct, np, vp);
break;
if (ct->c_type == CT_MESSAGE || ct->c_type == CT_MULTIPART)
adios(EX_DATAERR, NULL, "internal error, invalid encoding");
- np = getcpy(ENCODING_FIELD);
+ np = mh_xstrdup(ENCODING_FIELD);
vp = concat(" ", "base64", "\n", NULL);
add_header(ct, np, vp);
break;
if (ct->c_type == CT_MESSAGE)
adios(EX_DATAERR, NULL, "internal error, invalid encoding");
- np = getcpy(ENCODING_FIELD);
+ np = mh_xstrdup(ENCODING_FIELD);
vp = concat(" ", "binary", "\n", NULL);
add_header(ct, np, vp);
break;
int n = 0;
/* split the fields */
- tmparray = brkstring(getcpy(++parptr), ",",
+ tmparray = brkstring(mh_xstrdup(++parptr), ",",
NULL);
/*
** copy pointers to split fields
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;
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;
if (fp != stdin)
fclose(fp);
if (holder.c_text) {
- free(holder.c_text);
- holder.c_text = NULL;
+ mh_free0(&(holder.c_text));
}
free_queue(&msghd, &msgtl);
for (c1 = fmthd; c1; c1 = c1->c_next)
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) {
printf("\n-------");
- if (ofilen == 1)
+ if (ofilen == 1) {
printf(" Forwarded Message%s", ofilec > 1 ? "s" : "");
- else
+ } else {
printf(" Message %d", ofilen);
+ }
printf("\n\n");
} else if (ofilec > 1) {
if (ofilen > 1) {
printf(">>> %s\n\n", mname);
}
- for (state = FLD;!eflag;) {
- 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_xcalloc(sizeof(buf), sizeof(char));
- strncpy(holder.c_text, buf, sizeof(buf));
- while (state == BODY) {
+ if (dobody && mh_strcasecmp(c1->c_name, "body")==0) {
- holder.c_text = getcpy(f.value);
++ 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 = getcpy(f.value);
++ 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;
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))) {
- p = (struct pqpair *) mh_xcalloc((size_t) 1, sizeof(*p));
+ 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;
- c1 = (struct mcomp *) mh_xcalloc((size_t) 1, sizeof(*c1));
+ 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;
advise("mhparse", "unable to create temporary file");
return NULL;
}
- file = getcpy(tfile);
+ file = mh_xstrdup(tfile);
chmod(file, 0600);
while (fgets(buffer, sizeof(buffer), stdin))
static CT
get_content(FILE *in, char *file, int toplevel)
{
- int compnum, state;
- char buf[BUFSIZ], name[NAMESZ];
- char *np, *vp;
+ enum state state;
+ struct field f = {{0}};
+ int compnum;
CT ct;
HF hp;
/* allocate the content structure */
- ct = (CT) mh_xcalloc(1, sizeof(*ct));
+ ct = mh_xcalloc(1, sizeof(*ct));
ct->c_fp = in;
- ct->c_file = getcpy(file);
+ ct->c_file = mh_xstrdup(file);
ct->c_begin = ftell(ct->c_fp) + 1;
/*
** Parse the header fields for this
** content into a linked list.
*/
- for (compnum = 1, state = FLD;;) {
- switch (state = m_getfld(state, name, buf, sizeof(buf), in)) {
- case FLD:
- case FLDPLUS:
+ for (compnum = 1, state = FLD2;;) {
+ switch (state = m_getfld2(state, &f, in)) {
+ case FLD2:
compnum++;
- /* get copies of the buffers */
- np = mh_xstrdup(name);
- vp = mh_xstrdup(buf);
-
- /* if necessary, get rest of field */
- while (state == FLDPLUS) {
- state = m_getfld(state, name, buf,
- sizeof(buf), in);
- vp = add(buf, vp); /* add to previous value */
- }
-
- /* Now add the header data to the list */
- add_header(ct, np, vp);
+ /* add the header data to the list */
- add_header(ct, getcpy(f.name), getcpy(f.value));
++ add_header(ct, mh_xstrdup(f.name), mh_xstrdup(f.value));
ct->c_begin = ftell(in) + 1;
continue;
- case BODY:
- ct->c_begin = ftell(in) - strlen(buf);
+ case BODY2:
+ ct->c_begin = ftell(in) - strlen(f.value);
break;
- case FILEEOF:
+ case FILEEOF2:
ct->c_begin = ftell(in);
break;
- case LENERR:
- case FMTERR:
+ case LENERR2:
+ case FMTERR2:
+ case IOERR2:
adios(EX_DATAERR, NULL, "message format error in component #%d",
compnum);
default:
adios(EX_SOFTWARE, NULL, "getfld() returned %d", state);
}
-
- /* break out of the loop */
break;
}
advise(NULL, "message %s has multiple %s: fields", ct->c_file, VRSN_FIELD);
goto next_header;
}
- ct->c_vrsn = getcpy(hp->value);
+ ct->c_vrsn = mh_xstrdup(hp->value);
/* Now, cleanup this field */
cp = ct->c_vrsn;
}
/* get copy of this field */
- ct->c_celine = cp = getcpy(hp->value);
+ ct->c_celine = cp = mh_xstrdup(hp->value);
while (isspace(*cp))
cp++;
HF hp;
/* allocate header field structure */
- hp = mh_xmalloc(sizeof(*hp));
+ hp = mh_xcalloc(1, sizeof(*hp));
/* link data into header structure */
hp->name = name;
** Insert at first semicolon, if any.
** If none, append to end.
*/
- prefix = getcpy(buf);
+ prefix = mh_xstrdup(buf);
if ((cp = strchr(prefix, ';'))) {
suffix = concat(cp, NULL);
*cp = '\0';
newbuf = concat(prefix, insertion, suffix,
"\n", NULL);
- free(suffix);
+ mh_free0(&suffix);
} else {
/* Append to end. */
newbuf = concat(buf, insertion, "\n", NULL);
}
- free(prefix);
- free(insertion);
- free(buf);
+ mh_free0(&prefix);
+ mh_free0(&insertion);
+ mh_free0(&buf);
}
- free(name_plus_equal);
+ mh_free0(&name_plus_equal);
}
return newbuf;
char *name_suffix_equals = strstr(value, name_suffix_plus_quote);
char *cp;
- free(name_suffix_plus_quote);
+ mh_free0(&name_suffix_plus_quote);
if (name_suffix_equals) {
char *name_suffix_begin;
for (; *cp != '"'; ++cp)
;
- extracted_name_value = mh_xmalloc(cp - name_suffix_begin + 1);
+ extracted_name_value = mh_xcalloc(cp - name_suffix_begin + 1, sizeof(char));
memcpy(extracted_name_value, name_suffix_begin,
cp - name_suffix_begin);
extracted_name_value[cp - name_suffix_begin] = '\0';
i = strlen(invo_name) + 2;
/* store copy of Content-Type line */
- cp = ct->c_ctline = getcpy(cp);
+ cp = ct->c_ctline = mh_xstrdup(cp);
while (isspace(*cp)) /* trim leading spaces */
cp++;
for (dp = cp; istoken(*dp); dp++)
continue;
c = *dp, *dp = '\0';
- ci->ci_type = getcpy(cp); /* store content type */
+ ci->ci_type = mh_xstrdup(cp); /* store content type */
*dp = c, cp = dp;
if (!*ci->ci_type) {
if (*cp != '/') {
if (!magic)
- ci->ci_subtype = getcpy("");
+ ci->ci_subtype = mh_xstrdup("");
goto magic_skip;
}
for (dp = cp; istoken(*dp); dp++)
continue;
c = *dp, *dp = '\0';
- ci->ci_subtype = getcpy(cp); /* store the content subtype */
+ ci->ci_subtype = mh_xstrdup(cp); /* store the content subtype */
*dp = c, cp = dp;
if (!*ci->ci_subtype) {
return NOTOK;
}
- vp = (*ap = getcpy(cp)) + (up - cp);
+ vp = (*ap = mh_xstrdup(cp)) + (up - cp);
*vp = '\0';
for (dp++; isspace(*dp);)
dp++;
*/
if (magic && *cp == '<') {
if (ct->c_id) {
- free(ct->c_id);
- ct->c_id = NULL;
+ mh_free0(&(ct->c_id));
}
if (!(dp = strchr(ct->c_id = ++cp, '>'))) {
advise(NULL, "invalid ID in message %s", ct->c_file);
*/
if (*cp) {
if (magic) {
- ci->ci_magic = getcpy(cp);
+ ci->ci_magic = mh_xstrdup(cp);
/*
** If there is a Content-Disposition header and
if (istype) {
if ((dp = ci->ci_comment)) {
ci->ci_comment = concat(dp, " ", buffer, NULL);
- free(dp);
+ mh_free0(&dp);
} else {
- ci->ci_comment = getcpy(buffer);
+ ci->ci_comment = mh_xstrdup(buffer);
}
}
ct->c_subtype = kv->kv_value;
/* allocate text character set structure */
- t = (struct text *) mh_xcalloc(1, sizeof(*t));
+ t = mh_xcalloc(1, sizeof(*t));
ct->c_ctparams = (void *) t;
/* scan for charset parameter */
/* check if content specified a character set */
if (*ap) {
/* store its name */
- ct->c_charset = getcpy(norm_charmap(*ep));
+ ct->c_charset = mh_xstrdup(norm_charmap(*ep));
/* match character set or set to CHARSET_UNKNOWN */
for (kv = Charset; kv->kv_key; kv++) {
if (!mh_strcasecmp(*ep, kv->kv_key)) {
}
/* allocate primary structure for multipart info */
- m = (struct multipart *) mh_xcalloc(1, sizeof(*m));
+ m = mh_xcalloc(1, sizeof(*m));
ct->c_ctparams = (void *) m;
/* check if boundary parameter contains only whitespace characters */
if (strcmp(buffer + 2, m->mp_start)!=0)
continue;
next_part:
- part = (struct part *) mh_xcalloc(1, sizeof(*part));
+ part = mh_xcalloc(1, sizeof(*part));
*next = part;
next = &part->mp_next;
continue;
*next = NULL;
free_content(p);
- free((char *) part);
+ mh_free0(&part);
}
}
p = part->mp_part;
sprintf(pp, "%d", partnum);
- p->c_partno = getcpy(partnam);
+ p->c_partno = mh_xstrdup(partnam);
/* initialize the content of the subparts */
if (p->c_ctinitfnx && (*p->c_ctinitfnx) (p) == NOTOK) {
i++;
/* allocate array of pointers to the parts */
- base = (struct part **) mh_xcalloc((size_t) (i + 1), sizeof(*base));
+ base = mh_xcalloc(i + 1, sizeof(*base));
bmp = base;
/* point at all the parts */
*next = NULL;
/* free array of pointers */
- free((char *) base);
+ mh_free0(&base);
}
char **ap, **ep;
struct partial *p;
- p = (struct partial *) mh_xcalloc(1, sizeof(*p));
+ p = mh_xcalloc(1, sizeof(*p));
ct->c_ctparams = (void *) p;
/*
*/
for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
if (!mh_strcasecmp(*ap, "id")) {
- p->pm_partid = getcpy(*ep);
+ p->pm_partid = mh_xstrdup(*ep);
continue;
}
if (!mh_strcasecmp(*ap, "number")) {
{
CE ce;
- ce = (CE) mh_xcalloc(1, sizeof(*ce));
+ ce = mh_xcalloc(1, sizeof(*ce));
ct->c_cefile = ce;
ct->c_ceopenfnx = openfnx;
}
if (*file == NULL) {
- ce->ce_file = getcpy(m_mktemp(tmp, NULL, NULL));
+ ce->ce_file = mh_xstrdup(m_mktemp(tmp, NULL, NULL));
ce->ce_unlink = 1;
} else {
- ce->ce_file = getcpy(*file);
+ ce->ce_file = mh_xstrdup(*file);
ce->ce_unlink = 0;
}
** Temporary file already exists, so we rename to
** version with extension.
*/
- char *file_org = strdup(ce->ce_file);
+ char *file_org = mh_xstrdup(ce->ce_file);
ce->ce_file = add(cp, ce->ce_file);
if (rename(file_org, ce->ce_file)) {
adios(EX_IOERR, ce->ce_file, "unable to rename %s to ",
file_org);
}
- free(file_org);
+ mh_free0(&file_org);
} else {
ce->ce_file = add(cp, ce->ce_file);
}
if (*file == NULL) {
- ce->ce_file = getcpy(m_mktemp(tmp, NULL, NULL));
+ ce->ce_file = mh_xstrdup(m_mktemp(tmp, NULL, NULL));
ce->ce_unlink = 1;
} else {
- ce->ce_file = getcpy(*file);
+ ce->ce_file = mh_xstrdup(*file);
ce->ce_unlink = 0;
}
** Temporary file already exists, so we rename to
** version with extension.
*/
- char *file_org = strdup(ce->ce_file);
+ char *file_org = mh_xstrdup(ce->ce_file);
ce->ce_file = add(cp, ce->ce_file);
if (rename(file_org, ce->ce_file)) {
adios(EX_IOERR, ce->ce_file, "unable to rename %s to ",
file_org);
}
- free(file_org);
+ mh_free0(&file_org);
} else {
ce->ce_file = add(cp, ce->ce_file);
}
if (*file == NULL) {
- ce->ce_file = getcpy(m_mktemp(tmp, NULL, NULL));
+ ce->ce_file = mh_xstrdup(m_mktemp(tmp, NULL, NULL));
ce->ce_unlink = 1;
} else {
- ce->ce_file = getcpy(*file);
+ ce->ce_file = mh_xstrdup(*file);
ce->ce_unlink = 0;
}
** Temporary file already exists, so we rename to
** version with extension.
*/
- char *file_org = strdup(ce->ce_file);
+ char *file_org = mh_xstrdup(ce->ce_file);
ce->ce_file = add(cp, ce->ce_file);
if (rename(file_org, ce->ce_file)) {
adios(EX_IOERR, ce->ce_file, "unable to rename %s to ",
file_org);
}
- free(file_org);
+ mh_free0(&file_org);
} else {
ce->ce_file = add(cp, ce->ce_file);
int j, k;
char *cp, **ap;
- field = getcpy(field);
+ field = mh_xstrdup(field);
/* copied from seq_read.c:seq_init */
for (ap = brkstring(field, " ", "\n"); *ap; ap++) {
}
}
- free(field);
+ mh_free0(&field);
return total;
}
static char *
get_msgnums(char *folder, char *sequences[])
{
+ enum state state;
+ struct field f = {{0}};
char *seqfile = concat(toabsdir(folder), "/", mh_seq, (void *)NULL);
FILE *fp = fopen(seqfile, "r");
- int state;
- char name[NAMESZ], field[BUFSIZ];
- char *cp;
char *msgnums = NULL, *this_msgnums, *old_msgnums;
/* no sequences file -> no messages */
return NULL;
}
- /* copied from seq_read.c:seq_public */
- for (state = FLD;;) {
- switch (state = m_getfld(state, name, field, sizeof(field),
- fp)) {
- case FLD:
- case FLDPLUS:
- if (state == FLDPLUS) {
- cp = mh_xstrdup(field);
- while (state == FLDPLUS) {
- state = m_getfld(state, name, field,
- sizeof(field), fp);
- cp = add(field, cp);
- }
-
- /*
- ** Here's where we differ from
- ** seq_public: if it's in a
- ** sequence we want, save the list
- ** of messages.
- */
- if (seq_in_list(name, sequences)) {
- this_msgnums = trimcpy(cp);
- if (msgnums == NULL) {
- msgnums = this_msgnums;
- } else {
- old_msgnums = msgnums;
- msgnums = concat(old_msgnums, " ", this_msgnums, (void *)NULL);
- mh_free0(&old_msgnums);
- mh_free0(&this_msgnums);
- }
- }
- mh_free0(&cp);
- } else {
- /* and here */
- if (seq_in_list(name, sequences)) {
- this_msgnums = trimcpy(field);
- if (msgnums == NULL) {
- msgnums = this_msgnums;
- } else {
- old_msgnums = msgnums;
- msgnums = concat(old_msgnums, " ", this_msgnums, (void *)NULL);
- mh_free0(&old_msgnums);
- mh_free0(&this_msgnums);
- }
+ for (state = FLD2;;) {
+ switch (state = m_getfld2(state, &f, fp)) {
+ case FLD2:
+ /*
+ ** if it's in a sequence we want,
+ ** save the list of messages.
+ */
+ if (seq_in_list(f.name, sequences)) {
+ this_msgnums = trimcpy(f.value);
+ if (msgnums == NULL) {
+ msgnums = this_msgnums;
+ } else {
+ old_msgnums = msgnums;
+ msgnums = concat(old_msgnums, " ",
+ this_msgnums,
- (void *)NULL);
- free(old_msgnums);
- free(this_msgnums);
++ NULL);
++ mh_free0(&old_msgnums);
++ mh_free0(&this_msgnums);
}
}
-
continue;
- case BODY:
- adios(EX_DATAERR, NULL, "no blank lines are permitted in %s",
- seqfile);
- /* fall */
+ case BODY2:
+ adios(EX_DATAERR, NULL, "no blank lines are permitted in %s", seqfile);
+ /* FALL */
- case FILEEOF:
+ case FILEEOF2:
break;
default:
adios(EX_SOFTWARE, NULL, "%s is poorly formatted", seqfile);
}
- break; /* break from for loop */
+ break;
}
fclose(fp);
if (is_cur || msgnums != NULL) {
if (*b->first == NULL) {
- *b->first = b->node = mh_xmalloc(sizeof(*b->node));
+ *b->first = b->node = mh_xcalloc(1, sizeof(*b->node));
} else {
- b->node->n_next = mh_xmalloc(sizeof(*b->node));
+ b->node->n_next = mh_xcalloc(1, sizeof(*b->node));
b->node = b->node->n_next;
}
b->node->n_name = folder;
while (vfgets(fp, &line) == OK) {
len = strlen(line) - 1;
line[len] = '\0';
- check_folder(getcpy(line), len, &b);
+ check_folder(mh_xstrdup(line), len, &b);
}
fclose(fp);
}
for (i = 0; sequences[i] != NULL; i++) {
len += strlen(sequences[i]) + 1;
}
- result = mh_xmalloc(len + 1);
+ result = mh_xcalloc(len + 1, sizeof(char));
for (i = 0, cp = result; sequences[i] != NULL; i++, cp += len + 1) {
len = strlen(sequences[i]);
} else {
unseen = seq_unseen; /* use default */
}
- dp = getcpy(unseen);
+ dp = mh_xstrdup(unseen);
for (ap = brkstring(dp, " ", "\n"); *ap; ap++) {
sequences[i++] = *ap;
}
if (folder)
adios(EX_USAGE, NULL, "only one folder at a time!");
else
- folder = getcpy(expandfol(cp));
+ folder = mh_xstrdup(expandfol(cp));
} else
app_msgarg(&msgs, cp);
}
padvise(NULL, "pattern error in %s %s", argp[-2], cp);
return NULL;
}
- n->n_patbuf = getcpy(dp);
+ n->n_patbuf = mh_xstrdup(dp);
return n;
case PROTHR:
{
struct nexus *p;
- p = (struct nexus *) mh_xcalloc((size_t) 1, sizeof *p);
+ p = mh_xcalloc(1, sizeof *p);
p->n_action = action;
return p;
TWSaction(params)
plist
{
- int state;
+ enum state state;
+ struct field f = {{0}};
char *bp;
struct tws *tw;
fseek(fp, start, SEEK_SET);
- for (state = FLD, bp = NULL;;) {
- switch (state = m_getfld(state, name, buf, sizeof buf, fp)) {
- case FLD:
- case FLDPLUS:
- if (bp != NULL) {
+ for (state = FLD2, bp = NULL;;) {
+ switch (state = m_getfld2(state, &f, fp)) {
+ case FLD2:
+ if (bp) {
- free(bp);
- bp = NULL;
+ mh_free0(&bp);
}
- bp = mh_xstrdup(buf);
- while (state == FLDPLUS) {
- state = m_getfld(state, name, buf,
- sizeof buf, fp);
- bp = add(buf, bp);
- }
- if (!mh_strcasecmp(name, n->n_datef))
- bp = getcpy(f.value);
++ bp = mh_xstrdup(f.value);
+ if (mh_strcasecmp(f.name, n->n_datef)==0) {
break;
+ }
continue;
- case BODY:
- case FILEEOF:
- case LENERR:
- case FMTERR:
- if (state == LENERR || state == FMTERR)
- advise(NULL, "format error in message %d", msgnum);
- if (bp != NULL)
- mh_free0(&bp);
+ case LENERR2:
+ case FMTERR2:
+ case IOERR2:
+ advise(NULL, "format error in message %d", msgnum);
+ /* FALL */
+
+ case BODY2:
+ case FILEEOF2:
- if (bp) {
- free(bp);
- }
++ mh_free0(&bp);
return 0;
default:
: (twsort(tw, &n->n_tws) < 0);
if (bp != NULL)
- free(bp);
+ mh_free0(&bp);
return state;
}
continue;
}
}
- addrs = addrs ? add(cp, add(", ", addrs)) : getcpy(cp);
+ addrs = addrs ? add(cp, add(", ", addrs)) : mh_xstrdup(cp);
}
if (!addrs) {
/* very similar to routine in replsbr.c */
static struct format *fmt;
static int ncomps = 0;
- static char **compbuffers = 0;
- static struct comp **used_buf = 0;
static int dat[5];
static void
rcvdistout(FILE *inb, char *form, char *addrs)
{
- int char_read = 0, format_len, i, state;
- char *tmpbuf, **nxtbuf, **ap;
- char *cp, *scanl, name[NAMESZ];
- struct comp *cptr, **savecomp;
+ int char_read = 0, format_len, i;
+ enum state state;
+ struct field f = {{0}};
+ char **ap;
+ char *cp, *scanl;
+ struct comp *cptr;
FILE *out;
if (!(out = fopen(drft, "w"))) {
cp = new_fs(form ? form : rcvdistcomps, NULL);
format_len = strlen(cp);
ncomps = fmt_compile(cp, &fmt) + 1;
- nxtbuf = compbuffers = mh_xcalloc(ncomps, sizeof(char *));
- savecomp = used_buf = mh_xcalloc(ncomps + 1, sizeof(struct comp *));
- savecomp += ncomps + 1;
- *--savecomp = 0;
-
- for (i = ncomps; i--;) {
- *nxtbuf++ = mh_xcalloc(SBUFSIZ, sizeof(char));
- }
- nxtbuf = compbuffers;
- tmpbuf = *nxtbuf++;
for (ap = addrcomps; *ap; ap++) {
FINDCOMP(cptr, *ap);
if (cptr) {
cptr->c_text = addrs;
}
- state = FLD;
+ state = FLD2;
while (1) {
- state = m_getfld(state, name, tmpbuf, SBUFSIZ, inb);
+ state = m_getfld2(state, &f, inb);
switch (state) {
- case FLD:
- case FLDPLUS:
- if ((cptr = wantcomp[CHASH(name)])) {
+ case FLD2:
+ if ((cptr = wantcomp[CHASH(f.name)])) {
do {
- if (mh_strcasecmp(name, cptr->c_name)!=0) {
+ if (mh_strcasecmp(f.name, cptr->c_name)!=0) {
continue;
}
- char_read += msg_count;
+ char_read += strlen(f.value);
if (!cptr->c_text) {
- cptr->c_text = tmpbuf;
- *--savecomp = cptr;
- tmpbuf = *nxtbuf++;
- cptr->c_text = getcpy(f.value);
++ cptr->c_text = mh_xstrdup(f.value);
} else {
cp = cptr->c_text;
i = strlen(cp) - 1;
cp = add("\t", cp);
}
}
- cptr->c_text = add(tmpbuf, cp);
- }
- while (state == FLDPLUS) {
- state = m_getfld(state, name, tmpbuf, SBUFSIZ, inb);
- cptr->c_text = add(tmpbuf, cptr->c_text);
- char_read += msg_count;
+ cptr->c_text = add(f.value, cp);
}
break;
} while ((cptr = cptr->c_next));
}
-
- while (state == FLDPLUS) {
- state = m_getfld(state, name, tmpbuf,
- SBUFSIZ, inb);
- }
break;
- case LENERR:
- case FMTERR:
- case BODY:
- case FILEEOF:
+ case LENERR2:
+ case FMTERR2:
+ case IOERR2:
+ case BODY2:
+ case FILEEOF2:
goto finished;
default:
finished: ;
i = format_len + char_read + 256;
- scanl = mh_xmalloc((size_t) i + 2);
+ scanl = mh_xcalloc(i + 2, sizeof(char));
dat[0] = dat[1] = dat[2] = dat[4] = 0;
dat[3] = OUTPUTLINELEN;
fmt_scan(fmt, scanl, i, dat);
}
fclose(out);
- free(scanl);
+ mh_free0(&scanl);
- for (nxtbuf = compbuffers, i = ncomps; (cptr = *savecomp++);
- nxtbuf++, i--) {
- mh_free0(&(cptr->c_text));
- }
- while (i-- > 0) {
- mh_free0(nxtbuf++);
- }
- mh_free0(&compbuffers);
- mh_free0(&used_buf);
}
*/
#include <h/mh.h>
+#include <h/utils.h>
#include <fcntl.h>
#include <h/signals.h>
#include <errno.h>
static char *tmpfilenam = NULL;
void unlink_done();
+ static void fix_mbox(int out, char *ofile);
int
main(int argc, char **argv)
if (folder)
adios(EX_USAGE, NULL, "only one folder at a time!");
else
- folder = getcpy(expandfol(cp));
+ folder = mh_xstrdup(expandfol(cp));
} else {
adios(EX_USAGE, NULL, "usage: %s [+folder] [switches]",
invo_name);
}
chmod(tmpfilenam, m_gmprot());
+ /* check if incoming mail is in mbox-format */
+ fix_mbox(fd, tmpfilenam);
+
/* copy the message from stdin into temp file */
cpydata(fileno(stdin), fd, "standard input", tmpfilenam);
return EX_OK;
}
+ static void
+ fix_mbox(int out, char *outfile)
+ {
+ char mbox[5];
+ int ret;
+
+ if ((ret = read(fileno(stdin), mbox, sizeof(mbox))) != sizeof(mbox)) {
+ if (ret == -1) {
+ adios(EX_IOERR, "standard input", "error reading");
+ }
+ return;
+ }
+
+ if (strncmp(mbox, "From ", sizeof(mbox))==0) {
+ do {
+ if ((ret = read(fileno(stdin), mbox, 1)) != 1) {
+ if (ret == -1) {
+ adios(EX_IOERR, "standard input", "error reading");
+ }
+ return;
+ }
+ } while (*mbox != '\n');
+ } else {
+ if (write(out, mbox, sizeof(mbox)) != sizeof(mbox)) {
+ adios(EX_IOERR, outfile, "error writing");
+ }
+ }
+ }
+
/*
** Clean up and exit
*/
{ NULL, 0 }
};
- /*
- ** Buffer size for content part of header fields.
- ** We want this to be large enough so that we don't
- ** do a lot of extra FLDPLUS calls on m_getfld but
- ** small enough so that we don't snarf the entire
- ** message body when we're not going to use any of it.
- */
- #define SBUFSIZ 256
-
static short ccto = -1;
static short cccc = -1;
static short ccme = -1;
static struct format *fmt;
static int ncomps = 0; /* # of interesting components */
- static char **compbuffers = NULL; /* buffers for component text */
- static struct comp **used_buf = NULL; /* stack for comp that use buffers */
static int dat[5]; /* aux. data for format routine */
FILE *in;
int buildsw = 0;
- filter = getcpy(etcpath(mhlreply));
-
setlocale(LC_ALL, "");
invo_name = mhbasename(argv[0]);
/* read user profile/context */
context_read();
+ filter = mh_xstrdup(etcpath(mhlreply));
+
arguments = getarguments(invo_name, argc, argv, 1);
argp = arguments;
if (!(cp = *argp++) || *cp == '-')
adios(EX_USAGE, NULL, "missing argument to %s",
argp[-2]);
- file = getcpy(expanddir(cp));
+ file = mh_xstrdup(expanddir(cp));
continue;
case FORMSW:
if (!(form = *argp++) || *form == '-')
if (!(cp = *argp++) || *cp == '-')
adios(EX_USAGE, NULL, "missing argument to %s",
argp[-2]);
- filter = getcpy(etcpath(cp));
+ filter = mh_xstrdup(etcpath(cp));
continue;
case NFILTSW:
filter = NULL;
if (folder)
adios(EX_USAGE, NULL, "only one folder at a time!");
else
- folder = getcpy(expandfol(cp));
+ folder = mh_xstrdup(expandfol(cp));
} else {
if (msg)
adios(EX_USAGE, NULL, "only one message at a time!");
if (ccme == -1)
ccme = groupreply;
- cwd = getcpy(pwd());
+ cwd = mh_xstrdup(pwd());
if (file && (msg || folder))
adios(EX_USAGE, NULL, "can't mix files and folders/msgs");
context_save(); /* save the context file */
}
- msg = file ? file : getcpy(m_name(mp->lowsel));
+ msg = file ? file : mh_xstrdup(m_name(mp->lowsel));
if ((in = fopen(msg, "r")) == NULL)
adios(EX_IOERR, msg, "unable to open");
replout(FILE *inb, char *drft, struct msgs *mp,
int mime, char *form, char *filter)
{
- int state, i;
+ enum state state;
+ struct field f = {{0}};
+ int i;
struct comp *cptr;
- char *tmpbuf;
- char **nxtbuf;
char **ap;
- struct comp **savecomp;
int char_read = 0, format_len, mask;
- char name[NAMESZ], *scanl;
+ char *scanl;
unsigned char *cp;
FILE *out;
/* compile format string */
ncomps = fmt_compile(cp, &fmt) + 1;
- nxtbuf = compbuffers = mh_xcalloc(ncomps, sizeof(char *));
- savecomp = used_buf = mh_xcalloc(ncomps+1, sizeof(struct comp *));
- savecomp += ncomps + 1;
- *--savecomp = NULL; /* point at zero'd end minus 1 */
-
- for (i = ncomps; i--; )
- *nxtbuf++ = mh_xcalloc(SBUFSIZ, sizeof(char));
-
- nxtbuf = compbuffers; /* point at start */
- tmpbuf = *nxtbuf++;
-
for (ap = addrcomps; *ap; ap++) {
FINDCOMP(cptr, *ap);
if (cptr)
if ((cp = getenv("USER"))) {
FINDCOMP(cptr, "user");
if (cptr)
- cptr->c_text = getcpy(cp);
+ cptr->c_text = mh_xstrdup(cp);
}
if (!ccme)
ismymbox(NULL);
/*
** pick any interesting stuff out of msg "inb"
*/
- for (state = FLD;;) {
- state = m_getfld(state, name, tmpbuf, SBUFSIZ, inb);
+ for (state = FLD2;;) {
+ state = m_getfld2(state, &f, inb);
switch (state) {
- case FLD:
- case FLDPLUS:
+ case FLD2:
/*
** if we're interested in this component, save
** a pointer to the component text, then start
** temp buffer (buffer switching saves an extra
** copy of the component text).
*/
- if ((cptr = wantcomp[CHASH(name)]))
+ if ((cptr = wantcomp[CHASH(f.name)])) {
do {
- if (!mh_strcasecmp(name, cptr->c_name)) {
- char_read += msg_count;
- if (! cptr->c_text) {
- i = strlen(cptr->c_text = tmpbuf) - 1;
- if (tmpbuf[i] == '\n')
- tmpbuf[i] = '\0';
- *--savecomp = cptr;
- tmpbuf = *nxtbuf++;
- } else {
- i = strlen(cp = cptr->c_text) - 1;
- if (cp[i] == '\n') {
- if (cptr->c_type & CT_ADDR) {
- cp[i] = '\0';
- cp = add(",\n\t", cp);
- } else {
- cp = add("\t", cp);
- }
- }
- cptr->c_text = add(tmpbuf, cp);
+ if (mh_strcasecmp(f.name, cptr->c_name)!=0) {
+ continue;
+ }
+ char_read += strlen(f.value);
+ if (!cptr->c_text) {
- cptr->c_text = getcpy(f.value);
++ cptr->c_text = mh_xstrdup(f.value);
+ i = strlen(cptr->c_text) - 1;
+ if (cptr->c_text[i] == '\n') {
+ cptr->c_text[i] = '\0';
}
- while (state == FLDPLUS) {
- state = m_getfld(state, name, tmpbuf,
- SBUFSIZ, inb);
- cptr->c_text = add(tmpbuf, cptr->c_text);
- char_read += msg_count;
+ } else {
+ cp = cptr->c_text;
+ i = strlen(cp) - 1;
+ if (cp[i] == '\n') {
+ if (cptr->c_type & CT_ADDR) {
+ cp[i] = '\0';
+ cp = add(",\n\t", cp);
+ } else {
+ cp = add("\t", cp);
+ }
}
- break;
+ cptr->c_text = add(f.value, cp);
}
+ break;
} while ((cptr = cptr->c_next));
-
- while (state == FLDPLUS)
- state = m_getfld(state, name, tmpbuf,
- SBUFSIZ, inb);
+ }
break;
- case LENERR:
- case FMTERR:
- case BODY:
- case FILEEOF:
+ case LENERR2:
+ case FMTERR2:
+ case IOERR2:
+ case BODY2:
+ case FILEEOF2:
goto finished;
default:
}
if (sp != cptr->c_text) {
cp = cptr->c_text;
- cptr->c_text = getcpy(sp);
- free(cp);
+ cptr->c_text = mh_xstrdup(sp);
+ mh_free0(&cp);
}
}
i = format_len + char_read + 256;
- scanl = mh_xmalloc((size_t) i + 2);
+ scanl = mh_xcalloc(i + 2, sizeof(char));
dat[0] = 0;
dat[1] = 0;
dat[2] = 0;
}
/* return dynamically allocated buffers */
- free(scanl);
+ mh_free0(&scanl);
- for (nxtbuf = compbuffers, i = ncomps; (cptr = *savecomp++);
- nxtbuf++, i--)
- mh_free0(&(cptr->c_text)); /* if not nxtbuf, nxtbuf already freed */
- while ( i-- > 0)
- mh_free0(nxtbuf++); /* free unused nxtbufs */
- mh_free0(&compbuffers);
- mh_free0(&used_buf);
}
static char *buf; /* our current working buffer */
** returns a pointer to the concatenated address string.
**
** We try to not do a lot of malloc/copy/free's (which is why we
-** don't call "getcpy") but still place no upper limit on the
+** don't call "mh_xstrdup") but still place no upper limit on the
** length of the result string.
**
** This routine is an override for the equally named one in sbr/fmt_addr.c.
/* if we don't have a buffer yet, get one */
if (bufsiz == 0) {
- buf = mh_xmalloc(BUFINCR);
+ buf = mh_xcalloc(BUFINCR, sizeof(char));
last_dst = buf; /* XXX */
bufsiz = BUFINCR - 6; /* leave some slop */
bufend = buf + bufsiz;
static void
replfilter(FILE *in, FILE *out, char *filter)
{
- int pid, n;
+ int pid, pid_show, n;
+ int mailpipe[2];
char *errstr;
if (filter == NULL)
rewind(in);
lseek(fileno(in), (off_t) 0, SEEK_SET);
- switch (pid = fork()) {
+ if (pipe(mailpipe) == -1) {
+ adios(EX_OSERR, "pipe", "can't create pipe");
+ }
+
+ switch (pid_show = fork()) {
case NOTOK:
adios(EX_OSERR, "fork", "unable to");
case OK:
dup2(fileno(in), fileno(stdin));
+ dup2(mailpipe[1], fileno(stdout));
+ for (n=3; n<OPEN_MAX; n++) {
+ close(n);
+ }
+
+ execlp("show", "show", "-file", "-", NULL);
+
+ adios(EX_OSERR, "exec", "unable to");
+ }
+
+ switch (pid = fork()) {
+ case NOTOK:
+ adios(EX_OSERR, "fork", "unable to");
+
+ case OK:
+ dup2(mailpipe[0], fileno(stdin));
dup2(fileno(out), fileno(stdout));
for (n=3; n<OPEN_MAX; n++) {
close(n);
_exit(EX_OSERR);
default:
- if (pidXwait(pid, "mhl"))
+ if (pidXwait(-1, "show | mhl"))
exit(EX_SOFTWARE);
fseek(out, 0L, SEEK_END);
break;
}
+
+ close(mailpipe[0]);
+ close(mailpipe[1]);
}
adios(EX_USAGE, NULL, "missing argument to %s",
argp[-2]);
if (strcmp(file = cp, "-")!=0)
- file = getcpy(expanddir(cp));
+ file = mh_xstrdup(expanddir(cp));
continue;
}
}
if (folder)
adios(EX_USAGE, NULL, "only one folder at a time!");
else
- folder = getcpy(expandfol(cp));
+ folder = mh_xstrdup(expandfol(cp));
} else
app_msgarg(&msgs, cp);
}
- /*
- ** Get new format string. Must be before chdir().
- */
- fmtstr = new_fs(form, FORMAT);
+ /* Set format string. Must be before chdir(). */
+ fmtstr = new_fs(form, scanformat);
/*
** We are scanning a maildrop file
adios(EX_IOERR, file, "unable to open");
}
- thisisanmbox(in);
for (msgnum = 1; ; ++msgnum) {
state = scan(in, msgnum, SCN_MBOX, fmtstr, width, 0, 0);
if (state != SCNMSG)
if (chdir(maildir) == NOTOK)
adios(EX_OSERR, maildir, "unable to change directory to");
- /* read folder and create message structure */
if (!(mp = folder_read(folder)))
adios(EX_IOERR, NULL, "unable to read folder %s", folder);
for (msgnum = 0; msgnum < msgs.size; msgnum++)
if (!m_convert(mp, msgs.msgs[msgnum]))
exit(EX_USAGE);
- seq_setprev(mp); /* set the Previous-Sequence */
+ seq_setprev(mp);
- context_replace(curfolder, folder); /* update current folder */
- seq_save(mp); /* synchronize message sequences */
- context_save(); /* save the context file */
+ context_replace(curfolder, folder);
+ seq_save(mp);
+ context_save();
/*
** Get the sequence number for each `unseen' sequence
if (*cp) {
char **ap, *dp;
- dp = getcpy(cp);
+ dp = mh_xstrdup(cp);
ap = brkstring(dp, " ", "\n");
for (i = 0; ap && *ap; i++, ap++) {
seqnum[i] = seq_getnum(mp, *ap);
}
num_unseen_seq = i;
if (dp) {
- free(dp);
+ mh_free0(&dp);
}
}
for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
- if (is_selected(mp, msgnum)) {
- if ((in = fopen(cp = m_name(msgnum), "r")) == NULL) {
- admonish(cp, "unable to open message");
- continue;
- }
+ if (!is_selected(mp, msgnum)) {
+ continue;
+ }
- /*
- ** Check if message is in any sequence given
- ** by Unseen-Sequence profile entry.
- */
- unseen = 0;
- for (i = 0; i < num_unseen_seq; i++) {
- if (in_sequence(mp, seqnum[i], msgnum)) {
- unseen = 1;
- break;
- }
- }
+ if ((in = fopen(cp = m_name(msgnum), "r")) == NULL) {
+ admonish(cp, "unable to open message");
+ continue;
+ }
- switch (state = scan(in, msgnum, SCN_FOLD, fmtstr,
- width, msgnum==mp->curmsg, unseen)) {
- case SCNMSG:
- case SCNERR:
+ /*
+ ** Check if message is in any sequence given
+ ** by Unseen-Sequence profile entry.
+ */
+ unseen = 0;
+ for (i = 0; i < num_unseen_seq; i++) {
+ if (in_sequence(mp, seqnum[i], msgnum)) {
+ unseen = 1;
break;
+ }
+ }
- default:
- adios(EX_SOFTWARE, NULL, "scan() botch(%d)", state);
+ switch (state = scan(in, msgnum, SCN_FOLD, fmtstr,
+ width, msgnum==mp->curmsg, unseen)) {
+ case SCNMSG:
+ case SCNERR:
+ break;
- case SCNEOF:
- advise(NULL, "message %d: empty", msgnum);
- break;
- }
- fclose(in);
+ default:
+ adios(EX_SOFTWARE, NULL, "scan() botch(%d)", state);
+
+ case SCNEOF:
+ advise(NULL, "message %d: empty", msgnum);
+ break;
}
+ fclose(in);
}
-
- folder_free(mp); /* free folder/message structure */
+ folder_free(mp);
return 0;
}
#include <sys/stat.h>
#include <sysexits.h>
- #ifdef _FSTDIO
- # define _ptr _p /* Gag */
- # define _cnt _w /* Wretch */
- #endif
-
#define MAXSCANL 256 /* longest possible scan line */
- /*
- ** Buffer size for content part of header fields. We want this
- ** to be large enough so that we don't do a lot of extra FLDPLUS
- ** calls on m_getfld.
- */
- #define SBUFSIZ 512
-
static struct format *fmt;
static struct comp *datecomp; /* pntr to "date" comp */
static int ncomps = 0; /* # of interesting components */
- static char **compbuffers = NULL; /* buffers for component text */
- static struct comp **used_buf = NULL; /* stack for comp that use buffers */
static int dat[5]; /* aux. data for format routine */
int unseen)
{
static int slwidth;
- int i, compnum, state;
- unsigned char *cp, *tmpbuf;
- char **nxtbuf;
+ int compnum, i;
+ enum state state;
+ struct field f = {{0}};
+ char *cp;
struct comp *cptr;
- struct comp **savecomp;
char *scnmsg = NULL;
FILE *scnout = NULL;
- char name[NAMESZ];
int incing = (outnum != SCN_MBOX && outnum != SCN_FOLD);
int scanfolder = (outnum == SCN_FOLD);
long fpos;
struct stat st;
+ int blankline;
/* first-time only initialization */
if (!scanl) {
width = MAXSCANL;
}
dat[3] = slwidth = width;
- scanl = (char *) mh_xmalloc((size_t) SCAN_CHARWIDTH *
- (slwidth + 2)); /* probably for \n and \0 */
+ scanl = mh_xcalloc(slwidth + 2, SCAN_CHARWIDTH); /* probably for \n and \0 */
/* Compile format string */
ncomps = fmt_compile(fmtstr, &fmt) + 1;
FINDCOMP(datecomp, "date");
ncomps = 1;
datecomp = NULL;
}
+ }
- nxtbuf = compbuffers = mh_xcalloc(ncomps, sizeof(char *));
- used_buf = mh_xcalloc(ncomps+1, sizeof(struct comp *));
- /* NULL-terminate array */
- used_buf += ncomps;
- *used_buf = NULL;
- /* allocate space for the items */
- for (i = ncomps; i--; )
- *nxtbuf++ = mh_xcalloc(SBUFSIZ, sizeof(char));
+ if (feof(inb)) {
+ return SCNEOF;
}
/*
** each-message initialization
*/
- nxtbuf = compbuffers;
- savecomp = used_buf;
- tmpbuf = *nxtbuf++;
dat[0] = innum ? innum : outnum;
dat[1] = curflg;
dat[4] = unseen;
fpos = ftell(inb);
- /*
- ** Get the first field. If the message is non-empty
- ** and we're doing an "inc", open the output file.
- */
- if ((state = m_getfld(FLD, name, tmpbuf, SBUFSIZ, inb)) == FILEEOF) {
- if (ferror(inb)) {
- advise("read", "unable to"); /* "read error" */
- return SCNFAT;
- } else {
- return SCNEOF;
- }
- }
-
if (incing) {
scnmsg = m_name(outnum);
if (*scnmsg == '?') /* msg num out of range */
if (!(scnout = fopen(scnmsg, "w")))
adios(EX_IOERR, scnmsg, "unable to write");
}
-
/* scan - main loop */
- for (compnum = 1; ;
- state = m_getfld(state, name, tmpbuf, SBUFSIZ, inb)) {
+ for (compnum = 1, state = FLD2; ; ) {
+ state = m_getfld2(state, &f, inb);
switch (state) {
- case FLD:
- case FLDPLUS:
+ case FLD2:
compnum++;
if (incing) {
- FPUTS(name);
+ FPUTS(f.name);
FPUTS(":");
- FPUTS(tmpbuf);
+ FPUTS(f.value);
}
- /*
- ** if we're interested in this component, save
- ** a pointer to the component text, then start
- ** using our next free buffer as the component
- ** temp buffer (buffer switching saves an extra
- ** copy of the component text).
- */
- if (fmtstr && (cptr = wantcomp[CHASH(name)])) {
+ if (fmtstr && (cptr = wantcomp[CHASH(f.name)])) {
+ /*
+ ** we're interested in this component,
+ ** but find the right one in the hash
+ ** collision chain ...
+ */
do {
- if (mh_strcasecmp(name, cptr->c_name)!=0) {
+ if (mh_strcasecmp(f.name, cptr->c_name)!=0) {
continue;
}
- if (!cptr->c_text) {
- cptr->c_text = tmpbuf;
- cp = tmpbuf+strlen(tmpbuf)-1;
- for (; cp >= tmpbuf; cp--) {
- if (isspace(*cp))
- *cp = '\0';
- else
- break;
+ if (cptr->c_text) {
+ free(cptr->c_text);
+ cptr->c_text = NULL;
+ }
- cptr->c_text = getcpy(f.value);
++ cptr->c_text = mh_xstrdup(f.value);
+ cp = cptr->c_text + strlen(cptr->c_text) - 1;
+ for (; cp >= cptr->c_text; cp--) {
+ if (isspace(*cp)) {
+ *cp = '\0';
+ } else {
+ break;
}
- *--savecomp = cptr;
- tmpbuf = *nxtbuf++;
}
break;
} while ((cptr = cptr->c_next));
}
-
- while (state == FLDPLUS) {
- state = m_getfld(state, name, tmpbuf, SBUFSIZ,
- inb);
- if (incing)
- FPUTS(tmpbuf);
- }
break;
- case BODY:
+ case BODY2:
compnum = -1;
if (scanfolder) {
/* stop here if we scan a msg in a folder */
- state = FILEEOF;
+ state = FILEEOF2;
goto finished;
}
/* otherwise (mbox): snarf the body */
+ if (strncmp("From ", f.value, 5)==0) {
+ state = FILEEOF2;
+ goto finished;
+ }
if (incing) {
FPUTS("\n");
- FPUTS(tmpbuf);
+ FPUTS(f.value);
}
body:;
- while (state == BODY) {
- state = m_getfld(state, name, tmpbuf, SBUFSIZ,
- inb);
+ blankline = 0;
+ while ((state = m_getfld2(state, &f, inb)) == BODY2) {
+ /*
+ ** recognize From lines without blank lines
+ ** before them as well.
+ */
+ if (strncmp("From ", f.value, 5)==0) {
+ state = FILEEOF2;
+ goto finished;
+ }
+ /*
+ ** delay the printing of blank lines
+ ** because if it's the end of the message,
+ ** then we must omit the blank line,
+ ** as it is not part of the message but
+ ** part of the mbox format
+ */
+ if (blankline) {
+ /* print the delayed blank line */
+ FPUTS("\n");
+ blankline = 0;
+ }
+ if (strcmp(f.value, "\n")==0) {
+ blankline = 1;
+ continue;
+ }
if (incing) {
- FPUTS(tmpbuf);
+ FPUTS(f.value);
}
}
goto finished;
- case LENERR:
- case FMTERR:
- fprintf(stderr, innum ? "??Format error (message %d) in " : "??Format error in ", outnum ? outnum : innum);
+ case LENERR2:
+ advise(NULL, "line \"%s\" too long", trim(f.value));
+ goto handleerror;
+
+ case FMTERR2:
+ if (strncmp("From ", f.value, 5)==0) {
+ state = FILEEOF2;
+ goto finished;
+ }
+ /* FALL */
+
+ case IOERR2:
+ handleerror:;
+ fprintf(stderr, innum ?
+ "??Format error (message %d) in " :
+ "??Format error in ",
+ outnum ? outnum : innum);
fprintf(stderr, "component %d\n", compnum);
if (incing) {
FPUTS("\n\nBAD MSG:\n");
- FPUTS(name);
+ FPUTS(f.name); /* XXX use f.field? */
FPUTS("\n");
- state = BODY;
+ state = BODY2;
goto body;
}
/* fall through if we scan only */
- case FILEEOF:
+ case FILEEOF2:
goto finished;
default:
}
finished:
-
/* Format and output the scan line. */
if (ferror(inb)) {
advise("read", "unable to");
if (datecomp && !datecomp->c_text) {
if (!datecomp->c_text) {
if (!datecomp->c_tws)
- datecomp->c_tws = (struct tws *) mh_xcalloc((size_t) 1, sizeof(*datecomp->c_tws));
+ datecomp->c_tws = mh_xcalloc(1, sizeof(*datecomp->c_tws));
if (!datecomp->c_tws)
adios(EX_OSERR, NULL, "unable to allocate tws buffer");
*datecomp->c_tws = *dlocaltime((time_t *) &st.st_mtime);
fputs(scanl, stdout);
}
- /* return dynamically allocated buffers to pool */
- while ((cptr = *savecomp++)) {
- *--nxtbuf = cptr->c_text;
- cptr->c_text = NULL;
+ /* clean up old values */
+ for (i=0; i < sizeof(wantcomp)/sizeof(wantcomp[0]); i++) {
+ for (cptr=wantcomp[i]; cptr; cptr=cptr->c_next) {
+ if (cptr->c_text) {
+ free(cptr->c_text);
+ cptr->c_text = NULL;
+ }
+ }
}
- *--nxtbuf = tmpbuf;
if (incing && (ferror(scnout) || fclose(scnout) == EOF))
adios(EX_IOERR, scnmsg, "write error on");
- return (state != FILEEOF ? SCNERR : SCNMSG);
+ return (state == FILEEOF2 ? SCNMSG : SCNERR);
}
static int
parse(int fd)
{
- int i, state;
- int fd1;
+ enum state state;
+ struct field f = {{0}};
+ int i, fd1;
char *cp, *dp, *lp;
- char name[NAMESZ], field[BUFSIZ];
struct pair *p, *q;
FILE *in;
/* add special entries to lookup table */
if ((p = lookup(hdrs, "source"))) {
- p->p_value = getcpy(sender);
+ p->p_value = mh_xstrdup(sender);
}
if ((p = lookup(hdrs, "addr"))) {
- p->p_value = getcpy(addr);
+ p->p_value = mh_xstrdup(addr);
}
/*
** Scan the headers of the message and build a lookup table.
*/
- for (i = 0, state = FLD;;) {
- switch (state = m_getfld(state, name, field, sizeof(field),
- in)) {
- case FLD:
- case FLDPLUS:
- lp = mh_xstrdup(field);
- while (state == FLDPLUS) {
- state = m_getfld(state, name, field,
- sizeof(field), in);
- lp = add(field, lp);
- }
+ for (i = 0, state = FLD2;;) {
+ switch (state = m_getfld2(state, &f, in)) {
+ case FLD2:
- lp = getcpy(f.value);
++ lp = mh_xstrdup(f.value);
for (p = hdrs; p->p_name; p++) {
- if (mh_strcasecmp(p->p_name, name)!=0) {
+ if (mh_strcasecmp(p->p_name, f.name)!=0) {
if (!(p->p_flags & P_HID)) {
if ((cp = p->p_value)) {
if (p->p_flags & P_ADR) {
}
p->p_value = add(lp, cp);
}
- free(lp);
+ mh_free0(&lp);
break;
}
}
if (!p->p_name && i < NVEC) {
- p->p_name = mh_xstrdup(name);
- p->p_name = getcpy(f.name);
++ p->p_name = mh_xstrdup(f.name);
p->p_value = lp;
p->p_flags = P_NIL;
p++, i++;
}
continue;
- case BODY:
- case FILEEOF:
+ case BODY2:
+ case FILEEOF2:
break;
- case LENERR:
- case FMTERR:
+ case LENERR2:
+ case FMTERR2:
+ case IOERR2:
advise(NULL, "format error in message");
break;
if (!(q = lookup(hdrs, "reply-to")) || !q->p_value) {
q = lookup(hdrs, "from");
}
- p->p_value = getcpy(q ? q->p_value : "");
+ p->p_value = mh_xstrdup(q ? q->p_value : "");
p->p_flags &= ~P_CHK;
if (debug) {
debug_printf("vars[%d]: name=\"%s\" value=\"%s\"\n",
return;
}
if ((p = lookup(vars, "sender"))) {
- p->p_value = getcpy(sender);
+ p->p_value = mh_xstrdup(sender);
}
if ((p = lookup(vars, "address"))) {
- p->p_value = getcpy(addr);
+ p->p_value = mh_xstrdup(addr);
}
if ((p = lookup(vars, "size"))) {
snprintf(buffer, sizeof(buffer), "%d",
fstat(fd, &st) != -1 ? (int) st.st_size : 0);
- p->p_value = getcpy(buffer);
+ p->p_value = mh_xstrdup(buffer);
}
if ((p = lookup(vars, "info"))) {
- p->p_value = getcpy(info);
+ p->p_value = mh_xstrdup(info);
}
if (debug) {
for (p = vars; p->p_name; p++) {
unsigned char buffer[BUFSIZ];
if (!envelope) {
- *sender = getcpy("");
+ *sender = mh_xstrdup("");
return;
}
} else {
break;
}
- *sender = getcpy(buffer);
+ *sender = mh_xstrdup(buffer);
}
** get copy of envelope information
** ("From " line)
*/
- envelope = getcpy(buffer);
+ envelope = mh_xstrdup(buffer);
/* Put the delivery date in message */
fputs(ddate, ffp);
*sp = ' ';
}
}
- return getcpy(bp);
+ return mh_xstrdup(bp);
}
/*
if (folder)
adios(EX_USAGE, NULL, "only one folder at a time!");
else
- folder = getcpy(expandfol(cp));
+ folder = mh_xstrdup(expandfol(cp));
} else
app_msgarg(&msgs, cp);
}
/*
** sort a list of pointers to our "messages to be sorted".
*/
- dlist = (struct smsg **) mh_xcalloc((size_t) (nmsgs+1), sizeof(*dlist));
+ dlist = mh_xcalloc(nmsgs+1, sizeof(*dlist));
for (i = 0; i < nmsgs; i++)
dlist[i] = &smsgs[i];
dlist[nmsgs] = 0;
struct smsg **slist, **flist;
struct smsg ***il, **fp, **dp;
- slist = (struct smsg **)
- mh_xmalloc((nmsgs+1) * sizeof(*slist));
+ slist = mh_xcalloc(nmsgs+1, sizeof(*slist));
memcpy((char *)slist, (char *)dlist, (nmsgs+1)*sizeof(*slist));
qsort((char *)slist, nmsgs, sizeof(*slist),
(qsort_comp) subsort);
** the collection of messages with the same subj
** given a message number.
*/
- il = (struct smsg ***) mh_xcalloc(mp->hghsel+1, sizeof(*il));
+ il = mh_xcalloc(mp->hghsel+1, sizeof(*il));
if (! il)
adios(EX_OSERR, NULL, "couldn't allocate msg list");
for (i = 0; i < nmsgs; i++)
** make up the final list, chronological but with
** all the same subjects grouped together.
*/
- flist = (struct smsg **)
- mh_xmalloc((nmsgs+1) * sizeof(*flist));
+ flist = mh_xcalloc(nmsgs+1, sizeof(*flist));
fp = flist;
for (dp = dlist; *dp;) {
struct smsg **s = il[(*dp++)->s_msg];
}
}
*fp = 0;
- free(slist);
- free(dlist);
+ mh_free0(&slist);
+ mh_free0(&dlist);
dlist = flist;
}
twscopy(&tb, dlocaltimenow());
- smsgs = (struct smsg *) mh_xcalloc((size_t) (mp->hghsel - mp->lowsel + 2),
- sizeof(*smsgs));
+ smsgs = mh_xcalloc(mp->hghsel - mp->lowsel + 2, sizeof(*smsgs));
s = smsgs;
for (msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) {
static int
get_fields(char *datesw, int msg, struct smsg *smsg)
{
- int state;
+ enum state state;
+ struct field f = {{0}};
int compnum;
- char *msgnam, buf[BUFSIZ], nam[NAMESZ];
+ char *msgnam;
struct tws *tw;
char *datecomp = NULL, *subjcomp = NULL;
FILE *in;
admonish(msgnam, "unable to read message");
return (0);
}
- for (compnum = 1, state = FLD;;) {
- switch (state = m_getfld(state, nam, buf, sizeof(buf), in)) {
- case FLD:
- case FLDPLUS:
- compnum++;
- if (!mh_strcasecmp(nam, datesw)) {
- datecomp = add(buf, datecomp);
- while (state == FLDPLUS) {
- state = m_getfld(state, nam, buf,
- sizeof(buf), in);
- datecomp = add(buf, datecomp);
- }
- if (!subjsort || subjcomp)
+ for (compnum = 1, state = FLD2;; compnum++) {
+ switch (state = m_getfld2(state, &f, in)) {
+ case FLD2:
+ if (mh_strcasecmp(f.name, datesw)==0) {
- datecomp = getcpy(f.value);
++ datecomp = mh_xstrdup(f.value);
+ if (!subjsort || subjcomp) {
break;
- } else if (subjsort && !mh_strcasecmp(nam, subjsort)) {
- subjcomp = add(buf, subjcomp);
- while (state == FLDPLUS) {
- state = m_getfld(state, nam, buf,
- sizeof(buf), in);
- subjcomp = add(buf, subjcomp);
}
- if (datecomp)
+ } else if (subjsort && mh_strcasecmp(f.name,
+ subjsort)==0) {
- subjcomp = getcpy(f.value);
++ subjcomp = mh_xstrdup(f.value);
+ if (datecomp) {
break;
- } else {
- /* just flush this guy */
- while (state == FLDPLUS)
- state = m_getfld(state, nam, buf,
- sizeof(buf), in);
+ }
}
continue;
- case BODY:
- case FILEEOF:
+ case BODY2:
+ case FILEEOF2:
break;
- case LENERR:
- case FMTERR:
- if (state == LENERR || state == FMTERR)
- admonish(NULL, "format error in message %d (header #%d)", msg, compnum);
- if (datecomp)
+ case LENERR2:
+ case FMTERR2:
+ case IOERR2:
+ admonish(NULL, "format error in message %d (header #%d)", msg, compnum);
+ if (datecomp) {
- free(datecomp);
+ mh_free0(&datecomp);
- if (subjcomp)
+ }
+ if (subjcomp) {
- free(subjcomp);
+ mh_free0(&subjcomp);
+ }
fclose(in);
return (0);
}
fclose(in);
if (datecomp)
- free(datecomp);
+ mh_free0(&datecomp);
return (1);
}
static char *tmpfil;
static char *subject = NULL; /* the subject field for BCC'ing */
+static struct mailname *from = NULL; /* the from field for BCC'ing */
static char fccs[BUFSIZ] = "";
struct mailname *bccs = NULL; /* list of the bcc recipients */
struct mailname *recipients = NULL; /* list of the recipients */
int
main(int argc, char **argv)
{
- int state, compnum;
+ enum state state;
+ struct field f = {{0}};
+ int compnum;
char *cp, *msg = NULL, **argp, **arguments;
- char **sargv, buf[BUFSIZ], name[NAMESZ];
+ char **sargv, buf[BUFSIZ];
FILE *in;
setlocale(LC_ALL, "");
verbose++;
out = stdout;
} else {
- tmpfil = getcpy(m_mktemp2("/tmp/", invo_name, NULL, &out));
+ tmpfil = mh_xstrdup(m_mktemp2("/tmp/", invo_name, NULL, &out));
}
/* check for "Aliasfile:" profile entry */
char *dp, **ap;
aliasflg = 1;
- for (ap=brkstring(dp=getcpy(cp), " ", "\n"); ap && *ap;
+ for (ap=brkstring(dp=mh_xstrdup(cp), " ", "\n"); ap && *ap;
ap++) {
if ((state = alias(etcpath(*ap))) != AK_OK) {
adios(EX_IOERR, NULL, "aliasing error in file %s: %s",
hdrtab = (msgstate == normal) ? NHeaders : RHeaders;
- for (compnum = 1, state = FLD;;) {
- switch (state = m_getfld(state, name, buf, sizeof(buf), in)) {
- case FLD:
- case FLDPLUS:
+ for (compnum = 1, state = FLD2;;) {
+ switch (state = m_getfld2(state, &f, in)) {
+ case FLD2:
compnum++;
- cp = mh_xstrdup(buf);
- while (state == FLDPLUS) {
- state = m_getfld(state, name, buf,
- sizeof(buf), in);
- cp = add(buf, cp);
- }
- putfmt(name, cp, out);
- mh_free0(&cp);
+ putfmt(f.name, f.value, out);
continue;
- case BODY:
+ case BODY2:
finish_headers(out);
- fprintf(out, "\n%s", buf);
- while (state == BODY) {
- state = m_getfld(state, name, buf,
- sizeof(buf), in);
- fputs(buf, out);
+ fprintf(out, "\n%s", f.value);
+ while ((state = m_getfld2(state, &f, in)) == BODY2) {
+ fputs(f.value, out);
}
break;
- case FILEEOF:
+ case FILEEOF2:
finish_headers(out);
break;
- case LENERR:
- case FMTERR:
+ case LENERR2:
+ case FMTERR2:
+ case IOERR2:
adios(EX_DATAERR, NULL, "message format error in component #%d",
compnum);
adios(EX_DATAERR, NULL, "message has no recipients");
}
- sargv = mh_xmalloc(sizeof(char **) * (recipientsc + 4));
+ sargv = mh_xcalloc(recipientsc + 4, sizeof(char **));
argp = sargv;
*argp++ = "send-mail";
}
while (recipients != NULL) {
- cp = getcpy(recipients->m_mbox);
+ cp = mh_xstrdup(recipients->m_mbox);
if (recipients->m_host) {
cp = add("@", cp);
cp = add(recipients->m_host, cp);
}
if (hdr->flags & HSUB) {
- subject = getcpy(str);
+ subject = mh_xstrdup(str);
}
if (!(hdr->flags & HADR)) {
/* needed because the address parser holds global state */
ismymbox(NULL);
- for ( mp = addr_start.m_next; mp; mp = mp->m_next) {
+ for (mp = addr_start.m_next; mp; mp = mp->m_next) {
if (ismymbox(mp)) {
msgflags |= MFMM;
if (my == NULL) {
- my = mp;
+ from = my = mp;
}
}
}
}
if (mp->m_ingrp) {
if (mp->m_gname != NULL) {
- cp = getcpy(mp->m_gname);
+ cp = mh_xstrdup(mp->m_gname);
cp = add(";", cp);
linepos = putone(cp, linepos, namelen);
- free(cp);
+ mh_free0(&cp);
cp = NULL;
}
} else {
fprintf(stderr, "Skipped %sFcc %s: unable to system().\n",
msgstate == resent ? "Resent-" : "", folders);
} else if (status != 0) {
- fprintf(stderr, "%sFcc %s: Problems occured.\n",
+ fprintf(stderr, "%sFcc %s: Problems occurred.\n",
msgstate == resent ? "Resent-" : "", folders);
}
}
FILE *out = NULL;
for (mp=bccs; mp; mp=mp->m_next) {
- bccdraft = getcpy(m_mktemp2("/tmp/", invo_name, NULL, &out));
+ bccdraft = mh_xstrdup(m_mktemp2("/tmp/", invo_name, NULL, &out));
fprintf(out, "To: %s\n", mp->m_text);
+ if (from) {
+ fprintf(out, "From: %s\n", from->m_text);
+ }
fprintf(out, "Subject: [BCC] %s", subject ? subject : "");
fprintf(out, "%s: %s\n", attach_hdr, origmsg);
fprintf(out, "------------\n");
}
pclose(in);
}
- free(cmd);
+ mh_free0(&cmd);
naddrs += n;
cmd = add("ali -list", NULL);
}
pclose(in);
}
- free(cmd);
+ mh_free0(&cmd);
naddrs += n;
cmd = add("ali -list", NULL);
}
pclose(in);
}
- free(cmd);
+ mh_free0(&cmd);
naddrs += n;
return naddrs ? 0 : 1;
static int
process(char *file)
{
- int state, compnum;
- char *cp = NULL;
- char buf[BUFSIZ], name[NAMESZ];
+ enum state state;
+ struct field f = {{0}};
+ int compnum;
FILE *in;
adios(EX_IOERR, file, "unable to open");
}
- for (compnum = 1, state = FLD;;) {
- switch (state = m_getfld(state, name, buf, sizeof(buf), in)) {
- case FLD:
- compnum++;
- proc_hdr(name, buf);
+ for (compnum=1, state=FLD2;; compnum++) {
+ switch (state = m_getfld2(state, &f, in)) {
+ case FLD2:
+ proc_hdr(f.name, f.value);
continue;
- case FLDPLUS:
- compnum++;
- cp = mh_xstrdup(buf);
- while (state == FLDPLUS) {
- state = m_getfld(state, name, buf,
- sizeof(buf), in);
- cp = add(buf, cp);
- }
- proc_hdr(name, cp);
- mh_free0(&cp);
- continue;
-
- case BODY:
- case FILEEOF:
+ case BODY2:
+ case FILEEOF2:
break;
- case LENERR:
- case FMTERR:
+ case LENERR2:
+ case FMTERR2:
+ case IOERR2:
adios(EX_DATAERR, NULL, "message format error in component #%d",
compnum);