X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=uip%2Fmhparse.c;h=01170a1415018e77c029a9df0d11fdf9ff94d721;hp=95f89121045ecc589ae77049ce906db7456f2bf6;hb=d1fefd9f614e4dc3cda16da6c69133c1b2005269;hpb=5b792c4424571f05bc2008e3109797d18d7d00d1 diff --git a/uip/mhparse.c b/uip/mhparse.c index 95f8912..01170a1 100644 --- a/uip/mhparse.c +++ b/uip/mhparse.c @@ -9,33 +9,20 @@ #include #include #include -#include #include #include #include -#include #include #include #include #include -#ifdef HAVE_SYS_WAIT_H -# include -#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. @@ -89,12 +76,6 @@ struct k2v SubApplication[] = { }; -/* 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); @@ -131,7 +112,6 @@ static int InitFTP(CT); 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 }, @@ -199,7 +179,7 @@ parse_mime(char *file) /* ** 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"); @@ -454,45 +434,6 @@ get_content(FILE *in, char *file, int toplevel) 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); @@ -1197,7 +1138,7 @@ InitMultiPart(CT ct) 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))) @@ -1704,8 +1645,8 @@ InitBase64(CT ct) 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; @@ -1713,7 +1654,6 @@ openBase64(CT ct, char **file) /* sbeck -- handle suffixes */ CI ci; CE ce; - MD5_CTX mdContext; b = (unsigned char *) &bits; b1 = &b[endian > 0 ? 1 : 2]; @@ -1781,14 +1721,15 @@ openBase64(CT ct, char **file) 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; @@ -1826,16 +1767,10 @@ openBase64(CT ct, char **file) 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); } } @@ -1874,25 +1809,22 @@ self_delimiting: 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; } @@ -1931,14 +1863,13 @@ InitQuoted(CT ct) 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) { @@ -1996,27 +1927,19 @@ openQuoted(CT ct, char **file) 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) { @@ -2047,8 +1970,6 @@ openQuoted(CT ct, char **file) 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; @@ -2101,13 +2022,6 @@ openQuoted(CT ct, char **file) /* 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"); @@ -2127,25 +2041,22 @@ openQuoted(CT ct, char **file) 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; } @@ -2168,7 +2079,7 @@ Init7Bit(CT ct) 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; @@ -2285,9 +2196,13 @@ open7Bit(CT ct, char **file) 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); @@ -2325,10 +2240,18 @@ open7Bit(CT ct, char **file) 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; } @@ -2340,8 +2263,6 @@ clean_up: 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; @@ -2356,17 +2277,6 @@ openExternal(CT ct, CT cb, CE ce, char **file, int *fd) 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: @@ -2389,8 +2299,7 @@ InitFile(CT ct) 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; @@ -2416,39 +2325,6 @@ openFile(CT ct, char **file) 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); @@ -2468,14 +2344,16 @@ InitFTP(CT ct) 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; @@ -2483,10 +2361,8 @@ openFTP(CT ct, char **file) 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: @@ -2561,23 +2437,9 @@ openFTP(CT ct, char **file) } 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)); @@ -2587,92 +2449,41 @@ openFTP(CT ct, char **file) 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 */ + 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; - case OK: - close(fileno(ce->ce_fp)); - execvp(ftp, vec); - fprintf(stderr, "unable to exec "); - perror(ftp); - _exit(-1); - /* NOTREACHED */ + fflush(stdout); - 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); + 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); @@ -2695,7 +2506,7 @@ InitMail(CT ct) 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; @@ -2747,7 +2558,7 @@ openMail(CT ct, char **file) 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"; @@ -2755,17 +2566,15 @@ openMail(CT ct, char **file) vec[vecp++] = e->eb_body; vec[vecp] = NULL; - for (i = 0; (child_id = vfork()) == NOTOK && i < 5; i++) - sleep(5); - switch (child_id) { + switch (child_id = fork()) { case NOTOK: advise("fork", "unable to"); return NOTOK; case OK: - execvp(mailproc, vec); + execvp(*vec, vec); fprintf(stderr, "unable to exec "); - perror(mailproc); + perror(*vec); _exit(-1); /* NOTREACHED */ @@ -2801,85 +2610,3 @@ openMail(CT ct, char **file) *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; -}