NeoMutt  2018-07-16 +2481-68dcde
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/mutt.h"
37 #include "address/lib.h"
38 #include "email/lib.h"
39 #include "mutt.h"
40 #include "curs_lib.h"
41 #include "filter.h"
42 #include "format_flags.h"
43 #include "keymap.h"
44 #include "mutt_curses.h"
45 #include "mutt_menu.h"
46 #include "mutt_window.h"
47 #include "muttlib.h"
48 #include "opcodes.h"
49 #include "options.h"
50 #include "protos.h"
51 #include "recvattach.h"
52 #include "sendlib.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 
64 struct Coord
65 {
66  short r;
67  short c;
68 };
69 
75 static MixCapFlags mix_get_caps(const char *capstr)
76 {
78 
79  while (*capstr)
80  {
81  switch (*capstr)
82  {
83  case 'C':
84  caps |= MIX_CAP_COMPRESS;
85  break;
86 
87  case 'M':
88  caps |= MIX_CAP_MIDDLEMAN;
89  break;
90 
91  case 'N':
92  {
93  switch (*++capstr)
94  {
95  case 'm':
96  caps |= MIX_CAP_NEWSMAIL;
97  break;
98 
99  case 'p':
100  caps |= MIX_CAP_NEWSPOST;
101  break;
102  }
103  }
104  }
105 
106  if (*capstr)
107  capstr++;
108  }
109 
110  return caps;
111 }
112 
120 static void mix_add_entry(struct Remailer ***type2_list, struct Remailer *entry,
121  size_t *slots, size_t *used)
122 {
123  if (*used == *slots)
124  {
125  *slots += 5;
126  mutt_mem_realloc(type2_list, sizeof(struct Remailer *) * (*slots));
127  }
128 
129  (*type2_list)[(*used)++] = entry;
130  if (entry)
131  entry->num = *used;
132 }
133 
138 static struct Remailer *remailer_new(void)
139 {
140  return mutt_mem_calloc(1, sizeof(struct Remailer));
141 }
142 
147 static void remailer_free(struct Remailer **ptr)
148 {
149  if (!ptr || !*ptr)
150  return;
151 
152  struct Remailer *r = *ptr;
153 
154  FREE(&r->shortname);
155  FREE(&r->addr);
156  FREE(&r->ver);
157  FREE(ptr);
158 }
159 
165 static struct Remailer **mix_type2_list(size_t *l)
166 {
167  if (!l)
168  return NULL;
169 
170  FILE *fp = NULL;
171  char line[8192];
172  char *t = NULL;
173 
174  struct Remailer **type2_list = NULL;
175  struct Remailer *p = NULL;
176  size_t slots = 0, used = 0;
177 
178  int fd_null = open("/dev/null", O_RDWR);
179  if (fd_null == -1)
180  return NULL;
181 
182  struct Buffer *cmd = mutt_buffer_pool_get();
183  mutt_buffer_printf(cmd, "%s -T", C_Mixmaster);
184 
185  pid_t mm_pid =
186  mutt_create_filter_fd(mutt_b2s(cmd), NULL, &fp, NULL, fd_null, -1, fd_null);
187  if (mm_pid == -1)
188  {
190  close(fd_null);
191  return NULL;
192  }
193 
195 
196  /* first, generate the "random" remailer */
197 
198  p = remailer_new();
199  p->shortname = mutt_str_strdup(_("<random>"));
200  mix_add_entry(&type2_list, p, &slots, &used);
201 
202  while (fgets(line, sizeof(line), fp))
203  {
204  p = remailer_new();
205 
206  t = strtok(line, " \t\n");
207  if (!t)
208  goto problem;
209 
210  p->shortname = mutt_str_strdup(t);
211 
212  t = strtok(NULL, " \t\n");
213  if (!t)
214  goto problem;
215 
216  p->addr = mutt_str_strdup(t);
217 
218  t = strtok(NULL, " \t\n");
219  if (!t)
220  goto problem;
221 
222  t = strtok(NULL, " \t\n");
223  if (!t)
224  goto problem;
225 
226  p->ver = mutt_str_strdup(t);
227 
228  t = strtok(NULL, " \t\n");
229  if (!t)
230  goto problem;
231 
232  p->caps = mix_get_caps(t);
233 
234  mix_add_entry(&type2_list, p, &slots, &used);
235  continue;
236 
237  problem:
238  remailer_free(&p);
239  }
240 
241  *l = used;
242 
243  mix_add_entry(&type2_list, NULL, &slots, &used);
244  mutt_wait_filter(mm_pid);
245 
246  close(fd_null);
247 
248  return type2_list;
249 }
250 
255 static void mix_type2_list_free(struct Remailer ***ttlp)
256 {
257  struct Remailer **type2_list = *ttlp;
258 
259  for (int i = 0; type2_list[i]; i++)
260  remailer_free(&type2_list[i]);
261 
262  FREE(type2_list);
263 }
264 
265 #define MIX_HOFFSET 2
266 #define MIX_VOFFSET (MuttIndexWindow->rows - 4)
267 #define MIX_MAXROW (MuttIndexWindow->rows - 1)
268 
276 static void mix_screen_coordinates(struct Remailer **type2_list, struct Coord **coordsp,
277  struct MixChain *chain, int i)
278 {
279  if (!chain->cl)
280  return;
281 
282  short c, r;
283 
284  mutt_mem_realloc(coordsp, sizeof(struct Coord) * chain->cl);
285 
286  struct Coord *coords = *coordsp;
287 
288  if (i)
289  {
290  c = coords[i - 1].c + strlen(type2_list[chain->ch[i - 1]]->shortname) + 2;
291  r = coords[i - 1].r;
292  }
293  else
294  {
295  r = MIX_VOFFSET;
296  c = MIX_HOFFSET;
297  }
298 
299  for (; i < chain->cl; i++)
300  {
301  short oc = c;
302  c += strlen(type2_list[chain->ch[i]]->shortname) + 2;
303 
304  if (c >= MuttIndexWindow->cols)
305  {
306  oc = MIX_HOFFSET;
307  c = MIX_HOFFSET;
308  r++;
309  }
310 
311  coords[i].c = oc;
312  coords[i].r = r;
313  }
314 }
315 
324 static void mix_redraw_ce(struct Remailer **type2_list, struct Coord *coords,
325  struct MixChain *chain, int i, bool selected)
326 {
327  if (!coords || !chain)
328  return;
329 
330  if (coords[i].r < MIX_MAXROW)
331  {
332  if (selected)
334  else
335  NORMAL_COLOR;
336 
337  mutt_window_mvaddstr(MuttIndexWindow, coords[i].r, coords[i].c,
338  type2_list[chain->ch[i]]->shortname);
339  NORMAL_COLOR;
340 
341  if (i + 1 < chain->cl)
342  addstr(", ");
343  }
344 }
345 
353 static void mix_redraw_chain(struct Remailer **type2_list, struct Coord *coords,
354  struct MixChain *chain, int cur)
355 {
356  for (int i = MIX_VOFFSET; i < MIX_MAXROW; i++)
357  {
360  }
361 
362  for (int i = 0; i < chain->cl; i++)
363  mix_redraw_ce(type2_list, coords, chain, i, i == cur);
364 }
365 
370 static void mix_redraw_head(struct MixChain *chain)
371 {
374  "-- Remailer chain [Length: %d]", chain ? chain->cl : 0);
376  NORMAL_COLOR;
377 }
378 
386 static const char *mix_format_caps(struct Remailer *r)
387 {
388  static char capbuf[10];
389  char *t = capbuf;
390 
391  if (r->caps & MIX_CAP_COMPRESS)
392  *t++ = 'C';
393  else
394  *t++ = ' ';
395 
396  if (r->caps & MIX_CAP_MIDDLEMAN)
397  *t++ = 'M';
398  else
399  *t++ = ' ';
400 
401  if (r->caps & MIX_CAP_NEWSPOST)
402  {
403  *t++ = 'N';
404  *t++ = 'p';
405  }
406  else
407  {
408  *t++ = ' ';
409  *t++ = ' ';
410  }
411 
412  if (r->caps & MIX_CAP_NEWSMAIL)
413  {
414  *t++ = 'N';
415  *t++ = 'm';
416  }
417  else
418  {
419  *t++ = ' ';
420  *t++ = ' ';
421  }
422 
423  *t = '\0';
424 
425  return capbuf;
426 }
427 
438 static const char *mix_format_str(char *buf, size_t buflen, size_t col, int cols,
439  char op, const char *src, const char *prec,
440  const char *if_str, const char *else_str,
441  unsigned long data, MuttFormatFlags flags)
442 {
443  char fmt[128];
444  struct Remailer *remailer = (struct Remailer *) data;
445  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
446 
447  switch (op)
448  {
449  case 'a':
450  if (!optional)
451  {
452  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
453  snprintf(buf, buflen, fmt, NONULL(remailer->addr));
454  }
455  else if (!remailer->addr)
456  optional = false;
457  break;
458 
459  case 'c':
460  if (!optional)
461  {
462  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
463  snprintf(buf, buflen, fmt, mix_format_caps(remailer));
464  }
465  break;
466 
467  case 'n':
468  if (!optional)
469  {
470  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
471  snprintf(buf, buflen, fmt, remailer->num);
472  }
473  break;
474 
475  case 's':
476  if (!optional)
477  {
478  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
479  snprintf(buf, buflen, fmt, NONULL(remailer->shortname));
480  }
481  else if (!remailer->shortname)
482  optional = false;
483  break;
484 
485  default:
486  *buf = '\0';
487  }
488 
489  if (optional)
490  mutt_expando_format(buf, buflen, col, cols, if_str, attach_format_str, data,
492  else if (flags & MUTT_FORMAT_OPTIONAL)
493  mutt_expando_format(buf, buflen, col, cols, else_str, attach_format_str,
494  data, MUTT_FORMAT_NO_FLAGS);
495  return src;
496 }
497 
505 static void mix_entry(char *buf, size_t buflen, struct Menu *menu, int num)
506 {
507  struct Remailer **type2_list = menu->data;
508  mutt_expando_format(buf, buflen, 0, menu->indexwin->cols,
510  (unsigned long) type2_list[num], MUTT_FORMAT_ARROWCURSOR);
511 }
512 
521 static int mix_chain_add(struct MixChain *chain, const char *s, struct Remailer **type2_list)
522 {
523  int i;
524 
525  if (chain->cl >= MAX_MIXES)
526  return -1;
527 
528  if ((mutt_str_strcmp(s, "0") == 0) || (mutt_str_strcasecmp(s, "<random>") == 0))
529  {
530  chain->ch[chain->cl++] = 0;
531  return 0;
532  }
533 
534  for (i = 0; type2_list[i]; i++)
535  {
536  if (mutt_str_strcasecmp(s, type2_list[i]->shortname) == 0)
537  {
538  chain->ch[chain->cl++] = i;
539  return 0;
540  }
541  }
542 
543  /* replace unknown remailers by <random> */
544 
545  if (!type2_list[i])
546  chain->ch[chain->cl++] = 0;
547 
548  return 0;
549 }
550 
551 static const struct Mapping RemailerHelp[] = {
552  { N_("Append"), OP_MIX_APPEND }, { N_("Insert"), OP_MIX_INSERT },
553  { N_("Delete"), OP_MIX_DELETE }, { N_("Abort"), OP_EXIT },
554  { N_("OK"), OP_MIX_USE }, { NULL, 0 },
555 };
556 
563 void mix_make_chain(struct ListHead *chainhead)
564 {
565  int c_cur = 0, c_old = 0;
566  bool c_redraw = true;
567  size_t ttll = 0;
568 
569  struct Coord *coords = NULL;
570 
571  struct Menu *menu = NULL;
572  char helpstr[1024];
573  bool loop = true;
574 
575  char *t = NULL;
576 
577  struct Remailer **type2_list = mix_type2_list(&ttll);
578  if (!type2_list)
579  {
580  mutt_error(_("Can't get mixmaster's type2.list"));
581  return;
582  }
583 
584  struct MixChain *chain = mutt_mem_calloc(1, sizeof(struct MixChain));
585 
586  struct ListNode *p = NULL;
587  STAILQ_FOREACH(p, chainhead, entries)
588  {
589  mix_chain_add(chain, p->data, type2_list);
590  }
591  mutt_list_free(chainhead);
592 
593  /* safety check */
594  for (int i = 0; i < chain->cl; i++)
595  {
596  if (chain->ch[i] >= ttll)
597  chain->ch[i] = 0;
598  }
599 
600  mix_screen_coordinates(type2_list, &coords, chain, 0);
601 
602  menu = mutt_menu_new(MENU_MIX);
603  menu->max = ttll;
604  menu->menu_make_entry = mix_entry;
605  menu->menu_tag = NULL;
606  menu->title = _("Select a remailer chain");
607  menu->data = type2_list;
608  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_MIX, RemailerHelp);
609  menu->pagelen = MIX_VOFFSET - 1;
611 
612  while (loop)
613  {
614  if (menu->pagelen != MIX_VOFFSET - 1)
615  {
616  menu->pagelen = MIX_VOFFSET - 1;
617  menu->redraw = REDRAW_FULL;
618  }
619 
620  if (c_redraw)
621  {
622  mix_redraw_head(chain);
623  mix_redraw_chain(type2_list, coords, chain, c_cur);
624  c_redraw = false;
625  }
626  else if (c_cur != c_old)
627  {
628  mix_redraw_ce(type2_list, coords, chain, c_old, false);
629  mix_redraw_ce(type2_list, coords, chain, c_cur, true);
630  }
631 
632  c_old = c_cur;
633 
634  const int op = mutt_menu_loop(menu);
635  switch (op)
636  {
637  case OP_REDRAW:
638  {
639  menu_redraw_status(menu);
640  mix_redraw_head(chain);
641  mix_screen_coordinates(type2_list, &coords, chain, 0);
642  mix_redraw_chain(type2_list, coords, chain, c_cur);
643  menu->pagelen = MIX_VOFFSET - 1;
644  break;
645  }
646 
647  case OP_EXIT:
648  {
649  chain->cl = 0;
650  loop = false;
651  break;
652  }
653 
654  case OP_MIX_USE:
655  {
656  if (!chain->cl)
657  {
658  chain->cl++;
659  chain->ch[0] = menu->current;
660  mix_screen_coordinates(type2_list, &coords, chain, c_cur);
661  c_redraw = true;
662  }
663 
664  if (chain->cl && chain->ch[chain->cl - 1] &&
665  (type2_list[chain->ch[chain->cl - 1]]->caps & MIX_CAP_MIDDLEMAN))
666  {
667  mutt_error(
668  _("Error: %s can't be used as the final remailer of a chain"),
669  type2_list[chain->ch[chain->cl - 1]]->shortname);
670  }
671  else
672  {
673  loop = false;
674  }
675  break;
676  }
677 
678  case OP_GENERIC_SELECT_ENTRY:
679  case OP_MIX_APPEND:
680  {
681  if ((chain->cl < MAX_MIXES) && (c_cur < chain->cl))
682  c_cur++;
683  }
684  /* fallthrough */
685  case OP_MIX_INSERT:
686  {
687  if (chain->cl < MAX_MIXES)
688  {
689  chain->cl++;
690  for (int i = chain->cl - 1; i > c_cur; i--)
691  chain->ch[i] = chain->ch[i - 1];
692 
693  chain->ch[c_cur] = menu->current;
694  mix_screen_coordinates(type2_list, &coords, chain, c_cur);
695  c_redraw = true;
696  }
697  else
698  {
699  /* L10N The '%d' here hard-coded to 19 */
700  mutt_error(_("Mixmaster chains are limited to %d elements"), MAX_MIXES);
701  }
702 
703  break;
704  }
705 
706  case OP_MIX_DELETE:
707  {
708  if (chain->cl)
709  {
710  chain->cl--;
711 
712  for (int i = c_cur; i < chain->cl; i++)
713  chain->ch[i] = chain->ch[i + 1];
714 
715  if ((c_cur == chain->cl) && c_cur)
716  c_cur--;
717 
718  mix_screen_coordinates(type2_list, &coords, chain, c_cur);
719  c_redraw = true;
720  }
721  else
722  {
723  mutt_error(_("The remailer chain is already empty"));
724  }
725  break;
726  }
727 
728  case OP_MIX_CHAIN_PREV:
729  {
730  if (c_cur)
731  c_cur--;
732  else
733  mutt_error(_("You already have the first chain element selected"));
734 
735  break;
736  }
737 
738  case OP_MIX_CHAIN_NEXT:
739  {
740  if (chain->cl && (c_cur < chain->cl - 1))
741  c_cur++;
742  else
743  mutt_error(_("You already have the last chain element selected"));
744 
745  break;
746  }
747  }
748  }
749 
750  mutt_menu_pop_current(menu);
751  mutt_menu_free(&menu);
752 
753  /* construct the remailer list */
754 
755  if (chain->cl)
756  {
757  for (int i = 0; i < chain->cl; i++)
758  {
759  const int j = chain->ch[i];
760  if (j != 0)
761  t = type2_list[j]->shortname;
762  else
763  t = "*";
764 
765  mutt_list_insert_tail(chainhead, mutt_str_strdup(t));
766  }
767  }
768 
769  mix_type2_list_free(&type2_list);
770  FREE(&coords);
771  FREE(&chain);
772 }
773 
780 int mix_check_message(struct Email *e)
781 {
782  bool need_hostname = false;
783 
784  if (!TAILQ_EMPTY(&e->env->cc) || !TAILQ_EMPTY(&e->env->bcc))
785  {
786  mutt_error(_("Mixmaster doesn't accept Cc or Bcc headers"));
787  return -1;
788  }
789 
790  /* When using mixmaster, we MUST qualify any addresses since
791  * the message will be delivered through remote systems.
792  *
793  * use_domain won't be respected at this point, hidden_host will.
794  */
795 
796  struct Address *a = NULL;
797  TAILQ_FOREACH(a, &e->env->to, entries)
798  {
799  if (!a->group && !strchr(a->mailbox, '@'))
800  {
801  need_hostname = true;
802  break;
803  }
804  }
805 
806  if (need_hostname)
807  {
808  const char *fqdn = mutt_fqdn(true);
809  if (!fqdn)
810  {
811  mutt_error(_("Please set the hostname variable to a proper value when "
812  "using mixmaster"));
813  return -1;
814  }
815 
816  /* Cc and Bcc are empty at this point. */
817  mutt_addrlist_qualify(&e->env->to, fqdn);
818  mutt_addrlist_qualify(&e->env->reply_to, fqdn);
820  }
821 
822  return 0;
823 }
824 
832 int mix_send_message(struct ListHead *chain, const char *tempfile)
833 {
834  int i = 0;
835  struct Buffer *cmd = mutt_buffer_pool_get();
836  struct Buffer *cd_quoted = mutt_buffer_pool_get();
837 
838  mutt_buffer_printf(cmd, "cat %s | %s -m ", tempfile, C_Mixmaster);
839 
840  struct ListNode *np = NULL;
841  STAILQ_FOREACH(np, chain, entries)
842  {
843  mutt_buffer_addstr(cmd, (i != 0) ? "," : " -l ");
844  mutt_buffer_quote_filename(cd_quoted, (char *) np->data, true);
845  mutt_buffer_addstr(cmd, mutt_b2s(cd_quoted));
846  i = 1;
847  }
848 
849  mutt_endwin();
850 
851  i = mutt_system(cmd->data);
852  if (i != 0)
853  {
854  fprintf(stderr, _("Error sending message, child exited %d.\n"), i);
855  if (!OptNoCurses)
856  {
858  mutt_error(_("Error sending message"));
859  }
860  }
861 
863  mutt_buffer_pool_release(&cd_quoted);
864  unlink(tempfile);
865  return i;
866 }
#define MIX_VOFFSET
Definition: remailer.c:266
void mutt_buffer_quote_filename(struct Buffer *buf, const char *filename, bool add_outer)
Quote a filename to survive the shell&#39;s quoting rules.
Definition: file.c:832
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, unsigned long data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:844
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:47
Manage keymappings.
uint8_t MuttFormatFlags
Flags for mutt_expando_format(), e.g. MUTT_FORMAT_FORCESUBJ.
Definition: format_flags.h:29
#define NONULL(x)
Definition: string2.h:37
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
Define wrapper functions around Curses/Slang.
#define MIX_CAP_NEWSPOST
Definition: remailer.h:43
The envelope/body of an email.
Definition: email.h:39
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:100
static const char * mix_format_caps(struct Remailer *r)
Turn flags into a MixMaster capability string.
Definition: remailer.c:386
GUI selectable list of items.
Definition: mutt_menu.h:82
struct AddressList mail_followup_to
Email&#39;s &#39;mail-followup-to&#39;.
Definition: envelope.h:63
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:719
Window management.
A Mixmaster chain.
Definition: remailer.h:61
int ch[MAX_MIXES]
Definition: remailer.h:64
GUI miscellaneous curses (window drawing) routines.
Structs that make up an email.
static void mix_redraw_chain(struct Remailer **type2_list, struct Coord *coords, struct MixChain *chain, int cur)
Redraw the chain on screen.
Definition: remailer.c:353
struct AddressList reply_to
Email&#39;s &#39;reply-to&#39;.
Definition: envelope.h:62
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
#define NORMAL_COLOR
Definition: mutt_curses.h:239
Pass files through external commands (filters)
short r
row
Definition: remailer.c:66
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:107
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:111
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
MixCapFlags caps
Definition: remailer.h:55
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
An email address.
Definition: address.h:34
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:46
char * mailbox
Mailbox and host address.
Definition: address.h:37
int num
Definition: remailer.h:51
static void mix_screen_coordinates(struct Remailer **type2_list, struct Coord **coordsp, struct MixChain *chain, int i)
Get the screen coordinates to place a chain.
Definition: remailer.c:276
char * C_MixEntryFormat
Config: (mixmaster) printf-like format string for the mixmaster chain.
Definition: remailer.c:58
static void mix_redraw_head(struct MixChain *chain)
Redraw the Chain info.
Definition: remailer.c:370
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
Flags to control mutt_expando_format()
All user-callable functions.
void(* menu_make_entry)(char *buf, size_t buflen, struct Menu *menu, int line)
Format a item for a menu.
Definition: mutt_menu.h:120
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:123
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
Email Address Handling.
Some miscellaneous functions.
char * C_Mixmaster
Config: (mixmaster) External command to route a mixmaster message.
Definition: remailer.c:59
static void remailer_free(struct Remailer **ptr)
Free a Remailer.
Definition: remailer.c:147
struct Envelope * env
Envelope information.
Definition: email.h:91
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
static void mix_entry(char *buf, size_t buflen, struct Menu *menu, int num)
Format a menu item for the mixmaster chain list.
Definition: remailer.c:505
#define MIX_MAXROW
Definition: remailer.c:267
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:120
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
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, unsigned long data, MuttFormatFlags flags)
Format a string for the remailer menu - Implements format_t.
Definition: remailer.c:438
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:65
#define mutt_b2s(buf)
Definition: buffer.h:41
Prototypes for many functions.
const char * line
Definition: common.c:36
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:499
uint8_t MixCapFlags
Flags, e.g. MIX_CAP_NO_FLAGS.
Definition: remailer.h:39
#define MIX_CAP_NO_FLAGS
No flags are set.
Definition: remailer.h:40
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:40
struct MuttWindow * indexwin
Definition: mutt_menu.h:95
char * data
Pointer to data.
Definition: buffer.h:35
pid_t mutt_create_filter_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:65
GUI present the user with a selectable list.
char * shortname
Definition: remailer.h:52
void mix_make_chain(struct ListHead *chainhead)
Create a Mixmaster chain.
Definition: remailer.c:563
int mix_send_message(struct ListHead *chain, const char *tempfile)
Send an email via Mixmaster.
Definition: remailer.c:832
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
#define MIX_CAP_NEWSMAIL
Definition: remailer.h:44
int pagelen
Number of entries per screen.
Definition: mutt_menu.h:92
size_t cl
Definition: remailer.h:63
#define SET_COLOR(X)
Definition: mutt_curses.h:224
int mutt_window_mvaddstr(struct MuttWindow *win, int row, int col, const char *str)
Move the cursor and write a fixed string to a Window.
Definition: mutt_window.c:202
#define MIX_CAP_MIDDLEMAN
Definition: remailer.h:42
const char * mutt_fqdn(bool may_hide_host)
Get the Fully-Qualified Domain Name.
Definition: sendlib.c:2527
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:188
int max
Number of entries in the menu.
Definition: mutt_menu.h:88
int(* menu_tag)(struct Menu *menu, int sel, int act)
Tag some menu items.
Definition: mutt_menu.h:137
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:89
#define MIX_HOFFSET
Definition: remailer.c:265
char * title
Title of this menu.
Definition: mutt_menu.h:84
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:532
static void mix_type2_list_free(struct Remailer ***ttlp)
Free a Remailer List.
Definition: remailer.c:255
static void mix_redraw_ce(struct Remailer **type2_list, struct Coord *coords, struct MixChain *chain, int i, bool selected)
Redraw the Remailer chain.
Definition: remailer.c:324
void mutt_addrlist_qualify(struct AddressList *al, const char *host)
Expand local names in an Address list using a hostname.
Definition: address.c:640
char * data
String.
Definition: list.h:35
Routines for managing attachments.
bool group
Group mailbox?
Definition: address.h:38
static MixCapFlags mix_get_caps(const char *capstr)
Get Mixmaster Capabilities.
Definition: remailer.c:75
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
const char * attach_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, unsigned long data, MuttFormatFlags flags)
Format a string for the attachment menu - Implements format_t.
Definition: recvattach.c:210
#define mutt_error(...)
Definition: logging.h:84
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
#define FREE(x)
Definition: memory.h:40
Status bar.
Definition: mutt_curses.h:129
void * data
Extra data for the current menu.
Definition: mutt_menu.h:86
Mapping between user-readable string and a constant.
Definition: mapping.h:29
#define MIX_CAP_COMPRESS
Definition: remailer.h:41
#define MUTT_FORMAT_OPTIONAL
Allow optional field processing.
Definition: format_flags.h:33
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
int mutt_window_mvprintw(struct MuttWindow *win, int row, int col, const char *fmt,...)
Move the cursor and write a formatted string to a Window.
Definition: mutt_window.c:217
static struct Remailer * remailer_new(void)
Create a new Remailer.
Definition: remailer.c:138
Handling of global boolean variables.
Miscellaneous functions for sending an email.
static int mix_chain_add(struct MixChain *chain, const char *s, struct Remailer **type2_list)
Add a host to the chain.
Definition: remailer.c:521
#define TAILQ_EMPTY(head)
Definition: queue.h:715
Selected item in list.
Definition: mutt_curses.h:128
char * addr
Definition: remailer.h:53
int current
Current entry.
Definition: mutt_menu.h:87
int mutt_wait_filter(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:228
char * mutt_compile_help(char *buf, size_t buflen, enum MenuType menu, const struct Mapping *items)
Create the text for the help menu.
Definition: help.c:115
A List node for strings.
Definition: list.h:33
#define N_(a)
Definition: message.h:32
static struct Remailer ** mix_type2_list(size_t *l)
parse the type2.list as given by mixmaster -T
Definition: remailer.c:165
Convenience wrapper for the library headers.
char * help
Quickref for the current menu.
Definition: mutt_menu.h:85
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
#define MAX_MIXES
Definition: remailer.h:37
Screen coordinates.
Definition: remailer.c:64
Support of Mixmaster anonymous remailer.
int mix_check_message(struct Email *e)
Safety-check the message before passing it to mixmaster.
Definition: remailer.c:780
char * ver
Definition: remailer.h:54
short c
column
Definition: remailer.c:67
A Mixmaster remailer.
Definition: remailer.h:49