NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
lib.h File Reference
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "mutt_commands.h"
#include "sort.h"
#include "gui.h"
+ Include dependency graph for lib.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void alias_init (void)
 Set up the Alias globals. More...
 
void alias_shutdown (void)
 Clean up the Alias globals. More...
 
void alias_create (struct AddressList *al, const struct ConfigSubset *sub)
 Create a new Alias from an Address. More...
 
struct AddressList * alias_lookup (const char *name)
 Find an Alias. More...
 
bool mutt_addr_is_user (const struct Address *addr)
 Does the address belong to the user. More...
 
void mutt_expand_aliases_env (struct Envelope *env)
 Expand aliases in all the fields of an Envelope. More...
 
void mutt_expand_aliases (struct AddressList *al)
 Expand aliases in a List of Addresses. More...
 
struct AddressList * mutt_get_address (struct Envelope *env, const char **prefix)
 Get an Address from an Envelope. More...
 
enum CommandResult parse_alias (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'alias' command - Implements Command::parse() More...
 
enum CommandResult parse_unalias (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unalias' command - Implements Command::parse() More...
 
int alias_complete (char *buf, size_t buflen, struct ConfigSubset *sub)
 alias completion routine More...
 
int query_complete (char *buf, size_t buflen, struct ConfigSubset *sub)
 Perform auto-complete using an Address Query. More...
 
void query_index (struct ConfigSubset *sub)
 Perform an Alias Query and display the results. More...
 
struct Addressalias_reverse_lookup (const struct Address *addr)
 Does the user have an alias for the given address. More...
 
void alias_array_sort (struct AliasViewArray *ava, const struct ConfigSubset *sub)
 Sort and reindex an AliasViewArray. More...
 

Detailed Description

Email Aliases

Authors
  • 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 lib.h.

Function Documentation

◆ 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:

◆ 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:

◆ 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_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:

◆ 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_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_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:

◆ parse_alias()

enum CommandResult parse_alias ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'alias' command - Implements Command::parse()

e.g. "alias jim James Smith <js@example.com> # Pointy-haired boss"

Definition at line 49 of file commands.c.

51 {
52  struct Alias *tmp = NULL;
53  struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
54  enum NotifyAlias event;
55 
56  if (!MoreArgs(s))
57  {
58  mutt_buffer_strcpy(err, _("alias: no address"));
59  return MUTT_CMD_WARNING;
60  }
61 
62  /* name */
64  mutt_debug(LL_DEBUG5, "First token is '%s'\n", buf->data);
65  if (parse_grouplist(&gl, buf, s, err) == -1)
66  {
67  return MUTT_CMD_ERROR;
68  }
69  char *name = mutt_str_dup(buf->data);
70 
71  /* address list */
73  mutt_debug(LL_DEBUG5, "Second token is '%s'\n", buf->data);
74  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
75  int parsed = mutt_addrlist_parse2(&al, buf->data);
76  if (parsed == 0)
77  {
78  mutt_buffer_printf(err, _("Warning: Bad address '%s' in alias '%s'"), buf->data, name);
79  FREE(&name);
80  goto bail;
81  }
82 
83  /* IDN */
84  char *estr = NULL;
85  if (mutt_addrlist_to_intl(&al, &estr))
86  {
87  mutt_buffer_printf(err, _("Warning: Bad IDN '%s' in alias '%s'"), estr, name);
88  FREE(&name);
89  FREE(&estr);
90  goto bail;
91  }
92 
93  /* check to see if an alias with this name already exists */
94  TAILQ_FOREACH(tmp, &Aliases, entries)
95  {
96  if (mutt_istr_equal(tmp->name, name))
97  break;
98  }
99 
100  if (tmp)
101  {
102  FREE(&name);
104  /* override the previous value */
105  mutt_addrlist_clear(&tmp->addr);
106  FREE(&tmp->comment);
107  event = NT_ALIAS_CHANGED;
108  }
109  else
110  {
111  /* create a new alias */
112  tmp = alias_new();
113  tmp->name = name;
114  TAILQ_INSERT_TAIL(&Aliases, tmp, entries);
115  event = NT_ALIAS_NEW;
116  }
117  tmp->addr = al;
118 
119  mutt_grouplist_add_addrlist(&gl, &tmp->addr);
120 
121  if (C_DebugLevel > LL_DEBUG4)
122  {
123  /* A group is terminated with an empty address, so check a->mailbox */
124  struct Address *a = NULL;
125  TAILQ_FOREACH(a, &tmp->addr, entries)
126  {
127  if (!a->mailbox)
128  break;
129 
130  if (a->group)
131  mutt_debug(LL_DEBUG5, " Group %s\n", a->mailbox);
132  else
133  mutt_debug(LL_DEBUG5, " %s\n", a->mailbox);
134  }
135  }
137  if (!MoreArgs(s) && (s->dptr[0] == '#'))
138  {
139  char *comment = s->dptr + 1;
140  SKIPWS(comment);
141  tmp->comment = mutt_str_dup(comment);
142  }
143 
144  alias_reverse_add(tmp);
145 
146  struct EventAlias ea = { tmp };
147  notify_send(NeoMutt->notify, NT_ALIAS, event, &ea);
148 
149  return MUTT_CMD_SUCCESS;
150 
151 bail:
153  return MUTT_CMD_ERROR;
154 }
+ Here is the call graph for this function:

◆ parse_unalias()

enum CommandResult parse_unalias ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'unalias' command - Implements Command::parse()

Definition at line 159 of file commands.c.

161 {
162  do
163  {
165 
166  struct Alias *np = NULL;
167  if (mutt_str_equal("*", buf->data))
168  {
169  TAILQ_FOREACH(np, &Aliases, entries)
170  {
172  }
173 
175  return MUTT_CMD_SUCCESS;
176  }
177 
178  TAILQ_FOREACH(np, &Aliases, entries)
179  {
180  if (!mutt_istr_equal(buf->data, np->name))
181  continue;
182 
183  TAILQ_REMOVE(&Aliases, np, entries);
185  alias_free(&np);
186  break;
187  }
188  } while (MoreArgs(s));
189  return MUTT_CMD_SUCCESS;
190 }
+ Here is the call graph for this function:

◆ alias_complete()

int alias_complete ( char *  buf,
size_t  buflen,
struct ConfigSubset sub 
)

alias completion routine

Parameters
bufPartial Alias to complete
buflenLength of buffer
subConfig items
Return values
1Success
0Error

Given a partial alias, this routine attempts to fill in the alias from the alias list as much as possible. if given empty search string or found nothing, present all aliases

Definition at line 375 of file dlgalias.c.

376 {
377  struct Alias *np = NULL;
378  char bestname[8192] = { 0 };
379 
380  struct AliasMenuData mdata = { NULL, NULL, ARRAY_HEAD_INITIALIZER, sub };
381  mdata.str = mutt_str_dup(buf);
382 
383  if (buf[0] != '\0')
384  {
385  TAILQ_FOREACH(np, &Aliases, entries)
386  {
387  if (np->name && mutt_strn_equal(np->name, buf, strlen(buf)))
388  {
389  if (bestname[0] == '\0') /* init */
390  {
391  mutt_str_copy(bestname, np->name,
392  MIN(mutt_str_len(np->name) + 1, sizeof(bestname)));
393  }
394  else
395  {
396  int i;
397  for (i = 0; np->name[i] && (np->name[i] == bestname[i]); i++)
398  ; // do nothing
399 
400  bestname[i] = '\0';
401  }
402  }
403  }
404 
405  if (bestname[0] != '\0')
406  {
407  /* fake the pattern for menu title */
408  char *mtitle = NULL;
409  mutt_str_asprintf(&mtitle, "~f ^%s", buf);
410  FREE(&mdata.str);
411  mdata.str = mtitle;
412 
413  if (!mutt_str_equal(bestname, buf))
414  {
415  /* we are adding something to the completion */
416  mutt_str_copy(buf, bestname, mutt_str_len(bestname) + 1);
417  FREE(&mdata.str);
418  return 1;
419  }
420 
421  /* build alias list and show it */
422  TAILQ_FOREACH(np, &Aliases, entries)
423  {
424  int aasize = alias_array_alias_add(&mdata.ava, np);
425 
426  struct AliasView *av = ARRAY_GET(&mdata.ava, aasize - 1);
427 
428  if (np->name && !mutt_strn_equal(np->name, buf, strlen(buf)))
429  {
430  av->is_visible = false;
431  }
432  }
433  }
434  }
435 
436  if (ARRAY_EMPTY(&mdata.ava))
437  {
438  TAILQ_FOREACH(np, &Aliases, entries)
439  {
440  alias_array_alias_add(&mdata.ava, np);
441  }
442 
443  mutt_pattern_alias_func(MUTT_LIMIT, NULL, _("Aliases"), &mdata, Context, NULL);
444  }
445 
446  alias_array_sort(&mdata.ava, mdata.sub);
447 
448  bestname[0] = '\0';
449  dlg_select_alias(bestname, sizeof(bestname), &mdata);
450  if (bestname[0] != '\0')
451  mutt_str_copy(buf, bestname, buflen);
452 
453  struct AliasView *avp = NULL;
454  ARRAY_FOREACH(avp, &mdata.ava)
455  {
456  if (!avp->is_deleted)
457  continue;
458 
459  TAILQ_REMOVE(&Aliases, avp->alias, entries);
460  alias_free(&avp->alias);
461  }
462 
463  ARRAY_FREE(&mdata.ava);
464  FREE(&mdata.str);
465 
466  return 0;
467 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ query_complete()

int query_complete ( char *  buf,
size_t  buflen,
struct ConfigSubset sub 
)

Perform auto-complete using an Address Query.

Parameters
bufBuffer for completion
buflenLength of buffer
subConfig item
Return values
0Always

Definition at line 606 of file dlgquery.c.

607 {
608  const char *query_command = cs_subset_string(sub, "query_command");
609  if (!query_command)
610  {
611  mutt_warning(_("Query command not defined"));
612  return 0;
613  }
614 
615  struct AliasList al = TAILQ_HEAD_INITIALIZER(al);
616  query_run(buf, true, &al, sub);
617  if (TAILQ_EMPTY(&al))
618  return 0;
619 
620  struct Alias *a_first = TAILQ_FIRST(&al);
621  if (!TAILQ_NEXT(a_first, entries)) // only one response?
622  {
623  struct AddressList addr = TAILQ_HEAD_INITIALIZER(addr);
624  if (alias_to_addrlist(&addr, a_first))
625  {
626  mutt_addrlist_to_local(&addr);
627  buf[0] = '\0';
628  mutt_addrlist_write(&addr, buf, buflen, false);
629  mutt_addrlist_clear(&addr);
630  aliaslist_free(&al);
632  }
633  return 0;
634  }
635 
636  /* multiple results, choose from query menu */
637  dlg_select_query(buf, buflen, &al, true, sub);
638  aliaslist_free(&al);
639  return 0;
640 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ query_index()

void query_index ( struct ConfigSubset sub)

Perform an Alias Query and display the results.

Parameters
subConfig item

Definition at line 646 of file dlgquery.c.

647 {
648  const char *query_command = cs_subset_string(sub, "query_command");
649  if (!query_command)
650  {
651  mutt_warning(_("Query command not defined"));
652  return;
653  }
654 
655  char buf[256] = { 0 };
656  if ((mutt_get_field(_("Query: "), buf, sizeof(buf), MUTT_COMP_NO_FLAGS, false,
657  NULL, NULL) != 0) ||
658  (buf[0] == '\0'))
659  {
660  return;
661  }
662 
663  struct AliasList al = TAILQ_HEAD_INITIALIZER(al);
664  query_run(buf, false, &al, sub);
665  if (TAILQ_EMPTY(&al))
666  return;
667 
668  dlg_select_query(buf, sizeof(buf), &al, false, sub);
669  aliaslist_free(&al);
670 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ alias_reverse_lookup()

struct Address* alias_reverse_lookup ( const struct Address addr)

Does the user have an alias for the given address.

Parameters
addrAddress to lookup
Return values
ptrMatching Address

Definition at line 105 of file reverse.c.

106 {
107  if (!addr || !addr->mailbox)
108  return NULL;
109 
110  return mutt_hash_find(ReverseAliases, addr->mailbox);
111 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ alias_array_sort()

void alias_array_sort ( struct AliasViewArray *  ava,
const struct ConfigSubset sub 
)

Sort and reindex an AliasViewArray.

Parameters
avaArray of Aliases
subConfig items

Definition at line 158 of file sort.c.

159 {
160  if (!ava || ARRAY_EMPTY(ava))
161  return;
162 
163  sort_alias = cs_subset_sort(sub, "sort_alias");
165 
166  struct AliasView *avp = NULL;
167  ARRAY_FOREACH(avp, ava)
168  {
169  avp->num = ARRAY_FOREACH_IDX;
170  }
171 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:
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
dlg_select_query
static void dlg_select_query(char *buf, size_t buflen, struct AliasList *all, bool retbuf, struct ConfigSubset *sub)
Get the user to enter an Address Query.
Definition: dlgquery.c:310
NotifyAlias
NotifyAlias
Alias notification types.
Definition: alias.h:49
_
#define _(a)
Definition: message.h:28
NONULL
#define NONULL(x)
Definition: string2.h:37
mutt_grouplist_add_addrlist
void mutt_grouplist_add_addrlist(struct GroupList *gl, struct AddressList *al)
Add Address list to a GroupList.
Definition: group.c:226
MUTT_TOKEN_SEMICOLON
#define MUTT_TOKEN_SEMICOLON
Don't treat ; as special.
Definition: mutt.h:77
aliaslist_free
void aliaslist_free(struct AliasList *al)
Free a List of Aliases.
Definition: alias.c:648
Alias::addr
struct AddressList addr
List of Addresses the Alias expands to.
Definition: alias.h:36
mutt_strn_equal
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:593
mutt_addrlist_dedupe
void mutt_addrlist_dedupe(struct AddressList *al)
Remove duplicate addresses.
Definition: address.c:1405
MoreArgs
#define MoreArgs(buf)
Definition: buffer.h:40
alias_array_sort
void alias_array_sort(struct AliasViewArray *ava, const struct ConfigSubset *sub)
Sort and reindex an AliasViewArray.
Definition: sort.c:158
mutt_addrlist_to_intl
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1304
sort_alias
static short sort_alias
Definition: sort.c:42
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
AliasMenuData::str
char * str
String representing the limit being used.
Definition: gui.h:55
mutt_file_fclose
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
alias_array_alias_add
int alias_array_alias_add(struct AliasViewArray *ava, struct Alias *alias)
Add an Alias to the AliasViewArray.
Definition: array.c:45
alias_reverse_init
void alias_reverse_init(void)
Set up the Reverse Alias Hash Table.
Definition: reverse.c:42
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
Context
The "current" mailbox.
Definition: context.h:38
mutt_str_dup
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
AliasView::is_visible
bool is_visible
Is visible?
Definition: gui.h:44
ARRAY_SORT
#define ARRAY_SORT(head, fn)
Sort an array.
Definition: array.h:271
AliasView::alias
struct Alias * alias
Alias.
Definition: gui.h:45
FREE
#define FREE(x)
Definition: memory.h:40
AliasView::num
int num
Index number in list.
Definition: gui.h:38
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
MUTT_TOKEN_NO_FLAGS
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:70
alias_free
void alias_free(struct Alias **ptr)
Free an Alias.
Definition: alias.c:628
NT_ALIAS_CHANGED
@ NT_ALIAS_CHANGED
An Alias has been changed.
Definition: alias.h:52
Buffer::dptr
char * dptr
Current read/write position.
Definition: buffer.h:36
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
alias_reverse_add
void alias_reverse_add(struct Alias *alias)
Add an email address lookup for an Alias.
Definition: reverse.c:61
MUTT_LIMIT
@ MUTT_LIMIT
Messages in limited view.
Definition: mutt.h:105
Username
WHERE char * Username
User's login name.
Definition: mutt_globals.h:52
ARRAY_GET
#define ARRAY_GET(head, idx)
Return the element at index.
Definition: array.h:105
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
AliasView
GUI data wrapping an Alias.
Definition: gui.h:36
SKIPWS
#define SKIPWS(ch)
Definition: string2.h:46
mutt_istr_equal
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
mutt_hash_find
void * mutt_hash_find(const struct HashTable *table, const char *strkey)
Find the HashElem data in a Hash Table element using a key.
Definition: hash.c:354
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
mutt_extract_token
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:393
TAILQ_FIRST
#define TAILQ_FIRST(head)
Definition: queue.h:716
Envelope::cc
struct AddressList cc
Email's 'Cc' list.
Definition: envelope.h:59
AliasMenuData::ava
struct AliasViewArray ava
Array of AliasView.
Definition: gui.h:57
mutt_expand_path
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:128
ARRAY_FOREACH
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:206
ARRAY_HEAD_INITIALIZER
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition: array.h:54
Address::group
bool group
Group mailbox?
Definition: address.h:38
mutt_grouplist_destroy
void mutt_grouplist_destroy(struct GroupList *gl)
Free a GroupList.
Definition: group.c:157
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
mutt_clear_error
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
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
mutt_addrlist_parse2
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:616
parse_grouplist
int parse_grouplist(struct GroupList *gl, struct Buffer *buf, struct Buffer *s, struct Buffer *err)
Parse a group context.
Definition: command_parse.c:393
ARRAY_FREE
#define ARRAY_FREE(head)
Release all memory.
Definition: array.h:198
Envelope::to
struct AddressList to
Email's 'To' list.
Definition: envelope.h:58
mutt_debug
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
MUTT_CMD_SUCCESS
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition: mutt_commands.h:38
AliasMenuData::sub
struct ConfigSubset * sub
Config items.
Definition: gui.h:58
mutt_str_len
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
Aliases
struct AliasList Aliases
List of all the user's email aliases.
Definition: alias.c:55
alias_get_sort_function
static sort_t alias_get_sort_function(short sort)
Sorting function decision logic.
Definition: sort.c:138
MUTT_CMD_ERROR
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: mutt_commands.h:36
query_run
static int query_run(char *s, bool verbose, struct AliasList *al, const struct ConfigSubset *sub)
Run an external program to find Addresses.
Definition: dlgquery.c:236
mutt_str_replace
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
cs_subset_sort
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:219
Address::mailbox
char * mailbox
Mailbox and host address.
Definition: address.h:37
Alias::name
char * name
Short name.
Definition: alias.h:35
STAILQ_HEAD_INITIALIZER
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
NT_ALIAS_NEW
@ NT_ALIAS_NEW
A new Alias has been created.
Definition: alias.h:51
cs_subset_string
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:241
MUTT_CMD_WARNING
@ MUTT_CMD_WARNING
Warning: Help given to the user.
Definition: mutt_commands.h:37
ARRAY_EMPTY
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition: array.h:70
Envelope::from
struct AddressList from
Email's 'From' list.
Definition: envelope.h:57
C_DebugLevel
short C_DebugLevel
Config: Logging level for debug logs.
Definition: mutt_logging.c:48
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_TOKEN_QUOTE
#define MUTT_TOKEN_QUOTE
Don't interpret quotes.
Definition: mutt.h:74
NT_ALIAS
@ NT_ALIAS
Alias has changed, NotifyAlias, EventAlias.
Definition: notify_type.h:44
AliasMenuData
AliasMenuData - AliasView array wrapper with Pattern information.
Definition: gui.h:53
mutt_pattern_alias_func
int mutt_pattern_alias_func(int op, char *prompt, char *title, struct AliasMenuData *mdata, struct Context *ctx, struct Menu *menu)
Perform some Pattern matching for Alias.
Definition: pattern.c:241
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_to_addrlist
static bool alias_to_addrlist(struct AddressList *al, struct Alias *alias)
Turn an Alias into an AddressList.
Definition: dlgquery.c:76
ReverseAliases
static struct HashTable * ReverseAliases
Hash Table of aliases (email address -> alias)
Definition: reverse.c:37
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
mutt_yesorno
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:380
Buffer::data
char * data
Pointer to data.
Definition: buffer.h:35
mutt_message
#define mutt_message(...)
Definition: logging.h:83
LL_DEBUG4
@ LL_DEBUG4
Log at debug level 4.
Definition: logging.h:43
mutt_str_asprintf
int mutt_str_asprintf(char **strp, const char *fmt,...)
Definition: string.c:1095
dlg_select_alias
static void dlg_select_alias(char *buf, size_t buflen, struct AliasMenuData *mdata)
Display a menu of Aliases.
Definition: dlgalias.c:194
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_buffer_printf
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
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_warning
#define mutt_warning(...)
Definition: logging.h:82
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
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_buffer_strcpy
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
AliasView::is_deleted
bool is_deleted
Is it deleted?
Definition: gui.h:43
MUTT_TOKEN_SPACE
#define MUTT_TOKEN_SPACE
Don't treat whitespace as a term.
Definition: mutt.h:73
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
MIN
#define MIN(a, b)
Definition: memory.h:31
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