comparison lisp/tar-mode.el @ 8023:f29df49c6e53

(tar-extract): Set file name by hand before calling set-visited-file-name. Various renamings; all callers changed. (tar-header-block-tokenize): Renamed from tokenize-tar-header-block. (tar-header-block-checksum): Renamed from checksum-tar-header-block. (tar-header-block-check-checksum): Renamed from check-tar-header-block-checksum. (tar-header-block-recompute-checksum): Renamed from recompute-tar-header-block-checksum. (tar-header-block-summarize): Renamed from summarize-tar-header-block.
author Richard M. Stallman <rms@gnu.org>
date Thu, 23 Jun 1994 17:52:44 +0000
parents 2308d6e6404c
children 93beabc37a44
comparison
equal deleted inserted replaced
8022:fcf805b27bc5 8023:f29df49c6e53
214 (defconst tar-gname-offset (+ tar-uname-offset 32)) 214 (defconst tar-gname-offset (+ tar-uname-offset 32))
215 (defconst tar-dmaj-offset (+ tar-gname-offset 32)) 215 (defconst tar-dmaj-offset (+ tar-gname-offset 32))
216 (defconst tar-dmin-offset (+ tar-dmaj-offset 8)) 216 (defconst tar-dmin-offset (+ tar-dmaj-offset 8))
217 (defconst tar-end-offset (+ tar-dmin-offset 8)) 217 (defconst tar-end-offset (+ tar-dmin-offset 8))
218 218
219 (defun tokenize-tar-header-block (string) 219 (defun tar-header-block-tokenize (string)
220 "Return a `tar-header' structure. 220 "Return a `tar-header' structure.
221 This is a list of name, mode, uid, gid, size, 221 This is a list of name, mode, uid, gid, size,
222 write-date, checksum, link-type, and link-name." 222 write-date, checksum, link-type, and link-name."
223 (cond ((< (length string) 512) nil) 223 (cond ((< (length string) 512) nil)
224 (;(some 'plusp string) ; <-- oops, massive cycle hog! 224 (;(some 'plusp string) ; <-- oops, massive cycle hog!
281 (> (aref string i) ?7)) 281 (> (aref string i) ?7))
282 (error "'%c' is not an octal digit")))) 282 (error "'%c' is not an octal digit"))))
283 (tar-parse-octal-integer string)) 283 (tar-parse-octal-integer string))
284 284
285 285
286 (defun checksum-tar-header-block (string) 286 (defun tar-header-block-checksum (string)
287 "Compute and return a tar-acceptable checksum for this block." 287 "Compute and return a tar-acceptable checksum for this block."
288 (let* ((chk-field-start tar-chk-offset) 288 (let* ((chk-field-start tar-chk-offset)
289 (chk-field-end (+ chk-field-start 8)) 289 (chk-field-end (+ chk-field-start 8))
290 (sum 0) 290 (sum 0)
291 (i 0)) 291 (i 0))
298 (while (< i 512) 298 (while (< i 512)
299 (setq sum (+ sum (aref string i)) 299 (setq sum (+ sum (aref string i))
300 i (1+ i))) 300 i (1+ i)))
301 (+ sum (* 32 8)))) 301 (+ sum (* 32 8))))
302 302
303 (defun check-tar-header-block-checksum (hblock desired-checksum file-name) 303 (defun tar-header-block-check-checksum (hblock desired-checksum file-name)
304 "Beep and print a warning if the checksum doesn't match." 304 "Beep and print a warning if the checksum doesn't match."
305 (if (not (= desired-checksum (checksum-tar-header-block hblock))) 305 (if (not (= desired-checksum (tar-header-block-checksum hblock)))
306 (progn (beep) (message "Invalid checksum for file %s!" file-name)))) 306 (progn (beep) (message "Invalid checksum for file %s!" file-name))))
307 307
308 (defun recompute-tar-header-block-checksum (hblock) 308 (defun tar-header-block-recompute-checksum (hblock)
309 "Modifies the given string to have a valid checksum field." 309 "Modifies the given string to have a valid checksum field."
310 (let* ((chk (checksum-tar-header-block hblock)) 310 (let* ((chk (tar-header-block-checksum hblock))
311 (chk-string (format "%6o" chk)) 311 (chk-string (format "%6o" chk))
312 (l (length chk-string))) 312 (l (length chk-string)))
313 (aset hblock 154 0) 313 (aset hblock 154 0)
314 (aset hblock 155 32) 314 (aset hblock 155 32)
315 (tar-dotimes (i l) (aset hblock (- 153 i) (aref chk-string (- l i 1))))) 315 (tar-dotimes (i l) (aset hblock (- 153 i) (aref chk-string (- l i 1)))))
329 (aset string (+ start 8) (if (zerop (logand 1 mode)) ?- ?x)) 329 (aset string (+ start 8) (if (zerop (logand 1 mode)) ?- ?x))
330 (if (zerop (logand 1024 mode)) nil (aset string (+ start 2) ?s)) 330 (if (zerop (logand 1024 mode)) nil (aset string (+ start 2) ?s))
331 (if (zerop (logand 2048 mode)) nil (aset string (+ start 5) ?s)) 331 (if (zerop (logand 2048 mode)) nil (aset string (+ start 5) ?s))
332 string) 332 string)
333 333
334 (defun summarize-tar-header-block (tar-hblock &optional mod-p) 334 (defun tar-header-block-summarize (tar-hblock &optional mod-p)
335 "Returns a line similar to the output of `tar -vtf'." 335 "Returns a line similar to the output of `tar -vtf'."
336 (let ((name (tar-header-name tar-hblock)) 336 (let ((name (tar-header-name tar-hblock))
337 (mode (tar-header-mode tar-hblock)) 337 (mode (tar-header-mode tar-hblock))
338 (uid (tar-header-uid tar-hblock)) 338 (uid (tar-header-uid tar-hblock))
339 (gid (tar-header-gid tar-hblock)) 339 (gid (tar-header-gid tar-hblock))
399 (bs (max 1 (- (buffer-size) 1024))) ; always 2+ empty blocks at end. 399 (bs (max 1 (- (buffer-size) 1024))) ; always 2+ empty blocks at end.
400 (bs100 (max 1 (/ bs 100))) 400 (bs100 (max 1 (/ bs 100)))
401 (tokens nil)) 401 (tokens nil))
402 (while (not (eq tokens 'empty-tar-block)) 402 (while (not (eq tokens 'empty-tar-block))
403 (let* ((hblock (buffer-substring pos (+ pos 512)))) 403 (let* ((hblock (buffer-substring pos (+ pos 512))))
404 (setq tokens (tokenize-tar-header-block hblock)) 404 (setq tokens (tar-header-block-tokenize hblock))
405 (setq pos (+ pos 512)) 405 (setq pos (+ pos 512))
406 (message "parsing tar file...%s%%" 406 (message "parsing tar file...%s%%"
407 ;(/ (* pos 100) bs) ; this gets round-off lossage 407 ;(/ (* pos 100) bs) ; this gets round-off lossage
408 (/ pos bs100) ; this doesn't 408 (/ pos bs100) ; this doesn't
409 ) 409 )
417 (if (< size 0) 417 (if (< size 0)
418 (error "%s has size %s - corrupted" 418 (error "%s has size %s - corrupted"
419 (tar-header-name tokens) size)) 419 (tar-header-name tokens) size))
420 ; 420 ;
421 ; This is just too slow. Don't really need it anyway.... 421 ; This is just too slow. Don't really need it anyway....
422 ;(check-tar-header-block-checksum 422 ;(tar-header-block-check-checksum
423 ; hblock (checksum-tar-header-block hblock) 423 ; hblock (tar-header-block-checksum hblock)
424 ; (tar-header-name tokens)) 424 ; (tar-header-name tokens))
425 425
426 (setq result (cons (make-tar-desc pos tokens) result)) 426 (setq result (cons (make-tar-desc pos tokens) result))
427 427
428 (if (and (null (tar-header-link-type tokens)) 428 (if (and (null (tar-header-link-type tokens))
437 (save-excursion 437 (save-excursion
438 (goto-char (point-min)) 438 (goto-char (point-min))
439 (let ((buffer-read-only nil)) 439 (let ((buffer-read-only nil))
440 (tar-dolist (tar-desc tar-parse-info) 440 (tar-dolist (tar-desc tar-parse-info)
441 (insert-string 441 (insert-string
442 (summarize-tar-header-block (tar-desc-tokens tar-desc))) 442 (tar-header-block-summarize (tar-desc-tokens tar-desc)))
443 (insert-string "\n")) 443 (insert-string "\n"))
444 (make-local-variable 'tar-header-offset) 444 (make-local-variable 'tar-header-offset)
445 (setq tar-header-offset (point)) 445 (setq tar-header-offset (point))
446 (narrow-to-region 1 tar-header-offset) 446 (narrow-to-region 1 tar-header-offset)
447 (set-buffer-modified-p nil))) 447 (set-buffer-modified-p nil)))
681 (widen) 681 (widen)
682 (save-excursion 682 (save-excursion
683 (set-buffer buffer) 683 (set-buffer buffer)
684 (insert-buffer-substring tar-buffer start end) 684 (insert-buffer-substring tar-buffer start end)
685 (goto-char 0) 685 (goto-char 0)
686 ;; Give it a name for lit-buffers and to decide mode. 686 ;; Give it a name for list-buffers and to decide mode.
687 (set-visited-file-name (concat tarname ":" name)) 687 ;; Set buffer-file-name by hand first
688 ;; so that set-visited-file-name won't lock the filename.
689 (setq buffer-file-name
690 (expand-file-name (concat tarname ":" name)))
691 (set-visited-file-name buffer-file-name)
688 (normal-mode) ; pick a mode. 692 (normal-mode) ; pick a mode.
689 ;;; Without a file name, save-buffer doesn't work. 693 ;;; Without a file name, save-buffer doesn't work.
690 ;;; (set-visited-file-name nil) ; nuke the name - not meaningful. 694 ;;; (set-visited-file-name nil) ; nuke the name - not meaningful.
691 (rename-buffer bufname) 695 (rename-buffer bufname)
692 696
961 ;; update the header-line. 965 ;; update the header-line.
962 (beginning-of-line) 966 (beginning-of-line)
963 (let ((p (point))) 967 (let ((p (point)))
964 (forward-line 1) 968 (forward-line 1)
965 (delete-region p (point)) 969 (delete-region p (point))
966 (insert (summarize-tar-header-block tokens) "\n") 970 (insert (tar-header-block-summarize tokens) "\n")
967 (setq tar-header-offset (point-max))) 971 (setq tar-header-offset (point-max)))
968 972
969 (widen) 973 (widen)
970 (let* ((start (+ (tar-desc-data-start descriptor) tar-header-offset -513))) 974 (let* ((start (+ (tar-desc-data-start descriptor) tar-header-offset -513)))
971 ;; 975 ;;
973 (goto-char (+ start data-position)) 977 (goto-char (+ start data-position))
974 (delete-region (point) (+ (point) (length new-data-string))) ; <-- 978 (delete-region (point) (+ (point) (length new-data-string))) ; <--
975 (insert new-data-string) ; <-- 979 (insert new-data-string) ; <--
976 ;; 980 ;;
977 ;; compute a new checksum and insert it. 981 ;; compute a new checksum and insert it.
978 (let ((chk (checksum-tar-header-block 982 (let ((chk (tar-header-block-checksum
979 (buffer-substring start (+ start 512))))) 983 (buffer-substring start (+ start 512)))))
980 (goto-char (+ start tar-chk-offset)) 984 (goto-char (+ start tar-chk-offset))
981 (delete-region (point) (+ (point) 8)) 985 (delete-region (point) (+ (point) 8))
982 (insert (format "%6o" chk)) 986 (insert (format "%6o" chk))
983 (insert 0) 987 (insert 0)
1061 (delete-region (point) (+ (point) 12)) 1065 (delete-region (point) (+ (point) 12))
1062 (insert (tar-octal-time (current-time))) 1066 (insert (tar-octal-time (current-time)))
1063 (insert ? )) 1067 (insert ? ))
1064 ;; 1068 ;;
1065 ;; compute a new checksum and insert it. 1069 ;; compute a new checksum and insert it.
1066 (let ((chk (checksum-tar-header-block 1070 (let ((chk (tar-header-block-checksum
1067 (buffer-substring header-start data-start)))) 1071 (buffer-substring header-start data-start))))
1068 (goto-char (+ header-start tar-chk-offset)) 1072 (goto-char (+ header-start tar-chk-offset))
1069 (delete-region (point) (+ (point) 8)) 1073 (delete-region (point) (+ (point) 8))
1070 (insert (format "%6o" chk)) 1074 (insert (format "%6o" chk))
1071 (insert 0) 1075 (insert 0)
1083 (m (set-marker (make-marker) tar-header-offset))) 1087 (m (set-marker (make-marker) tar-header-offset)))
1084 (forward-line 1) 1088 (forward-line 1)
1085 (setq after (point)) 1089 (setq after (point))
1086 ;; Insert the new text after the old, before deleting, 1090 ;; Insert the new text after the old, before deleting,
1087 ;; to preserve the window start. 1091 ;; to preserve the window start.
1088 (insert-before-markers (summarize-tar-header-block tokens t) "\n") 1092 (insert-before-markers (tar-header-block-summarize tokens t) "\n")
1089 (delete-region p after) 1093 (delete-region p after)
1090 (setq tar-header-offset (marker-position m))) 1094 (setq tar-header-offset (marker-position m)))
1091 ))) 1095 )))
1092 ;; after doing the insertion, add any final padding that may be necessary. 1096 ;; after doing the insertion, add any final padding that may be necessary.
1093 (tar-pad-to-blocksize)) 1097 (tar-pad-to-blocksize))