NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
remailer.c
Go to the documentation of this file.
1 
30 #include "config.h"
31 #include <fcntl.h>
32 #include <stdbool.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <unistd.h>
36 #include "mutt/lib.h"
37 #include "address/lib.h"
38 #include "config/lib.h"
39 #include "email/lib.h"
40 #include "core/lib.h"
41 #include "gui/lib.h"
42 #include "mutt.h"
43 #include "send/lib.h"
44 #include "format_flags.h"
45 #include "keymap.h"
46 #include "mutt_globals.h"
47 #include "mutt_menu.h"
48 #include "muttlib.h"
49 #include "opcodes.h"
50 #include "options.h"
51 #include "protos.h"
52 #include "recvattach.h"
53 #ifdef MIXMASTER
54 #include "remailer.h"
55 #endif
56 
57 /* These Config Variables are only used in remailer.c */
59 char *C_Mixmaster;
60 
61 #define MIX_HOFFSET 2
62 #define MIX_VOFFSET (win->state.rows - 4)
63 #define MIX_MAXROW (win->state.rows - 1)
64 
68 struct Coord
69 {
70  short r;
71  short c;
72 };
73 
75 static const struct Mapping RemailerHelp[] = {
76  // clang-format off
77  { N_("Append"), OP_MIX_APPEND },
78  { N_("Insert"), OP_MIX_INSERT },
79  { N_("Delete"), OP_MIX_DELETE },
80  { N_("Abort"), OP_EXIT },
81  { N_("OK"), OP_MIX_USE },
82  { NULL, 0 },
83  // clang-format on
84 };
85 
91 static MixCapFlags mix_get_caps(const char *capstr)
92 {
94 
95  while (*capstr)
96  {
97  switch (*capstr)
98  {
99  case 'C':
100  caps |= MIX_CAP_COMPRESS;
101  break;
102 
103  case 'M':
104  caps |= MIX_CAP_MIDDLEMAN;
105  break;
106 
107  case 'N':
108  {
109  switch (*++capstr)
110  {
111  case 'm':
112  caps |= MIX_CAP_NEWSMAIL;
113  break;
114 
115  case 'p':
116  caps |= MIX_CAP_NEWSPOST;
117  break;
118  }
119  }
120  }
121 
122  if (*capstr)
123  capstr++;
124  }
125 
126  return caps;
127 }
128 
136 static void mix_add_entry(struct Remailer ***type2_list, struct Remailer *entry,
137  size_t *slots, size_t *used)
138 {
139  if (*used == *slots)
140  {
141  *slots += 5;
142  mutt_mem_realloc(type2_list, sizeof(struct Remailer *) * (*slots));
143  }
144 
145  (*type2_list)[(*used)++] = entry;
146  if (entry)
147  entry->num = *used;
148 }
149 
154 static struct Remailer *remailer_new(void)
155 {
156  return mutt_mem_calloc(1, sizeof(struct Remailer));
157 }
158 
163 static void remailer_free(struct Remailer **ptr)
164 {
165  if (!ptr || !*ptr)
166  return;
167 
168  struct Remailer *r = *ptr;
169 
170  FREE(&r->shortname);
171  FREE(&r->addr);
172  FREE(&r->ver);
173  FREE(ptr);
174 }
175 
181 static struct Remailer **mix_type2_list(size_t *l)
182 {
183  if (!l)
184  return NULL;
185 
186  FILE *fp = NULL;
187  char line[8192];
188  char *t = NULL;
189 
190  struct Remailer **type2_list = NULL;
191  struct Remailer *p = NULL;
192  size_t slots = 0, used = 0;
193 
194  int fd_null = open("/dev/null", O_RDWR);
195  if (fd_null == -1)
196  return NULL;
197 
198  struct Buffer *cmd = mutt_buffer_pool_get();
199  mutt_buffer_printf(cmd, "%s -T", C_Mixmaster);
200 
201  pid_t mm_pid =
202  filter_create_fd(mutt_buffer_string(cmd), NULL, &fp, NULL, fd_null, -1, fd_null);
203  if (mm_pid == -1)
204  {
206  close(fd_null);
207  return NULL;
208  }
209 
211 
212  /* first, generate the "random" remailer */
213 
214  p = remailer_new();
215  p->shortname = mutt_str_dup(_("<random>"));
216  mix_add_entry(&type2_list, p, &slots, &used);
217 
218  while (fgets(line, sizeof(line), fp))
219  {
220  p = remailer_new();
221 
222  t = strtok(line, " \t\n");
223  if (!t)
224  goto problem;
225 
226  p->shortname = mutt_str_dup(t);
227 
228  t = strtok(NULL, " \t\n");
229  if (!t)
230  goto problem;
231 
232  p->addr = mutt_str_dup(t);
233 
234  t = strtok(NULL, " \t\n");
235  if (!t)
236  goto problem;
237 
238  t = strtok(NULL, " \t\n");
239  if (!t)
240  goto problem;
241 
242  p->ver = mutt_str_dup(t);
243 
244  t = strtok(NULL, " \t\n");
245  if (!t)
246  goto problem;
247 
248  p->caps = mix_get_caps(t);
249 
250  mix_add_entry(&type2_list, p, &slots, &used);
251  continue;
252 
253  problem:
254  remailer_free(&p);
255  }
256 
257  *l = used;
258 
259  mix_add_entry(&type2_list, NULL, &slots, &used);
260  filter_wait(mm_pid);
261 
262  close(fd_null);
263 
264  return type2_list;
265 }
266 
271 static void mix_type2_list_free(struct Remailer ***ttlp)
272 {
273  struct Remailer **type2_list = *ttlp;
274 
275  for (int i = 0; type2_list[i]; i++)
276  remailer_free(&type2_list[i]);
277 
278  FREE(type2_list);
279 }
280 
289 static void mix_screen_coordinates(struct MuttWindow *win, struct Remailer **type2_list,
290  struct Coord **coordsp, struct MixChain *chain, int i)
291 {
292  if (!chain->cl)
293  return;
294 
295  short c, r;
296 
297  mutt_mem_realloc(coordsp, sizeof(struct Coord) * chain->cl);
298 
299  struct Coord *coords = *coordsp;
300 
301  if (i)
302  {
303  c = coords[i - 1].c + strlen(type2_list[chain->ch[i - 1]]->shortname) + 2;
304  r = coords[i - 1].r;
305  }
306  else
307  {
308  r = MIX_VOFFSET;
309  c = MIX_HOFFSET;
310  }
311 
312  for (; i < chain->cl; i++)
313  {
314  short oc = c;
315  c += strlen(type2_list[chain->ch[i]]->shortname) + 2;
316 
317  if (c >= win->state.cols)
318  {
319  oc = MIX_HOFFSET;
320  c = MIX_HOFFSET;
321  r++;
322  }
323 
324  coords[i].c = oc;
325  coords[i].r = r;
326  }
327 }
328 
338 static void mix_redraw_ce(struct MuttWindow *win, struct Remailer **type2_list,
339  struct Coord *coords, struct MixChain *chain, int i, bool selected)
340 {
341  if (!coords || !chain)
342  return;
343 
344  if (coords[i].r < MIX_MAXROW)
345  {
346  if (selected)
348  else
350 
351  mutt_window_mvaddstr(win, coords[i].c, coords[i].r, type2_list[chain->ch[i]]->shortname);
353 
354  if (i + 1 < chain->cl)
355  mutt_window_addstr(", ");
356  }
357 }
358 
367 static void mix_redraw_chain(struct MuttWindow *win, struct Remailer **type2_list,
368  struct Coord *coords, struct MixChain *chain, int cur)
369 {
370  for (int i = MIX_VOFFSET; i < MIX_MAXROW; i++)
371  {
372  mutt_window_move(win, 0, i);
374  }
375 
376  for (int i = 0; i < chain->cl; i++)
377  mix_redraw_ce(win, type2_list, coords, chain, i, i == cur);
378 }
379 
385 static void mix_redraw_head(struct MuttWindow *win, struct MixChain *chain)
386 {
388  mutt_window_mvprintw(win, 0, MIX_VOFFSET - 1,
389  "-- Remailer chain [Length: %d]", chain ? chain->cl : 0);
392 }
393 
401 static const char *mix_format_caps(struct Remailer *r)
402 {
403  static char capbuf[10];
404  char *t = capbuf;
405 
406  if (r->caps & MIX_CAP_COMPRESS)
407  *t++ = 'C';
408  else
409  *t++ = ' ';
410 
411  if (r->caps & MIX_CAP_MIDDLEMAN)
412  *t++ = 'M';
413  else
414  *t++ = ' ';
415 
416  if (r->caps & MIX_CAP_NEWSPOST)
417  {
418  *t++ = 'N';
419  *t++ = 'p';
420  }
421  else
422  {
423  *t++ = ' ';
424  *t++ = ' ';
425  }
426 
427  if (r->caps & MIX_CAP_NEWSMAIL)
428  {
429  *t++ = 'N';
430  *t++ = 'm';
431  }
432  else
433  {
434  *t++ = ' ';
435  *t++ = ' ';
436  }
437 
438  *t = '\0';
439 
440  return capbuf;
441 }
442 
453 static const char *mix_format_str(char *buf, size_t buflen, size_t col, int cols,
454  char op, const char *src, const char *prec,
455  const char *if_str, const char *else_str,
456  intptr_t data, MuttFormatFlags flags)
457 {
458  char fmt[128];
459  struct Remailer *remailer = (struct Remailer *) data;
460  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
461 
462  switch (op)
463  {
464  case 'a':
465  if (!optional)
466  {
467  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
468  snprintf(buf, buflen, fmt, NONULL(remailer->addr));
469  }
470  else if (!remailer->addr)
471  optional = false;
472  break;
473 
474  case 'c':
475  if (optional)
476  break;
477 
478  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
479  snprintf(buf, buflen, fmt, mix_format_caps(remailer));
480  break;
481 
482  case 'n':
483  if (optional)
484  break;
485 
486  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
487  snprintf(buf, buflen, fmt, remailer->num);
488  break;
489 
490  case 's':
491  if (!optional)
492  {
493  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
494  snprintf(buf, buflen, fmt, NONULL(remailer->shortname));
495  }
496  else if (!remailer->shortname)
497  optional = false;
498  break;
499 
500  default:
501  *buf = '\0';
502  }
503 
504  if (optional)
505  {
506  mutt_expando_format(buf, buflen, col, cols, if_str, mix_format_str, data,
508  }
509  else if (flags & MUTT_FORMAT_OPTIONAL)
510  {
511  mutt_expando_format(buf, buflen, col, cols, else_str, mix_format_str, data,
513  }
514  return src;
515 }
516 
520 static void mix_make_entry(struct Menu *menu, char *buf, size_t buflen, int num)
521 {
522  struct Remailer **type2_list = menu->mdata;
523  mutt_expando_format(buf, buflen, 0, menu->win_index->state.cols,
525  (intptr_t) type2_list[num], MUTT_FORMAT_ARROWCURSOR);
526 }
527 
536 static int mix_chain_add(struct MixChain *chain, const char *s, struct Remailer **type2_list)
537 {
538  int i;
539 
540  if (chain->cl >= MAX_MIXES)
541  return -1;
542 
543  if (mutt_str_equal(s, "0") || mutt_istr_equal(s, "<random>"))
544  {
545  chain->ch[chain->cl++] = 0;
546  return 0;
547  }
548 
549  for (i = 0; type2_list[i]; i++)
550  {
551  if (mutt_istr_equal(s, type2_list[i]->shortname))
552  {
553  chain->ch[chain->cl++] = i;
554  return 0;
555  }
556  }
557 
558  /* replace unknown remailers by <random> */
559 
560  if (!type2_list[i])
561  chain->ch[chain->cl++] = 0;
562 
563  return 0;
564 }
565 
574 void dlg_select_mixmaster_chain(struct MuttWindow *win, struct ListHead *chainhead, int cols)
575 {
576  int c_cur = 0, c_old = 0;
577  bool c_redraw = true;
578  size_t ttll = 0;
579 
580  struct Coord *coords = NULL;
581 
582  struct Menu *menu = NULL;
583  bool loop = true;
584 
585  char *t = NULL;
586 
587  struct Remailer **type2_list = mix_type2_list(&ttll);
588  if (!type2_list)
589  {
590  mutt_error(_("Can't get mixmaster's type2.list"));
591  return;
592  }
593 
594  struct MixChain *chain = mutt_mem_calloc(1, sizeof(struct MixChain));
595 
596  struct ListNode *p = NULL;
597  STAILQ_FOREACH(p, chainhead, entries)
598  {
599  mix_chain_add(chain, p->data, type2_list);
600  }
601  mutt_list_free(chainhead);
602 
603  /* safety check */
604  for (int i = 0; i < chain->cl; i++)
605  {
606  if (chain->ch[i] >= ttll)
607  chain->ch[i] = 0;
608  }
609 
610  mix_screen_coordinates(win, type2_list, &coords, chain, 0);
611 
612  menu = mutt_menu_new(MENU_MIX);
614  dlg->help_data = RemailerHelp;
615  dlg->help_menu = MENU_MIX;
616 
617  menu->max = ttll;
618  menu->make_entry = mix_make_entry;
619  menu->tag = NULL;
620  menu->title = _("Select a remailer chain");
621  menu->mdata = type2_list;
622  menu->pagelen = MIX_VOFFSET - 1;
624 
625  while (loop)
626  {
627  if (menu->pagelen != MIX_VOFFSET - 1)
628  {
629  menu->pagelen = MIX_VOFFSET - 1;
630  menu->redraw = REDRAW_FULL;
631  }
632 
633  if (c_redraw)
634  {
635  mix_redraw_head(menu->win_index, chain);
636  mix_redraw_chain(menu->win_index, type2_list, coords, chain, c_cur);
637  c_redraw = false;
638  }
639  else if (c_cur != c_old)
640  {
641  mix_redraw_ce(menu->win_index, type2_list, coords, chain, c_old, false);
642  mix_redraw_ce(menu->win_index, type2_list, coords, chain, c_cur, true);
643  }
644 
645  c_old = c_cur;
646 
647  const int op = mutt_menu_loop(menu);
648  switch (op)
649  {
650  case OP_REDRAW:
651  {
652  menu_redraw_status(menu);
653  mix_redraw_head(menu->win_index, chain);
654  mix_screen_coordinates(menu->win_index, type2_list, &coords, chain, 0);
655  mix_redraw_chain(menu->win_index, type2_list, coords, chain, c_cur);
656  menu->pagelen = MIX_VOFFSET - 1;
657  break;
658  }
659 
660  case OP_EXIT:
661  {
662  chain->cl = 0;
663  loop = false;
664  break;
665  }
666 
667  case OP_MIX_USE:
668  {
669  if (!chain->cl)
670  {
671  chain->cl++;
672  chain->ch[0] = menu->current;
673  mix_screen_coordinates(menu->win_index, type2_list, &coords, chain, c_cur);
674  c_redraw = true;
675  }
676 
677  if (chain->cl && chain->ch[chain->cl - 1] &&
678  (type2_list[chain->ch[chain->cl - 1]]->caps & MIX_CAP_MIDDLEMAN))
679  {
680  mutt_error(
681  _("Error: %s can't be used as the final remailer of a chain"),
682  type2_list[chain->ch[chain->cl - 1]]->shortname);
683  }
684  else
685  {
686  loop = false;
687  }
688  break;
689  }
690 
691  case OP_GENERIC_SELECT_ENTRY:
692  case OP_MIX_APPEND:
693  {
694  if ((chain->cl < MAX_MIXES) && (c_cur < chain->cl))
695  c_cur++;
696  }
697  /* fallthrough */
698  case OP_MIX_INSERT:
699  {
700  if (chain->cl < MAX_MIXES)
701  {
702  chain->cl++;
703  for (int i = chain->cl - 1; i > c_cur; i--)
704  chain->ch[i] = chain->ch[i - 1];
705 
706  chain->ch[c_cur] = menu->current;
707  mix_screen_coordinates(menu->win_index, type2_list, &coords, chain, c_cur);
708  c_redraw = true;
709  }
710  else
711  {
712  /* L10N The '%d' here hard-coded to 19 */
713  mutt_error(_("Mixmaster chains are limited to %d elements"), MAX_MIXES);
714  }
715 
716  break;
717  }
718 
719  case OP_MIX_DELETE:
720  {
721  if (chain->cl)
722  {
723  chain->cl--;
724 
725  for (int i = c_cur; i < chain->cl; i++)
726  chain->ch[i] = chain->ch[i + 1];
727 
728  if ((c_cur == chain->cl) && c_cur)
729  c_cur--;
730 
731  mix_screen_coordinates(menu->win_index, type2_list, &coords, chain, c_cur);
732  c_redraw = true;
733  }
734  else
735  {
736  mutt_error(_("The remailer chain is already empty"));
737  }
738  break;
739  }
740 
741  case OP_MIX_CHAIN_PREV:
742  {
743  if (c_cur)
744  c_cur--;
745  else
746  mutt_error(_("You already have the first chain element selected"));
747 
748  break;
749  }
750 
751  case OP_MIX_CHAIN_NEXT:
752  {
753  if (chain->cl && (c_cur < chain->cl - 1))
754  c_cur++;
755  else
756  mutt_error(_("You already have the last chain element selected"));
757 
758  break;
759  }
760  }
761  }
762 
763  mutt_menu_pop_current(menu);
764  mutt_menu_free(&menu);
766 
767  /* construct the remailer list */
768 
769  if (chain->cl)
770  {
771  for (int i = 0; i < chain->cl; i++)
772  {
773  const int j = chain->ch[i];
774  if (j != 0)
775  t = type2_list[j]->shortname;
776  else
777  t = "*";
778 
779  mutt_list_insert_tail(chainhead, mutt_str_dup(t));
780  }
781  }
782 
783  mix_type2_list_free(&type2_list);
784  FREE(&coords);
785  FREE(&chain);
786 }
787 
794 int mix_check_message(struct Email *e)
795 {
796  bool need_hostname = false;
797 
798  if (!TAILQ_EMPTY(&e->env->cc) || !TAILQ_EMPTY(&e->env->bcc))
799  {
800  mutt_error(_("Mixmaster doesn't accept Cc or Bcc headers"));
801  return -1;
802  }
803 
804  /* When using mixmaster, we MUST qualify any addresses since
805  * the message will be delivered through remote systems.
806  *
807  * use_domain won't be respected at this point, hidden_host will.
808  */
809 
810  struct Address *a = NULL;
811  TAILQ_FOREACH(a, &e->env->to, entries)
812  {
813  if (!a->group && !strchr(a->mailbox, '@'))
814  {
815  need_hostname = true;
816  break;
817  }
818  }
819 
820  if (need_hostname)
821  {
822  const char *fqdn = mutt_fqdn(true, NeoMutt->sub);
823  if (!fqdn)
824  {
825  mutt_error(_("Please set the hostname variable to a proper value when "
826  "using mixmaster"));
827  return -1;
828  }
829 
830  /* Cc and Bcc are empty at this point. */
831  mutt_addrlist_qualify(&e->env->to, fqdn);
832  mutt_addrlist_qualify(&e->env->reply_to, fqdn);
834  }
835 
836  return 0;
837 }
838 
846 int mix_send_message(struct ListHead *chain, const char *tempfile)
847 {
848  int i = 0;
849  struct Buffer *cmd = mutt_buffer_pool_get();
850  struct Buffer *cd_quoted = mutt_buffer_pool_get();
851 
852  mutt_buffer_printf(cmd, "cat %s | %s -m ", tempfile, C_Mixmaster);
853 
854  struct ListNode *np = NULL;
855  STAILQ_FOREACH(np, chain, entries)
856  {
857  mutt_buffer_addstr(cmd, (i != 0) ? "," : " -l ");
858  mutt_buffer_quote_filename(cd_quoted, (char *) np->data, true);
859  mutt_buffer_addstr(cmd, mutt_buffer_string(cd_quoted));
860  i = 1;
861  }
862 
863  mutt_endwin();
864 
865  i = mutt_system(cmd->data);
866  if (i != 0)
867  {
868  fprintf(stderr, _("Error sending message, child exited %d\n"), i);
869  if (!OptNoCurses)
870  {
872  mutt_error(_("Error sending message"));
873  }
874  }
875 
877  mutt_buffer_pool_release(&cd_quoted);
878  unlink(tempfile);
879  return i;
880 }
Remailer
A Mixmaster remailer.
Definition: remailer.h:50
mutt_endwin
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:572
mix_send_message
int mix_send_message(struct ListHead *chain, const char *tempfile)
Send an email via Mixmaster.
Definition: remailer.c:846
MixChain::ch
int ch[MAX_MIXES]
Definition: remailer.h:65
Envelope::bcc
struct AddressList bcc
Email's 'Bcc' list.
Definition: envelope.h:60
mutt_window_clrtoeol
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:244
dialog_create_simple_index
struct MuttWindow * dialog_create_simple_index(struct Menu *menu, enum WindowType type)
Create a simple index Dialog.
Definition: dialog.c:165
mix_chain_add
static int mix_chain_add(struct MixChain *chain, const char *s, struct Remailer **type2_list)
Add a host to the chain.
Definition: remailer.c:536
mutt_window_move
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:382
MIX_HOFFSET
#define MIX_HOFFSET
Definition: remailer.c:61
mutt_mem_calloc
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
mix_format_str
static const char * mix_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a string for the remailer menu - Implements format_t.
Definition: remailer.c:453
_
#define _(a)
Definition: message.h:28
NONULL
#define NONULL(x)
Definition: string2.h:37
mutt_window_mvprintw
int mutt_window_mvprintw(struct MuttWindow *win, int col, int row, const char *fmt,...)
Move the cursor and write a formatted string to a Window.
Definition: mutt_window.c:415
Coord::r
short r
row
Definition: remailer.c:70
MIX_CAP_COMPRESS
#define MIX_CAP_COMPRESS
Definition: remailer.h:42
mutt_system
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
Remailer::addr
char * addr
Definition: remailer.h:54
mutt_addrlist_qualify
void mutt_addrlist_qualify(struct AddressList *al, const char *host)
Expand local names in an Address list using a hostname.
Definition: address.c:650
filter_create_fd
pid_t filter_create_fd(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err, int fdin, int fdout, int fderr)
Run a command on a pipe (optionally connect stdin/stdout)
Definition: filter.c:61
MT_COLOR_STATUS
@ MT_COLOR_STATUS
Status bar (takes a pattern)
Definition: color.h:94
ListNode
A List node for strings.
Definition: list.h:34
Buffer
String manipulation buffer.
Definition: buffer.h:33
remailer.h
MAX_MIXES
#define MAX_MIXES
Definition: remailer.h:38
mix_type2_list
static struct Remailer ** mix_type2_list(size_t *l)
parse the type2.list as given by mixmaster -T
Definition: remailer.c:181
format_flags.h
MUTT_FORMAT_ARROWCURSOR
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
Coord::c
short c
column
Definition: remailer.c:71
MixChain::cl
size_t cl
Definition: remailer.h:64
MIX_MAXROW
#define MIX_MAXROW
Definition: remailer.c:63
MuttWindow
A division of the screen.
Definition: mutt_window.h:115
TAILQ_EMPTY
#define TAILQ_EMPTY(head)
Definition: queue.h:714
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
mutt_str_dup
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
mutt_globals.h
MT_COLOR_INDICATOR
@ MT_COLOR_INDICATOR
Selected item in list.
Definition: color.h:73
MixCapFlags
uint8_t MixCapFlags
Flags, e.g. MIX_CAP_NO_FLAGS.
Definition: remailer.h:40
mix_check_message
int mix_check_message(struct Email *e)
Safety-check the message before passing it to mixmaster.
Definition: remailer.c:794
FREE
#define FREE(x)
Definition: memory.h:40
options.h
mutt_menu_new
struct Menu * mutt_menu_new(enum MenuType type)
Create a new Menu.
Definition: menu.c:956
MuttWindow::help_menu
int help_menu
Menu for key bindings, e.g. MENU_PAGER.
Definition: mutt_window.h:134
OptNoCurses
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:48
Menu::make_entry
void(* make_entry)(struct Menu *menu, char *buf, size_t buflen, int line)
Format a item for a menu.
Definition: mutt_menu.h:88
mutt_buffer_pool_release
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
MIX_CAP_NEWSMAIL
#define MIX_CAP_NEWSMAIL
Definition: remailer.h:45
MUTT_FORMAT_NO_FLAGS
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
menu_redraw_status
void menu_redraw_status(struct Menu *menu)
Force the redraw of the status bar.
Definition: menu.c:365
mutt_list_insert_tail
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
STAILQ_FOREACH
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
MT_COLOR_NORMAL
@ MT_COLOR_NORMAL
Plain text.
Definition: color.h:77
RemailerHelp
static const struct Mapping RemailerHelp[]
Help Bar for the Mixmaster dialog.
Definition: remailer.c:75
mutt_istr_equal
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
mix_redraw_ce
static void mix_redraw_ce(struct MuttWindow *win, struct Remailer **type2_list, struct Coord *coords, struct MixChain *chain, int i, bool selected)
Redraw the Remailer chain.
Definition: remailer.c:338
mutt_str_equal
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
Mapping
Mapping between user-readable string and a constant.
Definition: mapping.h:31
lib.h
Envelope::reply_to
struct AddressList reply_to
Email's 'reply-to'.
Definition: envelope.h:62
mix_redraw_chain
static void mix_redraw_chain(struct MuttWindow *win, struct Remailer **type2_list, struct Coord *coords, struct MixChain *chain, int cur)
Redraw the chain on screen.
Definition: remailer.c:367
protos.h
mutt_any_key_to_continue
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:605
MIX_CAP_NO_FLAGS
#define MIX_CAP_NO_FLAGS
No flags are set.
Definition: remailer.h:41
Envelope::cc
struct AddressList cc
Email's 'Cc' list.
Definition: envelope.h:59
mutt_menu_push_current
void mutt_menu_push_current(struct Menu *menu)
Add a new Menu to the stack.
Definition: menu.c:1015
mutt_buffer_pool_get
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
keymap.h
lib.h
muttlib.h
Address::group
bool group
Group mailbox?
Definition: address.h:38
mutt_menu.h
REDRAW_FULL
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:45
lib.h
lib.h
Menu::pagelen
int pagelen
Number of entries per screen.
Definition: mutt_menu.h:60
Remailer::shortname
char * shortname
Definition: remailer.h:53
mix_type2_list_free
static void mix_type2_list_free(struct Remailer ***ttlp)
Free a Remailer List.
Definition: remailer.c:271
Envelope::to
struct AddressList to
Email's 'To' list.
Definition: envelope.h:58
mix_format_caps
static const char * mix_format_caps(struct Remailer *r)
Turn flags into a MixMaster capability string.
Definition: remailer.c:401
mutt_mem_realloc
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
Email::env
struct Envelope * env
Envelope information.
Definition: email.h:90
Menu::tag
int(* tag)(struct Menu *menu, int sel, int act)
Tag some menu items.
Definition: mutt_menu.h:107
Menu::title
const char * title
Title of this menu.
Definition: mutt_menu.h:54
Remailer::num
int num
Definition: remailer.h:52
mutt_buffer_string
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
MIX_CAP_NEWSPOST
#define MIX_CAP_NEWSPOST
Definition: remailer.h:44
MuttWindow::help_data
const struct Mapping * help_data
Data for the Help Bar.
Definition: mutt_window.h:135
filter_wait
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
MUTT_FORMAT_OPTIONAL
#define MUTT_FORMAT_OPTIONAL
Allow optional field processing.
Definition: format_flags.h:33
C_MixEntryFormat
char * C_MixEntryFormat
Config: (mixmaster) printf-like format string for the mixmaster chain.
Definition: remailer.c:58
mutt_menu_loop
int mutt_menu_loop(struct Menu *menu)
Menu event loop.
Definition: menu.c:1309
MuttWindow::state
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:120
Address::mailbox
char * mailbox
Mailbox and host address.
Definition: address.h:37
lib.h
mutt_menu_pop_current
void mutt_menu_pop_current(struct Menu *menu)
Remove a Menu from the stack.
Definition: menu.c:1027
C_Mixmaster
char * C_Mixmaster
Config: (mixmaster) External command to route a mixmaster message.
Definition: remailer.c:59
lib.h
remailer_free
static void remailer_free(struct Remailer **ptr)
Free a Remailer.
Definition: remailer.c:163
mix_redraw_head
static void mix_redraw_head(struct MuttWindow *win, struct MixChain *chain)
Redraw the Chain info.
Definition: remailer.c:385
Menu::mdata
void * mdata
Extra data for the current menu.
Definition: mutt_menu.h:55
mutt_expando_format
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:774
MIX_CAP_MIDDLEMAN
#define MIX_CAP_MIDDLEMAN
Definition: remailer.h:43
Menu::max
int max
Number of entries in the menu.
Definition: mutt_menu.h:57
mix_screen_coordinates
static void mix_screen_coordinates(struct MuttWindow *win, struct Remailer **type2_list, struct Coord **coordsp, struct MixChain *chain, int i)
Get the screen coordinates to place a chain.
Definition: remailer.c:289
Remailer::ver
char * ver
Definition: remailer.h:55
NeoMutt
Container for Accounts, Notifications.
Definition: neomutt.h:36
mutt.h
Coord
Screen coordinates.
Definition: remailer.c:68
MIX_VOFFSET
#define MIX_VOFFSET
Definition: remailer.c:62
mutt_curses_set_color
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:57
recvattach.h
Menu::redraw
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:58
ListNode::data
char * data
String.
Definition: list.h:36
MENU_MIX
@ MENU_MIX
Create/edit a Mixmaster chain.
Definition: keymap.h:91
NeoMutt::sub
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
mix_get_caps
static MixCapFlags mix_get_caps(const char *capstr)
Get Mixmaster Capabilities.
Definition: remailer.c:91
mutt_buffer_addstr
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
mutt_window_mvaddstr
int mutt_window_mvaddstr(struct MuttWindow *win, int col, int row, const char *str)
Move the cursor and write a fixed string to a Window.
Definition: mutt_window.c:396
WindowState::cols
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:57
dialog_destroy_simple_index
void dialog_destroy_simple_index(struct MuttWindow **ptr)
Destroy a simple index Dialog.
Definition: dialog.c:209
Menu::current
int current
Current entry.
Definition: mutt_menu.h:56
mutt_buffer_quote_filename
void mutt_buffer_quote_filename(struct Buffer *buf, const char *filename, bool add_outer)
Quote a filename to survive the shell's quoting rules.
Definition: file.c:836
Remailer::caps
MixCapFlags caps
Definition: remailer.h:56
opcodes.h
mutt_fqdn
const char * mutt_fqdn(bool may_hide_host, const struct ConfigSubset *sub)
Get the Fully-Qualified Domain Name.
Definition: sendlib.c:1182
mutt_window_addstr
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:522
Buffer::data
char * data
Pointer to data.
Definition: buffer.h:35
Email
The envelope/body of an email.
Definition: email.h:37
lib.h
Envelope::mail_followup_to
struct AddressList mail_followup_to
Email's 'mail-followup-to'.
Definition: envelope.h:63
mutt_buffer_printf
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
MixChain
A Mixmaster chain.
Definition: remailer.h:62
Menu::win_index
struct MuttWindow * win_index
Definition: mutt_menu.h:63
mutt_list_free
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
Menu
GUI selectable list of items.
Definition: mutt_menu.h:52
WT_DLG_REMAILER
@ WT_DLG_REMAILER
Remailer Dialog, dlg_select_mixmaster_chain()
Definition: mutt_window.h:88
N_
#define N_(a)
Definition: message.h:32
dlg_select_mixmaster_chain
void dlg_select_mixmaster_chain(struct MuttWindow *win, struct ListHead *chainhead, int cols)
Create a Mixmaster chain.
Definition: remailer.c:574
remailer_new
static struct Remailer * remailer_new(void)
Create a new Remailer.
Definition: remailer.c:154
Address
An email address.
Definition: address.h:34
MuttFormatFlags
uint8_t MuttFormatFlags
Flags for mutt_expando_format(), e.g. MUTT_FORMAT_FORCESUBJ.
Definition: format_flags.h:29
mutt_menu_free
void mutt_menu_free(struct Menu **ptr)
Destroy a menu.
Definition: menu.c:972
mix_make_entry
static void mix_make_entry(struct Menu *menu, char *buf, size_t buflen, int num)
Format a menu item for the mixmaster chain list - Implements Menu::make_entry()
Definition: remailer.c:520
mix_add_entry
static void mix_add_entry(struct Remailer ***type2_list, struct Remailer *entry, size_t *slots, size_t *used)
Add an entry to the Remailer list.
Definition: remailer.c:136
mutt_error
#define mutt_error(...)
Definition: logging.h:84