From: Thomas Roessler Date: Wed, 14 Oct 1998 22:34:11 +0000 (+0000) Subject: Thinking about this once again, ok folks, here comes x-uuencode X-Git-Tag: mutt-0-94-13-rel~12 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0198e1dc80eb3d9b7b93934d6f9369ac513284da;p=mutt Thinking about this once again, ok folks, here comes x-uuencode support. --- diff --git a/globals.h b/globals.h index bd1cebc6..f0c73be9 100644 --- a/globals.h +++ b/globals.h @@ -130,7 +130,7 @@ 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" }; +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/handler.c b/handler.c index 8c10d4c8..263bfa4c 100644 --- a/handler.c +++ b/handler.c @@ -289,6 +289,52 @@ void mutt_decode_base64 (STATE *s, BODY *b, int istext) state_reset_prefix(s); } +unsigned char decode_byte (char ch) +{ + if (ch == 96) + return 0; + return ch - 32; +} + +void mutt_decode_uuencoded (STATE *s, long len, int istext) +{ + char tmps[SHORT_STRING]; + char linelen, c, l, out; + char *pt; + + FOREVER + { + if ((fgets(tmps, sizeof(tmps), s->fpin)) == NULL) + return; + if ((!strncmp (tmps, "begin", 5)) && isspace (tmps[5])) + break; + } + FOREVER + { + if ((fgets(tmps, sizeof(tmps), s->fpin)) == NULL) + return; + if (!strncmp (tmps, "end", 3)) + break; + pt = tmps; + linelen = decode_byte (*pt); + pt++; + for (c = 0; c < linelen;) + { + for (l = 2; l <= 6; l += 2) + { + out = decode_byte (*pt) << l; + pt++; + out |= (decode_byte (*pt) >> (6 - l)); + state_putc(out, s); + c++; + if (c == linelen) + break; + } + pt++; + } + } +} + /* ---------------------------------------------------------------------------- * A (not so) minimal implementation of RFC1563. */ @@ -892,7 +938,8 @@ void message_handler (BODY *a, STATE *s) long off_start; off_start = ftell (s->fpin); - if (a->encoding == ENCBASE64 || a->encoding == ENCQUOTEDPRINTABLE) + if (a->encoding == ENCBASE64 || a->encoding == ENCQUOTEDPRINTABLE || + a->encoding == ENCUUENCODED) { fstat (fileno (s->fpin), &st); b = mutt_new_body (); @@ -915,7 +962,8 @@ void message_handler (BODY *a, STATE *s) mutt_body_handler (b->parts, s); } - if (a->encoding == ENCBASE64 || a->encoding == ENCQUOTEDPRINTABLE) + if (a->encoding == ENCBASE64 || a->encoding == ENCQUOTEDPRINTABLE || + a->encoding == ENCUUENCODED) mutt_free_body (&b); } @@ -979,7 +1027,8 @@ void multipart_handler (BODY *a, STATE *s) struct stat st; int count; - if (a->encoding == ENCBASE64 || a->encoding == ENCQUOTEDPRINTABLE) + if (a->encoding == ENCBASE64 || a->encoding == ENCQUOTEDPRINTABLE || + a->encoding == ENCUUENCODED) { fstat (fileno (s->fpin), &st); b = mutt_new_body (); @@ -1037,7 +1086,8 @@ void multipart_handler (BODY *a, STATE *s) state_putc ('\n', s); } - if (a->encoding == ENCBASE64 || a->encoding == ENCQUOTEDPRINTABLE) + if (a->encoding == ENCBASE64 || a->encoding == ENCQUOTEDPRINTABLE || + a->encoding == ENCUUENCODED) mutt_free_body (&b); } @@ -1173,6 +1223,9 @@ void mutt_decode_attachment (BODY *b, STATE *s) case ENCBASE64: mutt_decode_base64 (s, b, mutt_is_text_type (b->type, b->subtype)); break; + case ENCUUENCODED: + mutt_decode_uuencoded (s, b->length, mutt_is_text_type (b->type, b->subtype)); + break; default: mutt_decode_xbit (s, b, mutt_is_text_type (b->type, b->subtype)); break; @@ -1286,7 +1339,7 @@ void mutt_body_handler (BODY *b, STATE *s) /* see if we need to decode this part before processing it */ if (b->encoding == ENCBASE64 || b->encoding == ENCQUOTEDPRINTABLE || - plaintext) + b->encoding == ENCUUENCODED || plaintext) { int origType = b->type; char *savePrefix = NULL; diff --git a/mime.h b/mime.h index 907f91fa..1484bae3 100644 --- a/mime.h +++ b/mime.h @@ -39,7 +39,8 @@ enum ENC8BIT, ENCQUOTEDPRINTABLE, ENCBASE64, - ENCBINARY + ENCBINARY, + ENCUUENCODED }; /* Content-Disposition values */ diff --git a/parse.c b/parse.c index 63e57921..b3558e93 100644 --- a/parse.c +++ b/parse.c @@ -126,6 +126,8 @@ int mutt_check_encoding (const char *c) return (ENCQUOTEDPRINTABLE); else if (strncasecmp ("base64", c, sizeof("base64")-1) == 0) return (ENCBASE64); + else if (strncasecmp ("x-uuencode", c, sizeof("x-uuencode")-1) == 0) + return (ENCUUENCODED); else return (ENCOTHER); } diff --git a/sendlib.c b/sendlib.c index c88b3712..8bf1917f 100644 --- a/sendlib.c +++ b/sendlib.c @@ -315,6 +315,65 @@ static void encode_base64 (FILE * fin, FILE *fout, int istext) fputc('\n', fout); } +#define UUENC(c) ((c) ? ((c) & 077) + ' ' : '`') + +static void encode_uuenc (FILE * fin, FILE * fout) +{ + register int ch, linelen; + register unsigned char *p; + unsigned char line[80]; + + while ((linelen = fread(line, 1, 45, fin))) + { + ch = UUENC(linelen); + fputc (ch, fout); + + for (p = line; linelen>0; linelen -= 3, p += 3) + { + ch = *p >> 2; + ch = UUENC(ch); + fputc(ch, fout); + + if (linelen>1) + { + ch = ((*p & 0x3) << 4) | (p[1] >> 4); + ch = UUENC(ch); + fputc(ch, fout); + } + else + { + ch = (*p & 0x3) << 4; + ch = UUENC(ch); + fputc(ch, fout); + break; + } + + if (linelen>2) + { + ch = ((p[1] & 0xf) << 2) | (p[2] >> 6); + ch = UUENC(ch); + fputc(ch, fout); + } + else + { + ch = (p[1] & 0xf) << 2; + ch = UUENC(ch); + fputc(ch, fout); + break; + } + + ch = p[2] & 0x3f; + ch = UUENC(ch); + fputc(ch, fout); + } + + fputc('\n', fout); + } + ch = UUENC('\0'); + fputc(ch, fout); + fputc('\n', fout); +} + int mutt_write_mime_header (BODY *a, FILE *f) { PARAMETER *p; @@ -399,6 +458,7 @@ int mutt_write_mime_body (BODY *a, FILE *f) char *p, boundary[SHORT_STRING]; FILE *fpin; BODY *t; + char *r; if (a->type == TYPEMULTIPART) { @@ -448,6 +508,17 @@ int mutt_write_mime_body (BODY *a, FILE *f) encode_quoted (fpin, f, mutt_is_text_type (a->type, a->subtype)); else if (a->encoding == ENCBASE64) encode_base64 (fpin, f, mutt_is_text_type (a->type, a->subtype)); + else if (a->encoding == ENCUUENCODED) + { + /* Strip off the leading path... */ + if ((r = strrchr (a->filename, '/'))) + r++; + else + r = a->filename; + fprintf (f, "begin 600 %s\n", r); + encode_uuenc (fpin, f); + fprintf (f, "end\n"); + } else mutt_copy_stream (fpin, f); fclose (fpin);