#include <lib-lib/ascii.h>
#include <lib-lib/str.h>
#include <lib-lib/macros.h>
+#include <lib-lib/file.h>
#include "mutt.h"
#include "handler.h"
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);
}
/* 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;
}
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++;
}
}
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);
/* 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;
}
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);
CONTENT_STATE state;
FILE *fp = NULL;
char *fromcode = NULL;
- char *tocode;
+ char *tocode = NULL;
char buffer[100];
char chsbuf[STRING];
size_t r;
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));
*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) {
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;
}
if (p)
mutt_canonical_charset (d, dlen, NONULL (p));
else
- strfcpy (d, "us-ascii", dlen);
+ m_strcpy(d, dlen, "us-ascii");
return d;
}
/* 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. */
continue;
i = p - h->data;
- ++p;
- SKIPWS (p);
+ p = vskipspaces(p + 1);
tmp = m_strdup(p);
if (!tmp)
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)