NeoMutt  2020-11-20
Teaching an old dog new tricks
DOXYGEN
remailer.c File Reference

Support of Mixmaster anonymous remailer. More...

#include "config.h"
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "mutt/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "send/lib.h"
#include "format_flags.h"
#include "keymap.h"
#include "mutt_globals.h"
#include "mutt_menu.h"
#include "muttlib.h"
#include "opcodes.h"
#include "options.h"
#include "protos.h"
#include "recvattach.h"
#include "remailer.h"
+ Include dependency graph for remailer.c:

Go to the source code of this file.

Data Structures

struct  Coord
 Screen coordinates. More...
 

Macros

#define MIX_HOFFSET   2
 
#define MIX_VOFFSET   (win->state.rows - 4)
 
#define MIX_MAXROW   (win->state.rows - 1)
 

Functions

static MixCapFlags mix_get_caps (const char *capstr)
 Get Mixmaster Capabilities. More...
 
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. More...
 
static struct Remailerremailer_new (void)
 Create a new Remailer. More...
 
static void remailer_free (struct Remailer **ptr)
 Free a Remailer. More...
 
static struct Remailer ** mix_type2_list (size_t *l)
 parse the type2.list as given by mixmaster -T More...
 
static void mix_type2_list_free (struct Remailer ***ttlp)
 Free a Remailer List. More...
 
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. More...
 
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. More...
 
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. More...
 
static void mix_redraw_head (struct MuttWindow *win, struct MixChain *chain)
 Redraw the Chain info. More...
 
static const char * mix_format_caps (struct Remailer *r)
 Turn flags into a MixMaster capability string. More...
 
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. More...
 
static void mix_make_entry (char *buf, size_t buflen, struct Menu *menu, int num)
 Format a menu item for the mixmaster chain list - Implements Menu::make_entry() More...
 
static int mix_chain_add (struct MixChain *chain, const char *s, struct Remailer **type2_list)
 Add a host to the chain. More...
 
void dlg_select_mixmaster_chain (struct MuttWindow *win, struct ListHead *chainhead, int cols)
 Create a Mixmaster chain. More...
 
int mix_check_message (struct Email *e)
 Safety-check the message before passing it to mixmaster. More...
 
int mix_send_message (struct ListHead *chain, const char *tempfile)
 Send an email via Mixmaster. More...
 

Variables

char * C_MixEntryFormat
 Config: (mixmaster) printf-like format string for the mixmaster chain. More...
 
char * C_Mixmaster
 Config: (mixmaster) External command to route a mixmaster message. More...
 
static const struct Mapping RemailerHelp []
 Help Bar for the Mixmaster dialog. More...
 

Detailed Description

Support of Mixmaster anonymous remailer.

Authors
  • Thomas Roessler
  • Pietro Cerutti

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file remailer.c.

Macro Definition Documentation

◆ MIX_HOFFSET

#define MIX_HOFFSET   2

Definition at line 61 of file remailer.c.

◆ MIX_VOFFSET

#define MIX_VOFFSET   (win->state.rows - 4)

Definition at line 62 of file remailer.c.

◆ MIX_MAXROW

#define MIX_MAXROW   (win->state.rows - 1)

Definition at line 63 of file remailer.c.

Function Documentation

◆ mix_get_caps()

static MixCapFlags mix_get_caps ( const char *  capstr)
static

Get Mixmaster Capabilities.

Parameters
capstrCapability string to parse
Return values
numCapabilities, see MixCapFlags

Definition at line 91 of file remailer.c.

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 }
#define MIX_CAP_NEWSPOST
Definition: remailer.h:44
uint8_t MixCapFlags
Flags, e.g. MIX_CAP_NO_FLAGS.
Definition: remailer.h:40
#define MIX_CAP_NO_FLAGS
No flags are set.
Definition: remailer.h:41
#define MIX_CAP_NEWSMAIL
Definition: remailer.h:45
#define MIX_CAP_MIDDLEMAN
Definition: remailer.h:43
#define MIX_CAP_COMPRESS
Definition: remailer.h:42
+ Here is the caller graph for this function:

◆ mix_add_entry()

