Use good m_ functions, because it smell like a flower, version 2.
[apps/madmutt.git] / remailer.c
index 83cb556..226953d 100644 (file)
  * Mixmaster support for Mutt
  */
 
-#if HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include <lib-lib/lib-lib.h>
+
+#include <lib-sys/unix.h>
+#include <lib-ui/curses.h>
+#include <lib-ui/menu.h>
 
 #include "mutt.h"
-#include "mutt_curses.h"
-#include "mutt_menu.h"
-#include "mutt_regex.h"
-#include "mapping.h"
+#include "recvattach.h"
 
 #include "remailer.h"
 
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <sys/types.h>
-#include <sys/file.h>
-#include <fcntl.h>
+#define SW              (option(OPTMBOXPANE)?SidebarWidth:0)
+
+#define MIX_CAP_COMPRESS  (1 << 0)
+#define MIX_CAP_MIDDLEMAN (1 << 1)
+#define MIX_CAP_NEWSPOST  (1 << 2)
+#define MIX_CAP_NEWSMAIL  (1 << 3)
+
+/* Mixmaster's maximum chain length.  Don't change this. */
+#define MAXMIXES 19
+
+typedef struct remailer_t {
+    int num;
+    int caps;
+    char *shortname;
+    char *addr;
+    char *ver;
+} remailer_t;
+
+DO_INIT(remailer_t, remailer);
+static void remailer_wipe(remailer_t *remailer) {
+    p_delete(&remailer->shortname);
+    p_delete(&remailer->addr);
+    p_delete(&remailer->ver);
+}
+DO_NEW(remailer_t, remailer);
+DO_DELETE(remailer_t, remailer);
 
-#ifdef MIXMASTER
+typedef struct mixchain_t {
+    ssize_t cl;
+    int ch[MAXMIXES];
+} mixchain_t;
 
 struct coord {
-  short r, c;
+    short r, c;
 };
 
