/src/neomutt/alias/commands.c
Line | Count | Source (jump to first uncovered line) |
1 | | /** |
2 | | * @file |
3 | | * Alias commands |
4 | | * |
5 | | * @authors |
6 | | * Copyright (C) 2020 Richard Russon <rich@flatcap.org> |
7 | | * |
8 | | * @copyright |
9 | | * This program is free software: you can redistribute it and/or modify it under |
10 | | * the terms of the GNU General Public License as published by the Free Software |
11 | | * Foundation, either version 2 of the License, or (at your option) any later |
12 | | * version. |
13 | | * |
14 | | * This program is distributed in the hope that it will be useful, but WITHOUT |
15 | | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
16 | | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
17 | | * details. |
18 | | * |
19 | | * You should have received a copy of the GNU General Public License along with |
20 | | * this program. If not, see <http://www.gnu.org/licenses/>. |
21 | | */ |
22 | | |
23 | | /** |
24 | | * @page alias_commands Alias commands |
25 | | * |
26 | | * Alias commands |
27 | | */ |
28 | | |
29 | | #include "config.h" |
30 | | #include <stdint.h> |
31 | | #include <stdio.h> |
32 | | #include "mutt/lib.h" |
33 | | #include "address/lib.h" |
34 | | #include "config/lib.h" |
35 | | #include "core/lib.h" |
36 | | #include "commands.h" |
37 | | #include "lib.h" |
38 | | #include "parse/lib.h" |
39 | | #include "alias.h" |
40 | | #include "reverse.h" |
41 | | |
42 | | /** |
43 | | * parse_alias - Parse the 'alias' command - Implements Command::parse() - @ingroup command_parse |
44 | | * |
45 | | * e.g. "alias jim James Smith <js@example.com> # Pointy-haired boss" |
46 | | */ |
47 | | enum CommandResult parse_alias(struct Buffer *buf, struct Buffer *s, |
48 | | intptr_t data, struct Buffer *err) |
49 | 0 | { |
50 | 0 | struct Alias *tmp = NULL; |
51 | 0 | struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl); |
52 | 0 | enum NotifyAlias event; |
53 | |
|
54 | 0 | if (!MoreArgs(s)) |
55 | 0 | { |
56 | 0 | buf_strcpy(err, _("alias: no address")); |
57 | 0 | return MUTT_CMD_WARNING; |
58 | 0 | } |
59 | | |
60 | | /* name */ |
61 | 0 | parse_extract_token(buf, s, TOKEN_NO_FLAGS); |
62 | 0 | mutt_debug(LL_DEBUG5, "First token is '%s'\n", buf->data); |
63 | 0 | if (parse_grouplist(&gl, buf, s, err) == -1) |
64 | 0 | { |
65 | 0 | return MUTT_CMD_ERROR; |
66 | 0 | } |
67 | 0 | char *name = mutt_str_dup(buf->data); |
68 | | |
69 | | /* address list */ |
70 | 0 | parse_extract_token(buf, s, TOKEN_QUOTE | TOKEN_SPACE | TOKEN_SEMICOLON); |
71 | 0 | mutt_debug(LL_DEBUG5, "Second token is '%s'\n", buf->data); |
72 | 0 | struct AddressList al = TAILQ_HEAD_INITIALIZER(al); |
73 | 0 | int parsed = mutt_addrlist_parse2(&al, buf->data); |
74 | 0 | if (parsed == 0) |
75 | 0 | { |
76 | 0 | buf_printf(err, _("Warning: Bad address '%s' in alias '%s'"), buf->data, name); |
77 | 0 | FREE(&name); |
78 | 0 | goto bail; |
79 | 0 | } |
80 | | |
81 | | /* IDN */ |
82 | 0 | char *estr = NULL; |
83 | 0 | if (mutt_addrlist_to_intl(&al, &estr)) |
84 | 0 | { |
85 | 0 | buf_printf(err, _("Warning: Bad IDN '%s' in alias '%s'"), estr, name); |
86 | 0 | FREE(&name); |
87 | 0 | FREE(&estr); |
88 | 0 | goto bail; |
89 | 0 | } |
90 | | |
91 | | /* check to see if an alias with this name already exists */ |
92 | 0 | TAILQ_FOREACH(tmp, &Aliases, entries) |
93 | 0 | { |
94 | 0 | if (mutt_istr_equal(tmp->name, name)) |
95 | 0 | break; |
96 | 0 | } |
97 | |
|
98 | 0 | if (tmp) |
99 | 0 | { |
100 | 0 | FREE(&name); |
101 | 0 | alias_reverse_delete(tmp); |
102 | | /* override the previous value */ |
103 | 0 | mutt_addrlist_clear(&tmp->addr); |
104 | 0 | FREE(&tmp->comment); |
105 | 0 | event = NT_ALIAS_CHANGE; |
106 | 0 | } |
107 | 0 | else |
108 | 0 | { |
109 | | /* create a new alias */ |
110 | 0 | tmp = alias_new(); |
111 | 0 | tmp->name = name; |
112 | 0 | TAILQ_INSERT_TAIL(&Aliases, tmp, entries); |
113 | 0 | event = NT_ALIAS_ADD; |
114 | 0 | } |
115 | 0 | tmp->addr = al; |
116 | |
|
117 | 0 | mutt_grouplist_add_addrlist(&gl, &tmp->addr); |
118 | |
|
119 | 0 | const short c_debug_level = cs_subset_number(NeoMutt->sub, "debug_level"); |
120 | 0 | if (c_debug_level > LL_DEBUG4) |
121 | 0 | { |
122 | | /* A group is terminated with an empty address, so check a->mailbox */ |
123 | 0 | struct Address *a = NULL; |
124 | 0 | TAILQ_FOREACH(a, &tmp->addr, entries) |
125 | 0 | { |
126 | 0 | if (!a->mailbox) |
127 | 0 | break; |
128 | | |
129 | 0 | if (a->group) |
130 | 0 | mutt_debug(LL_DEBUG5, " Group %s\n", buf_string(a->mailbox)); |
131 | 0 | else |
132 | 0 | mutt_debug(LL_DEBUG5, " %s\n", buf_string(a->mailbox)); |
133 | 0 | } |
134 | 0 | } |
135 | 0 | mutt_grouplist_destroy(&gl); |
136 | 0 | if (!MoreArgs(s) && (s->dptr[0] == '#')) |
137 | 0 | { |
138 | 0 | char *comment = s->dptr + 1; |
139 | 0 | SKIPWS(comment); |
140 | 0 | tmp->comment = mutt_str_dup(comment); |
141 | 0 | } |
142 | |
|
143 | 0 | alias_reverse_add(tmp); |
144 | |
|
145 | 0 | mutt_debug(LL_NOTIFY, "%s: %s\n", |
146 | 0 | (event == NT_ALIAS_ADD) ? "NT_ALIAS_ADD" : "NT_ALIAS_CHANGE", tmp->name); |
147 | 0 | struct EventAlias ev_a = { tmp }; |
148 | 0 | notify_send(NeoMutt->notify, NT_ALIAS, event, &ev_a); |
149 | |
|
150 | 0 | return MUTT_CMD_SUCCESS; |
151 | | |
152 | 0 | bail: |
153 | 0 | mutt_grouplist_destroy(&gl); |
154 | 0 | return MUTT_CMD_ERROR; |
155 | 0 | } |
156 | | |
157 | | /** |
158 | | * parse_unalias - Parse the 'unalias' command - Implements Command::parse() - @ingroup command_parse |
159 | | */ |
160 | | enum CommandResult parse_unalias(struct Buffer *buf, struct Buffer *s, |
161 | | intptr_t data, struct Buffer *err) |
162 | 0 | { |
163 | 0 | do |
164 | 0 | { |
165 | 0 | parse_extract_token(buf, s, TOKEN_NO_FLAGS); |
166 | |
|
167 | 0 | struct Alias *np = NULL; |
168 | 0 | if (mutt_str_equal("*", buf->data)) |
169 | 0 | { |
170 | 0 | TAILQ_FOREACH(np, &Aliases, entries) |
171 | 0 | { |
172 | 0 | alias_reverse_delete(np); |
173 | 0 | } |
174 | |
|
175 | 0 | aliaslist_free(&Aliases); |
176 | 0 | return MUTT_CMD_SUCCESS; |
177 | 0 | } |
178 | | |
179 | 0 | TAILQ_FOREACH(np, &Aliases, entries) |
180 | 0 | { |
181 | 0 | if (!mutt_istr_equal(buf->data, np->name)) |
182 | 0 | continue; |
183 | | |
184 | 0 | TAILQ_REMOVE(&Aliases, np, entries); |
185 | 0 | alias_reverse_delete(np); |
186 | 0 | alias_free(&np); |
187 | 0 | break; |
188 | 0 | } |
189 | 0 | } while (MoreArgs(s)); |
190 | 0 | return MUTT_CMD_SUCCESS; |
191 | 0 | } |