that needs to be done before it is complete.
int
contains8bit(const char *start, const char *end)
{
+ if (! start)
+ return 0;
+
while (*start != '\0' && (!end || (start < end)))
if (! isascii((unsigned char) *start++))
return 1;
if (!ce->ce_file) {
pid_t child_id;
int i, xstdout, len, buflen;
- char *bp, **ap, *cp;
+ char *bp, *cp;
char *vec[4], buffer[BUFSIZ];
FILE *out;
CI ci = &ct->c_ctinfo;
CT ct;
struct part *p;
struct multipart *m;
- char *cp;
const struct str2init *ctinit;
if ((ct = (CT) calloc (1, sizeof *ct)) == NULL)
ct->c_ctinfo.ci_subtype = add (subtypename, NULL);
}
- name = concat (" ", typename, "/", subtypename, boundary_indicator,
- boundary, NULL);
- if ((cp = strstr (name, boundary_indicator))) {
- ct->c_ctinfo.ci_attrs[0] = name;
- ct->c_ctinfo.ci_attrs[1] = NULL;
- /* ci_values don't get free'd, so point into ci_attrs. */
- ct->c_ctinfo.ci_values[0] = cp + strlen (boundary_indicator);
- }
+ add_param(&ct->c_ctinfo.ci_first_pm, &ct->c_ctinfo.ci_last_pm,
+ "boundary", boundary);
p = (struct part *) mh_xmalloc (sizeof *p);
p->mp_next = (struct part *) mh_xmalloc (sizeof *p->mp_next);
const char *const charset = "charset";
char *default_codeset = NULL;
CI ctinfo = &ct->c_ctinfo;
- char **ap, **vp;
char **src_codeset = NULL;
+ PM pm;
- for (ap = ctinfo->ci_attrs, vp = ctinfo->ci_values; *ap; ++ap, ++vp) {
- if (! strcasecmp (*ap, charset)) {
- src_codeset = vp;
+ for (pm = ctinfo->ci_first_pm; pm; pm = pm->pm_next) {
+ if (! strcasecmp (pm->pm_name, charset)) {
+ src_codeset = &pm->pm_value;
break;
}
}
/* RFC 2045, Sec. 5.2: default to us-ascii. */
- if (src_codeset == NULL) src_codeset = &default_codeset;
- if (*src_codeset == NULL) *src_codeset = "US-ASCII";
+ if (src_codeset == NULL) {
+ src_codeset = &default_codeset;
+ if (*src_codeset == NULL)
+ *src_codeset = "US-ASCII";
+ }
return *src_codeset;
}
static size_t param_len(PM, int, size_t, int *);
static size_t encode_param(PM, char *, size_t, size_t, size_t, int);
static size_t normal_param(PM, char *, size_t, size_t, size_t);
+static int get_dispo (char *, CT);
struct str2init str2cts[] = {
{ "application", CT_APPLICATION, InitApplication },
}
else if (!strcasecmp (hp->name, DISPO_FIELD)) {
/* Get Content-Disposition field */
- ct->c_dispo = add (hp->value, ct->c_dispo);
+ if (get_dispo(hp->value, ct) == NOTOK)
+ goto out;
}
next_header:
int
get_ctinfo (char *cp, CT ct, int magic)
{
- int i;
char *dp;
char c;
CI ci;
}
else
advise (NULL,
- "extraneous information in message %s's %s: field\n%*.*s(%s)",
- ct->c_file, TYPE_FIELD, i, i, "", cp);
+ "extraneous information in message %s's %s: field\n%*s(%s)",
+ ct->c_file, TYPE_FIELD, strlen(invo_name) + 2, "", cp);
+ }
+
+ return OK;
+}
+
+
+/*
+ * Parse out a Content-Disposition header. A lot of this is cribbed from
+ * get_ctinfo().
+ */
+static int
+get_dispo (char *cp, CT ct)
+{
+ char *dp;
+ char c;
+ int status;
+
+ /* Save the whole copy of the Content-Disposition header */
+
+ ct->c_dispo = add(cp, NULL);
+
+ while (isspace ((unsigned char) *cp)) /* trim leading spaces */
+ cp++;
+
+ /* change newlines to spaces */
+ for (dp = strchr(cp, '\n'); dp; dp = strchr(dp, '\n'))
+ *dp++ = ' ';
+
+ /* trim trailing spaces */
+ for (dp = cp + strlen (cp) - 1; dp >= cp; dp--)
+ if (!isspace ((unsigned char) *dp))
+ break;
+ *++dp = '\0';
+
+ if (debugsw)
+ fprintf (stderr, "%s: %s\n", DISPO_FIELD, cp);
+
+ if (*cp == '(' && get_comment (ct->c_file, DISPO_FIELD, &cp, NULL) == NOTOK)
+ return NOTOK;
+
+ for (dp = cp; istoken (*dp); dp++)
+ continue;
+ c = *dp, *dp = '\0';
+ ct->c_dispo_type = add (cp, NULL); /* store disposition type */
+ *dp = c, cp = dp;
+
+ if (*cp == '(' && get_comment (ct->c_file, DISPO_FIELD, &cp, NULL) == NOTOK)
+ return NOTOK;
+
+ if ((status = parse_header_attrs (ct->c_file, DISPO_FIELD, &cp,
+ &ct->c_dispo_first, &ct->c_dispo_last,
+ NULL)) != OK) {
+ return status == NOTOK ? NOTOK : OK;
+ }
+
+ if (*cp) {
+ advise (NULL,
+ "extraneous information in message %s's %s: field\n%*s(%s)",
+ ct->c_file, DISPO_FIELD, strlen(invo_name) + 2, "", cp);
}
return OK;
/* Now store the attribute value. */
- pm->pm_value = vp = pm->pm_name + (dp - cp);
+ vp = pm->pm_name + (dp - cp);
if (*dp == '"') {
for (cp = ++dp, dp = vp;;) {
continue;
*dp = '\0';
}
+ pm->pm_value = getcpy(vp);
if (!*vp) {
advise (NULL,
"invalid parameter in message %s's %s: "
output_params(size_t initialwidth, PM params, int *offsetout)
{
char *paramout = NULL;
- char line[CPERLIN * 2], *p, *q;
+ char line[CPERLIN * 2], *q;
int curlen, index, eightbit, encode, i;
size_t valoff;
normal_param(PM pm, char *output, size_t len, size_t valuelen,
size_t valueoff)
{
- size_t outlen = 0, n;
+ size_t outlen = 0;
char *endptr = output + len, *p;
*output++ = '=';
memset(pm, 0, sizeof(*pm));
pm->pm_name = getcpy(name);
- pm->pm_value = getcpy(name);
+ pm->pm_value = getcpy(value);
if (*first) {
(*last)->pm_next = pm;
case 'a':
/* insert parameters from Content-Type field */
{
- char **ap, **ep;
+ PM pm;
char *s = "";
- for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
- snprintf (bp, buflen, "%s%s=\"%s\"", s, *ap, *ep);
+ for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) {
+ snprintf (bp, buflen, "%s%s=\"%s\"", s, pm->pm_name,
+ pm->pm_value);
len = strlen (bp);
bp += len;
buflen -= len;
case 'a':
/* insert parameters from Content-Type field */
{
- char **ap, **ep;
+ PM pm;
char *s = "";
- for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
- snprintf (bp, buflen, "%s%s=\"%s\"", s, *ap, *ep);
+ for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) {
+ snprintf (bp, buflen, "%s%s=\"%s\"", s, pm->pm_name,
+ pm->pm_value);
len = strlen (bp);
bp += len;
buflen -= len;
static int
store_application (CT ct)
{
- char **ap, **ep;
CI ci = &ct->c_ctinfo;
+ PM pm;
/* Check if the content specifies a filename */
if (autosw)
if (!ct->c_storeproc && ct->c_subtype == APPLICATION_OCTETS) {
int tarP = 0, zP = 0, gzP = 0;
- for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
+ for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) {
/* check for "type=tar" attribute */
- if (!strcasecmp (*ap, "type")) {
- if (strcasecmp (*ep, "tar"))
+ if (!strcasecmp (pm->pm_name, "type")) {
+ if (strcasecmp (pm->pm_value, "tar"))
break;
tarP = 1;
}
/* check for "conversions=compress" attribute */
- if ((!strcasecmp (*ap, "conversions") || !strcasecmp (*ap, "x-conversions"))
- && (!strcasecmp (*ep, "compress") || !strcasecmp (*ep, "x-compress"))) {
+ if ((!strcasecmp (pm->pm_name, "conversions") ||
+ !strcasecmp (pm->pm_name, "x-conversions"))
+ && (!strcasecmp (pm->pm_value, "compress") ||
+ !strcasecmp (pm->pm_value, "x-compress"))) {
zP = 1;
continue;
}
/* check for "conversions=gzip" attribute */
- if ((!strcasecmp (*ap, "conversions") || !strcasecmp (*ap, "x-conversions"))
- && (!strcasecmp (*ep, "gzip") || !strcasecmp (*ep, "x-gzip"))) {
+ if ((!strcasecmp (pm->pm_name, "conversions") ||
+ !strcasecmp (pm->pm_name, "x-conversions"))
+ && (!strcasecmp (pm->pm_value, "gzip") ||
+ !strcasecmp (pm->pm_value, "x-gzip"))) {
gzP = 1;
continue;
}
buflen--;
continue;
} else {
- char **ap, **ep;
+ PM pm;
char *s = "";
- for (ap = ci->ci_attrs, ep = ci->ci_values;
- *ap; ap++, ep++) {
- snprintf (bp, buflen, "%s%s=\"%s\"", s, *ap, *ep);
+ for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) {
+ snprintf (bp, buflen, "%s%s=\"%s\"", s,
+ pm->pm_name, pm->pm_value);
len = strlen (bp);
bp += len;
buflen -= len;
static void
get_storeproc (CT ct)
{
- char **ap, **ep, *cp;
+ char *cp;
CI ci;
+ PM pm;
/*
* If the storeproc has already been defined,
* use that (RFC-2183).
*/
if (ct->c_dispo) {
- char *cp = strchr (ct->c_dispo, ';');
- CI ci = calloc (1, sizeof *ci);
- int status;
int found_filename = 0;
- if (cp && parse_header_attrs (ct->c_file, strlen (invo_name) + 2, &cp,
- ci, &status) == OK) {
- for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
- if (! strcasecmp (*ap, "filename")
- && *(cp = *ep) != '/'
+ for (pm = ct->c_dispo_first; pm; pm = pm->pm_next) {
+ if (! strcasecmp (pm->pm_name, "filename")
+ && *(cp = pm->pm_value) != '/'
&& *cp != '.'
&& *cp != '|'
&& *cp != '!'
&& !strchr (cp, '%')) {
- ct->c_storeproc = add (cp, NULL);
- found_filename = 1;
- }
- free (*ap);
+ ct->c_storeproc = add (cp, NULL);
+ found_filename = 1;
}
}
- free (ci);
if (found_filename) return;
}
* the storeproc.
*/
ci = &ct->c_ctinfo;
- for (ap = ci->ci_attrs, ep = ci->ci_values; *ap; ap++, ep++) {
- if (! strcasecmp (*ap, "name")
- && *(cp = *ep) != '/'
+ for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) {
+ if (! strcasecmp (pm->pm_name, "name")
+ && *(cp = pm->pm_value) != '/'
&& *cp != '.'
&& *cp != '|'
&& *cp != '!'