NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
alias.c File Reference
#include "config.h"
#include <stddef.h>
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <wctype.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 "alias.h"
#include "lib.h"
#include "send/lib.h"
#include "maillist.h"
#include "mutt_globals.h"
#include "muttlib.h"
#include "reverse.h"
+ Include dependency graph for alias.c:

Go to the source code of this file.

Functions

static void write_safe_address (FILE *fp, char *s)
 Defang malicious email addresses. More...
 
static void expand_aliases_r (struct AddressList *al, struct ListHead *expn)
 Expand aliases, recursively. More...
 
static void recode_buf (char *buf, size_t buflen)
 Convert some text between two character sets. More...
 
static int check_alias_name (const char *s, char *dest, size_t destlen)
 Sanity-check an alias name. More...
 
static bool string_is_address (const char *str, const char *user, const char *domain)
 Does an email address match a user and domain? More...
 
struct AddressList * alias_lookup (const char *name)
 Find an Alias. More...
 
void mutt_expand_aliases (struct AddressList *al)
 Expand aliases in a List of Addresses. More...
 
void mutt_expand_aliases_env (struct Envelope *env)
 Expand aliases in all the fields of an Envelope. More...
 
struct AddressList * mutt_get_address (struct Envelope *env, const char **prefix)
 Get an Address from an Envelope. More...
 
void alias_create (struct AddressList *al, const struct ConfigSubset *sub)
 Create a new Alias from an Address. More...
 
bool mutt_addr_is_user (const struct Address *addr)
 Does the address belong to the user. More...
 
struct Aliasalias_new (void)
 Create a new Alias. More...
 
void alias_free (struct Alias **ptr)
 Free an Alias. More...
 
void aliaslist_free (struct AliasList *al)
 Free a List of Aliases. More...
 
void alias_init (void)
 Set up the Alias globals. More...
 
void alias_shutdown (void)
 Clean up the Alias globals. More...
 

Variables

struct AliasList Aliases = TAILQ_HEAD_INITIALIZER(Aliases)
 List of all the user's email aliases. More...
 

Detailed Description

Representation of a single alias to an email address

Authors
  • Michael R. Elkins
  • Pietro Cerutti
  • Richard Russon

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 alias.c.

Function Documentation

◆ write_safe_address()

static void write_safe_address ( FILE *  fp,
char *  s 
)
static

Defang malicious email addresses.

Parameters
fpFile to write to
sEmail address to defang

if someone has an address like From: Michael /bin/rm -f ~ Elkins me@mu.nosp@m.tt.o.nosp@m.rg and the user creates an alias for this, NeoMutt could wind up executing the backticks because it writes aliases like alias me Michael /bin/rm -f ~ Elkins me@mu.nosp@m.tt.o.nosp@m.rg To avoid this problem, use a backslash () to quote any backticks. We also need to quote backslashes as well, since you could defeat the above by doing From: Michael `/bin/rm -f ~` Elkins me@mu.nosp@m.tt.o.nosp@m.rg since that would get aliased as alias me Michael \`/bin/rm -f ~\` Elkins me@mu.nosp@m.tt.o.nosp@m.rg which still gets evaluated because the double backslash is not a quote.

Additionally, we need to quote ' and " characters - otherwise, neomutt will interpret them on the wrong parsing step.

$ wants to be quoted since it may indicate the start of an environment variable.

Definition at line 81 of file alias.c.

82 {
83  while (*s)
84  {
85  if ((*s == '\\') || (*s == '`') || (*s == '\'') || (*s == '"') || (*s == '$'))
86  fputc('\\', fp);
87  fputc(*s, fp);
88  s++;
89  }
90 }
+ Here is the caller graph for this function:

◆ expand_aliases_r()

static void expand_aliases_r ( struct AddressList *  al,
struct ListHead *  expn 
)
static

Expand aliases, recursively.

Parameters
[in]alAddress List
[out]expnAlias List

ListHead expn is used as temporary storage for already-expanded aliases.

Definition at line 99 of file alias.c.

