X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/88b27ae07f694e90637c2a852b754539c2f70172..167e542b:/uip/mhbuildsbr.c diff --git a/uip/mhbuildsbr.c b/uip/mhbuildsbr.c index 2a3f8996..e4499170 100644 --- a/uip/mhbuildsbr.c +++ b/uip/mhbuildsbr.c @@ -19,8 +19,6 @@ #include #include #include -#include -#include #include #include #include @@ -36,13 +34,10 @@ extern int debugsw; extern int verbosw; -extern int ebcdicsw; extern int listsw; extern int rfc934sw; extern int contentidsw; -extern int endian; /* mhmisc.c */ - /* cache policies */ extern int rcachesw; /* mhcachesbr.c */ extern int wcachesw; /* mhcachesbr.c */ @@ -57,24 +52,23 @@ pid_t xpid = 0; static char prefix[] = "----- =_aaaaaaaaaa"; +/* + * Maximum size of URL token in message/external-body + */ + +#define MAXURLTOKEN 40 + /* mhmisc.c */ -int make_intermediates (char *); void content_error (char *, CT, char *, ...); /* mhcachesbr.c */ int find_cache (CT, int, int *, char *, char *, int); /* mhfree.c */ -void free_content (CT); void free_ctinfo (CT); void free_encoding (CT, int); -/* - * prototypes - */ -CT build_mime (char *); - /* * static prototypes */ @@ -88,6 +82,37 @@ static int build_headers (CT); static char *calculate_digest (CT, int); +static unsigned char directives_stack[32]; +static unsigned int directives_index; + +static int do_direct(void) +{ + return directives_stack[directives_index]; +} + +static void directive_onoff(int onoff) +{ + if (directives_index >= sizeof(directives_stack) - 1) { + fprintf(stderr, "mhbuild: #on/off overflow, continuing\n"); + return; + } + directives_stack[++directives_index] = onoff; +} + +static void directive_init(int onoff) +{ + directives_index = 0; + directives_stack[0] = onoff; +} + +static void directive_pop(void) +{ + if (directives_index > 0) + directives_index--; + else + fprintf(stderr, "mhbuild: #pop underflow, continuing\n"); +} + /* * Main routine for translating composition file * into valid MIME message. It translates the draft @@ -98,7 +123,7 @@ static char *calculate_digest (CT, int); */ CT -build_mime (char *infile) +build_mime (char *infile, int directives, int header_encoding) { int compnum, state; char buf[BUFSIZ], name[NAMESZ]; @@ -107,6 +132,10 @@ build_mime (char *infile) struct part **pp; CT ct; FILE *in; + HF hp; + m_getfld_state_t gstate = 0; + + directive_init(directives); umask (~m_gmprot ()); @@ -132,25 +161,28 @@ build_mime (char *infile) * 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)) { + m_getfld_track_filepos (&gstate, in); + for (compnum = 1;;) { + int bufsz = sizeof buf; + switch (state = m_getfld (&gstate, name, buf, &bufsz, in)) { case FLD: case FLDPLUS: - case FLDEOF: compnum++; /* abort if draft has Mime-Version header field */ - if (!mh_strcasecmp (name, VRSN_FIELD)) + if (!strcasecmp (name, VRSN_FIELD)) adios (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 (!strcasecmp (name, ENCODING_FIELD)) adios (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 (!strcasecmp (name, TYPE_FIELD)) { + while (state == FLDPLUS) { + bufsz = sizeof buf; + state = m_getfld (&gstate, name, buf, &bufsz, in); + } goto finish_field; } @@ -160,7 +192,8 @@ build_mime (char *infile) /* if necessary, get rest of field */ while (state == FLDPLUS) { - state = m_getfld (state, name, buf, sizeof(buf), in); + bufsz = sizeof buf; + state = m_getfld (&gstate, name, buf, &bufsz, in); vp = add (buf, vp); /* add to previous value */ } @@ -169,16 +202,13 @@ build_mime (char *infile) finish_field: /* if this wasn't the last header field, then continue */ - if (state != FLDEOF) - continue; - /* else fall... */ + continue; case FILEEOF: adios (NULL, "draft has empty body -- no directives!"); /* NOTREACHED */ case BODY: - case BODYEOF: fseek (in, (long) (-strlen (buf)), SEEK_CUR); break; @@ -191,6 +221,18 @@ finish_field: } break; } + m_getfld_state_destroy (&gstate); + + /* + * Iterate through the list of headers and call the function to MIME-ify + * them if required. + */ + + for (hp = ct->c_first_hf; hp != NULL; hp = hp->next) { + if (encode_rfc2047(hp->name, &hp->value, header_encoding, NULL)) { + adios(NULL, "Unable to encode header \"%s\"", hp->name); + } + } /* * Now add the MIME-Version header field @@ -310,12 +352,6 @@ finish_field: static int init_decoded_content (CT ct) { - CE ce; - - if ((ce = (CE) calloc (1, sizeof(*ce))) == NULL) - adios (NULL, "out of memory"); - - ct->c_cefile = ce; ct->c_ceopenfnx = open7Bit; /* since unencoded */ ct->c_ceclosefnx = close_encoding; ct->c_cesizefnx = NULL; /* since unencoded */ @@ -328,20 +364,34 @@ static char * fgetstr (char *s, int n, FILE *stream) { char *cp, *ep; + int o_n = n; + + while(1) { + for (ep = (cp = s) + o_n; cp < ep; ) { + int i; - for (ep = (cp = s) + n; cp < ep; ) { - int i; + if (!fgets (cp, n, stream)) + return (cp != s ? s : NULL); - if (!fgets (cp, n, stream)) - return (cp != s ? s : NULL); - if (cp == s && *cp != '#') - return s; + if (cp == s && *cp != '#') + return s; + + cp += (i = strlen (cp)) - 1; + if (i <= 1 || *cp-- != '\n' || *cp != '\\') + break; + *cp = '\0'; + n -= (i - 2); + } - cp += (i = strlen (cp)) - 1; - if (i <= 1 || *cp-- != '\n' || *cp != '\\') + if (strcmp(s, "#on\n") == 0) { + directive_onoff(1); + } else if (strcmp(s, "#off\n") == 0) { + directive_onoff(0); + } else if (strcmp(s, "#pop\n") == 0) { + directive_pop(); + } else { break; - *cp = '\0'; - n -= (i - 2); + } } return s; @@ -357,8 +407,7 @@ static int user_content (FILE *in, char *file, char *buf, CT *ctp) { int extrnal, vrsn; - unsigned char *cp; - char **ap; + char *cp, **ap; char buffer[BUFSIZ]; struct multipart *m; struct part **pp; @@ -368,7 +417,7 @@ user_content (FILE *in, char *file, char *buf, CT *ctp) CT ct; CE ce; - if (buf[0] == '\n' || strcmp (buf, "#\n") == 0) { + if (buf[0] == '\n' || (do_direct() && strcmp (buf, "#\n") == 0)) { *ctp = NULL; return OK; } @@ -380,7 +429,7 @@ user_content (FILE *in, char *file, char *buf, CT *ctp) /* allocate basic structure for handling decoded content */ init_decoded_content (ct); - ce = ct->c_cefile; + ce = &ct->c_cefile; ci = &ct->c_ctinfo; set_id (ct, 0); @@ -393,7 +442,7 @@ user_content (FILE *in, char *file, char *buf, CT *ctp) * 2) begins with "##" (implicit directive) * 3) begins with "#<" */ - if (buf[0] != '#' || buf[1] == '#' || buf[1] == '<') { + if (!do_direct() || buf[0] != '#' || buf[1] == '#' || buf[1] == '<') { int headers; int inlineD; long pos; @@ -408,7 +457,7 @@ user_content (FILE *in, char *file, char *buf, CT *ctp) ce->ce_file = add (cp, NULL); ce->ce_unlink = 1; - if (buf[0] == '#' && buf[1] == '<') { + if (do_direct() && (buf[0] == '#' && buf[1] == '<')) { strncpy (content, buf + 2, sizeof(content)); inlineD = 1; goto rock_and_roll; @@ -419,11 +468,11 @@ user_content (FILE *in, char *file, char *buf, CT *ctp) /* the directive is implicit */ strncpy (content, "text/plain", sizeof(content)); headers = 0; - strncpy (buffer, buf[0] != '#' ? buf : buf + 1, sizeof(buffer)); + strncpy (buffer, (!do_direct() || buf[0] != '#') ? buf : buf + 1, sizeof(buffer)); for (;;) { int i; - if (headers >= 0 && uprf (buffer, DESCR_FIELD) + if (headers >= 0 && do_direct() && uprf (buffer, DESCR_FIELD) && buffer[i = strlen (DESCR_FIELD)] == ':') { headers = 1; @@ -446,7 +495,7 @@ again_descr: } } - if (headers >= 0 && uprf (buffer, DISPO_FIELD) + if (headers >= 0 && do_direct() && uprf (buffer, DISPO_FIELD) && buffer[i = strlen (DISPO_FIELD)] == ':') { headers = 1; @@ -477,7 +526,7 @@ rock_and_roll: pos = ftell (in); if ((cp = fgetstr (buffer, sizeof(buffer) - 1, in)) == NULL) break; - if (buffer[0] == '#') { + if (do_direct() && buffer[0] == '#') { char *bp; if (buffer[1] != '#') @@ -497,7 +546,7 @@ rock_and_roll: done (1); for (s2i = str2cts; s2i->si_key; s2i++) - if (!mh_strcasecmp (ci->ci_type, s2i->si_key)) + if (!strcasecmp (ci->ci_type, s2i->si_key)) break; if (!s2i->si_key && !uprf (ci->ci_type, "X-")) s2i++; @@ -507,7 +556,7 @@ rock_and_roll: */ switch (ct->c_type = s2i->si_val) { case CT_MESSAGE: - if (!mh_strcasecmp (ci->ci_subtype, "rfc822")) { + if (!strcasecmp (ci->ci_subtype, "rfc822")) { ct->c_encoding = CE_7BIT; goto call_init; } @@ -543,7 +592,7 @@ call_init: /* check directive against the list of MIME types */ for (s2i = str2cts; s2i->si_key; s2i++) - if (!mh_strcasecmp (ci->ci_type, s2i->si_key)) + if (!strcasecmp (ci->ci_type, s2i->si_key)) break; /* @@ -564,10 +613,10 @@ call_init: /* NOTREACHED */ case CT_MESSAGE: - if (!mh_strcasecmp (ci->ci_subtype, "partial")) + if (!strcasecmp (ci->ci_subtype, "partial")) adios (NULL, "sorry, \"#%s/%s\" isn't supported", ci->ci_type, ci->ci_subtype); - if (!mh_strcasecmp (ci->ci_subtype, "external-body")) + if (!strcasecmp (ci->ci_subtype, "external-body")) adios (NULL, "use \"#@type/subtype ... [] ...\" instead of \"#%s/%s\"", ci->ci_type, ci->ci_subtype); use_forw: @@ -631,7 +680,7 @@ use_forw: if (ci->ci_magic) { /* check if specifies command to execute */ if (*ci->ci_magic == '|' || *ci->ci_magic == '!') { - for (cp = ci->ci_magic + 1; isspace (*cp); cp++) + for (cp = ci->ci_magic + 1; isspace ((unsigned char) *cp); cp++) continue; if (!*cp) adios (NULL, "empty pipe command for #%s directive", ci->ci_type); @@ -674,7 +723,7 @@ use_forw: * Message directive * #forw [+folder] [msgs] */ - if (!mh_strcasecmp (ci->ci_type, "forw")) { + if (!strcasecmp (ci->ci_type, "forw")) { int msgnum; char *folder, *arguments[MAXARGS]; struct msgs *mp; @@ -703,7 +752,7 @@ use_forw: if (!folder) folder = add (getfolder (1), NULL); - if (!(mp = folder_read (folder))) + if (!(mp = folder_read (folder, 0))) adios (NULL, "unable to read folder %s", folder); for (ap = arguments; *ap; ap++) { cp = *ap; @@ -741,7 +790,7 @@ use_forw: if ((p = (CT) calloc (1, sizeof(*p))) == NULL) adios (NULL, "out of memory"); init_decoded_content (p); - pe = p->c_cefile; + pe = &p->c_cefile; if (get_ctinfo ("message/rfc822", p, 0) == NOTOK) done (1); p->c_type = CT_MESSAGE; @@ -780,7 +829,7 @@ use_forw: /* * #end */ - if (!mh_strcasecmp (ci->ci_type, "end")) { + if (!strcasecmp (ci->ci_type, "end")) { free_content (ct); *ctp = NULL; return DONE; @@ -789,14 +838,14 @@ use_forw: /* * #begin [ alternative | parallel ] */ - if (!mh_strcasecmp (ci->ci_type, "begin")) { + if (!strcasecmp (ci->ci_type, "begin")) { if (!ci->ci_magic) { vrsn = MULTI_MIXED; cp = SubMultiPart[vrsn - 1].kv_key; - } else if (!mh_strcasecmp (ci->ci_magic, "alternative")) { + } else if (!strcasecmp (ci->ci_magic, "alternative")) { vrsn = MULTI_ALTERNATE; cp = SubMultiPart[vrsn - 1].kv_key; - } else if (!mh_strcasecmp (ci->ci_magic, "parallel")) { + } else if (!strcasecmp (ci->ci_magic, "parallel")) { vrsn = MULTI_PARALLEL; cp = SubMultiPart[vrsn - 1].kv_key; } else if (uprf (ci->ci_magic, "digest")) { @@ -851,59 +900,22 @@ use_forw: static void set_id (CT ct, int top) { - char msgid[BUFSIZ]; + char contentid[BUFSIZ]; static int partno; static time_t clock = 0; static char *msgfmt; if (clock == 0) { time (&clock); - snprintf (msgid, sizeof(msgid), "<%d.%ld.%%d@%s>\n", - (int) getpid(), (long) clock, LocalName()); + snprintf (contentid, sizeof(contentid), "%s\n", message_id (clock, 1)); partno = 0; - msgfmt = getcpy(msgid); + msgfmt = getcpy(contentid); } - snprintf (msgid, sizeof(msgid), msgfmt, top ? 0 : ++partno); - ct->c_id = getcpy (msgid); + snprintf (contentid, sizeof(contentid), msgfmt, top ? 0 : ++partno); + ct->c_id = getcpy (contentid); } -static char ebcdicsafe[0x100] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - - /* * Fill out, or expand the various contents in the composition * draft. Read-in any necessary files. Parse and execute any @@ -913,7 +925,7 @@ static char ebcdicsafe[0x100] = { static int compose_content (CT ct) { - CE ce = ct->c_cefile; + CE ce = &ct->c_cefile; switch (ct->c_type) { case CT_MULTIPART: @@ -1087,7 +1099,7 @@ raw: if ((out = fopen (ce->ce_file, "w")) == NULL) adios (ce->ce_file, "unable to open for writing"); - for (i = 0; (child_id = vfork()) == NOTOK && i > 5; i++) + for (i = 0; (child_id = fork()) == NOTOK && i > 5; i++) sleep (5); switch (child_id) { case NOTOK: @@ -1147,11 +1159,10 @@ scan_content (CT ct) int checklinelen = 0, linelen = 0; /* check for long lines */ int checkboundary = 0, boundaryclash = 0; /* check if clashes with multipart boundary */ int checklinespace = 0, linespace = 0; /* check if any line ends with space */ - int checkebcdic = 0, ebcdicunsafe = 0; /* check if contains ebcdic unsafe characters */ - unsigned char *cp = NULL, buffer[BUFSIZ]; + char *cp = NULL, buffer[BUFSIZ]; struct text *t = NULL; FILE *in = NULL; - CE ce = ct->c_cefile; + CE ce = &ct->c_cefile; /* * handle multipart by scanning all subparts @@ -1188,11 +1199,9 @@ scan_content (CT ct) check8bit = 1; checkboundary = 1; if (ct->c_subtype == TEXT_PLAIN) { - checkebcdic = 0; checklinelen = 0; checklinespace = 0; } else { - checkebcdic = ebcdicsw; checklinelen = 1; checklinespace = 1; } @@ -1200,7 +1209,6 @@ scan_content (CT ct) case CT_APPLICATION: check8bit = 1; - checkebcdic = ebcdicsw; checklinelen = 1; checklinespace = 1; checkboundary = 1; @@ -1208,7 +1216,6 @@ scan_content (CT ct) case CT_MESSAGE: check8bit = 0; - checkebcdic = 0; checklinelen = 0; checklinespace = 0; @@ -1227,7 +1234,6 @@ scan_content (CT ct) * since we are forcing use of base64. */ check8bit = 0; - checkebcdic = 0; checklinelen = 0; checklinespace = 0; checkboundary = 0; @@ -1248,18 +1254,10 @@ scan_content (CT ct) */ if (check8bit) { for (cp = buffer; *cp; cp++) { - if (!isascii (*cp)) { + if (!isascii ((unsigned char) *cp)) { contains8bit = 1; check8bit = 0; /* no need to keep checking */ } - /* - * Check if character is ebcdic-safe. We only check - * this if also checking for 8bit data. - */ - if (checkebcdic && !ebcdicsafe[*cp & 0xff]) { - ebcdicunsafe = 1; - checkebcdic = 0; /* no need to keep checking */ - } } } @@ -1274,7 +1272,7 @@ scan_content (CT ct) /* * Check if line ends with a space. */ - if (checklinespace && (cp = buffer + strlen (buffer) - 2) > buffer && isspace (*cp)) { + if (checklinespace && (cp = buffer + strlen (buffer) - 2) > buffer && isspace ((unsigned char) *cp)) { linespace = 1; checklinespace = 0; /* no need to keep checking */ } @@ -1285,10 +1283,10 @@ scan_content (CT ct) */ if (checkboundary && buffer[0] == '-' && buffer[1] == '-') { for (cp = buffer + strlen (buffer) - 1; cp >= buffer; cp--) - if (!isspace (*cp)) + if (!isspace ((unsigned char) *cp)) break; *++cp = '\0'; - if (!strncmp(buffer + 2, prefix, len) && isdigit(buffer[2 + len])) { + if (!strncmp(buffer + 2, prefix, len) && isdigit((unsigned char) buffer[2 + len])) { boundaryclash = 1; checkboundary = 0; /* no need to keep checking */ } @@ -1315,12 +1313,11 @@ scan_content (CT ct) continue; if (contains8bit) { - t->tx_charset = CHARSET_UNKNOWN; *ap = concat ("charset=", write_charset_8bit(), NULL); } else { - t->tx_charset = CHARSET_USASCII; *ap = add ("charset=us-ascii", NULL); } + t->tx_charset = CHARSET_SPECIFIED; cp = strchr(*ap++, '='); *ap = NULL; @@ -1328,7 +1325,7 @@ scan_content (CT ct) *ep = cp; } - if (contains8bit || ebcdicunsafe || linelen || linespace || checksw) + if (contains8bit || linelen || linespace || checksw) ct->c_encoding = CE_QUOTED; else ct->c_encoding = CE_7BIT; @@ -1336,7 +1333,7 @@ scan_content (CT ct) case CT_APPLICATION: /* For application type, use base64, except when postscript */ - if (contains8bit || ebcdicunsafe || linelen || linespace || checksw) + if (contains8bit || linelen || linespace || checksw) ct->c_encoding = (ct->c_subtype == APPLICATION_POSTSCRIPT) ? CE_QUOTED : CE_BASE64; else @@ -1368,7 +1365,7 @@ scan_content (CT ct) static int build_headers (CT ct) { - int cc, mailbody, len; + int cc, mailbody, extbody, len; char **ap, **ep; char *np, *vp, buffer[BUFSIZ]; CI ci = &ct->c_ctinfo; @@ -1410,21 +1407,56 @@ build_headers (CT ct) len = strlen (TYPE_FIELD) + strlen (ci->ci_type) + strlen (ci->ci_subtype) + 3; - mailbody = ct->c_type == CT_MESSAGE - && ct->c_subtype == MESSAGE_EXTERNAL - && ((struct exbody *) ct->c_ctparams)->eb_body; + extbody = ct->c_type == CT_MESSAGE && ct->c_subtype == MESSAGE_EXTERNAL; + mailbody = extbody && ((struct exbody *) ct->c_ctparams)->eb_body; /* * Append the attribute/value pairs to * the end of the Content-Type line. */ for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) { - if (mailbody && !mh_strcasecmp (*ap, "body")) + if (mailbody && !strcasecmp (*ap, "body")) continue; vp = add (";", vp); len++; + /* + * According to RFC 2017, if we have a URL longer than 40 characters + * we have to break it across multiple lines + */ + + if (extbody && strcasecmp (*ap, "url") == 0) { + char *value = *ep; + + /* 7 here refers to " url=\"\"" */ + if (len + 1 + (cc = (min(MAXURLTOKEN, strlen(value)) + 7)) >= + CPERLIN) { + vp = add ("\n\t", vp); + len = 8; + } else { + vp = add (" ", vp); + len++; + } + + vp = add ("url=\"", vp); + len += 5; + + while (strlen(value) > MAXURLTOKEN) { + strncpy(buffer, value, MAXURLTOKEN); + buffer[MAXURLTOKEN] = '\0'; + vp = add (buffer, vp); + vp = add ("\n\t", vp); + value += MAXURLTOKEN; + len = 8; + } + + vp = add (value, vp); + vp = add ("\"", vp); + len += strlen(value) + 1; + continue; + } + snprintf (buffer, sizeof(buffer), "%s=\"%s\"", *ap, *ep); if (len + 1 + (cc = strlen (buffer)) >= CPERLIN) { vp = add ("\n\t", vp); @@ -1507,11 +1539,6 @@ skip_headers: switch (ct->c_encoding) { case CE_7BIT: /* Nothing to output */ -#if 0 - np = add (ENCODING_FIELD, NULL); - vp = concat (" ", "7bit", "\n", NULL); - add_header (ct, np, vp); -#endif break; case CE_8BIT: @@ -1603,13 +1630,14 @@ calculate_digest (CT ct, int asciiP) unsigned char *dp; unsigned char digest[16]; unsigned char outbuf[25]; - FILE *in; MD5_CTX mdContext; - CE ce = ct->c_cefile; + CE ce = &ct->c_cefile; + char *infilename = ce->ce_file ? ce->ce_file : ct->c_file; + FILE *in; /* open content */ - if ((in = fopen (ce->ce_file, "r")) == NULL) - adios (ce->ce_file, "unable to open for reading"); + if ((in = fopen (infilename, "r")) == NULL) + adios (infilename, "unable to open for reading"); /* Initialize md5 context */ MD5Init (&mdContext); @@ -1652,7 +1680,8 @@ calculate_digest (CT ct, int asciiP) } /* encode the digest using base64 */ - for (dp = digest, op = outbuf, cc = sizeof(digest) / sizeof(digest[0]); + for (dp = digest, op = (char *) outbuf, + cc = sizeof(digest) / sizeof(digest[0]); cc > 0; cc -= 3, op += 4) { unsigned long bits; char *bp;