*** empty log message ***
[bpt/emacs.git] / lisp / tar-mode.el
index 576d8be..2c755fd 100644 (file)
@@ -356,6 +356,7 @@ MODE should be an integer which is a file mode value."
                  ((eq type 5) ?d)      ; directory
                  ((eq type 6) ?p)      ; FIFO/pipe
                  ((eq type 20) ?*)     ; directory listing
+                 ((eq type 28) ?L)     ; next has longname
                  ((eq type 29) ?M)     ; multivolume continuation
                  ((eq type 35) ?S)     ; sparse
                  ((eq type 38) ?V)     ; volume header
@@ -374,7 +375,7 @@ MODE should be an integer which is a file mode value."
              ""))))
 
 (defun tar-untar-buffer ()
-  "Extract all archive members in the tar-file."
+  "Extract all archive members in the tar-file into the current directory."
   (interactive)
   (let ((multibyte enable-multibyte-characters))
     (unwind-protect
@@ -385,13 +386,16 @@ MODE should be an integer which is a file mode value."
            (let* ((tokens (tar-desc-tokens descriptor))
                   (name (tar-header-name tokens))
                   (dir (file-name-directory name))
-                  (start (+ (tar-desc-data-start descriptor) tar-header-offset -1))
+                  (start (+ (tar-desc-data-start descriptor)
+                            (- tar-header-offset (point-min))))
                   (end (+ start (tar-header-size tokens))))
-             (message "Extracting %s" name)
-             (if (and dir (not (file-exists-p dir)))
-                 (make-directory dir t))
-             (write-region start end name)
-             (set-file-modes name (tar-header-mode tokens)))))
+             (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)
+                 (write-region start end name))
+               (set-file-modes name (tar-header-mode tokens))))))
       (set-buffer-multibyte multibyte))))
 
 (defun tar-summarize-buffer ()
@@ -402,7 +406,7 @@ is visible (and the real data of the buffer is hidden)."
   (set-buffer-multibyte nil)
   (message "Parsing tar file...")
   (let* ((result '())
-        (pos 1)
+        (pos (point-min))
         (bs (max 1 (- (buffer-size) 1024))) ; always 2+ empty blocks at end.
         (bs100 (max 1 (/ bs 100)))
         tokens)
@@ -461,7 +465,7 @@ is visible (and the real data of the buffer is hidden)."
        (insert total-summaries))
       (make-local-variable 'tar-header-offset)
       (setq tar-header-offset (point))
-      (narrow-to-region 1 tar-header-offset)
+      (narrow-to-region (point-min) tar-header-offset)
       (if enable-multibyte-characters
          (setq tar-header-offset (position-bytes tar-header-offset)))
       (set-buffer-modified-p nil))))