100 {
101  struct Address *a = TAILQ_FIRST(al);
102  while (a)
103  {
104  if (!a->group && !a->personal && a->mailbox && !strchr(a->mailbox, '@'))
105  {
106  struct AddressList *alias = alias_lookup(a->mailbox);
107  if (alias)
108  {
109  bool duplicate = false;
110  struct ListNode *np = NULL;
111  STAILQ_FOREACH(np, expn, entries)
112  {
113  if (mutt_str_equal(a->mailbox, np->data)) /* alias already found */
114  {
115  mutt_debug(LL_DEBUG1, "loop in alias found for '%s'\n", a->mailbox);
116  duplicate = true;
117  break;
118  }
119  }
120 
121  if (duplicate)
122  {
123  // We've already seen this alias, so drop it
124  struct Address *next = TAILQ_NEXT(a, entries);
125  TAILQ_REMOVE(al, a, entries);
126  mutt_addr_free(&a);
127  a = next;
128  continue;
129  }
130 
131  // Keep a list of aliases that we've already seen
133 
134  /* The alias may expand to several addresses,
135  * some of which may themselves be aliases.
136  * Create a copy and recursively expand any aliases within. */
137  struct AddressList copy = TAILQ_HEAD_INITIALIZER(copy);
138  mutt_addrlist_copy(&copy, alias, false);
139  expand_aliases_r(&copy, expn);
140 
141  /* Next, move the expanded addresses
142  * from the copy into the original list (before the alias) */
143  struct Address *a2 = NULL, *tmp = NULL;
144  TAILQ_FOREACH_SAFE(a2, &copy, entries, tmp)
145  {
146  TAILQ_INSERT_BEFORE(a, a2, entries);
147  }
148  a = TAILQ_PREV(a, AddressList, entries);
149  // Finally, remove the alias itself
150  struct Address *next = TAILQ_NEXT(a, entries);
151  TAILQ_REMOVE(al, next, entries);
152  mutt_addr_free(&next);
153  }
154  else
155  {
156  struct passwd *pw = getpwnam(a->mailbox);
157  if (pw)
158  {
159  char namebuf[256];
160 
161  mutt_gecos_name(namebuf, sizeof(namebuf), pw);
162  mutt_str_replace(&a->personal, namebuf);
163  }
164  }
165  }
166  a = TAILQ_NEXT(a, entries);
167  }
168 
169  const char *fqdn = NULL;
170  if (C_UseDomain && (fqdn = mutt_fqdn(true, NeoMutt->sub)))
171  {
172  /* now qualify all local addresses */
173  mutt_addrlist_qualify(al, fqdn);
174  }
175 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ recode_buf()

static void recode_buf ( char *  buf,
size_t  buflen 
)
static

Convert some text between two character sets.

Parameters
bufBuffer to convert
buflenLength of buffer

The 'from' charset is controlled by the 'charset' config variable. The 'to' charset is controlled by the 'config_charset' config variable.

Definition at line 185 of file alias.c.

186 {
187  if (!C_ConfigCharset || !C_Charset)
188  return;
189 
190  char *s = mutt_str_dup(buf);
191  if (!s)
192  return;
194  mutt_str_copy(buf, s, buflen);
195  FREE(&s);
196 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ check_alias_name()

static int check_alias_name ( const char *  s,
char *  dest,
size_t  destlen 
)
static

Sanity-check an alias name.

Parameters
sAlias to check
destBuffer for the result
destlenLength of buffer
Return values
0Success
-1Error

Only characters which are non-special to both the RFC822 and the neomutt configuration parser are permitted.

Definition at line 209 of file alias.c.

210 {
211  wchar_t wc;
212  mbstate_t mb;
213  size_t l;
214  int rc = 0;
215  bool dry = !dest || !destlen;
216 
217  memset(&mb, 0, sizeof(mbstate_t));
218 
219  if (!dry)
220  destlen--;
221  for (; s && *s && (dry || destlen) && (l = mbrtowc(&wc, s, MB_CUR_MAX, &mb)) != 0;
222  s += l, destlen -= l)
223  {
224  bool bad = (l == (size_t)(-1)) || (l == (size_t)(-2)); /* conversion error */
225  bad = bad || (!dry && l > destlen); /* too few room for mb char */
226  if (l == 1)
227  bad = bad || (!strchr("-_+=.", *s) && !iswalnum(wc));
228  else
229  bad = bad || !iswalnum(wc);
230  if (bad)
231  {
232  if (dry)
233  return -1;
234  if (l == (size_t)(-1))
235  memset(&mb, 0, sizeof(mbstate_t));
236  *dest++ = '_';
237  rc = -1;
238  }
239  else if (!dry)
240  {
241  memcpy(dest, s, l);
242  dest += l;
243  }
244  }
245  if (!dry)
246  *dest = '\0';
247  return rc;
248 }
+ Here is the caller graph for this function:

◆ string_is_address()

static bool string_is_address ( const char *  str,
const char *  user,
const char *  domain 
)
static

Does an email address match a user and domain?

Parameters
strAddress string to test
userUser name
domainDomain name
Return values
trueThey match

Definition at line 257 of file alias.c.

258 {
259  char buf[1024];
260 
261  snprintf(buf, sizeof(buf), "%s@%s", NONULL(user), NONULL(domain));
262  if (mutt_istr_equal(str, buf))
263  return true;
264 
265  return false;
266 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ alias_lookup()

struct AddressList* alias_lookup ( const char *  name)

Find an Alias.

Parameters
nameAlias name to find
Return values
ptrAddress for the Alias
NULLNo such Alias
Note
The search is case-insensitive

Definition at line 276 of file alias.c.

277 {
278  struct Alias *a = NULL;
279 
280  TAILQ_FOREACH(a, &Aliases, entries)
281  {
282  if (mutt_istr_equal(name, a->name))
283  return &a->addr;
284  }
285  return NULL;
286 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_expand_aliases()

void mutt_expand_aliases ( struct AddressList *  al)

Expand aliases in a List of Addresses.

Parameters
alAddressList

Duplicate addresses are dropped

Definition at line 294 of file alias.c.

295 {
296  struct ListHead expn; /* previously expanded aliases to avoid loops */
297 
298  STAILQ_INIT(&expn);
299  expand_aliases_r(al, &expn);
300  mutt_list_free(&expn);
302 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_expand_aliases_env()

void mutt_expand_aliases_env ( struct Envelope env)

Expand aliases in all the fields of an Envelope.

Parameters
envEnvelope to expand

Definition at line 308 of file alias.c.

309 {
310  mutt_expand_aliases(&env->from);
311  mutt_expand_aliases(&env->to);
312  mutt_expand_aliases(&env->cc);
313  mutt_expand_aliases(&env->bcc);
316 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_get_address()

struct AddressList* mutt_get_address ( struct Envelope env,
const char **  prefix 
)

Get an Address from an Envelope.

Parameters
[in]envEnvelope to examine
[out]prefixPrefix for the Address, e.g. "To:"
Return values
ptrAddressList in the Envelope
Note
The caller must NOT free the returned AddressList

Definition at line 326 of file alias.c.

327 {
328  struct AddressList *al = NULL;
329  const char *pfx = NULL;
330 
331  if (mutt_addr_is_user(TAILQ_FIRST(&env->from)))
332  {
333  if (!TAILQ_EMPTY(&env->to) && !mutt_is_mail_list(TAILQ_FIRST(&env->to)))
334  {
335  pfx = "To";
336  al = &env->to;
337  }
338  else
339  {
340  pfx = "Cc";
341  al = &env->cc;
342  }
343  }
344  else if (!TAILQ_EMPTY(&env->reply_to) && !mutt_is_mail_list(TAILQ_FIRST(&env->reply_to)))
345  {
346  pfx = "Reply-To";
347  al = &env->reply_to;
348  }
349  else
350  {
351  al = &env->from;
352  pfx = "From";
353  }
354 
355  if (prefix)
356  *prefix = pfx;
357 
358  return al;
359 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ alias_create()

void alias_create ( struct AddressList *  al,
const struct ConfigSubset sub 
)

Create a new Alias from an Address.

Parameters
alAddress to use
subConfig items

Definition at line 366 of file alias.c.

367 {
368  struct Address *addr = NULL;
369  char buf[1024], tmp[1024] = { 0 }, prompt[2048];
370  char *pc = NULL;
371  char *err = NULL;
372  char fixed[1024];
373 
374  if (al)
375  {
376  addr = TAILQ_FIRST(al);
377  if (addr && addr->mailbox)
378  {
379  mutt_str_copy(tmp, addr->mailbox, sizeof(tmp));
380  pc = strchr(tmp, '@');
381  if (pc)
382  *pc = '\0';
383  }
384  }
385 
386  /* Don't suggest a bad alias name in the event of a strange local part. */
387  check_alias_name(tmp, buf, sizeof(buf));
388 
389 retry_name:
390  /* L10N: prompt to add a new alias */
391  if ((mutt_get_field(_("Alias as: "), buf, sizeof(buf), MUTT_COMP_NO_FLAGS,
392  false, NULL, NULL) != 0) ||
393  (buf[0] == '\0'))
394  {
395  return;
396  }
397 
398  /* check to see if the user already has an alias defined */
399  if (alias_lookup(buf))
400  {
401  mutt_error(_("You already have an alias defined with that name"));
402  return;
403  }
404 
405  if (check_alias_name(buf, fixed, sizeof(fixed)))
406  {
407  switch (mutt_yesorno(_("Warning: This alias name may not work. Fix it?"), MUTT_YES))
408  {
409  case MUTT_YES:
410  mutt_str_copy(buf, fixed, sizeof(buf));
411  goto retry_name;
412  case MUTT_ABORT:
413  return;
414  default:; // do nothing
415  }
416  }
417 
418  struct Alias *alias = alias_new();
419  alias->name = mutt_str_dup(buf);
420 
422 
423  if (addr && addr->mailbox)
424  mutt_str_copy(buf, addr->mailbox, sizeof(buf));
425  else
426  buf[0] = '\0';
427 
428  mutt_addrlist_to_intl(al, NULL);
429 
430  do
431  {
432  if ((mutt_get_field(_("Address: "), buf, sizeof(buf), MUTT_COMP_NO_FLAGS,
433  false, NULL, NULL) != 0) ||
434  (buf[0] == '\0'))
435  {
436  alias_free(&alias);
437  return;
438  }
439 
440  mutt_addrlist_parse(&alias->addr, buf);
441  if (TAILQ_EMPTY(&alias->addr))
442  mutt_beep(false);
443  if (mutt_addrlist_to_intl(&alias->addr, &err))
444  {
445  mutt_error(_("Bad IDN: '%s'"), err);
446  FREE(&err);
447  continue;
448  }
449  } while (TAILQ_EMPTY(&alias->addr));
450 
451  if (addr && addr->personal && !mutt_is_mail_list(addr))
452  mutt_str_copy(buf, addr->personal, sizeof(buf));
453  else
454  buf[0] = '\0';
455 
456  if (mutt_get_field(_("Personal name: "), buf, sizeof(buf), MUTT_COMP_NO_FLAGS,
457  false, NULL, NULL) != 0)
458  {
459  alias_free(&alias);
460  return;
461  }
462  mutt_str_replace(&TAILQ_FIRST(&alias->addr)->personal, buf);
463 
464  buf[0] = '\0';
465  if (mutt_get_field(_("Comment: "), buf, sizeof(buf), MUTT_COMP_NO_FLAGS,
466  false, NULL, NULL) == 0)
467  {
468  mutt_str_replace(&alias->comment, buf);
469  }
470 
471  buf[0] = '\0';
472  mutt_addrlist_write(&alias->addr, buf, sizeof(buf), true);
473  if (alias->comment)
474  {
475  snprintf(prompt, sizeof(prompt), "[%s = %s # %s] %s", alias->name, buf,
476  alias->comment, _("Accept?"));
477  }
478  else
479  {
480  snprintf(prompt, sizeof(prompt), "[%s = %s] %s", alias->name, buf, _("Accept?"));
481  }
482  if (mutt_yesorno(prompt, MUTT_YES) != MUTT_YES)
483  {
484  alias_free(&alias);
485  return;
486  }
487 
488  alias_reverse_add(alias);
489  TAILQ_INSERT_TAIL(&Aliases, alias, entries);
490 
491  const char *alias_file = cs_subset_path(sub, "alias_file");
492  mutt_str_copy(buf, NONULL(alias_file), sizeof(buf));
493 
494  if (mutt_get_field(_("Save to file: "), buf, sizeof(buf),
495  MUTT_FILE | MUTT_CLEAR, false, NULL, NULL) != 0)
496  {
497  return;
498  }
499  mutt_expand_path(buf, sizeof(buf));
500  FILE *fp_alias = fopen(buf, "a+");
501  if (!fp_alias)
502  {
503  mutt_perror(buf);
504  return;
505  }
506 
507  /* terminate existing file with \n if necessary */
508  if (fseek(fp_alias, 0, SEEK_END))
509  goto fseek_err;
510  if (ftell(fp_alias) > 0)
511  {
512  if (fseek(fp_alias, -1, SEEK_CUR) < 0)
513  goto fseek_err;
514  if (fread(buf, 1, 1, fp_alias) != 1)
515  {
516  mutt_perror(_("Error reading alias file"));
517  mutt_file_fclose(&fp_alias);
518  return;
519  }
520  if (fseek(fp_alias, 0, SEEK_END) < 0)
521  goto fseek_err;
522  if (buf[0] != '\n')
523  fputc('\n', fp_alias);
524  }
525 
526  if (check_alias_name(alias->name, NULL, 0))
527  mutt_file_quote_filename(alias->name, buf, sizeof(buf));
528  else
529  mutt_str_copy(buf, alias->name, sizeof(buf));
530  recode_buf(buf, sizeof(buf));
531  fprintf(fp_alias, "alias %s ", buf);
532  buf[0] = '\0';
533  mutt_addrlist_write(&alias->addr, buf, sizeof(buf), false);
534  recode_buf(buf, sizeof(buf));
535  write_safe_address(fp_alias, buf);
536  if (alias->comment)
537  fprintf(fp_alias, " # %s", alias->comment);
538  fputc('\n', fp_alias);
539  if (mutt_file_fsync_close(&fp_alias) != 0)
540  mutt_perror(_("Trouble adding alias"));
541  else
542  mutt_message(_("Alias added"));
543 
544  return;
545 
546 fseek_err:
547  mutt_perror(_("Error seeking in alias file"));
548  mutt_file_fclose(&fp_alias);
549 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_addr_is_user()

bool mutt_addr_is_user ( const struct Address addr)

Does the address belong to the user.

Parameters
addrAddress to check
Return values
trueif the given address belongs to the user

Definition at line 556 of file alias.c.

557 {
558  if (!addr)
559  {
560  mutt_debug(LL_DEBUG5, "no, NULL address\n");
561  return false;
562  }
563  if (!addr->mailbox)
564  {
565  mutt_debug(LL_DEBUG5, "no, no mailbox\n");
566  return false;
567  }
568 
569  if (mutt_istr_equal(addr->mailbox, Username))
570  {
571  mutt_debug(LL_DEBUG5, "#1 yes, %s = %s\n", addr->mailbox, Username);
572  return true;
573  }
575  {
576  mutt_debug(LL_DEBUG5, "#2 yes, %s = %s @ %s\n", addr->mailbox, Username, ShortHostname);
577  return true;
578  }
579  const char *fqdn = mutt_fqdn(false, NeoMutt->sub);
580  if (string_is_address(addr->mailbox, Username, fqdn))
581  {
582  mutt_debug(LL_DEBUG5, "#3 yes, %s = %s @ %s\n", addr->mailbox, Username, NONULL(fqdn));
583  return true;
584  }
585  fqdn = mutt_fqdn(true, NeoMutt->sub);
586  if (string_is_address(addr->mailbox, Username, fqdn))
587  {
588  mutt_debug(LL_DEBUG5, "#4 yes, %s = %s @ %s\n", addr->mailbox, Username, NONULL(fqdn));
589  return true;
590  }
591 
592  if (C_From && mutt_istr_equal(C_From->mailbox, addr->mailbox))
593  {
594  mutt_debug(LL_DEBUG5, "#5 yes, %s = %s\n", addr->mailbox, C_From->mailbox);
595  return true;
596  }
597 
598  if (mutt_regexlist_match(&Alternates, addr->mailbox))
599  {
600  mutt_debug(LL_DEBUG5, "yes, %s matched by alternates\n", addr->mailbox);
601  if (mutt_regexlist_match(&UnAlternates, addr->mailbox))
602  mutt_debug(LL_DEBUG5, "but, %s matched by unalternates\n", addr->mailbox);
603  else
604  return true;
605  }
606 
607  mutt_debug(LL_DEBUG5, "no, all failed\n");
608  return false;
609 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ alias_new()

struct Alias* alias_new ( void  )

Create a new Alias.

Return values
ptrNewly allocated Alias

Free the result with alias_free()

Definition at line 617 of file alias.c.

618 {
619  struct Alias *a = mutt_mem_calloc(1, sizeof(struct Alias));
620  TAILQ_INIT(&a->addr);
621  return a;
622 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ alias_free()

void alias_free ( struct Alias **  ptr)

Free an Alias.

Parameters
[out]ptrAlias to free

Definition at line 628 of file alias.c.

629 {
630  if (!ptr || !*ptr)
631  return;
632 
633  struct Alias *alias = *ptr;
634 
635  struct EventAlias ea = { alias };
637 
638  FREE(&alias->name);
639  FREE(&alias->comment);
641  FREE(ptr);
642 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ aliaslist_free()

void aliaslist_free ( struct AliasList *  al)

Free a List of Aliases.

Parameters
alAliasList to free

Definition at line 648 of file alias.c.

649 {
650  struct Alias *np = NULL, *tmp = NULL;
651  TAILQ_FOREACH_SAFE(np, al, entries, tmp)
652  {
653  TAILQ_REMOVE(al, np, entries);
654  alias_free(&np);
655  }
656  TAILQ_INIT(al);
657 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ alias_init()

void alias_init ( void  )

Set up the Alias globals.

Definition at line 662 of file alias.c.

663 {
665 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ alias_shutdown()

void alias_shutdown ( void  )

Clean up the Alias globals.

Definition at line 670 of file alias.c.

671 {
672  struct Alias *np = NULL;
673  TAILQ_FOREACH(np, &Aliases, entries)
674  {
676  }
679 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ Aliases

struct AliasList Aliases = TAILQ_HEAD_INITIALIZER(Aliases)

List of all the user's email aliases.

Definition at line 55 of file alias.c.

Envelope::bcc
struct AddressList bcc
Email's 'Bcc' list.
Definition: envelope.h:60
STAILQ_INIT
#define STAILQ_INIT(head)
Definition: queue.h:369
mutt_beep
void mutt_beep(bool force)
Irritate the user.
Definition: curs_lib.c:99
TAILQ_INIT
#define TAILQ_INIT(head)
Definition: queue.h:758
mutt_mem_calloc
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
_
#define _(a)
Definition: message.h:28
NONULL
#define NONULL(x)
Definition: string2.h:37
aliaslist_free
void aliaslist_free(struct AliasList *al)
Free a List of Aliases.
Definition: alias.c:648
TAILQ_PREV
#define TAILQ_PREV(elm, headname, field)
Definition: queue.h:827
Alias::addr
struct AddressList addr
List of Addresses the Alias expands to.
Definition: alias.h:36
mutt_addrlist_dedupe
void mutt_addrlist_dedupe(struct AddressList *al)
Remove duplicate addresses.
Definition: address.c:1405
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
Address::personal
char * personal
Real name of address.
Definition: address.h:36
ListNode
A List node for strings.
Definition: list.h:34
mutt_addrlist_to_intl
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1304
string_is_address
static bool string_is_address(const char *str, const char *user, const char *domain)
Does an email address match a user and domain?
Definition: alias.c:257
alias_new
struct Alias * alias_new(void)
Create a new Alias.
Definition: alias.c:617
mutt_file_fclose
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
alias_reverse_init
void alias_reverse_init(void)
Set up the Reverse Alias Hash Table.
Definition: reverse.c:42
MUTT_ICONV_NO_FLAGS
#define MUTT_ICONV_NO_FLAGS
No flags are set.
Definition: charset.h:73
mutt_addrlist_write
size_t mutt_addrlist_write(const struct AddressList *al, char *buf, size_t buflen, bool display)
Write an Address to a buffer.
Definition: address.c:1150
NeoMutt::notify
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
TAILQ_EMPTY
#define TAILQ_EMPTY(head)
Definition: queue.h:714
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
MUTT_YES
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition: quad.h:40
mutt_expand_aliases
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:294
mutt_str_dup
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
C_UseDomain
WHERE bool C_UseDomain
Config: Qualify local addresses using this domain.
Definition: mutt_globals.h:168
LL_DEBUG1
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
FREE
#define FREE(x)
Definition: memory.h:40
mutt_perror
#define mutt_perror(...)
Definition: logging.h:85
mutt_addrlist_parse
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:458
TAILQ_INSERT_TAIL
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:802
alias_free
void alias_free(struct Alias **ptr)
Free an Alias.
Definition: alias.c:628
LL_DEBUG5
@ LL_DEBUG5
Log at debug level 5.
Definition: logging.h:44
MUTT_ABORT
@ MUTT_ABORT
User aborted the question (with Ctrl-G)
Definition: quad.h:38
mutt_ch_convert_string
int mutt_ch_convert_string(char **ps, const char *from, const char *to, uint8_t flags)
Convert a string between encodings.
Definition: charset.c:754
alias_reverse_add
void alias_reverse_add(struct Alias *alias)
Add an email address lookup for an Alias.
Definition: reverse.c:61
Username
WHERE char * Username
User's login name.
Definition: mutt_globals.h:52
STAILQ_FOREACH
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
EventAlias
An alias-change event.
Definition: alias.h:59
notify_send
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:152
alias_reverse_shutdown
void alias_reverse_shutdown(void)
Clear up the Reverse Alias Hash Table.
Definition: reverse.c:52
mutt_istr_equal
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
mutt_is_mail_list
bool mutt_is_mail_list(const struct Address *addr)
Is this the email address of a mailing list? - Implements addr_predicate_t.
Definition: maillist.c:45
mutt_str_equal
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
Envelope::reply_to
struct AddressList reply_to
Email's 'reply-to'.
Definition: envelope.h:62
TAILQ_HEAD_INITIALIZER
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:630
MUTT_FILE
#define MUTT_FILE
Do file completion.
Definition: mutt.h:58
TAILQ_REMOVE
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:834
TAILQ_FIRST
#define TAILQ_FIRST(head)
Definition: queue.h:716
Envelope::cc
struct AddressList cc
Email's 'Cc' list.
Definition: envelope.h:59
mutt_expand_path
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:128
C_ConfigCharset
WHERE char * C_ConfigCharset
Config: Character set that the config files are in.
Definition: mutt_globals.h:88
Address::group
bool group
Group mailbox?
Definition: address.h:38
mutt_list_insert_head
struct ListNode * mutt_list_insert_head(struct ListHead *h, char *s)
Insert a string at the beginning of a List.
Definition: list.c:45
cs_subset_path
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:133
expand_aliases_r
static void expand_aliases_r(struct AddressList *al, struct ListHead *expn)
Expand aliases, recursively.
Definition: alias.c:99
mutt_addrlist_clear
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1468
Envelope::to
struct AddressList to
Email's 'To' list.
Definition: envelope.h:58
mutt_debug
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
mutt_addr_free
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition: address.c:440
TAILQ_FOREACH_SAFE
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:728
Aliases
struct AliasList Aliases
List of all the user's email aliases.
Definition: alias.c:55
mutt_str_replace
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
Address::mailbox
char * mailbox
Mailbox and host address.
Definition: address.h:37
Alias::name
char * name
Short name.
Definition: alias.h:35
EventAlias::alias
struct Alias * alias
Definition: alias.h:61
NT_ALIAS_DELETED
@ NT_ALIAS_DELETED
An Alias is about to be deleted.
Definition: alias.h:53
Envelope::from
struct AddressList from
Email's 'From' list.
Definition: envelope.h:57
TAILQ_NEXT
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
recode_buf
static void recode_buf(char *buf, size_t buflen)
Convert some text between two character sets.
Definition: alias.c:185
Alias::comment
char * comment
Free-form comment string.
Definition: alias.h:37
ShortHostname
WHERE char * ShortHostname
Short version of the hostname.
Definition: mutt_globals.h:50
alias_lookup
struct AddressList * alias_lookup(const char *name)
Find an Alias.
Definition: alias.c:276
NeoMutt
Container for Accounts, Notifications.
Definition: neomutt.h:36
NT_ALIAS
@ NT_ALIAS
Alias has changed, NotifyAlias, EventAlias.
Definition: notify_type.h:44
mutt_gecos_name
char * mutt_gecos_name(char *dest, size_t destlen, struct passwd *pw)
Lookup a user's real name in /etc/passwd.
Definition: muttlib.c:362
ListNode::data
char * data
String.
Definition: list.h:36
MUTT_CLEAR
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:62
NeoMutt::sub
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
C_From
WHERE struct Address * C_From
Config: Default 'From' address to use, if isn't otherwise set.
Definition: mutt_globals.h:81
Alias
A shortcut for an email address or addresses.
Definition: alias.h:33
mutt_addrlist_to_local
int mutt_addrlist_to_local(struct AddressList *al)
Convert an Address list from Punycode.
Definition: address.c:1386
mutt_get_field
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:311
alias_reverse_delete
void alias_reverse_delete(struct Alias *alias)
Remove an email address lookup for an Alias.
Definition: reverse.c:83
mutt_fqdn
const char * mutt_fqdn(bool may_hide_host, const struct ConfigSubset *sub)
Get the Fully-Qualified Domain Name.
Definition: sendlib.c:1182
C_Charset
char * C_Charset
Config: Default character set for displaying text on screen.
Definition: charset.c:53
mutt_yesorno
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:380
mutt_message
#define mutt_message(...)
Definition: logging.h:83
mutt_file_quote_filename
size_t mutt_file_quote_filename(const char *filename, char *buf, size_t buflen)
Quote a filename to survive the shell's quoting rules.
Definition: file.c:793
Envelope::mail_followup_to
struct AddressList mail_followup_to
Email's 'mail-followup-to'.
Definition: envelope.h:63
mutt_regexlist_match
bool mutt_regexlist_match(struct RegexList *rl, const char *str)
Does a string match any Regex in the list?
Definition: regex.c:192
mutt_addrlist_copy
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:737
mutt_file_fsync_close
int mutt_file_fsync_close(FILE **fp)
Flush the data, before closing a file (and NULL the pointer)
Definition: file.c:169
TAILQ_INSERT_BEFORE
#define TAILQ_INSERT_BEFORE(listelm, elm, field)
Definition: queue.h:779
mutt_list_free
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
check_alias_name
static int check_alias_name(const char *s, char *dest, size_t destlen)
Sanity-check an alias name.
Definition: alias.c:209
mutt_addr_is_user
bool mutt_addr_is_user(const struct Address *addr)
Does the address belong to the user.
Definition: alias.c:556
Address
An email address.
Definition: address.h:34
mutt_error
#define mutt_error(...)
Definition: logging.h:84
mutt_str_copy
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:716
write_safe_address
static void write_safe_address(FILE *fp, char *s)
Defang malicious email addresses.
Definition: alias.c:81
MUTT_COMP_NO_FLAGS
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:56