]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix visiting zip archives inside tar archives
authorEli Zaretskii <eliz@gnu.org>
Mon, 20 May 2024 12:29:39 +0000 (15:29 +0300)
committerEshel Yaron <me@eshelyaron.com>
Thu, 23 May 2024 08:28:04 +0000 (10:28 +0200)
* lisp/tar-mode.el (tar-archive-from-tar): New local variable.
(tar-extract): Set it non-nil for an extracted member that happens
to be arc-mode archive.
* lisp/arc-mode.el (tar-archive-from-tar): Defvar it.
(archive-unique-fname): Make sure FNAME can be created in DIR,
even if FNAME is provided as an absolute file name (this happens
if the archive is a member of a Tar archive, for example).
(archive-extract): Set 'archive-remote' for archives that were
extracted from Tar archives.  (Bug#70987)

(cherry picked from commit 45916eadaed1b7f3a02df62a25bc851a838b6309)

lisp/arc-mode.el
lisp/tar-mode.el

index 9a8dd6679e32955fbb4b2f4ffc61f40eaf7b3269..bf9def681c33a40663627109a72e1f8b41029ac3 100644 (file)
@@ -563,6 +563,8 @@ Its value is an `archive--file-desc'.")
 (defvar-local archive-files nil
   "Vector of `archive--file-desc' objects.")
 
+(defvar tar-archive-from-tar nil)
+
 ;; -------------------------------------------------------------------------
 ;;; Section: Support functions.
 
@@ -754,7 +756,8 @@ archive.
        ;; on local filesystem.  Treat such archives as remote.
        (or archive-remote
            (setq archive-remote
-                 (or (string-match archive-remote-regexp (buffer-file-name))
+                 (or tar-archive-from-tar ; was included in a tar archive
+                      (string-match archive-remote-regexp (buffer-file-name))
                      (string-match file-name-invalid-regexp
                                    (buffer-file-name)))))
 
@@ -920,6 +923,9 @@ If FNAME can be uniquely created in DIR, it is returned unaltered.
 If FNAME is something our underlying filesystem can't grok, or if another
 file by that name already exists in DIR, a unique new name is generated
 using `make-temp-file', and the generated name is returned."
+  (if (file-name-absolute-p fname)
+      ;; We need a file name relative to the filesystem root.
+      (setq fname (substring fname (1+ (string-search "/" fname)))))
   (let ((fullname (expand-file-name fname dir))
        (alien (string-match file-name-invalid-regexp fname))
        (tmpfile
@@ -1179,6 +1185,9 @@ NEW-NAME."
          (buffer (get-buffer bufname))
          (just-created nil)
         (file-name-coding archive-file-name-coding-system))
+      (or archive-remote
+          (and (local-variable-p 'tar-archive-from-tar)
+               (setq archive-remote tar-archive-from-tar)))
       (if (and buffer
               (string= (buffer-file-name buffer) arcfilename))
           nil
index 375191a816775c772aabadf3275674af97198c79..7278bee48d45f44b09b9cd3d27007ebddd651e2c 100644 (file)
@@ -135,6 +135,10 @@ This information is useful, but it takes screen space away from file names."
 (put 'tar-superior-buffer 'permanent-local t)
 (put 'tar-superior-descriptor 'permanent-local t)
 
+(defvar tar-archive-from-tar nil
+  "Non-nil if an arc-mode archive file is a member of a tar archive.")
+(put tar-archive-from-tar 'permanent-local t)
+
 ;; The Tar data is made up of bytes and better manipulated as bytes
 ;; and can be very large, so insert/delete can be costly.  The summary we
 ;; want to display may contain non-ascii chars, of course, so we'd like it
@@ -1124,6 +1128,8 @@ return nil.  Otherwise point is returned."
                 default-directory))
         (set-buffer-modified-p nil)
         (normal-mode)                   ; pick a mode.
+        (when (derived-mode-p 'archive-mode)
+          (setq-local tar-archive-from-tar t))
         (setq-local tar-superior-buffer tar-buffer)
         (setq-local tar-superior-descriptor descriptor)
         (setq buffer-read-only read-only-p)