- rediff patches
[packages/mutt.git] / mutt-cd.signatures_menu.patch
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 \
6         postpone.c query.c recvattach.c recvcmd.c \
7         rfc822.c rfc1524.c rfc2047.c rfc2231.c rfc3676.c \
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 \
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
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"
20 +OP_COMPOSE_SIG "choose a signature"
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"
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"
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"
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"
38  OP_PURGE_MESSAGE "delete the current entry, bypassing the trash folder"
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"
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"
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"
53  OP_TAG "tag the current entry"
54 diff -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
60 diff -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 */
65         break;
66  
67 +      case OP_COMPOSE_SIG:
68 +       mutt_signature(msg->content->filename);
69 +       mutt_update_encoding (msg->content);
70 +       break;
71 +
72        case OP_PIPE:
73        case OP_FILTER:
74          CHECK_COUNT;
75 diff -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>
82 +ESC s  signature-menu          select a signature and append it to your mail
83  
84  </sect1>
85  
86 diff -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 },
93 +  { "signature-menu",  OP_COMPOSE_SIG,                 "\033s" },
94  
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  
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,          "/" },
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" },
117 diff -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
123  WHERE char *Signature;
124 +WHERE char *SigDirectory;
125  WHERE char *SimpleSearch;
126  #if USE_SMTP
127  WHERE char *SmtpAuthenticators;
128 diff -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.
134    */
135 +  { "signatures_directory",    DT_PATH, R_NONE, {.p=&SigDirectory}, {.p=""} },
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 +  */
143    { "mark_old",                DT_BOOL, R_BOTH, {.l=OPTMARKOLD}, {.l=1} },
144    /*
145    ** .pp
146 diff -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 },
153 + { "signature",        MENU_SIG },
154 + { "sig_directory",    MENU_SIG_DIR },
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);
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  
166    if ((WithCrypto & APPLICATION_PGP))
167 @@ -851,6 +855,9 @@ void km_init (void)
168    km_bindkey ("<enter>", MENU_ATTACH, OP_VIEW_ATTACH);
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 */
176    km_bindkey ("T", MENU_COMPOSE, OP_TAG);
177 @@ -1015,6 +1022,10 @@ const struct binding_t *km_get_table (in
178        return OpEditor;
179      case MENU_QUERY:
180        return OpQuery;
181 +    case MENU_SIG:
182 +      return OpSig;
183 +    case MENU_SIG_DIR:
184 +      return OpSigDir;
185  
186      case MENU_PGP:
187        return (WithCrypto & APPLICATION_PGP)? OpPgp:NULL;
188 diff -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,
193    MENU_POST,
194    MENU_QUERY,
195 +  MENU_SIG,
196 +  MENU_SIG_DIR,
197  
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[];
204 +extern struct binding_t OpSig[];
205 +extern struct binding_t OpSigDir[];
206  extern const struct binding_t OpAttach[];
207  extern const struct binding_t OpPager[];
208  extern const struct binding_t OpCompose[];
209 diff -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  }
224  
225 -static void menu_prev_entry (MUTTMENU *menu)
226 +void menu_prev_entry (MUTTMENU *menu)
227  {
228    if (menu->current)
229    {
230 diff -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 **);
237 +void mutt_signature (char *);
238  void mutt_free_header (HEADER **);
239  void mutt_free_parameter (PARAMETER **);
240  void mutt_free_regexp (REGEXP **);
241 diff -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
244 @@ -0,0 +1,499 @@
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 +
263 +#if HAVE_CONFIG_H
264 +# include "config.h"
265 +#endif
266 +
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"));
417 +  SETCOLOR (MT_COLOR_STATUS);
418 +  clrtoeol ();
419 +
420 +  NORMAL_COLOR;
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 +
466 +  menu = mutt_new_menu (MENU_SIG);
467 +  menu->make_entry = sig_make_entry;
468 +  menu->tag = NULL;
469 +  menu->search = sig_menu_search;
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:
516 +        done = 1;
517 +        break;
518 +    }
519 +  }
520 +  
521 +  mutt_menuDestroy (&menu);
522 +  safe_free ((void **)&SigTable);
523 +  return result;
524 +}
525 +
526 +extern char* SearchBuffers[MENU_MAX];
527 +
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;
534 +  char* searchBuf = menu->menu >= 0 && menu->menu < MENU_MAX ?
535 +                    SearchBuffers[menu->menu] : NULL;
536 +
537 +  snprintf (buf, sizeof(buf), searchBuf ? searchBuf : "");
538 +  if (mutt_get_field (_("Search for: "), buf,
539 +                     sizeof (buf), MUTT_CLEAR) != 0 || !buf[0])
540 +    return (NULL);
541 +  if (menu->menu >= 0 && menu->menu < MENU_MAX)
542 +  {
543 +    mutt_str_replace (&SearchBuffers[menu->menu], buf);
544 +    searchBuf = SearchBuffers[menu->menu];
545 +  }
546 +
547 +  if ((i = regcomp (&re, searchBuf, REG_NOSUB | REG_EXTENDED | REG_WORDS
548 +                   | mutt_which_case (searchBuf))) != 0)
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 +
659 +  menu = mutt_new_menu (MENU_SIG_DIR);
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;
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 +
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 +
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);
743 +}
This page took 0.236429 seconds and 3 git commands to generate.