#include <h/mh.h>
#include <fcntl.h>
#include <h/signals.h>
-#include <h/md5.h>
#include <errno.h>
#include <setjmp.h>
#include <signal.h>
-#include <h/mts.h>
#include <h/tws.h>
#include <h/mime.h>
#include <h/mhparse.h>
#include <h/utils.h>
-#ifdef HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-
-
extern int debugsw;
extern int endian; /* mhmisc.c */
extern pid_t xpid; /* mhshowsbr.c */
-/* cache policies */
-extern int rcachesw; /* mhcachesbr.c */
-extern int wcachesw; /* mhcachesbr.c */
-
-int checksw = 0; /* check Content-MD5 field */
-
/*
** Directory to place temp files. This must
** be set before these routines are called.
};
-/* ftpsbr.c */
-int ftp_get(char *, char *, char *, char *, char *, char *, int, int);
-
-/* mhcachesbr.c */
-int find_cache(CT, int, int *, char *, char *, int);
-
/* mhmisc.c */
int part_ok(CT, int);
int type_ok(CT, int);
static int openFTP(CT, char **);
static int InitMail(CT);
static int openMail(CT, char **);
-static int readDigest(CT, char *);
struct str2init str2cts[] = {
{ "application", CT_APPLICATION, InitApplication },
/*
** Check if file is actually standard input
*/
- if ((is_stdin = !(strcmp(file, "-")))) {
+ if ((is_stdin = (strcmp(file, "-")==0))) {
char *tfile = m_mktemp2(NULL, invo_name, NULL, &fp);
if (tfile == NULL) {
advise("mhparse", "unable to create temporary file");
if (s2i->si_init && (*s2i->si_init) (ct) == NOTOK)
goto out;
- } else if (!mh_strcasecmp(hp->name, MD5_FIELD)) {
- /* Get Content-MD5 field */
- unsigned char *cp, *dp;
- char *ep;
-
- if (!checksw)
- goto next_header;
-
- if (ct->c_digested) {
- advise(NULL, "message %s has multiple %s: fields", ct->c_file, MD5_FIELD);
- goto next_header;
- }
-
- ep = cp = getcpy(hp->value);
-
- while (isspace(*cp))
- cp++;
- for (dp = strchr(cp, '\n'); dp; dp = strchr(dp, '\n'))
- *dp++ = ' ';
- for (dp = cp + strlen(cp) - 1; dp >= cp; dp--)
- if (!isspace(*dp))
- break;
- *++dp = '\0';
- if (debugsw)
- fprintf(stderr, "%s: %s\n", MD5_FIELD, cp);
-
- if (*cp == '(' && get_comment(ct, &cp, 0) == NOTOK) {
- free(ep);
- goto out;
- }
-
- for (dp = cp; *dp && !isspace(*dp); dp++)
- continue;
- *dp = '\0';
-
- readDigest(ct, cp);
- free(ep);
- ct->c_digested++;
-
} else if (!mh_strcasecmp(hp->name, ID_FIELD)) {
/* Get Content-ID field */
ct->c_id = add(hp->value, ct->c_id);
if (*dp == '"') {
for (cp = ++dp, dp = vp;;) {
switch (c = *cp++) {
- case '\0':
+ case '\0':
bad_quote:
- advise(NULL, "invalid quoted-string in message %s's %s: field\n%*.*s(parameter %s)", ct->c_file, TYPE_FIELD, i, i, "", *ap);
- return NOTOK;
+ advise(NULL, "invalid quoted-string in message %s's %s: field\n%*.*s(parameter %s)", ct->c_file, TYPE_FIELD, i, i, "", *ap);
+ return NOTOK;
- case '\\':
- *dp++ = c;
- if ((c = *cp++) == '\0')
- goto bad_quote;
- /* else fall... */
+ case '\\':
+ *dp++ = c;
+ if ((c = *cp++) == '\0')
+ goto bad_quote;
+ /* else fall... */
- default:
- *dp++ = c;
- continue;
+ default:
+ *dp++ = c;
+ continue;
- case '"':
- *dp = '\0';
- break;
+ case '"':
+ *dp = '\0';
+ break;
}
break;
}
if (buffer[0] != '-' || buffer[1] != '-')
continue;
if (inout) {
- if (strcmp(buffer + 2, m->mp_start))
+ if (strcmp(buffer + 2, m->mp_start)!=0)
continue;
next_part:
if ((part = (struct part *) calloc(1, sizeof(*part)))
ct->c_subtype = kv->kv_value;
switch (ct->c_subtype) {
- case MESSAGE_RFC822:
- break;
+ case MESSAGE_RFC822:
+ break;
- case MESSAGE_PARTIAL:
- {
- char **ap, **ep;
- struct partial *p;
+ case MESSAGE_PARTIAL:
+ {
+ char **ap, **ep;
+ struct partial *p;
- if ((p = (struct partial *)
- calloc(1, sizeof(*p))) == NULL)
- adios(NULL, "out of memory");
- ct->c_ctparams = (void *) p;
+ if ((p = (struct partial *) calloc(1, sizeof(*p))) == NULL)
+ adios(NULL, "out of memory");
+ ct->c_ctparams = (void *) p;
- /*
- ** scan for parameters "id", "number",
- ** and "total"
- */
- for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
- if (!mh_strcasecmp(*ap, "id")) {
- p->pm_partid = getcpy(*ep);
- continue;
- }
- if (!mh_strcasecmp(*ap, "number")) {
- if (sscanf(*ep, "%d", &p->pm_partno) != 1 || p->pm_partno < 1) {
+ /*
+ ** scan for parameters "id", "number",
+ ** and "total"
+ */
+ for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
+ if (!mh_strcasecmp(*ap, "id")) {
+ p->pm_partid = getcpy(*ep);
+ continue;
+ }
+ if (!mh_strcasecmp(*ap, "number")) {
+ if (sscanf(*ep, "%d", &p->pm_partno) != 1 || p->pm_partno < 1) {
invalid_param:
- advise(NULL, "invalid %s parameter for \"%s/%s\" type in message %s's %s field", *ap, ci->ci_type, ci->ci_subtype, ct->c_file, TYPE_FIELD);
- return NOTOK;
- }
- continue;
- }
- if (!mh_strcasecmp(*ap, "total")) {
- if (sscanf(*ep, "%d", &p->pm_maxno) != 1 || p->pm_maxno < 1)
- goto invalid_param;
- continue;
- }
- }
-
- if (!p->pm_partid || !p->pm_partno
- || (p->pm_maxno && p->pm_partno > p->pm_maxno)) {
- advise(NULL, "invalid parameters for \"%s/%s\" type in message %s's %s field", ci->ci_type, ci->ci_subtype, ct->c_file, TYPE_FIELD);
+ advise(NULL, "invalid %s parameter for \"%s/%s\" type in message %s's %s field", *ap, ci->ci_type, ci->ci_subtype, ct->c_file, TYPE_FIELD);
return NOTOK;
}
+ continue;
}
- break;
+ if (!mh_strcasecmp(*ap, "total")) {
+ if (sscanf(*ep, "%d", &p->pm_maxno) != 1 ||
+ p->pm_maxno < 1)
+ goto invalid_param;
+ continue;
+ }
+ }
- case MESSAGE_EXTERNAL:
- {
- int exresult;
- struct exbody *e;
- CT p;
- FILE *fp;
+ if (!p->pm_partid || !p->pm_partno
+ || (p->pm_maxno && p->pm_partno > p->pm_maxno)) {
+ advise(NULL, "invalid parameters for \"%s/%s\" type in message %s's %s field", ci->ci_type, ci->ci_subtype, ct->c_file, TYPE_FIELD);
+ return NOTOK;
+ }
+ }
+ break;
- if ((e = (struct exbody *)
- calloc(1, sizeof(*e))) == NULL)
- adios(NULL, "out of memory");
- ct->c_ctparams = (void *) e;
+ case MESSAGE_EXTERNAL:
+ {
+ int exresult;
+ struct exbody *e;
+ CT p;
+ FILE *fp;
- if (!ct->c_fp && (ct->c_fp = fopen(ct->c_file, "r")) == NULL) {
- advise(ct->c_file, "unable to open for reading");
- return NOTOK;
- }
+ if ((e = (struct exbody *) calloc(1, sizeof(*e))) == NULL)
+ adios(NULL, "out of memory");
+ ct->c_ctparams = (void *) e;
- fseek(fp = ct->c_fp, ct->c_begin, SEEK_SET);
+ if (!ct->c_fp && (ct->c_fp = fopen(ct->c_file, "r")) == NULL) {
+ advise(ct->c_file, "unable to open for reading");
+ return NOTOK;
+ }
- if (!(p = get_content(fp, ct->c_file, 0))) {
- ct->c_fp = NULL;
- return NOTOK;
- }
+ fseek(fp = ct->c_fp, ct->c_begin, SEEK_SET);
- e->eb_parent = ct;
- e->eb_content = p;
- p->c_ctexbody = e;
- if ((exresult = params_external(ct, 0))
- != NOTOK &&
- p->c_ceopenfnx == openMail) {
- int cc, size;
- char *bp;
-
- if ((size = ct->c_end - p->c_begin) <= 0) {
- if (!e->eb_subject)
- content_error(NULL, ct, "empty body for access-type=mail-server");
- goto no_body;
- }
-
- e->eb_body = bp = mh_xmalloc((unsigned) size);
- fseek(p->c_fp, p->c_begin, SEEK_SET);
- while (size > 0)
- switch (cc = fread(bp, sizeof(*bp), size, p->c_fp)) {
- case NOTOK:
- adios("failed", "fread");
+ if (!(p = get_content(fp, ct->c_file, 0))) {
+ ct->c_fp = NULL;
+ return NOTOK;
+ }
- case OK:
- adios(NULL, "unexpected EOF from fread");
+ e->eb_parent = ct;
+ e->eb_content = p;
+ p->c_ctexbody = e;
+ if ((exresult = params_external(ct, 0)) != NOTOK &&
+ p->c_ceopenfnx == openMail) {
+ int cc, size;
+ char *bp;
+
+ if ((size = ct->c_end - p->c_begin) <= 0) {
+ if (!e->eb_subject)
+ content_error(NULL, ct, "empty body for access-type=mail-server");
+ goto no_body;
+ }
- default:
- bp += cc, size -= cc;
- break;
- }
- *bp = 0;
+ e->eb_body = bp = mh_xmalloc((unsigned) size);
+ fseek(p->c_fp, p->c_begin, SEEK_SET);
+ while (size > 0)
+ switch (cc = fread(bp, sizeof(*bp), size, p->c_fp)) {
+ case NOTOK:
+ adios("failed", "fread");
+ case OK:
+ adios(NULL, "unexpected EOF from fread");
+ default:
+ bp += cc, size -= cc;
+ break;
}
+ *bp = 0;
+ }
no_body:
- p->c_fp = NULL;
- p->c_end = p->c_begin;
+ p->c_fp = NULL;
+ p->c_end = p->c_begin;
- fclose(ct->c_fp);
- ct->c_fp = NULL;
+ fclose(ct->c_fp);
+ ct->c_fp = NULL;
- if (exresult == NOTOK)
- return NOTOK;
- if (e->eb_flags == NOTOK)
- return OK;
-
- switch (p->c_type) {
- case CT_MULTIPART:
- break;
+ if (exresult == NOTOK)
+ return NOTOK;
+ if (e->eb_flags == NOTOK)
+ return OK;
- case CT_MESSAGE:
- if (p->c_subtype != MESSAGE_RFC822)
- break;
- /* else fall... */
- default:
- e->eb_partno = ct->c_partno;
- if (p->c_ctinitfnx)
- (*p->c_ctinitfnx) (p);
- break;
- }
- }
+ switch (p->c_type) {
+ case CT_MULTIPART:
break;
+ case CT_MESSAGE:
+ if (p->c_subtype != MESSAGE_RFC822)
+ break;
+ /* else fall... */
default:
+ e->eb_partno = ct->c_partno;
+ if (p->c_ctinitfnx)
+ (*p->c_ctinitfnx) (p);
break;
+ }
+ }
+ break;
+
+ default:
+ break;
}
return OK;
static int
openBase64(CT ct, char **file)
{
- int bitno, cc, digested;
- int fd, len, skip;
+ int bitno, cc;
+ int fd, len, skip, own_ct_fp = 0;
unsigned long bits;
unsigned char value, *b, *b1, *b2, *b3;
unsigned char *cp, *ep;
/* sbeck -- handle suffixes */
CI ci;
CE ce;
- MD5_CTX mdContext;
b = (unsigned char *) &bits;
b1 = &b[endian > 0 ? 1 : 2];
if ((len = ct->c_end - ct->c_begin) < 0)
adios(NULL, "internal error(1)");
- if (!ct->c_fp && (ct->c_fp = fopen(ct->c_file, "r")) == NULL) {
- content_error(ct->c_file, ct, "unable to open for reading");
- return NOTOK;
+ if (!ct->c_fp) {
+ if ((ct->c_fp = fopen(ct->c_file, "r")) == NULL) {
+ content_error(ct->c_file, ct,
+ "unable to open for reading");
+ return NOTOK;
+ }
+ own_ct_fp = 1;
}
- if ((digested = ct->c_digested))
- MD5Init(&mdContext);
-
bitno = 18;
bits = 0L;
skip = 0;
test_end:
if ((bitno -= 6) < 0) {
putc((char) *b1, ce->ce_fp);
- if (digested)
- MD5Update(&mdContext, b1, 1);
if (skip < 2) {
putc((char) *b2, ce->ce_fp);
- if (digested)
- MD5Update(&mdContext, b2, 1);
if (skip < 1) {
putc((char) *b3, ce->ce_fp);
- if (digested)
- MD5Update(&mdContext, b3, 1);
}
}
goto clean_up;
}
- if (digested) {
- unsigned char digest[16];
-
- MD5Final(digest, &mdContext);
- if (memcmp((char *) digest, (char *) ct->c_digest,
- sizeof(digest) / sizeof(digest[0])))
- content_error(NULL, ct, "content integrity suspect (digest mismatch) -- continuing");
- else if (debugsw)
- fprintf(stderr, "content integrity confirmed\n");
- }
-
fseek(ce->ce_fp, 0L, SEEK_SET);
ready_to_go:
*file = ce->ce_file;
+ if (own_ct_fp) {
+ fclose(ct->c_fp);
+ ct->c_fp = NULL;
+ }
return fileno(ce->ce_fp);
clean_up:
free_encoding(ct, 0);
+ if (own_ct_fp) {
+ fclose(ct->c_fp);
+ ct->c_fp = NULL;
+ }
return NOTOK;
}
static int
openQuoted(CT ct, char **file)
{
- int cc, digested, len, quoted;
+ int cc, len, quoted, own_ct_fp = 0;
unsigned char *cp, *ep;
char buffer[BUFSIZ];
- unsigned char mask;
+ unsigned char mask = 0;
CE ce;
/* sbeck -- handle suffixes */
CI ci;
- MD5_CTX mdContext;
ce = ct->c_cefile;
if (ce->ce_fp) {
return NOTOK;
}
- if ((ce->ce_fp = fopen(ce->ce_file, "w+")) == NULL) {
- content_error(ce->ce_file, ct,
- "unable to fopen for reading/writing");
- return NOTOK;
- }
-
if ((len = ct->c_end - ct->c_begin) < 0)
adios(NULL, "internal error(2)");
- if (!ct->c_fp && (ct->c_fp = fopen(ct->c_file, "r")) == NULL) {
- content_error(ct->c_file, ct, "unable to open for reading");
- return NOTOK;
+ if (!ct->c_fp) {
+ if ((ct->c_fp = fopen(ct->c_file, "r")) == NULL) {
+ content_error(ct->c_file, ct,
+ "unable to open for reading");
+ return NOTOK;
+ }
+ own_ct_fp = 1;
}
- if ((digested = ct->c_digested))
- MD5Init(&mdContext);
-
quoted = 0;
-#ifdef lint
- mask = 0;
-#endif
fseek(ct->c_fp, ct->c_begin, SEEK_SET);
while (len > 0) {
mask <<= 4;
mask |= hex2nib[*cp & 0x7f];
putc(mask, ce->ce_fp);
- if (digested)
- MD5Update(&mdContext, &mask, 1);
if (ferror(ce->ce_fp)) {
content_error(ce->ce_file, ct, "error writing to");
goto clean_up;
/* Just show the raw byte. */
putc(*cp, ce->ce_fp);
- if (digested) {
- if (*cp == '\n') {
- MD5Update(&mdContext, (unsigned char *) "\r\n",2);
- } else {
- MD5Update(&mdContext, (unsigned char *) cp, 1);
- }
- }
if (ferror(ce->ce_fp)) {
content_error(ce->ce_file, ct,
"error writing to");
goto clean_up;
}
- if (digested) {
- unsigned char digest[16];
-
- MD5Final(digest, &mdContext);
- if (memcmp((char *) digest, (char *) ct->c_digest,
- sizeof(digest) / sizeof(digest[0])))
- content_error(NULL, ct, "content integrity suspect (digest mismatch) -- continuing");
- else if (debugsw)
- fprintf(stderr, "content integrity confirmed\n");
- }
-
fseek(ce->ce_fp, 0L, SEEK_SET);
ready_to_go:
*file = ce->ce_file;
+ if (own_ct_fp) {
+ fclose(ct->c_fp);
+ ct->c_fp = NULL;
+ }
return fileno(ce->ce_fp);
clean_up:
free_encoding(ct, 0);
+ if (own_ct_fp) {
+ fclose(ct->c_fp);
+ ct->c_fp = NULL;
+ }
return NOTOK;
}
int
open7Bit(CT ct, char **file)
{
- int cc, fd, len;
+ int cc, fd, len, own_ct_fp = 0;
char buffer[BUFSIZ];
/* sbeck -- handle suffixes */
char *cp;
if ((len = ct->c_end - ct->c_begin) < 0)
adios(NULL, "internal error(3)");
- if (!ct->c_fp && (ct->c_fp = fopen(ct->c_file, "r")) == NULL) {
- content_error(ct->c_file, ct, "unable to open for reading");
- return NOTOK;
+ if (!ct->c_fp) {
+ if ((ct->c_fp = fopen(ct->c_file, "r")) == NULL) {
+ content_error(ct->c_file, ct,
+ "unable to open for reading");
+ return NOTOK;
+ }
+ own_ct_fp = 1;
}
lseek(fd = fileno(ct->c_fp), (off_t) ct->c_begin, SEEK_SET);
ready_to_go:
*file = ce->ce_file;
+ if (own_ct_fp) {
+ fclose(ct->c_fp);
+ ct->c_fp = NULL;
+ }
return fileno(ce->ce_fp);
clean_up:
free_encoding(ct, 0);
+ if (own_ct_fp) {
+ fclose(ct->c_fp);
+ ct->c_fp = NULL;
+ }
return NOTOK;
}
static int
openExternal(CT ct, CT cb, CE ce, char **file, int *fd)
{
- char cachefile[BUFSIZ];
-
if (ce->ce_fp) {
fseek(ce->ce_fp, 0L, SEEK_SET);
goto ready_already;
goto ready_already;
}
- if (find_cache(ct, rcachesw, (int *) 0, cb->c_id,
- cachefile, sizeof(cachefile)) != NOTOK) {
- if ((ce->ce_fp = fopen(cachefile, "r"))) {
- ce->ce_file = getcpy(cachefile);
- ce->ce_unlink = 0;
- goto ready_already;
- } else {
- admonish(cachefile, "unable to fopen for reading");
- }
- }
-
return OK;
ready_already:
static int
openFile(CT ct, char **file)
{
- int fd, cachetype;
- char cachefile[BUFSIZ];
+ int fd;
struct exbody *e = ct->c_ctexbody;
CE ce = ct->c_cefile;
switch (openExternal(e->eb_parent, e->eb_content, ce, file, &fd)) {
- case NOTOK:
- return NOTOK;
-
- case OK:
- break;
-
- case DONE:
- return fd;
+ case NOTOK:
+ return NOTOK;
+ case OK:
+ break;
+ case DONE:
+ return fd;
}
if (!e->eb_name) {
return NOTOK;
}
- if ((!e->eb_permission ||
- mh_strcasecmp(e->eb_permission, "read-write")) &&
- find_cache(NULL, wcachesw, &cachetype,
- e->eb_content->c_id, cachefile, sizeof(cachefile))
- != NOTOK) {
- int mask;
- FILE *fp;
-
- mask = umask(cachetype ? ~m_gmprot() : 0222);
- if ((fp = fopen(cachefile, "w"))) {
- int cc;
- char buffer[BUFSIZ];
- FILE *gp = ce->ce_fp;
-
- fseek(gp, 0L, SEEK_SET);
-
- while ((cc = fread(buffer, sizeof(*buffer),
- sizeof(buffer), gp)) > 0)
- fwrite(buffer, sizeof(*buffer), cc, fp);
- fflush(fp);
-
- if (ferror(gp)) {
- admonish(ce->ce_file, "error reading");
- unlink(cachefile);
- } else if (ferror(fp)) {
- admonish(cachefile, "error writing");
- unlink(cachefile);
- }
- fclose(fp);
- }
- umask(mask);
- }
-
fseek(ce->ce_fp, 0L, SEEK_SET);
*file = ce->ce_file;
return fileno(ce->ce_fp);
static int
openFTP(CT ct, char **file)
{
- int cachetype, caching, fd;
+ int fd;
int len, buflen;
char *bp, *ftp, *user, *pass;
- char buffer[BUFSIZ], cachefile[BUFSIZ];
+ char buffer[BUFSIZ];
struct exbody *e;
CE ce;
static char *username = NULL;
static char *password = NULL;
+ int child_id, vecp;
+ char *vec[9];
e = ct->c_ctexbody;
ce = ct->c_cefile;
if ((ftp = context_find(nmhaccessftp)) && !*ftp)
ftp = NULL;
-#ifndef BUILTIN_FTP
if (!ftp)
return NOTOK;
-#endif
switch (openExternal(e->eb_parent, e->eb_content, ce, file, &fd)) {
- case NOTOK:
- return NOTOK;
-
- case OK:
- break;
-
- case DONE:
- return fd;
+ case NOTOK:
+ return NOTOK;
+ case OK:
+ break;
+ case DONE:
+ return fd;
}
if (!e->eb_name || !e->eb_site) {
}
ce->ce_unlink = (*file == NULL);
- caching = 0;
- cachefile[0] = '\0';
- if ((!e->eb_permission ||
- mh_strcasecmp(e->eb_permission, "read-write")) &&
- find_cache(NULL, wcachesw, &cachetype,
- e->eb_content->c_id, cachefile, sizeof(cachefile))
- != NOTOK) {
- if (*file == NULL) {
- ce->ce_unlink = 0;
- caching = 1;
- }
- }
if (*file)
ce->ce_file = getcpy(*file);
- else if (caching)
- ce->ce_file = getcpy(cachefile);
else
ce->ce_file = getcpy(m_mktemp(tmp, NULL, NULL));
return NOTOK;
}
-#ifdef BUILTIN_FTP
- if (ftp)
-#endif
- {
- int child_id, i, vecp;
- char *vec[9];
-
- vecp = 0;
- vec[vecp++] = mhbasename(ftp);
- vec[vecp++] = e->eb_site;
- vec[vecp++] = user;
- vec[vecp++] = pass;
- vec[vecp++] = e->eb_dir;
- vec[vecp++] = e->eb_name;
- vec[vecp++] = ce->ce_file,
- vec[vecp++] = e->eb_mode &&
- !mh_strcasecmp(e->eb_mode, "ascii") ?
- "ascii" : "binary";
- vec[vecp] = NULL;
-
- fflush(stdout);
-
- for (i = 0; (child_id = vfork()) == NOTOK && i < 5; i++)
- sleep(5);
- switch (child_id) {
- case NOTOK:
- adios("fork", "unable to");
- /* NOTREACHED */
-
- case OK:
- close(fileno(ce->ce_fp));
- execvp(ftp, vec);
- fprintf(stderr, "unable to exec ");
- perror(ftp);
- _exit(-1);
- /* NOTREACHED */
-
- default:
- if (pidXwait(child_id, NULL)) {
-#ifdef BUILTIN_FTP
-losing_ftp:
-#endif
- username = password = NULL;
- ce->ce_unlink = 1;
- return NOTOK;
- }
- break;
- }
- }
-#ifdef BUILTIN_FTP
- else if (ftp_get(e->eb_site, user, pass, e->eb_dir, e->eb_name,
- ce->ce_file, e->eb_mode && !mh_strcasecmp(e->eb_mode,
- "ascii"), 0) == NOTOK)
- goto losing_ftp;
-#endif
-
- if (cachefile[0]) {
- if (caching)
- chmod(cachefile, cachetype ? m_gmprot() : 0444);
- else {
- int mask;
- FILE *fp;
-
- mask = umask(cachetype ? ~m_gmprot() : 0222);
- if ((fp = fopen(cachefile, "w"))) {
- int cc;
- FILE *gp = ce->ce_fp;
-
- fseek(gp, 0L, SEEK_SET);
-
- while ((cc= fread(buffer, sizeof(*buffer),
- sizeof(buffer), gp)) > 0)
- fwrite(buffer, sizeof(*buffer), cc, fp);
- fflush(fp);
-
- if (ferror(gp)) {
- admonish(ce->ce_file, "error reading");
- unlink(cachefile);
- } else if (ferror(fp)) {
- admonish(cachefile, "error writing");
- unlink(cachefile);
- }
- fclose(fp);
- }
- umask(mask);
+ vecp = 0;
+ vec[vecp++] = mhbasename(ftp);
+ vec[vecp++] = e->eb_site;
+ vec[vecp++] = user;
+ vec[vecp++] = pass;
+ vec[vecp++] = e->eb_dir;
+ vec[vecp++] = e->eb_name;
+ vec[vecp++] = ce->ce_file,
+ vec[vecp++] = e->eb_mode &&
+ !mh_strcasecmp(e->eb_mode, "ascii") ?
+ "ascii" : "binary";
+ vec[vecp] = NULL;
+
+ fflush(stdout);
+
+ switch (child_id = fork()) {
+ case NOTOK:
+ adios("fork", "unable to");
+ /* NOTREACHED */
+
+ case OK:
+ close(fileno(ce->ce_fp));
+ execvp(ftp, vec);
+ fprintf(stderr, "unable to exec ");
+ perror(ftp);
+ _exit(-1);
+ /* NOTREACHED */
+
+ default:
+ if (pidXwait(child_id, NULL)) {
+ username = password = NULL;
+ ce->ce_unlink = 1;
+ return NOTOK;
}
+ break;
}
fseek(ce->ce_fp, 0L, SEEK_SET);
static int
openMail(CT ct, char **file)
{
- int child_id, fd, i, vecp;
+ int child_id, fd, vecp;
int len, buflen;
char *bp, buffer[BUFSIZ], *vec[7];
struct exbody *e = ct->c_ctexbody;
CE ce = ct->c_cefile;
switch (openExternal(e->eb_parent, e->eb_content, ce, file, &fd)) {
- case NOTOK:
- return NOTOK;
-
- case OK:
- break;
-
- case DONE:
- return fd;
+ case NOTOK:
+ return NOTOK;
+ case OK:
+ break;
+ case DONE:
+ return fd;
}
if (!e->eb_server) {
return NOTOK;
vecp = 0;
- vec[vecp++] = mhbasename(mailproc);
+ vec[vecp++] = "mhmail";
vec[vecp++] = e->eb_server;
vec[vecp++] = "-subject";
vec[vecp++] = e->eb_subject ? e->eb_subject : "mail-server request";
vec[vecp++] = e->eb_body;
vec[vecp] = NULL;
- for (i = 0; (child_id = vfork()) == NOTOK && i < 5; i++)
- sleep(5);
- switch (child_id) {
- case NOTOK:
- advise("fork", "unable to");
- return NOTOK;
+ switch (child_id = fork()) {
+ case NOTOK:
+ advise("fork", "unable to");
+ return NOTOK;
- case OK:
- execvp(mailproc, vec);
- fprintf(stderr, "unable to exec ");
- perror(mailproc);
- _exit(-1);
- /* NOTREACHED */
+ case OK:
+ execvp(*vec, vec);
+ fprintf(stderr, "unable to exec ");
+ perror(*vec);
+ _exit(-1);
+ /* NOTREACHED */
- default:
- if (pidXwait(child_id, NULL) == OK)
- advise(NULL, "request sent");
- break;
+ default:
+ if (pidXwait(child_id, NULL) == OK)
+ advise(NULL, "request sent");
+ break;
}
if (*file == NULL) {
*file = ce->ce_file;
return fileno(ce->ce_fp);
}
-
-
-static int
-readDigest(CT ct, char *cp)
-{
- int bitno, skip;
- unsigned long bits;
- char *bp = cp;
- unsigned char *dp, value, *ep;
- unsigned char *b, *b1, *b2, *b3;
-
- b = (unsigned char *) &bits,
- b1 = &b[endian > 0 ? 1 : 2],
- b2 = &b[endian > 0 ? 2 : 1],
- b3 = &b[endian > 0 ? 3 : 0];
- bitno = 18;
- bits = 0L;
- skip = 0;
-
- for (ep = (dp = ct->c_digest)
- + sizeof(ct->c_digest) / sizeof(ct->c_digest[0]); *cp; cp++)
- switch (*cp) {
- default:
- if (skip || (*cp & 0x80) ||
- (value = b642nib[*cp & 0x7f])
- > 0x3f) {
- if (debugsw)
- fprintf(stderr, "invalid BASE64 encoding\n");
- return NOTOK;
- }
-
- bits |= value << bitno;
-test_end:
- if ((bitno -= 6) < 0) {
- if (dp + (3 - skip) > ep)
- goto invalid_digest;
- *dp++ = *b1;
- if (skip < 2) {
- *dp++ = *b2;
- if (skip < 1)
- *dp++ = *b3;
- }
- bitno = 18;
- bits = 0L;
- skip = 0;
- }
- break;
-
- case '=':
- if (++skip > 3)
- goto self_delimiting;
- goto test_end;
- }
- if (bitno != 18) {
- if (debugsw)
- fprintf(stderr, "premature ending (bitno %d)\n",
- bitno);
-
- return NOTOK;
- }
-self_delimiting:
- if (dp != ep) {
-invalid_digest:
- if (debugsw) {
- while (*cp)
- cp++;
- fprintf(stderr, "invalid MD5 digest (got %d octets)\n",
- (int)(cp - bp));
- }
-
- return NOTOK;
- }
-
- if (debugsw) {
- fprintf(stderr, "MD5 digest=");
- for (dp = ct->c_digest; dp < ep; dp++)
- fprintf(stderr, "%02x", *dp & 0xff);
- fprintf(stderr, "\n");
- }
-
- return OK;
-}