move signal.c into lib/sys
[apps/madmutt.git] / sendlib.c
index 7c8ab2b..e911fed 100644 (file)
--- a/sendlib.c
+++ b/sendlib.c
 # include "config.h"
 #endif
 
-#include "mutt.h"
-#include "ascii.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 "mutt_crypt.h"
-#include "mutt_idna.h"
-
-#include "lib/mem.h"
-#include "lib/str.h"
-#include "lib/intl.h"
-#include "lib/debug.h"
-
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/utsname.h>
 
+#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 <lib-lib/debug.h>
+
+#include <lib-sys/exit.h>
+#include <lib-sys/mutt_signal.h>
+
+#include <lib-mime/mime.h>
+
+#include <lib-ui/curses.h>
+
+#include "mutt.h"
+#include "handler.h"
+#include "recvattach.h"
+#include "mx.h"
+#include "copy.h"
+#include "pager.h"
+#include "charset.h"
+#include <lib-crypt/crypt.h>
+#include "mutt_idna.h"
+
 #ifdef USE_LIBESMTP
 # include "mutt_libesmtp.h"
 #endif /* USE_LIBESMTP */
 #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);
@@ -119,16 +111,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;
     }
 
@@ -221,19 +213,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++;
     }
   }
@@ -294,7 +286,7 @@ int mutt_write_mime_header (BODY * a, FILE * f)
   fprintf (f, "Content-Type: %s/%s", TYPE (a), a->subtype);
 
   if (a->parameter) {
-    len = 25 + str_len (a->subtype);        /* approximate len. of content-type */
+    len = 25 + m_strlen(a->subtype);        /* approximate len. of content-type */
 
     for (p = a->parameter; p; p = p->next) {
       char *tmp;
@@ -305,9 +297,9 @@ int mutt_write_mime_header (BODY * a, FILE * f)
       fputc (';', f);
 
       buffer[0] = 0;
-      tmp = str_dup (p->value);
+      tmp = m_strdup(p->value);
       encode = rfc2231_encode_string (&tmp);
-      rfc822_cat (buffer, sizeof (buffer), tmp, MimeSpecials);
+      rfc822_strcpy(buffer, sizeof(buffer), tmp, MimeSpecials);
 
       /* Dirty hack to make messages readable by Outlook Express 
        * for the Mac: force quotes around the boundary parameter
@@ -318,9 +310,9 @@ int mutt_write_mime_header (BODY * a, FILE * f)
           && !strcmp (buffer, tmp))
         snprintf (buffer, sizeof (buffer), "\"%s\"", tmp);
 
-      mem_free (&tmp);
+      p_delete(&tmp);
 
-      tmplen = str_len (buffer) + str_len (p->attribute) + 1;
+      tmplen = m_strlen(buffer) + m_strlen(p->attribute) + 1;
 
       if (len + tmplen + 2 > 76) {
         fputs ("\n\t", f);
@@ -357,10 +349,10 @@ int mutt_write_mime_header (BODY * a, FILE * f)
         t = fn;
 
       buffer[0] = 0;
-      tmp = str_dup (t);
+      tmp = m_strdup(t);
       encode = rfc2231_encode_string (&tmp);
-      rfc822_cat (buffer, sizeof (buffer), tmp, MimeSpecials);
-      mem_free (&tmp);
+      rfc822_strcpy(buffer, sizeof(buffer), tmp, MimeSpecials);
+      p_delete(&tmp);
       fprintf (f, "; filename%s=%s", encode ? "*" : "", buffer);
     }
   }
@@ -374,9 +366,7 @@ int mutt_write_mime_header (BODY * a, FILE * f)
   return (ferror (f) ? -1 : 0);
 }
 
-# define write_as_text_part(a)  (mutt_is_text_part(a) \
-                                 || ((WithCrypto & APPLICATION_PGP)\
-                                      && mutt_is_application_pgp(a)))
+# define write_as_text_part(a)  (mutt_is_text_part(a) || mutt_is_application_pgp(a))
 
 int mutt_write_mime_body (BODY * a, FILE * f)
 {
@@ -394,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);
@@ -409,9 +399,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) {
+  if (a->type == TYPEAPPLICATION && !m_strcmp(a->subtype, "pgp-encrypted")) {
     fputs ("Version: 1\n", f);
     return 0;
   }
@@ -455,7 +443,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);
@@ -616,10 +604,10 @@ static size_t convert_file_to (FILE * file, const char *fromcode,
   if (cd1 == (iconv_t) (-1))
     return -1;
 
-  cd = mem_calloc (ncodes, sizeof (iconv_t));
-  score = mem_calloc (ncodes, sizeof (size_t));
-  states = mem_calloc (ncodes, sizeof (CONTENT_STATE));
-  infos = mem_calloc (ncodes, sizeof (CONTENT));
+  cd = p_new(iconv_t, ncodes);
+  score = p_new(size_t, ncodes);
+  states = p_new(CONTENT_STATE, ncodes);
+  infos = p_new(CONTENT, ncodes);
 
   for (i = 0; i < ncodes; i++)
     if (ascii_strcasecmp (tocodes[i], "UTF-8"))
@@ -709,10 +697,10 @@ static size_t convert_file_to (FILE * file, const char *fromcode,
       iconv_close (cd[i]);
 
   iconv_close (cd1);
-  mem_free (&cd);
-  mem_free (&infos);
-  mem_free (&score);
-  mem_free (&states);
+  p_delete(&cd);
+  p_delete(&infos);
+  p_delete(&score);
+  p_delete(&states);
 
   return ret;
 #else
@@ -751,11 +739,11 @@ static size_t convert_file_from_to (FILE * file,
   }
 
   /* Copy them */
-  tcode = mem_malloc (ncodes * sizeof (char *));
+  tcode = p_new(char *, ncodes);
   for (c = tocodes, i = 0; c; c = c1 ? c1 + 1 : 0, i++) {
     if ((c1 = strchr (c, ':')) == c)
       continue;
-    tcode[i] = str_substrdup (c, c1);
+    tcode[i] = m_substrdup(c, c1);
   }
 
   ret = (size_t) (-1);
@@ -764,7 +752,7 @@ static size_t convert_file_from_to (FILE * file,
     for (c = fromcodes; c; c = c1 ? c1 + 1 : 0) {
       if ((c1 = strchr (c, ':')) == c)
         continue;
-      fcode = str_substrdup (c, c1);
+      fcode = m_substrdup(c, c1);
 
       ret = convert_file_to (file, fcode, ncodes, (const char **) tcode,
                              &cn, info);
@@ -774,7 +762,7 @@ static size_t convert_file_from_to (FILE * file,
         tcode[cn] = 0;
         break;
       }
-      mem_free (&fcode);
+      p_delete(&fcode);
     }
   }
   else {
@@ -789,9 +777,9 @@ static size_t convert_file_from_to (FILE * file,
 
   /* Free memory */
   for (i = 0; i < ncodes; i++)
-    mem_free (&tcode[i]);
+    p_delete(&tcode[i]);
 
-  mem_free (tcode);
+  p_delete(tcode);
 
   return ret;
 }
@@ -806,7 +794,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;
@@ -831,8 +819,8 @@ CONTENT *mutt_get_content_info (const char *fname, BODY * b)
     return (NULL);
   }
 
-  info = mem_calloc (1, sizeof (CONTENT));
-  memset (&state, 0, sizeof (state));
+  info = p_new(CONTENT, 1);
+  p_clear(&state, 1);
 
   if (b != NULL && b->type == TYPETEXT && (!b->noconv && !b->force_charset)) {
     char *chs = mutt_get_parameter ("charset", b->parameter);
@@ -846,7 +834,7 @@ CONTENT *mutt_get_content_info (const char *fname, BODY * b)
         mutt_set_parameter ("charset", chsbuf, &b->parameter);
       }
       b->file_charset = fromcode;
-      mem_free (&tocode);
+      p_delete(&tocode);
       safe_fclose (&fp);
       return info;
     }
@@ -890,7 +878,7 @@ int mutt_lookup_mime_type (BODY * att, const char *path)
   type = TYPEOTHER;
   cur_sze = 0;
 
-  szf = str_len (path);
+  szf = m_strlen(path);
 
   for (count = 0; count < 4; count++) {
     /*
@@ -902,13 +890,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 "/madmutt-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));
@@ -922,27 +910,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 = str_len (p);
+          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) {
@@ -953,10 +936,10 @@ int mutt_lookup_mime_type (BODY * att, const char *path)
 
             for (q = p; *q && !ISSPACE (*q); q++);
 
-            str_substrcpy (subtype, p, q, sizeof (subtype));
+            m_strncpy(subtype, sizeof(subtype), p, q - p);
 
             if ((type = mutt_check_mime_type (ct)) == TYPEOTHER)
-              strfcpy (xtype, ct, sizeof (xtype));
+              m_strcpy(xtype, sizeof(xtype), ct);
 
             cur_sze = sze;
           }
@@ -971,8 +954,8 @@ bye:
 
   if (type != TYPEOTHER || *xtype != '\0') {
     att->type = type;
-    str_replace (&att->subtype, subtype);
-    str_replace (&att->xtype, xtype);
+    m_strreplace(&att->subtype, subtype);
+    m_strreplace(&att->xtype, xtype);
   }
 
   return (type);
@@ -1021,7 +1004,7 @@ void mutt_message_to_7bit (BODY * a, FILE * fp)
   mutt_write_mime_body (a->parts, fpout);
 
 cleanup:
-  mem_free (&line);
+  p_delete(&line);
 
   if (fpin && !fp)
     fclose (fpin);
@@ -1034,7 +1017,7 @@ cleanup:
   a->d_filename = a->filename;
   if (a->filename && a->unlink)
     unlink (a->filename);
-  a->filename = str_dup (temp);
+  a->filename = m_strdup(temp);
   a->unlink = 1;
   if (stat (a->filename, &sb) == -1) {
     mutt_perror ("stat");
@@ -1051,7 +1034,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)
@@ -1075,7 +1058,7 @@ static void transform_to_7bit (BODY * a, FILE * fpin)
       mutt_decode_attachment (a, &s);
       fclose (s.fpout);
       a->d_filename = a->filename;
-      a->filename = str_dup (buff);
+      a->filename = m_strdup(buff);
       a->unlink = 1;
       if (stat (a->filename, &sb) == -1) {
         mutt_perror ("stat");
@@ -1160,7 +1143,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;
 }
@@ -1185,7 +1168,7 @@ void mutt_update_encoding (BODY * a)
   mutt_set_encoding (a, info);
   mutt_stamp_attachment (a);
 
-  mem_free (&a->content);
+  p_delete(&a->content);
   a->content = info;
 
 }
@@ -1196,14 +1179,12 @@ BODY *mutt_make_message_attach (CONTEXT * ctx, HEADER * hdr, int attach_msg)
   BODY *body;
   FILE *fp;
   int cmflags, chflags;
-  int pgp = WithCrypto ? hdr->security : 0;
+  int pgp = hdr->security;
 
-  if (WithCrypto) {
-    if ((option (OPTMIMEFORWDECODE) || option (OPTFORWDECRYPT)) &&
-        (hdr->security & ENCRYPT)) {
-      if (!crypt_valid_passphrase (hdr->security))
-        return (NULL);
-    }
+  if ((option (OPTMIMEFORWDECODE) || option (OPTFORWDECRYPT)) &&
+      (hdr->security & ENCRYPT)) {
+    if (!crypt_valid_passphrase (hdr->security))
+      return (NULL);
   }
 
   mutt_mktemp (buffer);
@@ -1212,8 +1193,8 @@ BODY *mutt_make_message_attach (CONTEXT * ctx, HEADER * hdr, int attach_msg)
 
   body = mutt_new_body ();
   body->type = TYPEMESSAGE;
-  body->subtype = str_dup ("rfc822");
-  body->filename = str_dup (buffer);
+  body->subtype = m_strdup("rfc822");
+  body->filename = m_strdup(buffer);
   body->unlink = 1;
   body->use_disp = 0;
   body->disposition = DISPINLINE;
@@ -1228,26 +1209,20 @@ BODY *mutt_make_message_attach (CONTEXT * ctx, HEADER * hdr, int attach_msg)
   if (!attach_msg && option (OPTMIMEFORWDECODE)) {
     chflags |= CH_MIME | CH_TXTPLAIN;
     cmflags = M_CM_DECODE | M_CM_CHARCONV;
-    if ((WithCrypto & APPLICATION_PGP))
-      pgp &= ~PGPENCRYPT;
-    if ((WithCrypto & APPLICATION_SMIME))
-      pgp &= ~SMIMEENCRYPT;
+    pgp &= ~(PGPENCRYPT|SMIMEENCRYPT);
   }
-  else if (WithCrypto && option (OPTFORWDECRYPT) && (hdr->security & ENCRYPT)) {
-    if ((WithCrypto & APPLICATION_PGP)
-        && mutt_is_multipart_encrypted (hdr->content)) {
+  else if (option (OPTFORWDECRYPT) && (hdr->security & ENCRYPT)) {
+    if (mutt_is_multipart_encrypted (hdr->content)) {
       chflags |= CH_MIME | CH_NONEWLINE;
       cmflags = M_CM_DECODE_PGP;
       pgp &= ~PGPENCRYPT;
     }
-    else if ((WithCrypto & APPLICATION_PGP)
-             && (mutt_is_application_pgp (hdr->content) & PGPENCRYPT)) {
+    else if (mutt_is_application_pgp (hdr->content) & PGPENCRYPT) {
       chflags |= CH_MIME | CH_TXTPLAIN;
       cmflags = M_CM_DECODE | M_CM_CHARCONV;
       pgp &= ~PGPENCRYPT;
     }
-    else if ((WithCrypto & APPLICATION_SMIME)
-             && mutt_is_application_smime (hdr->content) & SMIMEENCRYPT) {
+    else if (mutt_is_application_smime (hdr->content) & SMIMEENCRYPT) {
       chflags |= CH_MIME | CH_TXTPLAIN;
       cmflags = M_CM_DECODE | M_CM_CHARCONV;
       pgp &= ~SMIMEENCRYPT;
@@ -1259,12 +1234,11 @@ BODY *mutt_make_message_attach (CONTEXT * ctx, HEADER * hdr, int attach_msg)
   fflush (fp);
   rewind (fp);
 
-  body->hdr = mutt_new_header ();
+  body->hdr = header_new();
   body->hdr->offset = 0;
   /* we don't need the user headers here */
   body->hdr->env = mutt_read_rfc822_header (fp, body->hdr, 0, 0);
-  if (WithCrypto)
-    body->hdr->security = pgp;
+  body->hdr->security = pgp;
   mutt_update_encoding (body);
   body->parts = body->hdr->content;
 
@@ -1279,7 +1253,7 @@ BODY *mutt_make_file_attach (const char *path)
   CONTENT *info;
 
   att = mutt_new_body ();
-  att->filename = str_dup (path);
+  att->filename = m_strdup(path);
 
   /* Attempt to determine the appropriate content-type based on the filename
    * suffix.
@@ -1291,8 +1265,8 @@ BODY *mutt_make_file_attach (const char *path)
        mutt_lookup_mime_type (buf, sizeof (buf), xbuf, sizeof (xbuf),
                               path)) != TYPEOTHER || *xbuf != '\0') {
     att->type = n;
-    att->subtype = str_dup (buf);
-    att->xtype = str_dup (xbuf);
+    att->subtype = m_strdup(buf);
+    att->xtype = m_strdup(xbuf);
   }
 
 #else
@@ -1314,11 +1288,11 @@ BODY *mutt_make_file_attach (const char *path)
        * chars if this is really a binary file...
        */
       att->type = TYPETEXT;
-      att->subtype = str_dup ("plain");
+      att->subtype = m_strdup("plain");
     }
     else {
       att->type = TYPEAPPLICATION;
-      att->subtype = str_dup ("octet-stream");
+      att->subtype = m_strdup("octet-stream");
     }
   }
 
