summaryrefslogtreecommitdiff
path: root/lisp/tar-mode.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/tar-mode.el')
-rw-r--r--lisp/tar-mode.el130
1 files changed, 57 insertions, 73 deletions
diff --git a/lisp/tar-mode.el b/lisp/tar-mode.el
index a73fa917e4b..cf777817666 100644
--- a/lisp/tar-mode.el
+++ b/lisp/tar-mode.el
@@ -1,4 +1,4 @@
-;;; tar-mode.el --- simple editing of tar files from GNU Emacs
+;;; tar-mode.el --- simple editing of tar files from GNU Emacs -*- lexical-binding:t -*-
;; Copyright (C) 1990-1991, 1993-2019 Free Software Foundation, Inc.
@@ -95,6 +95,7 @@
;;; Code:
(eval-when-compile (require 'cl-lib))
+(require 'arc-mode)
(defgroup tar nil
"Simple editing of tar files."
@@ -109,8 +110,7 @@ this is the size of the *tape* blocks, but when writing to a file, it doesn't
matter much. The only noticeable difference is that if a tar file does not
have a blocksize of 20, tar will tell you that; all this really controls is
how many null padding bytes go on the end of the tar file."
- :type '(choice integer (const nil))
- :group 'tar)
+ :type '(choice integer (const nil)))
(defcustom tar-update-datestamp nil
"Non-nil means Tar mode should play fast and loose with sub-file datestamps.
@@ -120,14 +120,12 @@ You may or may not want this - it is good in that you can tell when a file
in a tar archive has been changed, but it is bad for the same reason that
editing a file in the tar archive at all is bad - the changed version of
the file never exists on disk."
- :type 'boolean
- :group 'tar)
+ :type 'boolean)
(defcustom tar-mode-show-date nil
"Non-nil means Tar mode should show the date/time of each subfile.
This information is useful, but it takes screen space away from file names."
- :type 'boolean
- :group 'tar)
+ :type 'boolean)
(defvar tar-parse-info nil)
(defvar tar-superior-buffer nil
@@ -265,11 +263,10 @@ write-date, checksum, link-type, and link-name."
(setq name (concat (substring string tar-prefix-offset
(1- (match-end 0)))
"/" name)))
- (if (default-value 'enable-multibyte-characters)
- (setq name
- (decode-coding-string name coding)
- linkname
- (decode-coding-string linkname coding)))
+ (setq name
+ (decode-coding-string name coding)
+ linkname
+ (decode-coding-string linkname coding))
(if (and (null link-p) (string-match "/\\'" name))
(setq link-p 5)) ; directory
@@ -305,7 +302,7 @@ write-date, checksum, link-type, and link-name."
(tar-parse-octal-integer string tar-uid-offset tar-gid-offset)
(tar-parse-octal-integer string tar-gid-offset tar-size-offset)
(tar-parse-octal-integer string tar-size-offset tar-time-offset)
- (tar-parse-octal-long-integer string tar-time-offset tar-chk-offset)
+ (tar-parse-octal-integer string tar-time-offset tar-chk-offset)
(tar-parse-octal-integer string tar-chk-offset tar-linkp-offset)
link-p
linkname
@@ -343,20 +340,8 @@ write-date, checksum, link-type, and link-name."
start (1+ start)))
n)))
-(defun tar-parse-octal-long-integer (string &optional start end)
- (if (null start) (setq start 0))
- (if (null end) (setq end (length string)))
- (if (= (aref string start) 0)
- (list 0 0)
- (let ((lo 0)
- (hi 0))
- (while (< start end)
- (if (>= (aref string start) ?0)
- (setq lo (+ (* lo 8) (- (aref string start) ?0))
- hi (+ (* hi 8) (ash lo -16))
- lo (logand lo 65535)))
- (setq start (1+ start)))
- (list hi lo))))
+(define-obsolete-function-alias 'tar-parse-octal-long-integer
+ #'tar-parse-octal-integer "27.1")
(defun tar-parse-octal-integer-safe (string)
(if (zerop (length string)) (error "empty string"))
@@ -535,30 +520,38 @@ MODE should be an integer which is a file mode value."
"Extract all archive members in the tar-file into the current directory."
(interactive)
;; FIXME: make it work even if we're not in tar-mode.
- (let ((descriptors tar-parse-info)) ;Read the var in its buffer.
- (with-current-buffer
- (if (tar-data-swapped-p) tar-data-buffer (current-buffer))
- (set-buffer-multibyte nil) ;Hopefully, a no-op.
- (dolist (descriptor descriptors)
- (let* ((name (tar-header-name descriptor))
- (dir (if (eq (tar-header-link-type descriptor) 5)
- name
- (file-name-directory name)))
- (link-desc (tar--describe-as-link descriptor))
- (start (tar-header-data-start descriptor))
- (end (+ start (tar-header-size descriptor))))
+ (let ((data-buf (if (tar-data-swapped-p) tar-data-buffer
+ (current-buffer)))
+ (reporter (make-progress-reporter "Extracting")))
+ (with-current-buffer data-buf
+ (cl-assert (not enable-multibyte-characters)))
+ (dolist (descriptor tar-parse-info)
+ (let* ((orig (tar-header-name descriptor))
+ ;; Note that default-directory may have different values
+ ;; in the tar-mode and data buffers, so we stick to the
+ ;; absolute file name from now on.
+ (name (expand-file-name orig))
+ (dir (if (eq (tar-header-link-type descriptor) 5)
+ name
+ (file-name-directory name)))
+ (link-desc (tar--describe-as-link descriptor))
+ (start (tar-header-data-start descriptor))
+ (end (+ start (tar-header-size descriptor))))
+ (unless (file-directory-p name)
+ (progress-reporter-update reporter name)
+ (if (and dir (not (file-exists-p dir)))
+ (make-directory dir t))
(unless (file-directory-p name)
- (message "Extracting %s" name)
- (if (and dir (not (file-exists-p dir)))
- (make-directory dir t))
- (unless (file-directory-p name)
- (let ((coding-system-for-write 'no-conversion))
+ (with-current-buffer data-buf
+ (let ((coding-system-for-write 'no-conversion)
+ (write-region-inhibit-fsync t))
(when link-desc
(lwarn '(tar link) :warning
"Extracted `%s', %s, as a normal file"
name link-desc))
- (write-region start end name)))
- (set-file-modes name (tar-header-mode descriptor))))))))
+ (write-region start end name nil :nomessage)))
+ (set-file-modes name (tar-header-mode descriptor))))))
+ (progress-reporter-done reporter)))
(defun tar-summarize-buffer ()
"Parse the contents of the tar file in the current buffer."
@@ -596,10 +589,10 @@ MODE should be an integer which is a file mode value."
(progress-reporter-done progress-reporter)
(message "Warning: premature EOF parsing tar file"))
(goto-char (point-min))
- (let ((buffer-file-truename nil) ; avoid changing dir mtime by lock_file
+ (let ((create-lockfiles nil) ; avoid changing dir mtime by lock_file
(inhibit-read-only t)
(total-summaries
- (mapconcat 'tar-header-block-summarize tar-parse-info "\n")))
+ (mapconcat #'tar-header-block-summarize tar-parse-info "\n")))
(insert total-summaries "\n")
(goto-char (point-min))
(restore-buffer-modified-p modified))))
@@ -733,13 +726,13 @@ See also: variables `tar-update-datestamp' and `tar-anal-blocksize'.
;; Now move the Tar data into an auxiliary buffer, so we can use the main
;; buffer for the summary.
(cl-assert (not (tar-data-swapped-p)))
- (set (make-local-variable 'revert-buffer-function) 'tar-mode-revert)
+ (set (make-local-variable 'revert-buffer-function) #'tar-mode-revert)
;; We started using write-contents-functions, but this hook is not
;; used during auto-save, so we now use
;; write-region-annotate-functions which hooks at a lower-level.
- (add-hook 'write-region-annotate-functions 'tar-write-region-annotate nil t)
- (add-hook 'kill-buffer-hook 'tar-mode-kill-buffer-hook nil t)
- (add-hook 'change-major-mode-hook 'tar-change-major-mode-hook nil t)
+ (add-hook 'write-region-annotate-functions #'tar-write-region-annotate nil t)
+ (add-hook 'kill-buffer-hook #'tar-mode-kill-buffer-hook nil t)
+ (add-hook 'change-major-mode-hook #'tar-change-major-mode-hook nil t)
;; Tar data is made of bytes, not chars.
(set-buffer-multibyte nil) ;Hopefully a no-op.
(set (make-local-variable 'tar-data-buffer)
@@ -763,24 +756,22 @@ See also: variables `tar-update-datestamp' and `tar-anal-blocksize'.
(define-minor-mode tar-subfile-mode
"Minor mode for editing an element of a tar-file.
-With a prefix argument ARG, enable the mode if ARG is positive,
-and disable it otherwise. If called from Lisp, enable the mode
-if ARG is omitted or nil. This mode arranges for \"saving\" this
-buffer to write the data into the tar-file buffer that it came
-from. The changes will actually appear on disk when you save the
-tar-file's buffer."
+
+This mode arranges for \"saving\" this buffer to write the data
+into the tar-file buffer that it came from. The changes will
+actually appear on disk when you save the tar-file's buffer."
;; Don't do this, because it is redundant and wastes mode line space.
;; :lighter " TarFile"
nil nil nil
(or (and (boundp 'tar-superior-buffer) tar-superior-buffer)
(error "This buffer is not an element of a tar file"))
(cond (tar-subfile-mode
- (add-hook 'write-file-functions 'tar-subfile-save-buffer nil t)
+ (add-hook 'write-file-functions #'tar-subfile-save-buffer nil t)
;; turn off auto-save.
(auto-save-mode -1)
(setq buffer-auto-save-file-name nil))
(t
- (remove-hook 'write-file-functions 'tar-subfile-save-buffer t))))
+ (remove-hook 'write-file-functions #'tar-subfile-save-buffer t))))
;; Revert the buffer and recompute the dired-like listing.
@@ -907,8 +898,7 @@ tar-file's buffer."
(if (or (not coding)
(eq (coding-system-type coding) 'undecided))
(setq coding (detect-coding-region start end t)))
- (if (and (default-value 'enable-multibyte-characters)
- (coding-system-get coding :for-unibyte))
+ (if (coding-system-get coding :for-unibyte)
(with-current-buffer buffer
(set-buffer-multibyte nil)))
(widen)
@@ -947,6 +937,7 @@ tar-file's buffer."
(setq buffer-file-name new-buffer-file-name)
(setq buffer-file-truename
(abbreviate-file-name buffer-file-name))
+ (archive-try-jka-compr) ;Pretty ugly hack :-(
;; Force buffer-file-coding-system to what
;; decode-coding-region actually used.
(set-buffer-file-coding-system last-coding-system-used t)
@@ -1036,8 +1027,7 @@ the current tar-entry."
(defun tar-new-entry (filename &optional index)
"Insert a new empty regular file before point."
(interactive "*sFile name: ")
- (let* ((buffer (current-buffer))
- (index (or index (tar-current-position)))
+ (let* ((index (or index (tar-current-position)))
(d-list (and (not (zerop index))
(nthcdr (+ -1 index) tar-parse-info)))
(pos (if d-list
@@ -1069,7 +1059,7 @@ the current tar-entry."
With a prefix argument, mark that many files."
(interactive "p")
(beginning-of-line)
- (dotimes (i (abs p))
+ (dotimes (_ (abs p))
(if (tar-current-descriptor unflag) ; barf if we're not on an entry-line.
(progn
(delete-char 1)
@@ -1280,14 +1270,8 @@ for this to be permanent."
(defun tar-octal-time (timeval)
- ;; Format a timestamp as 11 octal digits. Ghod, I hope this works...
- (let ((hibits (car timeval)) (lobits (car (cdr timeval))))
- (format "%05o%01o%05o"
- (lsh hibits -2)
- (logior (lsh (logand 3 hibits) 1)
- (if (> (logand lobits 32768) 0) 1 0))
- (logand 32767 lobits)
- )))
+ ;; Format a timestamp as 11 octal digits.
+ (format "%011o" (encode-time timeval 'integer)))
(defun tar-subfile-save-buffer ()
"In tar subfile mode, save this buffer into its parent tar-file buffer.