static void mix_add_entry ( struct Remailer ***  type2_list,
struct Remailer entry,
size_t *  slots,
size_t *  used 
)
static

Add an entry to the Remailer list.

Parameters
[out]type2_listRemailer list to add to
[in]entryRemailer to add
[out]slotsTotal number of slots
[out]usedNumber of slots used

Definition at line 136 of file remailer.c.

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 }
int num
Definition: remailer.h:52
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
A Mixmaster remailer.
Definition: remailer.h:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ remailer_new()

static struct Remailer* remailer_new ( void  )
static

Create a new Remailer.

Return values
ptrNewly allocated Remailer

Definition at line 154 of file remailer.c.

155 {
156  return mutt_mem_calloc(1, sizeof(struct Remailer));
157 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
A Mixmaster remailer.
Definition: remailer.h:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ remailer_free()

static void remailer_free ( struct Remailer **  ptr)
static

Free a Remailer.

Parameters
[out]ptrRemailer to free

Definition at line 163 of file remailer.c.

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 }
char * shortname
Definition: remailer.h:53
#define FREE(x)
Definition: memory.h:40
char * addr
Definition: remailer.h:54
char * ver
Definition: remailer.h:55
A Mixmaster remailer.
Definition: remailer.h:50
+ Here is the caller graph for this function:

◆ mix_type2_list()

static struct Remailer** mix_type2_list ( size_t *  l)
static

parse the type2.list as given by mixmaster -T

Parameters
[out]lLength of list
Return values
ptrtype2.list

Definition at line 181 of file remailer.c.

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 = filter_create_fd(mutt_b2s(cmd), NULL, &fp, NULL, fd_null, -1, fd_null);
202  if (mm_pid == -1)
203  {
205  close(fd_null);
206  return NULL;
207  }
208 
210 
211  /* first, generate the "random" remailer */
212 
213  p = remailer_new();
214  p->shortname = mutt_str_dup(_("<random>"));
215  mix_add_entry(&type2_list, p, &slots, &used);
216 
217  while (fgets(line, sizeof(line), fp))
218  {
219  p = remailer_new();
220 
221  t = strtok(line, " \t\n");
222  if (!t)
223  goto problem;
224 
225  p->shortname = mutt_str_dup(t);
226 
227  t = strtok(NULL, " \t\n");
228  if (!t)
229  goto problem;
230 
231  p->addr = mutt_str_dup(t);
232 
233  t = strtok(NULL, " \t\n");
234  if (!t)
235  goto problem;
236 
237  t = strtok(NULL, " \t\n");
238  if (!t)
239  goto problem;
240 
241  p->ver = mutt_str_dup(t);
242 
243  t = strtok(NULL, " \t\n");
244  if (!t)
245  goto problem;
246 
247  p->caps = mix_get_caps(t);
248 
249  mix_add_entry(&type2_list, p, &slots, &used);
250  continue;
251 
252  problem:
253  remailer_free(&p);
254  }
255 
256  *l = used;
257 
258  mix_add_entry(&type2_list, NULL, &slots, &used);
259  filter_wait(mm_pid);
260 
261  close(fd_null);
262 
263  return type2_list;
264 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
MixCapFlags caps
Definition: remailer.h:56
String manipulation buffer.
Definition: buffer.h:33
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
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:163
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
#define mutt_b2s(buf)
Definition: buffer.h:41
char * shortname
Definition: remailer.h:53
static MixCapFlags mix_get_caps(const char *capstr)
Get Mixmaster Capabilities.
Definition: remailer.c:91
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
static struct Remailer * remailer_new(void)
Create a new Remailer.
Definition: remailer.c:154
char * addr
Definition: remailer.h:54
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
char * ver
Definition: remailer.h:55
A Mixmaster remailer.
Definition: remailer.h:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_type2_list_free()

static void mix_type2_list_free ( struct Remailer ***  ttlp)
static

Free a Remailer List.

Parameters
[out]ttlpRemailer List to free

Definition at line 270 of file remailer.c.

271 {
272  struct Remailer **type2_list = *ttlp;
273 
274  for (int i = 0; type2_list[i]; i++)
275  remailer_free(&type2_list[i]);
276 
277  FREE(type2_list);
278 }
static void remailer_free(struct Remailer **ptr)
Free a Remailer.
Definition: remailer.c:163
#define FREE(x)
Definition: memory.h:40
A Mixmaster remailer.
Definition: remailer.h:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_screen_coordinates()

