aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog12
-rw-r--r--camel/camel-mime-filter-basic.c62
-rw-r--r--camel/camel-mime-filter-basic.h3
-rw-r--r--camel/camel-mime-part-utils.c8
-rw-r--r--camel/camel-mime-part.c46
-rw-r--r--camel/camel-mime-part.h1
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;