support.
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[];
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.
*/
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 ();
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);
}
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 ();
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);
}
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;
/* 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;
ENC8BIT,
ENCQUOTEDPRINTABLE,
ENCBASE64,
- ENCBINARY
+ ENCBINARY,
+ ENCUUENCODED
};
/* Content-Disposition values */
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);
}
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;
char *p, boundary[SHORT_STRING];
FILE *fpin;
BODY *t;
+ char *r;
if (a->type == TYPEMULTIPART)
{
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);