]>
Commit | Line | Data |
---|---|---|
1d12b69c | 1 | diff -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 | |
9 | diff -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> | |
23 | diff -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 > %t" | |
106 | +close-hook \\.gz$ "gzip -c %t > %f" | |
107 | +append-hook \\.gz$ "gzip -c %t >> %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="$save_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: %f, which is replaced with the | |
136 | +(compressed) folder name, and %t which is replaced with the | |
137 | +name of the temporary folder to which to write. | |
138 | + | |
139 | +%f and %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, %% is replaced by | |
142 | +%, as in printf, and any other %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 > %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 > %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 >> %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="$mbox_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 < %f > %t" | |
231 | +close-hook \\.pgp$ "pgp -fe YourPgpUserIdOrKeyId < %t > %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 < %f > %t" | |
242 | +close-hook \\.gpg$ "gpg --encrypt --recipient YourGpgUserIdOrKeyId < %t > %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_order"></tt> <em/mimetype/ [ <em/mimetype/ ... ] | |
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_view"></tt> <em/mimetype/ [ <em/mimetype/ ... ] | |
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/ [ <em/regexp/ ] | |
267 | <item> | |
268 | <tt><ref id="color" name="uncolor"></tt> <em/index/ <em/pattern/ [ <em/pattern/ ... ] | |
269 | @@ -2919,6 +3126,8 @@ | |
270 | <item> | |
271 | <tt><ref id="my_hdr" name="unmy_hdr"></tt> <em/field/ [ <em/field/ ... ] | |
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/ | |
278 | diff -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" | |
292 | diff -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 | ||
335 | diff -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 | |
836 | diff -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 | |
869 | diff -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 | |
885 | diff -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 | |
890 | diff -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, | |
904 | diff -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 */ | |
923 | diff -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); | |
1067 | diff -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]; | |
1131 | diff -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 | ||
1143 | diff -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); |