Mercurial > hg > xemacs-beta
comparison lisp/packages/crypt.el @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | e04119814345 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
1 ;;; crypt.el --- code for handling all sorts of compressed and encrypted files | |
2 | |
3 ;; Author: Lawrence R. Dodd <dodd@roebling.poly.edu> | |
4 ;; Rod Whitby <rwhitby@research.canon.oz.au> | |
5 ;; Kyle E. Jones <kyle@uunet.uu.net> | |
6 ;; Maintainer: Lawrence R. Dodd <dodd@roebling.poly.edu> | |
7 ;; Created: crypt.el in 1988, crypt++.el on 18 Jan 1993 | |
8 ;; Version: 2.82 | |
9 ;; Date: 1994/03/31 12:30:17 | |
10 ;; Keywords: extensions | |
11 | |
12 ;;; Copyright (C) 1994 Lawrence R. Dodd | |
13 ;;; Copyright (C) 1993 Lawrence R. Dodd and Rod Whitby | |
14 ;;; Copyright (C) 1988, 1989, 1990 Kyle E. Jones | |
15 ;;; | |
16 ;;; This program is free software; you can redistribute it and/or modify | |
17 ;;; it under the terms of the GNU General Public License as published by | |
18 ;;; the Free Software Foundation; either version 2 of the License, or | |
19 ;;; (at your option) any later version. | |
20 ;;; | |
21 ;;; This program is distributed in the hope that it will be useful, | |
22 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24 ;;; GNU General Public License for more details. | |
25 ;;; | |
26 ;;; You should have received a copy of the GNU General Public License | |
27 ;;; along with this program; if not, write to the Free Software | |
28 ;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
29 | |
30 ;;; Synched up with: Not in FSF. | |
31 | |
32 ;;; Commentary: | |
33 | |
34 ;;; NOTE: Apparently not being maintained by the author, who now | |
35 ;;; uses jka-compr.el. --ben (1/26/96) | |
36 ;;; Included patch (1/26/96) | |
37 | |
38 ;;; Please see notes on INSTALLATION and USAGE on the pages below. | |
39 | |
40 ;;; LCD Archive Entry: | |
41 ;;; crypt++|Rod Whitby and Lawrence R. Dodd|dodd@roebling.poly.edu| | |
42 ;;; Code for handling all sorts of compressed and encrypted files.| | |
43 ;;; 1994/03/31 12:30:17|2.82|~/misc/crypt++.el.Z| | |
44 | |
45 ;;; AVAILABLE: | |
46 ;;; | |
47 ;;; via anonymous ftp to roebling.poly.edu [128.238.5.31] in | |
48 ;;; /pub/lisp/crypt++.el.gz | |
49 ;;; | |
50 ;;; via anonymous ftp to archive.cis.ohio-state.edu [128.146.8.52] in | |
51 ;;; /pub/gnu/emacs/elisp-archive/misc/crypt++.el.Z | |
52 | |
53 ;;; BUG REPORTS | |
54 ;;; | |
55 ;;; Type M-x crypt-submit-report to generate a bug report template or put your | |
56 ;;; cursor at the end of this line and type C-x C-e: (crypt-submit-report) | |
57 ;;; | |
58 ;;; Please note that this bug-report facility (crypt-submit-report) uses Barry | |
59 ;;; Warsaw's reporter.el which is part of GNU Emacs v19 and bundled with many | |
60 ;;; other packages. If needed, you can obtain a copy of reporter.el at | |
61 ;;; /roebling.poly.edu:/pub/reporter.el or the elisp-archive. In fact, | |
62 ;;; crypt-submit-report will attempt to ange-ftp a copy for you from roebling | |
63 ;;; if you do not have one accessible. | |
64 | |
65 ;;; Lawrence R. Dodd <dodd@roebling.poly.edu> | |
66 ;;; Polytechnic University | |
67 ;;; Brooklyn, New York USA | |
68 | |
69 ;;; VERSION: | |
70 ;;; | |
71 ;;; Version: 2.82 | |
72 ;;; Ident: crypt++.el,v 2.82 1994/03/31 12:30:17 dodd Exp | |
73 ;;; Date: 1994/03/31 12:30:17 | |
74 | |
75 | |
76 ;;; INSTALLATION: | |
77 ;;; | |
78 ;;; To use this package, simply put it in a file called "crypt.el" in a Lisp | |
79 ;;; directory known to Emacs (see `load-path'), byte-compile it (you may get a | |
80 ;;; warning saying that the function reporter-submit-bug-report is not known | |
81 ;;; to be defined -- ignore it), and put the line: | |
82 ;;; | |
83 ;;; (require 'crypt) | |
84 ;;; | |
85 ;;; in your ~/.emacs file or in the file default.el in the ../lisp directory | |
86 ;;; of the Emacs distribution. Do not bother trying to autoload this file; | |
87 ;;; this package uses find-file and write-file hooks and thus should be loaded | |
88 ;;; the first time you visit any sort of file. Any package loaded after this | |
89 ;;; one that appends something to `write-file-hooks' will not be executed | |
90 ;;; because this package writes out the file. Other packages that append to | |
91 ;;; `write-file-hooks' should either be modified to prepend to that hook or be | |
92 ;;; loaded before this one (preferably the former). | |
93 | |
94 ;;; NOTE: encryption users should set `crypt-encryption-type' to one of the | |
95 ;;; values in `crypt-encryption-alist' (see USAGE below). | |
96 | |
97 ;;; SEE ALSO: /roebling.poly.edu:/pub/crypt++-fnf.el for file-not-found | |
98 ;;; support for GNU Emacs. | |
99 | |
100 ;;; SPECIAL NOTES: | |
101 ;;; | |
102 ;;; If crypt is dumped with the emacs executable, or if it has already been | |
103 ;;; loaded in an emacs session, then modifying the variables used in building | |
104 ;;; the encryption and encoding tables will have no effect until these tables | |
105 ;;; are rebuilt. This may be done with `M-x crypt-rebuild-tables'. See USAGE | |
106 ;;; below to determine variables for which this is needed. For example, | |
107 ;;; post-load changes to `crypt-encryption-file-extension' or | |
108 ;;; `crypt-freeze-vs-fortran' can be incorporated into the encryption table | |
109 ;;; via `M-x crypt-rebuild-tables'. Similarly, post-load changes to | |
110 ;;; `crypt-bind-insert-file' are handled with `M-x crypt-bind-insert-file'. | |
111 | |
112 | |
113 ;;; USAGE: | |
114 ;;; | |
115 ;;; By default, intended to be transparent. User-defined variables | |
116 ;;; | |
117 ;;; controlling ENCRYPTION are | |
118 ;;; | |
119 ;;; crypt-encryption-type | |
120 ;;; crypt-encryption-file-extension | |
121 ;;; crypt-never-ever-decrypt | |
122 ;;; crypt-auto-write-buffer-encrypted | |
123 ;;; crypt-confirm-password | |
124 ;;; crypt-encrypted-disable-auto-save | |
125 ;;; crypt-encryption-alist | |
126 ;;; | |
127 ;;; controlling ENCODING are | |
128 ;;; | |
129 ;;; crypt-auto-decode-buffer | |
130 ;;; crypt-auto-write-buffer | |
131 ;;; crypt-query-if-interactive | |
132 ;;; crypt-no-extension-implies-plain | |
133 ;;; crypt-freeze-vs-fortran | |
134 ;;; crypt-compact-vs-C++ | |
135 ;;; crypt-ignored-filenames | |
136 ;;; crypt-default-encoding | |
137 ;;; crypt-encoded-disable-auto-save | |
138 ;;; crypt-encoding-alist | |
139 ;;; | |
140 ;;; controlling file insertion are | |
141 ;;; | |
142 ;;; crypt-bind-insert-file | |
143 ;;; crypt-auto-decode-insert | |
144 ;;; | |
145 ;;; To find out more about these variables, load this file, put your cursor at | |
146 ;;; the end of any of the variable names, and hit C-h v [RET]. | |
147 ;;; | |
148 ;;; NOTE: encryption users should set `crypt-encryption-type' to one of the | |
149 ;;; values in `crypt-encryption-alist' | |
150 ;;; | |
151 ;;; Although rarely needed, the following functions may be called interactively | |
152 ;;; | |
153 ;;; (crypt-encoded-mode) | |
154 ;;; (crypt-encode-region) | |
155 ;;; (crypt-encrypted-mode) | |
156 ;;; (crypt-encrypt-region) | |
157 ;;; (crypt-set-encryption-key) | |
158 ;;; (crypt-rebuild-tables) | |
159 ;;; (crypt-insert-file) | |
160 ;;; (crypt-bind-insert-file) | |
161 ;;; (crypt-submit-report) | |
162 ;;; | |
163 ;;; To find out more about these functions, load this file, put your cursor | |
164 ;;; inside any of the `()' of the above lines, and hit C-h f [RET]. | |
165 | |
166 | |
167 ;;; NOTES ON INTERFACES WITH OTHER PROGRAMS AND PACKAGES: | |
168 ;;; | |
169 ;;; GZIP: the environment variable GZIP of gzip can cause an error if it | |
170 ;;; contains `--verbose' because standard output messages will be appended to | |
171 ;;; gzip'ed files. This corrupts the files. The cleanest solution is to pass | |
172 ;;; the `--quiet' switch in `crypt-encoding-alist' to override this. use gzip | |
173 ;;; version 1.0.4 or higher from prep.ai.mit.edu:/pub/gnu | |
174 ;;; | |
175 ;;; TAR-MODE: works properly with version 1.28 (or higher) with v19 emacs. | |
176 | |
177 | |
178 ;;; DESCRIPTION: | |
179 ;;; | |
180 ;;; The basic purpose of this package of Lisp functions is to recognize | |
181 ;;; automatically encrypted and encoded (i.e., compressed) files when they are | |
182 ;;; first visited or written. The BUFFER corresponding to the file is decoded | |
183 ;;; and/or decrypted before it is presented to the user. The file itself is | |
184 ;;; unchanged on the disk. When the buffer is subsequently saved to disk, a | |
185 ;;; hook function re-encodes the buffer before the actual disk write takes | |
186 ;;; place. | |
187 ;;; | |
188 ;;; This package recognizes all sorts of compressed files by a magic number at | |
189 ;;; the beginning of these files but uses a heuristic to detect encrypted | |
190 ;;; files. If you are asked for an encryption key for a file that is in fact | |
191 ;;; not encrypted, just hit RET and the file will be accepted as is, and the | |
192 ;;; crypt minor mode will not be entered. | |
193 ;;; | |
194 ;;; Other types of encoding programs may be added to this package by using the | |
195 ;;; variable `crypt-encoding-alist' which contains a table of encoding | |
196 ;;; programs such as compress, gzip (GNU zip), freeze, and compact. | |
197 ;;; | |
198 ;;; This new extended version of crypt now monitors the filename extensions of | |
199 ;;; buffers that are written out using write-file (C-x C-w). If the filename | |
200 ;;; extension matches one of the extensions listed in `crypt-encoding-alist,' | |
201 ;;; then this package will write the file out using the corresponding encoding | |
202 ;;; (compression) method. This is done whether or not the buffer originated | |
203 ;;; from a previously encoded (compressed) file. | |
204 ;;; | |
205 ;;; Thus, if the user is editing a file that may or may not have been encoded | |
206 ;;; originally (e.g., foobar.Z or foobar) and decides to write it to a | |
207 ;;; different file (e.g., barfoo or barfoo.z or barfoo.C). This package will | |
208 ;;; examine the filename extension and write the buffer in plain format or an | |
209 ;;; alternate encoding (compression) format by searching through the entries | |
210 ;;; in the table of encoding methods `crypt-encoding-alist.' This change in | |
211 ;;; encoding state is done automatically if the variable | |
212 ;;; `crypt-auto-write-buffer' is t otherwise the user is asked. | |
213 | |
214 | |
215 ;;; TO DO/KNOWN BUGS/HELP WANTED/APPLY WITHIN: | |
216 ;;; | |
217 ;;; All Users/hackers out there are strongly encouraged to pursue any of these | |
218 ;;; matters further (especially those that concern encryption and decryption!). | |
219 ;;; It is important to future programmers and modifiers of crypt++.el to know | |
220 ;;; about its perceived limitations. Since necessity drives invention, users | |
221 ;;; who find any of the following features of crypt++.el annoying are asked to | |
222 ;;; make suggestions and send patches (again, especially those that concern | |
223 ;;; encryption and decryption!). | |
224 ;;; | |
225 ;;; * currently crypt++ assumes that if a file is both encrypted and encoded | |
226 ;;; (i.e., compressed) that the order in which it was done was encryption | |
227 ;;; first _then_ compression. As has been pointed by many people compression | |
228 ;;; following encryption is useless since the encrypted file is basically | |
229 ;;; random. On the other hand, many agree that doing encryption _following_ | |
230 ;;; compression is better since it makes it harder to crack the encryption. | |
231 ;;; We would like to make the ordering of these two user-configurable or if | |
232 ;;; nothing else change the order. | |
233 ;;; | |
234 ;;; Having read the above however, Francois Pinard <pinard@iro.umontreal.ca> | |
235 ;;; writes that encryption following compression may not be harder to crack | |
236 ;;; since "the fact that the first few uncrypted bytes are expected (the | |
237 ;;; compress signature) facilitates a serious attempt at uncrypting." | |
238 ;;; jwz agrees with Francois. | |
239 ;;; | |
240 ;;; * get write-region and append-to-file to handle encoded and encrypted | |
241 ;;; files. There is an interesting low-level encoding package by Jay Adams | |
242 ;;; <jka@ece.cmu.edu> called jka-compr.el that might address some of these | |
243 ;;; issues. We encourage hackers out there to come up with crypt++ versions | |
244 ;;; of write-region and append-to-file. The difficulty is creating versions | |
245 ;;; that mimic the originals as closely as possible. | |
246 ;;; | |
247 ;;; * instead of using call-process-region (which can fail badly if the region | |
248 ;;; is large and there's not much room in /tmp), write the region to a temp | |
249 ;;; file (with a customisable location) and use call-process directly. | |
250 ;;; | |
251 ;;; * users have mentioned trouble using crypt++ and hilit simultaneously since | |
252 ;;; the functions in write-file-hook for both write the file to disk and | |
253 ;;; return t. A possible solution is to have one of them write to a | |
254 ;;; scratch buffer instead of to disk and return nil and then allow the | |
255 ;;; other to do its work on the scratch buffer and write it to disk. Thanks | |
256 ;;; to Wayne Folta <folta@cs.UMD.EDU> and Amir J Katz <amir@matis.ingr.com>. | |
257 ;;; It would be nice to have another way in emacs to have an | |
258 ;;; after-write-file-hook and a before-write-file-hook of some sort. | |
259 ;;; Lucid Emacs has an after-write-file-hook. Recent versions of hilit19.el | |
260 ;;; do not automatically attach to `write-file-hooks' and return t. | |
261 ;;; However, the general problem of multiple packages returning t still | |
262 ;;; remains. dos-mode.el and crypt.el also conflict. | |
263 ;;; | |
264 ;;; * another possible source of trouble is with encryption (and encoding) | |
265 ;;; programs sticking verbose output into buffers prior to being written to | |
266 ;;; disk. This was definitely occurring with gzip because of --verbose in | |
267 ;;; the GZIP environment variable and is solved/hidden with the --quiet | |
268 ;;; switch. However, I suspect that some encryption problems out there are | |
269 ;;; capable of similar things so the user should be careful. | |
270 ;;; | |
271 ;;; * integrating crypt++ with a backgrounding package such as Olin Shivers' | |
272 ;;; `background.el' might be useful too. thanks to Mark Borges | |
273 ;;; <mdb@noaacrd.Colorado.EDU> for suggesting this. | |
274 ;;; | |
275 ;;; * Performing M-x crypt-encode-buffer or M-x crypt-encrypt-buffer and then | |
276 ;;; saving the file would possibly cause errors. It is better to toggle | |
277 ;;; `crypt-encoded-mode' (or `crypt-encrypted-mode') and simply save the | |
278 ;;; file. It is for this reason that `crypt-encode-buffer' and | |
279 ;;; `crypt-encrypt-buffer' are not interactive. | |
280 ;;; | |
281 ;;; * use plists instead of alists replacing calls to `nth' with `get' | |
282 ;;; | |
283 ;;; * merge encryption code completely into encoding code making encryption | |
284 ;;; just a special case of encoding. | |
285 | |
286 | |
287 ;;; Change log: | |
288 ;;; | |
289 ;;; 1.1 - original version of crypt.el | |
290 ;;; 1.2 - | |
291 ;;; jwz: works with tar-mode.el | |
292 ;;; jwz: applied patch from piet, merged with Lawrence Dodd's gzip version | |
293 ;;; 1.3 - | |
294 ;;; lrd: fixed compress-magic-regexp | |
295 ;;; 1.4, 1.5, 1.6 - | |
296 ;;; lrd: write-file compresses or gzips based on file extension | |
297 ;;; 2.1 - | |
298 ;;; lrd: merged with Rod Whitby's table-driven version (major upgrade) | |
299 ;;; 2.2 - | |
300 ;;; rjw: Changed file name to crypt++.el, so archie and lispdir can find it. | |
301 ;;; 2.3 - | |
302 ;;; rjw: Separated the hook additions and minor mode alist additions. | |
303 ;;; 2.4 - | |
304 ;;; rjw: Fixed the interactive form for crypt-buffer. | |
305 ;;; 2.5 - | |
306 ;;; lrd: doc mods, changed GNU free software notice (was out of date), added | |
307 ;;; anonymous ftp information | |
308 ;;; 2.6 - | |
309 ;;; lrd: added back in definition of `buffer' in defun crypt-buffer caused | |
310 ;;; an error when trying to read encrypted file; modified check for minor | |
311 ;;; mode alist addition; added gzip magic number warning | |
312 ;;; 2.7 - [posted to gnu.emacs.sources] | |
313 ;;; lrd: added `TO DO' and `KNOW BUGS' section to header | |
314 ;;; 2.8 - | |
315 ;;; lrd: added note about updating to v 1.24 of tar-mode.el | |
316 ;;; Thanks to Mark Borges <mdb@noaacrd.Colorado.EDU> | |
317 ;;; 2.9 - | |
318 ;;; lrd: moved query about `crypt-freeze-vs-fortran' out of defvar for | |
319 ;;; `crypt-encoding-alist,' an erroneous value of nil was being stuck into | |
320 ;;; alist when user set `crypt-freeze-vs-fortran' was nil, doc mod. | |
321 ;;; Thanks to Mark Borges <mdb@noaacrd.Colorado.EDU> | |
322 ;;; 2.10 - | |
323 ;;; rjw: moved query about `crypt-freeze-vs-fortran' back into defvar for | |
324 ;;; `crypt-encoding-alist,' - used append to ignore the erroneous nil. | |
325 ;;; 2.11 - | |
326 ;;; rjw: fixed a bug in my fix :-( | |
327 ;;; 2.12 - | |
328 ;;; rjw: Defvar crypt-magic-regexp and crypt-magic-regexp-inverse and | |
329 ;;; allow either a regexp or an elisp expression. | |
330 ;;; Suggested by Franc,ois Pinard <pinard@iro.umontreal.ca>. | |
331 ;;; 2.13 - | |
332 ;;; lrd: added in info on lispdir.el, doc mods and some puttering while | |
333 ;;; looking over rjw's v 2.12 mods. | |
334 ;;; 2.14 - | |
335 ;;; lrd: doc mod - trivial huh? switched `compact' and `gzip' in | |
336 ;;; `crypt-encoding-alist' - want gzip near top | |
337 ;;; 2.15 - | |
338 ;;; lrd: added in LCD Archive Entry and modified comments on tar-mode.el | |
339 ;;; since the version at the elisp-archive now works with crypt++.el | |
340 ;;; 2.16 - | |
341 ;;; lrd: provide `crypt' as well as `crypt++' allowing something like `ln -s | |
342 ;;; crypt++.el crypt.el' to be meaningful | |
343 ;;; Suggested (by|as) Per Abrahamsen <amanda@iesd.auc.dk> | |
344 ;;; 2.17 - | |
345 ;;; lrd: clarified bug report procedure, added fancy pseudo-graphics, added | |
346 ;;; to the `TO DO' list, put RCS tags in LCD Archive entry | |
347 ;;; 2.18 - [posted to gnu.emacs.sources] | |
348 ;;; lrd: included pointer to elisp archive in crypt-version description, | |
349 ;;; changed "Decode buffer %s? " to "Decode %s? " in crypt-find-file-hook | |
350 ;;; to be more general (mainly for crypt-insert-file) | |
351 ;;; 2.19 - | |
352 ;;; rjw: Added the crypt-compact-vs-C++ switch to distinguish compacted and | |
353 ;;; C++ files. | |
354 ;;; 2.20 - | |
355 ;;; lrd: (1) modified interactive form of crypt-buffer. (2) made search | |
356 ;;; case-insensitive in crypt-submit-report. (3) modified encoded-mode and | |
357 ;;; crypt-mode so that buffer-modified is not unconditionally set to nil | |
358 ;;; when the mode is not changed. Thanks to Gerd Hillebrand | |
359 ;;; <ggh@cs.brown.edu> for suggesting (2) and (3). | |
360 ;;; 2.21 - | |
361 ;;; rjw: Added an entry to the TODO list about the hazards of using | |
362 ;;; call-process-region on a large region and not much room in /tmp | |
363 ;;; (David Carlisle <carlisle@computer-science.manchester.ac.uk>). | |
364 ;;; 2.22 - | |
365 ;;; lrd: allow write-file-hooks to contain functions as well as lists. | |
366 ;;; Contributed by Ken Laprade <laprade@trantor.harris-atd.com>. | |
367 ;;; 2.23 - | |
368 ;;; lrd: made crypt-submit-report list values of more user-defined variables | |
369 ;;; 2.24 - | |
370 ;;; lrd: pass the -q switch to gzip to thwart the possibility of a --verbose | |
371 ;;; in the GZIP environment variable | |
372 ;;; 2.25 - | |
373 ;;; lrd: added some more to the TO DO list, clarified some things, also | |
374 ;;; untabified the entire file (I got tired of the control I's) | |
375 ;;; 2.26 - | |
376 ;;; lrd: use the long-named options for GNU zip (self-documenting) | |
377 ;;; 2.27 - | |
378 ;;; lrd: included observation by Francois Pinard <pinard@iro.umontreal.ca> | |
379 ;;; and worked on text in TO DO/KNOWN BUGS list | |
380 ;;; 2.28 - | |
381 ;;; lrd: added two new variables in (crypt-submit-report) to the list stuck | |
382 ;;; at the bottom of the mail message; changed the comments regarding the | |
383 ;;; user-defined variables. added in default values in user defined | |
384 ;;; variables. added to and removed stuff to the `TO DO' list. | |
385 ;;; | |
386 ;;; (encoded-mode): | |
387 ;;; added in code to remove any auto-save-files that may have been formed | |
388 ;;; before becoming an encoded buffer (for example a plain file saved to | |
389 ;;; disk encoded had orphan auto-save-files left behind). turning off | |
390 ;;; auto-save-mode disables the creation of auto-save-files, but it also | |
391 ;;; disables the possibility of these being removed when the buffer is | |
392 ;;; saved. | |
393 ;;; | |
394 ;;; (crypt-region): | |
395 ;;; now call the encryption and decryption program directly instead of | |
396 ;;; through the shell. this is more secure since the shell will expose the | |
397 ;;; password (key). thanks to Jon Cargille <jcargill@cs.wisc.edu>. defined | |
398 ;;; two new variables `crypt-decryption-args' and `crypt-encryption-args' to | |
399 ;;; take the arguments separately. removed (let ((opoint)...)) construct | |
400 ;;; this was a throw back to some old dead code and was not being used. | |
401 ;;; 2.29 - | |
402 ;;; lrd: added three new variables in (crypt-submit-report); added to the | |
403 ;;; `TO DO' list. | |
404 ;;; | |
405 ;;; (encode-region,encode-buffer,encoded-mode): fixed interactive forms - | |
406 ;;; the conversion to table version had eliminated some of the interactive | |
407 ;;; features of these. thanks to Kimball Collins <kpc@ptolemy.arc.nasa.gov> | |
408 ;;; for point this out. new interactive form uses functions | |
409 ;;; `crypt-get-encoding-type' and `crypt-symbol-alist-to-table' and variable | |
410 ;;; `crypt-default-encoding' to generate completion list of encoding types. | |
411 ;;; | |
412 ;;; (crypt-write-file-hook): two new user-defined variables | |
413 ;;; `crypt-query-if-interactive' and `crypt-no-extension-implies-plain' and | |
414 ;;; the buffer-local variable `buffer-interactive-mode' are used to help | |
415 ;;; determined whether or not plain output is really desired for files | |
416 ;;; without a compression file-name extension. the default behavior is the | |
417 ;;; same as before. | |
418 ;;; 2.30 - | |
419 ;;; lrd: added test for user-defined variable `crypt-never-ever-decrypt' | |
420 ;;; when finding a file. some users may never wish to decrypt files | |
421 ;;; and like to edit binary files. thanks to Nelson Minar | |
422 ;;; <nelson@reed.edu>. added to doc-strings of | |
423 ;;; `crypt-magic-regexp[-inverse]' -- these can be set to nil[t] and | |
424 ;;; accomplish the same thing as setting `crypt-never-ever-decrypt' to t | |
425 ;;; 2.31 - | |
426 ;;; rjw: Updated the comments in the encryption check section. | |
427 ;;; 2.32 - [posted to gnu.emacs.sources] | |
428 ;;; lrd: added warning about `crypt-(de|en)cryption-program'; doc mod. | |
429 ;;; 2.33 - | |
430 ;;; lrd: if `crypt-(de|en)cryption-args' are nil then don't pass any | |
431 ;;; arguments to (de|en)cryption program, nil is the default instead of | |
432 ;;; "". Thanks to Joe Ilacqua <spike@world.std.com>, David J. Schur | |
433 ;;; <djs@idm.com>, Peter Nuth <nuth@ai.mit.edu>, and Greg Larson | |
434 ;;; <glarson@bnr.ca>. `-q' exists in gzip 1.0.3 but not `--quiet' changed | |
435 ;;; GZIP NOTE. Thanks to Chris Moore <moore@src.bae.co.uk>. | |
436 ;;; 2.34 - | |
437 ;;; lrd: allow `crypt-(de|en)cryption-args' to be a list of strings -- more | |
438 ;;; robust. query for password (key), if none is set, when writing out file | |
439 ;;; for which `buffer-save-encrypted' is t. Thanks to John Interrante | |
440 ;;; <interran@uluru.Stanford.EDU>. (crypt-write-file-hook): check filename | |
441 ;;; extension against regexp `crypt-encryption-file-extension' and query for | |
442 ;;; encryption, unless `crypt-auto-write-buffer-encrypted' is t (don't | |
443 ;;; bother doing reverse check, encrypted to plain, not a common request). | |
444 ;;; (crypt-mode): delete auto-save files (cf., encoded-mode), may exist now. | |
445 ;;; (read-string-no-echo): applied patch from Piet van Oostrum | |
446 ;;; <piet@cs.ruu.nl> -- set `cursor-in-echo-area' _after_ setting buffer | |
447 ;;; (this was screwing up gnews). | |
448 ;;; 2.35 - | |
449 ;;; lrd: doc mod | |
450 ;;; 2.36 - | |
451 ;;; lrd: fixed typo, added RMAIL note. | |
452 ;;; 2.37 - [posted to gnu.emacs.sources] | |
453 ;;; lrd: | |
454 ;;; (crypt-write-file-hook): search user-defined list | |
455 ;;; `crypt-ignored-filenames' for possible match with `buffer-filename' | |
456 ;;; before attempting conversion from compressed to plain format; useful for | |
457 ;;; compressed incoming mail files (e.g., RMAIL, INBOX). | |
458 ;;; | |
459 ;;; (crypt-mode): query for key if not set already; need to switch order of | |
460 ;;; recovering key and toggling crypt-mode in crypt-find-file-hook (thanks | |
461 ;;; to Piet van Oostrum <piet@cs.ruu.nl>). | |
462 ;;; | |
463 ;;; (crypt-buffer) and (encode-buffer): remove interactive form; use | |
464 ;;; (crypt-mode) and (encoded-mode) instead so encryption and compression | |
465 ;;; are done at the very end; leave interactive form in (crypt-region) and | |
466 ;;; (encode-region) may still be used. | |
467 ;;; | |
468 ;;; (set-encryption-key): remove from `command-history' if called | |
469 ;;; interactively - thanks to George M. Georgiou | |
470 ;;; <georgiou@silicon.csci.csusb.edu>. | |
471 ;;; 2.38 - | |
472 ;;; lrd: added `crypt-' prefix to `(read-string-no-echo)' and `(save-point)' | |
473 ;;; changed file extension for gzip files to `.z' _or_ `.gz' (future release | |
474 ;;; of gzip with use later extension by default and so this should be | |
475 ;;; changed to just `.gz' someday). | |
476 ;;; 2.39 - | |
477 ;;; lrd: doc mod. added in patch from jwz - `(crypt-read-string-no-echo)' is | |
478 ;;; more secure, put property 'permanent-local on buffer-locals works for | |
479 ;;; Lucid Emacs and doesn't harm v18 emacs, change `buffer-interactive-mode' | |
480 ;;; to `buffer-interactive-encoded-mode.' | |
481 ;;; 2.40 - | |
482 ;;; lrd: put property 'preserved in case kill-fix.el is being used. | |
483 ;;; 2.41 - | |
484 ;;; lrd: all functions and variables now start with `crypt-', moved REVISION | |
485 ;;; HISTORY to bottom of header, interactive version of | |
486 ;;; `(crypt-encrypt-region)' clearer, `(crypt-read-string-no-echo)' now | |
487 ;;; echos `.' | |
488 ;;; 2.42 - | |
489 ;;; lrd: (crypt-check-extension-for-encoding): broke out of | |
490 ;;; `(crypt-write-file-hook)'. setting user variables | |
491 ;;; `crypt-compact-vs-C++' and `crypt-freeze-vs-fortran' to nil no longer | |
492 ;;; completely disables the reading compact'ed and frozen files but just | |
493 ;;; disables the use of the file-extension tricks of | |
494 ;;; `(crypt-check-extension-for-encoding).' (crypt-encode-region): allow | |
495 ;;; for a single line message from encoding program at top of region; if it | |
496 ;;; is there, then remove it; kludge for `compact' program. | |
497 ;;; 2.43 - | |
498 ;;; lrd: (crypt-encode-region): generalize the clean up procedure; add | |
499 ;;; element to `crypt-encoding-alist' and introduce new function | |
500 ;;; `(crypt-encoding-cleanup-regexp)' to extract a compression specific | |
501 ;;; regexp for erroneous message or lisp expression for cleanup. | |
502 ;;; 2.44 - | |
503 ;;; lrd: new element for `crypt-encoding-alist' handles whether or not | |
504 ;;; file-name extension tricks may be play with encoding method; compact and | |
505 ;;; freeze values default to `crypt-compact-vs-C++' and | |
506 ;;; `crypt-freeze-vs-fortran' (thanks to rjw); | |
507 ;;; (crypt-encoding-extension-tricks): new defun to handle this; | |
508 ;;; (crypt-check-extension-for-encoding): monitors "tricks" entry of | |
509 ;;; `crypt-encoding-alist' and adjust the bag of tricks it can apply. | |
510 ;;; 2.45 - | |
511 ;;; lrd: (crypt-encode-region): delete entire match of cleanup regexp by | |
512 ;;; requiring newlines in GARBAGE-REGEXP-OR-LISPEXP. (crypt-submit-report): | |
513 ;;; use Warsaw's reporter.el. | |
514 ;;; 2.46 - | |
515 ;;; lrd: (crypt-find-file-hook, crypt-write-file-hook): cleaned, documented, | |
516 ;;; and replaced occurrences of `(cond (C BODY))' with `(if C BODY)'; | |
517 ;;; changed `crypt-magic-regexp' to `crypt-encryption-magic-regexp' and | |
518 ;;; `crypt-magic-regexp-inverse' to `crypt-encryption-magic-regexp-inverse' | |
519 ;;; for consistency with other variable names. new user-defined variable | |
520 ;;; `crypt-encryption-minor-mode-name' instead of always "Crypt". grouped | |
521 ;;; all encryption variables together. | |
522 ;;; 2.47 - | |
523 ;;; lrd: somewhat major change - put program-specific encryption variables | |
524 ;;; into a single table `crypt-encryption-alist' and let the variable | |
525 ;;; `crypt-encryption-type' define the appropriate entry to use; new | |
526 ;;; user-defined variable `crypt-confirm-password,' thanks to Jeff Clark | |
527 ;;; <jclark@src.honeywell.com>. (crypt-submit-report): improved error | |
528 ;;; handling, thanks to baw. (crypt-write-file-hook): fixed bug with | |
529 ;;; `crypt-encoding-extension-tricks' | |
530 ;;; 2.48 - | |
531 ;;; lrd: added dummy argument to `crypt-encoding-alist' and | |
532 ;;; `crypt-encryption-alist' and merged all defuns that work on their | |
533 ;;; elements into defuns that all start with `crypt-get-' and look through | |
534 ;;; both lists. simplifies some of code and closer to treating encryption | |
535 ;;; as a special case of encoding; crypt-minor-mode-alist: replaced (nth *) | |
536 ;;; with `(crypt-get-minor-mode)' call; (crypt-encode-region): allow | |
537 ;;; arguments to be list of strings; renamed (crypt-get-encoding-type) to | |
538 ;;; (crypt-read-encoding-type) for clarity. | |
539 ;;; 2.49 - [posted to gnu.emacs.sources] | |
540 ;;; lrd: (crypt-encode-region): ignore `args' if set to t | |
541 ;;; 2.50 - | |
542 ;;; lrd: (crypt-write-file-hook): in v19 we need to call `backup-buffer' | |
543 ;;; ourselves -- we write out the file and return t so `basic-save-buffer' | |
544 ;;; does not do it; also call `set-file-modes' | |
545 ;;; 2.51 - | |
546 ;;; lrd: some `defvar's are now `defconst's and tar-mode note was changed. | |
547 ;;; 2.52 - | |
548 ;;; lrd: make doc strings conform to GNU standards. | |
549 ;;; 2.53 - | |
550 ;;; lrd: made header conform to GNU Conventional Headers standard. | |
551 ;;; 2.54 - | |
552 ;;; lrd: `crypt-encryption-file-extension', `crypt-freeze-vs-fortran', | |
553 ;;; `crypt-compact-vs-C++', `crypt-encryption-magic-regexp', and | |
554 ;;; `crypt-encryption-magic-regexp-inverse' are used in defining the tables | |
555 ;;; `crypt-encoding-alist' and `crypt-encryption-alist' and so need to be set | |
556 ;;; _before_ loading crypt++. use `add-hook' if it is available. | |
557 ;;; 2.55 - | |
558 ;;; lrd: new interactive function `crypt-insert-file' mimics `insert-file' | |
559 ;;; but attempts to decode or decrypt before insertion; bound `C-x i' if | |
560 ;;; `crypt-bind-insert-file' is non-nil. comment out doc-strings from | |
561 ;;; internal subroutines, saves space. | |
562 ;;; 2.56 - | |
563 ;;; tfb: change the definitions of crypt-{encoding,encryption}-alist, to | |
564 ;;; call the functions crypt-make-{encoding,encryption}-alist resp. | |
565 ;;; Added crypt-reinit which regenerates these variables from their | |
566 ;;; functions, thus allowing this stuff to be preloaded even if people | |
567 ;;; set things in their init files. | |
568 ;;; Tim Bradshaw <tim.bradshaw@mid-heidelberg.de> | |
569 ;;; 2.57 - | |
570 ;;; lrd: untabify; remove duplicate entry in `crypt-make-encoding-alist'; | |
571 ;;; change name of `crypt-make-*-alist' to `crypt-build-*-alist' and | |
572 ;;; `crypt-reinit' to `crypt-rebuild-tables'; (crypt-read-string-no-echo): | |
573 ;;; change local variable `form' to `help-form' so it is defined; | |
574 ;;; `crypt-encryption-alist' and `crypt-encoding-alist' must be defined with | |
575 ;;; `defconst' since we wish crypt++ to initialize these variables | |
576 ;;; unconditionally; modify INSTALLATION section to reflect these changes. | |
577 ;;; 2.58 - | |
578 ;;; lrd: doc mod. | |
579 ;;; 2.59 - [posted to gnu.emacs.sources] | |
580 ;;; lrd: (crypt-bind-insert-file): new function for changing "C-x i" in | |
581 ;;; initialization file or interactively. | |
582 ;;; 2.60 - | |
583 ;;; lrd: add `crypt-rebuild-tables' and `crypt-bind-insert-file' to | |
584 ;;; `after-init-hook' in GNU emacs v19 and to `term-setup-hook' in Lucid | |
585 ;;; emacs. Change INSTALLATION notes. | |
586 ;;; 2.61 - [posted to gnu.emacs.sources] | |
587 ;;; lrd: Doc mod. Clean up the installation of minor mode indicators. | |
588 ;;; 2.62 - [posted to gnu.emacs.sources] | |
589 ;;; lrd: installed patch from stig@hackvan.com to simplify crypt-get-* defuns | |
590 ;;; (now defmacros). Don't add to `term-setup-hook' unless no | |
591 ;;; `after-init-hook' _and_ definitely running v19, otherwise Rod gets an | |
592 ;;; error at home :-<. Don't assume C-x i had `insert-file' bound to it: | |
593 ;;; store old binding in `crypt-old-binding' before overwriting and use in | |
594 ;;; function `crypt-bind-insert-file.' | |
595 ;;; 2.63 - | |
596 ;;; lrd: (crypt-encode-buffer, crypt-encode-region, crypt-encrypt-buffer, | |
597 ;;; crypt-encrypt-region): changed argument list putting optional buffer | |
598 ;;; last and making default action to encode or encrypt. (crypt-encoded-p, | |
599 ;;; crypt-encrypted-p): new functions that do the actual testing of file | |
600 ;;; contents. (crypt-find-file): uses these new functions. | |
601 ;;; (crypt-rebuild-minor-modes-alist): new function to rebuild | |
602 ;;; `minor-mode-alist' called by function crypt-rebuild-tables. | |
603 ;;; (crypt-build-minor-mode-alist): new function called by | |
604 ;;; `crypt-minor-mode-alist' to create itself. `crypt-minor-mode-encrypted' | |
605 ;;; removed because defined in function crypt-build-minor-mode-alist. | |
606 ;;; 2.64 - | |
607 ;;; lrd: (crypt-find-file-hook): temporarily remove the encrytion file | |
608 ;;; extension to help determine the major mode, just like is done with the | |
609 ;;; encoding file extension. In order for this to work properly the file | |
610 ;;; extension in `crypt-encryption-file-extension' and | |
611 ;;; `crypt-encryption-alist' needs to be inside a pair of \\( \\). | |
612 ;;; 2.65 - | |
613 ;;; lrd: (crypt-find-file-hook): move determination of key, password, into | |
614 ;;; (crypt-encrypted-p). | |
615 ;;; 2.66 - | |
616 ;;; lrd: (crypt-set-encryption-key): improve prompt string for encryption | |
617 ;;; key. | |
618 ;;; 2.67 - | |
619 ;;; lrd: (crypt-write-file-hook): make check for encryption file-name | |
620 ;;; extension case-sensitive. | |
621 ;;; 2.68 - | |
622 ;;; lrd: fixed check for previous addition to `minor-mode-alist' -- was not | |
623 ;;; working. Check for an `add-hook' function; if one does not exist then | |
624 ;;; use a copy of one from GNU Emacs 19. When using `add-hook' to append to | |
625 ;;; the `write-file-hooks' make sure that the version accepts the optional | |
626 ;;; APPEND argument -- v19's does but the one in the elisp archive by Dan | |
627 ;;; LaLiberte <liberte@cs.uiuc.edu> does not append. This causes problems. | |
628 ;;; Thanks to Francesco Potorti` <pot@fly.CNUCE.CNR.IT> for pointing this | |
629 ;;; out. | |
630 ;;; 2.69 - [posted to gnu.emacs.sources] | |
631 ;;; lrd: doc mod with regards `after-init-hook' and Lucid Emacs. Add | |
632 ;;; pointer to crypt++-fnf.el for people who might be interested. | |
633 ;;; 2.70 - | |
634 ;;; lrd: narrow conditions under which crypt-encryption-magic-regexp | |
635 ;;; matches. Thanks to Philippe Michel <michel@thomson-lcr.fr> and Francois | |
636 ;;; Pinard <pinard@iro.umontreal.ca> for helping explain this with regards | |
637 ;;; to ISO/Latin-1. | |
638 ;;; 2.71 - | |
639 ;;; lrd: applied patches from Darrin Jewell <jewell@bdi.com> for DOS to UNIX | |
640 ;;; support. DOS entry added to crypt-build-encoding-alist. | |
641 ;;; (crypt-dos-to-unix-region, crypt-unix-to-dos-region): New | |
642 ;;; functions. (crypt-dos-has-ctrl-z): New buffer-local variable. | |
643 ;;; (crypt-encode-region): allow for encoding and decoding programs to be | |
644 ;;; elisp expressions. If they are then apply them directly to region. | |
645 ;;; Point out that crypt++.el conflicts with dos-mode.el. | |
646 ;;; 2.72 - | |
647 ;;; lrd: The limit for the regular expression search done by | |
648 ;;; `crypt-encrypted-p' is extended to 100 by default. The enlargement of | |
649 ;;; search field is needed because of previous reduction in size of regexp | |
650 ;;; being searched for. (crypt-magic-search-limit): New variable defining | |
651 ;;; this new limit. (crypt-encrypted-p): Uses it and cleaned up. Doc mod. | |
652 ;;; Thanks to Philippe Michel <michel@thomson-lcr.fr>, Francois Pinard | |
653 ;;; <pinard@iro.umontreal.ca>, and Dave Goldberg <dsg@blackbird.mitre.org>. | |
654 ;;; 2.73 - [posted to gnu.emacs.sources] | |
655 ;;; lrd: Apply patch from Kevin Rodgers <kevin@traffic.den.mmc.com> that | |
656 ;;; uses more verbose messages and capitals. Doc mod. | |
657 ;;; 2.74 - | |
658 ;;; lrd: Untabify. (crypt-encrypted-p): Check value of | |
659 ;;; `crypt-never-ever-decrypt' before anything else. | |
660 ;;; 2.75 - | |
661 ;;; lrd: (crypt-version): Remove call to `substring'. | |
662 ;;; 2.76 - | |
663 ;;; lrd: (crypt-encryption-magic-regexp-inverse): Add in regexp that will | |
664 ;;; match ksh `.sh_history' files so that they are not interpreted as | |
665 ;;; encrypted files. Thanks to Francesco Potorti` <pot@fly.CNUCE.CNR.IT>. | |
666 ;;; 2.77 - [posted to gnu.emacs.sources] | |
667 ;;; lrd: (crypt-bind-insert-file): Use substitute-key-definition to bind | |
668 ;;; crypt-insert-file to whatever key insert-file is bound to (not | |
669 ;;; necessarily C-x i). Call crypt-bind-insert-file directly in | |
670 ;;; file. Variable crypt-bind-insert-file: Doc mod. Remove | |
671 ;;; crypt-old-binding. Replace `M-x foobar' in doc strings with | |
672 ;;; `\\[foobar]'. | |
673 ;;; 2.78 - | |
674 ;;; lrd: (crypt-auto-write-answer-local): New internal variable. Holds | |
675 ;;; answer to query about file-extension tricks question per buffer. Thanks | |
676 ;;; to George Forman <forman@cs.washington.edu>. Remove Rod from list of | |
677 ;;; maintainers...he's busy enough. Merge multiple setq forms into single | |
678 ;;; setq forms. | |
679 ;;; 2.79 - | |
680 ;;; lrd: (crypt-y-or-n-p): New internal function for querying. Tests the | |
681 ;;; internal variable crypt-auto-write-answer-local to ensure single query. | |
682 ;;; (crypt-check-extension-for-encoding): Replace all occurrences of queries | |
683 ;;; involving y-or-no-p constructs with crypt-y-or-n-p. | |
684 ;;; 2.80 - [posted to gnu.emacs.sources] | |
685 ;;; lrd: (crypt-set-encryption-key): Shorten interactive prompt. Change | |
686 ;;; documentation. | |
687 ;;; 2.81 - | |
688 ;;; lrd: (crypt-variable-list): Add shell and path variables. | |
689 ;;; (crypt-confirm-password): Fix spelling error in doc. | |
690 ;;; 2.82 - | |
691 ;;; lrd: Applied patch from Noah Friedman <friedman@prep.ai.mit.edu>. | |
692 ;;; (crypt-encoded-disable-auto-save, crypt-encrypted-disable-auto-save): | |
693 ;;; New user-defined variables. (crypt-encoded-mode, crypt-encrypted-mode): | |
694 ;;; Use them. | |
695 | |
696 | |
697 ;;; Code: | |
698 | |
699 ;;;; User definable variables. | |
700 | |
701 (defvar crypt-encryption-type 'crypt | |
702 "*Method of encryption. Must be an element of `crypt-encryption-alist.' | |
703 If you change this after crypt++ is loaded then do \\[crypt-rebuild-tables].") | |
704 | |
705 (defvar crypt-encryption-file-extension nil | |
706 "*Regexp for extension of files encrypted with `crypt-encryption-type.' | |
707 Should be of the form \"\\\\(\\\\.foo\\\\)$\". nil says use default values in | |
708 `crypt-encryption-alist.' If you change this after crypt++ is loaded then do | |
709 \\[crypt-rebuild-tables].") | |
710 | |
711 (defvar crypt-never-ever-decrypt nil | |
712 "*t says never attempt to decrypt a buffer.") | |
713 | |
714 (defvar crypt-auto-write-buffer-encrypted nil | |
715 "*t says files with `crypt-encryption-alist' file extension auto-encrypted. | |
716 nil says query. See `crypt-auto-write-buffer.'") | |
717 | |
718 (defvar crypt-confirm-password nil | |
719 "*t says confirm new passwords and when writing a newly encrypted buffer.") | |
720 | |
721 (defvar crypt-encoded-disable-auto-save t | |
722 "*If t, turn off auto-save-mode for buffers which are encoded. | |
723 If non-nil but not t, then no message is displayed. | |
724 | |
725 The default is t is because there isn't any way to tell emacs to encode the | |
726 autosave file, so the autosave would be in a different format from the | |
727 original. The disadvantage of turning off autosaves is that any work you | |
728 do in that buffer will be completely lost if the changes are not explicitly | |
729 saved. | |
730 | |
731 It is probably best to set this variable to nil and use buffer-local | |
732 variables in files for which you don't actually care about autosaves. | |
733 Unencoded recovery data is better than none at all.") | |
734 | |
735 (defvar crypt-encrypted-disable-auto-save t | |
736 "*If t, turn off auto-save-mode for buffers which are encrypted. | |
737 If non-nil but not t, then no message is displayed. | |
738 | |
739 The default is t is because there isn't any way to tell emacs to encrypt | |
740 the autosave file, so the autosave would be in cleartext form. The | |
741 disadvantage of turning off autosaves is that any work you do in that | |
742 buffer will be completely lost if the changes are not explicitly saved. | |
743 | |
744 You might consider setting this variable to nil and use buffer-local | |
745 variables in files for which security is more important than data | |
746 recovery.") | |
747 | |
748 ;;; ENCRYPTION | |
749 | |
750 ;;; Encrypted files have no magic number, so we have to hack a way of | |
751 ;;; determining when a buffer should be decrypted. we do this only buffers | |
752 ;;; that match a MAGIC-REGEXP very close to beginning of buffer and that do | |
753 ;;; _NOT_ match a MAGIC-REGEXP-INVERSE. | |
754 ;;; | |
755 ;;; Currently MAGIC-REGEXP matches non-ASCII characters and | |
756 ;;; MAGIC-REGEXP-INVERSE will match Sun OS, 4.x BSD, and Ultrix executable | |
757 ;;; magic numbers, so binaries can still be edited (heh) without headaches. | |
758 | |
759 (defconst crypt-encryption-magic-regexp "[\000\200-\237]" | |
760 "Regexp that must be found very close to beginning of encrypted buffer. | |
761 This is intended to be an internal variable \(not user-visible\). If you | |
762 change this after crypt++ is loaded then do \\[crypt-rebuild-tables].") | |
763 | |
764 (defconst crypt-encryption-magic-regexp-inverse | |
765 "\\`\201\001\\|^\\(..\\)?\\([\007\010\013]\001\\|\001[\007\010\013]\\)" | |
766 "Regexp that must *not* be found very close to beginning of encrypted buffer. | |
767 This is intended to be an internal variable \(not user-visible\). If you | |
768 change this after crypt++ is loaded then do \\[crypt-rebuild-tables].") | |
769 | |
770 (defconst crypt-magic-search-limit 100 | |
771 "Limit of regular expression search used to recognize encrypted files. | |
772 Maximum position in file for presence of `crypt-encryption-magic-regexp' and | |
773 absence of `crypt-encryption-magic-regexp-inverse'.") | |
774 | |
775 (defun crypt-build-encryption-alist () | |
776 ;; Returns the encryption alist | |
777 (list | |
778 ;; crypt | |
779 (list 'crypt | |
780 crypt-encryption-magic-regexp crypt-encryption-magic-regexp-inverse | |
781 (or crypt-encryption-file-extension "\\(\\.e\\)$") | |
782 "crypt" "crypt" | |
783 nil | |
784 nil | |
785 "Crypt" | |
786 nil | |
787 t | |
788 ) | |
789 ;; DES (Cipher Block Chaining - CBC) [DES' default] | |
790 (list 'des | |
791 crypt-encryption-magic-regexp crypt-encryption-magic-regexp-inverse | |
792 (or crypt-encryption-file-extension "\\(\\.des\\)$") | |
793 "des" "des" | |
794 '("-e" "-k") | |
795 '("-d" "-k") | |
796 "DES-CBC" | |
797 nil | |
798 t | |
799 ) | |
800 ;; DES (Electronic Code Book - ECB) | |
801 (list 'des-ecb | |
802 crypt-encryption-magic-regexp crypt-encryption-magic-regexp-inverse | |
803 (or crypt-encryption-file-extension "\\(\\.des\\)$") | |
804 "des" "des" | |
805 '("-e" "-b" "-k") | |
806 '("-d" "-b" "-k") | |
807 "DES-ECB" | |
808 nil | |
809 t | |
810 ) | |
811 ;; PGP | |
812 (list 'pgp | |
813 crypt-encryption-magic-regexp crypt-encryption-magic-regexp-inverse | |
814 (or crypt-encryption-file-extension "\\(\\.pgp\\)$") | |
815 "pgp" "pgp" | |
816 '("+batchmode" "+verbose=0" "-c" "-f" "-z") | |
817 '("+batchmode" "+verbose=0" "-f" "-z") | |
818 "PGP" | |
819 nil | |
820 t | |
821 ) | |
822 ;; Add new elements here ... | |
823 )) | |
824 | |
825 (defconst crypt-encryption-alist (crypt-build-encryption-alist) | |
826 "List of elements describing the encryption methods available. | |
827 each element looks like | |
828 | |
829 \(ENCRYPTION-TYPE | |
830 MAGIC-REGEXP MAGIC-REGEXP-INVERSE | |
831 FILE-EXTENSION | |
832 ENCRYPT-PROGRAM DECRYPT-PROGRAM | |
833 ENCRYPT-ARGS | |
834 DECRYPT-ARGS | |
835 MINOR-MODE | |
836 GARBAGE-REGEXP-OR-LISPEXP | |
837 FILE-EXTENSION-TRICKS | |
838 \) | |
839 | |
840 ENCRYPTION-TYPE is a symbol denoting the encryption type. | |
841 | |
842 MAGIC-REGEXP regexp that must match very close to the beginning of an | |
843 encrypted buffer. This may also be some elisp expression to be evaluated at | |
844 \(point-min\) that will return t for an encrypted buffer. If this is set to | |
845 nil then crypt++ will never try to decrypt a buffer. Currently set to the | |
846 internal variable `crypt-encryption-magic-regexp' which will match non-ASCII | |
847 characters. | |
848 | |
849 MAGIC-REGEXP-INVERSE regexp that must _NOT_ match very close to the beginning | |
850 of an encrypted buffer. This may also be some elisp expression to be | |
851 evaluated at \(point-min\) that will return t for a NON-encrypted buffer. | |
852 If this is set to t then crypt++ will never try to decrypt a buffer. | |
853 Currently set to the internal variable `crypt-encryption-magic-regexp-inverse' | |
854 which will match Sun OS, 4.x BSD, and Ultrix executable magic numbers, so | |
855 binaries can still be edited (heh) without headaches. | |
856 | |
857 FILE-EXTENSION regexp denoting the file extension usually appended the | |
858 filename of files encrypted with ENCRYPT-PROGRAM. The variable | |
859 `crypt-encryption-file-extension' will over ride the default. | |
860 | |
861 ENCRYPT-PROGRAM name of executable file to be used for encryption. | |
862 | |
863 DECRYPT-PROGRAM name of executable file to be used for decryption. | |
864 | |
865 ENCRYPT-ARGS arguments to be passed to ENCRYPT-PROGRAM may be a string or a | |
866 list of strings or nil. | |
867 | |
868 DECRYPT-ARGS arguments to be passed to DECRYPT-PROGRAM may be a string or a | |
869 list of strings or nil. | |
870 | |
871 MINOR-MODE string denoting the name for the encrypted minor mode as it will | |
872 appear in the mode line. | |
873 | |
874 GARBAGE-REGEXP-OR-LISPEXP dummy variable for compatibility with encoding. | |
875 | |
876 FILE-EXTENSION-TRICKS is t or nil depending on whether or not tricks | |
877 converting between different encryption types can be done based on | |
878 FILE-EXTENSION; typically t. | |
879 ") | |
880 | |
881 | |
882 ;;; ENCODING | |
883 | |
884 (defvar crypt-auto-decode-buffer t | |
885 "*t says buffers visiting encoded files will be decoded automatically. | |
886 nil means to ask before doing the decoding.") | |
887 | |
888 (defvar crypt-auto-write-buffer nil | |
889 "*t says save files with `crypt-encoding-alist' file extensions as encoded. | |
890 nil says to ask before doing this encoding. Similarly, buffers originating | |
891 from encoded files to be written to files not ending in `crypt-encoding-alist' | |
892 file extensions will be written in plain format automatically. nil says to | |
893 ask before doing this decoding.") | |
894 | |
895 ;; This is an internal variable documented here and not in a DOCSTRING in | |
896 ;; order to save memory. If this variable's value has been changed from its | |
897 ;; default, then it contains the answer to the question "Write out buffer | |
898 ;; foobar using `compression-type'?". This question is asked only if *plain* | |
899 ;; buffer foobar is being written to disk *and* it has a provocative | |
900 ;; `compression-type' file-name extension (see DOCSTRING for variable | |
901 ;; crypt-auto-write-buffer). The variable is local to all buffers with a | |
902 ;; default value of 'ask so if the situation described above arises, then the | |
903 ;; question is asked at least once, unless the user-defined variable | |
904 ;; crypt-auto-write-buffer is non-nil. | |
905 (defvar crypt-auto-write-answer-local 'ask) | |
906 (make-variable-buffer-local 'crypt-auto-write-answer-local) | |
907 (setq-default crypt-auto-write-answer-local 'ask) | |
908 (put 'crypt-auto-write-answer-local 'permanent-local t) ; for v19 Emacs | |
909 (put 'crypt-auto-write-answer-local 'preserved t) ; for kill-fix.el | |
910 | |
911 (defvar crypt-query-if-interactive t | |
912 "*t says ask when saving buffers where `crypt-encoded-mode' was toggled. | |
913 nil says that even if filename extension is plain (i.e., not listed in | |
914 `crypt-encoding-alist') buffer will be written in an encoded format without | |
915 asking. | |
916 | |
917 This variable is designed for users that edit a plain file (with plain | |
918 extension) and then toggle `(crypt-encoded-mode)' and do not wish to be | |
919 queried every time that they save the buffer. | |
920 | |
921 NOTE: if `(crypt-encoded-mode)' was not called interactively (the usual | |
922 scenario) then the value of this variable has no effect on how the buffer is | |
923 written to disk. In such a case `crypt-no-extension-implies-plain' is then | |
924 the relevant variable.") | |
925 | |
926 (defvar crypt-no-extension-implies-plain t | |
927 "*t says file extensions not in `crypt-encoding-alist' may be written plain. | |
928 if `crypt-auto-write-buffer' is also t then any file ending in a plain | |
929 extension is written in plain format automatically, otherwise query user. | |
930 | |
931 nil says user works with encoded (compressed) files without file extensions | |
932 and will not be queried each time they save these files. | |
933 | |
934 NOTE: (1) this does not effect find-file (C-x C-f) since that works with a | |
935 magic regexp. (2) there is no way to distinguish between write-file and | |
936 save-buffer so nil will mean that neither will query.") | |
937 | |
938 (defvar crypt-freeze-vs-fortran t | |
939 "*t says `.F' file extension denotes a frozen file not a Fortran file. | |
940 If you change this variable after crypt++ has been loaded then do | |
941 \\[crypt-rebuild-tables].") | |
942 | |
943 (defvar crypt-compact-vs-C++ nil | |
944 "*t says `.C' file extension denotes a compacted file not a C++ file. | |
945 If you change this variable after crypt++ has been loaded then do | |
946 \\[crypt-rebuild-tables].") | |
947 | |
948 (defvar crypt-ignored-filenames nil | |
949 "*List of regexp filenames for which encoded to plain conversion is not done. | |
950 A filename with a plain extension, in encoded format, that is matched by one of | |
951 these elements will be saved in encoded format without a query for conversion to | |
952 plain format. | |
953 | |
954 This variable is provided for users that want to compress their incoming mail | |
955 for RMAIL and VM which look for files `RMAIL' and `INBOX,' respectively, to | |
956 store incoming mail. For example, the gzip extensions on `RMAIL.gz' and | |
957 `INBOX.gz' can be removed, this variable set to '\(\"INBOX$\" \"RMAIL$\"\) and | |
958 no query about conversion to plain format will be made.") | |
959 | |
960 (defvar crypt-default-encoding "gzip" | |
961 "*Default encoding type as string used when `crypt-encoded-mode' is toggled. | |
962 Must match one of the elements of `crypt-encoding-alist'.") | |
963 | |
964 (defvar crypt-dos-has-ctrl-z nil | |
965 "t if this buffer had a ctrl-z stripped from end, otherwise, nil. | |
966 Buffer local and set by `crypt-dos-to-unix-region'") | |
967 (make-variable-buffer-local 'crypt-dos-has-ctrl-z) | |
968 (setq-default crypt-dos-has-ctrl-z nil) | |
969 (put 'crypt-dos-has-ctrl-z 'permanent-local t) ; for v19 Emacs | |
970 (put 'crypt-dos-has-ctrl-z 'preserved t) ; for kill-fix.el | |
971 | |
972 (defun crypt-build-encoding-alist () | |
973 ;; Returns the encoding alist | |
974 (list | |
975 ;; compress | |
976 (list 'compress | |
977 "\037\235" nil | |
978 "\\(\\.Z\\)$" | |
979 "compress" "uncompress" | |
980 nil nil | |
981 "Compress" | |
982 nil | |
983 t) | |
984 ;; gzip (GNU zip) | |
985 (list 'gzip | |
986 "\037\213" nil | |
987 "\\(\\.g?z\\)$" | |
988 "gzip" "gzip" | |
989 "--quiet" "--decompress --quiet" | |
990 "Zip" | |
991 nil | |
992 t) | |
993 ;; freeze | |
994 (list 'freeze | |
995 "\037\236\\|\037\237" nil | |
996 "\\(\\.F\\)$" | |
997 "freeze" "freeze" | |
998 "" "-d" | |
999 "Freeze" | |
1000 nil | |
1001 crypt-freeze-vs-fortran) | |
1002 ;; compact | |
1003 (list 'compact | |
1004 "\377\037" nil | |
1005 "\\(\\.C\\)$" | |
1006 "compact" "uncompact" | |
1007 nil nil | |
1008 "Compact" | |
1009 "^Compression *:.*\n" | |
1010 crypt-compact-vs-C++) | |
1011 ;; DOS | |
1012 (list 'dos | |
1013 "[^\n\r]*\r$" nil | |
1014 "\\(\\.DOS\\)$" | |
1015 'crypt-unix-to-dos-region 'crypt-dos-to-unix-region | |
1016 nil nil | |
1017 "Dos" | |
1018 nil | |
1019 nil) | |
1020 ;; Add new elements here ... | |
1021 )) | |
1022 | |
1023 (defconst crypt-encoding-alist (crypt-build-encoding-alist) | |
1024 "List of elements describing the encoding methods available. | |
1025 each element looks like | |
1026 | |
1027 \(ENCODING-TYPE | |
1028 MAGIC-REGEXP MAGIC-REGEXP-INVERSE | |
1029 FILE-EXTENSION | |
1030 ENCODE-PROGRAM DECODE-PROGRAM | |
1031 ENCODE-ARGS DECODE-ARGS | |
1032 MINOR-MODE | |
1033 GARBAGE-REGEXP-OR-LISPEXP | |
1034 FILE-EXTENSION-TRICKS | |
1035 \) | |
1036 | |
1037 ENCODING-TYPE is a symbol denoting the encoding type. Currently known | |
1038 encodings are (compress compact freeze gzip). | |
1039 | |
1040 MAGIC-REGEXP is a regexp that matches the magic number at the | |
1041 beginning of files encoded with ENCODING-TYPE. | |
1042 | |
1043 MAGIC-REGEXP-INVERSE dummy variable for compatibility with encryption. | |
1044 | |
1045 FILE-EXTENSION is a string denoting the file extension usually | |
1046 appended the filename of files encoded with ENCODING-TYPE. | |
1047 | |
1048 ENCODE-PROGRAM is a string denoting the name of the executable used to | |
1049 encode files. | |
1050 | |
1051 DECODE-PROGRAM is a string denoting the name of the executable used to | |
1052 decode files. | |
1053 | |
1054 ENCODE-ARGS arguments to be passed to ENCODE-PROGRAM may be a string or a | |
1055 list of strings or nil. | |
1056 | |
1057 DECODE-ARGS arguments to be passed to DECODE-PROGRAM may be a string or a | |
1058 list of strings or nil. | |
1059 | |
1060 MINOR-MODE is a string denoting the name for the encoded minor mode as | |
1061 it will appear in the mode line. | |
1062 | |
1063 GARBAGE-REGEXP-OR-LISPEXP is (1) a regexp that matches any extraneous text | |
1064 that is produced by the ENCODE-COMMAND including any newlines and will be | |
1065 removed from the buffer before saving to disk; (2) a lisp expression that will | |
1066 clean up extraneous material in the buffer or nil. This is normally not | |
1067 needed but can be derived for any ENCODE-COMMAND by checking the standard | |
1068 error that results from `sh -c \"cat foo | ENCODE-COMMAND > bar\"'. | |
1069 | |
1070 FILE-EXTENSION-TRICKS is t or nil depending on whether or not tricks | |
1071 converting between different encoding types can be done based on | |
1072 FILE-EXTENSION; typically t. | |
1073 ") | |
1074 | |
1075 | |
1076 ;;; This allows the user to alter contents of the encoding and encryption | |
1077 ;;; table variables without having to reload all of crypt++. | |
1078 (defun crypt-rebuild-tables () | |
1079 "Rebuilds the encryption and encoding tables and `minor-mode-alist'. | |
1080 Allows user to alter variables used in building these tables. May be called | |
1081 interactively or in an initialization file. Part of `after-init-hook'." | |
1082 (interactive) | |
1083 (setq crypt-encryption-alist (crypt-build-encryption-alist) | |
1084 crypt-encoding-alist (crypt-build-encoding-alist)) | |
1085 (crypt-rebuild-minor-modes-alist)) | |
1086 | |
1087 | |
1088 ;;; Buffer locals. | |
1089 | |
1090 (defvar crypt-buffer-save-encrypted nil | |
1091 "*non-nil says save buffer encrypted with `crypt-encryption-type.' | |
1092 local to all buffers.") | |
1093 (make-variable-buffer-local 'crypt-buffer-save-encrypted) | |
1094 (put 'crypt-buffer-save-encrypted 'permanent-local t) ; for v19 Emacs | |
1095 (put 'crypt-buffer-save-encrypted 'preserved t) ; for kill-fix.el | |
1096 | |
1097 (defvar crypt-buffer-encryption-key nil | |
1098 "*Key used for encryption of current buffer. Local to all buffers.") | |
1099 (make-variable-buffer-local 'crypt-buffer-encryption-key) | |
1100 (put 'crypt-buffer-encryption-key 'permanent-local t) ; for v19 Emacs | |
1101 (put 'crypt-buffer-encryption-key 'preserved t) ; for kill-fix.el | |
1102 | |
1103 (defvar crypt-buffer-save-encoded nil | |
1104 "*non-nil says buffer will be saved encoded. Local to all buffers.") | |
1105 (make-variable-buffer-local 'crypt-buffer-save-encoded) | |
1106 (put 'crypt-buffer-save-encoded 'permanent-local t) ; for v19 Emacs | |
1107 (put 'crypt-buffer-save-encoded 'preserved t) ; for kill-fix.el | |
1108 | |
1109 (defvar crypt-buffer-encoding-type nil | |
1110 "*non-nil says buffer is encoded with ENCODING-TYPE. Local to all buffers.") | |
1111 (make-variable-buffer-local 'crypt-buffer-encoding-type) | |
1112 (put 'crypt-buffer-encoding-type 'permanent-local t) ; for v19 Emacs | |
1113 (put 'crypt-buffer-encoding-type 'preserved t) ; for kill-fix.el | |
1114 | |
1115 (defvar crypt-buffer-interactive-encoded-mode nil | |
1116 "t says `crypt-encoded-mode' was toggled interactively, almost always nil. | |
1117 Local to all buffers.") | |
1118 (make-variable-buffer-local 'crypt-buffer-interactive-encoded-mode) | |
1119 (put 'crypt-buffer-interactive-encoded-mode 'permanent-local t) ; v19 Emacs | |
1120 (put 'crypt-buffer-interactive-encoded-mode 'preserved t) ; kill-fix.el | |
1121 | |
1122 | |
1123 ;;; Functions and macros that search `crypt-encryption-alist' and | |
1124 ;;; `crypt-encoding-alist'. | |
1125 | |
1126 (defun crypt-get-alist-member (type n) | |
1127 ;; Returns TYPE's Nth element | |
1128 (nth n (or (assoc type crypt-encryption-alist) | |
1129 (assoc type crypt-encoding-alist)))) | |
1130 | |
1131 (defmacro crypt-get-magic-regexp (type) | |
1132 ;; Returns regexp found at top of files encoded/encrypted with TYPE. | |
1133 (list 'crypt-get-alist-member type 1)) | |
1134 | |
1135 (defmacro crypt-get-magic-regexp-inverse (type) | |
1136 ;; Returns regexp *not* found at top of files encoded/encrypted with TYPE. | |
1137 (list 'crypt-get-alist-member type 2)) | |
1138 | |
1139 (defmacro crypt-get-file-extension (type) | |
1140 ;; Returns regexp matching extension of files encoded/encrypted with TYPE. | |
1141 (list 'crypt-get-alist-member type 3)) | |
1142 | |
1143 (defmacro crypt-get-encoding-program (type) | |
1144 ;; Returns name of program, as string, used to encode/encrypt with TYPE. | |
1145 (list 'crypt-get-alist-member type 4)) | |
1146 | |
1147 (defmacro crypt-get-decoding-program (type) | |
1148 ;; Returns name of program, as string, used to decode/decrypt with TYPE. | |
1149 (list 'crypt-get-alist-member type 5)) | |
1150 | |
1151 (defmacro crypt-get-encoding-args (type) | |
1152 ;; Returns arguments passed to program used to encode/encrypt with TYPE. | |
1153 (list 'crypt-get-alist-member type 6)) | |
1154 | |
1155 (defmacro crypt-get-decoding-args (type) | |
1156 ;; Returns arguments passed to program used to decode/decrypt with TYPE. | |
1157 (list 'crypt-get-alist-member type 7)) | |
1158 | |
1159 (defmacro crypt-get-minor-mode-name (type) | |
1160 ;; Returns minor mode name, as string, for encoding/encrypting with TYPE. | |
1161 (list 'crypt-get-alist-member type 8)) | |
1162 | |
1163 (defmacro crypt-get-cleanup-regexp (type) | |
1164 ;; Returns regexp or lisp-exp for cleaning up encoding/encrypting with TYPE. | |
1165 (list 'crypt-get-alist-member type 9)) | |
1166 | |
1167 (defmacro crypt-get-extension-tricks (type) | |
1168 ;; Returns t if file extension tricks doable for encoding/encrypting with | |
1169 ;; TYPE. | |
1170 (list 'crypt-get-alist-member type 10)) | |
1171 | |
1172 (defun crypt-buffer-save-name (type) | |
1173 ;; Returns variable `crypt-buffer-save-TYPE', set to t if encoding with TYPE. | |
1174 ;; local to all buffers. | |
1175 (intern (concat "crypt-buffer-save-" (symbol-name type)))) | |
1176 | |
1177 | |
1178 ;;; Create a buffer-local variable for each type of encoding. | |
1179 ;;; These variables are used to trigger the minor mode names. | |
1180 | |
1181 (defun crypt-build-minor-mode-alist () | |
1182 ;; Returns minor mode alist entries for encoded and encrypted buffers. | |
1183 (append | |
1184 ;; First the encrypted minor mode -- only one. | |
1185 (list (list 'crypt-buffer-save-encrypted | |
1186 (concat " " (crypt-get-minor-mode-name crypt-encryption-type)))) | |
1187 ;; Now the encoding minor modes. | |
1188 (mapcar | |
1189 (function | |
1190 (lambda (element) | |
1191 (let ((variable (crypt-buffer-save-name (car element)))) | |
1192 (make-variable-buffer-local variable) | |
1193 (put variable 'permanent-local t) ; for v19 Emacs | |
1194 (put variable 'preserved t) ; for kill-fix.el | |
1195 (list variable | |
1196 (concat " " (crypt-get-minor-mode-name (car element))))))) | |
1197 crypt-encoding-alist))) | |
1198 | |
1199 (defconst crypt-minor-mode-alist (crypt-build-minor-mode-alist) | |
1200 "Alist containing encoded and encrypted minor modes. | |
1201 Derived from variable `crypt-encoding-alist' and function | |
1202 `crypt-build-minor-mode-encrypted'") | |
1203 | |
1204 (defun crypt-rebuild-minor-modes-alist () | |
1205 ;; Rebuilds the encryption and encoding minor modes and `minor-mode-alist.' | |
1206 ;; Allows user to alter variables used in building this alist. Called by | |
1207 ;; `crypt-rebuild-tables' and so part of `after-init-hook'." | |
1208 | |
1209 ;; First remove old crypt minor mode entries from `minor-mode-alist'. | |
1210 (if (memq (car crypt-minor-mode-alist) minor-mode-alist) | |
1211 (let ((alist crypt-minor-mode-alist) elt) | |
1212 (while (and alist (setq elt (car alist))) | |
1213 (setq minor-mode-alist (delq elt minor-mode-alist) | |
1214 alist (cdr alist))))) | |
1215 | |
1216 ;; Get new crypt minor mode entries and add to minor-mode-alist. | |
1217 (setq crypt-minor-mode-alist (crypt-build-minor-mode-alist) | |
1218 minor-mode-alist (append crypt-minor-mode-alist minor-mode-alist))) | |
1219 | |
1220 | |
1221 (defmacro crypt-save-point (&rest body) | |
1222 ;; Save value of point, evaluate FORMS, and restore value of point. If the | |
1223 ;; saved value of point is no longer valid go to (point-max). This macro | |
1224 ;; exists because, save-excursion loses track of point during some types of | |
1225 ;; deletions. | |
1226 (let ((var (make-symbol "saved-point"))) | |
1227 (list 'let (list (list var '(point))) | |
1228 (list 'unwind-protect | |
1229 (cons 'progn body) | |
1230 (list 'goto-char var))))) | |
1231 | |
1232 | |
1233 (defun crypt-find-file-hook () | |
1234 | |
1235 ;; Hook run for decoding and/or decrypting the contents of a buffer. Meant | |
1236 ;; to be called as part of `find-file-hooks' | |
1237 | |
1238 (let ((buffer-file-name buffer-file-name) | |
1239 (old-buffer-file-name buffer-file-name) | |
1240 (old-buffer-modified-p (buffer-modified-p)) | |
1241 (case-fold-search nil) ; case-sensitive | |
1242 encrypted encoded buffer-read-only) | |
1243 | |
1244 ;; DECODE AND/OR DECRYPT | |
1245 (crypt-save-point | |
1246 | |
1247 ;; Do we have to DECODE? If not, then move on. | |
1248 (if (and (crypt-encoded-p) | |
1249 (or crypt-auto-decode-buffer | |
1250 (y-or-n-p (format "Decode %s? " (buffer-name))))) | |
1251 | |
1252 ;; Decode, uncompress, the buffer. | |
1253 (progn | |
1254 | |
1255 (if (and (not (null buffer-file-name)) | |
1256 (string-match "\\.Z$" buffer-file-name)) | |
1257 (set-visited-file-name | |
1258 (substring buffer-file-name 0 (match-beginning 0))) | |
1259 (if (and (not (null buffer-file-name)) | |
1260 (string-match "\\.gz$" buffer-file-name)) | |
1261 (set-visited-file-name | |
1262 (substring buffer-file-name 0 (match-beginning 0))))) | |
1263 (message "Decoding %s..." (buffer-name)) | |
1264 (crypt-encode-buffer t) | |
1265 | |
1266 ;; Store the encoding mode. | |
1267 | |
1268 ;; We can not yet go into the minor modes because the major mode | |
1269 ;; may change later on and blow away all local variables (and thus | |
1270 ;; the minor modes). Only needed for vanilla v18. Our | |
1271 ;; buffer-locals defined 'permanent-local for v19 Emacs and | |
1272 ;; 'preserved for kill-fix.el. | |
1273 | |
1274 (setq encoded crypt-buffer-encoding-type) | |
1275 | |
1276 ;; Strip encoded file's extension so later we can set buffer's | |
1277 ;; major mode based on its file-name sans encoding extension. | |
1278 (if (string-match (crypt-get-file-extension | |
1279 crypt-buffer-encoding-type) buffer-file-name) | |
1280 (setq buffer-file-name | |
1281 (substring buffer-file-name 0 (match-beginning 1)))) | |
1282 | |
1283 ;; Decoding ends. | |
1284 (if (not (input-pending-p)) | |
1285 (message "Decoding %s... done" (buffer-name))))) | |
1286 | |
1287 ;; Do we have to DECRYPT? If not, then move on. | |
1288 (if (crypt-encrypted-p) | |
1289 | |
1290 ;; Decrypt buffer. | |
1291 (progn | |
1292 | |
1293 (message "Decrypting %s..." (buffer-name)) | |
1294 (crypt-encrypt-buffer crypt-buffer-encryption-key t) | |
1295 | |
1296 ;; Save key in case major mode blows all buffer-locals. | |
1297 | |
1298 ;; Only needed for vanilla v18. Our buffer-locals defined | |
1299 ;; 'permanent-local for v19 Emacs and 'preserved for | |
1300 ;; kill-fix.el. | |
1301 | |
1302 (setq encrypted crypt-buffer-encryption-key) | |
1303 | |
1304 ;; Strip encrypted file's extension so later we can set buffer's | |
1305 ;; major mode based on its file-name sans encrypting extension. | |
1306 (if (and (crypt-get-extension-tricks crypt-encryption-type) | |
1307 (string-match (crypt-get-file-extension | |
1308 crypt-encryption-type) buffer-file-name)) | |
1309 (setq buffer-file-name | |
1310 (substring buffer-file-name 0 (match-beginning 1)))) | |
1311 | |
1312 (if (not (input-pending-p)) | |
1313 (message "Decrypting %s... done" (buffer-name)))))) | |
1314 | |
1315 ;; MAJOR AND MINOR MODES | |
1316 | |
1317 ;; OK, if any changes have been made to the buffer we need to rerun the | |
1318 ;; code the does automatic selection of major mode. | |
1319 | |
1320 (if (or encoded encrypted) | |
1321 | |
1322 (progn | |
1323 | |
1324 ;; Set the major mode. | |
1325 (set-auto-mode) | |
1326 (hack-local-variables) | |
1327 | |
1328 ;; Now set our own minor mode(s). | |
1329 (if encoded | |
1330 ;; Recover encoding type, may have been smashed by major mode, | |
1331 ;; and toggle encoded mode. | |
1332 (progn (setq crypt-buffer-encoding-type encoded) | |
1333 (crypt-encoded-mode 1))) | |
1334 | |
1335 (if encrypted | |
1336 ;; Recover encryption key, may have been smashed by major mode, | |
1337 ;; and toggle encrypted mode. | |
1338 (progn (setq crypt-buffer-encryption-key encrypted) | |
1339 (crypt-encrypted-mode 1))) | |
1340 | |
1341 ;; Restore buffer file name now, so that lock file entry is removed | |
1342 ;; properly. | |
1343 (setq buffer-file-name old-buffer-file-name) | |
1344 | |
1345 ;; Restore buffer modified flag to its previous value. Will also | |
1346 ;; remove lock file entry for buffer if previous value was nil. | |
1347 ;; This is why buffer-file-name had to be restored manually above. | |
1348 (set-buffer-modified-p old-buffer-modified-p))))) | |
1349 | |
1350 (defun crypt-encoded-p (&optional buffer) | |
1351 ;; Returns t if current buffer, or optionally BUFFER, is encoded. | |
1352 ;; Sets `crypt-buffer-encoding-type' to encoding method. | |
1353 (save-excursion | |
1354 (and buffer (set-buffer buffer)) | |
1355 (save-restriction | |
1356 (widen) | |
1357 (goto-char (point-min)) | |
1358 (let ((alist crypt-encoding-alist) elt found) | |
1359 (while (and alist (setq elt (car alist)) (not found)) | |
1360 (if (looking-at (nth 1 elt)) | |
1361 (setq crypt-buffer-encoding-type (nth 0 elt) | |
1362 found t) | |
1363 ;; Decrement | |
1364 (setq alist (cdr alist)))) | |
1365 found)))) | |
1366 | |
1367 (defun crypt-encrypted-p (&optional buffer) | |
1368 ;; Returns t if current buffer, or optionally BUFFER, is encrypted. | |
1369 ;; Look for MAGIC-REGEXP and absence of MAGIC-REGEXP-INVERSE. If so, then | |
1370 ;; assume it is an encrypted buffer. | |
1371 ;; Sets `crypt-buffer-encryption-key' to password if not set already. | |
1372 | |
1373 ;; Do not try to decrypt buffer if not wanted. | |
1374 (if (not crypt-never-ever-decrypt) | |
1375 | |
1376 (save-excursion | |
1377 (and buffer (set-buffer buffer)) | |
1378 | |
1379 (save-restriction | |
1380 (widen) | |
1381 (goto-char (point-min)) | |
1382 | |
1383 (let ((magic-regexp (crypt-get-magic-regexp crypt-encryption-type)) | |
1384 (magic-regexp-inverse (crypt-get-magic-regexp-inverse | |
1385 crypt-encryption-type)) | |
1386 (limit (min (point-max) crypt-magic-search-limit))) | |
1387 | |
1388 ;; Check all encryption conditions. If any fail, then return nil | |
1389 ;; value of this if-form, else check for password. | |
1390 (if (and | |
1391 | |
1392 ;; Check for existence of MAGIC-REGEXP. | |
1393 (if (stringp magic-regexp) | |
1394 ;; regular expression | |
1395 (re-search-forward magic-regexp limit t) | |
1396 ;; lisp expression | |
1397 (eval magic-regexp)) | |
1398 | |
1399 (goto-char (point-min)) | |
1400 | |
1401 ;; Check for absence of MAGIC-REGEXP-INVERSE. | |
1402 (not (if (stringp magic-regexp-inverse) | |
1403 ;; regular expression | |
1404 (re-search-forward magic-regexp-inverse limit t) | |
1405 ;; lisp expression | |
1406 (eval magic-regexp-inverse)))) | |
1407 | |
1408 (progn | |
1409 | |
1410 ;; Get key, i.e., the password? | |
1411 (or crypt-buffer-encryption-key | |
1412 ;; Do not confirm on reading an encrypted file. | |
1413 (let ((crypt-confirm-password nil)) | |
1414 (call-interactively 'crypt-set-encryption-key))) | |
1415 | |
1416 ;; Do not turn on encryption mode if no key: may be a binary | |
1417 ;; file. Thanks to Paul Dworkin (paul@media-lab.media.mit.edu). | |
1418 (if (equal crypt-buffer-encryption-key "") | |
1419 ;; Return nil. | |
1420 (progn | |
1421 (message "No key given. Assumed normal.") | |
1422 nil) | |
1423 ;; Return t. | |
1424 t)))))))) | |
1425 | |
1426 | |
1427 ;;; | |
1428 | |
1429 (defun crypt-check-extension-for-encoding () | |
1430 | |
1431 ;; Checks file extensions for possible toggling of encoding modes. Used for | |
1432 ;; buffers to be written to disk and called by `crypt-write-file-hook' | |
1433 | |
1434 ;; We try to flag a buffer to be written out in encoded form if the file | |
1435 ;; ends in one of the file-extensions in `crypt-encoding-alist' even if | |
1436 ;; `crypt-buffer-save-encoded' is nil. Conversely, we try to write out a | |
1437 ;; buffer as a plain file if it does _not_ end in one of these | |
1438 ;; file-extensions even if `crypt-buffer-save-encoded' is non-nil. | |
1439 | |
1440 (let ((alist crypt-encoding-alist) | |
1441 (case-fold-search nil) | |
1442 found elt) | |
1443 | |
1444 ;; Search through the file name extensions for a match. | |
1445 (while (and alist (setq elt (car alist)) (not found)) | |
1446 (if (string-match (nth 3 elt) buffer-file-name) | |
1447 (setq found t) | |
1448 ;; Decrement. | |
1449 (setq alist (cdr alist)))) | |
1450 | |
1451 ;; Did we find a match? | |
1452 (if found | |
1453 | |
1454 ;; File name ends in a very provocative extension. | |
1455 | |
1456 ;; Check to see if already an encoded file. | |
1457 (if crypt-buffer-save-encoded | |
1458 | |
1459 ;; Already encoded - do the methods of encoding match? | |
1460 (if (not (eq (nth 0 elt) crypt-buffer-encoding-type)) | |
1461 | |
1462 ;; A new encoding method is desired. | |
1463 | |
1464 ;; Can we play some filename extension tricks with the | |
1465 ;; destination extension? | |
1466 (if (crypt-get-extension-tricks (nth 0 elt)) | |
1467 | |
1468 ;; Can play tricks. | |
1469 ;; Change the method of encoding? | |
1470 (if (crypt-y-or-n-p (format "Write %s using %s? " | |
1471 (buffer-name) (nth 4 elt))) | |
1472 | |
1473 ;; Case one. | |
1474 ;; Turn off original encoding and turn on new encoding. | |
1475 (progn (crypt-encoded-mode -1) | |
1476 (setq crypt-buffer-encoding-type (nth 0 elt)) | |
1477 (crypt-encoded-mode 1))) | |
1478 | |
1479 ;; Can not play tricks - maybe wants a plain file? | |
1480 (if (crypt-y-or-n-p (format "Write %s a plain file? " | |
1481 (buffer-name))) | |
1482 | |
1483 ;; Case three. | |
1484 ;; Turn off the minor mode and _then_ the flags. | |
1485 (progn | |
1486 (crypt-encoded-mode -1) | |
1487 (setq crypt-buffer-save-encoded nil | |
1488 crypt-buffer-encoding-type nil))))) | |
1489 | |
1490 ;; Was a plain file. | |
1491 (if (and | |
1492 ;; Can we play some filename extension tricks? | |
1493 ;; If not then we must abort. | |
1494 (crypt-get-extension-tricks (nth 0 elt)) | |
1495 | |
1496 (crypt-y-or-n-p (format "Write %s using %s? " | |
1497 (buffer-name) (nth 4 elt)))) | |
1498 | |
1499 ;; Case two. | |
1500 ;; Turn on encoding flags and _then_ the minor mode. | |
1501 (progn | |
1502 (setq crypt-buffer-save-encoded t | |
1503 crypt-buffer-encoding-type (nth 0 elt)) | |
1504 (crypt-encoded-mode 1)))) | |
1505 | |
1506 ;; No match - a plain-jane file extension - but if the encoded flag is | |
1507 ;; non-nil then the user may really want it written out in plain | |
1508 ;; format so we must override this flag. | |
1509 (if (and crypt-buffer-save-encoded | |
1510 | |
1511 ;; Search the list of files to be ignored. | |
1512 ;; If `crypt-ignored-filenames' is nil then this let form | |
1513 ;; will return t. If a match is found this form will return | |
1514 ;; nil. Otherwise it will return t. | |
1515 (let ((tlist crypt-ignored-filenames) | |
1516 case-fold-search found elt) | |
1517 | |
1518 ;; Search through the list of filenames for a match. | |
1519 (while (and tlist (setq elt (car tlist)) (not found)) | |
1520 (if (string-match elt buffer-file-name) | |
1521 (setq found t) | |
1522 ;; Decrement. | |
1523 (setq tlist (cdr tlist)))) | |
1524 | |
1525 ;; Return t if we can _not_ find a match. | |
1526 (not found)) | |
1527 | |
1528 ;; If `(crypt-encoded-mode)' was called interactively, then | |
1529 ;; there is a high probability that no matter what the file | |
1530 ;; name extension the user wishes to write the file out in some | |
1531 ;; encoded format. Thanks to Kimball Collins | |
1532 ;; <kpc@ptolemy.arc.nasa.gov> for pointing out the need for | |
1533 ;; this. Unfortunately, still can not distinguish between | |
1534 ;; write-file and save-buffer. In the former the user may want | |
1535 ;; to write in plain format (or indeed some other format). | |
1536 | |
1537 (if crypt-buffer-interactive-encoded-mode | |
1538 ;; Interactive | |
1539 crypt-query-if-interactive | |
1540 ;; Non-interactive but still may want encoded format. | |
1541 crypt-no-extension-implies-plain) | |
1542 | |
1543 (crypt-y-or-n-p (format "Write %s as a plain file? " | |
1544 (buffer-name)))) | |
1545 | |
1546 ;; Case three. | |
1547 ;; Turn off the minor mode and _then_ the flags. | |
1548 (progn | |
1549 (crypt-encoded-mode -1) | |
1550 (setq crypt-buffer-save-encoded nil | |
1551 crypt-buffer-encoding-type nil)))))) | |
1552 | |
1553 | |
1554 (defun crypt-y-or-n-p (prompt) | |
1555 ;; Queries user based on `crypt-auto-write-buffer' and internal buffer-local | |
1556 ;; variable `crypt-auto-write-answer-local'. Returns value of | |
1557 ;; `crypt-auto-write-answer-local', which is t or nil. | |
1558 | |
1559 ;; Check if we need to ask user. Should be 'ask, nil, or t. | |
1560 (if (eq crypt-auto-write-answer-local 'ask) ; Default value. | |
1561 ;; We may need to ask. | |
1562 (or crypt-auto-write-buffer | |
1563 ;; Ask and store the answer. | |
1564 ;; Note: we only store if we asked. | |
1565 (setq crypt-auto-write-answer-local (y-or-n-p prompt))) | |
1566 ;; Use previous answer. | |
1567 crypt-auto-write-answer-local)) ; Will be nil or t. | |
1568 | |
1569 | |
1570 ;;; This function should be called ONLY as a write-file hook. | |
1571 ;;; Odd things will happen if it is called elsewhere. | |
1572 | |
1573 (defun crypt-write-file-hook () | |
1574 | |
1575 ;; Hook for possibly writing out file, and backup file, in a non-plain | |
1576 ;; format. Terminates calls in `write-file-hooks' and should be at end of | |
1577 ;; list. | |
1578 | |
1579 ;; Check file-extension for possible toggling of encoding modes. | |
1580 (crypt-check-extension-for-encoding) | |
1581 | |
1582 ;; Check extension for encryption. | |
1583 (if (and | |
1584 | |
1585 ;; Maybe file ends with provocative extension w.r.t. encryption? | |
1586 (stringp (crypt-get-file-extension crypt-encryption-type)) | |
1587 (let ((case-fold-search nil)) ; Make case-sensitive. | |
1588 (string-match (crypt-get-file-extension crypt-encryption-type) | |
1589 buffer-file-name)) | |
1590 | |
1591 ;; Can we play tricks? | |
1592 (crypt-get-extension-tricks crypt-encryption-type) | |
1593 | |
1594 ;; Match of filename extension - is file in plain format? | |
1595 (not crypt-buffer-save-encrypted) | |
1596 | |
1597 ;; Query? | |
1598 (or crypt-auto-write-buffer-encrypted | |
1599 (y-or-n-p | |
1600 (format "Write %s as an encrypted file? " (buffer-name))))) | |
1601 | |
1602 (progn | |
1603 ;; Set password and toggle `crypt-encrypted-mode' | |
1604 (call-interactively 'crypt-set-encryption-key) | |
1605 (crypt-encrypted-mode 1))) | |
1606 | |
1607 ;; Now decide whether or not we need to continue with this defun. Does the | |
1608 ;; buffer need to be saved in a non-plain form? If not then writing is not | |
1609 ;; done here but later in the write-file-hooks - probably at the end. | |
1610 | |
1611 (if (or crypt-buffer-save-encoded crypt-buffer-save-encrypted) | |
1612 | |
1613 (save-excursion | |
1614 (save-restriction | |
1615 | |
1616 (let | |
1617 | |
1618 ;; BINDINGS | |
1619 ((copy-buffer (get-buffer-create " *crypt copy buffer*")) | |
1620 (selective-display selective-display) | |
1621 (buffer-read-only)) | |
1622 | |
1623 ;; FORMS | |
1624 (copy-to-buffer copy-buffer 1 (1+ (buffer-size))) | |
1625 (narrow-to-region (point) (point)) | |
1626 | |
1627 (unwind-protect | |
1628 | |
1629 ;; BODYFORM | |
1630 (let (setmodes) | |
1631 | |
1632 ;; As of v19, if one of functions of the `write-file-hooks' | |
1633 ;; returns a non-nil value, then `basic-save-buffer' no | |
1634 ;; longer creates a backup file. We must do it ourselves. | |
1635 ;; this should be a no-op in v18. | |
1636 (or buffer-backed-up | |
1637 (setq setmodes (backup-buffer))) | |
1638 | |
1639 (insert-buffer-substring copy-buffer) | |
1640 (kill-buffer copy-buffer) | |
1641 | |
1642 ;; "Who would cross the Bridge of Death | |
1643 ;; Must answer me | |
1644 ;; These questions three | |
1645 ;; Ere the other side he see." | |
1646 ;; | |
1647 ;; Bridgekeeper from Monty Python and the Holy Grail | |
1648 | |
1649 ;; [1] selective-display non-nil means we must convert | |
1650 ;; carriage returns to newlines now, and set the variable | |
1651 ;; selective-display temporarily to nil. | |
1652 (if selective-display | |
1653 (progn | |
1654 (goto-char (point-min)) | |
1655 (subst-char-in-region (point-min) (point-max) ?\r ?\n) | |
1656 (setq selective-display nil))) | |
1657 | |
1658 ;; [2] encryption | |
1659 (if crypt-buffer-save-encrypted | |
1660 (progn | |
1661 ;; check for password | |
1662 (if (not crypt-buffer-encryption-key) | |
1663 (call-interactively 'crypt-set-encryption-key)) | |
1664 (if (null crypt-buffer-encryption-key) | |
1665 (error "No encryption key set for buffer %s" | |
1666 (buffer-name))) | |
1667 (if (not (stringp crypt-buffer-encryption-key)) | |
1668 (error "Encryption key is not a string")) | |
1669 (message "Encrypting %s..." (buffer-name)) | |
1670 (crypt-encrypt-buffer crypt-buffer-encryption-key))) | |
1671 | |
1672 ;; [3] encoding | |
1673 (if crypt-buffer-save-encoded | |
1674 (progn | |
1675 (message "Encoding %s..." (buffer-name)) | |
1676 (crypt-encode-buffer))) | |
1677 | |
1678 ;; Now write buffer/region to disk. | |
1679 (write-region (point-min) (point-max) buffer-file-name nil t) | |
1680 (delete-region (point-min) (point-max)) | |
1681 (set-buffer-modified-p nil) | |
1682 | |
1683 ;; Now that the file is written, set its modes. | |
1684 (if setmodes | |
1685 (condition-case () | |
1686 (set-file-modes buffer-file-name setmodes) | |
1687 (error nil))) | |
1688 | |
1689 ;; Return t so that `basic-save-buffer' will know that the | |
1690 ;; save has already been done. | |
1691 | |
1692 ;; NOTE: this TERMINATES write-file-hooks so any hooks | |
1693 ;; following this one will not be executed. | |
1694 | |
1695 t ) | |
1696 | |
1697 ;; UNWINDFORMS | |
1698 ;; unwind...sit back...take a load off...have a beer | |
1699 | |
1700 ;; If the encoded and encrypted stuff has already been removed | |
1701 ;; then this is a no-op. This form is executed if BODYFORM | |
1702 ;; completes normally but the value of BODYFORM is returned - | |
1703 ;; i.e., t is returned. | |
1704 | |
1705 (delete-region (point-min) (point-max)))))))) | |
1706 | |
1707 | |
1708 ;;;; ENCRYPTION | |
1709 | |
1710 (defun crypt-encrypt-region (start end key &optional decrypt) | |
1711 "Encrypt region START to END using KEY and `crypt-encryption-type'. When | |
1712 called interactively START and END default to point and mark \(START being the | |
1713 lesser of the two\), and KEY is prompted for. With optional DECRYPT non-nil, | |
1714 decryption is done." | |
1715 | |
1716 (interactive | |
1717 (let (decrypt) | |
1718 (barf-if-buffer-read-only) | |
1719 (list (region-beginning) | |
1720 (region-end) | |
1721 (crypt-read-string-no-echo | |
1722 (concat (if (setq decrypt (y-or-n-p "Decrypt region? ")) "De" "En") | |
1723 "crypt buffer using key: ") | |
1724 ;; Do not confirm on decrypting region. | |
1725 (if (not decrypt) crypt-confirm-password)) | |
1726 decrypt))) | |
1727 | |
1728 (crypt-save-point | |
1729 | |
1730 ;; We define the PROGRAM as the encryption program or decryption program | |
1731 ;; listed for `crypt-encryption-type' of `crypt-encryption-alist.' These | |
1732 ;; should be just the name of the executable and should _not_ contain any | |
1733 ;; arguments. `(call-process-region)' would be confused if we tried to | |
1734 ;; pass the arguments as part of the PROGRAM. The arguments are passed | |
1735 ;; through the encryption args or decryption args listed for | |
1736 ;; `crypt-encryption-type' of `crypt-encryption-alist.' | |
1737 | |
1738 ;; Thanks to Joe Ilacqua <spike@world.std.com> and others for pointing out | |
1739 ;; an error that occurs with some encryption programs (e.g., the crypt from | |
1740 ;; Sun Microsystems, HPUX-8, and BSD) if `args' is `"".' This will allow | |
1741 ;; nil values and lists of strings for argument. | |
1742 | |
1743 (let (prog args) | |
1744 | |
1745 ;; Get the proper program and arguments. | |
1746 (if decrypt | |
1747 (setq prog (crypt-get-decoding-program crypt-encryption-type) | |
1748 args (crypt-get-decoding-args crypt-encryption-type)) | |
1749 (setq prog (crypt-get-encoding-program crypt-encryption-type) | |
1750 args (crypt-get-encoding-args crypt-encryption-type))) | |
1751 | |
1752 ;; Check arguments. | |
1753 (cond | |
1754 | |
1755 ;; nil or "" args - don't pass. | |
1756 ((or (not args) (equal "" args)) | |
1757 (call-process-region start end prog t t nil key)) | |
1758 | |
1759 ;; Check if the args are in the form of a list - must use apply. | |
1760 ((listp args) | |
1761 (apply 'call-process-region | |
1762 (append (list start end prog t t nil) args (list key)))) | |
1763 | |
1764 ;; Default - just a non-null string. | |
1765 (t | |
1766 (call-process-region start end prog t t nil args key)))))) | |
1767 | |
1768 | |
1769 (defun crypt-encrypt-buffer (key &optional decrypt buffer) | |
1770 | |
1771 ;; Use KEY to encrypt current buffer and with optional DECRYPT decrypt. | |
1772 ;; With optional BUFFER, encrypt or decrypt that buffer. Not meant to be | |
1773 ;; called interactively, toggle `crypt-encrypted-mode' to encrypt an entire | |
1774 ;; buffer. | |
1775 | |
1776 (or buffer (setq buffer (current-buffer))) | |
1777 (save-excursion (set-buffer buffer) | |
1778 (crypt-encrypt-region (point-min) (point-max) key decrypt))) | |
1779 | |
1780 | |
1781 ;;;; ENCODING | |
1782 | |
1783 (defun crypt-encode-region (start end &optional decode) | |
1784 | |
1785 "Encode region START to END. When called interactively START and END | |
1786 default to point and mark \(START being the lesser of the two\). With | |
1787 optional DECODE non-nil, decoding is done. | |
1788 | |
1789 If encoding is attempted, then checks for correct magic number at start of | |
1790 newly-encoded region. If not found, then searches and deletes a user-defined | |
1791 regexp, or executes a user-defined lisp expression, as defined in | |
1792 `crypt-encoding-alist,' and checks again for magic number." | |
1793 | |
1794 (interactive "*r\nP") | |
1795 | |
1796 ;; If called interactively then we may need to determine the encoding type. | |
1797 (if (and (interactive-p) (not crypt-buffer-encoding-type)) | |
1798 (crypt-read-encoding-type)) | |
1799 | |
1800 (crypt-save-point | |
1801 | |
1802 ;; We define the PROGRAM as `shell-file-name' and have it call the encoding | |
1803 ;; or decoding program with the arguments. | |
1804 | |
1805 (let (prog args) | |
1806 | |
1807 ;; Get the proper program and arguments. | |
1808 (if decode | |
1809 (setq prog (crypt-get-decoding-program crypt-buffer-encoding-type) | |
1810 args (crypt-get-decoding-args crypt-buffer-encoding-type)) | |
1811 (setq prog (crypt-get-encoding-program crypt-buffer-encoding-type) | |
1812 args (crypt-get-encoding-args crypt-buffer-encoding-type))) | |
1813 | |
1814 (cond | |
1815 | |
1816 ;; prog is a string? | |
1817 ((stringp prog) | |
1818 | |
1819 ;; Check arguments. | |
1820 (cond | |
1821 | |
1822 ;; Check if the args are in the form of a list, will catch 'nil. | |
1823 ((listp args) | |
1824 | |
1825 ;; Cat all the strings together. | |
1826 (while args | |
1827 (setq prog (concat prog " " (car args)) | |
1828 args (cdr args)))) | |
1829 | |
1830 ;; Check if a non-null string. | |
1831 ((and (not (string= "" args)) | |
1832 (not (eq args t))) ; just in case... | |
1833 (setq prog (concat prog " " args)))) | |
1834 | |
1835 (call-process-region start end shell-file-name t t nil "-c" prog)) | |
1836 | |
1837 ;; Otherwise try and eval it. | |
1838 (t | |
1839 (eval (if args | |
1840 (list prog start end args) | |
1841 (list prog start end)))))) | |
1842 | |
1843 ;; Encoding or decoding region? | |
1844 (if (not decode) | |
1845 | |
1846 ;; Check if encoded region starts with magic number. | |
1847 (let ((magic (crypt-get-magic-regexp crypt-buffer-encoding-type)) | |
1848 (clean (crypt-get-cleanup-regexp crypt-buffer-encoding-type)) | |
1849 (case-fold-search nil)) | |
1850 | |
1851 ;; Top of region. | |
1852 (goto-char start) | |
1853 | |
1854 ;; Check for magic number. | |
1855 (if (not (looking-at magic)) | |
1856 | |
1857 ;; Magic number not there. | |
1858 | |
1859 ;; Some compression programs produce an (inane) standard error | |
1860 ;; message that gets piped into the buffer. For example, some | |
1861 ;; versions of compact output "Compression : 35.50%." There may | |
1862 ;; be some way to clean up buffer and check again. | |
1863 | |
1864 (cond | |
1865 | |
1866 ;; No mechanism to clean up - failed. | |
1867 ((eq clean nil) | |
1868 (error "Encoding failed!")) | |
1869 | |
1870 ;; Cleanup a regexp string? | |
1871 ((stringp clean) | |
1872 | |
1873 ;; Is regexp there? | |
1874 (if (looking-at clean) | |
1875 | |
1876 (progn | |
1877 ;; Delete the match. | |
1878 (delete-region (match-beginning 0) (match-end 0)) | |
1879 | |
1880 ;; Check for magic again. | |
1881 (if (not (looking-at magic)) | |
1882 (error "Encoding failed!"))))) | |
1883 | |
1884 ;; Default: evaluate a lisp expression and check again. | |
1885 (t (eval clean) | |
1886 (if (not (looking-at magic)) | |
1887 (error "Encoding failed!"))))))))) | |
1888 | |
1889 (defun crypt-encode-buffer (&optional decode buffer) | |
1890 | |
1891 ;; Encode current buffer. With optional DECODE non-nil decode and optional | |
1892 ;; BUFFER, encode or decode that buffer. Not meant to be called | |
1893 ;; interactively, toggle `crypt-encoded-mode' to encode an entire buffer. | |
1894 | |
1895 (or buffer (setq buffer (current-buffer))) | |
1896 (save-excursion (set-buffer buffer) | |
1897 (crypt-encode-region (point-min) (point-max) decode))) | |
1898 | |
1899 | |
1900 ;;;; DOS <--> UNIX | |
1901 (defun crypt-dos-to-unix-region (start end) | |
1902 "Converts region from START to END, from dos to unix format. | |
1903 Replaces \"\\r\\n\" with \"\\n\" and, if exists, removes ^Z at end of file. | |
1904 Sets `crypt-dos-has-ctrl-z'." | |
1905 (save-excursion | |
1906 (save-restriction | |
1907 (let ((remove-ctrl-z (equal end (point-max)))) | |
1908 (narrow-to-region start end) | |
1909 (goto-char (point-min)) | |
1910 (while (search-forward "\r\n" nil t) | |
1911 (replace-match "\n" nil t)) | |
1912 (if remove-ctrl-z | |
1913 (progn | |
1914 (goto-char (1- (point-max))) | |
1915 (setq crypt-dos-has-ctrl-z (looking-at "\C-z")) | |
1916 (if crypt-dos-has-ctrl-z (replace-match "")))))))) | |
1917 | |
1918 (defun crypt-unix-to-dos-region (start end) | |
1919 "Converts region from START to END, from dos to unix format. | |
1920 Replaces \"\\n\" with \"\\r\\n\" and adds a ^Z at end of file if | |
1921 `crypt-dos-has-ctrl-z' is non-nil." | |
1922 (save-excursion | |
1923 (save-restriction | |
1924 (let ((add-ctrl-z (and crypt-dos-has-ctrl-z | |
1925 (equal end (point-max))))) | |
1926 (narrow-to-region start end) | |
1927 (goto-char (point-min)) | |
1928 (while (search-forward "\n" nil t) | |
1929 (replace-match "\r\n" nil t)) | |
1930 (if add-ctrl-z | |
1931 (progn | |
1932 (goto-char (point-max)) | |
1933 (insert "\C-z"))))))) | |
1934 | |
1935 | |
1936 ;;;; MODES | |
1937 | |
1938 (defun crypt-encrypted-mode (&optional arg) | |
1939 | |
1940 "Toggle encrypted mode. With ARG, turn on iff positive, otherwise turn off. | |
1941 minor mode in which buffers are automatically encrypted before being written. | |
1942 if toggled and a key has been set for the current buffer, then the current | |
1943 buffer is marked modified, since it needs to be rewritten with or without | |
1944 encryption. | |
1945 | |
1946 Entering encrypted mode causes auto-saving to be turned off in the current | |
1947 buffer, as there is no way in Emacs Lisp to force auto save files to be | |
1948 encrypted." | |
1949 | |
1950 (interactive "P") | |
1951 (let ((oldval crypt-buffer-save-encrypted)) | |
1952 (setq crypt-buffer-save-encrypted | |
1953 (if arg (> arg 0) (not crypt-buffer-save-encrypted))) | |
1954 | |
1955 (if crypt-buffer-save-encrypted | |
1956 ;; We are going to save as encrypted, we will turn off auto-saving. | |
1957 (progn | |
1958 ;; NEVER do this. Turning off auto-saving is one thing. But if there's | |
1959 ;; already an autosave for some other reason, what business does this | |
1960 ;; package have tampering with it? | |
1961 ; ;; If an auto-save file already exists, then delete it. | |
1962 ; (if (and (stringp buffer-auto-save-file-name) | |
1963 ; (file-exists-p buffer-auto-save-file-name)) | |
1964 ; (delete-file buffer-auto-save-file-name)) | |
1965 ;; If the key is not set then ask for it. | |
1966 (if (not crypt-buffer-encryption-key) | |
1967 (call-interactively 'crypt-set-encryption-key)) | |
1968 ;; Turn-off auto-saving if crypt-encrypted-disable-auto-save non-nil. | |
1969 (and crypt-encrypted-disable-auto-save | |
1970 auto-save-default | |
1971 (progn | |
1972 (auto-save-mode 0) | |
1973 (if (eq crypt-encrypted-disable-auto-save t) | |
1974 (message "Auto-save off (in this buffer)"))))) | |
1975 | |
1976 ;; We are not going to save as encrypted, we will turn on auto-saving | |
1977 ;; but only if we are editing a file and the default says we should. | |
1978 (auto-save-mode (if (and auto-save-default buffer-file-name) 1 0))) | |
1979 | |
1980 (if crypt-buffer-encryption-key | |
1981 ;; Set buffer-modified flag to t only if the mode has been changed, | |
1982 ;; old code set unconditionally to nil if mode was not changed . | |
1983 ;; Modification suggested by: Gerd Hillebrand <ggh@cs.brown.edu> | |
1984 (if (not (eq oldval crypt-buffer-save-encrypted)) | |
1985 (set-buffer-modified-p t))))) | |
1986 | |
1987 | |
1988 ;;; Forgetting encryption keys (by jwz) | |
1989 ;;; This is really kind of bogus. Good behavior would be: | |
1990 ;;; - If a crypted buffer has not been "accessed" (edited? selected? | |
1991 ;;; viewed?) in N minutes, kill the buffer (since the plaintext is valuable.) | |
1992 ;;; - If a crypted buffer is modified, but "idle", just forget the password | |
1993 ;;; instead of killing the buffer (though the plaintext is valuable, it's | |
1994 ;;; also unsaved...) | |
1995 ;;; - The "idleness" of a modified buffer should be reset with every mod, so | |
1996 ;;; that an unsaved buffer that you have been constantly typing at for an | |
1997 ;;; hour doesn't lose its password. | |
1998 ;;; - But, if a password for a buffer has been discarded, and then an attempt | |
1999 ;;; is made to save that buffer, then we should confirm that the newly- | |
2000 ;;; typed password is the same as the password used in the file on disk. | |
2001 ;;; with PGP, we could check that by attempting to decrypt the file on | |
2002 ;;; disk into a scratch buffer and seeing if it contains the PGP error | |
2003 ;;; message. | |
2004 ;;; - BUG: if a password has been forgotten, and you save, and are prompted, | |
2005 ;;; the old file has already been renamed to a backup!! so if you ^G, the | |
2006 ;;; real file name no longer exists on disk - only as a ~ file. | |
2007 | |
2008 (defun crypt-forget-encryption-key () | |
2009 (cond (crypt-buffer-encryption-key | |
2010 (let ((inhibit-quit t)) | |
2011 (fillarray crypt-buffer-encryption-key 0) | |
2012 (setq crypt-buffer-encryption-key nil)) | |
2013 t) | |
2014 (t nil))) | |
2015 | |
2016 (add-hook 'kill-buffer-hook 'crypt-forget-encryption-key) | |
2017 | |
2018 (defvar crypt-forget-passwd-timeout (* 60 60) | |
2019 "*Do not retain passwords for encrypted buffers more than this many seconds. | |
2020 If nil, keep them indefinitely.") | |
2021 | |
2022 (defun crypt-reset-passwd-timer () | |
2023 (if (fboundp 'get-itimer) ; XEmacs, or anything with itimer.el loaded. | |
2024 (let ((name "crypt-forget-passwds")) | |
2025 (if (get-itimer name) | |
2026 (delete-itimer name)) | |
2027 (if crypt-forget-passwd-timeout | |
2028 (start-itimer name | |
2029 'crypt-reset-passwds-timeout | |
2030 crypt-forget-passwd-timeout))))) | |
2031 | |
2032 (defun crypt-reset-passwds-timeout () | |
2033 ;; run by the timer code to forget all passwords | |
2034 (let ((buffers (buffer-list)) | |
2035 (inhibit-quit t) | |
2036 (keep-going nil)) | |
2037 (while buffers | |
2038 (save-excursion | |
2039 (set-buffer (car buffers)) | |
2040 (cond ((and crypt-buffer-encryption-key | |
2041 (buffer-modified-p)) | |
2042 ;; don't forget the password in modified buffers, but | |
2043 ;; do check again later (maybe it will be unmodified.) | |
2044 (setq keep-going t)) | |
2045 (crypt-buffer-encryption-key | |
2046 ;; forget the password in unmodified buffers. | |
2047 (crypt-forget-encryption-key) | |
2048 ;; Mark the buffer read only so that it's not accidentally | |
2049 ;; edited; the smart thing to do is revert it, type the | |
2050 ;; encryption key (to make sure they same key is used) | |
2051 ;; and then edit it. | |
2052 (setq buffer-read-only t) | |
2053 (message "Password discarded in buffer %s" | |
2054 (buffer-name (car buffers)))) | |
2055 )) | |
2056 (setq buffers (cdr buffers))) | |
2057 (if keep-going | |
2058 (crypt-reset-passwd-timer)) | |
2059 nil)) | |
2060 | |
2061 | |
2062 ;;; Originally `tek-symbol-alist-to-table' from tek-highlight.el. | |
2063 (defun crypt-symbol-alist-to-table (list) | |
2064 ;; Converts an alist of symbols to a table suitable for `completing-read.' | |
2065 ;; Called by `crypt-read-encoding-type' | |
2066 (mapcar (function (lambda (x) (list (symbol-name (car x))))) | |
2067 list)) | |
2068 | |
2069 (defun crypt-read-encoding-type () | |
2070 | |
2071 ;; Function called to query user for `crypt-buffer-encoding-type' uses | |
2072 ;; contents of `crypt-encoding-alist' and `crypt-default-encoding.' | |
2073 | |
2074 ;; Use poor man's gmhist (i.e., we could have used gmhist's | |
2075 ;; `completing-read-with-history-in' instead). | |
2076 (let ( | |
2077 ;; Find the encoding type desired by user. | |
2078 (type | |
2079 (completing-read | |
2080 (concat "encoding type (? for list): [" crypt-default-encoding "] ") | |
2081 (crypt-symbol-alist-to-table crypt-encoding-alist)))) | |
2082 | |
2083 ;; Test length of object returned by `completing-read'. | |
2084 (if (zerop (length type)) | |
2085 | |
2086 ;; Nothing there, i.e., user hit return -- use default. | |
2087 (setq crypt-buffer-encoding-type (intern crypt-default-encoding)) | |
2088 | |
2089 ;; Use the value from mini-buffer and update the default value. | |
2090 (setq crypt-buffer-encoding-type (intern type) | |
2091 crypt-default-encoding type)))) | |
2092 | |
2093 (defun crypt-encoded-mode (&optional arg) | |
2094 | |
2095 "Toggle encoded mode. With ARG, turn on iff positive, otherwise turn off. | |
2096 minor mode in which buffers are automatically encoded before being written. if | |
2097 toggled then current buffer is marked modified, since it needs to be written | |
2098 with or without encoding. | |
2099 | |
2100 Entering encoded mode causes auto-saving to be turned off in the current | |
2101 buffer, as there is no way in Emacs Lisp to force auto save files to be | |
2102 encoded." | |
2103 | |
2104 (interactive "P") | |
2105 | |
2106 ;; Set flag indicating whether or not `(crypt-encoded-mode)' was called | |
2107 ;; interactively. | |
2108 (setq crypt-buffer-interactive-encoded-mode (interactive-p)) | |
2109 | |
2110 ;; If called interactively then need to determine encoding type. | |
2111 (if (and crypt-buffer-interactive-encoded-mode | |
2112 (not crypt-buffer-encoding-type)) | |
2113 (crypt-read-encoding-type)) | |
2114 | |
2115 ;; Save old value of `crypt-buffer-save-encoded'. | |
2116 (let ((oldval crypt-buffer-save-encoded)) | |
2117 | |
2118 ;; Set the variable `crypt-buffer-save-encoded' to t if the argument is | |
2119 ;; positive, otherwise toggle its current value. | |
2120 (setq crypt-buffer-save-encoded | |
2121 (if arg (> arg 0) (not crypt-buffer-save-encoded))) | |
2122 | |
2123 ;; Set the variable generated by `(crypt-buffer-save-name)' to the value | |
2124 ;; stored in `crypt-buffer-save-encoded.' | |
2125 (set-variable (crypt-buffer-save-name crypt-buffer-encoding-type) | |
2126 crypt-buffer-save-encoded) | |
2127 | |
2128 (if crypt-buffer-save-encoded | |
2129 ;; We are going to save as encoded, we might turn off auto-saving. | |
2130 (progn | |
2131 ;; NEVER do this. Turning off auto-saving is one thing. But if there's | |
2132 ;; already an autosave for some other reason, what business does this | |
2133 ;; package have tampering with it? | |
2134 ; ;; If an auto-save file already exists, then delete it. | |
2135 ; (if (and (stringp buffer-auto-save-file-name) | |
2136 ; (file-exists-p buffer-auto-save-file-name)) | |
2137 ; (delete-file buffer-auto-save-file-name)) | |
2138 ;; Turn-off auto-saving if crypt-encoded-disable-auto-save non-nil. | |
2139 (and crypt-encoded-disable-auto-save | |
2140 auto-save-default | |
2141 (progn | |
2142 (auto-save-mode 0) | |
2143 (if (eq crypt-encoded-disable-auto-save t) | |
2144 (message "Auto-save off (in this buffer)"))))) | |
2145 | |
2146 ;; We are not going to save as encoded, we will turn on auto-saving but | |
2147 ;; only if we are editing a file and the default says we should. | |
2148 (auto-save-mode (if (and auto-save-default buffer-file-name) 1 0))) | |
2149 | |
2150 ;; Have we toggled the mode? | |
2151 | |
2152 ;; If yes, then mark buffer as modified. If not, then leave | |
2153 ;; buffer-modified flag alone. | |
2154 | |
2155 ;; The old code previously set the variable `set-buffer-modified-p' to a | |
2156 ;; value of t if there was a mode change and (unconditionally) to nil | |
2157 ;; if there was not a mode change. | |
2158 | |
2159 ;; Modification suggested by: Gerd Hillebrand <ggh@cs.brown.edu>. | |
2160 | |
2161 (if (not (eq oldval crypt-buffer-save-encoded)) | |
2162 (set-buffer-modified-p t)))) | |
2163 | |
2164 | |
2165 ;;;; Additional encryption functions | |
2166 | |
2167 ;; For Emacs V18 compatibility | |
2168 (and (not (fboundp 'buffer-disable-undo)) | |
2169 (fboundp 'buffer-flush-undo) | |
2170 (fset 'buffer-disable-undo 'buffer-flush-undo)) | |
2171 | |
2172 (fset 'crypt-read-string-no-echo 'read-passwd) | |
2173 | |
2174 ;(defun crypt-read-string-no-echo (prompt &optional confirm) | |
2175 ; | |
2176 ; ;; Read a string from minibuffer, prompting with PROMPT, echoing periods. | |
2177 ; ;; Optional second argument CONFIRM non-nil means that the user will be | |
2178 ; ;; asked to type the string a second time for confirmation and if there is a | |
2179 ; ;; mismatch, the whole process is repeated. | |
2180 ; ;; | |
2181 ; ;; Line editing keys are -- | |
2182 ; ;; C-h, DEL rubout | |
2183 ; ;; C-u, C-x line kill | |
2184 ; ;; C-q, C-v literal next | |
2185 ; | |
2186 ; (catch 'return-value | |
2187 ; (save-excursion | |
2188 ; | |
2189 ; (let ((input-buffer (get-buffer-create (make-temp-name " *password*"))) | |
2190 ; char hold-password help-form kill-ring) | |
2191 ; | |
2192 ; (set-buffer input-buffer) | |
2193 ; ;; Don't add to undo ring. | |
2194 ; (buffer-disable-undo input-buffer) | |
2195 ; | |
2196 ; (let ((cursor-in-echo-area t) | |
2197 ; (echo-keystrokes 0)) | |
2198 ; | |
2199 ; (unwind-protect | |
2200 ; | |
2201 ; ;; BODYFORM | |
2202 ; ;; Repeat until we get a `throw'. | |
2203 ; (while t | |
2204 ; (erase-buffer) | |
2205 ; (message prompt) | |
2206 ; | |
2207 ; ;; Read string. | |
2208 ; (while (not (memq (setq char (read-char)) '(?\C-m ?\C-j))) | |
2209 ; (if (setq help-form | |
2210 ; (cdr | |
2211 ; (assq char | |
2212 ; '((?\C-h . (delete-char -1)) | |
2213 ; (?\C-? . (delete-char -1)) | |
2214 ; (?\C-u . (delete-region 1 (point))) | |
2215 ; (?\C-x . (delete-region 1 (point))) | |
2216 ; (?\C-q . (quoted-insert 1)) | |
2217 ; (?\C-v . (quoted-insert 1)))))) | |
2218 ; (condition-case error-data | |
2219 ; (eval help-form) | |
2220 ; (error t)) | |
2221 ; ;; Just a plain character - insert into password buffer. | |
2222 ; (insert char)) | |
2223 ; | |
2224 ; ;; I think crypt-read-string-no-echo should echo asterisks. | |
2225 ; ;; -- Jamie. How about periods like in ange-ftp? -- lrd | |
2226 ; ;; | |
2227 ; (message "%s%s" prompt (make-string (buffer-size) ?.))) | |
2228 ; | |
2229 ; ;; Do we have to confirm password? | |
2230 ; (cond | |
2231 ; | |
2232 ; ;; No confirmation requested - terminate. | |
2233 ; ((not confirm) | |
2234 ; (throw 'return-value (buffer-string))) | |
2235 ; | |
2236 ; ;; Can we compare (confirm) password values yet? | |
2237 ; (hold-password | |
2238 ; (if (string= hold-password (buffer-string)) | |
2239 ; ;; The two passwords match - terminate. | |
2240 ; (throw 'return-value hold-password) | |
2241 ; | |
2242 ; ;; Mismatch - start over. | |
2243 ; (progn | |
2244 ; (message (concat prompt "[Mismatch. Start over]")) | |
2245 ; (beep) | |
2246 ; (sit-for 2) | |
2247 ; (fillarray hold-password 0) ; destroy extra copy now | |
2248 ; (setq hold-password nil)))) | |
2249 ; | |
2250 ; ;; Store password and read again. | |
2251 ; (t | |
2252 ; (setq hold-password (buffer-string)) | |
2253 ; (message (concat prompt "[Retype to confirm]")) | |
2254 ; (sit-for 2)))) | |
2255 ; | |
2256 ; ;; UNWINDFORMS | |
2257 ; ;; Clean up. | |
2258 ; (set-buffer input-buffer) | |
2259 ; (set-buffer-modified-p nil) | |
2260 ; (buffer-disable-undo input-buffer) ; redundant, but why not be safe. | |
2261 ; (widen) | |
2262 ; (goto-char (point-min)) | |
2263 ; (while (not (eobp)) (delete-char 1) (insert "*")) ; destroy now | |
2264 ; (kill-buffer input-buffer))))))) | |
2265 | |
2266 (defun crypt-set-encryption-key (key &optional buffer) | |
2267 | |
2268 "Set the encryption KEY, a string, for current buffer or optionally BUFFER. | |
2269 If buffer is in encrypted mode, then it is also marked as modified, since it | |
2270 needs to be saved with the new key." | |
2271 | |
2272 (interactive | |
2273 (progn | |
2274 (barf-if-buffer-read-only) | |
2275 (list (crypt-read-string-no-echo | |
2276 (format "Encryption key for %s? [RET to ignore]: " (buffer-name)) | |
2277 crypt-confirm-password)))) | |
2278 | |
2279 ;; For security reasons we remove `(crypt-set-encryption-key "password")' | |
2280 ;; from the `command-history' list if called interactively. | |
2281 (if (interactive-p) | |
2282 (setq command-history (cdr command-history))) | |
2283 | |
2284 (or buffer (setq buffer (current-buffer))) | |
2285 | |
2286 (save-excursion | |
2287 (set-buffer buffer) | |
2288 (if (equal key crypt-buffer-encryption-key) | |
2289 (message "Key is identical to original, no change.") | |
2290 | |
2291 (progn | |
2292 ;; jwz: destroy old string | |
2293 (if (and crypt-buffer-encryption-key | |
2294 (not (eq crypt-buffer-encryption-key key))) | |
2295 (fillarray crypt-buffer-encryption-key 0)) | |
2296 (setq crypt-buffer-encryption-key key) | |
2297 | |
2298 ;; Don't touch the modify flag unless we're in `(crypt-encrypted-mode)'. | |
2299 (if crypt-buffer-save-encrypted | |
2300 (set-buffer-modified-p t)) | |
2301 | |
2302 (crypt-reset-passwd-timer) | |
2303 )))) | |
2304 | |
2305 | |
2306 ;;;; Install hooks and mode indicators. | |
2307 | |
2308 ;;; Check if mode indicators are not already installed and then prepend them. | |
2309 (and (not (assq 'crypt-buffer-save-encrypted minor-mode-alist)) | |
2310 (setq minor-mode-alist (append crypt-minor-mode-alist minor-mode-alist))) | |
2311 | |
2312 ;;; Install the hooks. | |
2313 | |
2314 ;;; If add-hook isn't already defined overwrite it with our own. | |
2315 ;;; Note the `add-hook' function must take the optional APPEND argument. | |
2316 (if (not (fboundp 'add-hook)) | |
2317 ;; No add-hook found. | |
2318 ;; Use `add-hook' from GNU Emacs v19. | |
2319 (defun add-hook (hook function &optional append) | |
2320 "Add to the value of HOOK the function FUNCTION. | |
2321 FUNCTION is not added if already present. | |
2322 FUNCTION is added (if necessary) at the beginning of the hook list | |
2323 unless the optional argument APPEND is non-nil, in which case | |
2324 FUNCTION is added at the end. | |
2325 | |
2326 HOOK should be a symbol, and FUNCTION may be any valid function. If | |
2327 HOOK is void, it is first set to nil. If HOOK's value is a single | |
2328 function, it is changed to a list of functions." | |
2329 (or (boundp hook) (set hook nil)) | |
2330 ;; If the hook value is a single function, turn it into a list. | |
2331 (let ((old (symbol-value hook))) | |
2332 (if (or (not (listp old)) (eq (car old) 'lambda)) | |
2333 (set hook (list old)))) | |
2334 (or (if (consp function) | |
2335 ;; Clever way to tell whether a given lambda-expression | |
2336 ;; is equal to anything in the hook. | |
2337 (let ((tail (assoc (cdr function) (symbol-value hook)))) | |
2338 (equal function tail)) | |
2339 (memq function (symbol-value hook))) | |
2340 (set hook | |
2341 (if append | |
2342 (nconc (symbol-value hook) (list function)) | |
2343 (cons function (symbol-value hook))))))) | |
2344 | |
2345 ;;; Attach ourselves to the find-file-hooks and find-file-not-found-hooks. | |
2346 (add-hook 'find-file-hooks 'crypt-find-file-hook) | |
2347 (add-hook 'find-file-not-found-hooks 'crypt-find-file-hook) | |
2348 | |
2349 ;; Take care when appending to write-file-hook. User's version of add-hook | |
2350 ;; may not have APPEND option. If it fails then do it by hand. I wish | |
2351 ;; everyone would upgrade - lrd 8/31/93. | |
2352 (condition-case err | |
2353 (add-hook 'write-file-hooks 'crypt-write-file-hook t) ; *must* append this | |
2354 (error | |
2355 ;; Do it by hand. Not as robust as `add-hook'. | |
2356 | |
2357 ;; Contributed by Ken Laprade <laprade@trantor.harris-atd.com> | |
2358 ;; Really should use some sort of add-hook - 16 Feb 93 - KCL | |
2359 (or (and (listp write-file-hooks) (not (eq (car write-file-hooks) 'lambda))) | |
2360 (setq write-file-hooks (list write-file-hooks))) | |
2361 | |
2362 (cond | |
2363 ((not (memq 'crypt-write-file-hook write-file-hooks)) | |
2364 ;; make this hook last on purpose | |
2365 (setq write-file-hooks (append write-file-hooks | |
2366 (list 'crypt-write-file-hook))))))) | |
2367 | |
2368 ;; In order that the tables and key-binding correctly reflect user's | |
2369 ;; preferences we add ourselves to the `after-init-hook' GNU Emacs v19 and | |
2370 ;; Lucid Emacs v 19.8 (or later) or `term-setup-hook' in Lucid Emacs v 19.7 | |
2371 ;; (or earlier). These are run *after* ~/.emacs and ../lisp/default.el are | |
2372 ;; loaded. Unfortunately, v18 does not have `after-init-hook' and | |
2373 ;; `term-setup-hook' is just a single function. It is a bit of a pain trying | |
2374 ;; to work our functions in properly without overwriting the user's value. | |
2375 ;; Therefore, we do nothing and hope they upgrade to v19 soon. | |
2376 | |
2377 (cond ((boundp 'after-init-hook) | |
2378 ;; Must be running GNU Emacs v19 :-> | |
2379 (add-hook 'after-init-hook 'crypt-rebuild-tables) | |
2380 (add-hook 'after-init-hook 'crypt-rebuild-minor-modes-alist) | |
2381 (add-hook 'after-init-hook 'crypt-bind-insert-file)) | |
2382 | |
2383 ((and (string-match "^19" emacs-version) t) | |
2384 ;; Probably running Lucid Emacs v19.7 (or earlier) since it, | |
2385 ;; unfortunately, does not have `after-init-hook'. Use | |
2386 ;; `term-setup-hook' instead and hope they upgrade to Lucid 19.8 or GNU | |
2387 ;; Emacs 19. | |
2388 (add-hook 'term-setup-hook 'crypt-rebuild-tables) | |
2389 (add-hook 'term-setup-hook 'crypt-rebuild-minor-modes-alist) | |
2390 (add-hook 'term-setup-hook 'crypt-bind-insert-file))) | |
2391 | |
2392 | |
2393 ;;; Code for conditionally decoding/decrypting an inserted file | |
2394 | |
2395 (defvar crypt-bind-insert-file t | |
2396 "*t value means bind `crypt-insert-file' over `insert-file'. | |
2397 If you wish to change this variable after crypt++ has been loaded then do | |
2398 \\[crypt-bind-insert-file].") | |
2399 | |
2400 (defvar crypt-auto-decode-insert nil | |
2401 "*t says decode/decrypt files that are inserted with `crypt-insert-file'. | |
2402 nil says to ask before doing this.") | |
2403 | |
2404 ;;; Bind `crypt-insert-file' over wherever `insert-file' is bound? | |
2405 (defun crypt-bind-insert-file () | |
2406 | |
2407 "Bind `crypt-insert-file' in place of `insert-file' or reverse based on | |
2408 `crypt-bind-insert-file'. Part of `after-init-hook'." | |
2409 | |
2410 (interactive) | |
2411 | |
2412 (if (interactive-p) | |
2413 (setq crypt-bind-insert-file | |
2414 (y-or-n-p "Bind crypt-insert-file over insert-file? "))) | |
2415 | |
2416 (if crypt-bind-insert-file | |
2417 (substitute-key-definition | |
2418 'insert-file 'crypt-insert-file (current-global-map)) | |
2419 (substitute-key-definition | |
2420 'crypt-insert-file 'insert-file (current-global-map)))) | |
2421 | |
2422 ;;; Now call it. | |
2423 (crypt-bind-insert-file) | |
2424 | |
2425 ;;; crypt++ replacement for `insert-file' | |
2426 (defun crypt-insert-file (filename) | |
2427 "Insert decoded/decrypted contents of file FILENAME into buffer after point. | |
2428 Set mark after the inserted text. | |
2429 | |
2430 This function is meant for the user to run interactively. | |
2431 Don't call it from programs! Use `insert-file-contents' instead. | |
2432 \(Its calling sequence is different; see its documentation\). | |
2433 | |
2434 This version will attempt to decrypt and/or decode file before inserting. | |
2435 see variable `crypt-auto-decode-insert'." | |
2436 (interactive "fInsert file: ") | |
2437 (if (file-directory-p filename) | |
2438 (signal 'file-error (list "Opening input file" "file is a directory" | |
2439 filename))) | |
2440 (let ((tem (crypt-insert-file-contents filename))) ; use crypt++ to insert | |
2441 (push-mark (+ (point) (car (cdr tem)))))) | |
2442 | |
2443 (defun crypt-insert-file-contents (file) | |
2444 | |
2445 ;; Similar to `insert-file-contents' except decoding/decrypting of FILE | |
2446 ;; attempted. See `crypt-insert-file' and `crypt-auto-decode-insert' | |
2447 | |
2448 (let (temp-buffer | |
2449 temp-list | |
2450 (crypt-auto-decode-buffer crypt-auto-decode-insert) | |
2451 (orig-buffer (current-buffer))) | |
2452 | |
2453 ;; Create a temporary buffer and decode and decrypt it. | |
2454 (save-excursion | |
2455 | |
2456 ;; Temporary buffer, use the same name as the file to be inserted. | |
2457 (setq temp-buffer (generate-new-buffer (file-name-nondirectory file))) | |
2458 (set-buffer temp-buffer) | |
2459 | |
2460 ;; Original insert-file-contents - save list. | |
2461 (setq temp-list (insert-file-contents file nil)) | |
2462 | |
2463 ;; Make temp-buffer unmodified. | |
2464 (set-buffer-modified-p nil) | |
2465 | |
2466 ;; Need to set buffer name to file name for crypt++. | |
2467 (setq buffer-file-name file) | |
2468 | |
2469 ;; Decode and decrypt, if necessary. | |
2470 (crypt-find-file-hook) | |
2471 | |
2472 ;; Find the length of the file to be inserted. `insert-file-contents' | |
2473 ;; returns it for the original encoded/encrypted file. | |
2474 (setcdr temp-list (cons (buffer-size) ())) | |
2475 | |
2476 ;; Now insert temp-buffer into original buffer. | |
2477 (set-buffer orig-buffer) | |
2478 (insert-buffer temp-buffer) | |
2479 | |
2480 ;; Kill the temporary buffer. | |
2481 (kill-buffer temp-buffer)) | |
2482 | |
2483 ;; Return modified list from `insert-file-contents'. | |
2484 temp-list)) | |
2485 | |
2486 | |
2487 ;;;; BUG REPORTS | |
2488 | |
2489 ;;; This section is provided for reports. | |
2490 ;;; Using Barry A. Warsaw's reporter.el | |
2491 | |
2492 (defconst crypt-version "2.82" | |
2493 "Revision number of crypt++.el -- handles compressed and encrypted files. | |
2494 Type \\[crypt-submit-report] to send a bug report. Available via anonymous | |
2495 ftp in | |
2496 | |
2497 /roebling.poly.edu:/pub/lisp/crypt++.el.gz | |
2498 /archive.cis.ohio-state.edu:/pub/gnu/emacs/elisp-archive/misc/crypt++.el.Z") | |
2499 | |
2500 (defconst crypt-help-address | |
2501 "dodd@roebling.poly.edu" | |
2502 "Address(es) accepting submission of reports on crypt++.el.") | |
2503 | |
2504 (defconst crypt-maintainer "Larry" | |
2505 "First name(s) of people accepting submission of reports on crypt++.el.") | |
2506 | |
2507 (defconst crypt-file "crypt++.el" | |
2508 "Name of file containing emacs lisp code.") | |
2509 | |
2510 (defconst crypt-variable-list | |
2511 (list 'shell-file-name ; These | |
2512 'load-path ; are | |
2513 'exec-path ; useful. | |
2514 'crypt-encryption-type | |
2515 'crypt-encryption-file-extension | |
2516 'crypt-never-ever-decrypt | |
2517 'crypt-auto-write-buffer-encrypted | |
2518 'crypt-confirm-password | |
2519 'crypt-encrypted-disable-auto-save | |
2520 'crypt-auto-decode-buffer | |
2521 'crypt-auto-write-buffer | |
2522 'crypt-query-if-interactive | |
2523 'crypt-no-extension-implies-plain | |
2524 'crypt-freeze-vs-fortran | |
2525 'crypt-compact-vs-C++ | |
2526 'crypt-ignored-filenames | |
2527 'crypt-default-encoding | |
2528 'crypt-encoded-disable-auto-save | |
2529 'crypt-bind-insert-file | |
2530 'crypt-auto-decode-insert | |
2531 'crypt-encoding-alist | |
2532 'crypt-encryption-alist | |
2533 ) | |
2534 "List of variables to be appended to reports sent by `crypt-submit-report.'") | |
2535 | |
2536 (defun crypt-submit-report () | |
2537 "Submit via reporter.el a bug report on program. Send report on `crypt-file' | |
2538 version `crypt-version,' to `crypt-maintainer' at address `crypt-help-address' | |
2539 listing variables `crypt-variable-list' in the message." | |
2540 (interactive) | |
2541 | |
2542 ;; In case we can't find reporter... | |
2543 (condition-case err | |
2544 (progn | |
2545 ;; Get it if we can. | |
2546 (require 'reporter) | |
2547 | |
2548 (reporter-submit-bug-report | |
2549 crypt-help-address ; address | |
2550 (concat crypt-file " " crypt-version) ; pkgname | |
2551 crypt-variable-list ; varlist | |
2552 nil nil ; pre-hooks and post-hooks | |
2553 (concat "Yo! " crypt-maintainer ","))) ; salutation | |
2554 | |
2555 ;; ...fail gracefully. | |
2556 (error | |
2557 (beep) | |
2558 | |
2559 ;; Do they have ange-ftp? | |
2560 (if (and (featurep 'ange-ftp) | |
2561 (y-or-n-p (concat "Sorry, reporter.el not found. " | |
2562 "Can I ange-ftp it for you? "))) | |
2563 | |
2564 ;; Yes. Then Ange-ftp a copy from roebling. | |
2565 (let ((ange-ftp-generate-anonymous-password t)) | |
2566 ;; Might want to use the elisp archive official site? But | |
2567 ;; then it would have to be uncompressed, etc. Ick! | |
2568 (find-file-other-window | |
2569 "/anonymous@roebling.poly.edu:/pub/reporter.el") | |
2570 (eval-current-buffer) | |
2571 (message (concat "Save reporter.el somewhere in `load-path' " | |
2572 "and try again."))) | |
2573 | |
2574 ;; No ange-ftp. | |
2575 (message "Sorry, reporter.el not found.") | |
2576 (sit-for 3) | |
2577 (message (concat "Get it from archive.cis.ohio-state.edu " | |
2578 "or roebling.poly.edu")))))) | |
2579 | |
2580 ;;; Provide this package as crypt++ as well as crypt. | |
2581 (provide 'crypt++) | |
2582 (provide 'crypt) | |
2583 | |
2584 ;;; crypt++.el ends here. |