1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999-2021 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include "mail.h"
18
19 #define FIND_IN_TABLE(f,t,c)\
20 f ((void*)(t), sizeof ((t)) / sizeof ((t)[0]), sizeof ((t)[0]), c)
21
22 static const struct mail_command_entry mail_command_table[] = {
23 { "a", "alias", "a[lias] [alias [address...]]", 0,
24 mail_alias, alias_compl },
25 { "alt", "alternates", "alt[ernates] name...", 0,
26 mail_alt, NULL },
27 { "C", "Copy", "C[opy] [msglist]", 0,
28 mail_copy, msglist_compl },
29 { "cd", "cd", "cd [directory]", 0,
30 mail_cd, dir_compl },
31 { "ch", "chdir", "ch[dir] directory", 0,
32 mail_cd, NULL },
33 { "c", "copy", "c[opy] [[msglist] file]", 0,
34 mail_copy, msglist_file_compl },
35 { "dec", "decode", "dec[ode] [msglist]", 0,
36 mail_decode, msglist_compl },
37 { "d", "delete", "d[elete] [msglist]", 0,
38 mail_delete, msglist_compl },
39 { "di", "discard", "di[scard] [header-field...]", 0,
40 mail_discard, no_compl },
41 { "dp", "dp", "dp [msglist]", 0,
42 mail_dp, msglist_compl },
43 { "dt", "dt", "dt [msglist]", 0,
44 mail_dp, msglist_compl },
45 { "ec", "echo", "ec[ho] string ...", 0,
46 mail_echo, no_compl },
47 { "e", "edit", "e[dit] [msglist]", 0,
48 mail_edit, msglist_compl },
49 { "el", "else", "el[se]", EF_FLOW,
50 mail_else, no_compl },
51 { "en", "endif", "en[dif]", EF_FLOW,
52 mail_endif, no_compl },
53 { "env", "envelope", "en[velope]", 0,
54 mail_envelope, msglist_compl },
55 { "ex", "exit", "ex[it]", 0,
56 mail_exit, no_compl },
57 { "F", "Followup", "F[ollowup] [msglist]", EF_SEND,
58 mail_followup, msglist_compl },
59 { "fi", "file", "fi[le] [file]", 0,
60 mail_file, file_compl },
61 { "fold", "folder", "fold[er] [file]", 0,
62 mail_file, file_compl },
63 { "folders", "folders", "folders", 0,
64 mail_folders, no_compl },
65 { "fo", "followup", "fo[llowup] [message]", EF_SEND,
66 mail_followup, msglist_compl },
67 { "f", "from", "f[rom] [msglist]", 0,
68 mail_from, msglist_compl },
69 { "g", "group", "g[roup] [alias [address...]]", 0,
70 mail_alias, alias_compl },
71 { "h", "headers", "h[eaders] [msglist]", 0,
72 mail_headers, msglist_compl },
73 { "hel", "help", "hel[p] [command...]", 0,
74 mail_help, command_compl },
75 { "ho", "hold", "ho[ld] [msglist]", 0,
76 mail_hold, msglist_compl },
77 { "i", "if", "i[f] s|r|t", EF_FLOW,
78 mail_if, no_compl },
79 { "ig", "ignore", "ig[nore] [header-field...]", 0,
80 mail_discard, no_compl },
81 { "inc", "incorporate", "inc[orporate]", 0,
82 mail_inc, no_compl },
83 { "l", "list", "l[ist]", 0,
84 mail_list, no_compl },
85 { "m", "mail", "m[ail] [address...]", EF_SEND,
86 mail_send, alias_compl },
87 { "M", "Mail", "M[ail] [address...]", EF_SEND,
88 mail_send, alias_compl },
89 { "mb", "mbox", "mb[ox] [msglist]", 0,
90 mail_mbox, msglist_compl },
91 { "n", "next", "n[ext] [message]", 0,
92 mail_next, no_compl },
93 { "nosender", "nos", "nos[ender] [header-field...]", 0,
94 mail_nosender, no_compl },
95 { "nou", "nounfold", "nou[nfold] [header-field]", 0,
96 mail_nounfold, no_compl },
97 { "P", "Print", "P[rint] [msglist]", 0,
98 mail_print, msglist_compl },
99 { "pi", "pipe", "pi[pe] [[msglist] command]", 0,
100 mail_pipe, exec_compl },
101 { "pre", "preserve", "pre[serve] [msglist]", 0,
102 mail_hold, msglist_compl },
103 { "prev", "previous", "prev[ious] [message]", 0,
104 mail_previous, no_compl },
105 { "p", "print", "p[rint] [msglist]", 0,
106 mail_print, msglist_compl },
107 { "q", "quit", "q[uit]", 0,
108 mail_quit, no_compl },
109 { "R", "Reply", "R[eply] [msglist]", EF_SEND,
110 mail_reply, msglist_compl },
111 { "R", "Respond", "R[espond] [msglist]", EF_SEND,
112 mail_reply, msglist_compl },
113 { "r", "reply", "r[eply] [message]", EF_SEND,
114 mail_reply, msglist_compl },
115 { "r", "respond", "r[espond] [message]", EF_SEND,
116 mail_reply, msglist_compl },
117 { "ret", "retain", "ret[ain] [header-field]", 0,
118 mail_retain, no_compl },
119 { "S", "Save", "S[ave] [msglist]", 0,
120 mail_save, msglist_compl },
121 { "s", "save", "s[ave] [[msglist] file]", 0,
122 mail_save, msglist_file_compl },
123 { "sen", "sendheader", "sen[dheader] [[header][: value]]", EF_SEND,
124 mail_sendheader, no_compl },
125 { "se", "set", "se[t] [name[=[string]]...] [name=number...] [noname...]", 0,
126 mail_set, mailvar_set_compl },
127 { "setq", "setq", NULL, EF_HIDDEN,
128 mail_set, no_compl },
129 { "sender", "sen", "sen[der] [header-field...]", 0,
130 mail_sender, no_compl },
131 { "sete", "setenv", "sete[nv] [name[=value]]", 0,
132 mail_setenv, no_compl },
133 { "sh", "shell", "sh[ell] [command]", 0,
134 mail_shell, shell_compl },
135 { "si", "size", "si[ze] [msglist]", 0,
136 mail_size, msglist_compl },
137 { "so", "source", "so[urce] file", 0,
138 mail_source, NULL },
139 { "st", "struct", "st[ruct] [msglist]", 0,
140 mail_struct, NULL },
141 { "su", "summary", "su[mmary]", 0,
142 mail_summary, no_compl },
143 { "T", "Type", "T[ype] [msglist]", 0,
144 mail_print, msglist_compl },
145 { "ta", "tag", "ta[g] [msglist]", 0,
146 mail_tag, msglist_compl },
147 { "to", "top", "to[p] [msglist]", 0,
148 mail_top, msglist_compl },
149 { "tou", "touch", "tou[ch] [msglist]", 0,
150 mail_touch, msglist_compl },
151 { "t", "type", "t[ype] [msglist]", 0,
152 mail_print, msglist_compl },
153 { "una", "unalias", "una[lias] [alias]...", 0,
154 mail_unalias, NULL },
155 { "u", "undelete", "u[ndelete] [msglist]", 0,
156 mail_undelete, msglist_compl },
157 { "unf", "unfold", "unf[old] [header-field]", 0,
158 mail_unfold, no_compl },
159 { "uns", "unset", "uns[et] name...", 0,
160 mail_unset, mailvar_set_compl },
161 { "unt", "untag", "unt[ag] [msglist]", 0,
162 mail_tag, msglist_compl },
163 { "va", "variable", "variable [name...]", 0,
164 mail_variable, mailvar_set_compl },
165 { "ve", "version", "ve[rsion]", 0,
166 mail_version, no_compl },
167 { "v", "visual", "v[isual] [msglist]", 0,
168 mail_visual, msglist_compl },
169 { "wa", "warranty", "wa[rranty]", 0,
170 mail_warranty, no_compl },
171 { "W", "Write", "W[rite] [msglist]", 0,
172 mail_write, msglist_compl },
173 { "w", "write", "w[rite] [[msglist] file]", 0,
174 mail_write, msglist_file_compl },
175 { "x", "xit", "x[it]", 0,
176 mail_exit, no_compl },
177 { "z", "", "z[+|-|. [count]]", 0,
178 mail_z, no_compl },
179 { "?", "?", "? [command...]", 0,
180 mail_help, command_compl },
181 { "!", "", "![command]", 0,
182 mail_shell, shell_compl },
183 { "=", "=", "=", 0,
184 mail_eq, no_compl },
185 { "#", "#", "# comment", 0,
186 NULL, no_compl },
187 { "*", "*", "*", 0,
188 mail_list, no_compl },
189 { "+", "+", "+ [message]", 0,
190 mail_next, msglist_compl },
191 { "|", "|", "| [[msglist] command]", 0,
192 mail_pipe, exec_compl },
193 { "-", "-", "- [message]", 0,
194 mail_previous, msglist_compl },
195 };
196
197
198 const struct mail_command_entry *
mail_find_command(const char * cmd)199 mail_find_command (const char *cmd)
200 {
201 return FIND_IN_TABLE (util_find_entry, mail_command_table, cmd);
202 }
203
204 int
mail_command_help(const char * cmd)205 mail_command_help (const char *cmd)
206 {
207 return FIND_IN_TABLE (util_help, mail_command_table, cmd);
208 }
209
210 void
mail_command_list()211 mail_command_list ()
212 {
213 util_command_list ((void*)mail_command_table,
214 sizeof (mail_command_table) / sizeof (mail_command_table[0]),
215 sizeof (mail_command_table[0]));
216 }
217
218 const struct mail_command *
mail_command_name(int i)219 mail_command_name (int i)
220 {
221 if (i < 0 || i >= sizeof (mail_command_table) / sizeof (mail_command_table[0]))
222 return NULL;
223 return (struct mail_command*) &mail_command_table[i];
224 }
225
226 static const struct mail_escape_entry mail_escape_table[] = {
227 {"!", "!", "![shell-command]", escape_shell },
228 {":", ":", ":[mail-command]", escape_command },
229 {"-", "-", "-[mail-command]", escape_command },
230 {"+", "+", "+name [content-type [encoding]]", escape_attach },
231 {"^", "^", "^N", escape_remove_attachment },
232 {"/", "/", "/", escape_toggle_multipart_type },
233 {"?", "?", "?", escape_help },
234 {"A", "A", "A", escape_sign },
235 {"a", "a", "a", escape_sign },
236 {"b", "b", "b[bcc-list]", escape_bcc },
237 {"c", "c", "c[cc-list]", escape_cc },
238 {"d", "d", "d", escape_deadletter },
239 {"e", "e", "e", escape_editor },
240 {"f", "f", "f[mesg-list]", escape_print },
241 {"F", "F", "F[mesg-list]", escape_print },
242 {"h", "h", "h", escape_headers },
243 {"i", "i", "i[var-name]", escape_insert },
244 {"l", "l", "l", escape_list_attachments },
245 {"m", "m", "m[mesg-list]", escape_quote },
246 {"M", "M", "M[mesg-list]", escape_quote },
247 {"p", "p", "p", escape_type_input },
248 {"r", "<", "r[filename]", escape_read },
249 {"s", "s", "s[string]", escape_subj },
250 {"t", "t", "t[name-list]", escape_to },
251 {"v", "v", "v", escape_visual },
252 {"w", "w", "w[filename]", escape_write },
253 {"x", "x", "x", NULL }, /* Implemented directly in
254 send.c */
255 {"|", "|", "|[shell-command]", escape_pipe },
256 };
257
258 const struct mail_escape_entry *
mail_find_escape(const char * cmd)259 mail_find_escape (const char *cmd)
260 {
261 return FIND_IN_TABLE (util_find_entry, mail_escape_table, cmd);
262 }
263
264 int
mail_escape_help(const char * cmd)265 mail_escape_help (const char *cmd)
266 {
267 return FIND_IN_TABLE (util_help, mail_escape_table, cmd);
268 }
269
270