@@ -580,7 +584,7 @@ See also: variables `tar-update-datestamp' and `tar-anal-blocksize'.
   (set (make-local-variable 'write-contents-hooks) '(tar-mode-write-file))
   (widen)
   (if (and (boundp 'tar-header-offset) tar-header-offset)
-      (narrow-to-region 1 (byte-to-position tar-header-offset))
+      (narrow-to-region (point-min) (byte-to-position tar-header-offset))
     (tar-summarize-buffer)
     (tar-next-line 0)))
 
@@ -593,24 +597,23 @@ appear on disk when you save the tar-file's buffer."
   (interactive "P")
   (or (and (boundp 'tar-superior-buffer) tar-superior-buffer)
       (error "This buffer is not an element of a tar file"))
-;;; Don't do this, because it is redundant and wastes mode line space.
-;;;  (or (assq 'tar-subfile-mode minor-mode-alist)
-;;;      (setq minor-mode-alist (append minor-mode-alist
-;;;                                 (list '(tar-subfile-mode " TarFile")))))
+  ;; Don't do this, because it is redundant and wastes mode line space.
+  ;;  (or (assq 'tar-subfile-mode minor-mode-alist)
+  ;;      (setq minor-mode-alist (append minor-mode-alist
+  ;;                                (list '(tar-subfile-mode " TarFile")))))
   (make-local-variable 'tar-subfile-mode)
   (setq tar-subfile-mode
        (if (null p)
            (not tar-subfile-mode)
            (> (prefix-numeric-value p) 0)))
   (cond (tar-subfile-mode
-        (make-local-variable 'local-write-file-hooks)
-        (setq local-write-file-hooks '(tar-subfile-save-buffer))
+        (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)
         (run-hooks 'tar-subfile-mode-hook))
        (t
-        (kill-local-variable 'local-write-file-hooks))))
+        (remove-hook 'write-file-functions 'tar-subfile-save-buffer t))))
 
 
 ;; Revert the buffer and recompute the dired-like listing.
@@ -660,6 +663,7 @@ appear on disk when you save the tar-file's buffer."
        (error "This is a %s, not a real file"
               (cond ((eq link-p 5) "directory")
                     ((eq link-p 20) "tar directory header")
+                    ((eq link-p 28) "next has longname")
                     ((eq link-p 29) "multivolume-continuation")
                     ((eq link-p 35) "sparse entry")
                     ((eq link-p 38) "volume header")
@@ -688,7 +692,8 @@ appear on disk when you save the tar-file's buffer."
         (tokens (tar-desc-tokens descriptor))
         (name (tar-header-name tokens))
         (size (tar-header-size tokens))
-        (start (+ (tar-desc-data-start descriptor) tar-header-offset -1))
+        (start (+ (tar-desc-data-start descriptor)
+                  (- tar-header-offset (point-min))))
         (end (+ start size)))
     (let* ((tar-buffer (current-buffer))
           (tar-buffer-multibyte enable-multibyte-characters)
@@ -734,7 +739,8 @@ appear on disk when you save the tar-file's buffer."
                                           name (- (point-max) (point)))))))
                      (multibyte enable-multibyte-characters)
                      (detected (detect-coding-region
-                                1 (min 16384 (point-max)) t)))
+                                (point-min)
+                                (min (+ (point-min) 16384) (point-max)) t)))
                  (if coding
                      (or (numberp (coding-system-eol-type coding))
                          (setq coding (coding-system-change-eol-conversion
@@ -755,7 +761,7 @@ appear on disk when you save the tar-file's buffer."
                      (setq coding
                            (coding-system-change-text-conversion
                             coding 'raw-text)))
-                 (decode-coding-region 1 (point-max) coding)
+                 (decode-coding-region (point-min) (point-max) coding)
                  (set-buffer-file-coding-system coding))
                ;; Set the default-directory to the dir of the
                ;; superior buffer. 
@@ -773,7 +779,7 @@ appear on disk when you save the tar-file's buffer."
                (set-buffer-modified-p nil)
                (tar-subfile-mode 1))
              (set-buffer tar-buffer))
-         (narrow-to-region 1 tar-header-offset)
+         (narrow-to-region (point-min) tar-header-offset)
          (set-buffer-multibyte tar-buffer-multibyte)))
       (if view-p
          (view-buffer buffer (and just-created 'kill-buffer))
@@ -829,7 +835,8 @@ the current tar-entry."
         (tokens (tar-desc-tokens descriptor))
         (name (tar-header-name tokens))
         (size (tar-header-size tokens))
-        (start (+ (tar-desc-data-start descriptor) tar-header-offset -1))
+        (start (+ (tar-desc-data-start descriptor)
+                  (- tar-header-offset (point-min))))
         (end (+ start size))
         (multibyte enable-multibyte-characters)
         (inhibit-file-name-handlers inhibit-file-name-handlers)
@@ -920,7 +927,7 @@ With a prefix argument, un-mark that many files backward."
          (tar-setf (tar-desc-data-start desc)
                    (- (tar-desc-data-start desc) data-length))))
       ))
-  (narrow-to-region 1 tar-header-offset))
+  (narrow-to-region (point-min) tar-header-offset))
 
 
 (defun tar-expunge (&optional noconfirm)
@@ -942,7 +949,7 @@ for this to be permanent."
                (forward-line 1)))
          ;; after doing the deletions, add any padding that may be necessary.
          (tar-pad-to-blocksize)
-         (narrow-to-region 1 tar-header-offset))
+         (narrow-to-region (point-min) tar-header-offset))
        (set-buffer-multibyte multibyte)
        (if (zerop n)
            (message "Nothing to expunge.")
@@ -1082,7 +1089,7 @@ for this to be permanent."
                (buffer-substring start (+ start 512))
                chk (tar-header-name tokens))
              )))
-      (narrow-to-region 1 tar-header-offset)
+      (narrow-to-region (point-min) tar-header-offset)
       (set-buffer-multibyte multibyte)
       (tar-next-line 0))))
 
@@ -1090,11 +1097,12 @@ 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))))
-    (insert (format "%05o%01o%05o"
-                   (lsh hibits -2)
-                   (logior (lsh (logand 3 hibits) 1) (> (logand lobits 32768) 0))
-                   (logand 32767 lobits)
-                   ))))
+    (format "%05o%01o%05o"
+           (lsh hibits -2)
+           (logior (lsh (logand 3 hibits) 1)
+                   (if (> (logand lobits 32768) 0) 1 0))
+           (logand 32767 lobits)
+           )))
 
 (defun tar-subfile-save-buffer ()
   "In tar subfile mode, save this buffer into its parent tar-file buffer.
@@ -1131,7 +1139,7 @@ to make your changes permanent."
        (widen)
        (set-buffer-multibyte nil)
        ;; delete the old data...
-       (let* ((data-start (+ start tar-header-offset -1))
+       (let* ((data-start (+ start (- tar-header-offset (point-min))))
               (data-end (+ data-start (ash (ash (+ size 511) -9) 9))))
          (delete-region data-start data-end)
          ;; insert the new data...
@@ -1200,7 +1208,7 @@ to make your changes permanent."
              )))
        ;; after doing the insertion, add any final padding that may be necessary.
        (tar-pad-to-blocksize))
-       (narrow-to-region 1 tar-header-offset)
+       (narrow-to-region (point-min) tar-header-offset)
        (set-buffer-multibyte tar-buffer-multibyte)))
     (set-buffer-modified-p t)   ; mark the tar file as modified
     (tar-next-line 0)
@@ -1263,7 +1271,7 @@ Leaves the region wide."
                        buffer-file-name nil t))
        (tar-clear-modification-flags)
        (set-buffer-modified-p nil))
-    (narrow-to-region 1 (byte-to-position tar-header-offset)))
+    (narrow-to-region (point-min) (byte-to-position tar-header-offset)))
   ;; Return t because we've written the file.
   t)
 \f