NeoMutt  2025-01-09-81-g753ae0
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
commands.c
Go to the documentation of this file.
1
37#include "config.h"
38#include <errno.h>
39#include <limits.h>
40#include <stdbool.h>
41#include <stdio.h>
42#include <string.h>
43#include <sys/types.h>
44#include <unistd.h>
45#include "mutt/lib.h"
46#include "address/lib.h"
47#include "config/lib.h"
48#include "email/lib.h"
49#include "core/lib.h"
50#include "alias/lib.h"
51#include "gui/lib.h"
52#include "mutt.h"
53#include "commands.h"
54#include "attach/lib.h"
55#include "color/lib.h"
56#include "imap/lib.h"
57#include "key/lib.h"
58#include "menu/lib.h"
59#include "pager/lib.h"
60#include "parse/lib.h"
61#include "store/lib.h"
62#include "alternates.h"
63#include "globals.h"
64#include "muttlib.h"
65#include "mx.h"
66#include "score.h"
67#include "version.h"
68#ifdef USE_INOTIFY
69#include "monitor.h"
70#endif
71#ifdef ENABLE_NLS
72#include <libintl.h>
73#endif
74
78
79#define MAX_ERRS 128
80
85{
86 TB_UNSET = -1,
89};
90
95{
99};
100
107static bool is_function(const char *name)
108{
109 for (size_t i = 0; MenuNames[i].name; i++)
110 {
111 const struct MenuFuncOp *fns = km_get_table(MenuNames[i].value);
112 if (!fns)
113 continue;
114
115 for (int j = 0; fns[j].name; j++)
116 if (mutt_str_equal(name, fns[j].name))
117 return true;
118 }
119 return false;
120}
121
128static bool is_color_object(const char *name)
129{
131
132 return (cid > 0);
133}
134
144int parse_grouplist(struct GroupList *gl, struct Buffer *buf, struct Buffer *s,
145 struct Buffer *err)
146{
147 while (mutt_istr_equal(buf->data, "-group"))
148 {
149 if (!MoreArgs(s))
150 {
151 buf_strcpy(err, _("-group: no group name"));
152 return -1;
153 }
154
156
158
159 if (!MoreArgs(s))
160 {
161 buf_strcpy(err, _("out of arguments"));
162 return -1;
163 }
164
166 }
167
168 return 0;
169}
170
178enum CommandResult parse_rc_line_cwd(const char *line, char *cwd, struct Buffer *err)
179{
181
182 enum CommandResult ret = parse_rc_line(line, err);
183
184 struct ListNode *np = STAILQ_FIRST(&MuttrcStack);
186 FREE(&np->data);
187 FREE(&np);
188
189 return ret;
190}
191
199{
200 struct ListNode *np = STAILQ_FIRST(&MuttrcStack);
201 if (np && np->data)
202 return mutt_str_dup(np->data);
203
204 // stack is empty, return our own dummy file relative to cwd
205 struct Buffer *cwd = buf_pool_get();
206 mutt_path_getcwd(cwd);
207 buf_addstr(cwd, "/dummy.rc");
208 char *ret = buf_strdup(cwd);
209 buf_pool_release(&cwd);
210 return ret;
211}
212
219int source_rc(const char *rcfile_path, struct Buffer *err)
220{
221 int lineno = 0, rc = 0, warnings = 0;
222 enum CommandResult line_rc;
223 struct Buffer *token = NULL, *linebuf = NULL;
224 char *line = NULL;
225 char *currentline = NULL;
226 char rcfile[PATH_MAX + 1] = { 0 };
227 size_t linelen = 0;
228 pid_t pid;
229
230 mutt_str_copy(rcfile, rcfile_path, sizeof(rcfile));
231
232 size_t rcfilelen = mutt_str_len(rcfile);
233 if (rcfilelen == 0)
234 return -1;
235
236 bool ispipe = rcfile[rcfilelen - 1] == '|';
237
238 if (!ispipe)
239 {
240 struct ListNode *np = STAILQ_FIRST(&MuttrcStack);
241 if (!mutt_path_to_absolute(rcfile, np ? NONULL(np->data) : ""))
242 {
243 mutt_error(_("Error: Can't build path of '%s'"), rcfile_path);
244 return -1;
245 }
246
247 STAILQ_FOREACH(np, &MuttrcStack, entries)
248 {
249 if (mutt_str_equal(np->data, rcfile))
250 {
251 break;
252 }
253 }
254 if (np)
255 {
256 mutt_error(_("Error: Cyclic sourcing of configuration file '%s'"), rcfile);
257 return -1;
258 }
259
261 }
262
263 mutt_debug(LL_DEBUG2, "Reading configuration file '%s'\n", rcfile);
264
265 FILE *fp = mutt_open_read(rcfile, &pid);
266 if (!fp)
267 {
268 buf_printf(err, "%s: %s", rcfile, strerror(errno));
269 return -1;
270 }
271
272 token = buf_pool_get();
273 linebuf = buf_pool_get();
274
275 const char *const c_config_charset = cs_subset_string(NeoMutt->sub, "config_charset");
276 const char *const c_charset = cc_charset();
277 while ((line = mutt_file_read_line(line, &linelen, fp, &lineno, MUTT_RL_CONT)) != NULL)
278 {
279 const bool conv = c_config_charset && c_charset;
280 if (conv)
281 {
282 currentline = mutt_str_dup(line);
283 if (!currentline)
284 continue;
285 mutt_ch_convert_string(&currentline, c_config_charset, c_charset, MUTT_ICONV_NO_FLAGS);
286 }
287 else
288 {
289 currentline = line;
290 }
291
292 buf_strcpy(linebuf, currentline);
293
294 buf_reset(err);
295 line_rc = parse_rc_buffer(linebuf, token, err);
296 if (line_rc == MUTT_CMD_ERROR)
297 {
298 mutt_error("%s:%d: %s", rcfile, lineno, buf_string(err));
299 if (--rc < -MAX_ERRS)
300 {
301 if (conv)
302 FREE(&currentline);
303 break;
304 }
305 }
306 else if (line_rc == MUTT_CMD_WARNING)
307 {
308 /* Warning */
309 mutt_warning("%s:%d: %s", rcfile, lineno, buf_string(err));
310 warnings++;
311 }
312 else if (line_rc == MUTT_CMD_FINISH)
313 {
314 if (conv)
315 FREE(&currentline);
316 break; /* Found "finish" command */
317 }
318 else
319 {
320 if (rc < 0)
321 rc = -1;
322 }
323 if (conv)
324 FREE(&currentline);
325 }
326
327 FREE(&line);
328 mutt_file_fclose(&fp);
329 if (pid != -1)
330 filter_wait(pid);
331
332 if (rc)
333 {
334 /* the neomuttrc source keyword */
335 buf_reset(err);
336 buf_printf(err, (rc >= -MAX_ERRS) ? _("source: errors in %s") : _("source: reading aborted due to too many errors in %s"),
337 rcfile);
338 rc = -1;
339 }
340 else
341 {
342 /* Don't alias errors with warnings */
343 if (warnings > 0)
344 {
345 buf_printf(err, ngettext("source: %d warning in %s", "source: %d warnings in %s", warnings),
346 warnings, rcfile);
347 rc = -2;
348 }
349 }
350
351 if (!ispipe && !STAILQ_EMPTY(&MuttrcStack))
352 {
353 struct ListNode *np = STAILQ_FIRST(&MuttrcStack);
355 FREE(&np->data);
356 FREE(&np);
357 }
358
359 buf_pool_release(&token);
360 buf_pool_release(&linebuf);
361 return rc;
362}
363
367static enum CommandResult parse_cd(struct Buffer *buf, struct Buffer *s,
368 intptr_t data, struct Buffer *err)
369{
371 buf_expand_path(buf);
372 if (buf_is_empty(buf))
373 {
374 if (HomeDir)
375 {
376 buf_strcpy(buf, HomeDir);
377 }
378 else
379 {
380 buf_printf(err, _("%s: too few arguments"), "cd");
381 return MUTT_CMD_ERROR;
382 }
383 }
384
385 if (chdir(buf_string(buf)) != 0)
386 {
387 buf_printf(err, "cd: %s", strerror(errno));
388 return MUTT_CMD_ERROR;
389 }
390
391 return MUTT_CMD_SUCCESS;
392}
393
397static enum CommandResult parse_echo(struct Buffer *buf, struct Buffer *s,
398 intptr_t data, struct Buffer *err)
399{
400 if (!MoreArgs(s))
401 {
402 buf_printf(err, _("%s: too few arguments"), "echo");
403 return MUTT_CMD_WARNING;
404 }
406 OptForceRefresh = true;
407 mutt_message("%s", buf->data);
408 OptForceRefresh = false;
409 mutt_sleep(0);
410
411 return MUTT_CMD_SUCCESS;
412}
413
421static enum CommandResult parse_finish(struct Buffer *buf, struct Buffer *s,
422 intptr_t data, struct Buffer *err)
423{
424 if (MoreArgs(s))
425 {
426 buf_printf(err, _("%s: too many arguments"), "finish");
427 return MUTT_CMD_WARNING;
428 }
429
430 return MUTT_CMD_FINISH;
431}
432
436static enum CommandResult parse_group(struct Buffer *buf, struct Buffer *s,
437 intptr_t data, struct Buffer *err)
438{
439 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
440 enum GroupState gstate = GS_NONE;
441
442 do
443 {
445 if (parse_grouplist(&gl, buf, s, err) == -1)
446 goto bail;
447
448 if ((data == MUTT_UNGROUP) && mutt_istr_equal(buf->data, "*"))
449 {
451 goto out;
452 }
453
454 if (mutt_istr_equal(buf->data, "-rx"))
455 {
456 gstate = GS_RX;
457 }
458 else if (mutt_istr_equal(buf->data, "-addr"))
459 {
460 gstate = GS_ADDR;
461 }
462 else
463 {
464 switch (gstate)
465 {
466 case GS_NONE:
467 buf_printf(err, _("%sgroup: missing -rx or -addr"),
468 (data == MUTT_UNGROUP) ? "un" : "");
469 goto warn;
470
471 case GS_RX:
472 if ((data == MUTT_GROUP) &&
473 (mutt_grouplist_add_regex(&gl, buf->data, REG_ICASE, err) != 0))
474 {
475 goto bail;
476 }
477 else if ((data == MUTT_UNGROUP) &&
478 (mutt_grouplist_remove_regex(&gl, buf->data) < 0))
479 {
480 goto bail;
481 }
482 break;
483
484 case GS_ADDR:
485 {
486 char *estr = NULL;
487 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
488 mutt_addrlist_parse2(&al, buf->data);
489 if (TAILQ_EMPTY(&al))
490 goto bail;
491 if (mutt_addrlist_to_intl(&al, &estr))
492 {
493 buf_printf(err, _("%sgroup: warning: bad IDN '%s'"),
494 (data == 1) ? "un" : "", estr);
496 FREE(&estr);
497 goto bail;
498 }
499 if (data == MUTT_GROUP)
501 else if (data == MUTT_UNGROUP)
504 break;
505 }
506 }
507 }
508 } while (MoreArgs(s));
509
510out:
512 return MUTT_CMD_SUCCESS;
513
514bail:
516 return MUTT_CMD_ERROR;
517
518warn:
520 return MUTT_CMD_WARNING;
521}
522
536static enum CommandResult parse_ifdef(struct Buffer *buf, struct Buffer *s,
537 intptr_t data, struct Buffer *err)
538{
540
541 if (buf_is_empty(buf))
542 {
543 buf_printf(err, _("%s: too few arguments"), (data ? "ifndef" : "ifdef"));
544 return MUTT_CMD_WARNING;
545 }
546
547 // is the item defined as:
548 bool res = cs_subset_lookup(NeoMutt->sub, buf->data) // a variable?
549 || feature_enabled(buf->data) // a compiled-in feature?
550 || is_function(buf->data) // a function?
551 || command_get(buf->data) // a command?
552 || is_color_object(buf->data) // a color?
553#ifdef USE_HCACHE
554 || store_is_valid_backend(buf->data) // a store? (database)
555#endif
556 || mutt_str_getenv(buf->data); // an environment variable?
557
558 if (!MoreArgs(s))
559 {
560 buf_printf(err, _("%s: too few arguments"), (data ? "ifndef" : "ifdef"));
561 return MUTT_CMD_WARNING;
562 }
564
565 /* ifdef KNOWN_SYMBOL or ifndef UNKNOWN_SYMBOL */
566 if ((res && (data == 0)) || (!res && (data == 1)))
567 {
568 enum CommandResult rc = parse_rc_line(buf->data, err);
569 if (rc == MUTT_CMD_ERROR)
570 {
571 mutt_error(_("Error: %s"), buf_string(err));
572 return MUTT_CMD_ERROR;
573 }
574 return rc;
575 }
576 return MUTT_CMD_SUCCESS;
577}
578
582static enum CommandResult parse_ignore(struct Buffer *buf, struct Buffer *s,
583 intptr_t data, struct Buffer *err)
584{
585 do
586 {
589 add_to_stailq(&Ignore, buf->data);
590 } while (MoreArgs(s));
591
592 return MUTT_CMD_SUCCESS;
593}
594
598static enum CommandResult parse_lists(struct Buffer *buf, struct Buffer *s,
599 intptr_t data, struct Buffer *err)
600{
601 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
602
603 do
604 {
606
607 if (parse_grouplist(&gl, buf, s, err) == -1)
608 goto bail;
609
611
612 if (mutt_regexlist_add(&MailLists, buf->data, REG_ICASE, err) != 0)
613 goto bail;
614
615 if (mutt_grouplist_add_regex(&gl, buf->data, REG_ICASE, err) != 0)
616 goto bail;
617 } while (MoreArgs(s));
618
620 return MUTT_CMD_SUCCESS;
621
622bail:
624 return MUTT_CMD_ERROR;
625}
626
637static enum CommandResult mailbox_add(const char *folder, const char *mailbox,
638 const char *label, enum TriBool poll,
639 enum TriBool notify, struct Buffer *err)
640{
641 mutt_debug(LL_DEBUG1, "Adding mailbox: '%s' label '%s', poll %s, notify %s\n",
642 mailbox, label ? label : "[NONE]",
643 (poll == TB_UNSET) ? "[UNSPECIFIED]" :
644 (poll == TB_TRUE) ? "true" :
645 "false",
646 (notify == TB_UNSET) ? "[UNSPECIFIED]" :
647 (notify == TB_TRUE) ? "true" :
648 "false");
649 struct Mailbox *m = mailbox_new();
650
651 buf_strcpy(&m->pathbuf, mailbox);
652 /* int rc = */ mx_path_canon2(m, folder);
653
654 if (m->type <= MUTT_UNKNOWN)
655 {
656 buf_printf(err, "Unknown Mailbox: %s", m->realpath);
657 mailbox_free(&m);
658 return MUTT_CMD_ERROR;
659 }
660
661 bool new_account = false;
662 struct Account *a = mx_ac_find(m);
663 if (!a)
664 {
665 a = account_new(NULL, NeoMutt->sub);
666 a->type = m->type;
667 new_account = true;
668 }
669
670 if (!new_account)
671 {
672 struct Mailbox *m_old = mx_mbox_find(a, m->realpath);
673 if (m_old)
674 {
675 if (!m_old->visible)
676 {
677 m_old->visible = true;
678 m_old->gen = mailbox_gen();
679 }
680
681 if (label)
682 mutt_str_replace(&m_old->name, label);
683
684 if (notify != TB_UNSET)
685 m_old->notify_user = notify;
686
687 if (poll != TB_UNSET)
688 m_old->poll_new_mail = poll;
689
690 struct EventMailbox ev_m = { m_old };
692
693 mailbox_free(&m);
694 return MUTT_CMD_SUCCESS;
695 }
696 }
697
698 if (label)
699 m->name = mutt_str_dup(label);
700
701 if (notify != TB_UNSET)
702 m->notify_user = notify;
703
704 if (poll != TB_UNSET)
705 m->poll_new_mail = poll;
706
707 if (!mx_ac_add(a, m))
708 {
709 mailbox_free(&m);
710 if (new_account)
711 {
712 cs_subset_free(&a->sub);
713 FREE(&a->name);
714 notify_free(&a->notify);
715 FREE(&a);
716 }
717 return MUTT_CMD_SUCCESS;
718 }
719
720 if (new_account)
721 {
723 }
724
725 // this is finally a visible mailbox in the sidebar and mailboxes list
726 m->visible = true;
727
728#ifdef USE_INOTIFY
730#endif
731
732 return MUTT_CMD_SUCCESS;
733}
734
741bool mailbox_add_simple(const char *mailbox, struct Buffer *err)
742{
743 enum CommandResult rc = mailbox_add("", mailbox, NULL, TB_UNSET, TB_UNSET, err);
744
745 return (rc == MUTT_CMD_SUCCESS);
746}
747
753enum CommandResult parse_mailboxes(struct Buffer *buf, struct Buffer *s,
754 intptr_t data, struct Buffer *err)
755{
757
758 struct Buffer *label = buf_pool_get();
759 struct Buffer *mailbox = buf_pool_get();
760
761 const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
762 while (MoreArgs(s))
763 {
764 bool label_set = false;
765 enum TriBool notify = TB_UNSET;
766 enum TriBool poll = TB_UNSET;
767
768 do
769 {
770 // Start by handling the options
772
773 if (mutt_str_equal(buf_string(buf), "-label"))
774 {
775 if (!MoreArgs(s))
776 {
777 buf_printf(err, _("%s: too few arguments"), "mailboxes -label");
778 goto done;
779 }
780
782 label_set = true;
783 }
784 else if (mutt_str_equal(buf_string(buf), "-nolabel"))
785 {
786 buf_reset(label);
787 label_set = true;
788 }
789 else if (mutt_str_equal(buf_string(buf), "-notify"))
790 {
791 notify = TB_TRUE;
792 }
793 else if (mutt_str_equal(buf_string(buf), "-nonotify"))
794 {
795 notify = TB_FALSE;
796 }
797 else if (mutt_str_equal(buf_string(buf), "-poll"))
798 {
799 poll = TB_TRUE;
800 }
801 else if (mutt_str_equal(buf_string(buf), "-nopoll"))
802 {
803 poll = TB_FALSE;
804 }
805 else if ((data & MUTT_NAMED) && !label_set)
806 {
807 if (!MoreArgs(s))
808 {
809 buf_printf(err, _("%s: too few arguments"), "named-mailboxes");
810 goto done;
811 }
812
813 buf_copy(label, buf);
814 label_set = true;
815 }
816 else
817 {
818 buf_copy(mailbox, buf);
819 break;
820 }
821 } while (MoreArgs(s));
822
823 if (buf_is_empty(mailbox))
824 {
825 buf_printf(err, _("%s: too few arguments"), "mailboxes");
826 goto done;
827 }
828
829 rc = mailbox_add(c_folder, buf_string(mailbox),
830 label_set ? buf_string(label) : NULL, poll, notify, err);
831 if (rc != MUTT_CMD_SUCCESS)
832 goto done;
833
834 buf_reset(label);
835 buf_reset(mailbox);
836 }
837
838 rc = MUTT_CMD_SUCCESS;
839
840done:
841 buf_pool_release(&label);
842 buf_pool_release(&mailbox);
843 return rc;
844}
845
849enum CommandResult parse_my_hdr(struct Buffer *buf, struct Buffer *s,
850 intptr_t data, struct Buffer *err)
851{
853 char *p = strpbrk(buf->data, ": \t");
854 if (!p || (*p != ':'))
855 {
856 buf_strcpy(err, _("invalid header field"));
857 return MUTT_CMD_WARNING;
858 }
859
860 struct EventHeader ev_h = { buf->data };
861 struct ListNode *n = header_find(&UserHeader, buf->data);
862
863 if (n)
864 {
865 header_update(n, buf->data);
866 mutt_debug(LL_NOTIFY, "NT_HEADER_CHANGE: %s\n", buf->data);
868 }
869 else
870 {
871 header_add(&UserHeader, buf->data);
872 mutt_debug(LL_NOTIFY, "NT_HEADER_ADD: %s\n", buf->data);
874 }
875
876 return MUTT_CMD_SUCCESS;
877}
878
888enum CommandResult set_dump(enum GetElemListFlags flags, struct Buffer *err)
889{
890 struct Buffer *tempfile = buf_pool_get();
891 buf_mktemp(tempfile);
892
893 FILE *fp_out = mutt_file_fopen(buf_string(tempfile), "w");
894 if (!fp_out)
895 {
896 // L10N: '%s' is the file name of the temporary file
897 buf_printf(err, _("Could not create temporary file %s"), buf_string(tempfile));
898 buf_pool_release(&tempfile);
899 return MUTT_CMD_ERROR;
900 }
901
902 struct ConfigSet *cs = NeoMutt->sub->cs;
903 struct HashElemArray hea = get_elem_list(cs, flags);
904 dump_config(cs, &hea, CS_DUMP_NO_FLAGS, fp_out);
905 ARRAY_FREE(&hea);
906
907 mutt_file_fclose(&fp_out);
908
909 struct PagerData pdata = { 0 };
910 struct PagerView pview = { &pdata };
911
912 pdata.fname = buf_string(tempfile);
913
914 pview.banner = "set";
916 pview.mode = PAGER_MODE_OTHER;
917
918 mutt_do_pager(&pview, NULL);
919 buf_pool_release(&tempfile);
920
921 return MUTT_CMD_SUCCESS;
922}
923
927static int envlist_sort(const void *a, const void *b, void *sdata)
928{
929 return strcmp(*(const char **) a, *(const char **) b);
930}
931
935static enum CommandResult parse_setenv(struct Buffer *buf, struct Buffer *s,
936 intptr_t data, struct Buffer *err)
937{
938 char **envp = EnvList;
939
940 bool query = false;
941 bool prefix = false;
942 bool unset = (data == MUTT_SET_UNSET);
943
944 if (!MoreArgs(s))
945 {
946 if (!StartupComplete)
947 {
948 buf_printf(err, _("%s: too few arguments"), "setenv");
949 return MUTT_CMD_WARNING;
950 }
951
952 struct Buffer *tempfile = buf_pool_get();
953 buf_mktemp(tempfile);
954
955 FILE *fp_out = mutt_file_fopen(buf_string(tempfile), "w");
956 if (!fp_out)
957 {
958 // L10N: '%s' is the file name of the temporary file
959 buf_printf(err, _("Could not create temporary file %s"), buf_string(tempfile));
960 buf_pool_release(&tempfile);
961 return MUTT_CMD_ERROR;
962 }
963
964 int count = 0;
965 for (char **env = EnvList; *env; env++)
966 count++;
967
968 mutt_qsort_r(EnvList, count, sizeof(char *), envlist_sort, NULL);
969
970 for (char **env = EnvList; *env; env++)
971 fprintf(fp_out, "%s\n", *env);
972
973 mutt_file_fclose(&fp_out);
974
975 struct PagerData pdata = { 0 };
976 struct PagerView pview = { &pdata };
977
978 pdata.fname = buf_string(tempfile);
979
980 pview.banner = "setenv";
982 pview.mode = PAGER_MODE_OTHER;
983
984 mutt_do_pager(&pview, NULL);
985 buf_pool_release(&tempfile);
986
987 return MUTT_CMD_SUCCESS;
988 }
989
990 if (*s->dptr == '?')
991 {
992 query = true;
993 prefix = true;
994
995 if (unset)
996 {
997 buf_printf(err, _("Can't query option with the '%s' command"), "unsetenv");
998 return MUTT_CMD_WARNING;
999 }
1000
1001 s->dptr++;
1002 }
1003
1004 /* get variable name */
1006
1007 if (*s->dptr == '?')
1008 {
1009 if (unset)
1010 {
1011 buf_printf(err, _("Can't query option with the '%s' command"), "unsetenv");
1012 return MUTT_CMD_WARNING;
1013 }
1014
1015 if (prefix)
1016 {
1017 buf_printf(err, _("Can't use a prefix when querying a variable"));
1018 return MUTT_CMD_WARNING;
1019 }
1020
1021 query = true;
1022 s->dptr++;
1023 }
1024
1025 if (query)
1026 {
1027 bool found = false;
1028 while (envp && *envp)
1029 {
1030 /* This will display all matches for "^QUERY" */
1031 if (mutt_str_startswith(*envp, buf->data))
1032 {
1033 if (!found)
1034 {
1035 mutt_endwin();
1036 found = true;
1037 }
1038 puts(*envp);
1039 }
1040 envp++;
1041 }
1042
1043 if (found)
1044 {
1046 return MUTT_CMD_SUCCESS;
1047 }
1048
1049 buf_printf(err, _("%s is unset"), buf->data);
1050 return MUTT_CMD_WARNING;
1051 }
1052
1053 if (unset)
1054 {
1055 if (!envlist_unset(&EnvList, buf->data))
1056 {
1057 buf_printf(err, _("%s is unset"), buf->data);
1058 return MUTT_CMD_WARNING;
1059 }
1060 return MUTT_CMD_SUCCESS;
1061 }
1062
1063 /* set variable */
1064
1065 if (*s->dptr == '=')
1066 {
1067 s->dptr++;
1068 SKIPWS(s->dptr);
1069 }
1070
1071 if (!MoreArgs(s))
1072 {
1073 buf_printf(err, _("%s: too few arguments"), "setenv");
1074 return MUTT_CMD_WARNING;
1075 }
1076
1077 char *name = mutt_str_dup(buf->data);
1079 envlist_set(&EnvList, name, buf->data, true);
1080 FREE(&name);
1081
1082 return MUTT_CMD_SUCCESS;
1083}
1084
1088static enum CommandResult parse_source(struct Buffer *buf, struct Buffer *s,
1089 intptr_t data, struct Buffer *err)
1090{
1091 struct Buffer *path = buf_pool_get();
1092
1093 do
1094 {
1095 if (parse_extract_token(buf, s, TOKEN_BACKTICK_VARS) != 0)
1096 {
1097 buf_printf(err, _("source: error at %s"), s->dptr);
1098 buf_pool_release(&path);
1099 return MUTT_CMD_ERROR;
1100 }
1101 buf_copy(path, buf);
1102 buf_expand_path(path);
1103
1104 if (source_rc(buf_string(path), err) < 0)
1105 {
1106 buf_printf(err, _("source: file %s could not be sourced"), buf_string(path));
1107 buf_pool_release(&path);
1108 return MUTT_CMD_ERROR;
1109 }
1110
1111 } while (MoreArgs(s));
1112
1113 buf_pool_release(&path);
1114
1115 return MUTT_CMD_SUCCESS;
1116}
1117
1121static enum CommandResult parse_nospam(struct Buffer *buf, struct Buffer *s,
1122 intptr_t data, struct Buffer *err)
1123{
1124 if (!MoreArgs(s))
1125 {
1126 buf_printf(err, _("%s: too few arguments"), "nospam");
1127 return MUTT_CMD_ERROR;
1128 }
1129
1130 // Extract the first token, a regex or "*"
1132
1133 if (MoreArgs(s))
1134 {
1135 buf_printf(err, _("%s: too many arguments"), "finish");
1136 return MUTT_CMD_ERROR;
1137 }
1138
1139 // "*" is special - clear both spam and nospam lists
1140 if (mutt_str_equal(buf_string(buf), "*"))
1141 {
1144 return MUTT_CMD_SUCCESS;
1145 }
1146
1147 // If it's on the spam list, just remove it
1149 return MUTT_CMD_SUCCESS;
1150
1151 // Otherwise, add it to the nospam list
1152 if (mutt_regexlist_add(&NoSpamList, buf_string(buf), REG_ICASE, err) != 0)
1153 return MUTT_CMD_ERROR;
1154
1155 return MUTT_CMD_SUCCESS;
1156}
1157
1161static enum CommandResult parse_spam(struct Buffer *buf, struct Buffer *s,
1162 intptr_t data, struct Buffer *err)
1163{
1164 if (!MoreArgs(s))
1165 {
1166 buf_printf(err, _("%s: too few arguments"), "spam");
1167 return MUTT_CMD_ERROR;
1168 }
1169
1170 // Extract the first token, a regex
1172
1173 // If there's a second parameter, it's a template for the spam tag
1174 if (MoreArgs(s))
1175 {
1176 struct Buffer *templ = buf_pool_get();
1178
1179 // Add to the spam list
1180 int rc = mutt_replacelist_add(&SpamList, buf_string(buf), buf_string(templ), err);
1181 buf_pool_release(&templ);
1182 if (rc != 0)
1183 return MUTT_CMD_ERROR;
1184 }
1185 else
1186 {
1187 // If not, try to remove from the nospam list
1189 }
1190
1191 return MUTT_CMD_SUCCESS;
1192}
1193
1199static enum CommandResult parse_stailq(struct Buffer *buf, struct Buffer *s,
1200 intptr_t data, struct Buffer *err)
1201{
1202 do
1203 {
1205 add_to_stailq((struct ListHead *) data, buf->data);
1206 } while (MoreArgs(s));
1207
1208 return MUTT_CMD_SUCCESS;
1209}
1210
1214static enum CommandResult parse_subscribe(struct Buffer *buf, struct Buffer *s,
1215 intptr_t data, struct Buffer *err)
1216{
1217 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
1218
1219 do
1220 {
1222
1223 if (parse_grouplist(&gl, buf, s, err) == -1)
1224 goto bail;
1225
1228
1229 if (mutt_regexlist_add(&MailLists, buf->data, REG_ICASE, err) != 0)
1230 goto bail;
1231 if (mutt_regexlist_add(&SubscribedLists, buf->data, REG_ICASE, err) != 0)
1232 goto bail;
1233 if (mutt_grouplist_add_regex(&gl, buf->data, REG_ICASE, err) != 0)
1234 goto bail;
1235 } while (MoreArgs(s));
1236
1238 return MUTT_CMD_SUCCESS;
1239
1240bail:
1242 return MUTT_CMD_ERROR;
1243}
1244
1252enum CommandResult parse_subscribe_to(struct Buffer *buf, struct Buffer *s,
1253 intptr_t data, struct Buffer *err)
1254{
1255 if (!buf || !s || !err)
1256 return MUTT_CMD_ERROR;
1257
1258 buf_reset(err);
1259
1260 if (MoreArgs(s))
1261 {
1263
1264 if (MoreArgs(s))
1265 {
1266 buf_printf(err, _("%s: too many arguments"), "subscribe-to");
1267 return MUTT_CMD_WARNING;
1268 }
1269
1270 if (!buf_is_empty(buf))
1271 {
1272 /* Expand and subscribe */
1273 buf_expand_path(buf);
1274 if (imap_subscribe(buf_string(buf), true) == 0)
1275 {
1276 mutt_message(_("Subscribed to %s"), buf->data);
1277 return MUTT_CMD_SUCCESS;
1278 }
1279
1280 buf_printf(err, _("Could not subscribe to %s"), buf->data);
1281 return MUTT_CMD_ERROR;
1282 }
1283
1284 mutt_debug(LL_DEBUG1, "Corrupted buffer");
1285 return MUTT_CMD_ERROR;
1286 }
1287
1288 buf_addstr(err, _("No folder specified"));
1289 return MUTT_CMD_WARNING;
1290}
1291
1299static enum CommandResult parse_tag_formats(struct Buffer *buf, struct Buffer *s,
1300 intptr_t data, struct Buffer *err)
1301{
1302 if (!s)
1303 return MUTT_CMD_ERROR;
1304
1305 struct Buffer *tagbuf = buf_pool_get();
1306 struct Buffer *fmtbuf = buf_pool_get();
1307
1308 while (MoreArgs(s))
1309 {
1311 const char *tag = buf_string(tagbuf);
1312 if (*tag == '\0')
1313 continue;
1314
1316 const char *fmt = buf_string(fmtbuf);
1317
1318 /* avoid duplicates */
1319 const char *tmp = mutt_hash_find(TagFormats, fmt);
1320 if (tmp)
1321 {
1322 mutt_warning(_("tag format '%s' already registered as '%s'"), fmt, tmp);
1323 continue;
1324 }
1325
1327 }
1328
1329 buf_pool_release(&tagbuf);
1330 buf_pool_release(&fmtbuf);
1331 return MUTT_CMD_SUCCESS;
1332}
1333
1341static enum CommandResult parse_tag_transforms(struct Buffer *buf, struct Buffer *s,
1342 intptr_t data, struct Buffer *err)
1343{
1344 if (!s)
1345 return MUTT_CMD_ERROR;
1346
1347 struct Buffer *tagbuf = buf_pool_get();
1348 struct Buffer *trnbuf = buf_pool_get();
1349
1350 while (MoreArgs(s))
1351 {
1353 const char *tag = buf_string(tagbuf);
1354 if (*tag == '\0')
1355 continue;
1356
1358 const char *trn = buf_string(trnbuf);
1359
1360 /* avoid duplicates */
1361 const char *tmp = mutt_hash_find(TagTransforms, tag);
1362 if (tmp)
1363 {
1364 mutt_warning(_("tag transform '%s' already registered as '%s'"), tag, tmp);
1365 continue;
1366 }
1367
1369 }
1370
1371 buf_pool_release(&tagbuf);
1372 buf_pool_release(&trnbuf);
1373 return MUTT_CMD_SUCCESS;
1374}
1375
1379static enum CommandResult parse_unignore(struct Buffer *buf, struct Buffer *s,
1380 intptr_t data, struct Buffer *err)
1381{
1382 do
1383 {
1385
1386 /* don't add "*" to the unignore list */
1387 if (!mutt_str_equal(buf->data, "*"))
1388 add_to_stailq(&UnIgnore, buf->data);
1389
1391 } while (MoreArgs(s));
1392
1393 return MUTT_CMD_SUCCESS;
1394}
1395
1399static enum CommandResult parse_unlists(struct Buffer *buf, struct Buffer *s,
1400 intptr_t data, struct Buffer *err)
1401{
1403 do
1404 {
1408
1409 if (!mutt_str_equal(buf->data, "*") &&
1410 (mutt_regexlist_add(&UnMailLists, buf->data, REG_ICASE, err) != 0))
1411 {
1412 return MUTT_CMD_ERROR;
1413 }
1414 } while (MoreArgs(s));
1415
1416 return MUTT_CMD_SUCCESS;
1417}
1418
1423static void do_unmailboxes(struct Mailbox *m)
1424{
1425#ifdef USE_INOTIFY
1426 if (m->poll_new_mail)
1428#endif
1429 m->visible = false;
1430 m->gen = -1;
1431 if (m->opened)
1432 {
1433 struct EventMailbox ev_m = { NULL };
1434 mutt_debug(LL_NOTIFY, "NT_MAILBOX_CHANGE: NULL\n");
1436 }
1437 else
1438 {
1440 mailbox_free(&m);
1441 }
1442}
1443
1447static void do_unmailboxes_star(void)
1448{
1449 struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
1451 struct MailboxNode *np = NULL;
1452 struct MailboxNode *nptmp = NULL;
1453 STAILQ_FOREACH_SAFE(np, &ml, entries, nptmp)
1454 {
1456 }
1458}
1459
1465enum CommandResult parse_unmailboxes(struct Buffer *buf, struct Buffer *s,
1466 intptr_t data, struct Buffer *err)
1467{
1468 while (MoreArgs(s))
1469 {
1471
1472 if (mutt_str_equal(buf->data, "*"))
1473 {
1475 return MUTT_CMD_SUCCESS;
1476 }
1477
1478 buf_expand_path(buf);
1479
1480 struct Account *a = NULL;
1481 TAILQ_FOREACH(a, &NeoMutt->accounts, entries)
1482 {
1483 struct Mailbox *m = mx_mbox_find(a, buf_string(buf));
1484 if (m)
1485 {
1486 do_unmailboxes(m);
1487 break;
1488 }
1489 }
1490 }
1491 return MUTT_CMD_SUCCESS;
1492}
1493
1497static enum CommandResult parse_unmy_hdr(struct Buffer *buf, struct Buffer *s,
1498 intptr_t data, struct Buffer *err)
1499{
1500 struct ListNode *np = NULL, *tmp = NULL;
1501 size_t l;
1502
1503 do
1504 {
1506 if (mutt_str_equal("*", buf->data))
1507 {
1508 /* Clear all headers, send a notification for each header */
1509 STAILQ_FOREACH(np, &UserHeader, entries)
1510 {
1511 mutt_debug(LL_NOTIFY, "NT_HEADER_DELETE: %s\n", np->data);
1512 struct EventHeader ev_h = { np->data };
1514 }
1516 continue;
1517 }
1518
1519 l = mutt_str_len(buf->data);
1520 if (buf->data[l - 1] == ':')
1521 l--;
1522
1523 STAILQ_FOREACH_SAFE(np, &UserHeader, entries, tmp)
1524 {
1525 if (mutt_istrn_equal(buf->data, np->data, l) && (np->data[l] == ':'))
1526 {
1527 mutt_debug(LL_NOTIFY, "NT_HEADER_DELETE: %s\n", np->data);
1528 struct EventHeader ev_h = { np->data };
1530
1531 header_free(&UserHeader, np);
1532 }
1533 }
1534 } while (MoreArgs(s));
1535 return MUTT_CMD_SUCCESS;
1536}
1537
1543static enum CommandResult parse_unstailq(struct Buffer *buf, struct Buffer *s,
1544 intptr_t data, struct Buffer *err)
1545{
1546 do
1547 {
1549 /* Check for deletion of entire list */
1550 if (mutt_str_equal(buf->data, "*"))
1551 {
1552 mutt_list_free((struct ListHead *) data);
1553 break;
1554 }
1555 remove_from_stailq((struct ListHead *) data, buf->data);
1556 } while (MoreArgs(s));
1557
1558 return MUTT_CMD_SUCCESS;
1559}
1560
1564static enum CommandResult parse_unsubscribe(struct Buffer *buf, struct Buffer *s,
1565 intptr_t data, struct Buffer *err)
1566{
1568 do
1569 {
1572
1573 if (!mutt_str_equal(buf->data, "*") &&
1574 (mutt_regexlist_add(&UnSubscribedLists, buf->data, REG_ICASE, err) != 0))
1575 {
1576 return MUTT_CMD_ERROR;
1577 }
1578 } while (MoreArgs(s));
1579
1580 return MUTT_CMD_SUCCESS;
1581}
1582
1591 intptr_t data, struct Buffer *err)
1592{
1593 if (!buf || !s || !err)
1594 return MUTT_CMD_ERROR;
1595
1596 if (MoreArgs(s))
1597 {
1599
1600 if (MoreArgs(s))
1601 {
1602 buf_printf(err, _("%s: too many arguments"), "unsubscribe-from");
1603 return MUTT_CMD_WARNING;
1604 }
1605
1606 if (buf->data && (*buf->data != '\0'))
1607 {
1608 /* Expand and subscribe */
1609 buf_expand_path(buf);
1610 if (imap_subscribe(buf_string(buf), false) == 0)
1611 {
1612 mutt_message(_("Unsubscribed from %s"), buf->data);
1613 return MUTT_CMD_SUCCESS;
1614 }
1615
1616 buf_printf(err, _("Could not unsubscribe from %s"), buf->data);
1617 return MUTT_CMD_ERROR;
1618 }
1619
1620 mutt_debug(LL_DEBUG1, "Corrupted buffer");
1621 return MUTT_CMD_ERROR;
1622 }
1623
1624 buf_addstr(err, _("No folder specified"));
1625 return MUTT_CMD_WARNING;
1626}
1627
1631static enum CommandResult parse_version(struct Buffer *buf, struct Buffer *s,
1632 intptr_t data, struct Buffer *err)
1633{
1634 // silently ignore 'version' if it's in a config file
1635 if (!StartupComplete)
1636 return MUTT_CMD_SUCCESS;
1637
1638 struct Buffer *tempfile = buf_pool_get();
1639 buf_mktemp(tempfile);
1640
1641 FILE *fp_out = mutt_file_fopen(buf_string(tempfile), "w");
1642 if (!fp_out)
1643 {
1644 // L10N: '%s' is the file name of the temporary file
1645 buf_printf(err, _("Could not create temporary file %s"), buf_string(tempfile));
1646 buf_pool_release(&tempfile);
1647 return MUTT_CMD_ERROR;
1648 }
1649
1650 print_version(fp_out);
1651 mutt_file_fclose(&fp_out);
1652
1653 struct PagerData pdata = { 0 };
1654 struct PagerView pview = { &pdata };
1655
1656 pdata.fname = buf_string(tempfile);
1657
1658 pview.banner = "version";
1659 pview.flags = MUTT_PAGER_NO_FLAGS;
1660 pview.mode = PAGER_MODE_OTHER;
1661
1662 mutt_do_pager(&pview, NULL);
1663 buf_pool_release(&tempfile);
1664
1665 return MUTT_CMD_SUCCESS;
1666}
1667
1672{
1674}
1675
1679static const struct Command MuttCommands[] = {
1680 // clang-format off
1681 { "alias", parse_alias, 0 },
1682 { "alternates", parse_alternates, 0 },
1683 { "alternative_order", parse_stailq, IP &AlternativeOrderList },
1684 { "attachments", parse_attachments, 0 },
1685 { "auto_view", parse_stailq, IP &AutoViewList },
1686 { "bind", mutt_parse_bind, 0 },
1687 { "cd", parse_cd, 0 },
1688 { "color", mutt_parse_color, 0 },
1689 { "echo", parse_echo, 0 },
1690 { "exec", mutt_parse_exec, 0 },
1691 { "finish", parse_finish, 0 },
1692 { "group", parse_group, MUTT_GROUP },
1693 { "hdr_order", parse_stailq, IP &HeaderOrderList },
1694 { "ifdef", parse_ifdef, 0 },
1695 { "ifndef", parse_ifdef, 1 },
1696 { "ignore", parse_ignore, 0 },
1697 { "lists", parse_lists, 0 },
1698 { "macro", mutt_parse_macro, 1 },
1699 { "mailboxes", parse_mailboxes, 0 },
1700 { "mailto_allow", parse_stailq, IP &MailToAllow },
1701 { "mime_lookup", parse_stailq, IP &MimeLookupList },
1702 { "mono", mutt_parse_mono, 0 },
1703 { "my_hdr", parse_my_hdr, 0 },
1704 { "named-mailboxes", parse_mailboxes, MUTT_NAMED },
1705 { "nospam", parse_nospam, 0 },
1706 { "push", mutt_parse_push, 0 },
1707 { "reset", parse_set, MUTT_SET_RESET },
1708 { "score", mutt_parse_score, 0 },
1709 { "set", parse_set, MUTT_SET_SET },
1710 { "setenv", parse_setenv, MUTT_SET_SET },
1711 { "source", parse_source, 0 },
1712 { "spam", parse_spam, 0 },
1713 { "subjectrx", parse_subjectrx_list, 0 },
1714 { "subscribe", parse_subscribe, 0 },
1715 { "tag-formats", parse_tag_formats, 0 },
1716 { "tag-transforms", parse_tag_transforms, 0 },
1717 { "toggle", parse_set, MUTT_SET_INV },
1718 { "unalias", parse_unalias, 0 },
1719 { "unalternates", parse_unalternates, 0 },
1720 { "unalternative_order", parse_unstailq, IP &AlternativeOrderList },
1721 { "unattachments", parse_unattachments, 0 },
1722 { "unauto_view", parse_unstailq, IP &AutoViewList },
1723 { "unbind", mutt_parse_unbind, MUTT_UNBIND },
1724 { "uncolor", mutt_parse_uncolor, 0 },
1725 { "ungroup", parse_group, MUTT_UNGROUP },
1726 { "unhdr_order", parse_unstailq, IP &HeaderOrderList },
1727 { "unignore", parse_unignore, 0 },
1728 { "unlists", parse_unlists, 0 },
1729 { "unmacro", mutt_parse_unbind, MUTT_UNMACRO },
1730 { "unmailboxes", parse_unmailboxes, 0 },
1731 { "unmailto_allow", parse_unstailq, IP &MailToAllow },
1732 { "unmime_lookup", parse_unstailq, IP &MimeLookupList },
1733 { "unmono", mutt_parse_unmono, 0 },
1734 { "unmy_hdr", parse_unmy_hdr, 0 },
1735 { "unscore", mutt_parse_unscore, 0 },
1736 { "unset", parse_set, MUTT_SET_UNSET },
1737 { "unsetenv", parse_setenv, MUTT_SET_UNSET },
1738 { "unsubjectrx", parse_unsubjectrx_list, 0 },
1739 { "unsubscribe", parse_unsubscribe, 0 },
1740 { "version", parse_version, 0 },
1741 // clang-format on
1742};
1743
1748{
1750}
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1460
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:644
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1293
Email Address Handling.
Email Aliases.
Alternate address handling.
#define ARRAY_FREE(head)
Release all memory.
Definition: array.h:204
GUI display the mailboxes in a side panel.
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:161
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:76
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:291
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:226
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:395
size_t buf_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition: buffer.c:601
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition: buffer.c:571
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:96
Color and attribute parsing.
const struct Mapping ColorFields[]
Mapping of colour names to their IDs.
Definition: command.c:55
CommandResult
Error codes for command_t parse functions.
Definition: command.h:36
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition: command.h:39
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: command.h:37
@ MUTT_CMD_WARNING
Warning: Help given to the user.
Definition: command.h:38
@ MUTT_CMD_FINISH
Finish: Stop processing this file.
Definition: command.h:40
static const struct Command MuttCommands[]
General NeoMutt Commands.
Definition: commands.c:1679
static enum CommandResult mailbox_add(const char *folder, const char *mailbox, const char *label, enum TriBool poll, enum TriBool notify, struct Buffer *err)
Add a new Mailbox.
Definition: commands.c:637
static bool is_color_object(const char *name)
Is the argument a neomutt colour?
Definition: commands.c:128
GroupState
Type of email address group.
Definition: commands.c:95
@ GS_RX
Entry is a regular expression.
Definition: commands.c:97
@ GS_NONE
Group is missing an argument.
Definition: commands.c:96
@ GS_ADDR
Entry is an address.
Definition: commands.c:98
#define MAX_ERRS
Definition: commands.c:79
enum CommandResult parse_rc_line_cwd(const char *line, char *cwd, struct Buffer *err)
Parse and run a muttrc line in a relative directory.
Definition: commands.c:178
void commands_init(void)
Initialize commands array and register default commands.
Definition: commands.c:1747
int parse_grouplist(struct GroupList *gl, struct Buffer *buf, struct Buffer *s, struct Buffer *err)
Parse a group context.
Definition: commands.c:144
void source_stack_cleanup(void)
Free memory from the stack used for the source command.
Definition: commands.c:1671
static void do_unmailboxes_star(void)
Remove all Mailboxes from the Sidebar/notifications.
Definition: commands.c:1447
static struct ListHead MuttrcStack
LIFO designed to contain the list of config files that have been sourced and avoid cyclic sourcing.
Definition: commands.c:77
enum CommandResult set_dump(enum GetElemListFlags flags, struct Buffer *err)
Dump list of config variables into a file/pager.
Definition: commands.c:888
TriBool
Tri-state boolean.
Definition: commands.c:85
@ TB_FALSE
Value is false.
Definition: commands.c:87
@ TB_TRUE
Value is true.
Definition: commands.c:88
@ TB_UNSET
Value hasn't been set.
Definition: commands.c:86
bool mailbox_add_simple(const char *mailbox, struct Buffer *err)
Add a new Mailbox.
Definition: commands.c:741
static void do_unmailboxes(struct Mailbox *m)
Remove a Mailbox from the Sidebar/notifications.
Definition: commands.c:1423
int source_rc(const char *rcfile_path, struct Buffer *err)
Read an initialization file.
Definition: commands.c:219
char * mutt_get_sourced_cwd(void)
Get the current file path that is being parsed.
Definition: commands.c:198
static bool is_function(const char *name)
Is the argument a neomutt function?
Definition: commands.c:107
Functions to parse commands in a config file.
#define MUTT_NAMED
Definition: commands.h:36
bool dump_config(struct ConfigSet *cs, struct HashElemArray *hea, ConfigDumpFlags flags, FILE *fp)
Write all the config to a file.
Definition: dump.c:196
#define CS_DUMP_NO_FLAGS
No flags are set.
Definition: dump.h:36
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:291
Convenience wrapper for the config headers.
char * HomeDir
User's home directory.
Definition: globals.c:37
bool StartupComplete
When the config has been read.
Definition: main.c:198
#define IP
Definition: set.h:54
const char * cc_charset(void)
Get the cached value of $charset.
Definition: config_cache.c:116
bool account_mailbox_remove(struct Account *a, struct Mailbox *m)
Remove a Mailbox from an Account.
Definition: account.c:98
struct Account * account_new(const char *name, struct ConfigSubset *sub)
Create a new Account.
Definition: account.c:44
void commands_register(const struct Command *cmds, const size_t num_cmds)
Add commands to Commands array.
Definition: command.c:53
struct Command * command_get(const char *s)
Get a Command by its name.
Definition: command.c:87
Convenience wrapper for the core headers.
int mailbox_gen(void)
Get the next generation number.
Definition: mailbox.c:58
struct Mailbox * mailbox_new(void)
Create a new Mailbox.
Definition: mailbox.c:68
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:89
@ NT_MAILBOX_CHANGE
Mailbox has been changed.
Definition: mailbox.h:185
@ MUTT_MAILBOX_ANY
Match any Mailbox type.
Definition: mailbox.h:42
@ MUTT_UNKNOWN
Mailbox wasn't recognised.
Definition: mailbox.h:44
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:174
void mutt_endwin(void)
Shutdown curses.
Definition: curs_lib.c:152
int mutt_do_pager(struct PagerView *pview, struct Email *e)
Display some page-able text to the user (help or attachment)
Definition: do_pager.c:122
void header_free(struct ListHead *hdrlist, struct ListNode *target)
Free and remove a header from a header list.
Definition: email.c:202
struct ListNode * header_add(struct ListHead *hdrlist, const char *header)
Add a header to a list.
Definition: email.c:160
struct ListNode * header_update(struct ListNode *hdr, const char *header)
Update an existing header.
Definition: email.c:174
struct ListNode * header_find(const struct ListHead *hdrlist, const char *header)
Find a header, matching on its field, in a list of headers.
Definition: email.c:137
struct ReplaceList SpamList
List of regexes to match subscribed mailing lists.
Definition: globals.c:46
struct RegexList SubscribedLists
List of header patterns to unignore (see)
Definition: globals.c:48
struct HashTable * AutoSubscribeCache
< Hash Table: "mailto:" -> AutoSubscribeCache
Definition: globals.c:36
struct RegexList UnSubscribedLists
Definition: globals.c:54
struct RegexList UnMailLists
List of regexes to exclude false matches in SubscribedLists.
Definition: globals.c:52
struct RegexList MailLists
List of permitted fields in a mailto: url.
Definition: globals.c:40
struct ListHead MailToAllow
List of regexes to identify non-spam emails.
Definition: globals.c:42
struct ListHead Ignore
List of regexes to match mailing lists.
Definition: globals.c:38
struct RegexList NoSpamList
List of regexes and patterns to match spam emails.
Definition: globals.c:44
struct ListHead UnIgnore
List of regexes to exclude false matches in MailLists.
Definition: globals.c:50
Structs that make up an email.
@ NT_HEADER_CHANGE
An existing header has been changed.
Definition: email.h:210
@ NT_HEADER_ADD
Header has been added.
Definition: email.h:208
@ NT_HEADER_DELETE
Header has been removed.
Definition: email.h:209
bool envlist_set(char ***envp, const char *name, const char *value, bool overwrite)
Set an environment variable.
Definition: envlist.c:88
bool envlist_unset(char ***envp, const char *name)
Unset an environment variable.
Definition: envlist.c:136
int parse_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: extract.c:50
#define TOKEN_BACKTICK_VARS
Expand variables within backticks.
Definition: extract.h:54
#define TOKEN_SPACE
Don't treat whitespace as a term.
Definition: extract.h:49
#define TOKEN_QUOTE
Don't interpret quotes.
Definition: extract.h:50
#define TOKEN_EQUAL
Treat '=' as a special.
Definition: extract.h:47
#define MoreArgs(buf)
Definition: extract.h:32
#define TOKEN_QUESTION
Treat '?' as a special.
Definition: extract.h:56
#define TOKEN_NO_FLAGS
No flags are set.
Definition: extract.h:46
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, ReadLineFlags flags)
Read a line from a file.
Definition: file.c:685
#define MUTT_RL_CONT
-continuation
Definition: file.h:41
#define mutt_file_fclose(FP)
Definition: file.h:139
#define mutt_file_fopen(PATH, MODE)
Definition: file.h:138
struct ListHead MimeLookupList
List of mime types that that shouldn't use the mailcap entry.
Definition: globals.c:50
struct ListHead AlternativeOrderList
List of preferred mime types to display.
Definition: globals.c:47
struct ListHead AutoViewList
List of mime types to auto view.
Definition: globals.c:48
bool OptForceRefresh
(pseudo) refresh even during macros
Definition: globals.c:62
struct ListHead UserHeader
List of custom headers to add to outgoing emails.
Definition: globals.c:53
struct ListHead HeaderOrderList
List of header fields in the order they should be displayed.
Definition: globals.c:49
char ** EnvList
Private copy of the environment variables.
Definition: globals.c:75
Global variables.
int mutt_grouplist_remove_addrlist(struct GroupList *gl, struct AddressList *al)
Remove an AddressList from a GroupList.
Definition: group.c:290
void mutt_grouplist_add(struct GroupList *gl, struct Group *group)
Add a Group to a GroupList.
Definition: group.c:182
int mutt_grouplist_add_regex(struct GroupList *gl, const char *s, uint16_t flags, struct Buffer *err)
Add matching Addresses to a GroupList.
Definition: group.c:321
struct Group * mutt_pattern_group(const char *pat)
Match a pattern to a Group.
Definition: group.c:117
int mutt_grouplist_remove_regex(struct GroupList *gl, const char *s)
Remove matching addresses from a GroupList.
Definition: group.c:346
void mutt_grouplist_destroy(struct GroupList *gl)
Free a GroupList.
Definition: group.c:202
void mutt_grouplist_clear(struct GroupList *gl)
Clear a GroupList.
Definition: group.c:148
void mutt_grouplist_add_addrlist(struct GroupList *gl, struct AddressList *al)
Add Address list to a GroupList.
Definition: group.c:271
#define MUTT_GROUP
'group' config command
Definition: group.h:32
#define MUTT_UNGROUP
'ungroup' config command
Definition: group.h:33
static enum CommandResult parse_finish(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'finish' command - Implements Command::parse() -.
Definition: commands.c:421
static enum CommandResult parse_stailq(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse a list command - Implements Command::parse() -.
Definition: commands.c:1199
static enum CommandResult parse_version(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'version' command - Implements Command::parse() -.
Definition: commands.c:1631
static enum CommandResult parse_unlists(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'unlists' command - Implements Command::parse() -.
Definition: commands.c:1399
static enum CommandResult parse_group(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'group' and 'ungroup' commands - Implements Command::parse() -.
Definition: commands.c:436
enum CommandResult parse_unsubjectrx_list(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'unsubjectrx' command - Implements Command::parse() -.
Definition: subjectrx.c:188
enum CommandResult parse_set(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'set' family of commands - Implements Command::parse() -.
Definition: set.c:470
static enum CommandResult parse_spam(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'spam' command - Implements Command::parse() -.
Definition: commands.c:1161
enum CommandResult parse_alternates(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'alternates' command - Implements Command::parse() -.
Definition: alternates.c:92
enum CommandResult mutt_parse_unscore(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'unscore' command - Implements Command::parse() -.
Definition: score.c:201
enum CommandResult mutt_parse_unmono(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'unmono' command - Implements Command::parse() -.
Definition: command.c:447
static enum CommandResult parse_unstailq(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse an unlist command - Implements Command::parse() -.
Definition: commands.c:1543
enum CommandResult mutt_parse_bind(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'bind' command - Implements Command::parse() -.
Definition: parse.c:368
enum CommandResult parse_subjectrx_list(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'subjectrx' command - Implements Command::parse() -.
Definition: subjectrx.c:171
enum CommandResult parse_unsubscribe_from(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'unsubscribe-from' command - Implements Command::parse() -.
Definition: commands.c:1590
static enum CommandResult parse_unignore(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'unignore' command - Implements Command::parse() -.
Definition: commands.c:1379
static enum CommandResult parse_ifdef(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'ifdef' and 'ifndef' commands - Implements Command::parse() -.
Definition: commands.c:536
static enum CommandResult parse_source(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'source' command - Implements Command::parse() -.
Definition: commands.c:1088
enum CommandResult parse_unalternates(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'unalternates' command - Implements Command::parse() -.
Definition: alternates.c:128
enum CommandResult mutt_parse_score(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'score' command - Implements Command::parse() -.
Definition: score.c:91
enum CommandResult parse_unmailboxes(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'unmailboxes' command - Implements Command::parse() -.
Definition: commands.c:1465
static enum CommandResult parse_unmy_hdr(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'unmy_hdr' command - Implements Command::parse() -.
Definition: commands.c:1497
enum CommandResult mutt_parse_mono(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'mono' command - Implements Command::parse() -.
Definition: command.c:479
enum CommandResult mutt_parse_color(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'color' command - Implements Command::parse() -.
Definition: command.c:457
static enum CommandResult parse_subscribe(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'subscribe' command - Implements Command::parse() -.
Definition: commands.c:1214
static enum CommandResult parse_tag_transforms(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'tag-transforms' command - Implements Command::parse() -.
Definition: commands.c:1341
enum CommandResult mutt_parse_uncolor(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'uncolor' command - Implements Command::parse() -.
Definition: command.c:426
static enum CommandResult parse_cd(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'cd' command - Implements Command::parse() -.
Definition: commands.c:367
static enum CommandResult parse_ignore(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'ignore' command - Implements Command::parse() -.
Definition: commands.c:582
enum CommandResult parse_subscribe_to(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'subscribe-to' command - Implements Command::parse() -.
Definition: commands.c:1252
enum CommandResult mutt_parse_unbind(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'unbind' command - Implements Command::parse() -.
Definition: parse.c:481
enum CommandResult parse_alias(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'alias' command - Implements Command::parse() -.
Definition: commands.c:135
enum CommandResult parse_unalias(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'unalias' command - Implements Command::parse() -.
Definition: commands.c:251
enum CommandResult parse_mailboxes(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'mailboxes' command - Implements Command::parse() -.
Definition: commands.c:753
static enum CommandResult parse_tag_formats(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'tag-formats' command - Implements Command::parse() -.
Definition: commands.c:1299
enum CommandResult mutt_parse_macro(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'macro' command - Implements Command::parse() -.
Definition: parse.c:569
enum CommandResult parse_unattachments(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'unattachments' command - Implements Command::parse() -.
Definition: attachments.c:534
static enum CommandResult parse_lists(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'lists' command - Implements Command::parse() -.
Definition: commands.c:598
static enum CommandResult parse_echo(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'echo' command - Implements Command::parse() -.
Definition: commands.c:397
enum CommandResult parse_my_hdr(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'my_hdr' command - Implements Command::parse() -.
Definition: commands.c:849
static enum CommandResult parse_unsubscribe(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'unsubscribe' command - Implements Command::parse() -.
Definition: commands.c:1564
static enum CommandResult parse_setenv(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'setenv' and 'unsetenv' commands - Implements Command::parse() -.
Definition: commands.c:935
enum CommandResult mutt_parse_push(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'push' command - Implements Command::parse() -.
Definition: parse.c:349
enum CommandResult parse_attachments(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'attachments' command - Implements Command::parse() -.
Definition: attachments.c:475
enum CommandResult mutt_parse_exec(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'exec' command - Implements Command::parse() -.
Definition: parse.c:659
static enum CommandResult parse_nospam(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse the 'nospam' command - Implements Command::parse() -.
Definition: commands.c:1121
#define mutt_warning(...)
Definition: logging2.h:90
#define mutt_error(...)
Definition: logging2.h:92
#define mutt_message(...)
Definition: logging2.h:91
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
static int envlist_sort(const void *a, const void *b, void *sdata)
Compare two environment strings - Implements sort_t -.
Definition: commands.c:927
Convenience wrapper for the gui headers.
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
Definition: hash.c:335
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:362
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:457
IMAP network mailbox.
int imap_subscribe(const char *path, bool subscribe)
Subscribe to a mailbox.
Definition: imap.c:1222
const struct MenuFuncOp * km_get_table(enum MenuType mtype)
Lookup a Menu's functions.
Definition: lib.c:499
Manage keymappings.
#define MUTT_UNBIND
Parse 'unbind' command.
Definition: lib.h:48
#define MUTT_UNMACRO
Parse 'unmacro' command.
Definition: lib.h:49
struct ListNode * mutt_list_insert_head(struct ListHead *h, char *s)
Insert a string at the beginning of a List.
Definition: list.c:46
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:123
@ LL_DEBUG2
Log at debug level 2.
Definition: logging2.h:44
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
@ LL_NOTIFY
Log of notifications.
Definition: logging2.h:48
int mutt_map_get_value(const char *name, const struct Mapping *map)
Lookup the constant for a string.
Definition: mapping.c:85
#define FREE(x)
Definition: memory.h:55
#define mutt_array_size(x)
Definition: memory.h:38
GUI present the user with a selectable list.
int mutt_monitor_add(struct Mailbox *m)
Add a watch for a mailbox.
Definition: monitor.c:484
int mutt_monitor_remove(struct Mailbox *m)
Remove a watch for a mailbox.
Definition: monitor.c:528
Monitor files for changes.
int mutt_ch_convert_string(char **ps, const char *from, const char *to, uint8_t flags)
Convert a string between encodings.
Definition: charset.c:831
#define MUTT_ICONV_NO_FLAGS
No flags are set.
Definition: charset.h:64
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:220
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
void notify_free(struct Notify **ptr)
Free a notification handler.
Definition: notify.c:75
bool mutt_path_to_absolute(char *path, const char *reference)
Convert a relative path to its absolute form.
Definition: path.c:333
const char * mutt_path_getcwd(struct Buffer *cwd)
Get the current working directory.
Definition: path.c:476
int mutt_replacelist_remove(struct ReplaceList *rl, const char *pat)
Remove a pattern from a list.
Definition: regex.c:566
void mutt_regexlist_free(struct RegexList *rl)
Free a RegexList object.
Definition: regex.c:179
int mutt_regexlist_add(struct RegexList *rl, const char *str, uint16_t flags, struct Buffer *err)
Compile a regex string and add it to a list.
Definition: regex.c:140
void mutt_replacelist_free(struct ReplaceList *rl)
Free a ReplaceList object.
Definition: regex.c:450
int mutt_regexlist_remove(struct RegexList *rl, const char *str)
Remove a Regex from a list.
Definition: regex.c:235
int mutt_replacelist_add(struct ReplaceList *rl, const char *pat, const char *templ, struct Buffer *err)
Add a pattern and a template to a list.
Definition: regex.c:271
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:673
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:254
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:661
const char * mutt_str_getenv(const char *name)
Get an environment variable.
Definition: string.c:727
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:231
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:497
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:582
bool mutt_istrn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings ignoring case (to a maximum), safely.
Definition: string.c:454
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:281
Many unsorted constants and some structs.
#define PATH_MAX
Definition: mutt.h:42
void remove_from_stailq(struct ListHead *head, const char *str)
Remove an item, matching a string, from a List.
Definition: muttlib.c:1077
void add_to_stailq(struct ListHead *head, const char *str)
Add a string to a list.
Definition: muttlib.c:1052
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:842
void buf_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:315
FILE * mutt_open_read(const char *path, pid_t *thepid)
Run a command to read from.
Definition: muttlib.c:700
Some miscellaneous functions.
struct Mailbox * mx_mbox_find(struct Account *a, const char *path)
Find a Mailbox on an Account.
Definition: mx.c:1547
bool mx_ac_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account - Wrapper for MxOps::ac_add()
Definition: mx.c:1727
struct Account * mx_ac_find(struct Mailbox *m)
Find the Account owning a Mailbox.
Definition: mx.c:1523
int mx_path_canon2(struct Mailbox *m, const char *folder)
Canonicalise the path to realpath.
Definition: mx.c:1475
API for mailboxes.
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:168
bool neomutt_account_add(struct NeoMutt *n, struct Account *a)
Add an Account to the global list.
Definition: neomutt.c:110
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:191
@ NT_MAILBOX
Mailbox has changed, NotifyMailbox, EventMailbox.
Definition: notify_type.h:49
@ NT_HEADER
A header has changed, NotifyHeader EventHeader.
Definition: notify_type.h:47
GUI display a file/email/help in a viewport with paging.
#define MUTT_PAGER_NO_FLAGS
No flags are set.
Definition: lib.h:60
@ PAGER_MODE_OTHER
Pager is invoked via 3rd path. Non-email content is likely to be shown.
Definition: lib.h:140
Text parsing functions.
@ MUTT_SET_INV
default is to invert all vars
Definition: set.h:37
@ MUTT_SET_SET
default is to set all vars
Definition: set.h:36
@ MUTT_SET_RESET
default is to reset all vars to default
Definition: set.h:39
@ MUTT_SET_UNSET
default is to unset all vars
Definition: set.h:38
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:96
void mutt_qsort_r(void *base, size_t nmemb, size_t size, sort_t compar, void *sdata)
Sort an array, where the comparator has access to opaque data rather than requiring global variables.
Definition: qsort_r.c:67
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:782
#define STAILQ_REMOVE_HEAD(head, field)
Definition: queue.h:461
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
#define STAILQ_FIRST(head)
Definition: queue.h:388
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:390
#define STAILQ_EMPTY(head)
Definition: queue.h:382
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:694
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:400
#define TAILQ_EMPTY(head)
Definition: queue.h:778
enum CommandResult parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: rc.c:104
enum CommandResult parse_rc_buffer(struct Buffer *line, struct Buffer *token, struct Buffer *err)
Parse a line of user config.
Definition: rc.c:46
Routines for adding user scores to emails.
Key value store.
bool store_is_valid_backend(const char *str)
Is the string a valid Store backend.
Definition: store.c:129
#define NONULL(x)
Definition: string2.h:37
#define SKIPWS(ch)
Definition: string2.h:45
A group of associated Mailboxes.
Definition: account.h:36
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:37
char * name
Name of Account.
Definition: account.h:38
struct Notify * notify
Notifications: NotifyAccount, EventAccount.
Definition: account.h:41
struct ConfigSubset * sub
Inherited config items.
Definition: account.h:39
String manipulation buffer.
Definition: buffer.h:36
char * dptr
Current read/write position.
Definition: buffer.h:38
char * data
Pointer to data.
Definition: buffer.h:37
Container for lots of config items.
Definition: set.h:250
struct ConfigSet * cs
Parent ConfigSet.
Definition: subset.h:50
An event that happened to a header.
Definition: email.h:217
An Event that happened to a Mailbox.
Definition: mailbox.h:199
struct Mailbox * mailbox
The Mailbox this Event relates to.
Definition: mailbox.h:200
A List node for strings.
Definition: list.h:37
char * data
String.
Definition: list.h:38
List of Mailboxes.
Definition: mailbox.h:166
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:167
A mailbox.
Definition: mailbox.h:79
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:81
enum MailboxType type
Mailbox type.
Definition: mailbox.h:102
bool poll_new_mail
Check for new mail.
Definition: mailbox.h:115
char * name
A short name for the Mailbox.
Definition: mailbox.h:82
struct Notify * notify
Notifications: NotifyMailbox, EventMailbox.
Definition: mailbox.h:145
bool notify_user
Notify the user of new mail.
Definition: mailbox.h:113
struct Buffer pathbuf
Path of the Mailbox.
Definition: mailbox.h:80
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:127
bool visible
True if a result of "mailboxes".
Definition: mailbox.h:130
int opened
Number of times mailbox is opened.
Definition: mailbox.h:128
int gen
Generation number, for sorting.
Definition: mailbox.h:147
const char * name
String value.
Definition: mapping.h:34
Mapping between a function and an operation.
Definition: lib.h:102
const char * name
Name of the function.
Definition: lib.h:103
Container for Accounts, Notifications.
Definition: neomutt.h:42
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:47
struct Notify * notify
Notifications handler.
Definition: neomutt.h:43
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:46
Data to be displayed by PagerView.
Definition: lib.h:159
const char * fname
Name of the file to read.
Definition: lib.h:163
Paged view into some data.
Definition: lib.h:170
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition: lib.h:171
enum PagerMode mode
Pager mode.
Definition: lib.h:172
PagerFlags flags
Additional settings to tweak pager's function.
Definition: lib.h:173
const char * banner
Title to display in status bar.
Definition: lib.h:174
struct HashElemArray get_elem_list(struct ConfigSet *cs, enum GetElemListFlags flags)
Create a sorted list of all config items.
Definition: subset.c:80
void cs_subset_free(struct ConfigSubset **ptr)
Free a Config Subset.
Definition: subset.c:108
struct HashElem * cs_subset_lookup(const struct ConfigSubset *sub, const char *name)
Find an inherited config item.
Definition: subset.c:189
GetElemListFlags
Flags for get_elem_list()
Definition: subset.h:80
struct HashTable * TagFormats
Hash Table: "inbox" -> "GI" - Tag format strings.
Definition: tags.c:42
struct HashTable * TagTransforms
Hash Table: "inbox" -> "i" - Alternative tag names.
Definition: tags.c:41
#define buf_mktemp(buf)
Definition: tmp.h:33
const struct Mapping MenuNames[]
Menu name lookup table.
Definition: type.c:37
bool print_version(FILE *fp)
Print system and compile info to a file.
Definition: version.c:388
bool feature_enabled(const char *name)
Test if a compile-time feature is enabled.
Definition: version.c:544
Display version and copyright about NeoMutt.