From: Pierre Habouzit Date: Thu, 2 Nov 2006 01:20:01 +0000 (+0100) Subject: lot of restructurations. work in progress, *but* it does not seems to X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=commitdiff_plain;h=c660c8cbae7f647c637502779862e4a36ad6a074 lot of restructurations. work in progress, *but* it does not seems to break anything. Signed-off-by: Pierre Habouzit --- diff --git a/globals.h b/globals.h index 5977ee1..fac8994 100644 --- a/globals.h +++ b/globals.h @@ -304,13 +304,6 @@ const char *Weekdays[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; const char *Months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "ERR" }; - -const char *BodyTypes[] = - { "x-unknown", "audio", "application", "image", "message", "model", -"multipart", "text", "video" }; -const char *BodyEncodings[] = - { "x-unknown", "7bit", "8bit", "quoted-printable", "base64", "binary", -"x-uuencoded" }; #else extern const char *Weekdays[]; extern const char *Months[]; diff --git a/lib-mime/Makefile.am b/lib-mime/Makefile.am index 97db918..4cb982c 100644 --- a/lib-mime/Makefile.am +++ b/lib-mime/Makefile.am @@ -1,6 +1,6 @@ noinst_LIBRARIES = libmime.a -libmime_a_SOURCES = mime.h rfc2231.c +libmime_a_SOURCES = mime.h mime.c rfc2231.c noinst_HEADERS = mime.h diff --git a/lib-mime/mime.h b/lib-mime/mime.h index 97b1611..03acd98 100644 --- a/lib-mime/mime.h +++ b/lib-mime/mime.h @@ -67,25 +67,26 @@ typedef struct parameter { struct parameter *next; } PARAMETER; +extern const char MimeSpecials[]; +extern const char *BodyTypes[]; +extern const char *BodyEncodings[]; + /* MIME encoding/decoding global vars */ #define is_multipart(x) \ ((x)->type == TYPEMULTIPART \ || ((x)->type == TYPEMESSAGE && (!strcasecmp((x)->subtype, "rfc822") \ || !strcasecmp((x)->subtype, "news")))) - -extern const char *BodyTypes[]; -extern const char *BodyEncodings[]; - #define TYPE(X) ((X->type == TYPEOTHER) && (X->xtype != NULL) ? X->xtype : BodyTypes[(X->type)]) #define ENCODING(X) BodyEncodings[(X)] -/* other MIME-related global variables */ -#ifndef _SENDLIB_C -extern char MimeSpecials[]; -#endif +/****************************************************************************/ +/* RFC 2231 */ +/* MIME Parameter Value and Encoded Word Extensions: */ +/* Character Sets, Languages, and Continuations */ +/****************************************************************************/ -void rfc2231_decode_parameters (PARAMETER **); -int rfc2231_encode_string (char **); +int rfc2231_encode_string(char **); +void rfc2231_decode_parameters(PARAMETER **); #endif /* MUTT_LIB_MIME_MIME_H */ diff --git a/lib-mime/rfc2231.c b/lib-mime/rfc2231.c index b0fbd59..3f19406 100644 --- a/lib-mime/rfc2231.c +++ b/lib-mime/rfc2231.c @@ -49,51 +49,25 @@ #include "charset.h" #include "rfc2047.h" -typedef struct rfc2231_parameter { +typedef struct rfc2231_param { + struct rfc2231_param *next; + char *attribute; char *value; int idx; int encoded; - struct rfc2231_parameter *next; -} rfc2231_parameter; +} rfc2231_param; -DO_INIT(rfc2231_parameter, rfc2231_parameter); -static inline void rfc2231_parameter_wipe(rfc2231_parameter *param) +DO_INIT(rfc2231_param, rfc2231_param); +static inline void rfc2231_param_wipe(rfc2231_param *param) { p_delete(¶m->attribute); p_delete(¶m->value); } -DO_NEW(rfc2231_parameter, rfc2231_parameter); -DO_DELETE(rfc2231_parameter, rfc2231_parameter); - - -/* insert parameter into an ordered list. - * - * Primary sorting key: attribute - * Secondary sorting key: idx - */ -static void -rfc2231_list_insert(rfc2231_parameter **list, rfc2231_parameter *par) -{ - rfc2231_parameter **last = list; - rfc2231_parameter *p = *list, *q; - int c; - - while (p) { - last = &p->next; - q = p; - p = p->next; - - c = m_strcmp(par->value, q->value); - if ((c > 0) || (c == 0 && par->idx >= q->idx)) - break; - } - - par->next = p; - *last = par; -} - +DO_NEW(rfc2231_param, rfc2231_param); +DO_DELETE(rfc2231_param, rfc2231_param); +/* TODO: MC: replace with a str_unescape */ static void rfc2231_decode_one(char *dst, const char *src) { while (*src) { @@ -112,8 +86,7 @@ static void rfc2231_decode_one(char *dst, const char *src) *dst = '\0'; } -/* ---------------- TODO FIXME READ MARK ---------------- */ - +/* read the 'foo' part into charset, and skip that */ static char *rfc2231_get_charset(char *value, char *charset, size_t chslen) { char *t, *u; @@ -135,33 +108,113 @@ static char *rfc2231_get_charset(char *value, char *charset, size_t chslen) } -static void rfc2231_join_continuations(PARAMETER **, rfc2231_parameter *); +/* insert parameter into an ordered list. + * + * Primary sorting key: attribute + * Secondary sorting key: idx + * + * XXX: MC: looks very unclear to me + */ +static void +rfc2231_list_insert(rfc2231_param **list, rfc2231_param *par) +{ + int c; + + while (*list) { + rfc2231_param *q = *list; + + list = &(*list)->next; + + c = m_strcmp(par->value, q->value); + if ((c > 0) || (c == 0 && par->idx >= q->idx)) + break; + } + + par->next = *list; + *list = par; +} -static void purge_empty_parameters (PARAMETER **headp) +static void purge_empty_parameters(PARAMETER **headp) { - PARAMETER *p, *q, **last; + while (*headp) { + PARAMETER *p = *headp; - for (last = headp, p = *headp; p; p = q) { - q = p->next; if (!p->attribute || !p->value) { - *last = q; + *headp = p->next; p->next = NULL; - mutt_free_parameter (&p); + mutt_free_parameter(&p); + } else { + headp = &(*headp)->next; } + } +} + +/* process continuation parameters */ +/* XXX: MC: not read */ +static void +rfc2231_join_continuations(PARAMETER **head, rfc2231_param *par) +{ + rfc2231_param *q; + + char attribute[STRING]; + char charset[STRING]; + char *value = NULL; + char *valp; + int encoded; + + size_t l, vl; + + while (par) { + value = NULL; + l = 0; + + m_strcpy(attribute, sizeof(attribute), par->attribute); + + if ((encoded = par->encoded)) + valp = rfc2231_get_charset (par->value, charset, sizeof (charset)); else - last = &p->next; + valp = par->value; + + do { + if (encoded && par->encoded) + rfc2231_decode_one (par->value, valp); + + vl = m_strlen(par->value); + + p_realloc(&value, l + vl + 1); + strcpy (value + l, par->value); /* __STRCPY_CHECKED__ */ + l += vl; + + q = par->next; + rfc2231_param_delete (&par); + if ((par = q)) + valp = par->value; + } while (par && !m_strcmp(par->attribute, attribute)); + + if (value) { + if (encoded) + mutt_convert_string (&value, charset, Charset, M_ICONV_HOOK_FROM); + *head = mutt_new_parameter (); + (*head)->attribute = m_strdup(attribute); + (*head)->value = value; + head = &(*head)->next; + } } } +/****************************************************************************/ +/* Public API */ +/****************************************************************************/ +/* XXX: MC: not read */ void rfc2231_decode_parameters (PARAMETER ** headp) { PARAMETER *head = NULL; PARAMETER **last; PARAMETER *p, *q; - rfc2231_parameter *conthead = NULL; - rfc2231_parameter *conttmp; + rfc2231_param *conthead = NULL; + rfc2231_param *conttmp; char *s, *t; char charset[STRING]; @@ -222,7 +275,7 @@ void rfc2231_decode_parameters (PARAMETER ** headp) idx = atoi (s); - conttmp = rfc2231_parameter_new (); + conttmp = rfc2231_param_new (); conttmp->attribute = p->attribute; conttmp->value = p->value; conttmp->encoded = encoded; @@ -247,121 +300,64 @@ void rfc2231_decode_parameters (PARAMETER ** headp) purge_empty_parameters (headp); } -/* process continuation parameters */ - -static void -rfc2231_join_continuations(PARAMETER **head, rfc2231_parameter *par) -{ - rfc2231_parameter *q; - - char attribute[STRING]; - char charset[STRING]; - char *value = NULL; - char *valp; - int encoded; - - size_t l, vl; - - while (par) { - value = NULL; - l = 0; - - m_strcpy(attribute, sizeof(attribute), par->attribute); - - if ((encoded = par->encoded)) - valp = rfc2231_get_charset (par->value, charset, sizeof (charset)); - else - valp = par->value; - - do { - if (encoded && par->encoded) - rfc2231_decode_one (par->value, valp); - - vl = m_strlen(par->value); +#define RFC2231_SPECIALS "@.,;:<>[]\\\"()?/= \t*'%" - p_realloc(&value, l + vl + 1); - strcpy (value + l, par->value); /* __STRCPY_CHECKED__ */ - l += vl; - - q = par->next; - rfc2231_parameter_delete (&par); - if ((par = q)) - valp = par->value; - } while (par && !m_strcmp(par->attribute, attribute)); - - if (value) { - if (encoded) - mutt_convert_string (&value, charset, Charset, M_ICONV_HOOK_FROM); - *head = mutt_new_parameter (); - (*head)->attribute = m_strdup(attribute); - (*head)->value = value; - head = &(*head)->next; - } - } -} - -int rfc2231_encode_string (char **pd) +int rfc2231_encode_string(char **s) { - int ext = 0, encode = 0; - char *charset, *s, *t, *e, *d = 0; - size_t slen, dlen = 0; + char *charset = NULL; + char *e, *p, *t, *d = NULL; + int escapes = 0; + size_t dlen = 0; - /* + /* * A shortcut to detect pure 7bit data. - * - * This should prevent the worst when character set handling - * is flawed. + * + * This should prevent the worst when character set handling is flawed. */ - for (s = *pd; *s; s++) - if (*s & 0x80) + for (p = *s; ; p++) { + if (*p & 0x80) break; + if (!*p) + return 0; + } - if (!*s) - return 0; + if (Charset && SendCharset) { + charset = mutt_choose_charset(Charset, SendCharset, + *s, m_strlen(*s), &d, &dlen); + } - if (!Charset || !SendCharset || - !(charset = mutt_choose_charset (Charset, SendCharset, - *pd, m_strlen(*pd), &d, &dlen))) { + if (!charset) { charset = m_strdup(Charset ? Charset : "unknown-8bit"); - d = *pd; + d = *s; dlen = m_strlen(d); } - if (!mutt_is_us_ascii (charset)) - encode = 1; - - for (s = d, slen = dlen; slen; s++, slen--) - if (*s < 0x20 || *s >= 0x7f) - encode = 1, ++ext; - else if (strchr (MimeSpecials, *s) || strchr ("*'%", *s)) - ++ext; - - if (encode) { - e = p_new(char, dlen + 2 * ext + m_strlen(charset) + 3); - sprintf (e, "%s''", charset); /* __SPRINTF_CHECKED__ */ - t = e + m_strlen(e); - for (s = d, slen = dlen; slen; s++, slen--) - if (*s < 0x20 || *s >= 0x7f || - strchr (MimeSpecials, *s) || strchr ("*'%", *s)) { - sprintf (t, "%%%02X", (unsigned char) *s); - t += 3; - } - else - *t++ = *s; - *t = '\0'; - - if (d != *pd) - p_delete(&d); - p_delete(pd); - *pd = e; + for (p = d; *p; p++) { + if (*p < 0x20 || *p >= 0x7f || strchr(RFC2231_SPECIALS, *p)) { + ++escapes; + } } - else if (d != *pd) { - p_delete(pd); - *pd = d; + + e = p_new(char, dlen + 2 * escapes + m_strlen(charset) + 3); + + t = e + sprintf(e, "%s''", charset); + for (p = d; *p; p++) { + if (*p < 0x20 || *p >= 0x7f || strchr(RFC2231_SPECIALS, *p)) { + *t++ = '%'; + *t++ = __m_b36chars_upper[*p >> 4]; + *t++ = __m_b36chars_upper[*p & 0xf]; + } else { + *t++ = *p; + } } + *t = '\0'; + if (d != *s) + p_delete(&d); + p_delete(s); p_delete(&charset); - return encode; + *s = e; + return 1; } diff --git a/sendlib.c b/sendlib.c index b82ff18..91490fe 100644 --- a/sendlib.c +++ b/sendlib.c @@ -73,8 +73,6 @@ extern char RFC822Specials[]; #define DISPOSITION(X) X==DISPATTACH?"attachment":"inline" -const char MimeSpecials[] = "@.,;:<>[]\\\"()?/= \t"; - static char MsgIdPfx = 'A'; static void transform_to_7bit (BODY * a, FILE * fpin);