Mercurial > emacs
comparison lisp/tar-mode.el @ 6611:a5f180172ff3
Fix error message syntax.
(tar-mode): Doc fix.
(tar-mouse-extract): New command.
(tar-mode-map): Bind mouse-2.
(tar-get-descriptor): New function.
(tar-extract, tar-copy): Use that.
(tar-mode-maybe-write-tar-file): Renamed from maybe-write-tar-file.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Thu, 31 Mar 1994 17:16:37 +0000 |
parents | 4212fd8028bb |
children | 4e76332f7b44 |
comparison
equal
deleted
inserted
replaced
6610:35e857d14d40 | 6611:a5f180172ff3 |
---|---|
263 (let ((L (length string))) | 263 (let ((L (length string))) |
264 (if (= L 0) (error "empty string")) | 264 (if (= L 0) (error "empty string")) |
265 (tar-dotimes (i L) | 265 (tar-dotimes (i L) |
266 (if (or (< (aref string i) ?0) | 266 (if (or (< (aref string i) ?0) |
267 (> (aref string i) ?7)) | 267 (> (aref string i) ?7)) |
268 (error "'%c' is not an octal digit.")))) | 268 (error "'%c' is not an octal digit")))) |
269 (tar-parse-octal-integer string)) | 269 (tar-parse-octal-integer string)) |
270 | 270 |
271 | 271 |
272 (defun checksum-tar-header-block (string) | 272 (defun checksum-tar-header-block (string) |
273 "Compute and return a tar-acceptable checksum for this block." | 273 "Compute and return a tar-acceptable checksum for this block." |
391 ;(/ (* pos 100) bs) ; this gets round-off lossage | 391 ;(/ (* pos 100) bs) ; this gets round-off lossage |
392 (/ pos bs100) ; this doesn't | 392 (/ pos bs100) ; this doesn't |
393 ) | 393 ) |
394 (if (eq tokens 'empty-tar-block) | 394 (if (eq tokens 'empty-tar-block) |
395 nil | 395 nil |
396 (if (null tokens) (error "premature EOF parsing tar file.")) | 396 (if (null tokens) (error "premature EOF parsing tar file")) |
397 (if (eq (tar-header-link-type tokens) 20) | 397 (if (eq (tar-header-link-type tokens) 20) |
398 ;; Foo. There's an extra empty block after these. | 398 ;; Foo. There's an extra empty block after these. |
399 (setq pos (+ pos 512))) | 399 (setq pos (+ pos 512))) |
400 (let ((size (tar-header-size tokens))) | 400 (let ((size (tar-header-size tokens))) |
401 (if (< size 0) | 401 (if (< size 0) |
402 (error "%s has size %s - corrupted." | 402 (error "%s has size %s - corrupted" |
403 (tar-header-name tokens) size)) | 403 (tar-header-name tokens) size)) |
404 ; | 404 ; |
405 ; This is just too slow. Don't really need it anyway.... | 405 ; This is just too slow. Don't really need it anyway.... |
406 ;(check-tar-header-block-checksum | 406 ;(check-tar-header-block-checksum |
407 ; hblock (checksum-tar-header-block hblock) | 407 ; hblock (checksum-tar-header-block hblock) |
429 (setq tar-header-offset (point)) | 429 (setq tar-header-offset (point)) |
430 (narrow-to-region 1 tar-header-offset) | 430 (narrow-to-region 1 tar-header-offset) |
431 (set-buffer-modified-p nil))) | 431 (set-buffer-modified-p nil))) |
432 (message "parsing tar file...done.")) | 432 (message "parsing tar file...done.")) |
433 | 433 |
434 (defvar tar-mode-map nil "*Local keymap for tar-mode listings.") | 434 (defvar tar-mode-map nil "*Local keymap for Tar mode listings.") |
435 | 435 |
436 (if tar-mode-map | 436 (if tar-mode-map |
437 nil | 437 nil |
438 (setq tar-mode-map (make-keymap)) | 438 (setq tar-mode-map (make-keymap)) |
439 (suppress-keymap tar-mode-map) | 439 (suppress-keymap tar-mode-map) |
441 (define-key tar-mode-map "c" 'tar-copy) | 441 (define-key tar-mode-map "c" 'tar-copy) |
442 (define-key tar-mode-map "d" 'tar-flag-deleted) | 442 (define-key tar-mode-map "d" 'tar-flag-deleted) |
443 (define-key tar-mode-map "\^D" 'tar-flag-deleted) | 443 (define-key tar-mode-map "\^D" 'tar-flag-deleted) |
444 (define-key tar-mode-map "e" 'tar-extract) | 444 (define-key tar-mode-map "e" 'tar-extract) |
445 (define-key tar-mode-map "f" 'tar-extract) | 445 (define-key tar-mode-map "f" 'tar-extract) |
446 (define-key tar-mode-map [mouse-2] 'tar-mouse-extract) | |
446 (define-key tar-mode-map "g" 'revert-buffer) | 447 (define-key tar-mode-map "g" 'revert-buffer) |
447 (define-key tar-mode-map "h" 'describe-mode) | 448 (define-key tar-mode-map "h" 'describe-mode) |
448 (define-key tar-mode-map "n" 'tar-next-line) | 449 (define-key tar-mode-map "n" 'tar-next-line) |
449 (define-key tar-mode-map "\^N" 'tar-next-line) | 450 (define-key tar-mode-map "\^N" 'tar-next-line) |
450 (define-key tar-mode-map "o" 'tar-extract-other-window) | 451 (define-key tar-mode-map "o" 'tar-extract-other-window) |
511 ;;;###autoload | 512 ;;;###autoload |
512 (defun tar-mode () | 513 (defun tar-mode () |
513 "Major mode for viewing a tar file as a dired-like listing of its contents. | 514 "Major mode for viewing a tar file as a dired-like listing of its contents. |
514 You can move around using the usual cursor motion commands. | 515 You can move around using the usual cursor motion commands. |
515 Letters no longer insert themselves. | 516 Letters no longer insert themselves. |
516 Type `e' to pull a file out of the tar file and into its own buffer. | 517 Type `e' to pull a file out of the tar file and into its own buffer; |
518 or click mouse-2 on the file's line in the Tar mode buffer. | |
517 Type `c' to copy an entry from the tar file into another file on disk. | 519 Type `c' to copy an entry from the tar file into another file on disk. |
518 | 520 |
519 If you edit a sub-file of this archive (as with the `e' command) and | 521 If you edit a sub-file of this archive (as with the `e' command) and |
520 save it with Control-x Control-s, the contents of that buffer will be | 522 save it with Control-x Control-s, the contents of that buffer will be |
521 saved back into the tar-file buffer; in this way you can edit a file | 523 saved back into the tar-file buffer; in this way you can edit a file |
602 (or (nth (count-lines (point-min) | 604 (or (nth (count-lines (point-min) |
603 (save-excursion (beginning-of-line) (point))) | 605 (save-excursion (beginning-of-line) (point))) |
604 tar-parse-info) | 606 tar-parse-info) |
605 (if noerror | 607 (if noerror |
606 nil | 608 nil |
607 (error "This line does not describe a tar-file entry.")))) | 609 (error "This line does not describe a tar-file entry")))) |
608 | 610 |
609 | 611 (defun tar-get-descriptor () |
610 (defun tar-extract (&optional other-window-p) | 612 (let* ((descriptor (tar-current-descriptor)) |
611 "In Tar mode, extract this entry of the tar file into its own buffer." | |
612 (interactive) | |
613 (let* ((view-p (eq other-window-p 'view)) | |
614 (descriptor (tar-current-descriptor)) | |
615 (tokens (tar-desc-tokens descriptor)) | 613 (tokens (tar-desc-tokens descriptor)) |
616 (name (tar-header-name tokens)) | |
617 (size (tar-header-size tokens)) | 614 (size (tar-header-size tokens)) |
618 (link-p (tar-header-link-type tokens)) | 615 (link-p (tar-header-link-type tokens))) |
619 (start (+ (tar-desc-data-start descriptor) tar-header-offset -1)) | |
620 (end (+ start size))) | |
621 (if link-p | 616 (if link-p |
622 (error "This is a %s, not a real file." | 617 (error "This is a %s, not a real file" |
623 (cond ((eq link-p 5) "directory") | 618 (cond ((eq link-p 5) "directory") |
624 ((eq link-p 20) "tar directory header") | 619 ((eq link-p 20) "tar directory header") |
625 ((eq link-p 29) "multivolume-continuation") | 620 ((eq link-p 29) "multivolume-continuation") |
626 ((eq link-p 35) "sparse entry") | 621 ((eq link-p 35) "sparse entry") |
627 ((eq link-p 38) "volume header") | 622 ((eq link-p 38) "volume header") |
628 (t "link")))) | 623 (t "link")))) |
629 (if (zerop size) (error "This is a zero-length file.")) | 624 (if (zerop size) (error "This is a zero-length file")) |
625 descriptor)) | |
626 | |
627 (defun tar-mouse-extract (event) | |
628 "Extract a file whose tar directory line you click on." | |
629 (interactive "e") | |
630 (save-excursion | |
631 (set-buffer (window-buffer (posn-window (event-end event)))) | |
632 (save-excursion | |
633 (goto-char (posn-point (event-end event))) | |
634 ;; Just make sure this doesn't get an error. | |
635 (tar-get-descriptor))) | |
636 (select-window (posn-window (event-end event))) | |
637 (goto-char (posn-point (event-end event))) | |
638 (tar-extract)) | |
639 | |
640 (defun tar-extract (&optional other-window-p) | |
641 "In Tar mode, extract this entry of the tar file into its own buffer." | |
642 (interactive) | |
643 (let* ((view-p (eq other-window-p 'view)) | |
644 (descriptor (tar-get-descriptor)) | |
645 (tokens (tar-desc-tokens descriptor)) | |
646 (name (tar-header-name tokens)) | |
647 (size (tar-header-size tokens)) | |
648 (start (+ (tar-desc-data-start descriptor) tar-header-offset -1)) | |
649 (end (+ start size))) | |
630 (let* ((tar-buffer (current-buffer)) | 650 (let* ((tar-buffer (current-buffer)) |
631 (bufname (concat (file-name-nondirectory name) | 651 (bufname (concat (file-name-nondirectory name) |
632 " (" name " in " | 652 " (" name " in " |
633 (file-name-nondirectory (buffer-file-name)) | 653 (file-name-nondirectory (buffer-file-name)) |
634 ")")) | 654 ")")) |
712 (defun tar-copy (&optional to-file) | 732 (defun tar-copy (&optional to-file) |
713 "*In Tar mode, extract this entry of the tar file into a file on disk. | 733 "*In Tar mode, extract this entry of the tar file into a file on disk. |
714 If TO-FILE is not supplied, it is prompted for, defaulting to the name of | 734 If TO-FILE is not supplied, it is prompted for, defaulting to the name of |
715 the current tar-entry." | 735 the current tar-entry." |
716 (interactive (list (tar-read-file-name))) | 736 (interactive (list (tar-read-file-name))) |
717 (let* ((descriptor (tar-current-descriptor)) | 737 (let* ((descriptor (tar-get-descriptor)) |
718 (tokens (tar-desc-tokens descriptor)) | 738 (tokens (tar-desc-tokens descriptor)) |
719 (name (tar-header-name tokens)) | 739 (name (tar-header-name tokens)) |
720 (size (tar-header-size tokens)) | 740 (size (tar-header-size tokens)) |
721 (link-p (tar-header-link-type tokens)) | |
722 (start (+ (tar-desc-data-start descriptor) tar-header-offset -1)) | 741 (start (+ (tar-desc-data-start descriptor) tar-header-offset -1)) |
723 (end (+ start size))) | 742 (end (+ start size))) |
724 (if link-p (error "This is a link, not a real file.")) | |
725 (if (zerop size) (error "This is a zero-length file.")) | |
726 (let* ((tar-buffer (current-buffer)) | 743 (let* ((tar-buffer (current-buffer)) |
727 buffer) | 744 buffer) |
728 (unwind-protect | 745 (unwind-protect |
729 (progn | 746 (progn |
730 (setq buffer (generate-new-buffer "*tar-copy-tmp*")) | 747 (setq buffer (generate-new-buffer "*tar-copy-tmp*")) |
906 This does not modify the disk image; you must save the tar file itself | 923 This does not modify the disk image; you must save the tar file itself |
907 for this to be permanent." | 924 for this to be permanent." |
908 (interactive | 925 (interactive |
909 (list (read-string "New name: " | 926 (list (read-string "New name: " |
910 (tar-header-name (tar-desc-tokens (tar-current-descriptor)))))) | 927 (tar-header-name (tar-desc-tokens (tar-current-descriptor)))))) |
911 (if (string= "" new-name) (error "zero length name.")) | 928 (if (string= "" new-name) (error "zero length name")) |
912 (if (> (length new-name) 98) (error "name too long.")) | 929 (if (> (length new-name) 98) (error "name too long")) |
913 (tar-setf (tar-header-name (tar-desc-tokens (tar-current-descriptor))) | 930 (tar-setf (tar-header-name (tar-desc-tokens (tar-current-descriptor))) |
914 new-name) | 931 new-name) |
915 (tar-alter-one-field 0 | 932 (tar-alter-one-field 0 |
916 (substring (concat new-name (make-string 99 0)) 0 99))) | 933 (substring (concat new-name (make-string 99 0)) 0 99))) |
917 | 934 |
981 "In tar subfile mode, save this buffer into its parent tar-file buffer. | 998 "In tar subfile mode, save this buffer into its parent tar-file buffer. |
982 This doesn't write anything to disk; you must save the parent tar-file buffer | 999 This doesn't write anything to disk; you must save the parent tar-file buffer |
983 to make your changes permanent." | 1000 to make your changes permanent." |
984 (interactive) | 1001 (interactive) |
985 (if (not (and (boundp 'tar-superior-buffer) tar-superior-buffer)) | 1002 (if (not (and (boundp 'tar-superior-buffer) tar-superior-buffer)) |
986 (error "this buffer has no superior tar file buffer.")) | 1003 (error "This buffer has no superior tar file buffer")) |
987 (if (not (and (boundp 'tar-superior-descriptor) tar-superior-descriptor)) | 1004 (if (not (and (boundp 'tar-superior-descriptor) tar-superior-descriptor)) |
988 (error "this buffer doesn't have an index into its superior tar file!")) | 1005 (error "This buffer doesn't have an index into its superior tar file!")) |
989 (save-excursion | 1006 (save-excursion |
990 (let ((subfile (current-buffer)) | 1007 (let ((subfile (current-buffer)) |
991 (subfile-size (buffer-size)) | 1008 (subfile-size (buffer-size)) |
992 (descriptor tar-superior-descriptor)) | 1009 (descriptor tar-superior-descriptor)) |
993 (set-buffer tar-superior-buffer) | 1010 (set-buffer tar-superior-buffer) |
1099 (1+ (buffer-size))) | 1116 (1+ (buffer-size))) |
1100 0))) | 1117 0))) |
1101 ))) | 1118 ))) |
1102 | 1119 |
1103 | 1120 |
1104 (defun maybe-write-tar-file () | 1121 ;; Used in write-file-hook to write tar-files out correctly. |
1105 "Used as a write-file-hook to write tar-files out correctly." | 1122 (defun tar-mode-maybe-write-tar-file () |
1106 ;; | 1123 ;; |
1107 ;; If the current buffer is in Tar mode and has its header-offset set, | 1124 ;; If the current buffer is in Tar mode and has its header-offset set, |
1108 ;; only write out the part of the file after the header-offset. | 1125 ;; only write out the part of the file after the header-offset. |
1109 ;; | 1126 ;; |
1110 (if (and (eq major-mode 'tar-mode) | 1127 (if (and (eq major-mode 'tar-mode) |
1125 nil)) | 1142 nil)) |
1126 | 1143 |
1127 | 1144 |
1128 ;;; Patch it in. | 1145 ;;; Patch it in. |
1129 | 1146 |
1130 (or (memq 'maybe-write-tar-file write-file-hooks) | 1147 (or (memq 'tar-mode-maybe-write-tar-file write-file-hooks) |
1131 (setq write-file-hooks | 1148 (setq write-file-hooks |
1132 (cons 'maybe-write-tar-file write-file-hooks))) | 1149 (cons 'tar-mode-maybe-write-tar-file write-file-hooks))) |
1133 | 1150 |
1134 (provide 'tar-mode) | 1151 (provide 'tar-mode) |
1135 | 1152 |
1136 ;;; tar-mode.el ends here | 1153 ;;; tar-mode.el ends here |