]>
Commit | Line | Data |
---|---|---|
d26530dc JR |
1 | diff -urNp -x '*.orig' mutt-2.0.6.org/Makefile.am mutt-2.0.6/Makefile.am |
2 | --- mutt-2.0.6.org/Makefile.am 2021-03-06 20:06:37.000000000 +0100 | |
3 | +++ mutt-2.0.6/Makefile.am 2021-04-18 19:23:38.363346256 +0200 | |
4 | @@ -36,7 +36,7 @@ mutt_SOURCES = \ | |
5 | main.c mbox.c menu.c mh.c mx.c pager.c parse.c pattern.c \ | |
68667aa0 | 6 | postpone.c query.c recvattach.c recvcmd.c \ |
d26530dc | 7 | rfc822.c rfc1524.c rfc2047.c rfc2231.c rfc3676.c \ |
68667aa0 | 8 | - score.c send.c sendlib.c signal.c sort.c \ |
9 | + score.c send.c sendlib.c signal.c signature.c sort.c \ | |
10 | status.c system.c thread.c charset.c history.c lib.c \ | |
d26530dc JR |
11 | mutt_lisp.c muttlib.c editmsg.c mbyte.c \ |
12 | url.c ascii.c crypt-mod.c crypt-mod.h safe_asprintf.c \ | |
13 | diff -urNp -x '*.orig' mutt-2.0.6.org/OPS mutt-2.0.6/OPS | |
14 | --- mutt-2.0.6.org/OPS 2021-03-06 20:06:37.000000000 +0100 | |
15 | +++ mutt-2.0.6/OPS 2021-04-18 19:23:38.363346256 +0200 | |
18723767 AG |
16 | @@ -213,6 +213,11 @@ |
17 | */ | |
18 | OP_COMPOSE_EDIT_TO N_("edit the TO list") | |
19 | ||
20 | +/* L10N: Help screen description for OP_COMPOSE_SIG | |
21 | + compose menu: <signature-menu> | |
22 | + */ | |
23 | +OP_COMPOSE_SIG N_("choose a signature") | |
24 | + | |
25 | /* L10N: Help screen description for OP_CREATE_MAILBOX | |
26 | browser menu: <create-mailbox> | |
27 | */ | |
28 | @@ -907,6 +912,12 @@ | |
29 | */ | |
30 | OP_NEXT_PAGE N_("move to the next page") | |
31 | ||
32 | +/* L10N: Help screen description for OP_NEXT_SIG | |
33 | + generic menu: <next-signature> | |
34 | + pager menu: <next-signature> | |
35 | + */ | |
36 | +OP_NEXT_SIG N_("move to the next signature") | |
37 | + | |
38 | /* L10N: Help screen description for OP_PAGER_BOTTOM | |
39 | pager menu: <bottom> | |
40 | */ | |
41 | @@ -958,6 +969,12 @@ | |
42 | */ | |
43 | OP_PREV_PAGE N_("move to the previous page") | |
44 | ||
45 | +/* L10N: Help screen description for OP_PREV_SIG | |
46 | + generic menu: <prev-signature> | |
47 | + pager menu: <prev-signature> | |
48 | + */ | |
49 | +OP_PREV_SIG N_("move to the previous signature") | |
50 | + | |
51 | /* L10N: Help screen description for OP_PRINT | |
52 | index menu: <print-message> | |
53 | pager menu: <print-message> | |
54 | @@ -1006,6 +1006,12 @@ | |
55 | */ | |
56 | OP_QUIT N_("save changes to mailbox and quit") | |
57 | ||
58 | +/* L10N: Help screen description for OP_RANDOM_SIG | |
59 | + index menu: <random-sig> | |
60 | + pager menu: <random-sig> | |
61 | +*/ | |
62 | +OP_RANDOM_SIG N_("use random signature") | |
63 | + | |
64 | /* L10N: Help screen description for OP_RECALL_MESSAGE | |
65 | index menu: <recall-message> | |
66 | pager menu: <recall-message> | |
67 | @@ -1055,6 +1072,12 @@ | |
68 | */ | |
69 | OP_SEARCH_OPPOSITE N_("search for next match in opposite direction") | |
70 | ||
71 | +/* L10N: Help screen description for OP_SIG_SEARCH | |
72 | + generic menu: <search-sig> | |
73 | + pager menu: <search-sig> | |
74 | + */ | |
75 | +OP_SIG_SEARCH N_("search signatures matching a pattern") | |
76 | + | |
77 | /* L10N: Help screen description for OP_SEARCH_TOGGLE | |
78 | pager menu: <search-toggle> | |
79 | */ | |
d26530dc JR |
80 | diff -urNp -x '*.orig' mutt-2.0.6.org/PATCHES mutt-2.0.6/PATCHES |
81 | --- mutt-2.0.6.org/PATCHES 2021-04-18 19:23:38.230011162 +0200 | |
82 | +++ mutt-2.0.6/PATCHES 2021-04-18 19:23:38.366679633 +0200 | |
83 | @@ -1 +1,2 @@ | |
84 | vvv.quote | |
85 | +patch-1.3.27.cd.signatures_menu.2.1 | |
86 | diff -urNp -x '*.orig' mutt-2.0.6.org/compose.c mutt-2.0.6/compose.c | |
87 | --- mutt-2.0.6.org/compose.c 2020-12-01 04:05:21.000000000 +0100 | |
88 | +++ mutt-2.0.6/compose.c 2021-04-18 19:23:38.363346256 +0200 | |
89 | @@ -1747,6 +1747,11 @@ int mutt_compose_menu (SEND_CONTEXT *sct | |
90 | /* no send2hook, since this doesn't modify the message */ | |
68667aa0 | 91 | break; |
92 | ||
93 | + case OP_COMPOSE_SIG: | |
94 | + mutt_signature(msg->content->filename); | |
68667aa0 | 95 | + mutt_update_encoding (msg->content); |
96 | + break; | |
97 | + | |
98 | case OP_PIPE: | |
99 | case OP_FILTER: | |
d26530dc JR |
100 | CHECK_COUNT; |
101 | diff -urNp -x '*.orig' mutt-2.0.6.org/doc/manual.xml.head mutt-2.0.6/doc/manual.xml.head | |
102 | --- mutt-2.0.6.org/doc/manual.xml.head 2021-03-06 20:06:37.000000000 +0100 | |
103 | +++ mutt-2.0.6/doc/manual.xml.head 2021-04-18 19:23:38.363346256 +0200 | |
104 | @@ -525,6 +525,7 @@ linkend="tab-keys-nav-page"/> for page-b | |
105 | </tbody> | |
106 | </tgroup> | |
107 | </table> | |
68667aa0 | 108 | +ESC s signature-menu select a signature and append it to your mail |
d26530dc JR |
109 | |
110 | </sect1> | |
111 | ||
112 | diff -urNp -x '*.orig' mutt-2.0.6.org/functions.h mutt-2.0.6/functions.h | |
113 | --- mutt-2.0.6.org/functions.h 2021-03-06 20:06:37.000000000 +0100 | |
114 | +++ mutt-2.0.6/functions.h 2021-04-18 19:23:38.363346256 +0200 | |
115 | @@ -308,6 +308,7 @@ const struct binding_t OpPager[] = { /* | |
116 | ||
117 | { "what-key", OP_WHAT_KEY, NULL }, | |
118 | { "check-stats", OP_CHECK_STATS, NULL }, | |
68667aa0 | 119 | + { "signature-menu", OP_COMPOSE_SIG, "\033s" }, |
120 | ||
d26530dc JR |
121 | #ifdef USE_SIDEBAR |
122 | { "sidebar-first", OP_SIDEBAR_FIRST, NULL }, | |
123 | @@ -458,6 +459,19 @@ const struct binding_t OpQuery[] = { /* | |
124 | { NULL, 0, NULL } | |
125 | }; | |
126 | ||
68667aa0 | 127 | +/* Signature Menu */ |
128 | +struct binding_t OpSig[] = { | |
129 | + { "next-sig", OP_NEXT_SIG, "j" }, | |
130 | + { "previous-sig", OP_PREV_SIG, "k" }, | |
131 | + { "random-sig", OP_RANDOM_SIG, "r" }, | |
132 | + { NULL, 0, NULL } | |
133 | +}; | |
134 | + | |
135 | +struct binding_t OpSigDir[] = { | |
136 | + { "search-sig", OP_SIG_SEARCH, "/" }, | |
d26530dc JR |
137 | + { NULL, 0, NULL } |
138 | +}; | |
139 | + | |
140 | const struct binding_t OpEditor[] = { /* map: editor */ | |
141 | { "bol", OP_EDITOR_BOL, "\001" }, | |
142 | { "backward-char", OP_EDITOR_BACKWARD_CHAR, "\002" }, | |
143 | diff -urNp -x '*.orig' mutt-2.0.6.org/globals.h mutt-2.0.6/globals.h | |
144 | --- mutt-2.0.6.org/globals.h 2021-04-18 19:23:38.230011162 +0200 | |
145 | +++ mutt-2.0.6/globals.h 2021-04-18 19:23:38.363346256 +0200 | |
146 | @@ -145,6 +145,7 @@ WHERE char *SidebarFormat; | |
147 | WHERE char *SidebarIndentString; | |
148 | #endif | |
68667aa0 | 149 | WHERE char *Signature; |
150 | +WHERE char *SigDirectory; | |
151 | WHERE char *SimpleSearch; | |
d26530dc JR |
152 | #if USE_SMTP |
153 | WHERE char *SmtpAuthenticators; | |
154 | diff -urNp -x '*.orig' mutt-2.0.6.org/init.h mutt-2.0.6/init.h | |
155 | --- mutt-2.0.6.org/init.h 2021-04-18 19:23:38.230011162 +0200 | |
156 | +++ mutt-2.0.6/init.h 2021-04-18 19:23:38.363346256 +0200 | |
157 | @@ -1953,6 +1953,14 @@ struct option_t MuttVars[] = { | |
158 | ** automatically generated with \fI<mark-message>a\fP will be composed | |
159 | ** from this prefix and the letter \fIa\fP. | |
68667aa0 | 160 | */ |
8d013520 | 161 | + { "signatures_directory", DT_PATH, R_NONE, {.p=&SigDirectory}, {.p=""} }, |
68667aa0 | 162 | + /* |
163 | + ** .pp | |
164 | + ** Specifies the path where your signatures are located. In the files of | |
165 | + ** this directory, the signatures are separated by blank lines and/or | |
166 | + ** sig_dashes (``-- ''). | |
167 | + ** You can choose between these signatures from the compose menu. | |
168 | + */ | |
d26530dc | 169 | { "mark_old", DT_BOOL, R_BOTH, {.l=OPTMARKOLD}, {.l=1} }, |
68667aa0 | 170 | /* |
d26530dc JR |
171 | ** .pp |
172 | diff -urNp -x '*.orig' mutt-2.0.6.org/keymap.c mutt-2.0.6/keymap.c | |
173 | --- mutt-2.0.6.org/keymap.c 2021-03-06 20:06:37.000000000 +0100 | |
174 | +++ mutt-2.0.6/keymap.c 2021-04-18 19:23:38.366679633 +0200 | |
175 | @@ -49,6 +49,8 @@ const struct mapping_t Menus[] = { | |
176 | { "pager", MENU_PAGER }, | |
177 | { "postpone", MENU_POST }, | |
178 | { "pgp", MENU_PGP }, | |
68667aa0 | 179 | + { "signature", MENU_SIG }, |
180 | + { "sig_directory", MENU_SIG_DIR }, | |
d26530dc JR |
181 | { "smime", MENU_SMIME }, |
182 | #ifdef CRYPT_BACKEND_GPGME | |
183 | { "key_select_pgp", MENU_KEY_SELECT_PGP }, | |
184 | @@ -749,6 +751,8 @@ void km_init (void) | |
185 | create_bindings (OpPost, MENU_POST); | |
68667aa0 | 186 | create_bindings (OpQuery, MENU_QUERY); |
187 | create_bindings (OpAlias, MENU_ALIAS); | |
188 | + create_bindings (OpSig, MENU_SIG); | |
189 | + create_bindings (OpSigDir, MENU_SIG_DIR); | |
190 | ||
191 | ||
d26530dc JR |
192 | if ((WithCrypto & APPLICATION_PGP)) |
193 | @@ -851,6 +855,9 @@ void km_init (void) | |
194 | km_bindkey ("<enter>", MENU_ATTACH, OP_VIEW_ATTACH); | |
68667aa0 | 195 | km_bindkey ("<enter>", MENU_COMPOSE, OP_VIEW_ATTACH); |
196 | ||
197 | + km_bindkey ("<up>", MENU_SIG, OP_PREV_SIG); | |
198 | + km_bindkey ("<down>", MENU_SIG, OP_NEXT_SIG); | |
199 | + | |
200 | /* edit-to (default "t") hides generic tag-entry in Compose menu | |
201 | This will bind tag-entry to "T" in the Compose menu */ | |
d26530dc JR |
202 | km_bindkey ("T", MENU_COMPOSE, OP_TAG); |
203 | @@ -1015,6 +1022,10 @@ const struct binding_t *km_get_table (in | |
68667aa0 | 204 | return OpQuery; |
18723767 AG |
205 | case MENU_LIST: |
206 | return OpList; | |
68667aa0 | 207 | + case MENU_SIG: |
208 | + return OpSig; | |
209 | + case MENU_SIG_DIR: | |
210 | + return OpSigDir; | |
211 | ||
d26530dc JR |
212 | case MENU_PGP: |
213 | return (WithCrypto & APPLICATION_PGP)? OpPgp:NULL; | |
214 | diff -urNp -x '*.orig' mutt-2.0.6.org/keymap.h mutt-2.0.6/keymap.h | |
215 | --- mutt-2.0.6.org/keymap.h 2021-03-06 20:06:37.000000000 +0100 | |
216 | +++ mutt-2.0.6/keymap.h 2021-04-18 19:23:38.366679633 +0200 | |
217 | @@ -63,6 +63,8 @@ enum | |
218 | MENU_PAGER, | |
68667aa0 | 219 | MENU_POST, |
220 | MENU_QUERY, | |
221 | + MENU_SIG, | |
222 | + MENU_SIG_DIR, | |
223 | ||
d26530dc JR |
224 | |
225 | MENU_PGP, | |
226 | @@ -105,6 +107,8 @@ const struct binding_t *km_get_table (in | |
227 | extern const struct binding_t OpGeneric[]; | |
228 | extern const struct binding_t OpPost[]; | |
229 | extern const struct binding_t OpMain[]; | |
68667aa0 | 230 | +extern struct binding_t OpSig[]; |
231 | +extern struct binding_t OpSigDir[]; | |
d26530dc JR |
232 | extern const struct binding_t OpAttach[]; |
233 | extern const struct binding_t OpPager[]; | |
234 | extern const struct binding_t OpCompose[]; | |
235 | diff -urNp -x '*.orig' mutt-2.0.6.org/menu.c mutt-2.0.6/menu.c | |
236 | --- mutt-2.0.6.org/menu.c 2021-04-18 19:23:38.230011162 +0200 | |
237 | +++ mutt-2.0.6/menu.c 2021-04-18 19:23:38.366679633 +0200 | |
238 | @@ -683,7 +683,7 @@ void menu_current_bottom (MUTTMENU *menu | |
239 | mutt_error _("No entries."); | |
240 | } | |
241 | ||
242 | -static void menu_next_entry (MUTTMENU *menu) | |
243 | +void menu_next_entry (MUTTMENU *menu) | |
244 | { | |
245 | if (menu->current < menu->max - 1) | |
246 | { | |
247 | @@ -694,7 +694,7 @@ static void menu_next_entry (MUTTMENU *m | |
248 | mutt_error _("You are on the last entry."); | |
249 | } | |
68667aa0 | 250 | |
d26530dc JR |
251 | -static void menu_prev_entry (MUTTMENU *menu) |
252 | +void menu_prev_entry (MUTTMENU *menu) | |
253 | { | |
254 | if (menu->current) | |
255 | { | |
256 | diff -urNp -x '*.orig' mutt-2.0.6.org/protos.h mutt-2.0.6/protos.h | |
257 | --- mutt-2.0.6.org/protos.h 2021-03-06 20:06:37.000000000 +0100 | |
258 | +++ mutt-2.0.6/protos.h 2021-04-18 19:23:38.366679633 +0200 | |
259 | @@ -224,6 +224,7 @@ void mutt_free_body (BODY **); | |
18723767 | 260 | void mutt_free_body (BODY **); |
d26530dc JR |
261 | void mutt_free_enter_state (ENTER_STATE **); |
262 | void mutt_free_envelope (ENVELOPE **); | |
68667aa0 | 263 | +void mutt_signature (char *); |
d26530dc JR |
264 | void mutt_free_header (HEADER **); |
265 | void mutt_free_parameter (PARAMETER **); | |
266 | void mutt_free_regexp (REGEXP **); | |
267 | diff -urNp -x '*.orig' mutt-2.0.6.org/signature.c mutt-2.0.6/signature.c | |
268 | --- mutt-2.0.6.org/signature.c 1970-01-01 01:00:00.000000000 +0100 | |
269 | +++ mutt-2.0.6/signature.c 2021-04-18 19:23:38.366679633 +0200 | |
b324a978 | 270 | @@ -0,0 +1,499 @@ |
68667aa0 | 271 | +/* |
272 | + * Copyright (C) 2001 Cedric Duval <cedricduval@free.fr> | |
273 | + * | |
274 | + * This program is free software; you can redistribute it and/or modify | |
275 | + * it under the terms of the GNU General Public License as published by | |
276 | + * the Free Software Foundation; either version 2 of the License, or | |
277 | + * (at your option) any later version. | |
278 | + * | |
279 | + * This program is distributed in the hope that it will be useful, | |
280 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
281 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
282 | + * GNU General Public License for more details. | |
283 | + * | |
284 | + * You should have received a copy of the GNU General Public License | |
285 | + * along with this program; if not, write to the Free Software | |
286 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. | |
287 | + */ | |
288 | + | |
68eeb855 | 289 | +#if HAVE_CONFIG_H |
290 | +# include "config.h" | |
291 | +#endif | |
292 | + | |
68667aa0 | 293 | +#include "mutt.h" |
294 | +#include "mutt_menu.h" | |
295 | +#include "mapping.h" | |
296 | +#include "mutt_curses.h" | |
297 | + | |
298 | +#include <stdio.h> | |
299 | +#include <string.h> | |
300 | +#include <stdlib.h> | |
301 | +#include <dirent.h> | |
302 | +#include <sys/stat.h> | |
303 | + | |
304 | +#define SIG_DISPLAY_LINES 4 | |
305 | +#define SEPARATOR(x) ((*x == '\n') || (mutt_strcmp (x, "-- \n") == 0)) | |
306 | +#define SIG_ADD_LINE(x,y) mutt_add_list (x, strtok (y, "\n")) | |
307 | + | |
308 | +typedef struct sig_list | |
309 | +{ | |
310 | + struct sig_list *next; | |
311 | + LIST *sig; | |
312 | +} SIG_LIST; | |
313 | + | |
314 | +typedef struct sig_dir | |
315 | +{ | |
316 | + struct sig_dir *next; | |
317 | + char *name; | |
318 | +} SIG_DIR; | |
319 | + | |
320 | +typedef LIST * ENTRY; | |
321 | + | |
322 | +typedef struct entry_dir | |
323 | +{ | |
324 | + int tagged; | |
325 | + SIG_DIR *data; | |
326 | +} ENTRY_DIR; | |
327 | + | |
328 | +static struct mapping_t SigHelp[] = { | |
329 | + { N_("Exit"), OP_EXIT }, | |
330 | + { N_("Search"), OP_SEARCH }, | |
331 | + { N_("Random"), OP_RANDOM_SIG }, | |
332 | + { N_("Help"), OP_HELP }, | |
333 | + { NULL } | |
334 | +}; | |
335 | + | |
336 | +static struct mapping_t SigDirHelp[] = { | |
337 | + { N_("Exit"), OP_EXIT }, | |
338 | + { N_("Search signature"), OP_SIG_SEARCH }, | |
339 | + { N_("Help"), OP_HELP }, | |
340 | + { NULL } | |
341 | +}; | |
342 | + | |
343 | +void menu_next_entry (MUTTMENU *menu); | |
344 | +void menu_prev_entry (MUTTMENU *menu); | |
345 | + | |
346 | + | |
347 | +static int sig_match (LIST *s, regex_t *re) | |
348 | +{ | |
349 | + while (s) | |
350 | + { | |
351 | + if (regexec (re, s->data, (size_t)0, NULL, (int)0) == 0) | |
352 | + return 1; | |
353 | + s = s->next; | |
354 | + } | |
355 | + return 0; | |
356 | +} | |
357 | + | |
358 | +static void read_sig_file (char *name, SIG_LIST **begin, regex_t *re) | |
359 | +{ | |
360 | + FILE *fp; | |
361 | + char buf[STRING]; | |
362 | + LIST *sig = NULL; | |
363 | + SIG_LIST *first, *cur; | |
364 | + int append = 0; | |
365 | + | |
366 | + if (!(fp = safe_fopen (name, "r"))) | |
367 | + { | |
368 | + mutt_error (_("Can't open signature file %s"), name); | |
369 | + return; | |
370 | + } | |
371 | + | |
372 | + for (first = *begin; first && first->next; first = first->next, append++) | |
373 | + ; /* append results to an existing list */ | |
374 | + cur = first; | |
375 | + | |
376 | + while (fgets (buf, sizeof (buf), fp)) | |
377 | + { | |
378 | + if (buf[0] && !SEPARATOR (buf)) | |
379 | + { | |
380 | + sig = SIG_ADD_LINE (NULL, buf); | |
381 | + | |
382 | + while (fgets (buf, sizeof (buf), fp) && buf[0] && !SEPARATOR (buf)) | |
383 | + SIG_ADD_LINE (sig, buf); | |
384 | + | |
385 | + if (re && !sig_match (sig, re)) | |
386 | + mutt_free_list (&sig); /* previous sig didn't match the regexp */ | |
387 | + else | |
388 | + { | |
389 | + /* add signature */ | |
390 | + if (first == NULL) | |
391 | + first = cur = (SIG_LIST *) safe_calloc (1, sizeof (SIG_LIST)); | |
392 | + else | |
393 | + { | |
394 | + cur->next = (SIG_LIST *) safe_calloc (1, sizeof (SIG_LIST)); | |
395 | + cur = cur->next; | |
396 | + } | |
397 | + | |
398 | + cur->sig = sig; | |
399 | + cur->next = NULL; | |
400 | + } | |
401 | + } | |
402 | + } | |
403 | + | |
404 | + if (!append) | |
405 | + *begin = first; | |
406 | + | |
407 | + safe_fclose (&fp); | |
408 | +} | |
409 | + | |
410 | +static void sig_make_entry (char *s, size_t slen, MUTTMENU *menu, int num) | |
411 | +{ | |
412 | + ENTRY *table = (ENTRY *) menu->data; | |
413 | + | |
414 | + snprintf (s, slen, "%3d %s", | |
415 | + num + 1, | |
416 | + table[num]->data); | |
417 | +} | |
418 | + | |
419 | +static int sig_menu_search (MUTTMENU *menu, regex_t *re, int num) | |
420 | +{ | |
421 | + return (sig_match (((ENTRY *)menu->data)[num], re) ? 0 : REG_NOMATCH); | |
422 | +} | |
423 | + | |
424 | +static void draw_sig_frame (LIST *s) | |
425 | +{ | |
426 | + int i; | |
427 | + | |
428 | + for (i = 1; i <= SIG_DISPLAY_LINES; i++) | |
429 | + { | |
430 | + if (s) | |
431 | + { | |
432 | + mvaddstr (i, 0, s->data); | |
433 | + s = s->next; | |
434 | + } | |
435 | + else | |
436 | + move (i, 0); | |
437 | + | |
438 | + clrtoeol (); | |
439 | + } | |
440 | + | |
441 | + SETCOLOR (MT_COLOR_STATUS); | |
442 | + mvaddstr (SIG_DISPLAY_LINES + 1, 0, _("-- Signature")); | |
c59ea3a3 | 443 | + SETCOLOR (MT_COLOR_STATUS); |
68667aa0 | 444 | + clrtoeol (); |
445 | + | |
c59ea3a3 | 446 | + NORMAL_COLOR; |
68667aa0 | 447 | +} |
448 | + | |
449 | +static void free_sig_list (SIG_LIST **sigs) | |
450 | +{ | |
451 | + SIG_LIST *cur; | |
452 | + | |
453 | + while (*sigs) | |
454 | + { | |
455 | + cur = *sigs; | |
456 | + *sigs = (*sigs)->next; | |
457 | + mutt_free_list (&cur->sig); | |
458 | + safe_free ((void **)&cur); | |
459 | + } | |
460 | +} | |
461 | + | |
462 | +static void append_signature (char *msg_file, LIST *s) | |
463 | +{ | |
464 | + FILE *fp; | |
465 | + | |
466 | + if ((fp = safe_fopen (msg_file, "a")) == 0) | |
467 | + mutt_perror (msg_file); | |
468 | + else | |
469 | + { | |
470 | + if (option (OPTSIGDASHES)) | |
471 | + fputs ("\n-- \n", fp); | |
472 | + | |
473 | + for (; s; s = s->next) | |
474 | + fprintf (fp, "%s\n", s->data); | |
475 | + | |
476 | + mutt_message (_("Signature appended to your mail")); | |
477 | + safe_fclose (&fp); | |
478 | + } | |
479 | +} | |
480 | + | |
481 | +static LIST *sig_list_menu (char *file, SIG_LIST *list) | |
482 | +{ | |
483 | + LIST *result = NULL; | |
484 | + SIG_LIST *sigl; | |
485 | + MUTTMENU *menu; | |
486 | + ENTRY *SigTable; | |
487 | + char helpstr[SHORT_STRING], title[SHORT_STRING]; | |
488 | + int i, done = 0; | |
489 | + | |
490 | + snprintf (title, sizeof (title), _("Signature : %s"), file); | |
491 | + | |
b3471c65 | 492 | + menu = mutt_new_menu (MENU_SIG); |
68667aa0 | 493 | + menu->make_entry = sig_make_entry; |
494 | + menu->tag = NULL; | |
495 | + menu->search = sig_menu_search; | |
68667aa0 | 496 | + menu->title = title; |
497 | + menu->help = mutt_compile_help (helpstr, sizeof (helpstr), | |
498 | + MENU_SIG, SigHelp); | |
499 | + menu->offset = SIG_DISPLAY_LINES + 2; | |
500 | + menu->pagelen = LINES - SIG_DISPLAY_LINES - 4; | |
501 | + | |
502 | + for (sigl = list; sigl; sigl = sigl->next) | |
503 | + menu->max++; | |
504 | + | |
505 | + menu->data = SigTable = (ENTRY *) safe_calloc (menu->max, sizeof (ENTRY)); | |
506 | + | |
507 | + for (i = 0, sigl = list; sigl; i++, sigl = sigl->next) | |
508 | + SigTable[i] = sigl->sig; | |
509 | + | |
510 | + while (!done) | |
511 | + { | |
512 | + switch (mutt_menuLoop (menu)) | |
513 | + { | |
514 | + case OP_GENERIC_SELECT_ENTRY: | |
515 | + result = SigTable[menu->current]; | |
516 | + done = 1; | |
517 | + break; | |
518 | + | |
519 | + case OP_PREV_SIG: | |
520 | + menu_prev_entry (menu); | |
521 | + draw_sig_frame (SigTable[menu->current]); | |
522 | + break; | |
523 | + | |
524 | + case OP_NEXT_SIG: | |
525 | + menu_next_entry (menu); | |
526 | + draw_sig_frame (SigTable[menu->current]); | |
527 | + break; | |
528 | + | |
529 | + case OP_REDRAW: | |
530 | + menu->offset = SIG_DISPLAY_LINES + 2; | |
531 | + menu->pagelen = LINES - SIG_DISPLAY_LINES - 4; | |
532 | + draw_sig_frame (SigTable[menu->current]); | |
533 | + break; | |
534 | + | |
535 | + case OP_RANDOM_SIG: | |
536 | + menu->current = LRAND () % menu->max; | |
537 | + draw_sig_frame (SigTable[menu->current]); | |
538 | + menu->redraw |= REDRAW_MOTION; | |
539 | + break; | |
540 | + | |
541 | + case OP_EXIT: | |
68667aa0 | 542 | + done = 1; |
543 | + break; | |
544 | + } | |
545 | + } | |
546 | + | |
547 | + mutt_menuDestroy (&menu); | |
548 | + safe_free ((void **)&SigTable); | |
549 | + return result; | |
550 | +} | |
551 | + | |
b3471c65 JR |
552 | +extern char* SearchBuffers[MENU_MAX]; |
553 | + | |
68667aa0 | 554 | +static SIG_LIST *sig_search_filter (MUTTMENU *menu, char *path) |
555 | +{ | |
556 | + regex_t re; | |
557 | + char buf[STRING]; | |
558 | + SIG_LIST *result = NULL; | |
559 | + int i; | |
eb755509 JR |
560 | + char* searchBuf = menu->menu >= 0 && menu->menu < MENU_MAX ? |
561 | + SearchBuffers[menu->menu] : NULL; | |
68667aa0 | 562 | + |
eb755509 | 563 | + snprintf (buf, sizeof(buf), searchBuf ? searchBuf : ""); |
68667aa0 | 564 | + if (mutt_get_field (_("Search for: "), buf, |
b324a978 | 565 | + sizeof (buf), MUTT_CLEAR) != 0 || !buf[0]) |
68667aa0 | 566 | + return (NULL); |
eb755509 JR |
567 | + if (menu->menu >= 0 && menu->menu < MENU_MAX) |
568 | + { | |
569 | + mutt_str_replace (&SearchBuffers[menu->menu], buf); | |
570 | + searchBuf = SearchBuffers[menu->menu]; | |
571 | + } | |
68667aa0 | 572 | + |
eb755509 JR |
573 | + if ((i = regcomp (&re, searchBuf, REG_NOSUB | REG_EXTENDED | REG_WORDS |
574 | + | mutt_which_case (searchBuf))) != 0) | |
68667aa0 | 575 | + { |
576 | + regerror (i, &re, buf, sizeof (buf)); | |
577 | + regfree (&re); | |
578 | + mutt_error ("%s", buf); | |
579 | + return (NULL); | |
580 | + } | |
581 | + | |
582 | + /* building list of sigs matching the regexp */ | |
583 | + for (i = 0; i < menu->max; i++) | |
584 | + { | |
585 | + /* search in every file if none is tagged */ | |
586 | + if (((ENTRY_DIR *) menu->data)[i].tagged || (menu->tagged == 0)) | |
587 | + { | |
588 | + snprintf (buf, sizeof (buf), "%s/%s", path, | |
589 | + ((ENTRY_DIR *) menu->data)[i].data->name); | |
590 | + read_sig_file (buf, &result, &re); | |
591 | + } | |
592 | + } | |
593 | + | |
594 | + regfree (&re); | |
595 | + if (!result) | |
596 | + mutt_error (_("Not found.")); | |
597 | + | |
598 | + return (result); | |
599 | +} | |
600 | + | |
601 | +/* returns the list of files in this directory */ | |
602 | +static SIG_DIR *sig_directory (char *path) | |
603 | +{ | |
604 | + DIR *dp; | |
605 | + struct dirent *de; | |
606 | + struct stat s; | |
607 | + SIG_DIR *first = NULL, *cur = NULL; | |
608 | + char file[_POSIX_PATH_MAX + SHORT_STRING]; | |
609 | + | |
610 | + if ((dp = opendir (path)) == NULL) | |
611 | + { | |
612 | + mutt_perror (path); | |
613 | + return (NULL); | |
614 | + } | |
615 | + | |
616 | + while ((de = readdir (dp))) | |
617 | + { | |
618 | + if ((de->d_name)[0] == '.') /* no hidden files */ | |
619 | + continue; | |
620 | + | |
621 | + snprintf (file, sizeof (file), "%s/%s", path, de->d_name); | |
622 | + if (lstat (file, &s) == -1) | |
623 | + continue; | |
624 | + | |
625 | + if ((!S_ISREG (s.st_mode)) && (!S_ISLNK (s.st_mode))) | |
626 | + continue; | |
627 | + | |
628 | + if (first == NULL) | |
629 | + cur = first = safe_calloc (1, sizeof (SIG_DIR)); | |
630 | + else | |
631 | + { | |
632 | + cur->next = safe_calloc (1, sizeof (SIG_DIR)); | |
633 | + cur = cur->next; | |
634 | + } | |
635 | + cur->name = safe_strdup (de->d_name); | |
636 | + cur->next = NULL; | |
637 | + } | |
638 | + closedir (dp); | |
639 | + return first; | |
640 | +} | |
641 | + | |
642 | +static void sig_dir_make_entry (char *s, size_t slen, MUTTMENU *menu, int num) | |
643 | +{ | |
644 | + ENTRY_DIR *table = (ENTRY_DIR *) menu->data; | |
645 | + | |
646 | + snprintf (s, slen, "%c %3d - %s", | |
647 | + table[num].tagged ? '*' : ' ', | |
648 | + num + 1, | |
649 | + table[num].data->name); | |
650 | +} | |
651 | + | |
652 | +static int sig_dir_tag (MUTTMENU *menu, int n, int m) | |
653 | +{ | |
654 | + ENTRY_DIR *cur = &((ENTRY_DIR *) menu->data)[n]; | |
655 | + int ot = cur->tagged; | |
656 | + | |
657 | + cur->tagged = m >= 0 ? m : !cur->tagged; | |
658 | + return cur->tagged - ot; | |
659 | + | |
660 | +} | |
661 | + | |
662 | +static int sig_dir_sort (const void *a, const void *b) | |
663 | +{ | |
664 | + ENTRY_DIR *pa = (ENTRY_DIR *) a; | |
665 | + ENTRY_DIR *pb = (ENTRY_DIR *) b; | |
666 | + | |
667 | + return (mutt_strcmp (pa->data->name, pb->data->name)); | |
668 | +} | |
669 | + | |
670 | +static int sig_dir_menu (char *path, char *msg_file) | |
671 | +{ | |
672 | + MUTTMENU *menu; | |
673 | + SIG_LIST *sigl; | |
674 | + LIST *result = NULL; | |
675 | + ENTRY_DIR *FileTable; | |
676 | + SIG_DIR *list, *files; | |
677 | + char buf[STRING], helpstr[SHORT_STRING], title[SHORT_STRING]; | |
678 | + int i, done = 0; | |
679 | + | |
680 | + if ((list = sig_directory (path)) == NULL) | |
681 | + return -1; | |
682 | + | |
683 | + snprintf (title, sizeof (title), "Signature directory : %s", path); | |
684 | + | |
b3471c65 | 685 | + menu = mutt_new_menu (MENU_SIG_DIR); |
68667aa0 | 686 | + menu->make_entry = sig_dir_make_entry; |
687 | + menu->search = NULL; /* search within files with sig_search_filter() */ | |
688 | + menu->tag = sig_dir_tag; | |
68667aa0 | 689 | + menu->title = title; |
690 | + menu->help = mutt_compile_help (helpstr, sizeof (helpstr), | |
691 | + MENU_SIG_DIR, SigDirHelp); | |
692 | + | |
693 | + for (files = list; files; files = files->next) | |
694 | + menu->max++; | |
695 | + | |
696 | + menu->data = FileTable = (ENTRY_DIR *) safe_calloc (menu->max, | |
697 | + sizeof (ENTRY_DIR)); | |
698 | + | |
699 | + for (i = 0, files = list; files; i++, files = files->next) | |
700 | + FileTable[i].data = files; | |
701 | + | |
702 | + qsort (FileTable, menu->max, sizeof (ENTRY_DIR), sig_dir_sort); | |
703 | + | |
704 | + while (!done) | |
705 | + { | |
706 | + switch (mutt_menuLoop (menu)) | |
707 | + { | |
708 | + case OP_SIG_SEARCH: | |
709 | + sigl = sig_search_filter (menu, path); | |
710 | + | |
711 | + if (sigl) | |
712 | + { | |
713 | + if ((result = sig_list_menu (_("query results"), sigl)) != NULL) | |
714 | + { | |
715 | + append_signature (msg_file, result); | |
716 | + done = 1; | |
717 | + } | |
718 | + | |
68667aa0 | 719 | + free_sig_list (&sigl); |
720 | + } | |
721 | + break; | |
722 | + | |
723 | + case OP_GENERIC_SELECT_ENTRY: | |
724 | + snprintf (buf, sizeof (buf), "%s/%s", path, | |
725 | + FileTable[menu->current].data->name); | |
726 | + sigl = NULL; | |
727 | + read_sig_file (buf, &sigl, NULL); | |
728 | + | |
729 | + if (sigl) | |
730 | + { | |
731 | + if ((result = sig_list_menu (buf, sigl)) != NULL) | |
732 | + { | |
733 | + append_signature (msg_file, result); | |
734 | + done = 1; | |
735 | + } | |
736 | + | |
68667aa0 | 737 | + free_sig_list (&sigl); |
738 | + } | |
739 | + break; | |
740 | + | |
741 | + case OP_EXIT: | |
742 | + done = 1; | |
743 | + break; | |
744 | + } | |
745 | + } | |
746 | + | |
747 | + while (list) | |
748 | + { | |
749 | + safe_free ((void **)&list->name); | |
750 | + files = list; | |
751 | + list = list->next; | |
752 | + safe_free ((void **)&files); | |
753 | + } | |
754 | + safe_free ((void **)&FileTable); | |
755 | + mutt_menuDestroy (&menu); | |
756 | + return 0; | |
757 | +} | |
758 | + | |
759 | +void mutt_signature (char *msg_file) | |
760 | +{ | |
761 | + if (!SigDirectory) | |
762 | + { | |
763 | + mutt_error (_("variable 'signatures_directory' is unset")); | |
764 | + return; | |
765 | + } | |
766 | + | |
767 | + if (sig_dir_menu (SigDirectory, msg_file) == -1) | |
768 | + mutt_error (_("%s: no files in this directory"), SigDirectory); | |
68667aa0 | 769 | +} |