@@ -1346,7 +1320,7 @@ BODY *mutt_make_multipart (BODY * b)
 
   new = mutt_new_body ();
   new->type = TYPEMULTIPART;
-  new->subtype = str_dup ("mixed");
+  new->subtype = m_strdup("mixed");
   new->encoding = get_toplevel_encoding (b);
   mutt_generate_boundary (&new->parameter);
   new->use_disp = 0;
@@ -1387,10 +1361,10 @@ char *mutt_make_date (char *s, size_t len)
 
 /* wrapper around mutt_write_address() so we can handle very large
    recipient lists without needing a huge temporary buffer in memory */
-void mutt_write_address_list (ADDRESS * adr, FILE * fp, int linelen,
+void mutt_write_address_list (address_t * adr, FILE * fp, int linelen,
                               int display)
 {
-  ADDRESS *tmp;
+  address_t *tmp;
   char buf[LONG_STRING];
   int count = 0;
   int len;
@@ -1400,7 +1374,7 @@ void mutt_write_address_list (ADDRESS * adr, FILE * fp, int linelen,
     adr->next = NULL;
     buf[0] = 0;
     rfc822_write_address (buf, sizeof (buf), adr, display);
-    len = str_len (buf);
+    len = m_strlen(buf);
     if (count && linelen + len > 74) {
       fputs ("\n\t", fp);
       linelen = len + 8;        /* tab is usually about 8 spaces... */
@@ -1439,7 +1413,7 @@ void mutt_write_references (LIST * r, FILE * f)
 
   for (; (TrimRef == 0 || refcnt < TrimRef) && r; r = r->next) {
     if (refcnt == refmax)
-      mem_realloc (&ref, (refmax += REF_INC) * sizeof (LIST *));
+      p_realloc(&ref, refmax += REF_INC);
     ref[refcnt++] = r;
   }
 
@@ -1448,7 +1422,7 @@ void mutt_write_references (LIST * r, FILE * f)
     fputs (ref[refcnt]->data, f);
   }
 
-  mem_free (&ref);
+  p_delete(&ref);
 }
 
 /* Note: all RFC2047 encoding should be done outside of this routine, except
@@ -1594,8 +1568,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. */
 
@@ -1624,7 +1597,7 @@ int mutt_write_rfc822_header (FILE * fp, ENVELOPE * env, BODY * attach,
     fprintf (fp, "User-Agent: %s (%s)\n", mutt_make_version (0), os);
   }
 
-  list_del (&hdrs, (list_del_t*) _mem_free);
+  list_del (&hdrs, (list_del_t*)xmemfree);
 
   return (ferror (fp) == 0 ? 0 : -1);
 }
@@ -1640,20 +1613,18 @@ static void encode_headers (LIST * h)
       continue;
 
     i = p - h->data;
-    ++p;
-    SKIPWS (p);
-    tmp = str_dup (p);
+    p = vskipspaces(p + 1);
+    tmp = m_strdup(p);
 
     if (!tmp)
       continue;
 
     rfc2047_encode_string (&tmp);
-    mem_realloc (&h->data,
-                  str_len (h->data) + 2 + str_len (tmp) + 1);
+    p_realloc(&h->data, m_strlen(h->data) + 2 + m_strlen(tmp) + 1);
 
     sprintf (h->data + i, ": %s", NONULL (tmp));        /* __SPRINTF_CHECKED__ */
 
-    mem_free (&tmp);
+    p_delete(&tmp);
   }
 }
 
