]> granicus.if.org Git - neomutt/commitdiff
Thinking about this once again, ok folks, here comes x-uuencode
authorThomas Roessler <roessler@does-not-exist.org>
Wed, 14 Oct 1998 22:34:11 +0000 (22:34 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Wed, 14 Oct 1998 22:34:11 +0000 (22:34 +0000)
support.

globals.h
handler.c
mime.h
parse.c
sendlib.c

index bd1cebc6629bb802fbb4fa7db3cec9961529b979..f0c73be98f14904fec0bac65f6e2c23f86a34e99 100644 (file)
--- 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[];
index 8c10d4c81600e03b4fcfb2767bb61f9d12015e82..263bfa4c3d3aa213b44c2d36e42b902c4950e589 100644 (file)
--- 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 907f91fae376f88c0c7981c7d9ba7d5fa4bf2bb0..1484bae3f885e6ff3f43dd1cb3d6b4a85773d5c8 100644 (file)
--- 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 63e579212e37dc2c3eb2135f956b4982cb3a2d35..b3558e93a4664c738f3b2a1fc29d35baf8cc1838 100644 (file)
--- 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);
 }
index c88b3712b8cf8fb179c804968084bce6e57916f5..8bf1917fe892d487a9028a56290981227b0f6ef5 100644 (file)
--- 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);