NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
alias.c
Go to the documentation of this file.
1 
31 #include "config.h"
32 #include <stddef.h>
33 #include <pwd.h>
34 #include <stdbool.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <wchar.h>
39 #include <wctype.h>
40 #include "mutt/lib.h"
41 #include "address/lib.h"
42 #include "config/lib.h"
43 #include "email/lib.h"
44 #include "core/lib.h"
45 #include "gui/lib.h"
46 #include "mutt.h"
47 #include "alias.h"
48 #include "lib.h"
49 #include "send/lib.h"
50 #include "maillist.h"
51 #include "mutt_globals.h"
52 #include "muttlib.h"
53 #include "reverse.h"
54 
55 struct AliasList Aliases = TAILQ_HEAD_INITIALIZER(Aliases);
56 
81 static void write_safe_address(FILE *fp, char *s)
82 {
83  while (*s)
84  {
85  if ((*s == '\\') || (*s == '`') || (*s == '\'') || (*s == '"') || (*s == '$'))
86  fputc('\\', fp);
87  fputc(*s, fp);
88  s++;
89  }
90 }
91 
99 static void expand_aliases_r(struct AddressList *al, struct ListHead *expn)
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 }
176 
185 static void recode_buf(char *buf, size_t buflen)
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 }
197 
209 static int check_alias_name(const char *s, char *dest, size_t destlen)
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 }
249 
257 static bool string_is_address(const char *str, const char *user, const char *domain)
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 }
267 
276 struct AddressList *alias_lookup(const char *name)
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 }
287 
294 void mutt_expand_aliases(struct AddressList *al)
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 }
303 
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 }
317 
326 struct AddressList *mutt_get_address(struct Envelope *env, const char **prefix)
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 }
360 
366 void alias_create(struct AddressList *al, const struct ConfigSubset *sub)
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 }
550 
556 bool mutt_addr_is_user(const struct Address *addr)
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 }
610 
617 struct Alias *alias_new(void)
618 {
619  struct Alias *a = mutt_mem_calloc(1, sizeof(struct Alias));
620  TAILQ_INIT(&a->addr);
621  return a;
622 }
623 
628 void alias_free(struct Alias **ptr)
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 }
643 
648 void aliaslist_free(struct AliasList *al)
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 }
658 
662 void alias_init(void)
663 {
665 }
666 
670 void alias_shutdown(void)
671 {
672  struct Alias *np = NULL;
673  TAILQ_FOREACH(np, &Aliases, entries)
674  {
676  }
679 }
Envelope
The header of an Email.
Definition: envelope.h:54
mutt_expand_aliases_env
void mutt_expand_aliases_env(struct Envelope *env)
Expand aliases in all the fields of an Envelope.
Definition: alias.c:308
maillist.h
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
alias_init
void alias_init(void)
Set up the Alias globals.
Definition: alias.c:662
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
reverse.h
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
alias_shutdown
void alias_shutdown(void)
Clean up the Alias globals.
Definition: alias.c:670
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
mutt_globals.h
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
alias.h
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
lib.h
alias_create
void alias_create(struct AddressList *al, const struct ConfigSubset *sub)
Create a new Alias from an Address.
Definition: alias.c:366
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
lib.h
muttlib.h
Address::group
bool group
Group mailbox?
Definition: address.h:38
lib.h
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
lib.h
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
lib.h
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
lib.h
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
mutt.h
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
ConfigSubset
A set of inherited config items.
Definition: subset.h:46
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
lib.h
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_get_address
struct AddressList * mutt_get_address(struct Envelope *env, const char **prefix)
Get an Address from an Envelope.
Definition: alias.c:326
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