drop str_[n]cat.
[apps/madmutt.git] / sendlib.c
index a07b87d..0f17bf8 100644 (file)
--- a/sendlib.c
+++ b/sendlib.c
@@ -1690,90 +1690,91 @@ static char mutt_normalized_char (char c)
   return '.';                   /* normalized character (we're stricter than RFC2822, 3.6.4) */
 }
 
-static void mutt_gen_localpart (char *buf, unsigned int len, char *fmt)
+static void mutt_gen_localpart(char *buf, unsigned int len, char *fmt)
 {
-  time_t now;
-  struct tm *tm;
-  char tmp[SHORT_STRING];
+    time_t now;
+    struct tm *tm;
+    int snlen;
 
-  *buf = '\0';
+    *buf = '\0';
 
-  now = time (NULL);
-  tm = gmtime (&now);
+    now = time (NULL);
+    tm = gmtime (&now);
 
-  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;
+    for (; *fmt; ++fmt) {
+#define APPEND_FMT(fmt, ...) \
+        if (len > 0) {                                             \
+            snlen = snprintf(buf, len, fmt, ##__VA_ARGS__);        \
+            buf += snlen;                                          \
+            len -= snlen;                                          \
+        }
 
-      c = mutt_normalized_char (*fmt);  /* @todo: filter out invalid characters */
-      str_ncat (buf, len, &c, 1);
+#define APPEND_BYTE(c) \
+        if (len > 1) {                                             \
+            *buf++ = c;                                            \
+            *buf   = '\0';                                         \
+            len--;                                                 \
+        }
+
+        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));
+        }
+
+#undef APPEND_BYTE
+#undef APPEND_FMT
     }
-  }
 }
 
 char *mutt_gen_msgid (void)