move rfc822.c as well
[apps/madmutt.git] / sendlib.c
index 0f17bf8..208b434 100644 (file)
--- a/sendlib.c
+++ b/sendlib.c
 #include <lib-lib/macros.h>
 #include <lib-lib/file.h>
 
+#include <lib-mime/mime.h>
+
 #include "mutt.h"
 #include "handler.h"
 #include "recvattach.h"
 #include "mutt_curses.h"
 #include "rfc2047.h"
-#include "rfc2231.h"
 #include "mx.h"
-#include "mime.h"
 #include "copy.h"
 #include "pager.h"
 #include "charset.h"
 #include <assert.h>
 #endif
 
-extern char RFC822Specials[];
-
 #define DISPOSITION(X) X==DISPATTACH?"attachment":"inline"
 
-const char MimeSpecials[] = "@.,;:<>[]\\\"()?/= \t";
-
-char B64Chars[64] = {
-  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
-  'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
-  'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
-  't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
-  '8', '9', '+', '/'
-};
-
 static char MsgIdPfx = 'A';
 
 static void transform_to_7bit (BODY * a, FILE * fpin);
@@ -121,16 +109,16 @@ static void encode_quoted (FGETCONV * fc, FILE * fout, int istext)
     }
 
     /* Escape lines that begin with/only contain "the message separator". */
