+
+ 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, str_len (tmp));
+ break;
+ case 'p':
+ snprintf (tmp, sizeof (tmp), "%u", (unsigned int) getpid ());
+ str_ncat (buf, len, tmp, str_len (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, str_len (tmp));
+ break;
+ case 'R':
+ snprintf (tmp, sizeof (tmp), "%x", (unsigned int) rand ());
+ str_ncat (buf, len, tmp, str_len (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, str_len (tmp));
+ break;
+ case 'X':
+ snprintf (tmp, sizeof (tmp), "%x", (unsigned int) now);
+ str_ncat (buf, len, tmp, str_len (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;
+
+ c = mutt_normalized_char (*fmt); /* @todo: filter out invalid characters */
+ str_ncat (buf, len, &c, 1);
+ }
+ }
+}
+
+char *mutt_gen_msgid (void)
+{
+ char buf[SHORT_STRING];
+ char localpart[SHORT_STRING];
+ unsigned int localpart_length;
+ const char *fqdn;
+
+ if (!(fqdn = mutt_fqdn (0)))
+ fqdn = NONULL (Hostname);
+
+ localpart_length = sizeof (buf) - str_len (fqdn) - 4; /* the 4 characters are '<', '@', '>' and '\0' */
+
+ mutt_gen_localpart (localpart, localpart_length, MsgIdFormat);
+
+ snprintf (buf, sizeof (buf), "<%s@%s>", localpart, fqdn);
+ return (str_dup (buf));