Mercurial > emacs
annotate lisp/tar-mode.el @ 18092:8428d56cd207
(smtpmail-via-smtp): Recognize XVRB as a synonym for
VERB and XONE as a synonym for ONEX.
(smtpmail-read-response): Add "%s" to `message' calls to avoid
problems with percent signs in strings.
(smtpmail-read-response): Return all lines of the
response text as a list of strings. Formerly only the first line
was returned. This is insufficient when one wants to parse
e.g. an EHLO response.
Ignore responses starting with "0". This is necessary to support
the VERB SMTP extension.
(smtpmail-via-smtp): Try EHLO and find out which SMTP service
extensions the receiving mailer supports.
Issue the ONEX and XUSR commands if the corresponding extensions
are supported.
Issue VERB if supported and `smtpmail-debug-info' is non-nil.
Add SIZE attribute to MAIL FROM: command if SIZE extension is
supported.
Add code that could set the BODY= attribute to MAIL FROM: if the
receiving mailer supports 8BITMIME. This is currently disabled,
since doing it right might involve adding MIME headers to, and in
some cases reencoding, the message.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sun, 01 Jun 1997 22:24:22 +0000 |
parents | 849a396187cd |
children | f55270c78210 |
rev | line source |
---|---|
658
7cbd4fcd8b0f
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
584
diff
changeset
|
1 ;;; tar-mode.el --- simple editing of tar files from GNU emacs |
212 | 2 |
14169 | 3 ;; Copyright (C) 1990, 1991, 1993, 1994, 1995 Free Software Foundation, Inc. |
840
113281b361ec
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
814
diff
changeset
|
4 |
775
1ca26ccad38e
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
658
diff
changeset
|
5 ;; Author: Jamie Zawinski <jwz@lucid.com> |
807
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
775
diff
changeset
|
6 ;; Created: 04 Apr 1990 |
814
38b2499cb3e9
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
807
diff
changeset
|
7 ;; Keywords: unix |
212 | 8 |
14169 | 9 ;; This file is part of GNU Emacs. |
10 | |
11 ;; GNU Emacs is free software; you can redistribute it and/or modify | |
12 ;; it under the terms of the GNU General Public License as published by | |
13 ;; the Free Software Foundation; either version 2, or (at your option) | |
14 ;; any later version. | |
15 | |
16 ;; GNU Emacs is distributed in the hope that it will be useful, | |
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 ;; GNU General Public License for more details. | |
20 | |
21 ;; You should have received a copy of the GNU General Public License | |
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the | |
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
24 ;; Boston, MA 02111-1307, USA. | |
212 | 25 |
775
1ca26ccad38e
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
658
diff
changeset
|
26 ;;; Commentary: |
1ca26ccad38e
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
658
diff
changeset
|
27 |
14169 | 28 ;; This package attempts to make dealing with Unix 'tar' archives easier. |
29 ;; When this code is loaded, visiting a file whose name ends in '.tar' will | |
30 ;; cause the contents of that archive file to be displayed in a Dired-like | |
31 ;; listing. It is then possible to use the customary Dired keybindings to | |
32 ;; extract sub-files from that archive, either by reading them into their own | |
33 ;; editor buffers, or by copying them directly to arbitrary files on disk. | |
34 ;; It is also possible to delete sub-files from within the tar file and write | |
35 ;; the modified archive back to disk, or to edit sub-files within the archive | |
36 ;; and re-insert the modified files into the archive. See the documentation | |
37 ;; string of tar-mode for more info. | |
212 | 38 |
14169 | 39 ;; This code now understands the extra fields that GNU tar adds to tar files. |
212 | 40 |
14169 | 41 ;; This interacts correctly with "uncompress.el" in the Emacs library, |
42 ;; which you get with | |
43 ;; | |
44 ;; (autoload 'uncompress-while-visiting "uncompress") | |
45 ;; (setq auto-mode-alist (cons '("\\.Z$" . uncompress-while-visiting) | |
46 ;; auto-mode-alist)) | |
47 ;; | |
48 ;; Do not attempt to use tar-mode.el with crypt.el, you will lose. | |
212 | 49 |
14169 | 50 ;; *************** TO DO *************** |
51 ;; | |
52 ;; o chmod should understand "a+x,og-w". | |
53 ;; | |
54 ;; o It's not possible to add a NEW file to a tar archive; not that | |
55 ;; important, but still... | |
56 ;; | |
57 ;; o The code is less efficient that it could be - in a lot of places, I | |
58 ;; pull a 512-character string out of the buffer and parse it, when I could | |
59 ;; be parsing it in place, not garbaging a string. Should redo that. | |
60 ;; | |
61 ;; o I'd like a command that searches for a string/regexp in every subfile | |
62 ;; of an archive, where <esc> would leave you in a subfile-edit buffer. | |
63 ;; (Like the Meta-R command of the Zmacs mail reader.) | |
64 ;; | |
65 ;; o Sometimes (but not always) reverting the tar-file buffer does not | |
66 ;; re-grind the listing, and you are staring at the binary tar data. | |
67 ;; Typing 'g' again immediately after that will always revert and re-grind | |
68 ;; it, though. I have no idea why this happens. | |
69 ;; | |
70 ;; o Tar-mode interacts poorly with crypt.el and zcat.el because the tar | |
71 ;; write-file-hook actually writes the file. Instead it should remove the | |
72 ;; header (and conspire to put it back afterwards) so that other write-file | |
73 ;; hooks which frob the buffer have a chance to do their dirty work. There | |
74 ;; might be a problem if the tar write-file-hook does not come *first* on | |
75 ;; the list. | |
76 ;; | |
77 ;; o Block files, sparse files, continuation files, and the various header | |
78 ;; types aren't editable. Actually I don't know that they work at all. | |
212 | 79 |
14169 | 80 ;; Rationale: |
7103 | 81 |
14169 | 82 ;; Why does tar-mode edit the file itself instead of using tar? |
7103 | 83 |
14169 | 84 ;; That means that you can edit tar files which you don't have room for |
85 ;; on your local disk. | |
7103 | 86 |
14169 | 87 ;; I don't know about recent features in gnu tar, but old versions of tar |
88 ;; can't replace a file in the middle of a tar file with a new version. | |
89 ;; Tar-mode can. I don't think tar can do things like chmod the subfiles. | |
90 ;; An implementation which involved unpacking and repacking the file into | |
91 ;; some scratch directory would be very wasteful, and wouldn't be able to | |
92 ;; preserve the file owners. | |
7103 | 93 |
775
1ca26ccad38e
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
658
diff
changeset
|
94 ;;; Code: |
1ca26ccad38e
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
658
diff
changeset
|
95 |
212 | 96 (defvar tar-anal-blocksize 20 |
97 "*The blocksize of tar files written by Emacs, or nil, meaning don't care. | |
98 The blocksize of a tar file is not really the size of the blocks; rather, it is | |
99 the number of blocks written with one system call. When tarring to a tape, | |
100 this is the size of the *tape* blocks, but when writing to a file, it doesn't | |
101 matter much. The only noticeable difference is that if a tar file does not | |
102 have a blocksize of 20, tar will tell you that; all this really controls is | |
103 how many null padding bytes go on the end of the tar file.") | |
104 | |
105 (defvar tar-update-datestamp nil | |
10843
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
106 "*Non-nil means tar-mode should play fast and loose with sub-file datestamps. |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
107 If this is true, then editing and saving a tar file entry back into its |
212 | 108 tar file will update its datestamp. If false, the datestamp is unchanged. |
109 You may or may not want this - it is good in that you can tell when a file | |
110 in a tar archive has been changed, but it is bad for the same reason that | |
111 editing a file in the tar archive at all is bad - the changed version of | |
584 | 112 the file never exists on disk.") |
212 | 113 |
10843
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
114 (defvar tar-mode-show-date nil |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
115 "*Non-nil means Tar mode should show the date/time of each subfile. |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
116 This information is useful, but it takes screen space away from file names.") |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
117 |
2542
ae4176e2e8fa
Add defvars to pacify the byte compiler, at RMS's request.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
880
diff
changeset
|
118 (defvar tar-parse-info nil) |
ae4176e2e8fa
Add defvars to pacify the byte compiler, at RMS's request.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
880
diff
changeset
|
119 (defvar tar-header-offset nil) |
ae4176e2e8fa
Add defvars to pacify the byte compiler, at RMS's request.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
880
diff
changeset
|
120 (defvar tar-superior-buffer nil) |
ae4176e2e8fa
Add defvars to pacify the byte compiler, at RMS's request.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
880
diff
changeset
|
121 (defvar tar-superior-descriptor nil) |
ae4176e2e8fa
Add defvars to pacify the byte compiler, at RMS's request.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
880
diff
changeset
|
122 (defvar tar-subfile-mode nil) |
4260
e0713a13f2d7
(tar-parse-info, tar-header-offset, tar-superior-buffer)
Richard M. Stallman <rms@gnu.org>
parents:
4120
diff
changeset
|
123 |
e0713a13f2d7
(tar-parse-info, tar-header-offset, tar-superior-buffer)
Richard M. Stallman <rms@gnu.org>
parents:
4120
diff
changeset
|
124 (put 'tar-parse-info 'permanent-local t) |
e0713a13f2d7
(tar-parse-info, tar-header-offset, tar-superior-buffer)
Richard M. Stallman <rms@gnu.org>
parents:
4120
diff
changeset
|
125 (put 'tar-header-offset 'permanent-local t) |
e0713a13f2d7
(tar-parse-info, tar-header-offset, tar-superior-buffer)
Richard M. Stallman <rms@gnu.org>
parents:
4120
diff
changeset
|
126 (put 'tar-superior-buffer 'permanent-local t) |
e0713a13f2d7
(tar-parse-info, tar-header-offset, tar-superior-buffer)
Richard M. Stallman <rms@gnu.org>
parents:
4120
diff
changeset
|
127 (put 'tar-superior-descriptor 'permanent-local t) |
212 | 128 |
129 ;;; First, duplicate some Common Lisp functions; I used to just (require 'cl) | |
130 ;;; but "cl.el" was messing some people up (also it's really big). | |
131 | |
132 (defmacro tar-setf (form val) | |
133 "A mind-numbingly simple implementation of setf." | |
134 (let ((mform (macroexpand form (and (boundp 'byte-compile-macro-environment) | |
135 byte-compile-macro-environment)))) | |
136 (cond ((symbolp mform) (list 'setq mform val)) | |
137 ((not (consp mform)) (error "can't setf %s" form)) | |
138 ((eq (car mform) 'aref) | |
139 (list 'aset (nth 1 mform) (nth 2 mform) val)) | |
140 ((eq (car mform) 'car) | |
141 (list 'setcar (nth 1 mform) val)) | |
142 ((eq (car mform) 'cdr) | |
143 (list 'setcdr (nth 1 mform) val)) | |
144 (t (error "don't know how to setf %s" form))))) | |
145 | |
146 (defmacro tar-dolist (control &rest body) | |
147 "syntax: (dolist (var-name list-expr &optional return-value) &body body)" | |
148 (let ((var (car control)) | |
149 (init (car (cdr control))) | |
150 (val (car (cdr (cdr control))))) | |
151 (list 'let (list (list '_dolist_iterator_ init)) | |
152 (list 'while '_dolist_iterator_ | |
153 (cons 'let | |
154 (cons (list (list var '(car _dolist_iterator_))) | |
155 (append body | |
156 (list (list 'setq '_dolist_iterator_ | |
157 (list 'cdr '_dolist_iterator_))))))) | |
158 val))) | |
159 | |
160 (defmacro tar-dotimes (control &rest body) | |
161 "syntax: (dolist (var-name count-expr &optional return-value) &body body)" | |
162 (let ((var (car control)) | |
163 (n (car (cdr control))) | |
164 (val (car (cdr (cdr control))))) | |
165 (list 'let (list (list '_dotimes_end_ n) | |
166 (list var 0)) | |
167 (cons 'while | |
168 (cons (list '< var '_dotimes_end_) | |
169 (append body | |
170 (list (list 'setq var (list '1+ var)))))) | |
171 val))) | |
172 | |
173 | |
174 ;;; down to business. | |
175 | |
176 (defmacro make-tar-header (name mode uid git size date ck lt ln | |
177 magic uname gname devmaj devmin) | |
178 (list 'vector name mode uid git size date ck lt ln | |
179 magic uname gname devmaj devmin)) | |
180 | |
181 (defmacro tar-header-name (x) (list 'aref x 0)) | |
182 (defmacro tar-header-mode (x) (list 'aref x 1)) | |
183 (defmacro tar-header-uid (x) (list 'aref x 2)) | |
184 (defmacro tar-header-gid (x) (list 'aref x 3)) | |
185 (defmacro tar-header-size (x) (list 'aref x 4)) | |
186 (defmacro tar-header-date (x) (list 'aref x 5)) | |
187 (defmacro tar-header-checksum (x) (list 'aref x 6)) | |
188 (defmacro tar-header-link-type (x) (list 'aref x 7)) | |
189 (defmacro tar-header-link-name (x) (list 'aref x 8)) | |
190 (defmacro tar-header-magic (x) (list 'aref x 9)) | |
191 (defmacro tar-header-uname (x) (list 'aref x 10)) | |
192 (defmacro tar-header-gname (x) (list 'aref x 11)) | |
193 (defmacro tar-header-dmaj (x) (list 'aref x 12)) | |
194 (defmacro tar-header-dmin (x) (list 'aref x 13)) | |
195 | |
196 (defmacro make-tar-desc (data-start tokens) | |
197 (list 'cons data-start tokens)) | |
198 | |
199 (defmacro tar-desc-data-start (x) (list 'car x)) | |
200 (defmacro tar-desc-tokens (x) (list 'cdr x)) | |
201 | |
202 (defconst tar-name-offset 0) | |
203 (defconst tar-mode-offset (+ tar-name-offset 100)) | |
204 (defconst tar-uid-offset (+ tar-mode-offset 8)) | |
205 (defconst tar-gid-offset (+ tar-uid-offset 8)) | |
206 (defconst tar-size-offset (+ tar-gid-offset 8)) | |
207 (defconst tar-time-offset (+ tar-size-offset 12)) | |
208 (defconst tar-chk-offset (+ tar-time-offset 12)) | |
209 (defconst tar-linkp-offset (+ tar-chk-offset 8)) | |
210 (defconst tar-link-offset (+ tar-linkp-offset 1)) | |
211 ;;; GNU-tar specific slots. | |
212 (defconst tar-magic-offset (+ tar-link-offset 100)) | |
213 (defconst tar-uname-offset (+ tar-magic-offset 8)) | |
214 (defconst tar-gname-offset (+ tar-uname-offset 32)) | |
215 (defconst tar-dmaj-offset (+ tar-gname-offset 32)) | |
216 (defconst tar-dmin-offset (+ tar-dmaj-offset 8)) | |
217 (defconst tar-end-offset (+ tar-dmin-offset 8)) | |
218 | |
8023
f29df49c6e53
(tar-extract): Set file name by hand before calling
Richard M. Stallman <rms@gnu.org>
parents:
7497
diff
changeset
|
219 (defun tar-header-block-tokenize (string) |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
220 "Return a `tar-header' structure. |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
221 This is a list of name, mode, uid, gid, size, |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
222 write-date, checksum, link-type, and link-name." |
212 | 223 (cond ((< (length string) 512) nil) |
224 (;(some 'plusp string) ; <-- oops, massive cycle hog! | |
225 (or (not (= 0 (aref string 0))) ; This will do. | |
226 (not (= 0 (aref string 101)))) | |
227 (let* ((name-end (1- tar-mode-offset)) | |
228 (link-end (1- tar-magic-offset)) | |
229 (uname-end (1- tar-gname-offset)) | |
230 (gname-end (1- tar-dmaj-offset)) | |
231 (link-p (aref string tar-linkp-offset)) | |
232 (magic-str (substring string tar-magic-offset (1- tar-uname-offset))) | |
233 (uname-valid-p (or (string= "ustar " magic-str) (string= "GNUtar " magic-str))) | |
234 name | |
235 (nulsexp "[^\000]*\000")) | |
236 (and (string-match nulsexp string tar-name-offset) (setq name-end (min name-end (1- (match-end 0))))) | |
237 (and (string-match nulsexp string tar-link-offset) (setq link-end (min link-end (1- (match-end 0))))) | |
238 (and (string-match nulsexp string tar-uname-offset) (setq uname-end (min uname-end (1- (match-end 0))))) | |
239 (and (string-match nulsexp string tar-gname-offset) (setq gname-end (min gname-end (1- (match-end 0))))) | |
240 (setq name (substring string tar-name-offset name-end) | |
241 link-p (if (or (= link-p 0) (= link-p ?0)) | |
242 nil | |
243 (- link-p ?0))) | |
244 (if (and (null link-p) (string-match "/$" name)) (setq link-p 5)) ; directory | |
245 (make-tar-header | |
246 name | |
247 (tar-parse-octal-integer string tar-mode-offset (1- tar-uid-offset)) | |
248 (tar-parse-octal-integer string tar-uid-offset (1- tar-gid-offset)) | |
249 (tar-parse-octal-integer string tar-gid-offset (1- tar-size-offset)) | |
250 (tar-parse-octal-integer string tar-size-offset (1- tar-time-offset)) | |
10843
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
251 (tar-parse-octal-long-integer string tar-time-offset (1- tar-chk-offset)) |
212 | 252 (tar-parse-octal-integer string tar-chk-offset (1- tar-linkp-offset)) |
253 link-p | |
254 (substring string tar-link-offset link-end) | |
255 uname-valid-p | |
256 (and uname-valid-p (substring string tar-uname-offset uname-end)) | |
257 (and uname-valid-p (substring string tar-gname-offset gname-end)) | |
258 (tar-parse-octal-integer string tar-dmaj-offset (1- tar-dmin-offset)) | |
259 (tar-parse-octal-integer string tar-dmin-offset (1- tar-end-offset)) | |
260 ))) | |
261 (t 'empty-tar-block))) | |
262 | |
263 | |
264 (defun tar-parse-octal-integer (string &optional start end) | |
265 (if (null start) (setq start 0)) | |
266 (if (null end) (setq end (length string))) | |
267 (if (= (aref string start) 0) | |
268 0 | |
269 (let ((n 0)) | |
270 (while (< start end) | |
271 (setq n (if (< (aref string start) ?0) n | |
10843
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
272 (+ (* n 8) (- (aref string start) ?0))) |
212 | 273 start (1+ start))) |
274 n))) | |
275 | |
10843
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
276 (defun tar-parse-octal-long-integer (string &optional start end) |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
277 (if (null start) (setq start 0)) |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
278 (if (null end) (setq end (length string))) |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
279 (if (= (aref string start) 0) |
11071
d629a0af50ca
(tar-parse-octal-long-integer): Return list, not vector.
Karl Heuer <kwzh@gnu.org>
parents:
10922
diff
changeset
|
280 (list 0 0) |
10843
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
281 (let ((lo 0) |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
282 (hi 0)) |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
283 (while (< start end) |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
284 (if (>= (aref string start) ?0) |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
285 (setq lo (+ (* lo 8) (- (aref string start) ?0)) |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
286 hi (+ (* hi 8) (ash lo -16)) |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
287 lo (logand lo 65535))) |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
288 (setq start (1+ start))) |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
289 (list hi lo)))) |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
290 |
212 | 291 (defun tar-parse-octal-integer-safe (string) |
292 (let ((L (length string))) | |
293 (if (= L 0) (error "empty string")) | |
294 (tar-dotimes (i L) | |
295 (if (or (< (aref string i) ?0) | |
296 (> (aref string i) ?7)) | |
6611
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
297 (error "'%c' is not an octal digit")))) |
212 | 298 (tar-parse-octal-integer string)) |
299 | |
300 | |
8023
f29df49c6e53
(tar-extract): Set file name by hand before calling
Richard M. Stallman <rms@gnu.org>
parents:
7497
diff
changeset
|
301 (defun tar-header-block-checksum (string) |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
302 "Compute and return a tar-acceptable checksum for this block." |
212 | 303 (let* ((chk-field-start tar-chk-offset) |
304 (chk-field-end (+ chk-field-start 8)) | |
305 (sum 0) | |
306 (i 0)) | |
307 ;; Add up all of the characters except the ones in the checksum field. | |
308 ;; Add that field as if it were filled with spaces. | |
309 (while (< i chk-field-start) | |
310 (setq sum (+ sum (aref string i)) | |
311 i (1+ i))) | |
312 (setq i chk-field-end) | |
313 (while (< i 512) | |
314 (setq sum (+ sum (aref string i)) | |
315 i (1+ i))) | |
316 (+ sum (* 32 8)))) | |
317 | |
8023
f29df49c6e53
(tar-extract): Set file name by hand before calling
Richard M. Stallman <rms@gnu.org>
parents:
7497
diff
changeset
|
318 (defun tar-header-block-check-checksum (hblock desired-checksum file-name) |
212 | 319 "Beep and print a warning if the checksum doesn't match." |
8023
f29df49c6e53
(tar-extract): Set file name by hand before calling
Richard M. Stallman <rms@gnu.org>
parents:
7497
diff
changeset
|
320 (if (not (= desired-checksum (tar-header-block-checksum hblock))) |
212 | 321 (progn (beep) (message "Invalid checksum for file %s!" file-name)))) |
322 | |
8023
f29df49c6e53
(tar-extract): Set file name by hand before calling
Richard M. Stallman <rms@gnu.org>
parents:
7497
diff
changeset
|
323 (defun tar-header-block-recompute-checksum (hblock) |
212 | 324 "Modifies the given string to have a valid checksum field." |
8023
f29df49c6e53
(tar-extract): Set file name by hand before calling
Richard M. Stallman <rms@gnu.org>
parents:
7497
diff
changeset
|
325 (let* ((chk (tar-header-block-checksum hblock)) |
212 | 326 (chk-string (format "%6o" chk)) |
327 (l (length chk-string))) | |
328 (aset hblock 154 0) | |
329 (aset hblock 155 32) | |
330 (tar-dotimes (i l) (aset hblock (- 153 i) (aref chk-string (- l i 1))))) | |
331 hblock) | |
332 | |
10843
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
333 (defun tar-clip-time-string (time) |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
334 (let ((str (current-time-string time))) |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
335 (concat (substring str 4 16) (substring str 19 24)))) |
212 | 336 |
337 (defun tar-grind-file-mode (mode string start) | |
10922
0c3d44805949
(tar-grind-file-mode): Doc fix.
Richard M. Stallman <rms@gnu.org>
parents:
10843
diff
changeset
|
338 "Store `-rw--r--r--' indicating MODE into STRING beginning at START. |
0c3d44805949
(tar-grind-file-mode): Doc fix.
Richard M. Stallman <rms@gnu.org>
parents:
10843
diff
changeset
|
339 MODE should be an integer which is a file mode value." |
212 | 340 (aset string start (if (zerop (logand 256 mode)) ?- ?r)) |
341 (aset string (+ start 1) (if (zerop (logand 128 mode)) ?- ?w)) | |
342 (aset string (+ start 2) (if (zerop (logand 64 mode)) ?- ?x)) | |
343 (aset string (+ start 3) (if (zerop (logand 32 mode)) ?- ?r)) | |
344 (aset string (+ start 4) (if (zerop (logand 16 mode)) ?- ?w)) | |
345 (aset string (+ start 5) (if (zerop (logand 8 mode)) ?- ?x)) | |
346 (aset string (+ start 6) (if (zerop (logand 4 mode)) ?- ?r)) | |
347 (aset string (+ start 7) (if (zerop (logand 2 mode)) ?- ?w)) | |
348 (aset string (+ start 8) (if (zerop (logand 1 mode)) ?- ?x)) | |
349 (if (zerop (logand 1024 mode)) nil (aset string (+ start 2) ?s)) | |
350 (if (zerop (logand 2048 mode)) nil (aset string (+ start 5) ?s)) | |
351 string) | |
352 | |
8023
f29df49c6e53
(tar-extract): Set file name by hand before calling
Richard M. Stallman <rms@gnu.org>
parents:
7497
diff
changeset
|
353 (defun tar-header-block-summarize (tar-hblock &optional mod-p) |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
354 "Returns a line similar to the output of `tar -vtf'." |
212 | 355 (let ((name (tar-header-name tar-hblock)) |
356 (mode (tar-header-mode tar-hblock)) | |
357 (uid (tar-header-uid tar-hblock)) | |
358 (gid (tar-header-gid tar-hblock)) | |
359 (uname (tar-header-uname tar-hblock)) | |
360 (gname (tar-header-gname tar-hblock)) | |
361 (size (tar-header-size tar-hblock)) | |
362 (time (tar-header-date tar-hblock)) | |
363 (ck (tar-header-checksum tar-hblock)) | |
364 (link-p (tar-header-link-type tar-hblock)) | |
365 (link-name (tar-header-link-name tar-hblock)) | |
366 ) | |
367 (let* ((left 11) | |
368 (namew 8) | |
369 (groupw 8) | |
370 (sizew 8) | |
10843
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
371 (datew (if tar-mode-show-date 18 0)) |
212 | 372 (slash (1- (+ left namew))) |
373 (lastdigit (+ slash groupw sizew)) | |
10843
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
374 (datestart (+ lastdigit 2)) |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
375 (namestart (+ datestart datew)) |
212 | 376 (string (make-string (+ namestart (length name) (if link-p (+ 5 (length link-name)) 0)) 32)) |
377 (type (tar-header-link-type tar-hblock))) | |
378 (aset string 0 (if mod-p ?* ? )) | |
379 (aset string 1 | |
380 (cond ((or (eq type nil) (eq type 0)) ?-) | |
381 ((eq type 1) ?l) ; link | |
382 ((eq type 2) ?s) ; symlink | |
383 ((eq type 3) ?c) ; char special | |
384 ((eq type 4) ?b) ; block special | |
385 ((eq type 5) ?d) ; directory | |
386 ((eq type 6) ?p) ; FIFO/pipe | |
387 ((eq type 20) ?*) ; directory listing | |
388 ((eq type 29) ?M) ; multivolume continuation | |
389 ((eq type 35) ?S) ; sparse | |
390 ((eq type 38) ?V) ; volume header | |
391 )) | |
392 (tar-grind-file-mode mode string 2) | |
393 (setq uid (if (= 0 (length uname)) (int-to-string uid) uname)) | |
394 (setq gid (if (= 0 (length gname)) (int-to-string gid) gname)) | |
395 (setq size (int-to-string size)) | |
10843
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
396 (setq time (tar-clip-time-string time)) |
212 | 397 (tar-dotimes (i (min (1- namew) (length uid))) (aset string (- slash i) (aref uid (- (length uid) i 1)))) |
398 (aset string (1+ slash) ?/) | |
399 (tar-dotimes (i (min (1- groupw) (length gid))) (aset string (+ (+ slash 2) i) (aref gid i))) | |
400 (tar-dotimes (i (min sizew (length size))) (aset string (- lastdigit i) (aref size (- (length size) i 1)))) | |
10843
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
401 (if tar-mode-show-date |
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
402 (tar-dotimes (i (length time)) (aset string (+ datestart i) (aref time i)))) |
212 | 403 (tar-dotimes (i (length name)) (aset string (+ namestart i) (aref name i))) |
404 (if (or (eq link-p 1) (eq link-p 2)) | |
405 (progn | |
406 (tar-dotimes (i 3) (aset string (+ namestart 1 (length name) i) (aref (if (= link-p 1) "==>" "-->") i))) | |
407 (tar-dotimes (i (length link-name)) (aset string (+ namestart 5 (length name) i) (aref link-name i))))) | |
6641
4e76332f7b44
(summarize-tar-header-block): Add mouse-face properties.
Karl Heuer <kwzh@gnu.org>
parents:
6611
diff
changeset
|
408 (put-text-property namestart (length string) |
4e76332f7b44
(summarize-tar-header-block): Add mouse-face properties.
Karl Heuer <kwzh@gnu.org>
parents:
6611
diff
changeset
|
409 'mouse-face 'highlight string) |
212 | 410 string))) |
411 | |
412 | |
413 (defun tar-summarize-buffer () | |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
414 "Parse the contents of the tar file in the current buffer. |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
415 Place a dired-like listing on the front; |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
416 then narrow to it, so that only that listing |
212 | 417 is visible (and the real data of the buffer is hidden)." |
11450
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
418 (message "Parsing tar file...") |
212 | 419 (let* ((result '()) |
420 (pos 1) | |
421 (bs (max 1 (- (buffer-size) 1024))) ; always 2+ empty blocks at end. | |
422 (bs100 (max 1 (/ bs 100))) | |
9724
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
423 tokens) |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
424 (while (and (<= (+ pos 512) (point-max)) |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
425 (not (eq 'empty-tar-block |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
426 (setq tokens |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
427 (tar-header-block-tokenize |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
428 (buffer-substring pos (+ pos 512))))))) |
9698
b321ed01c3dc
(tar-summarize-buffer): Check for end of buffer before extracting substring.
Karl Heuer <kwzh@gnu.org>
parents:
8043
diff
changeset
|
429 (setq pos (+ pos 512)) |
9724
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
430 (message "Parsing tar file...%d%%" |
9698
b321ed01c3dc
(tar-summarize-buffer): Check for end of buffer before extracting substring.
Karl Heuer <kwzh@gnu.org>
parents:
8043
diff
changeset
|
431 ;(/ (* pos 100) bs) ; this gets round-off lossage |
b321ed01c3dc
(tar-summarize-buffer): Check for end of buffer before extracting substring.
Karl Heuer <kwzh@gnu.org>
parents:
8043
diff
changeset
|
432 (/ pos bs100) ; this doesn't |
b321ed01c3dc
(tar-summarize-buffer): Check for end of buffer before extracting substring.
Karl Heuer <kwzh@gnu.org>
parents:
8043
diff
changeset
|
433 ) |
9724
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
434 (if (eq (tar-header-link-type tokens) 20) |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
435 ;; Foo. There's an extra empty block after these. |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
436 (setq pos (+ pos 512))) |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
437 (let ((size (tar-header-size tokens))) |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
438 (if (< size 0) |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
439 (error "%s has size %s - corrupted" |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
440 (tar-header-name tokens) size)) |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
441 ; |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
442 ; This is just too slow. Don't really need it anyway.... |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
443 ;(tar-header-block-check-checksum |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
444 ; hblock (tar-header-block-checksum hblock) |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
445 ; (tar-header-name tokens)) |
9698
b321ed01c3dc
(tar-summarize-buffer): Check for end of buffer before extracting substring.
Karl Heuer <kwzh@gnu.org>
parents:
8043
diff
changeset
|
446 |
9724
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
447 (setq result (cons (make-tar-desc pos tokens) result)) |
9698
b321ed01c3dc
(tar-summarize-buffer): Check for end of buffer before extracting substring.
Karl Heuer <kwzh@gnu.org>
parents:
8043
diff
changeset
|
448 |
9724
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
449 (and (null (tar-header-link-type tokens)) |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
450 (> size 0) |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
451 (setq pos |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
452 (+ pos 512 (ash (ash (1- size) -9) 9)) ; this works |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
453 ;(+ pos (+ size (- 512 (rem (1- size) 512)))) ; this doesn't |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
454 )))) |
212 | 455 (make-local-variable 'tar-parse-info) |
9724
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
456 (setq tar-parse-info (nreverse result)) |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
457 ;; A tar file should end with a block or two of nulls, |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
458 ;; but let's not get a fatal error if it doesn't. |
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
459 (if (eq tokens 'empty-tar-block) |
14294
f8eba77ccb7f
(tar-summarize-buffer): Fix "done" message.
Karl Heuer <kwzh@gnu.org>
parents:
14174
diff
changeset
|
460 (message "Parsing tar file...done") |
9724
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
461 (message "Warning: premature EOF parsing tar file"))) |
212 | 462 (save-excursion |
463 (goto-char (point-min)) | |
14174
b986e1fb97a5
(tar-summarize-buffer): Speed-up for large files.
Richard M. Stallman <rms@gnu.org>
parents:
14169
diff
changeset
|
464 (let ((buffer-read-only nil) |
b986e1fb97a5
(tar-summarize-buffer): Speed-up for large files.
Richard M. Stallman <rms@gnu.org>
parents:
14169
diff
changeset
|
465 (summaries nil)) |
b986e1fb97a5
(tar-summarize-buffer): Speed-up for large files.
Richard M. Stallman <rms@gnu.org>
parents:
14169
diff
changeset
|
466 ;; Collect summary lines and insert them all at once since tar files |
b986e1fb97a5
(tar-summarize-buffer): Speed-up for large files.
Richard M. Stallman <rms@gnu.org>
parents:
14169
diff
changeset
|
467 ;; can be pretty big. |
14294
f8eba77ccb7f
(tar-summarize-buffer): Fix "done" message.
Karl Heuer <kwzh@gnu.org>
parents:
14174
diff
changeset
|
468 (tar-dolist (tar-desc (reverse tar-parse-info)) |
14174
b986e1fb97a5
(tar-summarize-buffer): Speed-up for large files.
Richard M. Stallman <rms@gnu.org>
parents:
14169
diff
changeset
|
469 (setq summaries |
b986e1fb97a5
(tar-summarize-buffer): Speed-up for large files.
Richard M. Stallman <rms@gnu.org>
parents:
14169
diff
changeset
|
470 (cons (tar-header-block-summarize (tar-desc-tokens tar-desc)) |
b986e1fb97a5
(tar-summarize-buffer): Speed-up for large files.
Richard M. Stallman <rms@gnu.org>
parents:
14169
diff
changeset
|
471 (cons "\n" |
b986e1fb97a5
(tar-summarize-buffer): Speed-up for large files.
Richard M. Stallman <rms@gnu.org>
parents:
14169
diff
changeset
|
472 summaries)))) |
b986e1fb97a5
(tar-summarize-buffer): Speed-up for large files.
Richard M. Stallman <rms@gnu.org>
parents:
14169
diff
changeset
|
473 (insert (apply 'concat summaries)) |
212 | 474 (make-local-variable 'tar-header-offset) |
475 (setq tar-header-offset (point)) | |
476 (narrow-to-region 1 tar-header-offset) | |
9724
193eeb5e78aa
(tar-summarize-buffer): Improperly terminated archive now produces only a
Karl Heuer <kwzh@gnu.org>
parents:
9698
diff
changeset
|
477 (set-buffer-modified-p nil)))) |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
478 |
6611
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
479 (defvar tar-mode-map nil "*Local keymap for Tar mode listings.") |
212 | 480 |
481 (if tar-mode-map | |
482 nil | |
483 (setq tar-mode-map (make-keymap)) | |
484 (suppress-keymap tar-mode-map) | |
485 (define-key tar-mode-map " " 'tar-next-line) | |
486 (define-key tar-mode-map "c" 'tar-copy) | |
487 (define-key tar-mode-map "d" 'tar-flag-deleted) | |
488 (define-key tar-mode-map "\^D" 'tar-flag-deleted) | |
489 (define-key tar-mode-map "e" 'tar-extract) | |
490 (define-key tar-mode-map "f" 'tar-extract) | |
10271
d20db86b0c0c
(tar-mode-map): Bind C-m to tar-extract.
Richard M. Stallman <rms@gnu.org>
parents:
10188
diff
changeset
|
491 (define-key tar-mode-map "\C-m" 'tar-extract) |
6611
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
492 (define-key tar-mode-map [mouse-2] 'tar-mouse-extract) |
212 | 493 (define-key tar-mode-map "g" 'revert-buffer) |
494 (define-key tar-mode-map "h" 'describe-mode) | |
495 (define-key tar-mode-map "n" 'tar-next-line) | |
496 (define-key tar-mode-map "\^N" 'tar-next-line) | |
15612
9b55a88233d1
(tar-mode-map): Bind up and down like C-p, C-n.
Miles Bader <miles@gnu.org>
parents:
15424
diff
changeset
|
497 (define-key tar-mode-map [down] 'tar-next-line) |
212 | 498 (define-key tar-mode-map "o" 'tar-extract-other-window) |
499 (define-key tar-mode-map "p" 'tar-previous-line) | |
500 (define-key tar-mode-map "\^P" 'tar-previous-line) | |
15612
9b55a88233d1
(tar-mode-map): Bind up and down like C-p, C-n.
Miles Bader <miles@gnu.org>
parents:
15424
diff
changeset
|
501 (define-key tar-mode-map [up] 'tar-previous-line) |
212 | 502 (define-key tar-mode-map "r" 'tar-rename-entry) |
503 (define-key tar-mode-map "u" 'tar-unflag) | |
504 (define-key tar-mode-map "v" 'tar-view) | |
505 (define-key tar-mode-map "x" 'tar-expunge) | |
506 (define-key tar-mode-map "\177" 'tar-unflag-backwards) | |
507 (define-key tar-mode-map "E" 'tar-extract-other-window) | |
508 (define-key tar-mode-map "M" 'tar-chmod-entry) | |
509 (define-key tar-mode-map "G" 'tar-chgrp-entry) | |
510 (define-key tar-mode-map "O" 'tar-chown-entry) | |
511 ) | |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
512 |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
513 ;; Make menu bar items. |
212 | 514 |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
515 ;; Get rid of the Edit menu bar item to save space. |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
516 (define-key tar-mode-map [menu-bar edit] 'undefined) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
517 |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
518 (define-key tar-mode-map [menu-bar immediate] |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
519 (cons "Immediate" (make-sparse-keymap "Immediate"))) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
520 |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
521 (define-key tar-mode-map [menu-bar immediate view] |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
522 '("View This File" . tar-view)) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
523 (define-key tar-mode-map [menu-bar immediate display] |
11210
48cbab79b9e7
(tar-mode-map): Fix typo for tar-display-other-file.
Richard M. Stallman <rms@gnu.org>
parents:
11071
diff
changeset
|
524 '("Display in Other Window" . tar-display-other-file)) |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
525 (define-key tar-mode-map [menu-bar immediate find-file-other-window] |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
526 '("Find in Other Window" . tar-extract-other-window)) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
527 (define-key tar-mode-map [menu-bar immediate find-file] |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
528 '("Find This File" . tar-extract)) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
529 |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
530 (define-key tar-mode-map [menu-bar mark] |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
531 (cons "Mark" (make-sparse-keymap "Mark"))) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
532 |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
533 (define-key tar-mode-map [menu-bar mark unmark-all] |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
534 '("Unmark All" . tar-clear-modification-flags)) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
535 (define-key tar-mode-map [menu-bar mark deletion] |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
536 '("Flag" . tar-flag-deleted)) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
537 (define-key tar-mode-map [menu-bar mark unmark] |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
538 '("Unflag" . tar-unflag)) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
539 |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
540 (define-key tar-mode-map [menu-bar operate] |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
541 (cons "Operate" (make-sparse-keymap "Operate"))) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
542 |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
543 (define-key tar-mode-map [menu-bar operate chown] |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
544 '("Change Owner..." . tar-chown-entry)) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
545 (define-key tar-mode-map [menu-bar operate chgrp] |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
546 '("Change Group..." . tar-chgrp-entry)) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
547 (define-key tar-mode-map [menu-bar operate chmod] |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
548 '("Change Mode..." . tar-chmod-entry)) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
549 (define-key tar-mode-map [menu-bar operate rename] |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
550 '("Rename to..." . tar-rename-entry)) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
551 (define-key tar-mode-map [menu-bar operate copy] |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
552 '("Copy to..." . tar-copy)) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
553 (define-key tar-mode-map [menu-bar operate expunge] |
12027
d5a2fb3235ef
(tar-mode-map): Fix capitalization in menu bar.
Karl Heuer <kwzh@gnu.org>
parents:
11847
diff
changeset
|
554 '("Expunge Marked Files" . tar-expunge)) |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
555 |
212 | 556 ;; tar mode is suitable only for specially formatted data. |
557 (put 'tar-mode 'mode-class 'special) | |
558 (put 'tar-subfile-mode 'mode-class 'special) | |
559 | |
3419
97205883b02d
Typo in autoload cookie.
Richard M. Stallman <rms@gnu.org>
parents:
3365
diff
changeset
|
560 ;;;###autoload |
212 | 561 (defun tar-mode () |
562 "Major mode for viewing a tar file as a dired-like listing of its contents. | |
563 You can move around using the usual cursor motion commands. | |
564 Letters no longer insert themselves. | |
6611
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
565 Type `e' to pull a file out of the tar file and into its own buffer; |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
566 or click mouse-2 on the file's line in the Tar mode buffer. |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
567 Type `c' to copy an entry from the tar file into another file on disk. |
212 | 568 |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
569 If you edit a sub-file of this archive (as with the `e' command) and |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
570 save it with Control-x Control-s, the contents of that buffer will be |
212 | 571 saved back into the tar-file buffer; in this way you can edit a file |
572 inside of a tar archive without extracting it and re-archiving it. | |
573 | |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
574 See also: variables `tar-update-datestamp' and `tar-anal-blocksize'. |
212 | 575 \\{tar-mode-map}" |
576 ;; this is not interactive because you shouldn't be turning this | |
577 ;; mode on and off. You can corrupt things that way. | |
4260
e0713a13f2d7
(tar-parse-info, tar-header-offset, tar-superior-buffer)
Richard M. Stallman <rms@gnu.org>
parents:
4120
diff
changeset
|
578 ;; rms: with permanent locals, it should now be possible to make this work |
e0713a13f2d7
(tar-parse-info, tar-header-offset, tar-superior-buffer)
Richard M. Stallman <rms@gnu.org>
parents:
4120
diff
changeset
|
579 ;; interactively in some reasonable fashion. |
e0713a13f2d7
(tar-parse-info, tar-header-offset, tar-superior-buffer)
Richard M. Stallman <rms@gnu.org>
parents:
4120
diff
changeset
|
580 (kill-all-local-variables) |
212 | 581 (make-local-variable 'tar-header-offset) |
582 (make-local-variable 'tar-parse-info) | |
583 (make-local-variable 'require-final-newline) | |
584 (setq require-final-newline nil) ; binary data, dude... | |
585 (make-local-variable 'revert-buffer-function) | |
586 (setq revert-buffer-function 'tar-mode-revert) | |
4260
e0713a13f2d7
(tar-parse-info, tar-header-offset, tar-superior-buffer)
Richard M. Stallman <rms@gnu.org>
parents:
4120
diff
changeset
|
587 (make-local-variable 'enable-local-variables) |
e0713a13f2d7
(tar-parse-info, tar-header-offset, tar-superior-buffer)
Richard M. Stallman <rms@gnu.org>
parents:
4120
diff
changeset
|
588 (setq enable-local-variables nil) |
11450
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
589 (make-local-variable 'next-line-add-newlines) |
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
590 (setq next-line-add-newlines nil) |
212 | 591 (setq major-mode 'tar-mode) |
592 (setq mode-name "Tar") | |
593 (use-local-map tar-mode-map) | |
594 (auto-save-mode 0) | |
11847
c5cf8807738b
(tar-mode): Set write-contents-hooks instead of
Karl Heuer <kwzh@gnu.org>
parents:
11450
diff
changeset
|
595 (make-local-variable 'write-contents-hooks) |
c5cf8807738b
(tar-mode): Set write-contents-hooks instead of
Karl Heuer <kwzh@gnu.org>
parents:
11450
diff
changeset
|
596 (setq write-contents-hooks '(tar-mode-write-file)) |
212 | 597 (widen) |
598 (if (and (boundp 'tar-header-offset) tar-header-offset) | |
599 (narrow-to-region 1 tar-header-offset) | |
600 (tar-summarize-buffer)) | |
601 (run-hooks 'tar-mode-hook) | |
602 ) | |
603 | |
604 | |
605 (defun tar-subfile-mode (p) | |
606 "Minor mode for editing an element of a tar-file. | |
14769
acf049402d18
(tar-subfile-mode): Doc fix.
Richard M. Stallman <rms@gnu.org>
parents:
14294
diff
changeset
|
607 This mode arranges for \"saving\" this buffer to write the data |
acf049402d18
(tar-subfile-mode): Doc fix.
Richard M. Stallman <rms@gnu.org>
parents:
14294
diff
changeset
|
608 into the tar-file buffer that it came from. The changes will actually |
acf049402d18
(tar-subfile-mode): Doc fix.
Richard M. Stallman <rms@gnu.org>
parents:
14294
diff
changeset
|
609 appear on disk when you save the tar-file's buffer." |
212 | 610 (interactive "P") |
2542
ae4176e2e8fa
Add defvars to pacify the byte compiler, at RMS's request.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
880
diff
changeset
|
611 (or (and (boundp 'tar-superior-buffer) tar-superior-buffer) |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
612 (error "This buffer is not an element of a tar file")) |
7078
cf120e7b7d2c
(tar-extract): Don't put whole file name in buffer name.
Richard M. Stallman <rms@gnu.org>
parents:
6641
diff
changeset
|
613 ;;; Don't do this, because it is redundant and wastes mode line space. |
cf120e7b7d2c
(tar-extract): Don't put whole file name in buffer name.
Richard M. Stallman <rms@gnu.org>
parents:
6641
diff
changeset
|
614 ;;; (or (assq 'tar-subfile-mode minor-mode-alist) |
cf120e7b7d2c
(tar-extract): Don't put whole file name in buffer name.
Richard M. Stallman <rms@gnu.org>
parents:
6641
diff
changeset
|
615 ;;; (setq minor-mode-alist (append minor-mode-alist |
cf120e7b7d2c
(tar-extract): Don't put whole file name in buffer name.
Richard M. Stallman <rms@gnu.org>
parents:
6641
diff
changeset
|
616 ;;; (list '(tar-subfile-mode " TarFile"))))) |
212 | 617 (make-local-variable 'tar-subfile-mode) |
618 (setq tar-subfile-mode | |
619 (if (null p) | |
620 (not tar-subfile-mode) | |
621 (> (prefix-numeric-value p) 0))) | |
622 (cond (tar-subfile-mode | |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
623 (make-local-variable 'local-write-file-hooks) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
624 (setq local-write-file-hooks '(tar-subfile-save-buffer)) |
212 | 625 ;; turn off auto-save. |
626 (auto-save-mode nil) | |
627 (setq buffer-auto-save-file-name nil) | |
628 (run-hooks 'tar-subfile-mode-hook)) | |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
629 (t |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
630 (kill-local-variable 'local-write-file-hooks)))) |
212 | 631 |
632 | |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
633 ;; Revert the buffer and recompute the dired-like listing. |
212 | 634 (defun tar-mode-revert (&optional no-autosave no-confirm) |
15424
85a85480fa3c
(tar-mode-revert): Cope if user cancels the revert.
Richard M. Stallman <rms@gnu.org>
parents:
14769
diff
changeset
|
635 (let ((revert-buffer-function nil) |
85a85480fa3c
(tar-mode-revert): Cope if user cancels the revert.
Richard M. Stallman <rms@gnu.org>
parents:
14769
diff
changeset
|
636 (old-offset tar-header-offset) |
85a85480fa3c
(tar-mode-revert): Cope if user cancels the revert.
Richard M. Stallman <rms@gnu.org>
parents:
14769
diff
changeset
|
637 success) |
85a85480fa3c
(tar-mode-revert): Cope if user cancels the revert.
Richard M. Stallman <rms@gnu.org>
parents:
14769
diff
changeset
|
638 (setq tar-header-offset nil) |
85a85480fa3c
(tar-mode-revert): Cope if user cancels the revert.
Richard M. Stallman <rms@gnu.org>
parents:
14769
diff
changeset
|
639 (unwind-protect |
85a85480fa3c
(tar-mode-revert): Cope if user cancels the revert.
Richard M. Stallman <rms@gnu.org>
parents:
14769
diff
changeset
|
640 (and (revert-buffer t no-confirm) |
85a85480fa3c
(tar-mode-revert): Cope if user cancels the revert.
Richard M. Stallman <rms@gnu.org>
parents:
14769
diff
changeset
|
641 (progn (widen) |
85a85480fa3c
(tar-mode-revert): Cope if user cancels the revert.
Richard M. Stallman <rms@gnu.org>
parents:
14769
diff
changeset
|
642 (setq success t) |
85a85480fa3c
(tar-mode-revert): Cope if user cancels the revert.
Richard M. Stallman <rms@gnu.org>
parents:
14769
diff
changeset
|
643 (tar-mode))) |
85a85480fa3c
(tar-mode-revert): Cope if user cancels the revert.
Richard M. Stallman <rms@gnu.org>
parents:
14769
diff
changeset
|
644 ;; If the revert was canceled, |
85a85480fa3c
(tar-mode-revert): Cope if user cancels the revert.
Richard M. Stallman <rms@gnu.org>
parents:
14769
diff
changeset
|
645 ;; put back the old value of tar-header-offset. |
85a85480fa3c
(tar-mode-revert): Cope if user cancels the revert.
Richard M. Stallman <rms@gnu.org>
parents:
14769
diff
changeset
|
646 (or success |
85a85480fa3c
(tar-mode-revert): Cope if user cancels the revert.
Richard M. Stallman <rms@gnu.org>
parents:
14769
diff
changeset
|
647 (setq tar-header-offset old-offset))))) |
212 | 648 |
649 | |
650 (defun tar-next-line (p) | |
651 (interactive "p") | |
652 (forward-line p) | |
10843
2f2e5033b3bb
(tar-header-block-tokenize): Parse 32-bit modtime
Richard M. Stallman <rms@gnu.org>
parents:
10271
diff
changeset
|
653 (if (eobp) nil (forward-char (if tar-mode-show-date 54 36)))) |
212 | 654 |
655 (defun tar-previous-line (p) | |
656 (interactive "p") | |
657 (tar-next-line (- p))) | |
658 | |
659 (defun tar-current-descriptor (&optional noerror) | |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
660 "Return the tar-descriptor of the current line, or signals an error." |
212 | 661 ;; I wish lines had plists, like in ZMACS... |
662 (or (nth (count-lines (point-min) | |
663 (save-excursion (beginning-of-line) (point))) | |
664 tar-parse-info) | |
665 (if noerror | |
666 nil | |
6611
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
667 (error "This line does not describe a tar-file entry")))) |
212 | 668 |
6611
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
669 (defun tar-get-descriptor () |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
670 (let* ((descriptor (tar-current-descriptor)) |
212 | 671 (tokens (tar-desc-tokens descriptor)) |
672 (size (tar-header-size tokens)) | |
6611
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
673 (link-p (tar-header-link-type tokens))) |
212 | 674 (if link-p |
6611
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
675 (error "This is a %s, not a real file" |
212 | 676 (cond ((eq link-p 5) "directory") |
677 ((eq link-p 20) "tar directory header") | |
678 ((eq link-p 29) "multivolume-continuation") | |
679 ((eq link-p 35) "sparse entry") | |
680 ((eq link-p 38) "volume header") | |
681 (t "link")))) | |
6611
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
682 (if (zerop size) (error "This is a zero-length file")) |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
683 descriptor)) |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
684 |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
685 (defun tar-mouse-extract (event) |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
686 "Extract a file whose tar directory line you click on." |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
687 (interactive "e") |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
688 (save-excursion |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
689 (set-buffer (window-buffer (posn-window (event-end event)))) |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
690 (save-excursion |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
691 (goto-char (posn-point (event-end event))) |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
692 ;; Just make sure this doesn't get an error. |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
693 (tar-get-descriptor))) |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
694 (select-window (posn-window (event-end event))) |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
695 (goto-char (posn-point (event-end event))) |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
696 (tar-extract)) |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
697 |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
698 (defun tar-extract (&optional other-window-p) |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
699 "In Tar mode, extract this entry of the tar file into its own buffer." |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
700 (interactive) |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
701 (let* ((view-p (eq other-window-p 'view)) |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
702 (descriptor (tar-get-descriptor)) |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
703 (tokens (tar-desc-tokens descriptor)) |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
704 (name (tar-header-name tokens)) |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
705 (size (tar-header-size tokens)) |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
706 (start (+ (tar-desc-data-start descriptor) tar-header-offset -1)) |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
707 (end (+ start size))) |
212 | 708 (let* ((tar-buffer (current-buffer)) |
7078
cf120e7b7d2c
(tar-extract): Don't put whole file name in buffer name.
Richard M. Stallman <rms@gnu.org>
parents:
6641
diff
changeset
|
709 (tarname (file-name-nondirectory (buffer-file-name))) |
212 | 710 (bufname (concat (file-name-nondirectory name) |
7078
cf120e7b7d2c
(tar-extract): Don't put whole file name in buffer name.
Richard M. Stallman <rms@gnu.org>
parents:
6641
diff
changeset
|
711 " (" |
cf120e7b7d2c
(tar-extract): Don't put whole file name in buffer name.
Richard M. Stallman <rms@gnu.org>
parents:
6641
diff
changeset
|
712 tarname |
212 | 713 ")")) |
714 (read-only-p (or buffer-read-only view-p)) | |
715 (buffer (get-buffer bufname)) | |
716 (just-created nil)) | |
717 (if buffer | |
718 nil | |
719 (setq buffer (get-buffer-create bufname)) | |
720 (setq just-created t) | |
721 (unwind-protect | |
722 (progn | |
723 (widen) | |
724 (save-excursion | |
725 (set-buffer buffer) | |
726 (insert-buffer-substring tar-buffer start end) | |
727 (goto-char 0) | |
8023
f29df49c6e53
(tar-extract): Set file name by hand before calling
Richard M. Stallman <rms@gnu.org>
parents:
7497
diff
changeset
|
728 (setq buffer-file-name |
f29df49c6e53
(tar-extract): Set file name by hand before calling
Richard M. Stallman <rms@gnu.org>
parents:
7497
diff
changeset
|
729 (expand-file-name (concat tarname ":" name))) |
10188
f837d768d569
(tar-extract): Don't use set-visited-file-name. to
Richard M. Stallman <rms@gnu.org>
parents:
9817
diff
changeset
|
730 (setq buffer-file-truename |
f837d768d569
(tar-extract): Don't use set-visited-file-name. to
Richard M. Stallman <rms@gnu.org>
parents:
9817
diff
changeset
|
731 (abbreviate-file-name buffer-file-name)) |
f837d768d569
(tar-extract): Don't use set-visited-file-name. to
Richard M. Stallman <rms@gnu.org>
parents:
9817
diff
changeset
|
732 ;; Set the default-directory to the dir of the |
f837d768d569
(tar-extract): Don't use set-visited-file-name. to
Richard M. Stallman <rms@gnu.org>
parents:
9817
diff
changeset
|
733 ;; superior buffer. |
f837d768d569
(tar-extract): Don't use set-visited-file-name. to
Richard M. Stallman <rms@gnu.org>
parents:
9817
diff
changeset
|
734 (setq default-directory |
f837d768d569
(tar-extract): Don't use set-visited-file-name. to
Richard M. Stallman <rms@gnu.org>
parents:
9817
diff
changeset
|
735 (save-excursion |
f837d768d569
(tar-extract): Don't use set-visited-file-name. to
Richard M. Stallman <rms@gnu.org>
parents:
9817
diff
changeset
|
736 (set-buffer tar-buffer) |
f837d768d569
(tar-extract): Don't use set-visited-file-name. to
Richard M. Stallman <rms@gnu.org>
parents:
9817
diff
changeset
|
737 default-directory)) |
212 | 738 (normal-mode) ; pick a mode. |
739 (rename-buffer bufname) | |
2542
ae4176e2e8fa
Add defvars to pacify the byte compiler, at RMS's request.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
880
diff
changeset
|
740 (make-local-variable 'tar-superior-buffer) |
ae4176e2e8fa
Add defvars to pacify the byte compiler, at RMS's request.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
880
diff
changeset
|
741 (make-local-variable 'tar-superior-descriptor) |
ae4176e2e8fa
Add defvars to pacify the byte compiler, at RMS's request.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
880
diff
changeset
|
742 (setq tar-superior-buffer tar-buffer) |
ae4176e2e8fa
Add defvars to pacify the byte compiler, at RMS's request.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
880
diff
changeset
|
743 (setq tar-superior-descriptor descriptor) |
14769
acf049402d18
(tar-subfile-mode): Doc fix.
Richard M. Stallman <rms@gnu.org>
parents:
14294
diff
changeset
|
744 (setq buffer-read-only read-only-p) |
acf049402d18
(tar-subfile-mode): Doc fix.
Richard M. Stallman <rms@gnu.org>
parents:
14294
diff
changeset
|
745 (set-buffer-modified-p nil) |
acf049402d18
(tar-subfile-mode): Doc fix.
Richard M. Stallman <rms@gnu.org>
parents:
14294
diff
changeset
|
746 (tar-subfile-mode 1)) |
212 | 747 (set-buffer tar-buffer)) |
748 (narrow-to-region 1 tar-header-offset))) | |
749 (if view-p | |
750 (progn | |
751 (view-buffer buffer) | |
4120
872d8ef4bb62
(tar-extract): Use view-exit-action to kill viewed buf.
Richard M. Stallman <rms@gnu.org>
parents:
3419
diff
changeset
|
752 (and just-created |
11450
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
753 ;; This will be created by view.el |
4120
872d8ef4bb62
(tar-extract): Use view-exit-action to kill viewed buf.
Richard M. Stallman <rms@gnu.org>
parents:
3419
diff
changeset
|
754 (setq view-exit-action 'kill-buffer))) |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
755 (if (eq other-window-p 'display) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
756 (display-buffer buffer) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
757 (if other-window-p |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
758 (switch-to-buffer-other-window buffer) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
759 (switch-to-buffer buffer))))))) |
212 | 760 |
761 | |
762 (defun tar-extract-other-window () | |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
763 "*In Tar mode, find this entry of the tar file in another window." |
212 | 764 (interactive) |
765 (tar-extract t)) | |
766 | |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
767 (defun tar-display-other-window () |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
768 "*In Tar mode, display this entry of the tar file in another window." |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
769 (interactive) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
770 (tar-extract 'display)) |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
771 |
212 | 772 (defun tar-view () |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
773 "*In Tar mode, view the tar file entry on this line." |
212 | 774 (interactive) |
775 (tar-extract 'view)) | |
776 | |
777 | |
778 (defun tar-read-file-name (&optional prompt) | |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
779 "Read a file name with this line's entry as the default." |
212 | 780 (or prompt (setq prompt "Copy to: ")) |
781 (let* ((default-file (expand-file-name | |
782 (tar-header-name (tar-desc-tokens | |
783 (tar-current-descriptor))))) | |
784 (target (expand-file-name | |
785 (read-file-name prompt | |
786 (file-name-directory default-file) | |
787 default-file nil)))) | |
788 (if (or (string= "" (file-name-nondirectory target)) | |
789 (file-directory-p target)) | |
790 (setq target (concat (if (string-match "/$" target) | |
791 (substring target 0 (1- (match-end 0))) | |
792 target) | |
793 "/" | |
794 (file-name-nondirectory default-file)))) | |
795 target)) | |
796 | |
797 | |
798 (defun tar-copy (&optional to-file) | |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
799 "*In Tar mode, extract this entry of the tar file into a file on disk. |
212 | 800 If TO-FILE is not supplied, it is prompted for, defaulting to the name of |
801 the current tar-entry." | |
802 (interactive (list (tar-read-file-name))) | |
6611
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
803 (let* ((descriptor (tar-get-descriptor)) |
212 | 804 (tokens (tar-desc-tokens descriptor)) |
805 (name (tar-header-name tokens)) | |
806 (size (tar-header-size tokens)) | |
807 (start (+ (tar-desc-data-start descriptor) tar-header-offset -1)) | |
12662
07ba0f6e9ada
(tar-copy): Inhibit use of jka-compr handler
Richard M. Stallman <rms@gnu.org>
parents:
12027
diff
changeset
|
808 (end (+ start size)) |
07ba0f6e9ada
(tar-copy): Inhibit use of jka-compr handler
Richard M. Stallman <rms@gnu.org>
parents:
12027
diff
changeset
|
809 (inhibit-file-name-handlers inhibit-file-name-handlers) |
07ba0f6e9ada
(tar-copy): Inhibit use of jka-compr handler
Richard M. Stallman <rms@gnu.org>
parents:
12027
diff
changeset
|
810 (inhibit-file-name-operation inhibit-file-name-operation)) |
7090
cf0b24d47cdd
(tar-copy): Don't bother with a temp buffer.
Karl Heuer <kwzh@gnu.org>
parents:
7078
diff
changeset
|
811 (save-restriction |
cf0b24d47cdd
(tar-copy): Don't bother with a temp buffer.
Karl Heuer <kwzh@gnu.org>
parents:
7078
diff
changeset
|
812 (widen) |
12662
07ba0f6e9ada
(tar-copy): Inhibit use of jka-compr handler
Richard M. Stallman <rms@gnu.org>
parents:
12027
diff
changeset
|
813 ;; Inhibit compressing a subfile again if *both* name and |
07ba0f6e9ada
(tar-copy): Inhibit use of jka-compr handler
Richard M. Stallman <rms@gnu.org>
parents:
12027
diff
changeset
|
814 ;; to-file are handled by jka-compr |
07ba0f6e9ada
(tar-copy): Inhibit use of jka-compr handler
Richard M. Stallman <rms@gnu.org>
parents:
12027
diff
changeset
|
815 (if (and (eq (find-file-name-handler name 'write-region) 'jka-compr-handler) |
07ba0f6e9ada
(tar-copy): Inhibit use of jka-compr handler
Richard M. Stallman <rms@gnu.org>
parents:
12027
diff
changeset
|
816 (eq (find-file-name-handler to-file 'write-region) 'jka-compr-handler)) |
07ba0f6e9ada
(tar-copy): Inhibit use of jka-compr handler
Richard M. Stallman <rms@gnu.org>
parents:
12027
diff
changeset
|
817 (setq inhibit-file-name-handlers |
07ba0f6e9ada
(tar-copy): Inhibit use of jka-compr handler
Richard M. Stallman <rms@gnu.org>
parents:
12027
diff
changeset
|
818 (cons 'jka-compr-handler |
07ba0f6e9ada
(tar-copy): Inhibit use of jka-compr handler
Richard M. Stallman <rms@gnu.org>
parents:
12027
diff
changeset
|
819 (and (eq inhibit-file-name-operation 'write-region) |
07ba0f6e9ada
(tar-copy): Inhibit use of jka-compr handler
Richard M. Stallman <rms@gnu.org>
parents:
12027
diff
changeset
|
820 inhibit-file-name-handlers)) |
07ba0f6e9ada
(tar-copy): Inhibit use of jka-compr handler
Richard M. Stallman <rms@gnu.org>
parents:
12027
diff
changeset
|
821 inhibit-file-name-operation 'write-region)) |
7090
cf0b24d47cdd
(tar-copy): Don't bother with a temp buffer.
Karl Heuer <kwzh@gnu.org>
parents:
7078
diff
changeset
|
822 (write-region start end to-file)) |
cf0b24d47cdd
(tar-copy): Don't bother with a temp buffer.
Karl Heuer <kwzh@gnu.org>
parents:
7078
diff
changeset
|
823 (message "Copied tar entry %s to %s" name to-file))) |
212 | 824 |
825 (defun tar-flag-deleted (p &optional unflag) | |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
826 "*In Tar mode, mark this sub-file to be deleted from the tar file. |
212 | 827 With a prefix argument, mark that many files." |
828 (interactive "p") | |
829 (beginning-of-line) | |
830 (tar-dotimes (i (if (< p 0) (- p) p)) | |
831 (if (tar-current-descriptor unflag) ; barf if we're not on an entry-line. | |
832 (progn | |
833 (delete-char 1) | |
834 (insert (if unflag " " "D")))) | |
835 (forward-line (if (< p 0) -1 1))) | |
836 (if (eobp) nil (forward-char 36))) | |
837 | |
838 (defun tar-unflag (p) | |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
839 "*In Tar mode, un-mark this sub-file if it is marked to be deleted. |
212 | 840 With a prefix argument, un-mark that many files forward." |
841 (interactive "p") | |
842 (tar-flag-deleted p t)) | |
843 | |
844 (defun tar-unflag-backwards (p) | |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
845 "*In Tar mode, un-mark this sub-file if it is marked to be deleted. |
212 | 846 With a prefix argument, un-mark that many files backward." |
847 (interactive "p") | |
848 (tar-flag-deleted (- p) t)) | |
849 | |
850 | |
851 (defun tar-expunge-internal () | |
852 "Expunge the tar-entry specified by the current line." | |
853 (let* ((descriptor (tar-current-descriptor)) | |
854 (tokens (tar-desc-tokens descriptor)) | |
855 (line (tar-desc-data-start descriptor)) | |
856 (name (tar-header-name tokens)) | |
857 (size (tar-header-size tokens)) | |
858 (link-p (tar-header-link-type tokens)) | |
859 (start (tar-desc-data-start descriptor)) | |
860 (following-descs (cdr (memq descriptor tar-parse-info)))) | |
861 (if link-p (setq size 0)) ; size lies for hard-links. | |
862 ;; | |
863 ;; delete the current line... | |
864 (beginning-of-line) | |
865 (let ((line-start (point))) | |
866 (end-of-line) (forward-char) | |
867 (let ((line-len (- (point) line-start))) | |
868 (delete-region line-start (point)) | |
869 ;; | |
14040 | 870 ;; decrement the header-pointer to be in sync... |
212 | 871 (setq tar-header-offset (- tar-header-offset line-len)))) |
872 ;; | |
873 ;; delete the data pointer... | |
874 (setq tar-parse-info (delq descriptor tar-parse-info)) | |
875 ;; | |
876 ;; delete the data from inside the file... | |
877 (widen) | |
878 (let* ((data-start (+ start tar-header-offset -513)) | |
879 (data-end (+ data-start 512 (ash (ash (+ size 511) -9) 9)))) | |
880 (delete-region data-start data-end) | |
881 ;; | |
882 ;; and finally, decrement the start-pointers of all following | |
883 ;; entries in the archive. This is a pig when deleting a bunch | |
884 ;; of files at once - we could optimize this to only do the | |
885 ;; iteration over the files that remain, or only iterate up to | |
886 ;; the next file to be deleted. | |
887 (let ((data-length (- data-end data-start))) | |
888 (tar-dolist (desc following-descs) | |
889 (tar-setf (tar-desc-data-start desc) | |
890 (- (tar-desc-data-start desc) data-length)))) | |
891 )) | |
892 (narrow-to-region 1 tar-header-offset)) | |
893 | |
894 | |
895 (defun tar-expunge (&optional noconfirm) | |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
896 "*In Tar mode, delete all the archived files flagged for deletion. |
212 | 897 This does not modify the disk image; you must save the tar file itself |
898 for this to be permanent." | |
899 (interactive) | |
900 (if (or noconfirm | |
11450
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
901 (y-or-n-p "Expunge files marked for deletion? ")) |
212 | 902 (let ((n 0)) |
903 (save-excursion | |
904 (goto-char 0) | |
905 (while (not (eobp)) | |
906 (if (looking-at "D") | |
907 (progn (tar-expunge-internal) | |
908 (setq n (1+ n))) | |
909 (forward-line 1))) | |
910 ;; after doing the deletions, add any padding that may be necessary. | |
911 (tar-pad-to-blocksize) | |
912 (narrow-to-region 1 tar-header-offset) | |
913 ) | |
914 (if (zerop n) | |
11450
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
915 (message "Nothing to expunge.") |
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
916 (message "%s files expunged. Be sure to save this buffer." n))))) |
212 | 917 |
918 | |
919 (defun tar-clear-modification-flags () | |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
920 "Remove the stars at the beginning of each line." |
11301
1234d00b8492
(tar-clear-modification-flags): Fix several bugs.
Richard M. Stallman <rms@gnu.org>
parents:
11210
diff
changeset
|
921 (interactive) |
212 | 922 (save-excursion |
11301
1234d00b8492
(tar-clear-modification-flags): Fix several bugs.
Richard M. Stallman <rms@gnu.org>
parents:
11210
diff
changeset
|
923 (goto-char 1) |
212 | 924 (while (< (point) tar-header-offset) |
11301
1234d00b8492
(tar-clear-modification-flags): Fix several bugs.
Richard M. Stallman <rms@gnu.org>
parents:
11210
diff
changeset
|
925 (if (not (eq (following-char) ?\ )) |
212 | 926 (progn (delete-char 1) (insert " "))) |
927 (forward-line 1)))) | |
928 | |
929 | |
930 (defun tar-chown-entry (new-uid) | |
931 "*Change the user-id associated with this entry in the tar file. | |
932 If this tar file was written by GNU tar, then you will be able to edit | |
933 the user id as a string; otherwise, you must edit it as a number. | |
934 You can force editing as a number by calling this with a prefix arg. | |
935 This does not modify the disk image; you must save the tar file itself | |
936 for this to be permanent." | |
937 (interactive (list | |
938 (let ((tokens (tar-desc-tokens (tar-current-descriptor)))) | |
939 (if (or current-prefix-arg | |
940 (not (tar-header-magic tokens))) | |
941 (let (n) | |
942 (while (not (numberp (setq n (read-minibuffer | |
943 "New UID number: " | |
944 (format "%s" (tar-header-uid tokens))))))) | |
945 n) | |
946 (read-string "New UID string: " (tar-header-uname tokens)))))) | |
947 (cond ((stringp new-uid) | |
948 (tar-setf (tar-header-uname (tar-desc-tokens (tar-current-descriptor))) | |
949 new-uid) | |
950 (tar-alter-one-field tar-uname-offset (concat new-uid "\000"))) | |
951 (t | |
952 (tar-setf (tar-header-uid (tar-desc-tokens (tar-current-descriptor))) | |
953 new-uid) | |
954 (tar-alter-one-field tar-uid-offset | |
955 (concat (substring (format "%6o" new-uid) 0 6) "\000 "))))) | |
956 | |
957 | |
958 (defun tar-chgrp-entry (new-gid) | |
959 "*Change the group-id associated with this entry in the tar file. | |
960 If this tar file was written by GNU tar, then you will be able to edit | |
961 the group id as a string; otherwise, you must edit it as a number. | |
962 You can force editing as a number by calling this with a prefix arg. | |
963 This does not modify the disk image; you must save the tar file itself | |
964 for this to be permanent." | |
965 (interactive (list | |
966 (let ((tokens (tar-desc-tokens (tar-current-descriptor)))) | |
967 (if (or current-prefix-arg | |
968 (not (tar-header-magic tokens))) | |
969 (let (n) | |
970 (while (not (numberp (setq n (read-minibuffer | |
971 "New GID number: " | |
972 (format "%s" (tar-header-gid tokens))))))) | |
973 n) | |
974 (read-string "New GID string: " (tar-header-gname tokens)))))) | |
975 (cond ((stringp new-gid) | |
976 (tar-setf (tar-header-gname (tar-desc-tokens (tar-current-descriptor))) | |
977 new-gid) | |
978 (tar-alter-one-field tar-gname-offset | |
979 (concat new-gid "\000"))) | |
980 (t | |
981 (tar-setf (tar-header-gid (tar-desc-tokens (tar-current-descriptor))) | |
982 new-gid) | |
983 (tar-alter-one-field tar-gid-offset | |
984 (concat (substring (format "%6o" new-gid) 0 6) "\000 "))))) | |
985 | |
986 (defun tar-rename-entry (new-name) | |
987 "*Change the name associated with this entry in the tar file. | |
988 This does not modify the disk image; you must save the tar file itself | |
989 for this to be permanent." | |
990 (interactive | |
991 (list (read-string "New name: " | |
992 (tar-header-name (tar-desc-tokens (tar-current-descriptor)))))) | |
6611
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
993 (if (string= "" new-name) (error "zero length name")) |
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
994 (if (> (length new-name) 98) (error "name too long")) |
212 | 995 (tar-setf (tar-header-name (tar-desc-tokens (tar-current-descriptor))) |
996 new-name) | |
997 (tar-alter-one-field 0 | |
998 (substring (concat new-name (make-string 99 0)) 0 99))) | |
999 | |
1000 | |
1001 (defun tar-chmod-entry (new-mode) | |
1002 "*Change the protection bits associated with this entry in the tar file. | |
1003 This does not modify the disk image; you must save the tar file itself | |
1004 for this to be permanent." | |
1005 (interactive (list (tar-parse-octal-integer-safe | |
1006 (read-string "New protection (octal): ")))) | |
1007 (tar-setf (tar-header-mode (tar-desc-tokens (tar-current-descriptor))) | |
1008 new-mode) | |
1009 (tar-alter-one-field tar-mode-offset | |
1010 (concat (substring (format "%6o" new-mode) 0 6) "\000 "))) | |
1011 | |
1012 | |
1013 (defun tar-alter-one-field (data-position new-data-string) | |
1014 (let* ((descriptor (tar-current-descriptor)) | |
1015 (tokens (tar-desc-tokens descriptor))) | |
1016 (unwind-protect | |
1017 (save-excursion | |
1018 ;; | |
1019 ;; update the header-line. | |
1020 (beginning-of-line) | |
1021 (let ((p (point))) | |
1022 (forward-line 1) | |
1023 (delete-region p (point)) | |
8023
f29df49c6e53
(tar-extract): Set file name by hand before calling
Richard M. Stallman <rms@gnu.org>
parents:
7497
diff
changeset
|
1024 (insert (tar-header-block-summarize tokens) "\n") |
212 | 1025 (setq tar-header-offset (point-max))) |
1026 | |
1027 (widen) | |
1028 (let* ((start (+ (tar-desc-data-start descriptor) tar-header-offset -513))) | |
1029 ;; | |
1030 ;; delete the old field and insert a new one. | |
1031 (goto-char (+ start data-position)) | |
1032 (delete-region (point) (+ (point) (length new-data-string))) ; <-- | |
1033 (insert new-data-string) ; <-- | |
1034 ;; | |
1035 ;; compute a new checksum and insert it. | |
8023
f29df49c6e53
(tar-extract): Set file name by hand before calling
Richard M. Stallman <rms@gnu.org>
parents:
7497
diff
changeset
|
1036 (let ((chk (tar-header-block-checksum |
212 | 1037 (buffer-substring start (+ start 512))))) |
1038 (goto-char (+ start tar-chk-offset)) | |
1039 (delete-region (point) (+ (point) 8)) | |
1040 (insert (format "%6o" chk)) | |
1041 (insert 0) | |
1042 (insert ? ) | |
1043 (tar-setf (tar-header-checksum tokens) chk) | |
1044 ;; | |
1045 ;; ok, make sure we didn't botch it. | |
8043
93beabc37a44
(tar-alter-one-field): Finish previous renaming change.
Richard M. Stallman <rms@gnu.org>
parents:
8023
diff
changeset
|
1046 (tar-header-block-check-checksum |
212 | 1047 (buffer-substring start (+ start 512)) |
1048 chk (tar-header-name tokens)) | |
1049 ))) | |
1050 (narrow-to-region 1 tar-header-offset)))) | |
1051 | |
1052 | |
880 | 1053 (defun tar-octal-time (timeval) |
1054 ;; Format a timestamp as 11 octal digits. Ghod, I hope this works... | |
1055 (let ((hibits (car timeval)) (lobits (car (cdr timeval)))) | |
1056 (insert (format "%05o%01o%05o" | |
1057 (lsh hibits -2) | |
1058 (logior (lsh (logand 3 hibits) 1) (> (logand lobits 32768) 0)) | |
1059 (logand 32767 lobits) | |
1060 )))) | |
1061 | |
212 | 1062 (defun tar-subfile-save-buffer () |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
1063 "In tar subfile mode, save this buffer into its parent tar-file buffer. |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
1064 This doesn't write anything to disk; you must save the parent tar-file buffer |
212 | 1065 to make your changes permanent." |
1066 (interactive) | |
2542
ae4176e2e8fa
Add defvars to pacify the byte compiler, at RMS's request.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
880
diff
changeset
|
1067 (if (not (and (boundp 'tar-superior-buffer) tar-superior-buffer)) |
6611
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
1068 (error "This buffer has no superior tar file buffer")) |
2542
ae4176e2e8fa
Add defvars to pacify the byte compiler, at RMS's request.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
880
diff
changeset
|
1069 (if (not (and (boundp 'tar-superior-descriptor) tar-superior-descriptor)) |
6611
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
1070 (error "This buffer doesn't have an index into its superior tar file!")) |
212 | 1071 (save-excursion |
1072 (let ((subfile (current-buffer)) | |
1073 (subfile-size (buffer-size)) | |
2542
ae4176e2e8fa
Add defvars to pacify the byte compiler, at RMS's request.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
880
diff
changeset
|
1074 (descriptor tar-superior-descriptor)) |
ae4176e2e8fa
Add defvars to pacify the byte compiler, at RMS's request.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
880
diff
changeset
|
1075 (set-buffer tar-superior-buffer) |
212 | 1076 (let* ((tokens (tar-desc-tokens descriptor)) |
1077 (start (tar-desc-data-start descriptor)) | |
1078 (name (tar-header-name tokens)) | |
1079 (size (tar-header-size tokens)) | |
1080 (size-pad (ash (ash (+ size 511) -9) 9)) | |
1081 (head (memq descriptor tar-parse-info)) | |
1082 (following-descs (cdr head))) | |
1083 (if (not head) | |
1084 (error "Can't find this tar file entry in its parent tar file!")) | |
1085 (unwind-protect | |
1086 (save-excursion | |
1087 (widen) | |
1088 ;; delete the old data... | |
1089 (let* ((data-start (+ start tar-header-offset -1)) | |
1090 (data-end (+ data-start (ash (ash (+ size 511) -9) 9)))) | |
1091 (delete-region data-start data-end) | |
1092 ;; insert the new data... | |
1093 (goto-char data-start) | |
1094 (insert-buffer subfile) | |
1095 ;; | |
1096 ;; pad the new data out to a multiple of 512... | |
1097 (let ((subfile-size-pad (ash (ash (+ subfile-size 511) -9) 9))) | |
1098 (goto-char (+ data-start subfile-size)) | |
1099 (insert (make-string (- subfile-size-pad subfile-size) 0)) | |
1100 ;; | |
1101 ;; update the data pointer of this and all following files... | |
1102 (tar-setf (tar-header-size tokens) subfile-size) | |
1103 (let ((difference (- subfile-size-pad size-pad))) | |
1104 (tar-dolist (desc following-descs) | |
1105 (tar-setf (tar-desc-data-start desc) | |
1106 (+ (tar-desc-data-start desc) difference)))) | |
1107 ;; | |
1108 ;; Update the size field in the header block. | |
1109 (let ((header-start (- data-start 512))) | |
1110 (goto-char (+ header-start tar-size-offset)) | |
1111 (delete-region (point) (+ (point) 12)) | |
1112 (insert (format "%11o" subfile-size)) | |
1113 (insert ? ) | |
1114 ;; | |
1115 ;; Maybe update the datestamp. | |
1116 (if (not tar-update-datestamp) | |
1117 nil | |
1118 (goto-char (+ header-start tar-time-offset)) | |
1119 (delete-region (point) (+ (point) 12)) | |
880 | 1120 (insert (tar-octal-time (current-time))) |
212 | 1121 (insert ? )) |
1122 ;; | |
1123 ;; compute a new checksum and insert it. | |
8023
f29df49c6e53
(tar-extract): Set file name by hand before calling
Richard M. Stallman <rms@gnu.org>
parents:
7497
diff
changeset
|
1124 (let ((chk (tar-header-block-checksum |
212 | 1125 (buffer-substring header-start data-start)))) |
1126 (goto-char (+ header-start tar-chk-offset)) | |
1127 (delete-region (point) (+ (point) 8)) | |
1128 (insert (format "%6o" chk)) | |
1129 (insert 0) | |
1130 (insert ? ) | |
1131 (tar-setf (tar-header-checksum tokens) chk))) | |
1132 ;; | |
1133 ;; alter the descriptor-line... | |
1134 ;; | |
1135 (let ((position (- (length tar-parse-info) (length head)))) | |
1136 (goto-char 1) | |
1137 (next-line position) | |
1138 (beginning-of-line) | |
1139 (let ((p (point)) | |
7497
2308d6e6404c
(tar-extract): Put tar name into subfile visited name.
Richard M. Stallman <rms@gnu.org>
parents:
7464
diff
changeset
|
1140 after |
212 | 1141 (m (set-marker (make-marker) tar-header-offset))) |
1142 (forward-line 1) | |
7497
2308d6e6404c
(tar-extract): Put tar name into subfile visited name.
Richard M. Stallman <rms@gnu.org>
parents:
7464
diff
changeset
|
1143 (setq after (point)) |
2308d6e6404c
(tar-extract): Put tar name into subfile visited name.
Richard M. Stallman <rms@gnu.org>
parents:
7464
diff
changeset
|
1144 ;; Insert the new text after the old, before deleting, |
2308d6e6404c
(tar-extract): Put tar name into subfile visited name.
Richard M. Stallman <rms@gnu.org>
parents:
7464
diff
changeset
|
1145 ;; to preserve the window start. |
8023
f29df49c6e53
(tar-extract): Set file name by hand before calling
Richard M. Stallman <rms@gnu.org>
parents:
7497
diff
changeset
|
1146 (insert-before-markers (tar-header-block-summarize tokens t) "\n") |
7497
2308d6e6404c
(tar-extract): Put tar name into subfile visited name.
Richard M. Stallman <rms@gnu.org>
parents:
7464
diff
changeset
|
1147 (delete-region p after) |
212 | 1148 (setq tar-header-offset (marker-position m))) |
1149 ))) | |
1150 ;; after doing the insertion, add any final padding that may be necessary. | |
1151 (tar-pad-to-blocksize)) | |
1152 (narrow-to-region 1 tar-header-offset))) | |
1153 (set-buffer-modified-p t) ; mark the tar file as modified | |
1154 (set-buffer subfile) | |
1155 (set-buffer-modified-p nil) ; mark the tar subfile as unmodified | |
11450
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
1156 (message "Saved into tar-buffer `%s'. Be sure to save that buffer!" |
2542
ae4176e2e8fa
Add defvars to pacify the byte compiler, at RMS's request.
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
880
diff
changeset
|
1157 (buffer-name tar-superior-buffer)) |
4387
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
1158 ;; Prevent ordinary saving from happening. |
3e18f6a1915b
Fix doc strings and error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
4260
diff
changeset
|
1159 t))) |
212 | 1160 |
1161 | |
1162 (defun tar-pad-to-blocksize () | |
1163 "If we are being anal about tar file blocksizes, fix up the current buffer. | |
1164 Leaves the region wide." | |
1165 (if (null tar-anal-blocksize) | |
1166 nil | |
1167 (widen) | |
1168 (let* ((last-desc (nth (1- (length tar-parse-info)) tar-parse-info)) | |
1169 (start (tar-desc-data-start last-desc)) | |
1170 (tokens (tar-desc-tokens last-desc)) | |
1171 (link-p (tar-header-link-type tokens)) | |
1172 (size (if link-p 0 (tar-header-size tokens))) | |
1173 (data-end (+ start size)) | |
1174 (bbytes (ash tar-anal-blocksize 9)) | |
1175 (pad-to (+ bbytes (* bbytes (/ (1- data-end) bbytes)))) | |
5821
4212fd8028bb
(tar-pad-to-blocksize): Bind inhibit-read-only, not buffer-read-only.
Richard M. Stallman <rms@gnu.org>
parents:
4586
diff
changeset
|
1176 (inhibit-read-only t) ; ## |
212 | 1177 ) |
1178 ;; If the padding after the last data is too long, delete some; | |
1179 ;; else insert some until we are padded out to the right number of blocks. | |
1180 ;; | |
1181 (goto-char (+ (or tar-header-offset 0) data-end)) | |
1182 (if (> (1+ (buffer-size)) (+ (or tar-header-offset 0) pad-to)) | |
1183 (delete-region (+ (or tar-header-offset 0) pad-to) (1+ (buffer-size))) | |
1184 (insert (make-string (- (+ (or tar-header-offset 0) pad-to) | |
1185 (1+ (buffer-size))) | |
1186 0))) | |
1187 ))) | |
1188 | |
1189 | |
6611
a5f180172ff3
Fix error message syntax.
Richard M. Stallman <rms@gnu.org>
parents:
5821
diff
changeset
|
1190 ;; Used in write-file-hook to write tar-files out correctly. |
11450
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
1191 (defun tar-mode-write-file () |
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
1192 (unwind-protect |
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
1193 (save-excursion |
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
1194 (widen) |
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
1195 ;; Doing this here confuses things - the region gets left too wide! |
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
1196 ;; I suppose this is run in a context where changing the buffer is bad. |
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
1197 ;; (tar-pad-to-blocksize) |
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
1198 (write-region tar-header-offset (point-max) buffer-file-name nil t) |
15947
849a396187cd
(tar-mode-write-file): Clear buffer's own modified flag
Richard M. Stallman <rms@gnu.org>
parents:
15612
diff
changeset
|
1199 (tar-clear-modification-flags) |
849a396187cd
(tar-mode-write-file): Clear buffer's own modified flag
Richard M. Stallman <rms@gnu.org>
parents:
15612
diff
changeset
|
1200 (set-buffer-modified-p nil)) |
11450
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
1201 (narrow-to-region 1 tar-header-offset)) |
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
1202 ;; return T because we've written the file. |
aee30032f324
(tar-mode): Locally bind next-line-add-newlines to nil.
Richard M. Stallman <rms@gnu.org>
parents:
11431
diff
changeset
|
1203 t) |
212 | 1204 |
1205 (provide 'tar-mode) | |
1206 | |
658
7cbd4fcd8b0f
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
584
diff
changeset
|
1207 ;;; tar-mode.el ends here |