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