static void mix_screen_coordinates ( struct MuttWindow win,
struct Remailer **  type2_list,
struct Coord **  coordsp,
struct MixChain chain,
int  i 
)
static

Get the screen coordinates to place a chain.

Parameters
[in]winWindow
[out]type2_listRemailer List
[out]coordspOn screen coordinates
[in]chainChain
[in]iIndex in chain

Definition at line 288 of file remailer.c.

290 {
291  if (!chain->cl)
292  return;
293 
294  short c, r;
295 
296  mutt_mem_realloc(coordsp, sizeof(struct Coord) * chain->cl);
297 
298  struct Coord *coords = *coordsp;
299 
300  if (i)
301  {
302  c = coords[i - 1].c + strlen(type2_list[chain->ch[i - 1]]->shortname) + 2;
303  r = coords[i - 1].r;
304  }
305  else
306  {
307  r = MIX_VOFFSET;
308  c = MIX_HOFFSET;
309  }
310 
311  for (; i < chain->cl; i++)
312  {
313  short oc = c;
314  c += strlen(type2_list[chain->ch[i]]->shortname) + 2;
315 
316  if (c >= win->state.cols)
317  {
318  oc = MIX_HOFFSET;
319  c = MIX_HOFFSET;
320  r++;
321  }
322 
323  coords[i].c = oc;
324  coords[i].r = r;
325  }
326 }
#define MIX_VOFFSET
Definition: remailer.c:62
int ch[MAX_MIXES]
Definition: remailer.h:65
short r
row
Definition: remailer.c:70
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:57
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:120
char * shortname
Definition: remailer.h:53
size_t cl
Definition: remailer.h:64
#define MIX_HOFFSET
Definition: remailer.c:61
Screen coordinates.
Definition: remailer.c:68
short c
column
Definition: remailer.c:71
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ 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 
)
static

Redraw the Remailer chain.

Parameters
[in]winWindow
[out]type2_listRemailer List
[in]coordsScreen Coordinates
[in]chainChain
[in]iIndex in chain
[in]selectedtrue, if this item is selected

Definition at line 337 of file remailer.c.

339 {
340  if (!coords || !chain)
341  return;
342 
343  if (coords[i].r < MIX_MAXROW)
344  {
345  if (selected)
347  else
349 
350  mutt_window_mvaddstr(win, coords[i].c, coords[i].r, type2_list[chain->ch[i]]->shortname);
352 
353  if (i + 1 < chain->cl)
354  mutt_window_addstr(", ");
355  }
356 }
int ch[MAX_MIXES]
Definition: remailer.h:65
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:57
short r
row
Definition: remailer.c:70
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
#define MIX_MAXROW
Definition: remailer.c:63
Plain text.
Definition: color.h:77
Selected item in list.
Definition: color.h:73
char * shortname
Definition: remailer.h:53
size_t cl
Definition: remailer.h:64
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:522
short c
column
Definition: remailer.c:71
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_redraw_chain()

static void mix_redraw_chain ( struct MuttWindow win,
struct Remailer **  type2_list,
struct Coord coords,
struct MixChain chain,
int  cur 
)
static

Redraw the chain on screen.

Parameters
[in]winWindow
[out]type2_listRemailer List
[in]coordsWhere to draw the list on screen
[in]chainChain to display
[in]curChain index of current selection

Definition at line 366 of file remailer.c.

368 {
369  for (int i = MIX_VOFFSET; i < MIX_MAXROW; i++)
370  {
371  mutt_window_move(win, 0, i);
373  }
374 
375  for (int i = 0; i < chain->cl; i++)
376  mix_redraw_ce(win, type2_list, coords, chain, i, i == cur);
377 }
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:337
#define MIX_VOFFSET
Definition: remailer.c:62
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:244
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:382
#define MIX_MAXROW
Definition: remailer.c:63
size_t cl
Definition: remailer.h:64
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_redraw_head()

static void mix_redraw_head ( struct MuttWindow win,
struct MixChain chain 
)
static

