diff options
Diffstat (limited to 'camel')
-rw-r--r-- | camel/ChangeLog | 12 | ||||
-rw-r--r-- | camel/camel-mime-filter-basic.c | 62 | ||||
-rw-r--r-- | camel/camel-mime-filter-basic.h | 3 | ||||
-rw-r--r-- | camel/camel-mime-part-utils.c | 8 | ||||
-rw-r--r-- | camel/camel-mime-part.c | 46 | ||||
-rw-r--r-- | camel/camel-mime-part.h | 1 |
6 files changed, 108 insertions, 24 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index eaf1edd0c1..6d4cc473e3 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,15 @@ +2001-11-26 Jeffrey Stedfast <fejj@ximian.com> + + * camel-mime-filter-basic.c: For the uudecoding mode, garble up + the "begin <mode> <filename>" line before decoding. + + * camel-mime-part-utils.c + (simple_data_wrapper_construct_from_parser): Add a uudecoder if + the transfer encoding is x-uuencode. + + * camel-mime-part.c (write_to_stream): Handle x-uuencoded content + too. + 2001-11-19 Jeffrey Stedfast <fejj@ximian.com> * camel-tcp-stream-ssl.c (stream_read): Added a check to see if diff --git a/camel/camel-mime-filter-basic.c b/camel/camel-mime-filter-basic.c index b1edd06f4b..ff21ad9609 100644 --- a/camel/camel-mime-filter-basic.c +++ b/camel/camel-mime-filter-basic.c @@ -21,6 +21,7 @@ #include "camel-mime-filter-basic.h" #include "camel-mime-utils.h" +#include <string.h> static void reset(CamelMimeFilter *mf); static void complete(CamelMimeFilter *mf, char *in, size_t len, @@ -78,7 +79,9 @@ static void reset(CamelMimeFilter *mf) { CamelMimeFilterBasic *f = (CamelMimeFilterBasic *)mf; - + + f->uu_begin = FALSE; + switch(f->type) { case CAMEL_MIME_FILTER_BASIC_QP_ENC: f->state = -1; @@ -94,7 +97,7 @@ complete(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out, { CamelMimeFilterBasic *f = (CamelMimeFilterBasic *)mf; int newlen; - + switch(f->type) { case CAMEL_MIME_FILTER_BASIC_BASE64_ENC: /* wont go to more than 2x size (overly conservative) */ @@ -128,9 +131,13 @@ complete(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out, g_assert(newlen <= len+2); break; case CAMEL_MIME_FILTER_BASIC_UU_DEC: - /* output can't possibly exceed the input size */ - camel_mime_filter_set_size (mf, len, FALSE); - newlen = uudecode_step (in, len, mf->outbuf, &f->state, &f->save, &f->uulen); + if (f->uu_begin) { + /* "begin <mode> <filename>\n" has been found, so we can now start decoding */ + camel_mime_filter_set_size (mf, len + 3, FALSE); + newlen = uudecode_step (in, len, mf->outbuf, &f->state, &f->save, &f->uulen); + } else { + newlen = 0; + } break; default: g_warning("unknown type %d in CamelMimeFilterBasic", f->type); @@ -186,9 +193,48 @@ filter(CamelMimeFilter *mf, char *in, size_t len, size_t prespace, char **out, s g_assert(newlen <= len); break; case CAMEL_MIME_FILTER_BASIC_UU_DEC: - /* output can't possibly exceed the input size */ - camel_mime_filter_set_size (mf, len, FALSE); - newlen = uudecode_step (in, len, mf->outbuf, &f->state, &f->save, &f->uulen); + if (!f->uu_begin) { + register char *inptr, *inend; + size_t left; + + inptr = in; + inend = inptr + len; + + while (inptr < inend) { + left = inend - inptr; + if (left < 6) { + if (!strncmp (inptr, "begin ", left)) + camel_mime_filter_backup (mf, inptr, left); + break; + } else if (!strncmp (inptr, "begin ", 6)) { + for (in = inptr; inptr < inend && *inptr != '\n'; inptr++); + if (inptr < inend) { + inptr++; + f->uu_begin = TRUE; + /* we can start uudecoding... */ + in = inptr; + len = inend - in; + } else { + camel_mime_filter_backup (mf, in, left); + } + break; + } + + /* go to the next line */ + for (inptr++; inptr < inend && *inptr != '\n'; inptr++); + + if (inptr < inend) + inptr++; + } + } + + if (f->uu_begin) { + /* "begin <mode> <filename>\n" has been found, so we can now start decoding */ + camel_mime_filter_set_size (mf, len + 3, FALSE); + newlen = uudecode_step (in, len, mf->outbuf, &f->state, &f->save, &f->uulen); + } else { + newlen = 0; + } break; default: g_warning("unknown type %d in CamelMimeFilterBasic", f->type); diff --git a/camel/camel-mime-filter-basic.h b/camel/camel-mime-filter-basic.h index 4bb248303f..939da6c190 100644 --- a/camel/camel-mime-filter-basic.h +++ b/camel/camel-mime-filter-basic.h @@ -44,7 +44,8 @@ struct _CamelMimeFilterBasic { struct _CamelMimeFilterBasicPrivate *priv; CamelMimeFilterBasicType type; - + + gboolean uu_begin; unsigned char uubuf[60]; int state; int save; diff --git a/camel/camel-mime-part-utils.c b/camel/camel-mime-part-utils.c index 3bad8de1b6..131667e696 100644 --- a/camel/camel-mime-part-utils.c +++ b/camel/camel-mime-part-utils.c @@ -97,7 +97,8 @@ check_html_charset(char *buffer, int length) return charset; } -static GByteArray *convert_buffer(GByteArray *in, const char *to, const char *from) +static GByteArray * +convert_buffer (GByteArray *in, const char *to, const char *from) { iconv_t ic; int inlen, outlen, i=2; @@ -189,9 +190,12 @@ simple_data_wrapper_construct_from_parser (CamelDataWrapper *dw, CamelMimeParser } else if (!strcasecmp(encoding, "quoted-printable")) { d(printf("Adding quoted-printable decoder ...\n")); enctype = CAMEL_MIME_FILTER_BASIC_QP_DEC; + } else if (!strcasecmp (encoding, "x-uuencode")) { + d(printf("Adding uudecoder ...\n")); + enctype = CAMEL_MIME_FILTER_BASIC_UU_DEC; } g_free (encoding); - + if (enctype != 0) { fdec = (CamelMimeFilter *)camel_mime_filter_basic_new_type(enctype); decid = camel_mime_parser_filter_add (mp, fdec); diff --git a/camel/camel-mime-part.c b/camel/camel-mime-part.c index 303fba6c7d..9a0f1b83eb 100644 --- a/camel/camel-mime-part.c +++ b/camel/camel-mime-part.c @@ -545,6 +545,7 @@ write_to_stream(CamelDataWrapper *data_wrapper, CamelStream *stream) { CamelMimePart *mp = CAMEL_MIME_PART(data_wrapper); CamelMedium *medium = CAMEL_MEDIUM(data_wrapper); + CamelStream *ostream = stream; CamelDataWrapper *content; int total = 0; int count; @@ -556,11 +557,11 @@ write_to_stream(CamelDataWrapper *data_wrapper, CamelStream *stream) #ifndef NO_WARNINGS #warning content-languages should be stored as a header #endif - + if (mp->headers) { struct _header_raw *h = mp->headers; char *val; - + /* fold/write the headers. But dont fold headers that are already formatted (e.g. ones with parameter-lists, that we know about, and have created) */ while (h) { @@ -581,12 +582,12 @@ write_to_stream(CamelDataWrapper *data_wrapper, CamelStream *stream) h = h->next; } } - + count = camel_stream_write(stream, "\n", 1); if (count == -1) return -1; total += count; - + content = camel_medium_get_content_object(medium); if (content) { /* I dont really like this here, but i dont know where else it might go ... */ @@ -595,15 +596,24 @@ write_to_stream(CamelDataWrapper *data_wrapper, CamelStream *stream) CamelMimeFilter *filter = NULL; CamelStreamFilter *filter_stream = NULL; CamelMimeFilter *charenc = NULL; + const char *filename; const char *charset; - - switch(mp->encoding) { + + switch (mp->encoding) { case CAMEL_MIME_PART_ENCODING_BASE64: filter = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_BASE64_ENC); break; case CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE: filter = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_QP_ENC); break; + case CAMEL_MIME_PART_ENCODING_UUENCODE: + filename = camel_mime_part_get_filename (mp); + count = camel_stream_printf (ostream, "begin 644 %s\n", filename ? filename : "untitled"); + if (count == -1) + return -1; + total += count; + filter = (CamelMimeFilter *)camel_mime_filter_basic_new_type(CAMEL_MIME_FILTER_BASIC_UU_ENC); + break; default: break; } @@ -617,33 +627,34 @@ write_to_stream(CamelDataWrapper *data_wrapper, CamelStream *stream) if (filter || charenc) { filter_stream = camel_stream_filter_new_with_stream(stream); - + /* if we have a character encoder, add that always */ if (charenc) { camel_stream_filter_add(filter_stream, charenc); camel_object_unref((CamelObject *)charenc); } - + /* we only re-do crlf on encoded blocks */ if (filter && header_content_type_is(mp->content_type, "text", "*")) { CamelMimeFilter *crlf = camel_mime_filter_crlf_new(CAMEL_MIME_FILTER_CRLF_ENCODE, CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY); - + camel_stream_filter_add(filter_stream, crlf); camel_object_unref((CamelObject *)crlf); - } - + if (filter) { camel_stream_filter_add(filter_stream, filter); camel_object_unref((CamelObject *)filter); } - + stream = (CamelStream *)filter_stream; } #endif + count = camel_data_wrapper_write_to_stream(content, stream); + if (filter_stream) { camel_stream_flush((CamelStream *)filter_stream); camel_object_unref((CamelObject *)filter_stream); @@ -651,9 +662,17 @@ write_to_stream(CamelDataWrapper *data_wrapper, CamelStream *stream) if (count == -1) return -1; total += count; + + if (mp->encoding == CAMEL_MIME_PART_ENCODING_UUENCODE) { + count = camel_stream_write (ostream, "end\n", 4); + if (count == -1) + return -1; + total += count; + } } else { g_warning("No content for medium, nothing to write"); } + return total; } @@ -750,7 +769,8 @@ static const char *encodings[] = { "8bit", "base64", "quoted-printable", - "binary" + "binary", + "x-uuencode", }; const char * diff --git a/camel/camel-mime-part.h b/camel/camel-mime-part.h index 785fecf9d9..4f05ecb71b 100644 --- a/camel/camel-mime-part.h +++ b/camel/camel-mime-part.h @@ -50,6 +50,7 @@ enum _CamelMimePartEncodingType { CAMEL_MIME_PART_ENCODING_BASE64, CAMEL_MIME_PART_ENCODING_QUOTEDPRINTABLE, CAMEL_MIME_PART_ENCODING_BINARY, + CAMEL_MIME_PART_ENCODING_UUENCODE, CAMEL_MIME_PART_NUM_ENCODINGS }; typedef enum _CamelMimePartEncodingType CamelMimePartEncodingType; |