make m_dupstr return NULL if the string was empty.
[apps/madmutt.git] / sendlib.c
index 60673be..a461354 100644 (file)
--- a/sendlib.c
+++ b/sendlib.c
 #endif
 
 #include <lib-lib/mem.h>
+#include <lib-lib/ascii.h>
 #include <lib-lib/str.h>
 #include <lib-lib/macros.h>
+#include <lib-lib/file.h>
 
 #include "mutt.h"
-#include "ascii.h"
 #include "handler.h"
 #include "recvattach.h"
 #include "mutt_curses.h"
@@ -412,7 +413,7 @@ int mutt_write_mime_body (BODY * a, FILE * f)
   /* This is pretty gross, but it's the best solution for now... */
   if ((WithCrypto & APPLICATION_PGP)
       && a->type == TYPEAPPLICATION
-      && str_cmp (a->subtype, "pgp-encrypted") == 0) {
+      && m_strcmp(a->subtype, "pgp-encrypted") == 0) {
     fputs ("Version: 1\n", f);
     return 0;
   }
@@ -807,7 +808,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;
@@ -833,7 +834,7 @@ CONTENT *mutt_get_content_info (const char *fname, BODY * b)
   }
 
   info = p_new(CONTENT, 1);
-  memset (&state, 0, sizeof (state));
+  p_clear(&state, 1);
 
   if (b != NULL && b->type == TYPETEXT && (!b->noconv && !b->force_charset)) {
     char *chs = mutt_get_parameter ("charset", b->parameter);
@@ -1052,7 +1053,7 @@ static void transform_to_7bit (BODY * a, FILE * fpin)
   STATE s;
   struct stat sb;
 
-  memset (&s, 0, sizeof (s));
+  p_clear(&s, 1);
   for (; a; a = a->next) {
     if (a->type == TYPEMULTIPART) {
       if (a->encoding != ENC7BIT)
@@ -1680,99 +1681,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)
 {
-  time_t now;
-  struct tm *tm;
-  char tmp[SHORT_STRING];
+#define APPEND_FMT(fmt, arg) \
+        if (len > 1) {                                  \
+            int snlen = snprintf(buf, len, fmt, arg);   \
+            buf += snlen;                               \
+            len -= snlen;                               \
+        }
 
-  *buf = '\0';
+#define APPEND_BYTE(c) \
+        if (len > 1) {                                  \
+            *buf++ = c;                                 \
+            *buf   = '\0';                              \
+            len--;                                      \
+        }
 
-  now = time (NULL);
-  tm = gmtime (&now);
+    time_t now;
+    struct tm *tm;
 
-  for (; *fmt; ++fmt) {
-    if (*fmt == '%') {
-      switch (fmt[1]) {
-      case 0:
-        return;
-      case 'd':
-        snprintf (tmp, sizeof (tmp), "%02d", tm->tm_mday);
-        str_ncat (buf, len, tmp, 2);
-        break;
-      case 'h':
-        snprintf (tmp, sizeof (tmp), "%02d", tm->tm_hour);
-        str_ncat (buf, len, tmp, 2);
-        break;
-      case 'm':
-        snprintf (tmp, sizeof (tmp), "%02d", tm->tm_mon + 1);
-        str_ncat (buf, len, tmp, 2);
-        break;
-      case 'M':
-        snprintf (tmp, sizeof (tmp), "%02d", tm->tm_min);
-        str_ncat (buf, len, tmp, 2);
-        break;
-      case 'O':
-        snprintf (tmp, sizeof (tmp), "%lo", (unsigned long) now);
-        str_ncat (buf, len, tmp, m_strlen(tmp));
-        break;
-      case 'p':
-        snprintf (tmp, sizeof (tmp), "%u", (unsigned int) getpid ());
-        str_ncat (buf, len, tmp, m_strlen(tmp));
-        break;
-      case 'P':
-        snprintf (tmp, sizeof (tmp), "%c", MsgIdPfx);
-        MsgIdPfx = (MsgIdPfx == 'Z') ? 'A' : MsgIdPfx + 1;
-        str_ncat (buf, len, tmp, 1);
-        break;
-      case 'r':
-        snprintf (tmp, sizeof (tmp), "%u", (unsigned int) rand ());
-        str_ncat (buf, len, tmp, m_strlen(tmp));
-        break;
-      case 'R':
-        snprintf (tmp, sizeof (tmp), "%x", (unsigned int) rand ());
-        str_ncat (buf, len, tmp, m_strlen(tmp));
-        break;
-      case 's':
-        snprintf (tmp, sizeof (tmp), "%02d", tm->tm_sec);
-        str_ncat (buf, len, tmp, 2);
-        break;
-      case 'T':
-        snprintf (tmp, sizeof (tmp), "%u", (unsigned int) now);
-        str_ncat (buf, len, tmp, m_strlen(tmp));
-        break;
-      case 'X':
-        snprintf (tmp, sizeof (tmp), "%x", (unsigned int) now);
-        str_ncat (buf, len, tmp, m_strlen(tmp));
-        break;
-      case 'Y':
-        snprintf (tmp, sizeof (tmp), "%04d", tm->tm_year + 1900);       /* this will break in the year 10000 ;-) */
-        str_ncat (buf, len, tmp, 4);
-        break;
-      case '%':
-        str_ncat (buf, len, "%", 1);
-        break;
-      default:
-        str_ncat (buf, len, ".", 1);        /* invalid formats are replaced by '.' */
-      }                         /* switch */
-      ++fmt;
-    }
-    else {
-      char c;
+    now = time (NULL);
+    tm = gmtime (&now);
+
+    while (*fmt) {
+        int c = *fmt++;
 
-      c = mutt_normalized_char (*fmt);  /* @todo: filter out invalid characters */
-      str_ncat (buf, len, &c, 1);
+        if (c != '%') {
+            APPEND_BYTE(mutt_normalized_char(c));
+            continue;
+        }
+
+        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)