@@ -1680,99 +1651,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, 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;
+    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)
@@ -1785,12 +1755,12 @@ char *mutt_gen_msgid (void)
   if (!(fqdn = mutt_fqdn (0)))
     fqdn = NONULL (Hostname);
 
-  localpart_length = sizeof (buf) - str_len (fqdn) - 4;  /* the 4 characters are '<', '@', '>' and '\0' */
+  localpart_length = sizeof (buf) - m_strlen(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));
+  return (m_strdup(buf));
 }
 
 static RETSIGTYPE alarm_handler (int sig)
@@ -1806,7 +1776,7 @@ static RETSIGTYPE alarm_handler (int sig)
                        to the temporary file containing the stdout of the
                        child process */
 static int
-send_msg (const char *path, char **args, const char *msg, char **tempfile)
+send_msg(const char *path, const char **args, const char *msg, char **tempfile)
 {
   sigset_t set;
   int fd, st;
@@ -1823,7 +1793,7 @@ send_msg (const char *path, char **args, const char *msg, char **tempfile)
     char tmp[_POSIX_PATH_MAX];
 
     mutt_mktemp (tmp);
-    *tempfile = str_dup (tmp);
+    *tempfile = m_strdup(tmp);
   }
 
   if ((pid = fork ()) == 0) {
@@ -1880,7 +1850,7 @@ send_msg (const char *path, char **args, const char *msg, char **tempfile)
     }
     else if (pid == -1) {
       unlink (msg);
-      mem_free (tempfile);
+      p_delete(tempfile);
       _exit (S_ERR);
     }
 