Redraw the Chain info.

Parameters
winWindow
chainChain

Definition at line 384 of file remailer.c.

385 {
387  mutt_window_mvprintw(win, 0, MIX_VOFFSET - 1,
388  "-- Remailer chain [Length: %d]", chain ? chain->cl : 0);
391 }
#define MIX_VOFFSET
Definition: remailer.c:62
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:57
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:244
Plain text.
Definition: color.h:77
Status bar (takes a pattern)
Definition: color.h:94
size_t cl
Definition: remailer.h:64
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
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_format_caps()

static const char* mix_format_caps ( struct Remailer r)
static

Turn flags into a MixMaster capability string.

Parameters
rRemailer to use
Return values
ptrCapability string
Note
The string is a static buffer

Definition at line 400 of file remailer.c.

401 {
402  static char capbuf[10];
403  char *t = capbuf;
404 
405  if (r->caps & MIX_CAP_COMPRESS)
406  *t++ = 'C';
407  else
408  *t++ = ' ';
409 
410  if (r->caps & MIX_CAP_MIDDLEMAN)
411  *t++ = 'M';
412  else
413  *t++ = ' ';
414 
415  if (r->caps & MIX_CAP_NEWSPOST)
416  {
417  *t++ = 'N';
418  *t++ = 'p';
419  }
420  else
421  {
422  *t++ = ' ';
423  *t++ = ' ';
424  }
425 
426  if (r->caps & MIX_CAP_NEWSMAIL)
427  {
428  *t++ = 'N';
429  *t++ = 'm';
430  }
431  else
432  {
433  *t++ = ' ';
434  *t++ = ' ';
435  }
436 
437  *t = '\0';
438 
439  return capbuf;
440 }
#define MIX_CAP_NEWSPOST
Definition: remailer.h:44
MixCapFlags caps
Definition: remailer.h:56
#define MIX_CAP_NEWSMAIL
Definition: remailer.h:45
#define MIX_CAP_MIDDLEMAN
Definition: remailer.h:43
#define MIX_CAP_COMPRESS
Definition: remailer.h:42
+ Here is the caller graph for this function:

◆ 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 
)
static

Format a string for the remailer menu - Implements format_t.

Expando Description
%a The remailer's e-mail address
%c Remailer capabilities
%n The running number on the menu
%s The remailer's short name

Definition at line 452 of file remailer.c.