-    if (linelen == 4 && !str_ncmp ("From", line, 4)) {
-      strfcpy (line, "=46rom", sizeof (line));
+    if (linelen == 4 && !m_strncmp("From", line, 4)) {
+      m_strcpy(line, sizeof(line), "=46rom");
       linelen = 6;
     }
-    else if (linelen == 4 && !str_ncmp ("from", line, 4)) {
-      strfcpy (line, "=66rom", sizeof (line));
+    else if (linelen == 4 && !m_strncmp("from", line, 4)) {
+      m_strcpy(line, sizeof(line), "=66rom");
       linelen = 6;
     }
     else if (linelen == 1 && line[0] == '.') {
-      strfcpy (line, "=2E", sizeof (line));
+      m_strcpy(line, sizeof(line), "=2E");
       linelen = 3;
     }
 
@@ -223,19 +211,19 @@ static void b64_flush (FILE * fout)
   for (i = b64_num; i < 3; i++)
     b64_buffer[i] = '\0';
 
-  fputc (B64Chars[(b64_buffer[0] >> 2) & 0x3f], fout);
+  fputc(__m_b64chars[(b64_buffer[0] >> 2) & 0x3f], fout);
   b64_linelen++;
-  fputc (B64Chars
+  fputc(__m_b64chars
          [((b64_buffer[0] & 0x3) << 4) | ((b64_buffer[1] >> 4) & 0xf)], fout);
   b64_linelen++;
 
   if (b64_num > 1) {
-    fputc (B64Chars
+    fputc (__m_b64chars
            [((b64_buffer[1] & 0xf) << 2) | ((b64_buffer[2] >> 6) & 0x3)],
            fout);
     b64_linelen++;
     if (b64_num > 2) {
-      fputc (B64Chars[b64_buffer[2] & 0x3f], fout);
+      fputc (__m_b64chars[b64_buffer[2] & 0x3f], fout);
       b64_linelen++;
     }
   }
@@ -396,7 +384,7 @@ int mutt_write_mime_body (BODY * a, FILE * f)
 
       return (-1);
     }
-    strfcpy (boundary, p, sizeof (boundary));
+    m_strcpy(boundary, sizeof(boundary), p);
 
     for (t = a->parts; t; t = t->next) {
       fprintf (f, "\n--%s\n", boundary);
@@ -457,7 +445,7 @@ void mutt_generate_boundary (PARAMETER ** parm)
 
   rs[BOUNDARYLEN] = 0;
   for (i = 0; i < BOUNDARYLEN; i++)
-    *p++ = B64Chars[LRAND () % sizeof (B64Chars)];
+    *p++ = __m_b64chars[LRAND() % sizeof(__m_b64chars)];
   *p = 0;
 
   mutt_set_parameter ("boundary", rs, parm);
@@ -808,7 +796,7 @@ CONTENT *mutt_get_content_info (const char *fname, BODY * b)
   CONTENT_STATE state;
   FILE *fp = NULL;
   char *fromcode = NULL;
-  char *tocode;
+  char *tocode = NULL;
   char buffer[100];
   char chsbuf[STRING];
   size_t r;
@@ -904,13 +892,13 @@ int mutt_lookup_mime_type (BODY * att, const char *path)
       snprintf (buf, sizeof (buf), "%s/.mime.types", NONULL (Homedir));
       break;
     case 1:
-      strfcpy (buf, SYSCONFDIR "/muttng-mime.types", sizeof (buf));
+      m_strcpy(buf, sizeof(buf), SYSCONFDIR "/muttng-mime.types");
       break;
     case 2:
-      strfcpy (buf, PKGDATADIR "/mime.types", sizeof (buf));
+      m_strcpy(buf, sizeof(buf), PKGDATADIR "/mime.types");
       break;
     case 3:
-      strfcpy (buf, SYSCONFDIR "/mime.types", sizeof (buf));
+      m_strcpy(buf, sizeof(buf), SYSCONFDIR "/mime.types");
       break;
     default:
       debug_print (1, ("Internal error, count = %d.\n", count));
@@ -924,27 +912,22 @@ int mutt_lookup_mime_type (BODY * att, const char *path)
           *p = 0;
 
         /* remove any leading space. */
-        ct = buf;
-        SKIPWS (ct);
+        ct = vskipspaces(buf);
 
         /* position on the next field in this line */
         if ((p = strpbrk (ct, " \t")) == NULL)
           continue;
         *p++ = 0;
-        SKIPWS (p);
+        p = vskipspaces(p);
 
         /* cycle through the file extensions */
         while ((p = strtok (p, " \t\n"))) {
           sze = m_strlen(p);
           if ((sze > cur_sze) && (szf >= sze) &&
-              (str_casecmp (path + szf - sze, p) == 0
-               || ascii_strcasecmp (path + szf - sze, p) == 0) && (szf == sze
-                                                                   || path[szf
-                                                                           -
-                                                                           sze
-                                                                           -
-                                                                           1]
-                                                                   == '.')) {
+              (m_strcasecmp(path + szf - sze, p) == 0
+               || ascii_strcasecmp (path + szf - sze, p) == 0)
+              && (szf == sze || path[szf - sze - 1] == '.'))
+          {
             /* get the content-type */
 
             if ((p = strchr (ct, '/')) == NULL) {
@@ -958,7 +941,7 @@ int mutt_lookup_mime_type (BODY * att, const char *path)
             str_substrcpy (subtype, p, q, sizeof (subtype));
 
             if ((type = mutt_check_mime_type (ct)) == TYPEOTHER)
-              strfcpy (xtype, ct, sizeof (xtype));
+              m_strcpy(xtype, sizeof(xtype), ct);
 
             cur_sze = sze;
           }
@@ -1162,7 +1145,7 @@ char *mutt_get_body_charset (char *d, size_t dlen, BODY * b)
   if (p)
     mutt_canonical_charset (d, dlen, NONULL (p));
   else
-    strfcpy (d, "us-ascii", dlen);
+    m_strcpy(d, dlen, "us-ascii");
 
   return d;
 }
@@ -1596,8 +1579,7 @@ int mutt_write_rfc822_header (FILE * fp, ENVELOPE * env, BODY * attach,
   /* Add any user defined headers */
   for (; tmp; tmp = tmp->next) {
     if ((p = strchr (tmp->data, ':'))) {
-      p++;
-      SKIPWS (p);
+      p = vskipspaces(p + 1);
       if (!*p)
         continue;               /* don't emit empty fields. */
 
@@ -1642,8 +1624,7 @@ static void encode_headers (LIST * h)
       continue;
 
     i = p - h->data;
-    ++p;
-    SKIPWS (p);
+    p = vskipspaces(p + 1);
     tmp = m_strdup(p);
 
     if (!tmp)
@@ -1681,100 +1662,98 @@ const char *mutt_fqdn (short may_hide_host)
   return p;
 }
 
-static char mutt_normalized_char (char c)
+/* normalized character (we're stricter than RFC2822, 3.6.4) */
+static char mutt_normalized_char(char c)
 {
-  if (isalnum (c))
-    return c;
-  if (strchr (".!#$%&'*+-/=?^_`{|}~", c))
-    return c;
-  return '.';                   /* normalized character (we're stricter than RFC2822, 3.6.4) */
+    return (isalnum(c) || strchr(".!#$%&'*+-/=?^_`{|}~", c)) ? c : '.';
 }
 
-static void mutt_gen_localpart(char *buf, unsigned int len, char *fmt)
+static void mutt_gen_localpart(char *buf, unsigned int len, const char *fmt)
 {
+#define APPEND_FMT(fmt, arg) \
+        if (len > 1) {                                  \
+            int snlen = snprintf(buf, len, fmt, arg);   \
+            buf += snlen;                               \
+            len -= snlen;                               \
+        }
+
+#define APPEND_BYTE(c) \
+        if (len > 1) {                                  \
+            *buf++ = c;                                 \
+            *buf   = '\0';                              \
+            len--;                                      \
+        }
+
     time_t now;
     struct tm *tm;
-    int snlen;
-
-    *buf = '\0';
 
     now = time (NULL);
     tm = gmtime (&now);
 
-    for (; *fmt; ++fmt) {
-#define APPEND_FMT(fmt, ...) \
-        if (len > 0) {                                             \
-            snlen = snprintf(buf, len, fmt, ##__VA_ARGS__);        \
-            buf += snlen;                                          \
-            len -= snlen;                                          \
-        }
+    while (*fmt) {
+        int c = *fmt++;
 
-#define APPEND_BYTE(c) \
-        if (len > 1) {                                             \
-            *buf++ = c;                                            \
-            *buf   = '\0';                                         \
-            len--;                                                 \
+        if (c != '%') {
+            APPEND_BYTE(mutt_normalized_char(c));
+            continue;
         }
 
-        if (*fmt == '%') {
-            switch (fmt[1]) {
-              case 0:
-                return;
-              case 'd':
-                APPEND_FMT("%02d", tm->tm_mday);
-                break;
-              case 'h':
-                APPEND_FMT("%02d", tm->tm_hour);
-                break;
-              case 'm':
-                APPEND_FMT("%02d", tm->tm_mon + 1);
-                break;
-              case 'M':
-                APPEND_FMT("%02d", tm->tm_min);
-                break;
-              case 'O':
-                APPEND_FMT("%lo", (unsigned long)now);
-                break;
-              case 'p':
-                APPEND_FMT("%u", (unsigned int)getpid());
-                break;
-              case 'P':
-                APPEND_FMT("%c", MsgIdPfx);
-                MsgIdPfx = (MsgIdPfx == 'Z') ? 'A' : MsgIdPfx + 1;
-                break;
-              case 'r':
-                APPEND_FMT("%u", (unsigned int)rand());
-                break;
-              case 'R':
-                APPEND_FMT("%x", (unsigned int)rand());
-                break;
-              case 's':
-                APPEND_FMT("%02d", tm->tm_sec);
-                break;
-              case 'T':
-                APPEND_FMT("%u", (unsigned int) now);
-                break;
-              case 'X':
-                APPEND_FMT("%x", (unsigned int) now);
-                break;
-              case 'Y':       /* this will break in the year 10000 ;-) */
-                APPEND_FMT("%04d", tm->tm_year + 1900);
-                break;
-              case '%':
-                APPEND_BYTE('%');
-                break;
-              default:       /* invalid formats are replaced by '.' */
-                APPEND_BYTE('.');
-                m_strncat(buf, len, ".", 1); 
-            }
-            ++fmt;
-        } else {
-            APPEND_BYTE(mutt_normalized_char(*fmt));
+        switch (*fmt++) {
+          case 0:
+            return;
+          case 'd':
+            APPEND_FMT("%02d", tm->tm_mday);
+            break;
+          case 'h':
+            APPEND_FMT("%02d", tm->tm_hour);
+            break;
+          case 'm':
+            APPEND_FMT("%02d", tm->tm_mon + 1);
+            break;
+          case 'M':
+            APPEND_FMT("%02d", tm->tm_min);
+            break;
+          case 'O':
+            APPEND_FMT("%lo", (unsigned long)now);
+            break;
+          case 'p':
+            APPEND_FMT("%u", (unsigned int)getpid());
+            break;
+          case 'P':
+            APPEND_FMT("%c", MsgIdPfx);
+            MsgIdPfx = (MsgIdPfx == 'Z') ? 'A' : MsgIdPfx + 1;
+            break;
+          case 'r':
+            APPEND_FMT("%u", (unsigned int)rand());
+            break;
+          case 'R':
+            APPEND_FMT("%x", (unsigned int)rand());
+            break;
+          case 's':
+            APPEND_FMT("%02d", tm->tm_sec);
+            break;
+          case 'T':
+            APPEND_FMT("%u", (unsigned int) now);
+            break;
+          case 'X':
+            APPEND_FMT("%x", (unsigned int) now);
+            break;
+          case 'Y':       /* this will break in the year 10000 ;-) */
+            APPEND_FMT("%04d", tm->tm_year + 1900);
+            break;
+          case '%':
+            APPEND_BYTE('%');
+            break;
+          default:       /* invalid formats are replaced by '.' */
+            APPEND_BYTE('.');
+            m_strncat(buf, len, ".", 1); 
         }
+    }
+
+    *buf = '\0';
 
 #undef APPEND_BYTE
 #undef APPEND_FMT
-    }
 }
 
 char *mutt_gen_msgid (void)