@@ -1908,14 +1878,14 @@ send_msg (const char *path, char **args, const char *msg, char **tempfile)
       st = WIFEXITED (st) ? WEXITSTATUS (st) : S_ERR;
       if (SendmailWait && st == (0xff & EX_OK)) {
         unlink (*tempfile);     /* no longer needed */
-        mem_free (tempfile);
+        p_delete(tempfile);
       }
     }
     else {
       st = (SendmailWait > 0 && errno == EINTR && SigAlrm) ? S_BKG : S_ERR;
       if (SendmailWait > 0) {
         unlink (*tempfile);
-        mem_free (tempfile);
+        p_delete(tempfile);
       }
     }
 
@@ -1926,7 +1896,7 @@ send_msg (const char *path, char **args, const char *msg, char **tempfile)
     if (kill (ppid, 0) == -1 && errno == ESRCH) {
       /* the parent is already dead */
       unlink (*tempfile);
-      mem_free (tempfile);
+      p_delete(tempfile);
     }
 
     _exit (st);
@@ -1944,37 +1914,37 @@ send_msg (const char *path, char **args, const char *msg, char **tempfile)
   return (st);
 }
 
-static char **add_args (char **args, size_t * argslen, size_t * argsmax,
-                        ADDRESS * addr)
+static const char **
+add_args(const char **args, size_t *argslen, size_t *argsmax, address_t * addr)
 {
   for (; addr; addr = addr->next) {
     /* weed out group mailboxes, since those are for display only */
     if (addr->mailbox && !addr->group) {
       if (*argslen == *argsmax)
-        mem_realloc (&args, (*argsmax += 5) * sizeof (char *));
+        p_realloc(&args, *argsmax += 5);
       args[(*argslen)++] = addr->mailbox;
     }
   }
   return (args);
 }
 
