aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-mime-utils.c
diff options
context:
space:
mode:
authorNotZed <NotZed@HelixCode.com>2000-04-22 13:22:20 +0800
committerMichael Zucci <zucchi@src.gnome.org>2000-04-22 13:22:20 +0800
commit0d82053015309f173335c41052356f20ef1c6227 (patch)
treee8013c96a9b77ea821f59e8df4e4aa1a84bac685 /camel/camel-mime-utils.c
parent05a7bb9ef8ed8327fde0b04a0cab854d2c4a5d36 (diff)
downloadgsoc2013-evolution-0d82053015309f173335c41052356f20ef1c6227.tar
gsoc2013-evolution-0d82053015309f173335c41052356f20ef1c6227.tar.gz
gsoc2013-evolution-0d82053015309f173335c41052356f20ef1c6227.tar.bz2
gsoc2013-evolution-0d82053015309f173335c41052356f20ef1c6227.tar.lz
gsoc2013-evolution-0d82053015309f173335c41052356f20ef1c6227.tar.xz
gsoc2013-evolution-0d82053015309f173335c41052356f20ef1c6227.tar.zst
gsoc2013-evolution-0d82053015309f173335c41052356f20ef1c6227.zip
Ref the folder after setting it in the new message.
2000-04-22 NotZed <NotZed@HelixCode.com> * providers/mbox/camel-mbox-folder.c (_get_message_by_uid): Ref the folder after setting it in the new message. * camel-mime-part.c (my_set_content_object): Have the headers follow the content-type change here too. (my_write_to_stream): Dont write content-type here, automatically stored in the headers ... (my_write_to_stream): Use header_disposition_format() to format the content-disposition header. (my_write_to_stream): Removed old code, all headers are now stored in the camel-medium level, always. Need to do the same with camel-mime-message i suppose ... * camel-mime-utils.c (header_content_type_is): Handle empty types. * gmime-content-field.c (gmime_content_field_write_to_stream): Use header_content_type_format() to format it. 2000-04-21 NotZed <NotZed@HelixCode.com> * camel-mime-utils.h: Add prototype for header_param_list_free. * camel-recipient.c: New function to remove all the types of a recipient list. I think this whole object needs a major review. * camel-mime-message.c (camel_mime_message_class_init): Removed parse_header_pair override, override add_header instead. (_parse_header_pair): Renamed to add_header. (remove_header): Add this method, to make sure we keep upto date with removed headers too. (_set_field): If given a NULL value, clear it out. (_set_recipient_list_from_string): Constify. (set_header): Override set_header from camel_medium. (process_header): Local function to handle set/add/remove of each header we know about. * camel-mime-part.c (camel_mime_part_class_init): Removed parse_header_pair setup. (my_parse_header_pair): Moved into add_header(), removed. (my_set_disposition): Allow a NULL disposition to clear it. (my_set_content_id): Allow NULL content id to clear it. (remove_header): Track removed headers. (my_set_description): Allow NULL description to clear it. (my_set_content_MD5): Make sure we copy the md5 value, and allow a NULL value to reset it. (my_set_filename): Copy the filename. (my_set_header_lines): Removed. Nothing uses it, it doesn't actually serve any purpose. (camel_mime_part_set_header_lines): Ditto. (my_get_header_lines): Ditto. (camel_mime_part_get_header_lines): Ditto. (camel_mime_part_class_init): Remove *_header_lines setup. (camel_mime_part_init): Remove header_lines init. (my_finalize): Remove header_lines finalise. (my_write_to_stream): Write the headers here. This is just WRONG, camel_medium should be doing this. (my_get_output_stream): Kill a warning. (camel_mime_part_encoding_to_string): Ditto. (camel_mime_part_set_description): Unvirtualiase, use add_header() to do the processing. (my_set_description): Removed. (set_disposition): Renamed from my_set_disposition. (camel_mime_part_get_description): Get the descriptionf rom the get_header method. (my_get_description): Removed. (my_set_filename): Removed. (camel_mime_part_get_filename): Get the parameter from the disposition. (camel_mime_part_encoding_from_string): Handle NULL string. (camel_mime_part_init): Remove reference to filename. (my_finalize): Dont free filename. * camel-mime-part.h (CamelMimePartClass): Removed parse_header_pair() method, it doesn't add anything that add_header() can't be used for. (CamelMimePartClass): Remove *_header_lines methods. (struct _CamelMimePart): Remove header_lines list. (struct _CamelMimePart): Removed filename attribute. * camel-medium.c (camel_medium_init): Init headers to null, not a hashtable. (add_header): Append the headers as a list. (remove_header): Remove headers as a list. (get_header): Likewise for lookup. (free_header): Removed, no longer needed. (finalize): Free headers using header_raw_clear(). (camel_medium_set_header): New function, to reset and override all values of a header with a new value. * camel-medium.h (struct _CamelMedium): Changed to use a header_raw struct rather than a hash table, to store headers (many headers can occur multiple times). * camel-mime-utils.c (header_raw_find_next): New function, allows you to find multi-valued header fields. (header_disposition_format): New function to format/create content-disposition header string. (header_param_list_format_append): Function to format parameter lists into a GString. (header_content_type_format): Function to format content-type into a usable format. (header_set_param): allow NULL value to remove the parameter. (decode_token): Renamed from header_decode_token. (header_decode_token): New interface for external use. (quoted_decode): Made static to kill annoying warnings. (g_strdup_len): Killed, replaced with calls to g_strndup(). (rfc2047_decode_word): Made static to kill warnings. (decode_coded_string): Terminated. (g_string_append_len): Made static to kill warnings. (header_decode_text): Made static to kill warnings. (header_decode_text): Constify. (rfc2047_decode_word): Constify. (header_param): Constify. (header_content_type_new): Copy the type/subtype strings. (header_param_list_decode): Made static. (header_param_list_format_append): Made static. (quoted_decode): Constify. (g_string_append_len): Constify. (header_token_decode): New function to decode a single token. * providers/mbox/camel-mbox-summary.c (header_write): Append a trailing \n when writing headers. (strdup_trim): Killed a warning. (camel_mbox_summary_set_uid): Make sure the next uid is at least 1 higher than any existing one. (header_evolution_decode): Use header_token_decode to get the token. * camel-mime-parser.c (folder_scan_header): Strip the trailing \n of the end of all header lines. svn path=/trunk/; revision=2551
Diffstat (limited to 'camel/camel-mime-utils.c')
-rw-r--r--camel/camel-mime-utils.c202
1 files changed, 147 insertions, 55 deletions
diff --git a/camel/camel-mime-utils.c b/camel/camel-mime-utils.c
index 94ede343e6..7b1ad93cd0 100644
--- a/camel/camel-mime-utils.c
+++ b/camel/camel-mime-utils.c
@@ -542,11 +542,13 @@ quoted_decode_step(unsigned char *in, int len, unsigned char *out, int *savestat
this is for the "Q" encoding of international words,
which is slightly different than plain quoted-printable
*/
-int
-quoted_decode(unsigned char *in, int len, unsigned char *out)
+static int
+quoted_decode(const unsigned char *in, int len, unsigned char *out)
{
- register unsigned char *inptr, *outptr;
- unsigned char *inend, c, c1;
+ register const unsigned char *inptr;
+ register unsigned char *outptr;
+ unsigned const char *inend;
+ unsigned char c, c1;
int ret = 0;
inend = in+len;
@@ -619,22 +621,12 @@ header_decode_lwsp(const char **in)
*in = inptr;
}
-char *
-g_strdup_len(const char *start, int len)
-{
- char *d = g_malloc(len+1);
- memcpy(d, start, len);
- d[len] = 0;
- return d;
-}
-
-
/* decode rfc 2047 encoded string segment */
-char *
-rfc2047_decode_word(char *in, int len)
+static char *
+rfc2047_decode_word(const char *in, int len)
{
- char *inptr = in+2;
- char *inend = in+len-2;
+ const char *inptr = in+2;
+ const char *inend = in+len-2;
char *encname;
int tmplen;
int ret;
@@ -668,7 +660,7 @@ rfc2047_decode_word(char *in, int len)
case 'B': {
int state=0;
unsigned int save=0;
- inlen = base64_decode_step(inptr+2, tmplen, decword, &state, &save);
+ inlen = base64_decode_step((char *)inptr+2, tmplen, decword, &state, &save);
/* if state != 0 then error? */
break;
}
@@ -704,15 +696,9 @@ rfc2047_decode_word(char *in, int len)
return decoded;
}
-char *
-decode_coded_string(char *in)
-{
- return rfc2047_decode_word(in, strlen(in));
-}
-
/* grrr, glib should have this ! */
-GString *
-g_string_append_len(GString *st, char *s, int l)
+static GString *
+g_string_append_len(GString *st, const char *s, int l)
{
char *tmp;
@@ -723,12 +709,12 @@ g_string_append_len(GString *st, char *s, int l)
}
/* decodes a simple text, rfc822 */
-char *
-header_decode_text(char *in, int inlen)
+static char *
+header_decode_text(const char *in, int inlen)
{
GString *out;
- char *inptr = in;
- char *inend = in+inlen;
+ const char *inptr = in;
+ const char *inend = in+inlen;
char *encstart, *encend;
char *decword;
@@ -748,9 +734,9 @@ header_decode_text(char *in, int inlen)
}
g_string_append_len(out, inptr, inend-inptr);
- inptr = out->str;
+ encstart = out->str;
g_string_free(out, FALSE);
- return inptr;
+ return encstart;
}
char *
@@ -764,8 +750,8 @@ header_decode_string(const char *in)
/* these are all internal parser functions */
-char *
-header_decode_token(const char **in)
+static char *
+decode_token(const char **in)
{
const char *inptr = *in;
const char *start;
@@ -776,12 +762,21 @@ header_decode_token(const char **in)
inptr++;
if (inptr>start) {
*in = inptr;
- return g_strdup_len(start, inptr-start);
+ return g_strndup(start, inptr-start);
} else {
return NULL;
}
}
+char *
+header_token_decode(const char *in)
+{
+ if (in == NULL)
+ return NULL;
+
+ return decode_token(&in);
+}
+
/*
<"> * ( <any char except <"> \, cr / \ <any char> ) <">
*/
@@ -832,7 +827,7 @@ header_decode_atom(const char **in)
inptr++;
*in = inptr;
if (inptr > start)
- return g_strdup_len(start, inptr-start);
+ return g_strndup(start, inptr-start);
else
return NULL;
}
@@ -864,7 +859,7 @@ header_decode_value(const char **in)
} else if (is_ttoken(*inptr)) {
d(printf("decoding token\n"));
/* this may not have the right specials for all params? */
- return header_decode_token(in);
+ return decode_token(in);
}
return NULL;
}
@@ -891,7 +886,7 @@ header_decode_param(const char **in, char **paramp, char **valuep)
const char *inptr = *in;
char *param, *value=NULL;
- param = header_decode_token(&inptr);
+ param = decode_token(&inptr);
header_decode_lwsp(&inptr);
if (*inptr == '=') {
inptr++;
@@ -911,7 +906,7 @@ header_decode_param(const char **in, char **paramp, char **valuep)
}
char *
-header_param(struct _header_param *p, char *name)
+header_param(struct _header_param *p, const char *name)
{
while (p && strcasecmp(p->name, name) != 0)
p = p->next;
@@ -929,12 +924,21 @@ header_set_param(struct _header_param **l, const char *name, const char *value)
pn = p->next;
if (!strcasecmp(pn->name, name)) {
g_free(pn->value);
- pn->value = g_strdup(value);
- return pn;
+ if (value) {
+ pn->value = g_strdup(value);
+ return pn;
+ } else {
+ p->next = pn->next;
+ g_free(pn);
+ return NULL;
+ }
}
p = pn;
}
+ if (value == NULL)
+ return NULL;
+
pn = g_malloc(sizeof(*pn));
pn->next = 0;
pn->name = g_strdup(name);
@@ -972,6 +976,8 @@ void header_content_type_set_param(struct _header_content_type *t, const char *n
int
header_content_type_is(struct _header_content_type *ct, const char *type, const char *subtype)
{
+ printf("type = %s / %s\n", type, subtype);
+
/* no type == text/plain or text/"*" */
if (ct==NULL) {
return (!strcasecmp(type, "text")
@@ -979,9 +985,11 @@ header_content_type_is(struct _header_content_type *ct, const char *type, const
|| !strcasecmp(subtype, "*")));
}
- return ((!strcasecmp(ct->type, type)
- && (!strcasecmp(ct->subtype, subtype)
- || !strcasecmp("*", subtype))));
+ return (ct->type != NULL
+ && (!strcasecmp(ct->type, type)
+ && ((ct->subtype != NULL
+ && !strcasecmp(ct->subtype, subtype))
+ || !strcasecmp("*", subtype))));
}
void
@@ -1003,8 +1011,8 @@ header_content_type_new(const char *type, const char *subtype)
{
struct _header_content_type *t = g_malloc(sizeof(*t));
- t->type = type;
- t->subtype = subtype;
+ t->type = g_strdup(type);
+ t->subtype = g_strdup(subtype);
t->params = NULL;
t->refcount = 1;
return t;
@@ -1332,6 +1340,8 @@ header_to_decode(const char *in)
d(printf("decoding To: '%s'\n", in));
+#warning header_to_decode needs to return some structure
+
if (in == NULL)
return NULL;
@@ -1362,6 +1372,8 @@ header_mime_decode(const char *in)
d(printf("decoding MIME-Version: '%s'\n", in));
+#warning header_mime_decode needs to return the version
+
if (in == NULL)
return NULL;
@@ -1380,7 +1392,7 @@ header_mime_decode(const char *in)
d(printf("major = %d, minor = %d\n", major, minor));
}
-struct _header_param *
+static struct _header_param *
header_param_list_decode(const char **in)
{
const char *inptr = *in;
@@ -1411,6 +1423,23 @@ header_param_list_decode(const char **in)
return head;
}
+static void
+header_param_list_format_append(GString *out, struct _header_param *p)
+{
+ int len = out->len;
+ while (p) {
+ int here = out->len;
+ if (len+strlen(p->name)+strlen(p->value)>60) {
+ g_string_append(out, "\n\t");
+ len = 0;
+ }
+ /* FIXME: format the value properly */
+ g_string_sprintfa(out, " ; %s=\"%s\"", p->name, p->value);
+ len += (out->len - here);
+ p = p->next;
+ }
+}
+
struct _header_content_type *
header_content_type_decode(const char *in)
{
@@ -1421,12 +1450,12 @@ header_content_type_decode(const char *in)
if (in==NULL)
return NULL;
- type = header_decode_token(&inptr);
+ type = decode_token(&inptr);
header_decode_lwsp(&inptr);
if (type) {
if (*inptr == '/') {
inptr++;
- subtype = header_decode_token(&inptr);
+ subtype = decode_token(&inptr);
}
if (subtype == NULL && (!strcasecmp(type, "text"))) {
g_warning("text type with no subtype, resorting to text/plain: %s", in);
@@ -1467,10 +1496,39 @@ header_content_type_dump(struct _header_content_type *ct)
}
char *
+header_content_type_format(struct _header_content_type *ct)
+{
+ GString *out;
+ char *ret;
+
+ if (ct==NULL)
+ return NULL;
+
+ out = g_string_new("");
+ if (ct->type == NULL) {
+ g_string_sprintfa(out, "text/plain");
+ g_warning("Content-Type with no main type");
+ } else if (ct->subtype == NULL) {
+ g_warning("Content-Type with no sub type: %s", ct->type);
+ if (!strcasecmp(ct->type, "multipart"))
+ g_string_sprintfa(out, "%s/mixed", ct->type);
+ else
+ g_string_sprintfa(out, "%s", ct->type);
+ } else {
+ g_string_sprintfa(out, "%s/%s", ct->type, ct->subtype);
+ }
+ header_param_list_format_append(out, ct->params);
+
+ ret = out->str;
+ g_string_free(out, FALSE);
+ return ret;
+}
+
+char *
header_content_encoding_decode(const char *in)
{
if (in)
- return header_decode_token(&in);
+ return decode_token(&in);
return NULL;
}
@@ -1484,7 +1542,7 @@ CamelMimeDisposition *header_disposition_decode(const char *in)
d = g_malloc(sizeof(*d));
d->refcount = 1;
- d->disposition = header_decode_token(&inptr);
+ d->disposition = decode_token(&inptr);
if (d->disposition == NULL)
g_warning("Empty disposition type");
d->params = header_param_list_decode(&inptr);
@@ -1509,6 +1567,26 @@ void header_disposition_unref(CamelMimeDisposition *d)
}
}
+char *header_disposition_format(CamelMimeDisposition *d)
+{
+ GString *out;
+ char *ret;
+
+ if (d==NULL)
+ return NULL;
+
+ out = g_string_new("");
+ if (d->disposition)
+ g_string_append(out, d->disposition);
+ else
+ g_string_append(out, "attachment");
+ header_param_list_format_append(out, d->params);
+
+ ret = out->str;
+ g_string_free(out, FALSE);
+ return ret;
+}
+
/* hrm, is there a library for this shit? */
static struct {
char *name;
@@ -1583,7 +1661,7 @@ header_decode_date(const char *in, int *saveoffset)
header_decode_lwsp(&inptr);
if (!isdigit(*inptr)) {
- char *day = header_decode_token(&inptr);
+ char *day = decode_token(&inptr);
/* we dont really care about the day, its only for display */
if (day) {
d(printf("got day: %s\n", day));
@@ -1596,7 +1674,7 @@ header_decode_date(const char *in, int *saveoffset)
}
}
tm.tm_mday = header_decode_int(&inptr);
- monthname = header_decode_token(&inptr);
+ monthname = decode_token(&inptr);
if (monthname) {
for (i=0;i<sizeof(tz_months)/sizeof(tz_months[0]);i++) {
if (!strcasecmp(tz_months[i], monthname)) {
@@ -1632,7 +1710,7 @@ header_decode_date(const char *in, int *saveoffset)
offset = header_decode_int(&inptr);
d(printf("abs offset = %d\n", offset));
} else {
- char *tz = header_decode_token(&inptr);
+ char *tz = decode_token(&inptr);
if (tz) {
for (i=0;i<sizeof(tz_offsets)/sizeof(tz_offsets[0]);i++) {
@@ -1792,6 +1870,20 @@ header_raw_find(struct _header_raw **list, const char *name, int *offset)
return NULL;
}
+const char *
+header_raw_find_next(struct _header_raw **list, const char *name, int *offset, const char *last)
+{
+ struct _header_raw *l;
+
+ if (last == NULL || name == NULL)
+ return NULL;
+
+ l = *list;
+ while (l && l->value != last)
+ l = l->next;
+ return header_raw_find(&l, name, offset);
+}
+
static void
header_raw_free(struct _header_raw *l)
{