]> git.eshelyaron.com Git - emacs.git/commitdiff
Add support for squashfs files in archive mode
authorRuthra Kumar <ruthrab@gmail.com>
Fri, 23 Oct 2020 11:02:55 +0000 (13:02 +0200)
committerLars Ingebrigtsen <larsi@gnus.org>
Fri, 23 Oct 2020 12:54:31 +0000 (14:54 +0200)
* lisp/arc-mode.el (archive-squashfs-extract): New variable
(bug#43827).
(archive-find-type): Identify squashfs.
(archive-squashfs-summarize, archive-squashfs-extract-by-stdout):
New functions to parse/extract squashfs.

* lisp/files.el (auto-mode-alist): Add squashfs.

etc/NEWS
lisp/arc-mode.el
lisp/files.el
lisp/international/mule.el

index 9e8182a2daea3e5aebf057284c67443ed4a1f58d..11c19b378a69101995cbc2d06245f3d7b0819526 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -308,6 +308,9 @@ and variables.
 
 ** Archive mode
 
+---
+*** Archive Mode can now parse .squashfs files.
+
 *** Can now modify members of 'ar' archives.
 
 *** Display of summaries unified between backends.
index eb62a8511832eb1afc7bc3dacc14cea717f00dee..ce0c061fc09a1224e3419e09d8c871ededed87c5 100644 (file)
 ;; ARCHIVE TYPES: Currently only the archives below are handled, but the
 ;; structure for handling just about anything is in place.
 ;;
-;;                     Arc     Lzh     Zip     Zoo     Rar     7z      Ar
-;;                     --------------------------------------------------
-;; View listing                Intern  Intern  Intern  Intern  Y       Y       Y
-;; Extract member      Y       Y       Y       Y       Y       Y       Y
-;; Save changed member Y       Y       Y       Y       N       Y       Y
-;; Add new member      N       N       N       N       N       N       N
-;; Delete member       Y       Y       Y       Y       N       Y       N
-;; Rename member       Y       Y       N       N       N       N       N
-;; Chmod               -       Y       Y       -       N       N       N
-;; Chown               -       Y       -       -       N       N       N
-;; Chgrp               -       Y       -       -       N       N       N
+;;                     Arc     Lzh     Zip     Zoo     Rar     7z      Ar      Squashfs
+;;                     ---------------------------------------------------------------
+;; View listing                Intern  Intern  Intern  Intern  Y       Y       Y       Y
+;; Extract member      Y       Y       Y       Y       Y       Y       Y       Y
+;; Save changed member Y       Y       Y       Y       N       Y       Y       N
+;; Add new member      N       N       N       N       N       N       N       N
+;; Delete member       Y       Y       Y       Y       N       Y       N       N
+;; Rename member       Y       Y       N       N       N       N       N       N
+;; Chmod               -       Y       Y       -       N       N       N       N
+;; Chown               -       Y       -       -       N       N       N       N
+;; Chgrp               -       Y       -       -       N       N       N       N
 ;;
 ;; Special thanks to Bill Brodie <wbrodie@panix.com> for very useful tips
 ;; on the first released version of this package.
@@ -370,6 +370,24 @@ file.  Archive and member name will be added."
                       :inline t
                       (string :format "%v"))))
 
+;; ------------------------------
+;; Squashfs archive configuration
+
+(defgroup archive-squashfs nil
+  "Squashfs-specific options to archive."
+  :group 'archive)
+
+(defcustom archive-squashfs-extract '("rdsquashfs" "-c")
+  "Program and its options to run in order to extract a squashsfs file member.
+Extraction should happen to standard output.  Archive and member name will
+be added."
+  :type '(list (string :tag "Program")
+              (repeat :tag "Options"
+                      :inline t
+                      (string :format "%v")))
+  :version "28.1"
+  :group 'archive-squashfs)
+
 ;; -------------------------------------------------------------------------
 ;;; Section: Variables
 
@@ -741,6 +759,7 @@ archive.
                 (re-search-forward "Rar!" (+ (point) 100000) t))
            'rar-exe)
          ((looking-at "7z\274\257\047\034") '7z)
+          ((looking-at "hsqs") 'squashfs)
          (t (error "Buffer format not recognized")))))
 ;; -------------------------------------------------------------------------
 
@@ -2280,6 +2299,85 @@ NAME is expected to be the 16-bytes part of an ar record."
    descr
    '("ar" "r")))
 
