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