-static REMAILER **mix_type2_list (size_t * l);
-static REMAILER *mix_new_remailer (void);
-static const char *mix_format_caps (REMAILER * r);
-static int mix_chain_add (MIXCHAIN * chain, const char *s,
-                          REMAILER ** type2_list);
-static int mix_get_caps (const char *capstr);
-static void mix_add_entry (REMAILER ***, REMAILER *, size_t *, size_t *);
-static void mix_entry (char *b, size_t blen, MUTTMENU * menu, int num);
-static void mix_free_remailer (REMAILER ** r);
-static void mix_free_type2_list (REMAILER *** ttlp);
-static void mix_redraw_ce (REMAILER ** type2_list, struct coord *coords,
-                           MIXCHAIN * chain, int i, short selected);
-static void mix_redraw_chain (REMAILER ** type2_list, struct coord *coords,
-                              MIXCHAIN * chain, int cur);
-static void mix_redraw_head (MIXCHAIN *);
-static void mix_screen_coordinates (REMAILER ** type2_list, struct coord **,
-                                    MIXCHAIN *, int);
-
-static int mix_get_caps (const char *capstr)
+static int mix_get_caps(const char *capstr)
 {
-  int caps = 0;
+    int caps = 0;
 
-  while (*capstr) {
-    switch (*capstr) {
-    case 'C':
-      caps |= MIX_CAP_COMPRESS;
-      break;
+    while (*capstr) {
+        switch (*capstr) {
+          case 'C':
+            caps |= MIX_CAP_COMPRESS;
+            break;
 
-    case 'M':
-      caps |= MIX_CAP_MIDDLEMAN;
-      break;
+          case 'M':
+            caps |= MIX_CAP_MIDDLEMAN;
+            break;
 
-    case 'N':
-      {
-        switch (*++capstr) {
-        case 'm':
-          caps |= MIX_CAP_NEWSMAIL;
-          break;
+          case 'N':
+            switch (*++capstr) {
+              case 'm':
+                caps |= MIX_CAP_NEWSMAIL;
+                break;
 
-        case 'p':
-          caps |= MIX_CAP_NEWSPOST;
-          break;
+              case 'p':
+                caps |= MIX_CAP_NEWSPOST;
+                break;
 
+            }
         }
-      }
-    }
-
-    if (*capstr)
-      capstr++;
-  }
-
-  return caps;
-}
 
-static void mix_add_entry (REMAILER *** type2_list, REMAILER * entry,
-                           size_t * slots, size_t * used)
-{
-  if (*used == *slots) {
-    *slots += 5;
-    safe_realloc (type2_list, sizeof (REMAILER *) * (*slots));
-  }
-
-  (*type2_list)[(*used)++] = entry;
-  if (entry)
-    entry->num = *used;
-}
+        if (*capstr)
+            capstr++;
+    }
 
-static REMAILER *mix_new_remailer (void)
-{
-  return safe_calloc (1, sizeof (REMAILER));
+    return caps;
 }
 
-static void mix_free_remailer (REMAILER ** r)
+static void mix_add_entry(remailer_t ***type2_list, remailer_t *entry,
+                          ssize_t *slots, ssize_t *used)
 {
-  FREE (&(*r)->shortname);
-  FREE (&(*r)->addr);
-  FREE (&(*r)->ver);
+    if (*used == *slots) {
+        *slots += 5;
+        p_realloc(type2_list, *slots);
+    }
 
-  FREE (r);
+    (*type2_list)[(*used)++] = entry;
+    if (entry)
+        entry->num = *used;
 }
 
 /* parse the type2.list as given by mixmaster -T */
-
-static REMAILER **mix_type2_list (size_t * l)
+static remailer_t **mix_type2_list (ssize_t * l)
 {
-  FILE *fp;
-  pid_t mm_pid;
-  int devnull;
+    FILE *fp;
+    pid_t mm_pid;
+    int devnull;
 
-  char cmd[HUGE_STRING + _POSIX_PATH_MAX];
-  char line[HUGE_STRING];
-  char *t;
+    char cmd[HUGE_STRING + _POSIX_PATH_MAX];
+    char line[HUGE_STRING];
+    char *t;
 
-  REMAILER **type2_list = NULL, *p;
-  size_t slots = 0, used = 0;
+    remailer_t **type2_list = NULL, *p;
+    ssize_t slots = 0, used = 0;
 
-  if (!l)
-    return NULL;
+    if (!l)
+        return NULL;
 
-  if ((devnull = open ("/dev/null", O_RDWR)) == -1)
-    return NULL;
+    if ((devnull = open ("/dev/null", O_RDWR)) == -1)
+        return NULL;
 
-  snprintf (cmd, sizeof (cmd), "%s -T", Mixmaster);
+    snprintf (cmd, sizeof (cmd), "%s -T", Mixmaster);
 
-  if ((mm_pid =
-       mutt_create_filter_fd (cmd, NULL, &fp, NULL, devnull, -1,
-                              devnull)) == -1) {
-    close (devnull);
-    return NULL;
-  }
+    if ((mm_pid =
+         mutt_create_filter_fd (cmd, NULL, &fp, NULL, devnull, -1,
+                                devnull)) == -1) {
+        close (devnull);
+        return NULL;
+    }
 
-  /* first, generate the "random" remailer */
+    /* first, generate the "random" remailer */
 
-  p = mix_new_remailer ();
-  p->shortname = safe_strdup ("<random>");
-  mix_add_entry (&type2_list, p, &slots, &used);
+    p = remailer_new();
+    p->shortname = m_strdup("<random>");
+    mix_add_entry (&type2_list, p, &slots, &used);
 
-  while (fgets (line, sizeof (line), fp)) {
-    p = mix_new_remailer ();
+    while (fgets (line, sizeof (line), fp)) {
+        p = remailer_new();
 
-    if (!(t = strtok (line, " \t\n")))
-      goto problem;
+        if (!(t = strtok (line, " \t\n")))
+            goto problem;
 
-    p->shortname = safe_strdup (t);
+        p->shortname = m_strdup(t);
 
-    if (!(t = strtok (NULL, " \t\n")))
-      goto problem;
+        if (!(t = strtok (NULL, " \t\n")))
+            goto problem;
 
-    p->addr = safe_strdup (t);
+        p->addr = m_strdup(t);
 
-    if (!(t = strtok (NULL, " \t\n")))
-      goto problem;
+        if (!(t = strtok (NULL, " \t\n")))
+            goto problem;
 
-    if (!(t = strtok (NULL, " \t\n")))
-      goto problem;
+        if (!(t = strtok (NULL, " \t\n")))
+            goto problem;
 
-    p->ver = safe_strdup (t);
+        p->ver = m_strdup(t);
 
-    if (!(t = strtok (NULL, " \t\n")))
-      goto problem;
+        if (!(t = strtok (NULL, " \t\n")))
+            goto problem;
 
-    p->caps = mix_get_caps (t);
+        p->caps = mix_get_caps (t);
 
-    mix_add_entry (&type2_list, p, &slots, &used);
-    continue;
+        mix_add_entry (&type2_list, p, &slots, &used);
+        continue;
 
-  problem:
-    mix_free_remailer (&p);
-  }
+problem:
+        remailer_delete(&p);
+    }
 
-  *l = used;
+    *l = used;
 
-  mix_add_entry (&type2_list, NULL, &slots, &used);
-  mutt_wait_filter (mm_pid);
+    mix_add_entry (&type2_list, NULL, &slots, &used);
+    mutt_wait_filter (mm_pid);
 
-  close (devnull);
+    close (devnull);
 
-  return type2_list;
+    return type2_list;
 }
 
-static void mix_free_type2_list (REMAILER *** ttlp)
+static void mix_free_type2_list (remailer_t *** ttlp)
 {
-  int i;
-  REMAILER **type2_list = *ttlp;
+    int i;
+    remailer_t **type2_list = *ttlp;
 
-  for (i = 0; type2_list[i]; i++)
-    mix_free_remailer (&type2_list[i]);
+    for (i = 0; type2_list[i]; i++)
+        remailer_delete(&type2_list[i]);
 
-  FREE (type2_list);
+    p_delete(type2_list);
 }
 
 
@@ -214,135 +200,135 @@ static void mix_free_type2_list (REMAILER *** ttlp)
 #define MIX_MAXROW  (LINES - 3)
 
 
-static void mix_screen_coordinates (REMAILER ** type2_list,
+static void mix_screen_coordinates (remailer_t ** type2_list,
                                     struct coord **coordsp,
-                                    MIXCHAIN * chain, int i)
+                                    mixchain_t * chain, int i)
 {
-  short c, r, oc;
-  struct coord *coords;
+    short c, r, oc;
+    struct coord *coords;
 
-  if (!chain->cl)
-    return;
+    if (!chain->cl)
+        return;
 
-  safe_realloc (coordsp, sizeof (struct coord) * chain->cl);
+    p_realloc(coordsp, chain->cl);
 
-  coords = *coordsp;
+    coords = *coordsp;
 
-  if (i) {
-    c =
-      coords[i - 1].c + strlen (type2_list[chain->ch[i - 1]]->shortname) + 2;
-    r = coords[i - 1].r;
-  }
-  else {
-    r = MIX_VOFFSET;
-    c = MIX_HOFFSET;
-  }
+    if (i) {
+        c =
+            coords[i - 1].c + m_strlen(type2_list[chain->ch[i - 1]]->shortname) + 2;
+        r = coords[i - 1].r;
+    }
+    else {
+        r = MIX_VOFFSET;
+        c = MIX_HOFFSET;
+    }
 
 
-  for (; i < chain->cl; i++) {
-    oc = c;
-    c += strlen (type2_list[chain->ch[i]]->shortname) + 2;
+    for (; i < chain->cl; i++) {
+        oc = c;
+        c += m_strlen(type2_list[chain->ch[i]]->shortname) + 2;
 
-    if (c >= COLS) {
-      oc = c = MIX_HOFFSET;
-      r++;
-    }
+        if (c >= COLS) {
+            oc = c = MIX_HOFFSET;
+            r++;
+        }
 
-    coords[i].c = oc;
-    coords[i].r = r;
+        coords[i].c = oc;
+        coords[i].r = r;
 
-  }
+    }
 
 }
 
-static void mix_redraw_ce (REMAILER ** type2_list,
+static void mix_redraw_ce (remailer_t ** type2_list,
                            struct coord *coords,
-                           MIXCHAIN * chain, int i, short selected)
+                           mixchain_t * chain, int i, short selected)
 {
-  if (!coords || !chain)
-    return;
+    if (!coords || !chain)
+        return;
 
-  if (coords[i].r < MIX_MAXROW) {
+    if (coords[i].r < MIX_MAXROW) {
 
-    if (selected)
-      SETCOLOR (MT_COLOR_INDICATOR);
-    else
-      SETCOLOR (MT_COLOR_NORMAL);
+        if (selected)
+            SETCOLOR (MT_COLOR_INDICATOR);
+        else
+            SETCOLOR (MT_COLOR_NORMAL);
 
-    mvaddstr (coords[i].r, coords[i].c, type2_list[chain->ch[i]]->shortname);
-    SETCOLOR (MT_COLOR_NORMAL);
+        mvaddstr (coords[i].r, coords[i].c, type2_list[chain->ch[i]]->shortname);
+        SETCOLOR (MT_COLOR_NORMAL);
 
-    if (i + 1 < chain->cl)
-      addstr (", ");
-  }
+        if (i + 1 < chain->cl)
+            addstr (", ");
+    }
 }
 
-static void mix_redraw_chain (REMAILER ** type2_list,
-                              struct coord *coords, MIXCHAIN * chain, int cur)
+static void mix_redraw_chain (remailer_t ** type2_list,
+                              struct coord *coords, mixchain_t * chain, int cur)
 {
-  int i;
+    int i;
 
-  SETCOLOR (MT_COLOR_NORMAL);
-  BKGDSET (MT_COLOR_NORMAL);
+    SETCOLOR (MT_COLOR_NORMAL);
+    BKGDSET (MT_COLOR_NORMAL);
 
-  for (i = MIX_VOFFSET; i < MIX_MAXROW; i++) {
-    move (i, 0);
-    clrtoeol ();
-  }
+    for (i = MIX_VOFFSET; i < MIX_MAXROW; i++) {
+        move (i, 0);
+        clrtoeol ();
+    }
 
-  for (i = 0; i < chain->cl; i++)
-    mix_redraw_ce (type2_list, coords, chain, i, i == cur);
+    for (i = 0; i < chain->cl; i++)
+        mix_redraw_ce (type2_list, coords, chain, i, i == cur);
 }
 
-static void mix_redraw_head (MIXCHAIN * chain)
+static void mix_redraw_head (mixchain_t * chain)
 {
-  SETCOLOR (MT_COLOR_STATUS);
-  mvprintw (MIX_VOFFSET - 1, 0, "-- Remailer chain [Length: %d]",
-            chain ? chain->cl : 0);
+    SETCOLOR (MT_COLOR_STATUS);
+    mvprintw (MIX_VOFFSET - 1, 0, "-- Remailer chain [Length: %d]",
+              chain ? chain->cl : 0);
 
-  BKGDSET (MT_COLOR_STATUS);
-  clrtoeol ();
+    BKGDSET (MT_COLOR_STATUS);
+    clrtoeol ();
 
-  BKGDSET (MT_COLOR_NORMAL);
-  SETCOLOR (MT_COLOR_NORMAL);
+    BKGDSET (MT_COLOR_NORMAL);
+    SETCOLOR (MT_COLOR_NORMAL);
 }
 
-static const char *mix_format_caps (REMAILER * r)
+static const char *mix_format_caps (remailer_t * r)
 {
-  static char capbuff[10];
-  char *t = capbuff;
-
-  if (r->caps & MIX_CAP_COMPRESS)
-    *t++ = 'C';
-  else
-    *t++ = ' ';
-
-  if (r->caps & MIX_CAP_MIDDLEMAN)
-    *t++ = 'M';
-  else
-    *t++ = ' ';
-
-  if (r->caps & MIX_CAP_NEWSPOST) {
-    *t++ = 'N';
-    *t++ = 'p';
-  }
-  else {
-    *t++ = ' ';
-    *t++ = ' ';
-  }
-
-  if (r->caps & MIX_CAP_NEWSMAIL) {
-    *t++ = 'N';
-    *t++ = 'm';
-  }
-  else {
-    *t++ = ' ';
-    *t++ = ' ';
-  }
-
-  *t = '\0';
-
-  return capbuff;
+    static char capbuff[10];
+    char *t = capbuff;
+
+    if (r->caps & MIX_CAP_COMPRESS)
+        *t++ = 'C';
+    else
+        *t++ = ' ';
+
+    if (r->caps & MIX_CAP_MIDDLEMAN)
+        *t++ = 'M';
+    else
+        *t++ = ' ';
+
+    if (r->caps & MIX_CAP_NEWSPOST) {
+        *t++ = 'N';
+        *t++ = 'p';
+    }
+    else {
+        *t++ = ' ';
+        *t++ = ' ';
+    }
+
+    if (r->caps & MIX_CAP_NEWSMAIL) {
+        *t++ = 'N';
+        *t++ = 'm';
+    }
+    else {
+        *t++ = ' ';
+        *t++ = ' ';
+    }
+
+    *t = '\0';
+
+    return capbuff;
 }
 
 /*
@@ -354,9 +340,8 @@ static const char *mix_format_caps (REMAILER * r)
  * %a  address
  *
  */
-
 static const char *mix_entry_fmt (char *dest,
-                                  size_t destlen,
+                                  ssize_t destlen,
                                   char op,
                                   const char *src,
                                   const char *prefix,
@@ -364,373 +349,372 @@ static const char *mix_entry_fmt (char *dest,
                                   const char *elsestring,
                                   unsigned long data, format_flag flags)
 {
-  char fmt[16];
-  REMAILER *remailer = (REMAILER *) data;
-  int optional = (flags & M_FORMAT_OPTIONAL);
-
-  switch (op) {
-  case 'n':
-    if (!optional) {
-      snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
-      snprintf (dest, destlen, fmt, remailer->num);
-    }
-    break;
-  case 'c':
-    if (!optional) {
-      snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
-      snprintf (dest, destlen, fmt, mix_format_caps (remailer));
-    }
-    break;
-  case 's':
-    if (!optional) {
-      snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
-      snprintf (dest, destlen, fmt, NONULL (remailer->shortname));
-    }
-    else if (!remailer->shortname)
-      optional = 0;
-    break;
-  case 'a':
-    if (!optional) {
-      snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
-      snprintf (dest, destlen, fmt, NONULL (remailer->addr));
+    char fmt[16];
+    remailer_t *remailer = (remailer_t *) data;
+    int optional = (flags & M_FORMAT_OPTIONAL);
+
+    switch (op) {
+      case 'n':
+        if (!optional) {
+            snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
+            snprintf (dest, destlen, fmt, remailer->num);
+        }
+        break;
+      case 'c':
+        if (!optional) {
+            snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
+            snprintf (dest, destlen, fmt, mix_format_caps (remailer));
+        }
+        break;
+      case 's':
+        if (!optional) {
+            snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
+            snprintf (dest, destlen, fmt, NONULL (remailer->shortname));
+        }
+        else if (!remailer->shortname)
+            optional = 0;
+        break;
+      case 'a':
+        if (!optional) {
+            snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
+            snprintf (dest, destlen, fmt, NONULL (remailer->addr));
+        }
+        else if (!remailer->addr)
+            optional = 0;
+        break;
+
+      default:
+        *dest = '\0';
     }
-    else if (!remailer->addr)
-      optional = 0;
-    break;
-
-  default:
-    *dest = '\0';
-  }
-
-  if (optional)
-    mutt_FormatString (dest, destlen, ifstring, mutt_attach_fmt, data, 0);
-  else if (flags & M_FORMAT_OPTIONAL)
-    mutt_FormatString (dest, destlen, elsestring, mutt_attach_fmt, data, 0);
-  return (src);
+
+    if (optional)
+        mutt_FormatString (dest, destlen, ifstring, mutt_attach_fmt, data, 0);
+    else if (flags & M_FORMAT_OPTIONAL)
+        mutt_FormatString (dest, destlen, elsestring, mutt_attach_fmt, data, 0);
+    return (src);
 }
 
 
 
-static void mix_entry (char *b, size_t blen, MUTTMENU * menu, int num)
+static void mix_entry (char *b, ssize_t blen, MUTTMENU * menu, int num)
 {
-  REMAILER **type2_list = (REMAILER **) menu->data;
+    remailer_t **type2_list = (remailer_t **) menu->data;
+    int w = (COLS-SW) > blen ? blen : (COLS-SW);
 
-  mutt_FormatString (b, blen, NONULL (MixEntryFormat), mix_entry_fmt,
-                     (unsigned long) type2_list[num], M_FORMAT_ARROWCURSOR);
+    mutt_FormatString (b, w, NONULL (MixEntryFormat), mix_entry_fmt,
+                       (unsigned long) type2_list[num], M_FORMAT_ARROWCURSOR);
 }
 
-static int mix_chain_add (MIXCHAIN * chain, const char *s,
-                          REMAILER ** type2_list)
+static int mix_chain_add (mixchain_t * chain, const char *s,
+                          remailer_t ** type2_list)
 {
-  int i;
+    int i;
 
-  if (chain->cl >= MAXMIXES)
-    return -1;
+    if (chain->cl >= MAXMIXES)
+        return -1;
 
-  if (!mutt_strcmp (s, "0") || !ascii_strcasecmp (s, "<random>")) {
-    chain->ch[chain->cl++] = 0;
-    return 0;
-  }
+    if (!m_strcmp(s, "0") || !ascii_strcasecmp (s, "<random>")) {
+        chain->ch[chain->cl++] = 0;
+        return 0;
+    }
 
-  for (i = 0; type2_list[i]; i++) {
-    if (!ascii_strcasecmp (s, type2_list[i]->shortname)) {
-      chain->ch[chain->cl++] = i;
-      return 0;
+    for (i = 0; type2_list[i]; i++) {
+        if (!ascii_strcasecmp (s, type2_list[i]->shortname)) {
+            chain->ch[chain->cl++] = i;
+            return 0;
+        }
     }
-  }
 
-  /* replace unknown remailers by <random> */
+    /* replace unknown remailers by <random> */
 
-  if (!type2_list[i])
-    chain->ch[chain->cl++] = 0;
+    if (!type2_list[i])
+        chain->ch[chain->cl++] = 0;
 
-  return 0;
+    return 0;
 }
 
 static struct mapping_t RemailerHelp[] = {
-  {N_("Append"), OP_MIX_APPEND},
-  {N_("Insert"), OP_MIX_INSERT},
-  {N_("Delete"), OP_MIX_DELETE},
-  {N_("Abort"), OP_EXIT},
-  {N_("OK"), OP_MIX_USE},
-  {NULL}
+    {N_("Append"), OP_MIX_APPEND},
+    {N_("Insert"), OP_MIX_INSERT},
+    {N_("Delete"), OP_MIX_DELETE},
+    {N_("Abort"), OP_EXIT},
+    {N_("OK"), OP_MIX_USE},
+    {NULL, OP_NULL}
 };
 
 
-void mix_make_chain (LIST ** chainp, int *redraw)
+void mix_make_chain (string_list_t ** chainp, int *redraw)
 {
-  LIST *p;
-  MIXCHAIN *chain;
-  int c_cur = 0, c_old = 0;
-  int m_len;
-  short c_redraw = 1;
-
-  REMAILER **type2_list = NULL;
-  size_t ttll = 0;
-
-  struct coord *coords = NULL;
-
-  MUTTMENU *menu;
-  char helpstr[SHORT_STRING];
-  short loop = 1;
-  int op;
-
-  int i, j;
-  char *t;
+    string_list_t *p;
+    mixchain_t *chain;
+    int c_cur = 0, c_old = 0;
+    int m_len;
+    short c_redraw = 1;
 
-  if (!(type2_list = mix_type2_list (&ttll))) {
-    mutt_error _("Can't get mixmaster's type2.list!");
+    remailer_t **type2_list = NULL;
+    ssize_t ttll = 0;
 
-    return;
-  }
+    struct coord *coords = NULL;
 
-  *redraw = REDRAW_FULL;
+    MUTTMENU *menu;
+    char helpstr[SHORT_STRING];
+    short loop = 1;
+    int op;
 
-  chain = safe_calloc (sizeof (MIXCHAIN), 1);
-  for (p = *chainp; p; p = p->next)
-    mix_chain_add (chain, (char *) p->data, type2_list);
+    int i, j;
+    const char *t;
 
-  mutt_free_list (chainp);
+    if (!(type2_list = mix_type2_list (&ttll))) {
+        mutt_error _("Can't get mixmaster's type2.list!");
 
-  /* safety check */
-  for (i = 0; i < chain->cl; i++) {
-    if (chain->ch[i] >= ttll)
-      chain->ch[i] = 0;
-  }
+        return;
+    }
 
-  mix_screen_coordinates (type2_list, &coords, chain, 0);
+    *redraw = REDRAW_FULL;
 
-  menu = mutt_new_menu ();
-  menu->menu = MENU_MIX;
-  menu->max = ttll;
-  menu->make_entry = mix_entry;
-  menu->tag = NULL;
-  menu->title = _("Select a remailer chain.");
-  menu->data = type2_list;
-  menu->help =
-    mutt_compile_help (helpstr, sizeof (helpstr), MENU_MIX, RemailerHelp);
+    chain = p_new(mixchain_t, 1);
+    for (p = *chainp; p; p = p->next)
+        mix_chain_add (chain, (char *) p->data, type2_list);
 
-  m_len = menu->pagelen = MIX_VOFFSET - menu->offset - 1;
+    string_list_wipe(chainp);
 
-  while (loop) {
-    if (menu->pagelen != m_len) {
-      menu->pagelen = m_len;
-      menu->redraw = REDRAW_FULL;
+    /* safety check */
+    for (i = 0; i < chain->cl; i++) {
+        if (chain->ch[i] >= ttll)
+            chain->ch[i] = 0;
     }
 
-    if (c_redraw) {
-      mix_redraw_head (chain);
-      mix_redraw_chain (type2_list, coords, chain, c_cur);
-      c_redraw = 0;
-    }
-    else if (c_cur != c_old) {
-      mix_redraw_ce (type2_list, coords, chain, c_old, 0);
-      mix_redraw_ce (type2_list, coords, chain, c_cur, 1);
-    }
+    mix_screen_coordinates (type2_list, &coords, chain, 0);
 
-    c_old = c_cur;
+    menu = mutt_new_menu ();
+    menu->menu = MENU_MIX;
+    menu->max = ttll;
+    menu->make_entry = mix_entry;
+    menu->tag = NULL;
+    menu->title = _("Select a remailer chain.");
+    menu->data = type2_list;
+    menu->help =
+        mutt_compile_help (helpstr, sizeof (helpstr), MENU_MIX, RemailerHelp);
 
-    switch ((op = mutt_menuLoop (menu))) {
-    case OP_REDRAW:
-      {
-        menu_redraw_status (menu);
-        mix_redraw_head (chain);
-        mix_screen_coordinates (type2_list, &coords, chain, 0);
-        mix_redraw_chain (type2_list, coords, chain, c_cur);
-        menu->pagelen = m_len = MIX_VOFFSET - menu->offset - 1;
-        break;
-      }
+    m_len = menu->pagelen = MIX_VOFFSET - menu->offset - 1;
 
-    case OP_EXIT:
-      {
-        chain->cl = 0;
-        loop = 0;
-        break;
-      }
-
-    case OP_MIX_USE:
-      {
-        if (!chain->cl) {
-          chain->cl++;
-          chain->ch[0] = menu->current;
-          mix_screen_coordinates (type2_list, &coords, chain, c_cur);
-          c_redraw = 1;
+    while (loop) {
+        if (menu->pagelen != m_len) {
+            menu->pagelen = m_len;
+            menu->redraw = REDRAW_FULL;
         }
 
-        if (chain->cl && chain->ch[chain->cl - 1] &&
-            (type2_list[chain->ch[chain->cl - 1]]->caps & MIX_CAP_MIDDLEMAN))
-        {
-          mutt_error (_
-                      ("Error: %s can't be used as the final remailer of a chain."),
-                      type2_list[chain->ch[chain->cl - 1]]->shortname);
+        if (c_redraw) {
+            mix_redraw_head (chain);
+            mix_redraw_chain (type2_list, coords, chain, c_cur);
+            c_redraw = 0;
         }
-        else {
-          loop = 0;
+        else if (c_cur != c_old) {
+            mix_redraw_ce (type2_list, coords, chain, c_old, 0);
+            mix_redraw_ce (type2_list, coords, chain, c_cur, 1);
         }
-        break;
-      }
-
-    case OP_GENERIC_SELECT_ENTRY:
-    case OP_MIX_APPEND:
-      {
-        if (chain->cl < MAXMIXES && c_cur < chain->cl)
-          c_cur++;
-      }
-      /* fallthrough */
-    case OP_MIX_INSERT:
-      {
-        if (chain->cl < MAXMIXES) {
-          chain->cl++;
-          for (i = chain->cl - 1; i > c_cur; i--)
-            chain->ch[i] = chain->ch[i - 1];
-
-          chain->ch[c_cur] = menu->current;
-          mix_screen_coordinates (type2_list, &coords, chain, c_cur);
-          c_redraw = 1;
-        }
-        else
-          mutt_error (_("Mixmaster chains are limited to %d elements."),
-                      MAXMIXES);
 
-        break;
-      }
+        c_old = c_cur;
+
+        switch ((op = mutt_menuLoop (menu))) {
+          case OP_REDRAW:
+            {
+                menu_redraw_status (menu);
+                mix_redraw_head (chain);
+                mix_screen_coordinates (type2_list, &coords, chain, 0);
+                mix_redraw_chain (type2_list, coords, chain, c_cur);
+                menu->pagelen = m_len = MIX_VOFFSET - menu->offset - 1;
+                break;
+            }
+
+          case OP_EXIT:
+            {
+                chain->cl = 0;
+                loop = 0;
+                break;
+            }
+
+          case OP_MIX_USE:
+            {
+                if (!chain->cl) {
+                    chain->cl++;
+                    chain->ch[0] = menu->current;
+                    mix_screen_coordinates (type2_list, &coords, chain, c_cur);
+                    c_redraw = 1;
+                }
+
+                if (chain->cl && chain->ch[chain->cl - 1] &&
+                    (type2_list[chain->ch[chain->cl - 1]]->caps & MIX_CAP_MIDDLEMAN))
+                {
+                    mutt_error (_
+                                ("Error: %s can't be used as the final remailer of a chain."),
+                                type2_list[chain->ch[chain->cl - 1]]->shortname);
+                }
+                else {
+                    loop = 0;
+                }
+                break;
+            }
+
+          case OP_GENERIC_SELECT_ENTRY:
+          case OP_MIX_APPEND:
+            {
+                if (chain->cl < MAXMIXES && c_cur < chain->cl)
+                    c_cur++;
+            }
+            /* fallthrough */
+          case OP_MIX_INSERT:
+            {
+                if (chain->cl < MAXMIXES) {
+                    chain->cl++;
+                    for (i = chain->cl - 1; i > c_cur; i--)
+                        chain->ch[i] = chain->ch[i - 1];
+
+                    chain->ch[c_cur] = menu->current;
+                    mix_screen_coordinates (type2_list, &coords, chain, c_cur);
+                    c_redraw = 1;
+                }
+                else
+                    mutt_error (_("Mixmaster chains are limited to %d elements."),
+                                MAXMIXES);
+
+                break;
+            }
+
+          case OP_MIX_DELETE:
+            {
+                if (chain->cl) {
+                    chain->cl--;
+
+                    for (i = c_cur; i < chain->cl; i++)
+                        chain->ch[i] = chain->ch[i + 1];
+
+                    if (c_cur == chain->cl && c_cur)
+                        c_cur--;
+
+                    mix_screen_coordinates (type2_list, &coords, chain, c_cur);
+                    c_redraw = 1;
+                }
+                else {
+                    mutt_error _("The remailer chain is already empty.");
+                }
+                break;
+            }
+
+          case OP_MIX_CHAIN_PREV:
+            {
+                if (c_cur)
+                    c_cur--;
+                else
+                    mutt_error _("You already have the first chain element selected.");
+
+                break;
+            }
+
+          case OP_MIX_CHAIN_NEXT:
+            {
+                if (chain->cl && c_cur < chain->cl - 1)
+                    c_cur++;
+                else
+                    mutt_error _("You already have the last chain element selected.");
+
+                break;
+            }
+        }
+    }
 
-    case OP_MIX_DELETE:
-      {
-        if (chain->cl) {
-          chain->cl--;
+    mutt_menuDestroy (&menu);
 
-          for (i = c_cur; i < chain->cl; i++)
-            chain->ch[i] = chain->ch[i + 1];
+    /* construct the remailer list */
 
-          if (c_cur == chain->cl && c_cur)
-            c_cur--;
+    if (chain->cl) {
+        for (i = 0; i < chain->cl; i++) {
+            if ((j = chain->ch[i]))
+                t = type2_list[j]->shortname;
+            else
+                t = "*";
 
-          mix_screen_coordinates (type2_list, &coords, chain, c_cur);
-          c_redraw = 1;
-        }
-        else {
-          mutt_error _("The remailer chain is already empty.");
+            *chainp = mutt_add_list (*chainp, t);
         }
-        break;
-      }
+    }
 
-    case OP_MIX_CHAIN_PREV:
-      {
-        if (c_cur)
-          c_cur--;
-        else
-          mutt_error _("You already have the first chain element selected.");
+    mix_free_type2_list (&type2_list);
+    p_delete(&coords);
+    p_delete(&chain);
+}
 
-        break;
-      }
+/* some safety checks before piping the message to mixmaster */
 
-    case OP_MIX_CHAIN_NEXT:
-      {
-        if (chain->cl && c_cur < chain->cl - 1)
-          c_cur++;
-        else
-          mutt_error _("You already have the last chain element selected.");
+int mix_check_message (HEADER * msg)
+{
+    const char *fqdn;
+    short need_hostname = 0;
+    address_t *p;
 
-        break;
-      }
+    if (msg->env->cc || msg->env->bcc) {
+        mutt_error _("Mixmaster doesn't accept Cc or Bcc headers.");
+
+        return -1;
     }
-  }
 
-  mutt_menuDestroy (&menu);
+    /* When using mixmaster, we MUST qualify any addresses since
+     * the message will be delivered through remote systems.
+     * 
+     * use_domain won't be respected at this point, hidden_host will.
+     */
+
+    for (p = msg->env->to; p; p = p->next) {
+        if (!p->group && strchr (p->mailbox, '@') == NULL) {
+            need_hostname = 1;
+            break;
+        }
+    }
 
-  /* construct the remailer list */
+    if (need_hostname) {
 
-  if (chain->cl) {
-    for (i = 0; i < chain->cl; i++) {
-      if ((j = chain->ch[i]))
-        t = type2_list[j]->shortname;
-      else
-        t = "*";
+        if (!(fqdn = mutt_fqdn (1))) {
+            mutt_error
+                _
+                ("Please set the hostname variable to a proper value when using mixmaster!");
+            return (-1);
+        }
 
-      *chainp = mutt_add_list (*chainp, t);
+        /* Cc and Bcc are empty at this point. */
+        rfc822_qualify (msg->env->to, fqdn);
+        rfc822_qualify (msg->env->reply_to, fqdn);
+        rfc822_qualify (msg->env->mail_followup_to, fqdn);
     }
-  }
 
-  mix_free_type2_list (&type2_list);
-  FREE (&coords);
-  FREE (&chain);
+    return 0;
 }
 
-/* some safety checks before piping the message to mixmaster */
-
-int mix_check_message (HEADER * msg)
+int mix_send_message (string_list_t * chain, const char *tempfile)
 {
-  const char *fqdn;
-  short need_hostname = 0;
-  ADDRESS *p;
-
-  if (msg->env->cc || msg->env->bcc) {
-    mutt_error _("Mixmaster doesn't accept Cc or Bcc headers.");
-
-    return -1;
-  }
-
-  /* When using mixmaster, we MUST qualify any addresses since
-   * the message will be delivered through remote systems.
-   * 
-   * use_domain won't be respected at this point, hidden_host will.
-   */
-
-  for (p = msg->env->to; p; p = p->next) {
-    if (!p->group && strchr (p->mailbox, '@') == NULL) {
-      need_hostname = 1;
-      break;
-    }
-  }
+    char cmd[HUGE_STRING];
+    char tmp[HUGE_STRING];
+    char cd_quoted[STRING];
+    int i;
 
-  if (need_hostname) {
+    snprintf (cmd, sizeof (cmd), "cat %s | %s -m ", tempfile, Mixmaster);
 
-    if (!(fqdn = mutt_fqdn (1))) {
-      mutt_error
-        _
-        ("Please set the hostname variable to a proper value when using mixmaster!");
-      return (-1);
+    for (i = 0; chain; chain = chain->next, i = 1) {
+        m_strcpy(tmp, sizeof(tmp), cmd);
+        mutt_quote_filename (cd_quoted, sizeof (cd_quoted), (char *) chain->data);
+        snprintf (cmd, sizeof (cmd), "%s%s%s", tmp, i ? "," : " -l ", cd_quoted);
     }
 
-    /* Cc and Bcc are empty at this point. */
-    rfc822_qualify (msg->env->to, fqdn);
-    rfc822_qualify (msg->env->reply_to, fqdn);
-    rfc822_qualify (msg->env->mail_followup_to, fqdn);
-  }
-
-  return 0;
-}
+    if (!option (OPTNOCURSES))
+        mutt_endwin (NULL);
 
-int mix_send_message (LIST * chain, const char *tempfile)
-{
-  char cmd[HUGE_STRING];
-  char tmp[HUGE_STRING];
-  char cd_quoted[STRING];
-  int i;
-
-  snprintf (cmd, sizeof (cmd), "cat %s | %s -m ", tempfile, Mixmaster);
-
-  for (i = 0; chain; chain = chain->next, i = 1) {
-    strfcpy (tmp, cmd, sizeof (tmp));
-    mutt_quote_filename (cd_quoted, sizeof (cd_quoted), (char *) chain->data);
-    snprintf (cmd, sizeof (cmd), "%s%s%s", tmp, i ? "," : " -l ", cd_quoted);
-  }
-
-  if (!option (OPTNOCURSES))
-    mutt_endwin (NULL);
-
-  if ((i = mutt_system (cmd))) {
-    fprintf (stderr, _("Error sending message, child exited %d.\n"), i);
-    if (!option (OPTNOCURSES)) {
-      mutt_any_key_to_continue (NULL);
-      mutt_error _("Error sending message.");
+    if ((i = mutt_system (cmd))) {
+        fprintf (stderr, _("Error sending message, child exited %d.\n"), i);
+        if (!option (OPTNOCURSES)) {
+            mutt_any_key_to_continue (NULL);
+            mutt_error _("Error sending message.");
+        }
     }
-  }
 
-  unlink (tempfile);
-  return i;
+    unlink (tempfile);
+    return i;
 }
 
-
-#endif