Mercurial > emacs
comparison lisp/tar-mode.el @ 90261:7beb78bc1f8e
Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-97
Merge from emacs--cvs-trunk--0
Patches applied:
* emacs--cvs-trunk--0 (patch 616-696)
- Add lisp/mh-e/.arch-inventory
- Update from CVS
- Merge from gnus--rel--5.10
- Update from CVS: lisp/smerge-mode.el: Add 'tools' to file keywords.
- lisp/gnus/ChangeLog: Remove duplicate entry
* gnus--rel--5.10 (patch 147-181)
- Update from CVS
- Merge from emacs--cvs-trunk--0
- Update from CVS: lisp/mml.el (mml-preview): Doc fix.
- Update from CVS: texi/message.texi: Fix default values.
- Update from CVS: texi/gnus.texi (RSS): Addition.
author | Miles Bader <miles@gnu.org> |
---|---|
date | Mon, 16 Jan 2006 08:37:27 +0000 |
parents | 2d92f5c9d6ae baa95d93b4e0 |
children | 9970a9645ad9 |
comparison
equal
deleted
inserted
replaced
90260:0ca0d9181b5e | 90261:7beb78bc1f8e |
---|---|
99 "Simple editing of tar files." | 99 "Simple editing of tar files." |
100 :prefix "tar-" | 100 :prefix "tar-" |
101 :group 'data) | 101 :group 'data) |
102 | 102 |
103 (defcustom tar-anal-blocksize 20 | 103 (defcustom tar-anal-blocksize 20 |
104 "*The blocksize of tar files written by Emacs, or nil, meaning don't care. | 104 "The blocksize of tar files written by Emacs, or nil, meaning don't care. |
105 The blocksize of a tar file is not really the size of the blocks; rather, it is | 105 The blocksize of a tar file is not really the size of the blocks; rather, it is |
106 the number of blocks written with one system call. When tarring to a tape, | 106 the number of blocks written with one system call. When tarring to a tape, |
107 this is the size of the *tape* blocks, but when writing to a file, it doesn't | 107 this is the size of the *tape* blocks, but when writing to a file, it doesn't |
108 matter much. The only noticeable difference is that if a tar file does not | 108 matter much. The only noticeable difference is that if a tar file does not |
109 have a blocksize of 20, tar will tell you that; all this really controls is | 109 have a blocksize of 20, tar will tell you that; all this really controls is |
110 how many null padding bytes go on the end of the tar file." | 110 how many null padding bytes go on the end of the tar file." |
111 :type '(choice integer (const nil)) | 111 :type '(choice integer (const nil)) |
112 :group 'tar) | 112 :group 'tar) |
113 | 113 |
114 (defcustom tar-update-datestamp nil | 114 (defcustom tar-update-datestamp nil |
115 "*Non-nil means Tar mode should play fast and loose with sub-file datestamps. | 115 "Non-nil means Tar mode should play fast and loose with sub-file datestamps. |
116 If this is true, then editing and saving a tar file entry back into its | 116 If this is true, then editing and saving a tar file entry back into its |
117 tar file will update its datestamp. If false, the datestamp is unchanged. | 117 tar file will update its datestamp. If false, the datestamp is unchanged. |
118 You may or may not want this - it is good in that you can tell when a file | 118 You may or may not want this - it is good in that you can tell when a file |
119 in a tar archive has been changed, but it is bad for the same reason that | 119 in a tar archive has been changed, but it is bad for the same reason that |
120 editing a file in the tar archive at all is bad - the changed version of | 120 editing a file in the tar archive at all is bad - the changed version of |
121 the file never exists on disk." | 121 the file never exists on disk." |
122 :type 'boolean | 122 :type 'boolean |
123 :group 'tar) | 123 :group 'tar) |
124 | 124 |
125 (defcustom tar-mode-show-date nil | 125 (defcustom tar-mode-show-date nil |
126 "*Non-nil means Tar mode should show the date/time of each subfile. | 126 "Non-nil means Tar mode should show the date/time of each subfile. |
127 This information is useful, but it takes screen space away from file names." | 127 This information is useful, but it takes screen space away from file names." |
128 :type 'boolean | 128 :type 'boolean |
129 :group 'tar) | 129 :group 'tar) |
130 | 130 |
131 (defvar tar-parse-info nil) | 131 (defvar tar-parse-info nil) |
283 lo (logand lo 65535))) | 283 lo (logand lo 65535))) |
284 (setq start (1+ start))) | 284 (setq start (1+ start))) |
285 (list hi lo)))) | 285 (list hi lo)))) |
286 | 286 |
287 (defun tar-parse-octal-integer-safe (string) | 287 (defun tar-parse-octal-integer-safe (string) |
288 (let ((L (length string))) | 288 (if (zerop (length string)) (error "empty string")) |
289 (if (= L 0) (error "empty string")) | 289 (mapc (lambda (c) |
290 (dotimes (i L) | 290 (if (or (< c ?0) (> c ?7)) |
291 (if (or (< (aref string i) ?0) | 291 (error "`%c' is not an octal digit" c))) |
292 (> (aref string i) ?7)) | 292 string) |
293 (error "`%c' is not an octal digit" (aref string i))))) | |
294 (tar-parse-octal-integer string)) | 293 (tar-parse-octal-integer string)) |
295 | 294 |
296 | 295 |
297 (defun tar-header-block-checksum (string) | 296 (defun tar-header-block-checksum (string) |
298 "Compute and return a tar-acceptable checksum for this block." | 297 "Compute and return a tar-acceptable checksum for this block." |
343 (gid (tar-header-gid tar-hblock)) | 342 (gid (tar-header-gid tar-hblock)) |
344 (uname (tar-header-uname tar-hblock)) | 343 (uname (tar-header-uname tar-hblock)) |
345 (gname (tar-header-gname tar-hblock)) | 344 (gname (tar-header-gname tar-hblock)) |
346 (size (tar-header-size tar-hblock)) | 345 (size (tar-header-size tar-hblock)) |
347 (time (tar-header-date tar-hblock)) | 346 (time (tar-header-date tar-hblock)) |
348 (ck (tar-header-checksum tar-hblock)) | 347 ;; (ck (tar-header-checksum tar-hblock)) |
349 (type (tar-header-link-type tar-hblock)) | 348 (type (tar-header-link-type tar-hblock)) |
350 (link-name (tar-header-link-name tar-hblock))) | 349 (link-name (tar-header-link-name tar-hblock))) |
351 (format "%c%c%s%8s/%-8s%7s%s %s%s" | 350 (format "%c%c%s%8s/%-8s%7s%s %s%s" |
352 (if mod-p ?* ? ) | 351 (if mod-p ?* ? ) |
353 (cond ((or (eq type nil) (eq type 0)) ?-) | 352 (cond ((or (eq type nil) (eq type 0)) ?-) |
555 Type `e' to pull a file out of the tar file and into its own buffer; | 554 Type `e' to pull a file out of the tar file and into its own buffer; |
556 or click mouse-2 on the file's line in the Tar mode buffer. | 555 or click mouse-2 on the file's line in the Tar mode buffer. |
557 Type `c' to copy an entry from the tar file into another file on disk. | 556 Type `c' to copy an entry from the tar file into another file on disk. |
558 | 557 |
559 If you edit a sub-file of this archive (as with the `e' command) and | 558 If you edit a sub-file of this archive (as with the `e' command) and |
560 save it with Control-x Control-s, the contents of that buffer will be | 559 save it with \\[save-buffer], the contents of that buffer will be |
561 saved back into the tar-file buffer; in this way you can edit a file | 560 saved back into the tar-file buffer; in this way you can edit a file |
562 inside of a tar archive without extracting it and re-archiving it. | 561 inside of a tar archive without extracting it and re-archiving it. |
563 | 562 |
564 See also: variables `tar-update-datestamp' and `tar-anal-blocksize'. | 563 See also: variables `tar-update-datestamp' and `tar-anal-blocksize'. |
565 \\{tar-mode-map}" | 564 \\{tar-mode-map}" |
769 (switch-to-buffer-other-window buffer) | 768 (switch-to-buffer-other-window buffer) |
770 (switch-to-buffer buffer))))))) | 769 (switch-to-buffer buffer))))))) |
771 | 770 |
772 | 771 |
773 (defun tar-extract-other-window () | 772 (defun tar-extract-other-window () |
774 "*In Tar mode, find this entry of the tar file in another window." | 773 "In Tar mode, find this entry of the tar file in another window." |
775 (interactive) | 774 (interactive) |
776 (tar-extract t)) | 775 (tar-extract t)) |
777 | 776 |
778 (defun tar-display-other-window () | 777 (defun tar-display-other-window () |
779 "*In Tar mode, display this entry of the tar file in another window." | 778 "In Tar mode, display this entry of the tar file in another window." |
780 (interactive) | 779 (interactive) |
781 (tar-extract 'display)) | 780 (tar-extract 'display)) |
782 | 781 |
783 (defun tar-view () | 782 (defun tar-view () |
784 "*In Tar mode, view the tar file entry on this line." | 783 "In Tar mode, view the tar file entry on this line." |
785 (interactive) | 784 (interactive) |
786 (tar-extract 'view)) | 785 (tar-extract 'view)) |
787 | 786 |
788 | 787 |
789 (defun tar-read-file-name (&optional prompt) | 788 (defun tar-read-file-name (&optional prompt) |
805 (file-name-nondirectory default-file)))) | 804 (file-name-nondirectory default-file)))) |
806 target)) | 805 target)) |
807 | 806 |
808 | 807 |
809 (defun tar-copy (&optional to-file) | 808 (defun tar-copy (&optional to-file) |
810 "*In Tar mode, extract this entry of the tar file into a file on disk. | 809 "In Tar mode, extract this entry of the tar file into a file on disk. |
811 If TO-FILE is not supplied, it is prompted for, defaulting to the name of | 810 If TO-FILE is not supplied, it is prompted for, defaulting to the name of |
812 the current tar-entry." | 811 the current tar-entry." |
813 (interactive (list (tar-read-file-name))) | 812 (interactive (list (tar-read-file-name))) |
814 (let* ((descriptor (tar-get-descriptor)) | 813 (let* ((descriptor (tar-get-descriptor)) |
815 (tokens (tar-desc-tokens descriptor)) | 814 (tokens (tar-desc-tokens descriptor)) |
834 (let ((coding-system-for-write 'no-conversion)) | 833 (let ((coding-system-for-write 'no-conversion)) |
835 (write-region start end to-file nil nil nil t))) | 834 (write-region start end to-file nil nil nil t))) |
836 (message "Copied tar entry %s to %s" name to-file))) | 835 (message "Copied tar entry %s to %s" name to-file))) |
837 | 836 |
838 (defun tar-flag-deleted (p &optional unflag) | 837 (defun tar-flag-deleted (p &optional unflag) |
839 "*In Tar mode, mark this sub-file to be deleted from the tar file. | 838 "In Tar mode, mark this sub-file to be deleted from the tar file. |
840 With a prefix argument, mark that many files." | 839 With a prefix argument, mark that many files." |
841 (interactive "p") | 840 (interactive "p") |
842 (beginning-of-line) | 841 (beginning-of-line) |
843 (dotimes (i (if (< p 0) (- p) p)) | 842 (dotimes (i (abs p)) |
844 (if (tar-current-descriptor unflag) ; barf if we're not on an entry-line. | 843 (if (tar-current-descriptor unflag) ; barf if we're not on an entry-line. |
845 (progn | 844 (progn |
846 (delete-char 1) | 845 (delete-char 1) |
847 (insert (if unflag " " "D")))) | 846 (insert (if unflag " " "D")))) |
848 (forward-line (if (< p 0) -1 1))) | 847 (forward-line (if (< p 0) -1 1))) |
849 (if (eobp) nil (forward-char 36))) | 848 (if (eobp) nil (forward-char 36))) |
850 | 849 |
851 (defun tar-unflag (p) | 850 (defun tar-unflag (p) |
852 "*In Tar mode, un-mark this sub-file if it is marked to be deleted. | 851 "In Tar mode, un-mark this sub-file if it is marked to be deleted. |
853 With a prefix argument, un-mark that many files forward." | 852 With a prefix argument, un-mark that many files forward." |
854 (interactive "p") | 853 (interactive "p") |
855 (tar-flag-deleted p t)) | 854 (tar-flag-deleted p t)) |
856 | 855 |
857 (defun tar-unflag-backwards (p) | 856 (defun tar-unflag-backwards (p) |
858 "*In Tar mode, un-mark this sub-file if it is marked to be deleted. | 857 "In Tar mode, un-mark this sub-file if it is marked to be deleted. |
859 With a prefix argument, un-mark that many files backward." | 858 With a prefix argument, un-mark that many files backward." |
860 (interactive "p") | 859 (interactive "p") |
861 (tar-flag-deleted (- p) t)) | 860 (tar-flag-deleted (- p) t)) |
862 | 861 |
863 | 862 |
864 (defun tar-expunge-internal () | 863 (defun tar-expunge-internal () |
865 "Expunge the tar-entry specified by the current line." | 864 "Expunge the tar-entry specified by the current line." |
866 (let* ((descriptor (tar-current-descriptor)) | 865 (let* ((descriptor (tar-current-descriptor)) |
867 (tokens (tar-desc-tokens descriptor)) | 866 (tokens (tar-desc-tokens descriptor)) |
868 (line (tar-desc-data-start descriptor)) | 867 ;; (line (tar-desc-data-start descriptor)) |
869 (name (tar-header-name tokens)) | 868 (name (tar-header-name tokens)) |
870 (size (tar-header-size tokens)) | 869 (size (tar-header-size tokens)) |
871 (link-p (tar-header-link-type tokens)) | 870 (link-p (tar-header-link-type tokens)) |
872 (start (tar-desc-data-start descriptor)) | 871 (start (tar-desc-data-start descriptor)) |
873 (following-descs (cdr (memq descriptor tar-parse-info)))) | 872 (following-descs (cdr (memq descriptor tar-parse-info)))) |
875 ;; | 874 ;; |
876 ;; delete the current line... | 875 ;; delete the current line... |
877 (beginning-of-line) | 876 (beginning-of-line) |
878 (let ((line-start (point))) | 877 (let ((line-start (point))) |
879 (end-of-line) (forward-char) | 878 (end-of-line) (forward-char) |
880 (let ((line-len (- (point) line-start))) | 879 ;; decrement the header-pointer to be in sync... |
881 (delete-region line-start (point)) | 880 (setq tar-header-offset (- tar-header-offset (- (point) line-start))) |
882 ;; | 881 (delete-region line-start (point))) |
883 ;; decrement the header-pointer to be in sync... | |
884 (setq tar-header-offset (- tar-header-offset line-len)))) | |
885 ;; | 882 ;; |
886 ;; delete the data pointer... | 883 ;; delete the data pointer... |
887 (setq tar-parse-info (delq descriptor tar-parse-info)) | 884 (setq tar-parse-info (delq descriptor tar-parse-info)) |
888 ;; | 885 ;; |
889 ;; delete the data from inside the file... | 886 ;; delete the data from inside the file... |
890 (widen) | 887 (widen) |
891 (let* ((data-start (+ start tar-header-offset -513)) | 888 (let* ((data-start (+ start (- tar-header-offset (point-min)) -512)) |
892 (data-end (+ data-start 512 (ash (ash (+ size 511) -9) 9)))) | 889 (data-end (+ data-start 512 (ash (ash (+ size 511) -9) 9)))) |
893 (delete-region data-start data-end) | 890 (delete-region data-start data-end) |
894 ;; | 891 ;; |
895 ;; and finally, decrement the start-pointers of all following | 892 ;; and finally, decrement the start-pointers of all following |
896 ;; entries in the archive. This is a pig when deleting a bunch | 893 ;; entries in the archive. This is a pig when deleting a bunch |
904 )) | 901 )) |
905 (narrow-to-region (point-min) tar-header-offset)) | 902 (narrow-to-region (point-min) tar-header-offset)) |
906 | 903 |
907 | 904 |
908 (defun tar-expunge (&optional noconfirm) | 905 (defun tar-expunge (&optional noconfirm) |
909 "*In Tar mode, delete all the archived files flagged for deletion. | 906 "In Tar mode, delete all the archived files flagged for deletion. |
910 This does not modify the disk image; you must save the tar file itself | 907 This does not modify the disk image; you must save the tar file itself |
911 for this to be permanent." | 908 for this to be permanent." |
912 (interactive) | 909 (interactive) |
913 (if (or noconfirm | 910 (if (or noconfirm |
914 (y-or-n-p "Expunge files marked for deletion? ")) | 911 (y-or-n-p "Expunge files marked for deletion? ")) |
938 (progn (delete-char 1) (insert " "))) | 935 (progn (delete-char 1) (insert " "))) |
939 (forward-line 1)))) | 936 (forward-line 1)))) |
940 | 937 |
941 | 938 |
942 (defun tar-chown-entry (new-uid) | 939 (defun tar-chown-entry (new-uid) |
943 "*Change the user-id associated with this entry in the tar file. | 940 "Change the user-id associated with this entry in the tar file. |
944 If this tar file was written by GNU tar, then you will be able to edit | 941 If this tar file was written by GNU tar, then you will be able to edit |
945 the user id as a string; otherwise, you must edit it as a number. | 942 the user id as a string; otherwise, you must edit it as a number. |
946 You can force editing as a number by calling this with a prefix arg. | 943 You can force editing as a number by calling this with a prefix arg. |
947 This does not modify the disk image; you must save the tar file itself | 944 This does not modify the disk image; you must save the tar file itself |
948 for this to be permanent." | 945 for this to be permanent." |
966 (tar-alter-one-field tar-uid-offset | 963 (tar-alter-one-field tar-uid-offset |
967 (concat (substring (format "%6o" new-uid) 0 6) "\000 "))))) | 964 (concat (substring (format "%6o" new-uid) 0 6) "\000 "))))) |
968 | 965 |
969 | 966 |
970 (defun tar-chgrp-entry (new-gid) | 967 (defun tar-chgrp-entry (new-gid) |
971 "*Change the group-id associated with this entry in the tar file. | 968 "Change the group-id associated with this entry in the tar file. |
972 If this tar file was written by GNU tar, then you will be able to edit | 969 If this tar file was written by GNU tar, then you will be able to edit |
973 the group id as a string; otherwise, you must edit it as a number. | 970 the group id as a string; otherwise, you must edit it as a number. |
974 You can force editing as a number by calling this with a prefix arg. | 971 You can force editing as a number by calling this with a prefix arg. |
975 This does not modify the disk image; you must save the tar file itself | 972 This does not modify the disk image; you must save the tar file itself |
976 for this to be permanent." | 973 for this to be permanent." |
994 new-gid) | 991 new-gid) |
995 (tar-alter-one-field tar-gid-offset | 992 (tar-alter-one-field tar-gid-offset |
996 (concat (substring (format "%6o" new-gid) 0 6) "\000 "))))) | 993 (concat (substring (format "%6o" new-gid) 0 6) "\000 "))))) |
997 | 994 |
998 (defun tar-rename-entry (new-name) | 995 (defun tar-rename-entry (new-name) |
999 "*Change the name associated with this entry in the tar file. | 996 "Change the name associated with this entry in the tar file. |
1000 This does not modify the disk image; you must save the tar file itself | 997 This does not modify the disk image; you must save the tar file itself |
1001 for this to be permanent." | 998 for this to be permanent." |
1002 (interactive | 999 (interactive |
1003 (list (read-string "New name: " | 1000 (list (read-string "New name: " |
1004 (tar-header-name (tar-desc-tokens (tar-current-descriptor)))))) | 1001 (tar-header-name (tar-desc-tokens (tar-current-descriptor)))))) |
1204 (tokens (tar-desc-tokens last-desc)) | 1201 (tokens (tar-desc-tokens last-desc)) |
1205 (link-p (tar-header-link-type tokens)) | 1202 (link-p (tar-header-link-type tokens)) |
1206 (size (if link-p 0 (tar-header-size tokens))) | 1203 (size (if link-p 0 (tar-header-size tokens))) |
1207 (data-end (+ start size)) | 1204 (data-end (+ start size)) |
1208 (bbytes (ash tar-anal-blocksize 9)) | 1205 (bbytes (ash tar-anal-blocksize 9)) |
1209 (pad-to (+ bbytes (* bbytes (/ (1- data-end) bbytes)))) | 1206 (pad-to (+ bbytes (* bbytes (/ (- data-end (point-min)) bbytes)))) |
1210 (inhibit-read-only t) ; ## | 1207 (inhibit-read-only t) ; ## |
1211 ) | 1208 ) |
1212 ;; If the padding after the last data is too long, delete some; | 1209 ;; If the padding after the last data is too long, delete some; |
1213 ;; else insert some until we are padded out to the right number of blocks. | 1210 ;; else insert some until we are padded out to the right number of blocks. |
1214 ;; | 1211 ;; |
1215 (goto-char (+ (or tar-header-offset 0) data-end)) | 1212 (let ((goal-end (+ (or tar-header-offset 0) pad-to))) |
1216 (if (> (1+ (buffer-size)) (+ (or tar-header-offset 0) pad-to)) | 1213 (if (> (point-max) goal-end) |
1217 (delete-region (+ (or tar-header-offset 0) pad-to) (1+ (buffer-size))) | 1214 (delete-region goal-end (point-max)) |
1218 (insert (make-string (- (+ (or tar-header-offset 0) pad-to) | 1215 (goto-char (point-max)) |
1219 (1+ (buffer-size))) | 1216 (insert (make-string (- goal-end (point-max)) ?\0))))))) |
1220 0))) | |
1221 ))) | |
1222 | 1217 |
1223 | 1218 |
1224 ;; Used in write-file-hook to write tar-files out correctly. | 1219 ;; Used in write-file-hook to write tar-files out correctly. |
1225 (defun tar-mode-write-file () | 1220 (defun tar-mode-write-file () |
1226 (unwind-protect | 1221 (unwind-protect |
1242 ;; Return t because we've written the file. | 1237 ;; Return t because we've written the file. |
1243 t) | 1238 t) |
1244 | 1239 |
1245 (provide 'tar-mode) | 1240 (provide 'tar-mode) |
1246 | 1241 |
1247 ;;; arch-tag: 8a585a4a-340e-42c2-89e7-d3b1013a4b78 | 1242 ;; arch-tag: 8a585a4a-340e-42c2-89e7-d3b1013a4b78 |
1248 ;;; tar-mode.el ends here | 1243 ;;; tar-mode.el ends here |