]> git.pld-linux.org Git - packages/mutt.git/blame - mutt-pgp_hook.patch
- added iso-8859-2 to Muttrc -- friendly for polish users by default
[packages/mutt.git] / mutt-pgp_hook.patch
CommitLineData
1d12b69c 1diff -rU3 --new-file mutt-1.3.99-vanilla/PATCHES mutt-1.3.99/PATCHES
2--- mutt-1.3.99-vanilla/PATCHES Thu May 23 14:12:14 2002
3+++ mutt-1.3.99/PATCHES Thu May 23 14:13:33 2002
4@@ -1,3 +1,4 @@
5+patch-1.3.28.dw.pgp-hook.3
6 vvv.quote
7 patch-1.3.27.cd.signatures_menu.2.1
8 patch-1.3.25.cd.purge_command.2
9diff -rU3 --new-file mutt-1.3.99-vanilla/doc/manual.sgml.head mutt-1.3.99/doc/manual.sgml.head
10--- mutt-1.3.99-vanilla/doc/manual.sgml.head Thu May 23 14:12:14 2002
11+++ mutt-1.3.99/doc/manual.sgml.head Thu May 23 14:13:33 2002
12@@ -1389,7 +1389,9 @@
13 or because, for some reasons, you need to override the key Mutt would
14 normally use. The pgp-hook command provides a method by which you can
15 specify the ID of the public key to be used when encrypting messages to
16-a certain recipient.
17+a certain recipient. You may use multiple pgp-hook's with the same
18+pattern; multiple matching pgp-hook's result in the use of multiple
19+keyids for recipient.
20
21 <sect1>Adding key sequences to the keyboard buffer<label id="push">
22 <p>
23diff -rU3 --new-file mutt-1.3.99-vanilla/doc/manual.sgml.head.orig mutt-1.3.99/doc/manual.sgml.head.orig
24--- mutt-1.3.99-vanilla/doc/manual.sgml.head.orig Thu Apr 25 15:28:00 2002
25+++ mutt-1.3.99/doc/manual.sgml.head.orig Thu May 23 14:12:14 2002
26@@ -525,6 +525,7 @@
27 c edit-cc edit the Cc field
28 b edit-bcc edit the Bcc field
29 y send-message send the message
30+ESC s signature-menu select a signature and append it to your mail
31 s edit-subject edit the Subject
32 f edit-fcc specify an ``Fcc'' mailbox
33 p pgp-menu select PGP options (``i'' version only)
34@@ -2115,8 +2116,40 @@
35 with large volume mailing lists easier because you can easily delete
36 uninteresting threads and quickly find topics of value.
37
38+<sect1>Editing threads
39+<p>
40+Mutt has the ability to dynamically restructure threads that are broken
41+either by misconfigured software or bad behaviour from some
42+correspondents. This allows to clean your mailboxes (<em/mbox/ and <em/mmdf/
43+formats) from these annoyances which make it hard to follow a discussion.
44+
45+<sect2>Linking threads
46+<p>
47+
48+Some mailers tend to "forget" to correctly set the "In-Reply-To:" and
49+"References:" headers when replying to a message. This results in broken
50+discussions because Mutt has not enough information to guess the correct
51+threading.
52+You can fix this by tagging the reply to a mail, then go onto this mail
53+and use the ``link-threads'' function (bound to & by default). The
54+reply will then be connected to its "parent" message.
55+
56+You can also connect multiple childs at once, tagging them and using the
57+tag-prefix command (';') or the auto_tag option.
58+
59+<sect2>Breaking threads
60+<p>
61+
62+On mailing lists, some people are in the bad habit of starting a new
63+discussion by hitting "reply" to any message from the list and changing
64+the subject to a totally unrelated one.
65+You can fix such threads by using the ``break-thread'' function (bound
66+by default to #), which will turn the subthread starting from the
67+current message into a whole different thread.
68+
69 <sect1>Delivery Status Notification (DSN) Support
70 <p>
71+
72 RFC1894 defines a set of MIME content types for relaying information
73 about the status of electronic mail messages. These can be thought of as
74 ``return receipts.'' Berkeley sendmail 8.8.x currently has some command
75@@ -2319,6 +2352,176 @@
76 macro pager \cb |urlview\n
77 </verb></tscreen>
78
79+<sect1>Compressed folders Support (OPTIONAL)
80+<p>
81+
82+If Mutt was compiled with compressed folders support (by running the
83+<em/configure/ script with the <em/--enable-compressed/ flag), Mutt
84+can open folders stored in an arbitrary format, provided that the user
85+has a script to convert from/to this format to one of the accepted.
86+
87+The most common use is to open compressed archived folders e.g. with
88+gzip.
89+
90+In addition, the user can provide a script that gets a folder in an
91+accepted format and appends its context to the folder in the
92+user-defined format, which may be faster than converting the entire
93+folder to the accepted format, appending to it and converting back to
94+the user-defined format.
95+
96+There are three hooks defined (<ref id="open-hook" name="open-hook">,
97+<ref id="close-hook" name="close-hook"> and <ref id="append-hook"
98+name="append-hook">) which define commands to uncompress and compress
99+a folder and to append messages to an existing compressed folder
100+respectively.
101+
102+For example:
103+
104+<tscreen><verb>
105+open-hook \\.gz$ "gzip -cd %f &gt; %t"
106+close-hook \\.gz$ "gzip -c %t &gt; %f"
107+append-hook \\.gz$ "gzip -c %t &gt;&gt; %f"
108+</verb></tscreen>
109+
110+You do not have to specify all of the commands. If you omit <ref
111+id="append-hook" name="append-hook">, the folder will be open and
112+closed again each time you will add to it. If you omit <ref
113+id="close-hook" name="close-hook"> (or give empty command) , the
114+folder will be open in the mode. If you specify <ref
115+id="append-hook" name="append-hook"> though you'll be able to append
116+to the folder.
117+
118+Note that Mutt will only try to use hooks if the file is not in one of
119+the accepted formats. In particular, if the file is empty, mutt
120+supposes it is not compressed. This is important because it allows the
121+use of programs that do not have well defined extensions. Just use
122+&dquot;.&dquot; as a regexp. But this may be surprising if your
123+compressing script produces empty files. In this situation, unset <ref
124+id="save_empty" name="&dollar;save&lowbar;empty">, so that the compressed file
125+will be removed if you delete all of the messages.
126+
127+<sect2>Open a compressed mailbox for reading<label id="open-hook">
128+<p>
129+Usage: <tt/open-hook/ <em/regexp/ &dquot;<em/command/&dquot;
130+
131+The <em/command/ is the command that can be used for opening the
132+folders whose names match <em/regexp/.
133+
134+The <em/command/ string is the printf-like format string, and it
135+should accept two parameters: &percnt;f, which is replaced with the
136+(compressed) folder name, and &percnt;t which is replaced with the
137+name of the temporary folder to which to write.
138+
139+&percnt;f and &percnt;t can be repeated any number of times in the
140+command string, and all of the entries are replaced with the
141+appropriate folder name. In addition, &percnt;&percnt; is replaced by
142+&percnt;, as in printf, and any other &percnt;anything is left as is.
143+
144+The <em/command/ should <bf/not/ remove the original compressed file.
145+The <em/command/ should return non-zero exit status if it fails, so
146+mutt knows something's wrong.
147+
148+Example:
149+
150+<tscreen><verb>
151+open-hook \\.gz$ "gzip -cd %f &gt; %t"
152+</verb></tscreen>
153+
154+If the <em/command/ is empty, this operation is disabled for this file
155+type.
156+
157+<sect2>Write a compressed mailbox<label id="close-hook">
158+<p>
159+Usage: <tt/close-hook/ <em/regexp/ &dquot;<em/command/&dquot;
160+
161+This is used to close the folder that was open with the <ref id="open-hook"
162+name="open-hook"> command after some changes were made to it.
163+
164+The <em/command/ string is the command that can be used for closing the
165+folders whose names match <em/regexp/. It has the same format as in
166+the <ref id="open-hook" name="open-hook"> command. Temporary folder
167+in this case is the folder previously produced by the <ref id="open-hook"
168+name="open-hook"> command.
169+
170+The <em/command/ should <bf/not/ remove the decompressed file. The
171+<em/command/ should return non-zero exit status if it fails, so mutt
172+knows something's wrong.
173+
174+Example:
175+
176+<tscreen><verb>
177+close-hook \\.gz$ "gzip -c %t &gt; %f"
178+</verb></tscreen>
179+
180+If the <em/command/ is empty, this operation is disabled for this file
181+type, and the file can only be open in the read-only mode.
182+
183+<ref id="close-hook" name ="close-hook"> is not called when you exit
184+from the folder if the folder was not changed.
185+
186+<sect2>Append a message to a compressed mailbox<label id="append-hook">
187+<p>
188+Usage: <tt/append-hook/ <em/regexp/ &dquot;<em/command/&dquot;
189+
190+This command is used for saving to an existing compressed folder.
191+The <em/command/ is the command that can be used for appending to the
192+folders whose names match <em/regexp/. It has the same format as in
193+ the <ref id="open-hook" name="open-hook"> command.
194+The temporary folder in this case contains the messages that are being
195+appended.
196+
197+The <em/command/ should <bf/not/ remove the decompressed file. The
198+<em/command/ should return non-zero exit status if it fails, so mutt
199+knows something's wrong.
200+
201+Example:
202+
203+<tscreen><verb>
204+append-hook \\.gz$ "gzip -c %t &gt;&gt; %f"
205+</verb></tscreen>
206+
207+When <ref id="append-hook" name="append-hook"> is used, the folder is
208+not opened, which saves time, but this means that we can not find out
209+what the folder type is. Thus the default (<ref id="mbox_type"
210+name="&dollar;mbox&lowbar;type">) type is always supposed (i.e.
211+this is the format used for the temporary folder).
212+
213+If the file does not exist when you save to it, <ref id="close-hook"
214+name="close-hook"> is called, and not <ref id="append-hook"
215+name="append-hook">. <ref id="append-hook" name="append-hook"> is only
216+for appending to existing folders.
217+
218+If the <em/command/ is empty, this operation is disabled for this file
219+type. In this case, the folder will be open and closed again (using
220+<ref id="open-hook" name="open-hook"> and <ref id="close-hook"
221+name="close-hook">respectively) each time you will add to it.
222+
223+<sect2>Encrypted folders
224+<p>
225+The compressed folders support can also be used to handle encrypted
226+folders. If you want to encrypt a folder with PGP, you may want to use
227+the following hooks:
228+
229+<tscreen><verb>
230+open-hook \\.pgp$ "pgp -f &lt; %f &gt; %t"
231+close-hook \\.pgp$ "pgp -fe YourPgpUserIdOrKeyId &lt; %t &gt; %f"
232+</verb></tscreen>
233+
234+Please note, that PGP does not support appending to an encrypted
235+folder, so there is no append-hook defined.
236+
237+If you are using GnuPG instead of PGP, you may use the following hooks
238+instead:
239+
240+<tscreen><verb>
241+open-hook \\.gpg$ "gpg --decrypt &lt; %f &gt; %t"
242+close-hook \\.gpg$ "gpg --encrypt --recipient YourGpgUserIdOrKeyId &lt; %t &gt; %f"
243+</verb></tscreen>
244+
245+<bf/Note:/ the folder is temporary stored decrypted in the /tmp
246+directory, where it can be read by your system administrator. So think
247+about the security aspects of this.
248+
249 <sect>Mutt's MIME Support
250 <p>
251 Quite a bit of effort has been made to make Mutt the premier text-mode
252@@ -2871,12 +3074,16 @@
253 <item>
254 <tt><ref id="alternative_order" name="alternative&lowbar;order"></tt> <em/mimetype/ &lsqb; <em/mimetype/ ... &rsqb;
255 <item>
256+<tt><ref id="append-hook" name="append-hook"></tt> <em/regexp/ &dquot;<em/command/&dquot;
257+<item>
258 <tt><ref id="auto_view" name="auto&lowbar;view"></tt> <em/mimetype/ &lsqb; <em/mimetype/ ... &rsqb;
259 <item>
260 <tt><ref id="bind" name="bind"></tt> <em/map/ <em/key/ <em/function/
261 <item>
262 <tt><ref id="charset-hook" name="charset-hook"></tt> <em/alias/ <em/charset/
263 <item>
264+<tt><ref id="close-hook" name="close-hook"></tt> <em/regexp/ &dquot;<em/command/&dquot;
265+<item>
266 <tt><ref id="color" name="color"></tt> <em/object/ <em/foreground/ <em/background/ &lsqb; <em/regexp/ &rsqb;
267 <item>
268 <tt><ref id="color" name="uncolor"></tt> <em/index/ <em/pattern/ &lsqb; <em/pattern/ ... &rsqb;
269@@ -2919,6 +3126,8 @@
270 <item>
271 <tt><ref id="my_hdr" name="unmy&lowbar;hdr"></tt> <em/field/ &lsqb; <em/field/ ... &rsqb;
272 <item>
273+<tt><ref id="open-hook" name="open-hook"></tt> <em/regexp/ &dquot;<em/command/&dquot;
274+<item>
275 <tt><ref id="pgp-hook" name="pgp-hook"></tt> <em/pattern/ <em/key-id/
276 <item>
277 <tt><ref id="push" name="push"></tt> <em/string/
278diff -rU3 --new-file mutt-1.3.99-vanilla/doc/muttrc.man.head mutt-1.3.99/doc/muttrc.man.head
279--- mutt-1.3.99-vanilla/doc/muttrc.man.head Thu May 23 14:12:13 2002
280+++ mutt-1.3.99/doc/muttrc.man.head Thu May 23 14:15:38 2002
281@@ -257,7 +257,9 @@
282 \fBpgp-hook\fP \fIpattern\fP \fIkey-id\fP
283 The pgp-hook command provides a method by which you can
284 specify the ID of the public key to be used when encrypting messages
285-to a certain recipient.
286+to a certain recipient. You may use multiple \fBpgp-hook\fPs with the
287+same \fIpattern\fP; multiple matching \fBpgp-hook\fPs result in the use
288+of multiple \fIkey-id\fPs for recipient.
289 .PP
290 .nf
291 \fBopen-hook\fP \fIregexp\fP "\fIcommand\fP"
292diff -rU3 --new-file mutt-1.3.99-vanilla/hook.c mutt-1.3.99/hook.c
293--- mutt-1.3.99-vanilla/hook.c Thu May 23 14:12:13 2002
294+++ mutt-1.3.99/hook.c Thu May 23 14:13:33 2002
295@@ -129,7 +129,11 @@
296 ptr->rx.not == not &&
297 !mutt_strcmp (pattern.data, ptr->rx.pattern))
298 {
299+#ifdef M_PGPHOOK
300+ if (data & (M_FOLDERHOOK | M_SENDHOOK | M_MESSAGEHOOK | M_ACCOUNTHOOK | M_PGPHOOK))
301+#else
302 if (data & (M_FOLDERHOOK | M_SENDHOOK | M_MESSAGEHOOK | M_ACCOUNTHOOK))
303+#endif /* M_PGPHOOK */
304 {
305 /* these hooks allow multiple commands with the same
306 * pattern, so if we've already seen this pattern/command pair, just
307@@ -456,9 +460,25 @@
308 }
309
310 #ifdef HAVE_PGP
311-char *mutt_pgp_hook (ADDRESS *adr)
312+LIST *mutt_pgp_hook (ADDRESS *adr)
313 {
314- return _mutt_string_hook (adr->mailbox, M_PGPHOOK);
315+ HOOK *hook;
316+ LIST *key_list = NULL;
317+
318+ if (!adr && !adr->mailbox)
319+ return (NULL);
320+
321+ for (hook = Hooks; hook; hook = hook->next)
322+ {
323+ if (!hook->command)
324+ continue;
325+ if (!(hook->type & M_PGPHOOK))
326+ continue;
327+
328+ if ((regexec (hook->rx.rx, adr->mailbox, 0, NULL, 0) == 0) ^ hook->rx.not)
329+ key_list = mutt_add_list (key_list, hook->command);
330+ }
331+ return (key_list);
332 }
333 #endif /* HAVE_PGP */
334
335diff -rU3 --new-file mutt-1.3.99-vanilla/hook.c.orig mutt-1.3.99/hook.c.orig
336--- mutt-1.3.99-vanilla/hook.c.orig Thu Jan 1 01:00:00 1970
337+++ mutt-1.3.99/hook.c.orig Thu May 23 14:12:13 2002
338@@ -0,0 +1,497 @@
339+/*
340+ * Copyright (C) 1996-2000 Michael R. Elkins <me@cs.hmc.edu>, and others
341+ *
342+ * This program is free software; you can redistribute it and/or modify
343+ * it under the terms of the GNU General Public License as published by
344+ * the Free Software Foundation; either version 2 of the License, or
345+ * (at your option) any later version.
346+ *
347+ * This program is distributed in the hope that it will be useful,
348+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
349+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
350+ * GNU General Public License for more details.
351+ *
352+ * You should have received a copy of the GNU General Public License
353+ * along with this program; if not, write to the Free Software
354+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
355+ */
356+
357+#include "mutt.h"
358+#include "mailbox.h"
359+
360+#ifdef USE_COMPRESSED
361+#include "compress.h"
362+#endif
363+
364+#include <limits.h>
365+#include <string.h>
366+#include <stdlib.h>
367+#include <ctype.h>
368+#include <unistd.h>
369+
370+typedef struct hook
371+{
372+ int type; /* hook type */
373+ REGEXP rx; /* regular expression */
374+ char *command; /* filename, command or pattern to execute */
375+ pattern_t *pattern; /* used for fcc,save,send-hook */
376+ struct hook *next;
377+} HOOK;
378+
379+static HOOK *Hooks = NULL;
380+
381+static int current_hook_type = 0;
382+
383+int mutt_parse_hook (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
384+{
385+ HOOK *ptr;
386+ BUFFER command, pattern;
387+ int rc, not = 0;
388+ regex_t *rx = NULL;
389+ pattern_t *pat = NULL;
390+ char path[_POSIX_PATH_MAX];
391+
392+ memset (&pattern, 0, sizeof (pattern));
393+ memset (&command, 0, sizeof (command));
394+
395+ if (*s->dptr == '!')
396+ {
397+ s->dptr++;
398+ SKIPWS (s->dptr);
399+ not = 1;
400+ }
401+
402+ mutt_extract_token (&pattern, s, 0);
403+
404+ if (!MoreArgs (s))
405+ {
406+ strfcpy (err->data, _("too few arguments"), err->dsize);
407+ goto error;
408+ }
409+
410+ mutt_extract_token (&command, s, (data & (M_FOLDERHOOK | M_SENDHOOK | M_ACCOUNTHOOK)) ? M_TOKEN_SPACE : 0);
411+
412+ if (!command.data)
413+ {
414+ strfcpy (err->data, _("too few arguments"), err->dsize);
415+ goto error;
416+ }
417+
418+ if (MoreArgs (s))
419+ {
420+ strfcpy (err->data, _("too many arguments"), err->dsize);
421+ goto error;
422+ }
423+
424+ if (data & (M_FOLDERHOOK | M_MBOXHOOK))
425+ {
426+ strfcpy (path, pattern.data, sizeof (path));
427+ _mutt_expand_path (path, sizeof (path), 1);
428+ FREE (&pattern.data);
429+ memset (&pattern, 0, sizeof (pattern));
430+ pattern.data = safe_strdup (path);
431+ }
432+#ifdef USE_COMPRESSED
433+ else if (data & (M_APPENDHOOK | M_OPENHOOK | M_CLOSEHOOK))
434+ {
435+ if (mutt_test_compress_command (command.data))
436+ {
437+ strfcpy (err->data, _("bad formatted command string"), err->dsize);
438+ return (-1);
439+ }
440+ }
441+#endif
442+ else if (DefaultHook && (data & (M_FOLDERHOOK | M_MBOXHOOK | M_SENDHOOK |
443+ M_FCCHOOK | M_SAVEHOOK | M_MESSAGEHOOK)))
444+ {
445+ char tmp[HUGE_STRING];
446+
447+ strfcpy (tmp, pattern.data, sizeof (tmp));
448+ mutt_check_simple (tmp, sizeof (tmp), DefaultHook);
449+ FREE (&pattern.data);
450+ memset (&pattern, 0, sizeof (pattern));
451+ pattern.data = safe_strdup (tmp);
452+ }
453+
454+ if (data & (M_MBOXHOOK | M_SAVEHOOK | M_FCCHOOK))
455+ {
456+ strfcpy (path, command.data, sizeof (path));
457+ mutt_expand_path (path, sizeof (path));
458+ FREE (&command.data);
459+ memset (&command, 0, sizeof (command));
460+ command.data = safe_strdup (path);
461+ }
462+
463+ /* check to make sure that a matching hook doesn't already exist */
464+ for (ptr = Hooks; ptr; ptr = ptr->next)
465+ {
466+ if (ptr->type == data &&
467+ ptr->rx.not == not &&
468+ !mutt_strcmp (pattern.data, ptr->rx.pattern))
469+ {
470+ if (data & (M_FOLDERHOOK | M_SENDHOOK | M_MESSAGEHOOK | M_ACCOUNTHOOK))
471+ {
472+ /* these hooks allow multiple commands with the same
473+ * pattern, so if we've already seen this pattern/command pair, just
474+ * ignore it instead of creating a duplicate */
475+ if (!mutt_strcmp (ptr->command, command.data))
476+ {
477+ FREE (&command.data);
478+ FREE (&pattern.data);
479+ return 0;
480+ }
481+ }
482+ else
483+ {
484+ /* other hooks only allow one command per pattern, so update the
485+ * entry with the new command. this currently does not change the
486+ * order of execution of the hooks, which i think is desirable since
487+ * a common action to perform is to change the default (.) entry
488+ * based upon some other information. */
489+ FREE (&ptr->command);
490+ ptr->command = command.data;
491+ FREE (&pattern.data);
492+ return 0;
493+ }
494+ }
495+ if (!ptr->next)
496+ break;
497+ }
498+
499+ if (data & (M_SENDHOOK | M_SAVEHOOK | M_FCCHOOK | M_MESSAGEHOOK))
500+ {
501+ if ((pat = mutt_pattern_comp (pattern.data,
502+ (data & (M_SENDHOOK | M_FCCHOOK)) ? 0 : M_FULL_MSG,
503+ err)) == NULL)
504+ goto error;
505+ }
506+ else
507+ {
508+ rx = safe_malloc (sizeof (regex_t));
509+#ifdef M_PGPHOOK
510+ if ((rc = REGCOMP (rx, NONULL(pattern.data), ((data & (M_PGPHOOK|M_CHARSETHOOK)) ? REG_ICASE : 0))) != 0)
511+#else
512+ if ((rc = REGCOMP (rx, NONULL(pattern.data), (data & (M_CHARSETHOOK|M_ICONVHOOK)) ? REG_ICASE : 0)) != 0)
513+#endif /* HAVE_PGP */
514+ {
515+ regerror (rc, rx, err->data, err->dsize);
516+ regfree (rx);
517+ safe_free ((void **) &rx);
518+ goto error;
519+ }
520+ }
521+
522+ if (ptr)
523+ {
524+ ptr->next = safe_calloc (1, sizeof (HOOK));
525+ ptr = ptr->next;
526+ }
527+ else
528+ Hooks = ptr = safe_calloc (1, sizeof (HOOK));
529+ ptr->type = data;
530+ ptr->command = command.data;
531+ ptr->pattern = pat;
532+ ptr->rx.pattern = pattern.data;
533+ ptr->rx.rx = rx;
534+ ptr->rx.not = not;
535+ return 0;
536+
537+error:
538+ FREE (&pattern.data);
539+ FREE (&command.data);
540+ return (-1);
541+}
542+
543+static void delete_hook (HOOK *h)
544+{
545+ FREE (&h->command);
546+ FREE (&h->rx.pattern);
547+ if (h->rx.rx)
548+ {
549+ regfree (h->rx.rx);
550+ }
551+ mutt_pattern_free (&h->pattern);
552+ FREE (&h);
553+}
554+
555+/* Deletes all hooks of type ``type'', or all defined hooks if ``type'' is 0 */
556+static void delete_hooks (int type)
557+{
558+ HOOK *h;
559+ HOOK *prev;
560+
561+ while (h = Hooks, h && (type == 0 || type == h->type))
562+ {
563+ Hooks = h->next;
564+ delete_hook (h);
565+ }
566+
567+ prev = h; /* Unused assignment to avoid compiler warnings */
568+
569+ while (h)
570+ {
571+ if (type == h->type)
572+ {
573+ prev->next = h->next;
574+ delete_hook (h);
575+ }
576+ else
577+ prev = h;
578+ h = prev->next;
579+ }
580+}
581+
582+int mutt_parse_unhook (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
583+{
584+ while (MoreArgs (s))
585+ {
586+ mutt_extract_token (buf, s, 0);
587+ if (mutt_strcmp ("*", buf->data) == 0)
588+ {
589+ if (current_hook_type)
590+ {
591+ snprintf (err->data, err->dsize,
592+ _("unhook: Can't do unhook * from within a hook."));
593+ return -1;
594+ }
595+ delete_hooks (0);
596+ }
597+ else
598+ {
599+ int type = mutt_get_hook_type (buf->data);
600+
601+ if (!type)
602+ {
603+ snprintf (err->data, err->dsize,
604+ _("unhook: unknown hook type: %s"), buf->data);
605+ return (-1);
606+ }
607+ if (current_hook_type == type)
608+ {
609+ snprintf (err->data, err->dsize,
610+ _("unhook: Can't delete a %s from within a %s."),
611+ buf->data, buf->data);
612+ return -1;
613+ }
614+ delete_hooks (type);
615+ }
616+ }
617+ return 0;
618+}
619+
620+void mutt_folder_hook (char *path)
621+{
622+ HOOK *tmp = Hooks;
623+ BUFFER err, token;
624+ char buf[STRING];
625+
626+ current_hook_type = M_FOLDERHOOK;
627+
628+ err.data = buf;
629+ err.dsize = sizeof (buf);
630+ memset (&token, 0, sizeof (token));
631+ for (; tmp; tmp = tmp->next)
632+ {
633+ if(!tmp->command)
634+ continue;
635+
636+ if (tmp->type & M_FOLDERHOOK)
637+ {
638+ if ((regexec (tmp->rx.rx, path, 0, NULL, 0) == 0) ^ tmp->rx.not)
639+ {
640+ if (mutt_parse_rc_line (tmp->command, &token, &err) == -1)
641+ {
642+ mutt_error ("%s", err.data);
643+ FREE (&token.data);
644+ mutt_sleep (1); /* pause a moment to let the user see the error */
645+ current_hook_type = 0;
646+ return;
647+ }
648+ }
649+ }
650+ }
651+ FREE (&token.data);
652+
653+ current_hook_type = 0;
654+}
655+
656+char *mutt_find_hook (int type, const char *pat)
657+{
658+ HOOK *tmp = Hooks;
659+
660+ for (; tmp; tmp = tmp->next)
661+ if (tmp->type & type)
662+ {
663+ if (regexec (tmp->rx.rx, pat, 0, NULL, 0) == 0)
664+ return (tmp->command);
665+ }
666+ return (NULL);
667+}
668+
669+void mutt_message_hook (CONTEXT *ctx, HEADER *hdr, int type)
670+{
671+ BUFFER err, token;
672+ HOOK *hook;
673+ char buf[STRING];
674+
675+ current_hook_type = type;
676+
677+ err.data = buf;
678+ err.dsize = sizeof (buf);
679+ memset (&token, 0, sizeof (token));
680+ for (hook = Hooks; hook; hook = hook->next)
681+ {
682+ if(!hook->command)
683+ continue;
684+
685+ if (hook->type & type)
686+ if ((mutt_pattern_exec (hook->pattern, 0, ctx, hdr) > 0) ^ hook->rx.not)
687+ if (mutt_parse_rc_line (hook->command, &token, &err) != 0)
688+ {
689+ FREE (&token.data);
690+ mutt_error ("%s", err.data);
691+ mutt_sleep (1);
692+ current_hook_type = 0;
693+ return;
694+ }
695+ }
696+ FREE (&token.data);
697+ current_hook_type = 0;
698+}
699+
700+static int
701+mutt_addr_hook (char *path, size_t pathlen, int type, CONTEXT *ctx, HEADER *hdr)
702+{
703+ HOOK *hook;
704+
705+ /* determine if a matching hook exists */
706+ for (hook = Hooks; hook; hook = hook->next)
707+ {
708+ if(!hook->command)
709+ continue;
710+
711+ if (hook->type & type)
712+ if ((mutt_pattern_exec (hook->pattern, 0, ctx, hdr) > 0) ^ hook->rx.not)
713+ {
714+ mutt_make_string (path, pathlen, hook->command, ctx, hdr);
715+ return 0;
716+ }
717+ }
718+
719+ return -1;
720+}
721+
722+void mutt_default_save (char *path, size_t pathlen, HEADER *hdr)
723+{
724+ *path = 0;
725+ if (mutt_addr_hook (path, pathlen, M_SAVEHOOK, Context, hdr) != 0)
726+ {
727+ char tmp[_POSIX_PATH_MAX];
728+ ADDRESS *adr;
729+ ENVELOPE *env = hdr->env;
730+ int fromMe = mutt_addr_is_user (env->from);
731+
732+ if (!fromMe && env->reply_to && env->reply_to->mailbox)
733+ adr = env->reply_to;
734+ else if (!fromMe && env->from && env->from->mailbox)
735+ adr = env->from;
736+ else if (env->to && env->to->mailbox)
737+ adr = env->to;
738+ else if (env->cc && env->cc->mailbox)
739+ adr = env->cc;
740+ else
741+ adr = NULL;
742+ if (adr)
743+ {
744+ mutt_safe_path (tmp, sizeof (tmp), adr);
745+ snprintf (path, pathlen, "=%s", tmp);
746+ }
747+ }
748+}
749+
750+void mutt_select_fcc (char *path, size_t pathlen, HEADER *hdr)
751+{
752+ ADDRESS *adr;
753+ char buf[_POSIX_PATH_MAX];
754+ ENVELOPE *env = hdr->env;
755+
756+ if (mutt_addr_hook (path, pathlen, M_FCCHOOK, NULL, hdr) != 0)
757+ {
758+ if ((option (OPTSAVENAME) || option (OPTFORCENAME)) &&
759+ (env->to || env->cc || env->bcc))
760+ {
761+ adr = env->to ? env->to : (env->cc ? env->cc : env->bcc);
762+ mutt_safe_path (buf, sizeof (buf), adr);
763+ snprintf (path, pathlen, "%s/%s", NONULL (Maildir), buf);
764+ if (!option (OPTFORCENAME) && mx_access (path, W_OK) != 0)
765+ strfcpy (path, NONULL (Outbox), pathlen);
766+ }
767+ else
768+ strfcpy (path, NONULL (Outbox), pathlen);
769+ }
770+ mutt_pretty_mailbox (path);
771+}
772+
773+static char *_mutt_string_hook (const char *match, int hook)
774+{
775+ HOOK *tmp = Hooks;
776+
777+ for (; tmp; tmp = tmp->next)
778+ {
779+ if ((tmp->type & hook) && ((match &&
780+ regexec (tmp->rx.rx, match, 0, NULL, 0) == 0) ^ tmp->rx.not))
781+ return (tmp->command);
782+ }
783+ return (NULL);
784+}
785+
786+char *mutt_charset_hook (const char *chs)
787+{
788+ return _mutt_string_hook (chs, M_CHARSETHOOK);
789+}
790+
791+char *mutt_iconv_hook (const char *chs)
792+{
793+ return _mutt_string_hook (chs, M_ICONVHOOK);
794+}
795+
796+#ifdef HAVE_PGP
797+char *mutt_pgp_hook (ADDRESS *adr)
798+{
799+ return _mutt_string_hook (adr->mailbox, M_PGPHOOK);
800+}
801+#endif /* HAVE_PGP */
802+
803+#ifdef USE_SOCKET
804+void mutt_account_hook (const char* url)
805+{
806+ HOOK* hook;
807+ BUFFER token;
808+ BUFFER err;
809+ char buf[STRING];
810+
811+ err.data = buf;
812+ err.dsize = sizeof (buf);
813+ memset (&token, 0, sizeof (token));
814+
815+ for (hook = Hooks; hook; hook = hook->next)
816+ {
817+ if (! (hook->command && (hook->type & M_ACCOUNTHOOK)))
818+ continue;
819+
820+ if ((regexec (hook->rx.rx, url, 0, NULL, 0) == 0) ^ hook->rx.not)
821+ {
822+ if (mutt_parse_rc_line (hook->command, &token, &err) == -1)
823+ {
824+ FREE (&token.data);
825+ mutt_error ("%s", err.data);
826+ mutt_sleep (1);
827+
828+ return;
829+ }
830+ }
831+ }
832+
833+ FREE (&token.data);
834+}
835+#endif
836diff -rU3 --new-file mutt-1.3.99-vanilla/init.h mutt-1.3.99/init.h
837--- mutt-1.3.99-vanilla/init.h Thu May 23 14:12:14 2002
838+++ mutt-1.3.99/init.h Thu May 23 14:13:33 2002
839@@ -1183,6 +1183,14 @@
840
841 #ifdef HAVE_PGP
842
843+ { "pgp_autoselectkey", DT_BOOL, R_NONE, OPTPGPAUTOSELECT, 0 },
844+ /*
845+ ** .pp
846+ ** If set, then a list of keys is not presented for selection when only
847+ ** one matching key is available. This may be useful in conjunction with
848+ ** the \fIpgp-hook\fP command (with ``$$pgp_confirmhook'' set) and the
849+ ** ``$$pgp_ignore_subkeys'' variable.
850+ */
851 { "pgp_autosign", DT_BOOL, R_NONE, OPTPGPAUTOSIGN, 0 },
852 /*
853 ** .pp
854@@ -1200,6 +1208,14 @@
855 ** \fIpgp-menu\fP, when encryption is not required or signing is
856 ** requested as well.
857 */
858+ { "pgp_confirmhook", DT_BOOL, R_NONE, OPTPGPCONFIRMHOOK, 1 },
859+ /*
860+ ** .pp
861+ ** If set, then you will be prompted for confirmation of keys when using
862+ ** the \fIpgp-hook\fP command. If unset, no such confirmation prompt will
863+ ** be presented. This is generally considered unsafe, especially where
864+ ** typos are concerned.
865+ */
866 { "pgp_ignore_subkeys", DT_BOOL, R_NONE, OPTPGPIGNORESUB, 1},
867 /*
868 ** .pp
869diff -rU3 --new-file mutt-1.3.99-vanilla/init.h.orig mutt-1.3.99/init.h.orig
870--- mutt-1.3.99-vanilla/init.h.orig Thu May 23 14:12:14 2002
871+++ mutt-1.3.99/init.h.orig Thu May 23 14:12:14 2002
872@@ -519,6 +519,12 @@
873 ** you use `+' or `=' for any other variables since expansion takes place
874 ** during the `set' command.
875 */
876+ { "folder_columns", DT_NUM, R_NONE, UL &FolderColumns, UL 1 },
877+ /*
878+ ** .pp
879+ ** Specifies the number of folder columns in folder browser.
880+ **
881+ */
882 { "folder_format", DT_STR, R_INDEX, UL &FolderFormat, UL "%2C %t %N %F %2l %-8.8u %-8.8g %8s %d %f" },
883 /*
884 ** .pp
885diff -rU3 --new-file mutt-1.3.99-vanilla/mutt-1.3.28/PATCHES mutt-1.3.99/mutt-1.3.28/PATCHES
886--- mutt-1.3.99-vanilla/mutt-1.3.28/PATCHES Thu Jan 1 01:00:00 1970
887+++ mutt-1.3.99/mutt-1.3.28/PATCHES Thu May 23 14:13:28 2002
888@@ -0,0 +1 @@
889+patch-1.3.28.dw.pgp-hook.3
890diff -rU3 --new-file mutt-1.3.99-vanilla/mutt.h mutt-1.3.99/mutt.h
891--- mutt-1.3.99-vanilla/mutt.h Thu May 23 14:12:14 2002
892+++ mutt-1.3.99/mutt.h Thu May 23 14:13:33 2002
893@@ -427,8 +427,10 @@
894 /* PGP options */
895
896 #ifdef HAVE_PGP
897+ OPTPGPAUTOSELECT,
898 OPTPGPAUTOSIGN,
899 OPTPGPAUTOENCRYPT,
900+ OPTPGPCONFIRMHOOK,
901 OPTPGPIGNORESUB,
902 OPTPGPLONGIDS,
903 OPTPGPREPLYENCRYPT,
904diff -rU3 --new-file mutt-1.3.99-vanilla/mutt.h.orig mutt-1.3.99/mutt.h.orig
905--- mutt-1.3.99-vanilla/mutt.h.orig Thu May 23 14:12:14 2002
906+++ mutt-1.3.99/mutt.h.orig Thu May 23 14:12:14 2002
907@@ -192,6 +192,7 @@
908 M_UNDELETE,
909 M_DELETED,
910 M_APPENDED,
911+ M_PURGED,
912 M_FLAG,
913 M_TAG,
914 M_UNTAG,
915@@ -632,6 +633,7 @@
916 unsigned int flagged : 1; /* marked important? */
917 unsigned int tagged : 1;
918 unsigned int appended : 1; /* has been saved */
919+ unsigned int purged : 1; /* bypassing the trash folder */
920 unsigned int deleted : 1;
921 unsigned int changed : 1;
922 unsigned int attach_del : 1; /* has an attachment marked for deletion */
923diff -rU3 --new-file mutt-1.3.99-vanilla/pgp.c mutt-1.3.99/pgp.c
924--- mutt-1.3.99-vanilla/pgp.c Wed Jan 9 16:39:28 2002
925+++ mutt-1.3.99/pgp.c Thu May 23 14:13:33 2002
926@@ -1327,6 +1327,8 @@
927 char *keyID, *keylist = NULL, *t;
928 size_t keylist_size = 0;
929 size_t keylist_used = 0;
930+ LIST *hook_list = NULL;
931+ LIST *hook = NULL;
932 ADDRESS *tmp = NULL, *addr = NULL;
933 ADDRESS **last = &tmp;
934 ADDRESS *p, *q;
935@@ -1360,62 +1362,88 @@
936 char buf[LONG_STRING];
937
938 q = p;
939- k_info = NULL;
940
941- if ((keyID = mutt_pgp_hook (p)) != NULL)
942+ /*
943+ * grab the list of matching hooks (matching on recipient address)
944+ * process each entry singly so that auto key selection still works
945+ */
946+ hook_list = mutt_pgp_hook (p);
947+ hook = hook_list;
948+ while (1)
949 {
950 int r;
951- snprintf (buf, sizeof (buf), _("Use keyID = \"%s\" for %s?"), keyID, p->mailbox);
952- if ((r = mutt_yesorno (buf, M_YES)) == M_YES)
953+
954+ k_info = NULL;
955+
956+ if (hook)
957 {
958- /* check for e-mail address */
959- if ((t = strchr (keyID, '@')) &&
960- (addr = rfc822_parse_adrlist (NULL, keyID)))
961+ keyID = (char *)hook->data;
962+ snprintf (buf, sizeof (buf), _("Use keyID = \"%s\" for %s?"), keyID, p->mailbox);
963+ if (!option(OPTPGPCONFIRMHOOK) || (r = mutt_yesorno (buf, M_YES)) == M_YES)
964 {
965- if (fqdn) rfc822_qualify (addr, fqdn);
966- q = addr;
967+ /* check for e-mail address */
968+ if ((t = strchr (keyID, '@')) &&
969+ (addr = rfc822_parse_adrlist (NULL, keyID)))
970+ {
971+ if (fqdn) rfc822_qualify (addr, fqdn);
972+ q = addr;
973+ }
974+ else
975+ k_info = pgp_getkeybystr (keyID, KEYFLAG_CANENCRYPT, PGP_PUBRING);
976+ }
977+ else if (r == -1)
978+ {
979+ /*
980+ * yes, this implies that if one key fails they all do
981+ */
982+ safe_free ((void **) &keylist);
983+ rfc822_free_address (&tmp);
984+ rfc822_free_address (&addr);
985+ mutt_free_list (&hook_list);
986+ return NULL;
987 }
988- else
989- k_info = pgp_getkeybystr (keyID, KEYFLAG_CANENCRYPT, PGP_PUBRING);
990- }
991- else if (r == -1)
992- {
993- safe_free ((void **) &keylist);
994- rfc822_free_address (&tmp);
995- rfc822_free_address (&addr);
996- return NULL;
997 }
998- }
999
1000- if (k_info == NULL)
1001- pgp_invoke_getkeys (q);
1002+ if (k_info == NULL)
1003+ pgp_invoke_getkeys (q);
1004
1005- if (k_info == NULL && (k_info = pgp_getkeybyaddr (q, KEYFLAG_CANENCRYPT, PGP_PUBRING)) == NULL)
1006- {
1007- snprintf (buf, sizeof (buf), _("Enter keyID for %s: "), q->mailbox);
1008-
1009- if ((key = pgp_ask_for_key (buf, q->mailbox,
1010- KEYFLAG_CANENCRYPT, PGP_PUBRING)) == NULL)
1011+ if (k_info == NULL && (k_info = pgp_getkeybyaddr (q, KEYFLAG_CANENCRYPT, PGP_PUBRING)) == NULL)
1012 {
1013- safe_free ((void **)&keylist);
1014- rfc822_free_address (&tmp);
1015- rfc822_free_address (&addr);
1016- return NULL;
1017+ snprintf (buf, sizeof (buf), _("Enter keyID for %s: "), q->mailbox);
1018+
1019+ if ((key = pgp_ask_for_key (buf, q->mailbox,
1020+ KEYFLAG_CANENCRYPT, PGP_PUBRING)) == NULL)
1021+ {
1022+ safe_free ((void **)&keylist);
1023+ rfc822_free_address (&tmp);
1024+ rfc822_free_address (&addr);
1025+ mutt_free_list (&hook_list);
1026+ return NULL;
1027+ }
1028 }
1029- }
1030- else
1031- key = k_info;
1032+ else
1033+ key = k_info;
1034
1035- keyID = pgp_keyid (key);
1036-
1037- keylist_size += mutt_strlen (keyID) + 4;
1038- safe_realloc ((void **)&keylist, keylist_size);
1039- sprintf (keylist + keylist_used, "%s0x%s", keylist_used ? " " : "", /* __SPRINTF_CHECKED__ */
1040- keyID);
1041- keylist_used = mutt_strlen (keylist);
1042+ keyID = pgp_keyid (key);
1043+
1044+ keylist_size += mutt_strlen (keyID) + 4;
1045+ safe_realloc ((void **)&keylist, keylist_size);
1046+ sprintf (keylist + keylist_used, "%s0x%s", keylist_used ? " " : "", /* __SPRINTF_CHECKED__ */
1047+ keyID);
1048+ keylist_used = mutt_strlen (keylist);
1049+
1050+ pgp_free_key (&key);
1051+ rfc822_free_address (&addr);
1052+
1053+ if (!hook_list)
1054+ break;
1055+
1056+ hook = hook->next;
1057+ if (!hook)
1058+ break;
1059
1060- pgp_free_key (&key);
1061- rfc822_free_address (&addr);
1062+ }
1063+ mutt_free_list (&hook_list);
1064
1065 }
1066 rfc822_free_address (&tmp);
1067diff -rU3 --new-file mutt-1.3.99-vanilla/pgpkey.c mutt-1.3.99/pgpkey.c
1068--- mutt-1.3.99-vanilla/pgpkey.c Tue Jan 15 10:04:28 2002
1069+++ mutt-1.3.99/pgpkey.c Thu May 23 14:13:33 2002
1070@@ -435,6 +435,11 @@
1071 return rv;
1072 }
1073
1074+
1075+#define pgp_trusted_id(uid) (!option(OPTPGPCHECKTRUST) \
1076+ || (pgp_id_is_valid((uid)) \
1077+ && pgp_id_is_strong((uid))))
1078+
1079 static pgp_key_t *pgp_select_key (pgp_key_t *keys,
1080 ADDRESS * p, const char *s)
1081 {
1082@@ -450,6 +455,7 @@
1083 pgp_uid_t *a;
1084 int (*f) (const void *, const void *);
1085
1086+ int keymatch = 0; /* count matching keys */
1087 int unusable = 0;
1088
1089 keymax = 0;
1090@@ -479,6 +485,7 @@
1091
1092 KeyTable[i++] = a;
1093 }
1094+ keymatch++;
1095 }
1096
1097 if (!i && unusable)
1098@@ -487,6 +494,21 @@
1099 mutt_sleep (1);
1100 return NULL;
1101 }
1102+ else if (keymatch == 1 && option(OPTPGPAUTOSELECT))
1103+ {
1104+ /*
1105+ * Only one matching key...see if there's an id with enough trust to auto-select
1106+ */
1107+ kp = KeyTable[0]->parent;
1108+ for (a = kp->address; a; a = a->next)
1109+ {
1110+ if (pgp_trusted_id(a))
1111+ {
1112+ safe_free ((void **) &KeyTable);
1113+ return (kp);
1114+ }
1115+ }
1116+ }
1117
1118 switch (PgpSortKeys & SORT_MASK)
1119 {
1120@@ -597,9 +619,7 @@
1121 break;
1122 }
1123
1124- if (option (OPTPGPCHECKTRUST) &&
1125- (!pgp_id_is_valid (KeyTable[menu->current])
1126- || !pgp_id_is_strong (KeyTable[menu->current])))
1127+ if (!pgp_trusted_id(KeyTable[menu->current]))
1128 {
1129 char *s = "";
1130 char buff[LONG_STRING];
1131diff -rU3 --new-file mutt-1.3.99-vanilla/protos.h mutt-1.3.99/protos.h
1132--- mutt-1.3.99-vanilla/protos.h Thu May 23 14:12:14 2002
1133+++ mutt-1.3.99/protos.h Thu May 23 14:13:33 2002
1134@@ -130,7 +130,7 @@
1135 char *mutt_get_name (ADDRESS *);
1136 char *mutt_get_parameter (const char *, PARAMETER *);
1137 #ifdef HAVE_PGP
1138-char *mutt_pgp_hook (ADDRESS *);
1139+LIST *mutt_pgp_hook (ADDRESS *);
1140 #endif /* HAVE_PGP */
1141 char *mutt_make_date (char *, size_t);
1142
1143diff -rU3 --new-file mutt-1.3.99-vanilla/protos.h.orig mutt-1.3.99/protos.h.orig
1144--- mutt-1.3.99-vanilla/protos.h.orig Thu May 23 14:12:13 2002
1145+++ mutt-1.3.99/protos.h.orig Thu May 23 14:12:14 2002
1146@@ -220,6 +220,7 @@
1147 void mutt_shell_escape (void);
1148 void mutt_show_error (void);
1149 void mutt_signal_init (void);
1150+void mutt_signature (char *);
1151 void mutt_stamp_attachment (BODY *a);
1152 void mutt_tabs_to_spaces (char *);
1153 void mutt_tag_set_flag (int, int);
This page took 0.364038 seconds and 4 git commands to generate.