char *get_param(PM first, const char *name, char replace, int fetchonly);
+/*
+ * Fetch a parameter value from a parameter structure, converting it to
+ * the local character set.
+ *
+ * Arguments are:
+ *
+ * pm - Pointer to parameter structure
+ * replace - If characters in the parameter list cannot be converted to
+ * the local character set, replace with this character.
+ *
+ * Returns a pointer to the parameter value. Memory is stored in an
+ * internal buffer, so the returned value is only valid until the next
+ * call to get_param_value() or get_param() (get_param() uses get_param_value()
+ * internally).
+ */
+char *get_param_value(PM pm, char replace);
+
extern int checksw; /* Add Content-MD5 field */
CI ci = &ct->c_ctinfo;
PM pm;
- for (pm = ci->ci_first_pm; pm; pm = pm->pm_next)
- printf ("\t %s=\"%s\"\n", pm->pm_name, pm->pm_value);
+ for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) {
+ printf ("\t %s=\"%s\"\n", pm->pm_name,
+ get_param_value(pm, '?'));
+ }
/*
* If verbose, print any RFC-822 comments in the
if (strcasecmp(name, first->pm_name) == 0) {
if (fetchonly)
return first->pm_value;
- else {
- char convbuf[BUFSIZ];
- size_t inbytes, outbytes = sizeof(convbuf);
+ else
+ return getcpy(get_param_value(first, replace));
+ }
+ first = first->pm_next;
+ }
+
+ return NULL;
+}
+
+/*
+ * Return a parameter value, converting to the local character set if
+ * necessary
+ */
+
+char *get_param_value(PM pm, char replace)
+{
+ static char buffer[4096]; /* I hope no parameters are larger */
+ size_t bufsize = sizeof(buffer);
#ifdef HAVE_ICONV
- int utf8;
- iconv_t cd;
- ICONV_CONST char *p;
- char *q;
+ size_t inbytes;
+ int utf8;
+ iconv_t cd;
+ ICONV_CONST char *p;
#endif /* HAVE_ICONV */
- if (!first->pm_charset ||
- check_charset(first->pm_charset,
- strlen(first->pm_charset))) {
- /*
- * No conversion necessary
- */
- return getcpy(first->pm_value);
- }
-#ifdef HAVE_ICONV
- utf8 = strcasecmp(first->pm_charset, "UTF-8") == 0;
+ char *q;
- cd = iconv_open(get_charset(), first->pm_charset);
- if (cd == (iconv_t) -1) {
- goto noconvert;
- }
+ /*
+ * If we don't have a character set indicated, it's assumed to be
+ * US-ASCII. If it matches our character set, we don't need to convert
+ * anything.
+ */
- inbytes = strlen(first->pm_value);
- outbytes = sizeof(convbuf);
- p = first->pm_value;
- q = convbuf;
+ if (!pm->pm_charset || check_charset(pm->pm_charset,
+ strlen(pm->pm_charset))) {
+ return pm->pm_value;
+ }
- while (inbytes) {
- if (iconv(cd, &p, &inbytes, &q, &outbytes) == (size_t)-1) {
- if (errno != EILSEQ) {
- iconv_close(cd);
- goto noconvert;
- }
- /*
- * Reset shift state, substitute our character,
- * try to restart conversion.
- */
- iconv(cd, NULL, NULL, &q, &outbytes);
- if (outbytes == 0) {
- iconv_close(cd);
- goto noconvert;
- }
- *q++ = replace;
- outbytes--;
- if (outbytes == 0) {
- iconv_close(cd);
- goto noconvert;
- }
- if (utf8) {
- for (++p, --inbytes; inbytes > 0 &&
- (((unsigned char) *q) & 0xc0) == 0x80;
- ++p, --inbytes)
- continue;
- } else {
- p++;
- inbytes--;
- }
- }
- }
+ /*
+ * In this case, we need to convert. If we have iconv support, use
+ * that. Otherwise, go through and simply replace every non-ASCII
+ * character with the substitution character.
+ */
- iconv_close(cd);
+#ifdef HAVE_ICONV
+ q = buffer;
+ bufsize = sizeof(buffer);
+ utf8 = strcasecmp(pm->pm_charset, "UTF-8") == 0;
- if (outbytes == 0)
- q--;
- *q = '\0';
+ cd = iconv_open(get_charset(), pm->pm_charset);
+ if (cd == (iconv_t) -1) {
+ goto noiconv;
+ }
- return getcpy(convbuf);
-#endif /* HAVE_ICONV */
-noconvert:
- for (p = first->pm_value, q = convbuf; *p && outbytes > 1;
- p++, q++, outbytes--) {
- if (isascii((unsigned char) p) &&
- isprint((unsigned char) p))
- *q = *p;
- else
- *q = replace;
- }
+ inbytes = strlen(pm->pm_value);
+ p = pm->pm_value;
+
+ while (inbytes) {
+ if (iconv(cd, &p, &inbytes, &q, &bufsize) == (size_t)-1) {
+ if (errno != EILSEQ) {
+ iconv_close(cd);
+ goto noiconv;
+ }
+ /*
+ * Reset shift state, substitute our character,
+ * try to restart conversion.
+ */
- *q = '\0';
+ iconv(cd, NULL, NULL, &q, &bufsize);
- return getcpy(convbuf);
+ if (bufsize == 0) {
+ iconv_close(cd);
+ goto noiconv;
+ }
+ *q++ = replace;
+ bufsize--;
+ if (bufsize == 0) {
+ iconv_close(cd);
+ goto noiconv;
+ }
+ if (utf8) {
+ for (++p, --inbytes;
+ inbytes > 0 && (((unsigned char) *q) & 0xc0) == 0x80;
+ ++p, --inbytes)
+ continue;
+ } else {
+ p++;
+ inbytes--;
}
}
+ }
- first = first->pm_next;
+ iconv_close(cd);
+
+ if (bufsize == 0)
+ q--;
+ *q = '\0';
+
+ return buffer;
+#endif /* HAVE_ICONV */
+
+noiconv:
+ /*
+ * Take everything non-ASCII and substituite the replacement character
+ */
+
+ q = buffer;
+ bufsize = sizeof(buffer);
+ for (p = pm->pm_value; *p != '\0' && bufsize > 1; p++, q++, bufsize--) {
+ if (isascii((unsigned char) *p) && !iscntrl((unsigned char) *p))
+ *q = *p;
+ else
+ *q = replace;
}
- return NULL;
+ *q = '\0';
+
+ return buffer;
}
store_application (CT ct)
{
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;
+ char *cp;
- for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) {
- /* check for "type=tar" attribute */
- if (!strcasecmp (pm->pm_name, "type")) {
- if (strcasecmp (pm->pm_value, "tar"))
- break;
-
+ if ((cp = get_param(ci->ci_first_pm, "type", ' ', 1))) {
+ if (strcasecmp (cp, "tar") == 0)
tarP = 1;
- continue;
- }
+ }
- /* check for "conversions=compress" attribute */
- if ((!strcasecmp (pm->pm_name, "conversions") ||
- !strcasecmp (pm->pm_name, "x-conversions"))
- && (!strcasecmp (pm->pm_value, "compress") ||
- !strcasecmp (pm->pm_value, "x-compress"))) {
+ /* check for "conversions=compress" attribute */
+ if ((cp = get_param(ci->ci_first_pm, "conversions", ' ', 1)) ||
+ (cp = get_param(ci->ci_first_pm, "x-conversions", ' ', 1))) {
+ if (strcasecmp (cp, "compress") == 0 ||
+ strcasecmp (cp, "x-compress") == 0) {
zP = 1;
- continue;
}
- /* check for "conversions=gzip" attribute */
- if ((!strcasecmp (pm->pm_name, "conversions") ||
- !strcasecmp (pm->pm_name, "x-conversions"))
- && (!strcasecmp (pm->pm_value, "gzip") ||
- !strcasecmp (pm->pm_value, "x-gzip"))) {
+ if (strcasecmp (cp, "gzip") == 0 ||
+ strcasecmp (cp, "x-gzip") == 0) {
gzP = 1;
- continue;
}
}
for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) {
snprintf (bp, buflen, "%s%s=\"%s\"", s,
- pm->pm_name, pm->pm_value);
+ pm->pm_name, get_param_value(pm, '?'));
len = strlen (bp);
bp += len;
buflen -= len;
{
char *cp;
CI ci;
- PM pm;
/*
* If the storeproc has already been defined,
* use that (RFC-2183).
*/
if (ct->c_dispo) {
- int found_filename = 0;
-
- 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, '%')) {
+ if ((cp = get_param(ct->c_dispo_first, "filename", '_', 0))
+ && *cp != '/'
+ && *cp != '.'
+ && *cp != '|'
+ && *cp != '!'
+ && !strchr (cp, '%')) {
ct->c_storeproc = add (cp, NULL);
- found_filename = 1;
- }
+ free(cp);
+ return;
}
-
- if (found_filename) return;
+ if (cp)
+ free(cp);
}
/*
* the storeproc.
*/
ci = &ct->c_ctinfo;
- for (pm = ci->ci_first_pm; pm; pm = pm->pm_next) {
- if (! strcasecmp (pm->pm_name, "name")
- && *(cp = pm->pm_value) != '/'
- && *cp != '.'
- && *cp != '|'
- && *cp != '!'
- && !strchr (cp, '%')) {
+ if ((cp = get_param(ci->ci_first_pm, "name", '_', 0))
+ && *cp != '/'
+ && *cp != '.'
+ && *cp != '|'
+ && *cp != '!'
+ && !strchr (cp, '%')) {
ct->c_storeproc = add (cp, NULL);
- return;
- }
+
}
+ if (cp)
+ free(cp);
}