456 {
457  char fmt[128];
458  struct Remailer *remailer = (struct Remailer *) data;
459  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
460 
461  switch (op)
462  {
463  case 'a':
464  if (!optional)
465  {
466  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
467  snprintf(buf, buflen, fmt, NONULL(remailer->addr));
468  }
469  else if (!remailer->addr)
470  optional = false;
471  break;
472 
473  case 'c':
474  if (optional)
475  break;
476 
477  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
478  snprintf(buf, buflen, fmt, mix_format_caps(remailer));
479  break;
480 
481  case 'n':
482  if (optional)
483  break;
484 
485  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
486  snprintf(buf, buflen, fmt, remailer->num);
487  break;
488 
489  case 's':
490  if (!optional)
491  {
492  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
493  snprintf(buf, buflen, fmt, NONULL(remailer->shortname));
494  }
495  else if (!remailer->shortname)
496  optional = false;
497  break;
498 
499  default:
500  *buf = '\0';
501  }
502 
503  if (optional)
504  {
505  mutt_expando_format(buf, buflen, col, cols, if_str, mix_format_str, data,
507  }
508  else if (flags & MUTT_FORMAT_OPTIONAL)
509  {
510  mutt_expando_format(buf, buflen, col, cols, else_str, mix_format_str, data,
512  }
513  return src;
514 }
#define NONULL(x)
Definition: string2.h:37
static const char * mix_format_caps(struct Remailer *r)
Turn flags into a MixMaster capability string.
Definition: remailer.c:400
int num
Definition: remailer.h:52
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
char * shortname
Definition: remailer.h:53
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:452
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:772
#define MUTT_FORMAT_OPTIONAL
Allow optional field processing.
Definition: format_flags.h:33
char * addr
Definition: remailer.h:54
A Mixmaster remailer.
Definition: remailer.h:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_make_entry()

static void mix_make_entry ( char *  buf,
size_t  buflen,
struct Menu menu,
int  num 
)
static

Format a menu item for the mixmaster chain list - Implements Menu::make_entry()

Definition at line 519 of file remailer.c.

520 {
521  struct Remailer **type2_list = menu->mdata;
522  mutt_expando_format(buf, buflen, 0, menu->win_index->state.cols,
524  (intptr_t) type2_list[num], MUTT_FORMAT_ARROWCURSOR);
525 }
#define NONULL(x)
Definition: string2.h:37
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
int num
Definition: remailer.h:52
char * C_MixEntryFormat
Config: (mixmaster) printf-like format string for the mixmaster chain.
Definition: remailer.c:58
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:57
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:120
void * mdata
Extra data for the current menu.
Definition: mutt_menu.h:55
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:452
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:772
struct MuttWindow * win_index
Definition: mutt_menu.h:63
A Mixmaster remailer.
Definition: remailer.h:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_chain_add()

static int mix_chain_add ( struct MixChain chain,
const char *  s,
struct Remailer **  type2_list 
)
static

Add a host to the chain.

Parameters
[in]chainChain to add to
[in]sHostname
[out]type2_listRemailer List
Return values
0Success
-1Error

Definition at line 535 of file remailer.c.

536 {
537  int i;
538 
539  if (chain->cl >= MAX_MIXES)
540  return -1;
541 
542  if (mutt_str_equal(s, "0") || mutt_istr_equal(s, "<random>"))
543  {
544  chain->ch[chain->cl++] = 0;
545  return 0;
546  }
547 
548  for (i = 0; type2_list[i]; i++)
549  {
550  if (mutt_istr_equal(s, type2_list[i]->shortname))
551  {
552  chain->ch[chain->cl++] = i;
553  return 0;
554  }
555  }
556 
557  /* replace unknown remailers by <random> */
558 
559  if (!type2_list[i])
560  chain->ch[chain->cl++] = 0;
561 
562  return 0;
563 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
int ch[MAX_MIXES]
Definition: remailer.h:65
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
char * shortname
Definition: remailer.h:53
size_t cl
Definition: remailer.h:64
#define MAX_MIXES
Definition: remailer.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_select_mixmaster_chain()

void dlg_select_mixmaster_chain ( struct MuttWindow win,
struct ListHead *  chainhead,
int  cols 
)

Create a Mixmaster chain.

Parameters
winWindow
chainheadList of chain links
colsNumber of screen columns

Ask the user to select Mixmaster hosts to create a chain.

Definition at line 573 of file remailer.c.

574 {
575  int c_cur = 0, c_old = 0;
576  bool c_redraw = true;
577  size_t ttll = 0;
578 
579  struct Coord *coords = NULL;
580 
581  struct Menu *menu = NULL;
582  bool loop = true;
583 
584  char *t = NULL;
585 
586  struct Remailer **type2_list = mix_type2_list(&ttll);
587  if (!type2_list)
588  {
589  mutt_error(_("Can't get mixmaster's type2.list"));
590  return;
591  }
592 
593  struct MixChain *chain = mutt_mem_calloc(1, sizeof(struct MixChain));
594 
595  struct ListNode *p = NULL;
596  STAILQ_FOREACH(p, chainhead, entries)
597  {
598  mix_chain_add(chain, p->data, type2_list);
599  }
600  mutt_list_free(chainhead);
601 
602  /* safety check */
603  for (int i = 0; i < chain->cl; i++)
604  {
605  if (chain->ch[i] >= ttll)
606  chain->ch[i] = 0;
607  }
608 
609  mix_screen_coordinates(win, type2_list, &coords, chain, 0);
610 
611  menu = mutt_menu_new(MENU_MIX);
613  dlg->help_data = RemailerHelp;
614  dlg->help_menu = MENU_MIX;
615 
616  menu->max = ttll;
617  menu->make_entry = mix_make_entry;
618  menu->tag = NULL;
619  menu->title = _("Select a remailer chain");
620  menu->mdata = type2_list;
621  menu->pagelen = MIX_VOFFSET - 1;
623 
624  while (loop)
625  {
626  if (menu->pagelen != MIX_VOFFSET - 1)
627  {
628  menu->pagelen = MIX_VOFFSET - 1;
629  menu->redraw = REDRAW_FULL;
630  }
631 
632  if (c_redraw)
633  {
634  mix_redraw_head(menu->win_index, chain);
635  mix_redraw_chain(menu->win_index, type2_list, coords, chain, c_cur);
636  c_redraw = false;
637  }
638  else if (c_cur != c_old)
639  {
640  mix_redraw_ce(menu->win_index, type2_list, coords, chain, c_old, false);
641  mix_redraw_ce(menu->win_index, type2_list, coords, chain, c_cur, true);
642  }
643 
644  c_old = c_cur;
645 
646  const int op = mutt_menu_loop(menu);
647  switch (op)
648  {
649  case OP_REDRAW:
650  {
651  menu_redraw_status(menu);
652  mix_redraw_head(menu->win_index, chain);
653  mix_screen_coordinates(menu->win_index, type2_list, &coords, chain, 0);
654  mix_redraw_chain(menu->win_index, type2_list, coords, chain, c_cur);
655  menu->pagelen = MIX_VOFFSET - 1;
656  break;
657  }
658 
659  case OP_EXIT:
660  {
661  chain->cl = 0;
662  loop = false;
663  break;
664  }
665 
666  case OP_MIX_USE:
667  {
668  if (!chain->cl)
669  {
670  chain->cl++;
671  chain->ch[0] = menu->current;
672  mix_screen_coordinates(menu->win_index, type2_list, &coords, chain, c_cur);
673  c_redraw = true;
674  }
675 
676  if (chain->cl && chain->ch[chain->cl - 1] &&
677  (type2_list[chain->ch[chain->cl - 1]]->caps & MIX_CAP_MIDDLEMAN))
678  {
679  mutt_error(
680  _("Error: %s can't be used as the final remailer of a chain"),
681  type2_list[chain->ch[chain->cl - 1]]->shortname);
682  }
683  else
684  {
685  loop = false;
686  }
687  break;
688  }
689 
690  case OP_GENERIC_SELECT_ENTRY:
691  case OP_MIX_APPEND:
692  {
693  if ((chain->cl < MAX_MIXES) && (c_cur < chain->cl))
694  c_cur++;
695  }
696  /* fallthrough */
697  case OP_MIX_INSERT:
698  {
699  if (chain->cl < MAX_MIXES)
700  {
701  chain->cl++;
702  for (int i = chain->cl - 1; i > c_cur; i--)
703  chain->ch[i] = chain->ch[i - 1];
704 
705  chain->ch[c_cur] = menu->current;
706  mix_screen_coordinates(menu->win_index, type2_list, &coords, chain, c_cur);
707  c_redraw = true;
708  }
709  else
710  {
711  /* L10N The '%d' here hard-coded to 19 */
712  mutt_error(_("Mixmaster chains are limited to %d elements"), MAX_MIXES);
713  }
714 
715  break;
716  }
717 
718  case OP_MIX_DELETE:
719  {
720  if (chain->cl)
721  {
722  chain->cl--;
723 
724  for (int i = c_cur; i < chain->cl; i++)
725  chain->ch[i] = chain->ch[i + 1];
726 
727  if ((c_cur == chain->cl) && c_cur)
728  c_cur--;
729 
730  mix_screen_coordinates(menu->win_index, type2_list, &coords, chain, c_cur);
731  c_redraw = true;
732  }
733  else
734  {
735  mutt_error(_("The remailer chain is already empty"));
736  }
737  break;
738  }
739 
740  case OP_MIX_CHAIN_PREV:
741  {
742  if (c_cur)
743  c_cur--;
744  else
745  mutt_error(_("You already have the first chain element selected"));
746 
747  break;
748  }
749 
750  case OP_MIX_CHAIN_NEXT:
751  {
752  if (chain->cl && (c_cur < chain->cl - 1))
753  c_cur++;
754  else
755  mutt_error(_("You already have the last chain element selected"));
756 
757  break;
758  }
759  }
760  }
761 
762  mutt_menu_pop_current(menu);
763  mutt_menu_free(&menu);
765 
766  /* construct the remailer list */
767 
768  if (chain->cl)
769  {
770  for (int i = 0; i < chain->cl; i++)
771  {
772  const int j = chain->ch[i];
773  if (j != 0)
774  t = type2_list[j]->shortname;
775  else
776  t = "*";
777 
778  mutt_list_insert_tail(chainhead, mutt_str_dup(t));
779  }
780  }
781 
782  mix_type2_list_free(&type2_list);
783  FREE(&coords);
784  FREE(&chain);
785 }
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:337
#define MIX_VOFFSET
Definition: remailer.c:62
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:45
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
GUI selectable list of items.
Definition: mutt_menu.h:52
A Mixmaster chain.
Definition: remailer.h:62
int ch[MAX_MIXES]
Definition: remailer.h:65
int help_menu
Menu for key bindings, e.g. MENU_PAGER.
Definition: mutt_window.h:134
MixCapFlags caps
Definition: remailer.h:56
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define _(a)
Definition: message.h:28
A division of the screen.
Definition: mutt_window.h:115
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:366
struct MuttWindow * dialog_create_simple_index(struct Menu *menu, enum WindowType type)
Create a simple index Dialog.
Definition: dialog.c:165
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
const char * title
Title of this menu.
Definition: mutt_menu.h:54
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
void * mdata
Extra data for the current menu.
Definition: mutt_menu.h:55
const struct Mapping * help_data
Data for the Help Bar.
Definition: mutt_window.h:135
void dialog_destroy_simple_index(struct MuttWindow **ptr)
Destroy a simple index Dialog.
Definition: dialog.c:209
char * shortname
Definition: remailer.h:53
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
int(* tag)(struct Menu *menu, int sel, int act)
Tag some menu items.
Definition: mutt_menu.h:107
int pagelen
Number of entries per screen.
Definition: mutt_menu.h:60
size_t cl
Definition: remailer.h:64
#define MIX_CAP_MIDDLEMAN
Definition: remailer.h:43
int max
Number of entries in the menu.
Definition: mutt_menu.h:57
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:58
static void mix_type2_list_free(struct Remailer ***ttlp)
Free a Remailer List.
Definition: remailer.c:270
char * data
String.
Definition: list.h:36
#define mutt_error(...)
Definition: logging.h:84
Create/edit a Mixmaster chain.
Definition: keymap.h:91
#define FREE(x)
Definition: memory.h:40
static void mix_redraw_head(struct MuttWindow *win, struct MixChain *chain)
Redraw the Chain info.
Definition: remailer.c:384
static int mix_chain_add(struct MixChain *chain, const char *s, struct Remailer **type2_list)
Add a host to the chain.
Definition: remailer.c:535
int current
Current entry.
Definition: mutt_menu.h:56
struct MuttWindow * win_index
Definition: mutt_menu.h:63
static void mix_make_entry(char *buf, size_t buflen, struct Menu *menu, int num)
Format a menu item for the mixmaster chain list - Implements Menu::make_entry()
Definition: remailer.c:519
A List node for strings.
Definition: list.h:34
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:288
static struct Remailer ** mix_type2_list(size_t *l)
parse the type2.list as given by mixmaster -T
Definition: remailer.c:181
void(* make_entry)(char *buf, size_t buflen, struct Menu *menu, int line)
Format a item for a menu.
Definition: mutt_menu.h:88
#define MAX_MIXES
Definition: remailer.h:38
Screen coordinates.
Definition: remailer.c:68
static const struct Mapping RemailerHelp[]
Help Bar for the Mixmaster dialog.
Definition: remailer.c:75
Remailer Dialog, dlg_select_mixmaster_chain()
Definition: mutt_window.h:88
A Mixmaster remailer.
Definition: remailer.h:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_check_message()

int mix_check_message ( struct Email e)

Safety-check the message before passing it to mixmaster.

Parameters
eEmail
Return values
0Success
-1Error

Definition at line 793 of file remailer.c.

794 {
795  bool need_hostname = false;
796 
797  if (!TAILQ_EMPTY(&e->env->cc) || !TAILQ_EMPTY(&e->env->bcc))
798  {
799  mutt_error(_("Mixmaster doesn't accept Cc or Bcc headers"));
800  return -1;
801  }
802 
803  /* When using mixmaster, we MUST qualify any addresses since
804  * the message will be delivered through remote systems.
805  *
806  * use_domain won't be respected at this point, hidden_host will.
807  */
808 
809  struct Address *a = NULL;
810  TAILQ_FOREACH(a, &e->env->to, entries)
811  {
812  if (!a->group && !strchr(a->mailbox, '@'))
813  {
814  need_hostname = true;
815  break;
816  }
817  }
818 
819  if (need_hostname)
820  {
821  const char *fqdn = mutt_fqdn(true, NeoMutt->sub);
822  if (!fqdn)
823  {
824  mutt_error(_("Please set the hostname variable to a proper value when "
825  "using mixmaster"));
826  return -1;
827  }
828 
829  /* Cc and Bcc are empty at this point. */
830  mutt_addrlist_qualify(&e->env->to, fqdn);
831  mutt_addrlist_qualify(&e->env->reply_to, fqdn);
833  }
834 
835  return 0;
836 }
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:718
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 _(a)
Definition: message.h:28
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
Container for Accounts, Notifications.
Definition: neomutt.h:36
struct Envelope * env
Envelope information.
Definition: email.h:90
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
void mutt_addrlist_qualify(struct AddressList *al, const char *host)
Expand local names in an Address list using a hostname.
Definition: address.c:650
const char * mutt_fqdn(bool may_hide_host, const struct ConfigSubset *sub)
Get the Fully-Qualified Domain Name.
Definition: sendlib.c:1181
bool group
Group mailbox?
Definition: address.h:38
#define mutt_error(...)
Definition: logging.h:84
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
#define TAILQ_EMPTY(head)
Definition: queue.h:714
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mix_send_message()

int mix_send_message ( struct ListHead *  chain,
const char *  tempfile 
)

Send an email via Mixmaster.

Parameters
chainString list of hosts
tempfileTemporary file containing email
Return values
-1Error
>=0Success (Mixmaster's return code)

Definition at line 845 of file remailer.c.

846 {
847  int i = 0;
848  struct Buffer *cmd = mutt_buffer_pool_get();
849  struct Buffer *cd_quoted = mutt_buffer_pool_get();
850 
851  mutt_buffer_printf(cmd, "cat %s | %s -m ", tempfile, C_Mixmaster);
852 
853  struct ListNode *np = NULL;
854  STAILQ_FOREACH(np, chain, entries)
855  {
856  mutt_buffer_addstr(cmd, (i != 0) ? "," : " -l ");
857  mutt_buffer_quote_filename(cd_quoted, (char *) np->data, true);
858  mutt_buffer_addstr(cmd, mutt_b2s(cd_quoted));
859  i = 1;
860  }
861 
862  mutt_endwin();
863 
864  i = mutt_system(cmd->data);
865  if (i != 0)
866  {
867  fprintf(stderr, _("Error sending message, child exited %d\n"), i);
868  if (!OptNoCurses)
869  {
871  mutt_error(_("Error sending message"));
872  }
873  }
874 
876  mutt_buffer_pool_release(&cd_quoted);
877  unlink(tempfile);
878  return i;
879 }
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:836
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:48
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
char * C_Mixmaster
Config: (mixmaster) External command to route a mixmaster message.
Definition: remailer.c:59
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
#define mutt_b2s(buf)
Definition: buffer.h:41
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:571
char * data
Pointer to data.
Definition: buffer.h:35
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:604
char * data
String.
Definition: list.h:36
#define mutt_error(...)
Definition: logging.h:84
A List node for strings.
Definition: list.h:34
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_MixEntryFormat

char* C_MixEntryFormat

Config: (mixmaster) printf-like format string for the mixmaster chain.

Definition at line 58 of file remailer.c.

◆ C_Mixmaster

char* C_Mixmaster

Config: (mixmaster) External command to route a mixmaster message.

Definition at line 59 of file remailer.c.

◆ RemailerHelp

const struct Mapping RemailerHelp[]
static
Initial value:
= {
{ 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, 0 },
}
#define N_(a)
Definition: message.h:32

Help Bar for the Mixmaster dialog.

Definition at line 75 of file remailer.c.