/* * rfc1738_str - convert rfc1738 escaped octets in place */ char * rfc1738_str(char *s) { register char *p = s, *q = s; while(1) switch(*q = *p++){ case '%' : if(isxpair(p)){ *q = X2C(p); p += 2; } default : q++; break; case '\0': return(s); } }
/* * rfc1738_num - return long value of a string of digits, possibly escaped */ unsigned long rfc1738_num(char **s) { register char *p = *s; unsigned long n = 0L; for(; *p; p++) if(*p == '%' && isxpair(p+1)){ int c = X2C(p+1); if(isdigit((unsigned char) c)){ n = (c - '0') + (n * 10); p += 2; } else break; } else if(isdigit((unsigned char) *p)) n = (*p - '0') + (n * 10); else break; *s = p; return(n); }
char * rfc2231_get_param(PARAMETER *parms, char *name, char **charset, char **lang) { char *buf, *p; int decode = 0, name_len, i; unsigned n; name_len = strlen(name); for(; parms ; parms = parms->next) if(!struncmp(name, parms->attribute, name_len)){ if(parms->attribute[name_len] == '*'){ for(p = &parms->attribute[name_len + 1], n = 0; *(p+n); n++) ; decode = *(p + n - 1) == '*'; if(isdigit((unsigned char) *p)){ char *pieces[RFC2231_MAX]; int count = 0, len; memset(pieces, 0, RFC2231_MAX * sizeof(char *)); while(parms){ n = 0; do n = (n * 10) + (*p - '0'); while(isdigit(*++p) && n < RFC2231_MAX); if(n < RFC2231_MAX){ pieces[n] = parms->value; if(n > count) count = n; } else{ q_status_message1(SM_ORDER | SM_DING, 0, 3, "Invalid attachment parameter segment number: %.25s", name); return(NULL); /* Too many segments! */ } while((parms = parms->next) != NULL) if(!struncmp(name, parms->attribute, name_len)){ if(*(p = &parms->attribute[name_len]) == '*' && isdigit((unsigned char) *++p)) break; else return(NULL); /* missing segment no.! */ } } for(i = len = 0; i <= count; i++) if(pieces[i]) len += strlen(pieces[i]); else{ q_status_message1(SM_ORDER | SM_DING, 0, 3, "Missing attachment parameter sequence: %.25s", name); return(NULL); /* hole! */ } buf = (char *) fs_get((len + 1) * sizeof(char)); for(i = len = 0; i <= count; i++){ if((n = *(p = pieces[i]) == '\"') != 0) /* quoted? */ p++; while(*p && !(n && *p == '\"' && !*(p+1))) buf[len++] = *p++; } buf[len] = '\0'; } else buf = cpystr(parms->value); /* Do any RFC 2231 decoding? */ if(decode){ char *converted = NULL, cs[1000]; cs[0] = '\0'; n = 0; if((p = strchr(buf, '\'')) != NULL){ n = (p - buf) + 1; *p = '\0'; strncpy(cs, buf, sizeof(cs)); cs[sizeof(cs)-1] = '\0'; *p = '\''; if(charset) *charset = cpystr(cs); if((p = strchr(&buf[n], '\'')) != NULL){ n = (p - buf) + 1; if(lang){ *p = '\0'; *lang = cpystr(p); *p = '\''; } } } if(n){ /* Suck out the charset & lang while decoding hex */ p = &buf[n]; for(i = 0; (buf[i] = *p) != '\0'; i++) if(*p++ == '%' && isxpair(p)){ buf[i] = X2C(p); p += 2; } } else fs_give((void **) &buf); /* problems!?! */ /* * Callers will expect the returned value to be UTF-8 * text, so we may need to translate here. */ if(buf) converted = convert_to_utf8(buf, cs, 0); if(converted && converted != buf){ fs_give((void **) &buf); buf = converted; } } return(buf); } else return(cpystr(parms->value ? parms->value : "")); } return(NULL); }