NeoMutt
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
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 "browser/lib.h"
50#include "editor/lib.h"
51#include "history/lib.h"
52#include "question/lib.h"
53#include "send/lib.h"
54#include "alternates.h"
55#include "globals.h" // IWYU pragma: keep
56#include "maillist.h"
57#include "muttlib.h"
58#include "reverse.h"
59
61
86static void write_safe_address(FILE *fp, const char *s)
87{
88 while (*s)
89 {
90 if ((*s == '\\') || (*s == '`') || (*s == '\'') || (*s == '"') || (*s == '$'))
91 fputc('\\', fp);
92 fputc(*s, fp);
93 s++;
94 }
95}
96
104static void expand_aliases_r(struct AddressList *al, struct ListHead *expn)
105{
106 struct Address *a = TAILQ_FIRST(al);
107 while (a)
108 {
109 if (!a->group && !a->personal && a->mailbox && !buf_find_char(a->mailbox, '@'))
110 {
111 struct AddressList *alias = alias_lookup(buf_string(a->mailbox));
112 if (alias)
113 {
114 bool duplicate = false;
115 struct ListNode *np = NULL;
116 STAILQ_FOREACH(np, expn, entries)
117 {
118 if (mutt_str_equal(buf_string(a->mailbox), np->data)) /* alias already found */
119 {
120 mutt_debug(LL_DEBUG1, "loop in alias found for '%s'\n", buf_string(a->mailbox));
121 duplicate = true;
122 break;
123 }
124 }
125
126 if (duplicate)
127 {
128 // We've already seen this alias, so drop it
129 struct Address *next = TAILQ_NEXT(a, entries);
130 TAILQ_REMOVE(al, a, entries);
131 mutt_addr_free(&a);
132 a = next;
133 continue;
134 }
135
136 // Keep a list of aliases that we've already seen
138
139 /* The alias may expand to several addresses,
140 * some of which may themselves be aliases.
141 * Create a copy and recursively expand any aliases within. */
142 struct AddressList copy = TAILQ_HEAD_INITIALIZER(copy);
143 mutt_addrlist_copy(&copy, alias, false);
144 expand_aliases_r(&copy, expn);
145
146 /* Next, move the expanded addresses
147 * from the copy into the original list (before the alias) */
148 struct Address *a2 = NULL, *tmp = NULL;
149 TAILQ_FOREACH_SAFE(a2, &copy, entries, tmp)
150 {
151 TAILQ_INSERT_BEFORE(a, a2, entries);
152 }
153 a = TAILQ_PREV(a, AddressList, entries);
154 // Finally, remove the alias itself
155 struct Address *next = TAILQ_NEXT(a, entries);
156 TAILQ_REMOVE(al, next, entries);
157 mutt_addr_free(&next);
158 }
159 else
160 {
161 struct passwd *pw = getpwnam(buf_string(a->mailbox));
162 if (pw)
163 {
164 char namebuf[256] = { 0 };
165
166 mutt_gecos_name(namebuf, sizeof(namebuf), pw);
167 a->personal = buf_new(namebuf);
168 }
169 }
170 }
171 a = TAILQ_NEXT(a, entries);
172 }
173
174 const char *fqdn = NULL;
175 const bool c_use_domain = cs_subset_bool(NeoMutt->sub, "use_domain");
176 if (c_use_domain && (fqdn = mutt_fqdn(true, NeoMutt->sub)))
177 {
178 /* now qualify all local addresses */
179 mutt_addrlist_qualify(al, fqdn);
180 }
181}
182
190static void recode_buf(struct Buffer *buf)
191{
192 const char *const c_config_charset = cs_subset_string(NeoMutt->sub, "config_charset");
193 if (!c_config_charset || !cc_charset())
194 return;
195
196 char *s = buf_strdup(buf);
197 if (!s)
198 return;
199 if (mutt_ch_convert_string(&s, cc_charset(), c_config_charset, MUTT_ICONV_NO_FLAGS) == 0)
200 buf_strcpy(buf, s);
201 FREE(&s);
202}
203
215static int check_alias_name(const char *s, char *dest, size_t destlen)
216{
217 wchar_t wc = 0;
218 mbstate_t mbstate = { 0 };
219 size_t l;
220 int rc = 0;
221 bool dry = !dest || !destlen;
222
223 if (!dry)
224 destlen--;
225 for (; s && *s && (dry || destlen) && (l = mbrtowc(&wc, s, MB_CUR_MAX, &mbstate)) != 0;
226 s += l, destlen -= l)
227 {
228 bool bad = (l == ICONV_ILLEGAL_SEQ) || (l == ICONV_BUF_TOO_SMALL); /* conversion error */
229 bad = bad || (!dry && l > destlen); /* too few room for mb char */
230 if (l == 1)
231 bad = bad || (!strchr("-_+=.", *s) && !iswalnum(wc));
232 else
233 bad = bad || !iswalnum(wc);
234 if (bad)
235 {
236 if (dry)
237 return -1;
238 if (l == ICONV_ILLEGAL_SEQ)
239 memset(&mbstate, 0, sizeof(mbstate_t));
240 *dest++ = '_';
241 rc = -1;
242 }
243 else if (!dry)
244 {
245 memcpy(dest, s, l);
246 dest += l;
247 }
248 }
249 if (!dry)
250 *dest = '\0';
251 return rc;
252}
253
261static bool string_is_address(const char *str, const char *user, const char *domain)
262{
263 char buf[1024] = { 0 };
264
265 snprintf(buf, sizeof(buf), "%s@%s", NONULL(user), NONULL(domain));
266 if (mutt_istr_equal(str, buf))
267 return true;
268
269 return false;
270}
271
280struct AddressList *alias_lookup(const char *name)
281{
282 struct Alias *a = NULL;
283
284 TAILQ_FOREACH(a, &Aliases, entries)
285 {
286 if (mutt_istr_equal(name, a->name))
287 return &a->addr;
288 }
289 return NULL;
290}
291
298void mutt_expand_aliases(struct AddressList *al)
299{
300 struct ListHead expn; /* previously expanded aliases to avoid loops */
301
302 STAILQ_INIT(&expn);
303 expand_aliases_r(al, &expn);
304 mutt_list_free(&expn);
306}
307
313{
315 mutt_expand_aliases(&env->to);
316 mutt_expand_aliases(&env->cc);
320}
321
330struct AddressList *mutt_get_address(struct Envelope *env, const char **prefix)
331{
332 struct AddressList *al = NULL;
333 const char *pfx = NULL;
334
336 {
337 if (!TAILQ_EMPTY(&env->to) && !mutt_is_mail_list(TAILQ_FIRST(&env->to)))
338 {
339 pfx = "To";
340 al = &env->to;
341 }
342 else
343 {
344 pfx = "Cc";
345 al = &env->cc;
346 }
347 }
348 else if (!TAILQ_EMPTY(&env->reply_to) && !mutt_is_mail_list(TAILQ_FIRST(&env->reply_to)))
349 {
350 pfx = "Reply-To";
351 al = &env->reply_to;
352 }
353 else
354 {
355 al = &env->from;
356 pfx = "From";
357 }
358
359 if (prefix)
360 *prefix = pfx;
361
362 return al;
363}
364
370void alias_create(struct AddressList *al, const struct ConfigSubset *sub)
371{
372 struct Buffer *buf = buf_pool_get();
373 struct Buffer *fixed = buf_pool_get();
374 struct Buffer *prompt = NULL;
375 struct Buffer *tmp = buf_pool_get();
376
377 struct Address *addr = NULL;
378 char *pc = NULL;
379 char *err = NULL;
380 FILE *fp_alias = NULL;
381
382 if (al)
383 {
384 addr = TAILQ_FIRST(al);
385 if (addr && addr->mailbox)
386 {
387 buf_copy(tmp, addr->mailbox);
388 pc = strchr(buf_string(tmp), '@');
389 if (pc)
390 *pc = '\0';
391 }
392 }
393
394 /* Don't suggest a bad alias name in the event of a strange local part. */
395 check_alias_name(buf_string(tmp), buf->data, buf->dsize);
396
397retry_name:
398 /* L10N: prompt to add a new alias */
399 if ((mw_get_field(_("Alias as: "), buf, MUTT_COMP_NO_FLAGS, HC_OTHER, NULL, NULL) != 0) ||
400 buf_is_empty(buf))
401 {
402 goto done;
403 }
404
405 /* check to see if the user already has an alias defined */
406 if (alias_lookup(buf_string(buf)))
407 {
408 mutt_error(_("You already have an alias defined with that name"));
409 goto done;
410 }
411
412 if (check_alias_name(buf_string(buf), fixed->data, fixed->dsize))
413 {
414 switch (query_yesorno(_("Warning: This alias name may not work. Fix it?"), MUTT_YES))
415 {
416 case MUTT_YES:
417 buf_copy(buf, fixed);
418 goto retry_name;
419 case MUTT_ABORT:
420 goto done;
421 default:; // do nothing
422 }
423 }
424
425 struct Alias *alias = alias_new();
426 alias->name = buf_strdup(buf);
427
429
430 if (addr && addr->mailbox)
431 buf_copy(buf, addr->mailbox);
432 else
433 buf_reset(buf);
434
435 mutt_addrlist_to_intl(al, NULL);
436
437 do
438 {
439 if ((mw_get_field(_("Address: "), buf, MUTT_COMP_NO_FLAGS, HC_OTHER, NULL, NULL) != 0) ||
440 buf_is_empty(buf))
441 {
442 alias_free(&alias);
443 goto done;
444 }
445
446 mutt_addrlist_parse(&alias->addr, buf_string(buf));
447 if (TAILQ_EMPTY(&alias->addr))
448 mutt_beep(false);
449 if (mutt_addrlist_to_intl(&alias->addr, &err))
450 {
451 mutt_error(_("Bad IDN: '%s'"), err);
452 FREE(&err);
453 continue;
454 }
455 } while (TAILQ_EMPTY(&alias->addr));
456
457 if (addr && addr->personal && !mutt_is_mail_list(addr))
458 buf_copy(buf, addr->personal);
459 else
460 buf_reset(buf);
461
462 if (mw_get_field(_("Personal name: "), buf, MUTT_COMP_NO_FLAGS, HC_OTHER, NULL, NULL) != 0)
463 {
464 alias_free(&alias);
465 goto done;
466 }
467 buf_copy(TAILQ_FIRST(&alias->addr)->personal, buf);
468
469 buf_reset(buf);
470 if (mw_get_field(_("Comment: "), buf, MUTT_COMP_NO_FLAGS, HC_OTHER, NULL, NULL) == 0)
471 {
472 mutt_str_replace(&alias->comment, buf_string(buf));
473 }
474
475 buf_reset(buf);
476 mutt_addrlist_write(&alias->addr, buf, true);
477 prompt = buf_pool_get();
478 if (alias->comment)
479 {
480 buf_printf(prompt, "[%s = %s # %s] %s", alias->name, buf_string(buf),
481 alias->comment, _("Accept?"));
482 }
483 else
484 {
485 buf_printf(prompt, "[%s = %s] %s", alias->name, buf_string(buf), _("Accept?"));
486 }
487 if (query_yesorno(buf_string(prompt), MUTT_YES) != MUTT_YES)
488 {
489 alias_free(&alias);
490 goto done;
491 }
492
493 alias_reverse_add(alias);
494 TAILQ_INSERT_TAIL(&Aliases, alias, entries);
495
496 const char *const c_alias_file = cs_subset_path(sub, "alias_file");
497 buf_strcpy(buf, c_alias_file);
498
499 struct FileCompletionData cdata = { false, NULL, NULL, NULL };
500 if (mw_get_field(_("Save to file: "), buf, MUTT_COMP_CLEAR, HC_FILE,
501 &CompleteMailboxOps, &cdata) != 0)
502 {
503 goto done;
504 }
505 mutt_expand_path(buf->data, buf->dsize);
506 fp_alias = fopen(buf_string(buf), "a+");
507 if (!fp_alias)
508 {
509 mutt_perror("%s", buf_string(buf));
510 goto done;
511 }
512
513 /* terminate existing file with \n if necessary */
514 if (!mutt_file_seek(fp_alias, 0, SEEK_END))
515 {
516 goto done;
517 }
518 if (ftell(fp_alias) > 0)
519 {
520 if (!mutt_file_seek(fp_alias, -1, SEEK_CUR))
521 {
522 goto done;
523 }
524 if (fread(buf->data, 1, 1, fp_alias) != 1)
525 {
526 mutt_perror(_("Error reading alias file"));
527 goto done;
528 }
529 if (!mutt_file_seek(fp_alias, 0, SEEK_END))
530 {
531 goto done;
532 }
533 if (buf->data[0] != '\n')
534 fputc('\n', fp_alias);
535 }
536
537 if (check_alias_name(alias->name, NULL, 0))
538 mutt_file_quote_filename(alias->name, buf->data, buf->dsize);
539 else
540 buf_strcpy(buf, alias->name);
541
542 recode_buf(buf);
543 fprintf(fp_alias, "alias %s ", buf_string(buf));
544 buf_reset(buf);
545
546 mutt_addrlist_write(&alias->addr, buf, false);
547 recode_buf(buf);
548 write_safe_address(fp_alias, buf_string(buf));
549 if (alias->comment)
550 fprintf(fp_alias, " # %s", alias->comment);
551 fputc('\n', fp_alias);
552 if (mutt_file_fsync_close(&fp_alias) != 0)
553 mutt_perror(_("Trouble adding alias"));
554 else
555 mutt_message(_("Alias added"));
556
557done:
558 mutt_file_fclose(&fp_alias);
559 buf_pool_release(&buf);
560 buf_pool_release(&fixed);
561 buf_pool_release(&prompt);
562 buf_pool_release(&tmp);
563}
564
570bool mutt_addr_is_user(const struct Address *addr)
571{
572 if (!addr)
573 {
574 mutt_debug(LL_DEBUG5, "no, NULL address\n");
575 return false;
576 }
577 if (!addr->mailbox)
578 {
579 mutt_debug(LL_DEBUG5, "no, no mailbox\n");
580 return false;
581 }
582
584 {
585 mutt_debug(LL_DEBUG5, "#1 yes, %s = %s\n", buf_string(addr->mailbox), Username);
586 return true;
587 }
589 {
590 mutt_debug(LL_DEBUG5, "#2 yes, %s = %s @ %s\n", buf_string(addr->mailbox),
592 return true;
593 }
594 const char *fqdn = mutt_fqdn(false, NeoMutt->sub);
595 if (string_is_address(buf_string(addr->mailbox), Username, fqdn))
596 {
597 mutt_debug(LL_DEBUG5, "#3 yes, %s = %s @ %s\n", buf_string(addr->mailbox),
598 Username, NONULL(fqdn));
599 return true;
600 }
601 fqdn = mutt_fqdn(true, NeoMutt->sub);
602 if (string_is_address(buf_string(addr->mailbox), Username, fqdn))
603 {
604 mutt_debug(LL_DEBUG5, "#4 yes, %s = %s @ %s\n", buf_string(addr->mailbox),
605 Username, NONULL(fqdn));
606 return true;
607 }
608
609 const struct Address *c_from = cs_subset_address(NeoMutt->sub, "from");
610 if (c_from && mutt_istr_equal(buf_string(c_from->mailbox), buf_string(addr->mailbox)))
611 {
612 mutt_debug(LL_DEBUG5, "#5 yes, %s = %s\n", buf_string(addr->mailbox),
613 buf_string(c_from->mailbox));
614 return true;
615 }
616
618 return true;
619
620 mutt_debug(LL_DEBUG5, "no, all failed\n");
621 return false;
622}
623
630struct Alias *alias_new(void)
631{
632 struct Alias *a = mutt_mem_calloc(1, sizeof(struct Alias));
633 TAILQ_INIT(&a->addr);
634 return a;
635}
636
641void alias_free(struct Alias **ptr)
642{
643 if (!ptr || !*ptr)
644 return;
645
646 struct Alias *alias = *ptr;
647
648 mutt_debug(LL_NOTIFY, "NT_ALIAS_DELETE: %s\n", alias->name);
649 struct EventAlias ev_a = { alias };
651
652 FREE(&alias->name);
653 FREE(&alias->comment);
655 FREE(ptr);
656}
657
662void aliaslist_free(struct AliasList *al)
663{
664 if (!al)
665 return;
666
667 struct Alias *np = NULL, *tmp = NULL;
668 TAILQ_FOREACH_SAFE(np, al, entries, tmp)
669 {
670 TAILQ_REMOVE(al, np, entries);
671 alias_free(&np);
672 }
673 TAILQ_INIT(al);
674}
675
679void alias_init(void)
680{
682}
683
688{
689 struct Alias *np = NULL;
690 TAILQ_FOREACH(np, &Aliases, entries)
691 {
693 }
696}
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:762
void mutt_addrlist_qualify(struct AddressList *al, const char *host)
Expand local names in an Address list using a hostname.
Definition: address.c:677
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1461
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition: address.c:460
int mutt_addrlist_to_local(struct AddressList *al)
Convert an Address list from Punycode.
Definition: address.c:1379
size_t mutt_addrlist_write(const struct AddressList *al, struct Buffer *buf, bool display)
Write an Address to a buffer.
Definition: address.c:1207
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:478
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1294
void mutt_addrlist_dedupe(struct AddressList *al)
Remove duplicate addresses.
Definition: address.c:1398
Email Address Handling.
void alias_cleanup(void)
Clean up the Alias globals.
Definition: alias.c:687
void alias_free(struct Alias **ptr)
Free an Alias.
Definition: alias.c:641
struct AliasList Aliases
List of all the user's email aliases.
Definition: alias.c:60
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:261
static int check_alias_name(const char *s, char *dest, size_t destlen)
Sanity-check an alias name.
Definition: alias.c:215
struct AddressList * alias_lookup(const char *name)
Find an Alias.
Definition: alias.c:280
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:298
static void recode_buf(struct Buffer *buf)
Convert some text between two character sets.
Definition: alias.c:190
void alias_create(struct AddressList *al, const struct ConfigSubset *sub)
Create a new Alias from an Address.
Definition: alias.c:370
bool mutt_addr_is_user(const struct Address *addr)
Does the address belong to the user.
Definition: alias.c:570
void alias_init(void)
Set up the Alias globals.
Definition: alias.c:679
struct Alias * alias_new(void)
Create a new Alias.
Definition: alias.c:630
void mutt_expand_aliases_env(struct Envelope *env)
Expand aliases in all the fields of an Envelope.
Definition: alias.c:312
struct AddressList * mutt_get_address(struct Envelope *env, const char **prefix)
Get an Address from an Envelope.
Definition: alias.c:330
void aliaslist_free(struct AliasList *al)
Free a List of Aliases.
Definition: alias.c:662
static void write_safe_address(FILE *fp, const char *s)
Defang malicious email addresses.
Definition: alias.c:86
static void expand_aliases_r(struct AddressList *al, struct ListHead *expn)
Expand aliases, recursively.
Definition: alias.c:104
Representation of a single alias to an email address.
@ NT_ALIAS_DELETE
Alias is about to be deleted.
Definition: alias.h:55
bool mutt_alternates_match(const char *addr)
Compare an Address to the Un/Alternates lists.
Definition: alternates.c:155
Alternate address handling.
const struct CompleteOps CompleteMailboxOps
Auto-Completion of Files / Mailboxes.
Definition: complete.c:160
Select a Mailbox from a list.
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:173
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:88
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:303
struct Buffer * buf_new(const char *str)
Allocate a new Buffer.
Definition: buffer.c:316
const char * buf_find_char(const struct Buffer *buf, const char c)
Return a pointer to a char found in the buffer.
Definition: buffer.c:623
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:407
size_t buf_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition: buffer.c:572
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition: buffer.c:542
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:93
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:292
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:169
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:48
Convenience wrapper for the config headers.
const char * cc_charset(void)
Get the cached value of $charset.
Definition: config_cache.c:115
const struct Address * cs_subset_address(const struct ConfigSubset *sub, const char *name)
Get an Address config item by name.
Definition: config_type.c:262
Convenience wrapper for the core headers.
void mutt_beep(bool force)
Irritate the user.
Definition: curs_lib.c:69
Enter a string.
Structs that make up an email.
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
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:891
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition: file.c:733
int mutt_file_fsync_close(FILE **fp)
Flush the data, before closing a file (and NULL the pointer)
Definition: file.c:168
char * ShortHostname
Short version of the hostname.
Definition: globals.c:40
char * Username
User's login name.
Definition: globals.c:42
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:44
int mw_get_field(const char *prompt, struct Buffer *buf, CompletionFlags complete, enum HistoryClass hclass, const struct CompleteOps *comp_api, void *cdata)
Ask the user for a string -.
Definition: window.c:275
#define mutt_error(...)
Definition: logging2.h:92
#define mutt_message(...)
Definition: logging2.h:91
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
#define mutt_perror(...)
Definition: logging2.h:93
Convenience wrapper for the gui headers.
Read/write command history from/to a file.
@ HC_FILE
Files.
Definition: lib.h:52
@ HC_OTHER
Miscellaneous strings.
Definition: lib.h:54
struct ListNode * mutt_list_insert_head(struct ListHead *h, char *s)
Insert a string at the beginning of a List.
Definition: list.c:45
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
@ LL_DEBUG5
Log at debug level 5.
Definition: logging2.h:47
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
@ LL_NOTIFY
Log of notifications.
Definition: logging2.h:48
Handle mailing lists.
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define FREE(x)
Definition: memory.h:45
int mutt_ch_convert_string(char **ps, const char *from, const char *to, uint8_t flags)
Convert a string between encodings.
Definition: charset.c:826
#define ICONV_BUF_TOO_SMALL
Error value for iconv() - Buffer too small.
Definition: charset.h:105
#define MUTT_ICONV_NO_FLAGS
No flags are set.
Definition: charset.h:71
#define ICONV_ILLEGAL_SEQ
Error value for iconv() - Illegal sequence.
Definition: charset.h:103
Convenience wrapper for the library headers.
#define _(a)
Definition: message.h:28
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:173
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:810
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:798
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:327
Many unsorted constants and some structs.
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:55
#define MUTT_COMP_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:56
char * mutt_gecos_name(char *dest, size_t destlen, struct passwd *pw)
Lookup a user's real name in /etc/passwd.
Definition: muttlib.c:374
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:126
Some miscellaneous functions.
@ NT_ALIAS
Alias has changed, NotifyAlias, EventAlias.
Definition: notify_type.h:37
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
@ MUTT_ABORT
User aborted the question (with Ctrl-G)
Definition: quad.h:37
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition: quad.h:39
Ask the user a question.
enum QuadOption query_yesorno(const char *prompt, enum QuadOption def)
Ask the user a Yes/No question.
Definition: question.c:330
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:735
#define STAILQ_INIT(head)
Definition: queue.h:372
#define TAILQ_INIT(head)
Definition: queue.h:765
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:809
#define TAILQ_PREV(elm, headname, field)
Definition: queue.h:834
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define TAILQ_FIRST(head)
Definition: queue.h:723
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:841
#define TAILQ_NEXT(elm, field)
Definition: queue.h:832
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:637
#define TAILQ_EMPTY(head)
Definition: queue.h:721
#define TAILQ_INSERT_BEFORE(listelm, elm, field)
Definition: queue.h:786
void alias_reverse_add(struct Alias *alias)
Add an email address lookup for an Alias.
Definition: reverse.c:61
void alias_reverse_shutdown(void)
Clear up the Reverse Alias Hash Table.
Definition: reverse.c:52
void alias_reverse_delete(struct Alias *alias)
Remove an email address lookup for an Alias.
Definition: reverse.c:83
void alias_reverse_init(void)
Set up the Reverse Alias Hash Table.
Definition: reverse.c:42
Manage alias reverse lookups.
Convenience wrapper for the send headers.
const char * mutt_fqdn(bool may_hide_host, const struct ConfigSubset *sub)
Get the Fully-Qualified Domain Name.
Definition: sendlib.c:705
Key value store.
#define NONULL(x)
Definition: string2.h:37
An email address.
Definition: address.h:36
struct Buffer * personal
Real name of address.
Definition: address.h:37
bool group
Group mailbox?
Definition: address.h:39
struct Buffer * mailbox
Mailbox and host address.
Definition: address.h:38
A shortcut for an email address or addresses.
Definition: alias.h:34
char * comment
Free-form comment string.
Definition: alias.h:37
char * name
Short name.
Definition: alias.h:35
struct AddressList addr
List of Addresses the Alias expands to.
Definition: alias.h:36
String manipulation buffer.
Definition: buffer.h:34
size_t dsize
Length of data.
Definition: buffer.h:37
char * data
Pointer to data.
Definition: buffer.h:35
A set of inherited config items.
Definition: subset.h:47
The header of an Email.
Definition: envelope.h:57
struct AddressList to
Email's 'To' list.
Definition: envelope.h:60
struct AddressList reply_to
Email's 'reply-to'.
Definition: envelope.h:64
struct AddressList mail_followup_to
Email's 'mail-followup-to'.
Definition: envelope.h:65
struct AddressList cc
Email's 'Cc' list.
Definition: envelope.h:61
struct AddressList bcc
Email's 'Bcc' list.
Definition: envelope.h:62
struct AddressList from
Email's 'From' list.
Definition: envelope.h:59
An alias-change event.
Definition: alias.h:64
struct Alias * alias
Alias that changed.
Definition: alias.h:65
Input for the file completion function.
Definition: curs_lib.h:49
A List node for strings.
Definition: list.h:35
char * data
String.
Definition: list.h:36
Container for Accounts, Notifications.
Definition: neomutt.h:41
struct Notify * notify
Notifications handler.
Definition: neomutt.h:42
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:45