-static char **add_option(const char **args, size_t * argslen, size_t * argsmax,
-                         const char *s)
+static const char **
+add_option(const char **args, size_t *argslen, size_t *argsmax, const char *s)
 {
     if (*argslen == *argsmax) {
-        mem_realloc(&args, (*argsmax += 5) * sizeof (char *));
+        p_realloc(&args, *argsmax += 5);
     }
     args[(*argslen)++] = s;
     return (args);
 }
 
-static int mutt_invoke_sendmail (ADDRESS * from,        /* the sender */
-                                 ADDRESS * to, ADDRESS * cc, ADDRESS * bcc,     /* recips */
+static int mutt_invoke_sendmail (address_t * from,        /* the sender */
+                                 address_t * to, address_t * cc, address_t * bcc,     /* recips */
                                  const char *msg,       /* file containing message */
                                  int eightbit)
 {                               /* message contains 8bit chars */
   char *ps = NULL, *path = NULL, *s = NULL, *childout = NULL;
-  char **args = NULL;
+  const char **args = NULL;
   size_t argslen = 0, argsmax = 0;
   int i;
 
@@ -1990,22 +1960,22 @@ static int mutt_invoke_sendmail (ADDRESS * from,        /* the sender */
       return i;
     }
 
-    s = str_dup (cmd);
+    s = m_strdup(cmd);
   }
   else
 #endif
-    s = str_dup (Sendmail);
+    s = m_strdup(Sendmail);
 
   ps = s;
   i = 0;
   while ((ps = strtok (ps, " "))) {
     if (argslen == argsmax)
-      mem_realloc (&args, sizeof (char *) * (argsmax += 5));
+      p_realloc(&args, argsmax += 5);
 
     if (i)
       args[argslen++] = ps;
     else {
-      path = str_dup (ps);
+      path = m_strdup(ps);
       ps = strrchr (ps, '/');
       if (ps)
         ps++;
@@ -2021,10 +1991,10 @@ static int mutt_invoke_sendmail (ADDRESS * from,        /* the sender */
   if (!option (OPTNEWSSEND)) {
 #endif
     if (eightbit && option (OPTUSE8BITMIME))
-      args = add_option (args, &argslen, &argsmax, "-B8BITMIME");
+      args = add_option(args, &argslen, &argsmax, "-B8BITMIME");
 
     if (option (OPTENVFROM)) {
-      ADDRESS *f = NULL;
+      address_t *f = NULL;
       if (EnvFrom)
         f = EnvFrom;
       else if (from && !from->next)
@@ -2051,17 +2021,14 @@ static int mutt_invoke_sendmail (ADDRESS * from,        /* the sender */
 #endif
 
   if (argslen == argsmax)
-    mem_realloc (&args, sizeof (char *) * (++argsmax));
+    p_realloc(&args, ++argsmax);
 
   args[argslen++] = NULL;
 
   if ((i = send_msg (path, args, msg, &childout)) != (EX_OK & 0xff)) {
     if (i != S_BKG) {
-      const char *e = mutt_strsysexit (i);
-
-      e = mutt_strsysexit (i);
       mutt_error (_("Error sending message, child exited %d (%s)."), i,
-                  NONULL (e));
+                  m_strsysexit(i));
       if (childout) {
         struct stat st;
 
@@ -2074,10 +2041,10 @@ static int mutt_invoke_sendmail (ADDRESS * from,        /* the sender */
   else
     unlink (childout);
 
-  mem_free (&childout);
-  mem_free (&path);
-  mem_free (&s);
-  mem_free (&args);
+  p_delete(&childout);
+  p_delete(&path);
+  p_delete(&s);
+  p_delete(&args);
 
   if (i == (EX_OK & 0xff))
     i = 0;
@@ -2088,8 +2055,8 @@ static int mutt_invoke_sendmail (ADDRESS * from,        /* the sender */
   return (i);
 }
 
-int mutt_invoke_mta (ADDRESS * from,    /* the sender */
-                     ADDRESS * to, ADDRESS * cc, ADDRESS * bcc, /* recips */
+int mutt_invoke_mta (address_t * from,    /* the sender */
+                     address_t * to, address_t * cc, address_t * bcc, /* recips */
                      const char *msg,   /* file containing message */
                      int eightbit)
 {                               /* message contains 8bit chars */
@@ -2108,9 +2075,9 @@ int mutt_invoke_mta (ADDRESS * from,    /* the sender */
    string. */
 char *mutt_append_string (char *a, const char *b)
 {
-  size_t la = str_len (a);
+  size_t la = m_strlen(a);
 
-  mem_realloc (&a, la + str_len (b) + 1);
+  p_realloc(&a, la + m_strlen(b) + 1);
   strcpy (a + la, b);           /* __STRCPY_CHECKED__ */
   return (a);
 }
@@ -2138,14 +2105,14 @@ char *mutt_quote_string (const char *s)
   char *r, *pr;
   size_t rlen;
 
-  rlen = str_len (s) + 3;
-  pr = r = (char *) mem_malloc (rlen);
+  rlen = m_strlen(s) + 3;
+  pr = r = p_new(char, rlen);
   *pr++ = '"';
   while (*s) {
     if (INVALID_CHAR (*s)) {
       size_t o = pr - r;
 
-      mem_realloc (&r, ++rlen);
+      p_realloc(&r, ++rlen);
       pr = r + o;
       *pr++ = '\\';
     }
@@ -2167,15 +2134,15 @@ void mutt_prepare_envelope (ENVELOPE * env, int final)
        * recipients if there is no To: or Cc: field, so attempt to suppress
        * it by using an empty To: field.
        */
-      env->to = rfc822_new_address ();
+      env->to = address_new ();
       env->to->group = 1;
-      env->to->next = rfc822_new_address ();
+      env->to->next = address_new ();
 
       buffer[0] = 0;
-      rfc822_cat (buffer, sizeof (buffer), "undisclosed-recipients",
-                  RFC822Specials);
+      rfc822_strcpy(buffer, sizeof(buffer), "undisclosed-recipients",
+                    RFC822Specials);
 
-      env->to->mailbox = str_dup (buffer);
+      env->to->mailbox = m_strdup(buffer);
     }
 
     mutt_set_followup_to (env);
@@ -2209,7 +2176,7 @@ void mutt_unprepare_envelope (ENVELOPE * env)
   for (item = env->userhdrs; item; item = item->next)
     rfc2047_decode (&item->data);
 
-  rfc822_free_address (&env->mail_followup_to);
+  address_delete (&env->mail_followup_to);
 
   /* back conversions */
   rfc2047_decode_adrlist (env->to);
@@ -2220,8 +2187,8 @@ void mutt_unprepare_envelope (ENVELOPE * env)
   rfc2047_decode (&env->subject);
 }
 
-static int _mutt_bounce_message (FILE * fp, HEADER * h, ADDRESS * to,
-                                 const char *resent_from, ADDRESS * env_from)
+static int _mutt_bounce_message (FILE * fp, HEADER * h, address_t * to,
+                                 const char *resent_from, address_t * env_from)
 {
   int i, ret = 0;
   FILE *f;
@@ -2274,9 +2241,9 @@ static int _mutt_bounce_message (FILE * fp, HEADER * h, ADDRESS * to,
   return ret;
 }
 
-int mutt_bounce_message (FILE * fp, HEADER * h, ADDRESS * to)
+int mutt_bounce_message (FILE * fp, HEADER * h, address_t * to)
 {
-  ADDRESS *from;
+  address_t *from;
   const char *fqdn = mutt_fqdn (1);
   char resent_from[STRING];
   int ret;
@@ -2301,18 +2268,18 @@ int mutt_bounce_message (FILE * fp, HEADER * h, ADDRESS * to)
 
   ret = _mutt_bounce_message (fp, h, to, resent_from, from);
 
-  rfc822_free_address (&from);
+  address_delete (&from);
 
   return ret;
 }
 
 
 /* given a list of addresses, return a list of unique addresses */
-ADDRESS *mutt_remove_duplicates (ADDRESS * addr)
+address_t *mutt_remove_duplicates (address_t * addr)
 {
-  ADDRESS *top = addr;
-  ADDRESS **last = &top;
-  ADDRESS *tmp;
+  address_t *top = addr;
+  address_t **last = &top;
+  address_t *tmp;
   int dup;
 
   while (addr) {
@@ -2330,7 +2297,7 @@ ADDRESS *mutt_remove_duplicates (ADDRESS * addr)
       *last = addr->next;
 
       addr->next = NULL;
-      rfc822_free_address (&addr);
+      address_delete (&addr);
 
       addr = *last;
     }
@@ -2417,8 +2384,7 @@ int mutt_write_fcc (const char *path, HEADER * hdr, const char *msgid,
 
 
   /* (postponment) if the mail is to be signed or encrypted, save this info */
-  if ((WithCrypto & APPLICATION_PGP)
-      && post && (hdr->security & APPLICATION_PGP)) {
+  if (post && (hdr->security & APPLICATION_PGP)) {
     fputs ("X-Mutt-PGP: ", msg->fp);
     if (hdr->security & ENCRYPT)
       fputc ('E', msg->fp);
@@ -2433,8 +2399,7 @@ int mutt_write_fcc (const char *path, HEADER * hdr, const char *msgid,
   }
 
   /* (postponment) if the mail is to be signed or encrypted, save this info */
-  if ((WithCrypto & APPLICATION_SMIME)
-      && post && (hdr->security & APPLICATION_SMIME)) {
+  if (post && (hdr->security & APPLICATION_SMIME)) {
     fputs ("X-Mutt-SMIME: ", msg->fp);
     if (hdr->security & ENCRYPT) {
       fputc ('E', msg->fp);