+;; -------------------------------------------------------------------------
+;;; Section Squashfs archives.
+
+(defun archive-squashfs-summarize (&optional file)
+  (unless file
+    (setq file buffer-file-name))
+  (let ((copy (file-local-copy file))
+        (files ()))
+    (with-temp-buffer
+      (call-process "unsquashfs" nil t nil "-ll" (or file copy))
+      (when copy
+        (delete-file copy))
+      (goto-char (point-min))
+      (search-forward-regexp "[drwxl\\-]\\{10\\}")
+      (beginning-of-line)
+      (while (looking-at (concat
+                          "^\\(.[rwx\\-]\\{9\\}\\) " ;Mode
+                          "\\(.+\\)/\\(.+\\) "       ;user/group
+                          "\\(.+\\) "                ;size
+                          "\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\) " ;date
+                          "\\([0-9]\\{2\\}:[0-9]\\{2\\}\\) " ;time
+                          "\\(.+\\)\n"))                     ;Filename
+        (let* ((name (match-string 7))
+               (flags (match-string 1))
+               (uid (match-string 2))
+               (gid (match-string 3))
+               (size (string-to-number (match-string 4)))
+               (date (match-string 5))
+               (time (match-string 6))
+               (date-time)
+               (mode))
+          ;; Only list directory and regular files
+          (when (or (eq (aref flags 0) ?d)
+                    (eq (aref flags 0) ?-))
+            (when (equal name "squashfs-root")
+              (setf name "/"))
+            ;; Remove 'squashfs-root/' from filenames.
+            (setq name (string-replace "squashfs-root/" "" name))
+            (setq date-time (concat date " " time))
+            (setq mode (logior
+                        (cond
+                         ((eq (aref flags 0) ?d) #o40000)
+                         (t 0))
+                        ;; Convert symbolic to octal representation.
+                        (file-modes-symbolic-to-number
+                         (concat
+                          "u=" (string-replace "-" "" (substring flags 1 4))
+                          ",g=" (string-replace "-" "" (substring flags 4 7))
+                          ",o=" (string-replace "-" ""
+                                                (substring flags 7 10))))))
+            (push (archive--file-desc name name mode size
+                                      date-time :uid uid :gid gid)
+                  files)))
+        (goto-char (match-end 0))))
+    (archive--summarize-descs (nreverse files))))
+
+(defun archive-squashfs-extract-by-stdout (archive name command
+                                                   &optional stderr-test)
+  (let ((stderr-file (make-temp-file "arc-stderr")))
+    (unwind-protect
+       (prog1
+           (apply #'call-process
+                  (car command)
+                  nil
+                  (if stderr-file (list t stderr-file) t)
+                  nil
+                  (append (cdr command) (list name archive)))
+         (with-temp-buffer
+           (insert-file-contents stderr-file)
+           (goto-char (point-min))
+           (when (if (stringp stderr-test)
+                     (not (re-search-forward stderr-test nil t))
+                   (> (buffer-size) 0))
+             (message "%s" (buffer-string)))))
+      (if (file-exists-p stderr-file)
+          (delete-file stderr-file)))))
+
+(defun archive-squashfs-extract (archive name)
+  (archive-squashfs-extract-by-stdout archive name archive-squashfs-extract))
 
 ;; -------------------------------------------------------------------------
 ;; This line was a mistake; it is kept now for compatibility.
index bbc8f881590559aaf93b02e40ebf8c0a2a1f7e29..fdf758ad927180b5da9720c4eb738c12f3b6c112 100644 (file)
@@ -2758,8 +2758,8 @@ since only a single case-insensitive search through the alist is made."
      ;; The list of archive file extensions should be in sync with
      ;; `auto-coding-alist' with `no-conversion' coding system.
      ("\\.\\(\
-arc\\|zip\\|lzh\\|lha\\|zoo\\|[jew]ar\\|xpi\\|rar\\|cbr\\|7z\\|\
-ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|CBR\\|7Z\\)\\'" . archive-mode)
+arc\\|zip\\|lzh\\|lha\\|zoo\\|[jew]ar\\|xpi\\|rar\\|cbr\\|7z\\|squashfs\\|\
+ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|CBR\\|7Z\\|SQUASHFS\\)\\'" . archive-mode)
      ("\\.oxt\\'" . archive-mode) ;(Open|Libre)Office extensions.
      ("\\.\\(deb\\|[oi]pk\\)\\'" . archive-mode) ; Debian/Opkg packages.
      ;; Mailer puts message to be edited in
index 2af64de77b5b2d6b231c453b0890f11243c3dccd..ad9c3a230666105b278dba6513358ce9611ea58b 100644 (file)
@@ -1710,8 +1710,8 @@ in-place."
   ;; self-extracting exe archives.
   (mapcar (lambda (arg) (cons (purecopy (car arg)) (cdr arg)))
          '(("\\.\\(\
-arc\\|zip\\|lzh\\|lha\\|zoo\\|[jew]ar\\|xpi\\|rar\\|7z\\|\
-ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|7Z\\)\\'"
+arc\\|zip\\|lzh\\|lha\\|zoo\\|[jew]ar\\|xpi\\|rar\\|7z\\|squashfs\\|\
+ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|7Z\\|SQUASHFS\\)\\'"
      . no-conversion-multibyte)
     ("\\.\\(exe\\|EXE\\)\\'" . no-conversion)
     ("\\.\\(sx[dmicw]\\|odt\\|tar\\|t[bg]z\\)\\'" . no-conversion)