Commit d338325c authored by Michael Albinus's avatar Michael Albinus
Browse files

Support for archive file names

* doc/misc/tramp.texi (Top, Usage): Add entry "Archive file names".
(History): Mention archive file names.
(GVFS based methods): Mentio "http" and "https" methods.
(Archive file names): New node.
(Frequently Asked Questions): Add Emacs 27 as supported version.

* etc/NEWS: Mention tramp-archive.el.

* lisp/net/tramp.el (tramp-run-real-handler)
(tramp-register-file-name-handlers)
(tramp-register-file-name-handlers, tramp-unload-file-name-handlers):
Add `tramp-archive-file-name-handler'.
(tramp-handle-file-name-completion): Do not insist in Tramp
file names.

* lisp/net/tramp-archive.el: New package.

* lisp/net/tramp-cache.el (tramp-dump-connection-properties): Check for
"archive" method.

* lisp/net/tramp-cmds.el (tramp-cleanup-all-connections): Cleanup also
local copies of archives.

* lisp/net/tramp-compat.el (tramp-compat-use-url-tramp-p): New defconst.

* lisp/net/tramp-gvfs.el (tramp-gvfs-methods): Add "http" and "https".
(tramp-gvfs-gio-mapping): Add "gvfs-mount".
(tramp-gvfs-handler-mounted-unmounted)
(tramp-gvfs-connection-mounted-p, tramp-gvfs-mount-spec):
Handle "uri" and "http".
(tramp-gvfs-unmount): New defun.

* test/lisp/net/tramp-archive-tests.el: New package.
parent 2ffdc041
......@@ -164,6 +164,7 @@ Using @value{tramp}
* Ad-hoc multi-hops:: Declaring multiple hops in the file name.
* Remote processes:: Integration with other Emacs packages.
* Cleanup remote connections:: Cleanup remote connections.
* Archive file names:: Access to files in file archives.
How file names, directories and localnames are mangled and managed
......@@ -407,7 +408,8 @@ since April 2007 (and removed in December 2016). GVFS integration
started in February 2009. Remote commands on MS Windows hosts since
September 2011. Ad-hoc multi-hop methods (with a changed syntax)
re-enabled in November 2011. In November 2012, added Juergen
Hoetzel's @file{tramp-adb.el}.
Hoetzel's @file{tramp-adb.el}. Archive file names are supported since
December 2017.
XEmacs support was stopped in January 2016. Since March 2017,
@value{tramp} syntax mandates a method.
......@@ -1134,7 +1136,10 @@ requires the SYNCE-GVFS plugin.
This user option is a list of external methods for GVFS@. By default,
this list includes @option{afp}, @option{dav}, @option{davs},
@option{gdrive}, @option{obex}, @option{sftp} and @option{synce}.
Other methods to include are: @option{ftp} and @option{smb}.
Other methods to include are @option{ftp}, @option{http},
@option{https} and @option{smb}. These methods are not intended to be
used directly as GVFS based method. Instead, they are added here for
the benefit of @ref{Archive file names}.
@end defopt
......@@ -2284,6 +2289,7 @@ is a feature of Emacs that may cause missed prompts when using
* Ad-hoc multi-hops:: Declaring multiple hops in the file name.
* Remote processes:: Integration with other Emacs packages.
* Cleanup remote connections:: Cleanup remote connections.
* Archive file names:: Access to files in file archives.
@end menu
......@@ -2913,6 +2919,209 @@ that remote connection.
@end deffn
@node Archive file names
@section Archive file names
@cindex file archives
@cindex archive file names
@cindex method archive
@cindex archive method
@value{tramp} offers also transparent access to files inside file
archives. This is possible only on machines which have installed the
virtual file system for the Gnome Desktop (GVFS), @ref{GVFS based
methods}. Internally, file archives are mounted via the GVFS
@option{archive} method.
A file archive is a regular file of kind @file{/path/to/dir/file.EXT}.
The extension @samp{.EXT} identifies the type of the file archive. A
file inside a file archive, called archive file name, has the name
@file{/path/to/dir/file.EXT/dir/file}.
Most of the @ref{Magic File Names, , magic file name operations,
elisp}, are implemented for archive file names, exceptions are all
operations which write into a file archive, and process related
operations. Therefore, functions like
@lisp
(copy-file "/path/to/dir/file.tar/dir/file" "/somewhere/else")
@end lisp
@noindent
work out of the box. This is also true for file name completion, and
for libraries like @code{dired} or @code{ediff}, which accept archive
file names as well.
@vindex tramp-archive-suffixes
File archives are identified by the file name extension @samp{.EXT}.
Since GVFS uses internally the library @code{libarchive(3)}, all
suffixes, which are accepted by this library, work also for archive
file names. Accepted suffixes are listed in the constant
@code{tramp-archive-suffixes}. They are
@itemize
@item @samp{.7z} ---
7-Zip archives
@cindex 7z, file archive suffix
@cindex file archive suffix 7z
@item @samp{.apk} ---
Android package kits
@cindex apk, file archive suffix
@cindex file archive suffix apk
@item @samp{.ar} ---
UNIX archiver formats
@cindex ar, file archive suffix
@cindex file archive suffix ar
@item @samp{.cab}, @samp{.CAB} ---
Microsoft Windows cabinets
@cindex cab, file archive suffix
@cindex CAB, file archive suffix
@cindex file archive suffix cab
@cindex file archive suffix CAB
@item @samp{.cpio} ---
CPIO archives
@cindex cpio, file archive suffix
@cindex file archive suffix cpio
@item @samp{.deb} ---
Debian packages
@cindex deb, file archive suffix
@cindex file archive suffix deb
@item @samp{.depot} ---
HP-UX SD depots
@cindex depot, file archive suffix
@cindex file archive suffix depot
@item @samp{.exe} ---
Self extracting Microsoft Windows EXE files
@cindex exe, file archive suffix
@cindex file archive suffix exe
@item @samp{.iso} ---
ISO 9660 images
@cindex iso, file archive suffix
@cindex file archive suffix iso
@item @samp{.jar} ---
Java archives
@cindex jar, file archive suffix
@cindex file archive suffix jar
@item @samp{.lzh}, @samp{LZH} ---
Microsoft Windows compressed LHA archives
@cindex lzh, file archive suffix
@cindex LZH, file archive suffix
@cindex file archive suffix lzh
@cindex file archive suffix LZH
@item @samp{.mtree} ---
BSD mtree format
@cindex mtree, file archive suffix
@cindex file archive suffix mtree
@item @samp{.pax} ---
Posix archives
@cindex pax, file archive suffix
@cindex file archive suffix pax
@item @samp{.rar} ---
RAR archives
@cindex rar, file archive suffix
@cindex file archive suffix rar
@item @samp{.rpm} ---
Red Hat packages
@cindex rpm, file archive suffix
@cindex file archive suffix rpm
@item @samp{.shar} ---
Shell archives
@cindex shar, file archive suffix
@cindex file archive suffix shar
@item @samp{.tar}, @samp{tbz}, @samp{tgz}, @samp{tlz}, @samp{txz} ---
(Compressed) tape archives
@cindex tar, file archive suffix
@cindex tbz, file archive suffix
@cindex tgz, file archive suffix
@cindex tlz, file archive suffix
@cindex txz, file archive suffix
@cindex file archive suffix tar
@cindex file archive suffix tbz
@cindex file archive suffix tgz
@cindex file archive suffix tlz
@cindex file archive suffix txz
@item @samp{.warc} ---
Web archives
@cindex warc, file archive suffix
@cindex file archive suffix warc
@item @samp{.xar} ---
macOS XAR archives
@cindex xar, file archive suffix
@cindex file archive suffix xar
@item @samp{.xps} ---
Open XML Paper Specification (OpenXPS) documents
@cindex xps, file archive suffix
@cindex file archive suffix xps
@item @samp{.zip}, @samp{.ZIP} ---
ZIP archives
@cindex zip, file archive suffix
@cindex ZIP, file archive suffix
@cindex file archive suffix zip
@cindex file archive suffix ZIP
@end itemize
@vindex tramp-archive-compression-suffixes
File archives could also be compressed, identified by an additional
compression suffix. Valid compression suffixes are listed in the
constant @code{tramp-archive-compression-suffixes}. They are
@samp{.bz2}, @samp{.gz}, @samp{.lrz}, @samp{.lz}, @samp{.lz4},
@samp{.lzma}, @samp{.lzo}, @samp{.uu}, @samp{.xz} and @samp{.Z}. A
valid archive file name would be
@file{/path/to/dir/file.tar.gz/dir/file}. Even several suffixes in a
row are possible, like @file{/path/to/dir/file.tar.gz.uu/dir/file}.
@vindex tramp-archive-all-gvfs-methods
An archive file name could be a remote file name, as in
@file{/ftp:anonymous@@ftp.gnu.org:/gnu/tramp/tramp-2.3.2.tar.gz/INSTALL}.
Since all file operations are mapped internally to GVFS operations,
remote file names supported by @code{tramp-gvfs} perform better,
because no local copy of the file archive must be downloaded first.
For example, @samp{/sftp:user@@host:...} performs better than the
similar @samp{/scp:user@@host:...}. See the constant
@code{tramp-archive-all-gvfs-methods} for a complete list of
@code{tramp-gvfs} supported method names.
If @code{url-handler-mode} is enabled, archives could be visited via
URLs, like @file{https://ftp.gnu.org/gnu/tramp/tramp-2.3.2.tar.gz/INSTALL}.
This allows complex file operations like
@lisp
@group
(ediff-directories
"https://ftp.gnu.org/gnu/tramp/tramp-2.3.1.tar.gz/tramp-2.3.1"
"https://ftp.gnu.org/gnu/tramp/tramp-2.3.2.tar.gz/tramp-2.3.2" "")
@end group
@end lisp
It is even possible to access file archives in file archives, as
@lisp
@group
(find-file
"http://ftp.debian.org/debian/pool/main/c/coreutils/coreutils_8.28-1_amd64.deb/control.tar.gz/control")
@end group
@end lisp
@node Bug Reports
@chapter Reporting Bugs and Problems
@cindex bug reports
......@@ -2997,7 +3206,8 @@ Where is the latest @value{tramp}?
@item
Which systems does it work on?
The package works successfully on Emacs 24, Emacs 25, and Emacs 26.
The package works successfully on Emacs 24, Emacs 25, Emacs 26, and
Emacs 27.
While Unix and Unix-like systems are the primary remote targets,
@value{tramp} has equal success connecting to other platforms, such as
......
......@@ -125,6 +125,12 @@ To restore the old behavior, use
* New Modes and Packages in Emacs 27.1
+++
** The package tramp-archive.el brings file name handler support for
file archives. It works on systems which support GVFS, which is
GNU/Linux, roughly spoken. See the chapter "(tramp) Archive file
names" in the Tramp manual for full documentation of these facilities.
* Incompatible Lisp Changes in Emacs 27.1
......
This diff is collapsed.
......@@ -384,6 +384,8 @@ used to cache connection properties of the local machine."
(maphash
(lambda (key value)
(if (and (tramp-file-name-p key) value
(not (string-equal
(tramp-file-name-method key) tramp-archive-method))
(not (tramp-file-name-localname key))
(not (gethash "login-as" value))
(not (gethash "started" value)))
......
......@@ -143,6 +143,9 @@ This includes password cache, file cache, connection cache, buffers."
;; Flush file and connection cache.
(clrhash tramp-cache-data)
;; Cleanup local copies of archives.
(tramp-archive-cleanup-hash)
;; Remove buffers.
(dolist (name (tramp-list-tramp-buffers))
(when (bufferp (get-buffer name)) (kill-buffer name))))
......
......@@ -190,11 +190,6 @@ This is a string of ten letters or dashes as in ls -l."
(if (get 'file-missing 'error-conditions) 'file-missing 'file-error)
"The error symbol for the `file-missing' error.")
(add-hook 'tramp-unload-hook
(lambda ()
(unload-feature 'tramp-loaddefs 'force)
(unload-feature 'tramp-compat 'force)))
;; `file-name-quoted-p', `file-name-quote' and `file-name-unquote' are
;; introduced in Emacs 26.
(eval-and-compile
......@@ -243,6 +238,17 @@ If NAME is a remote file name, the local part of NAME is unquoted."
`(cdr (mapcar 'car (cl-struct-slot-info 'tramp-file-name)))
`(cdr (mapcar 'car (get 'tramp-file-name 'cl-struct-slots)))))
;; The signature of `tramp-make-tramp-file-name' has been changed.
;; Therefore, we cannot us `url-tramp-convert-url-to-tramp' prior
;; Emacs 26.1. We use `temporary-file-directory' as indicator.
(defconst tramp-compat-use-url-tramp-p (fboundp 'temporary-file-directory)
"Whether to use url-tramp.el.")
(add-hook 'tramp-unload-hook
(lambda ()
(unload-feature 'tramp-loaddefs 'force)
(unload-feature 'tramp-compat 'force)))
(provide 'tramp-compat)
;;; TODO:
......
......@@ -54,10 +54,12 @@
;; device, if it hasn't been done already. There might be also some
;; few seconds delay in discovering available bluetooth devices.
;; Other possible connection methods are "ftp" and "smb". When one of
;; these methods is added to the list, the remote access for that
;; method is performed via GVFS instead of the native Tramp
;; implementation.
;; Other possible connection methods are "ftp", "http", "https" and
;; "smb". When one of these methods is added to the list, the remote
;; access for that method is performed via GVFS instead of the native
;; Tramp implementation. However, this is not recommended. These
;; methods are listed here for the benefit of file archives, see
;; tramp-archive.el.
;; GVFS offers even more connection methods. The complete list of
;; connection methods of the actual GVFS implementation can be
......@@ -119,6 +121,8 @@
(const "davs")
(const "ftp")
(const "gdrive")
(const "http")
(const "https")
(const "obex")
(const "sftp")
(const "smb")
......@@ -424,6 +428,7 @@ Every entry is a list (NAME ADDRESS).")
("gvfs-ls" . "list")
("gvfs-mkdir" . "mkdir")
("gvfs-monitor-file" . "monitor")
("gvfs-mount" . "mount")
("gvfs-move" . "move")
("gvfs-rm" . "remove")
("gvfs-trash" . "trash"))
......@@ -1455,6 +1460,8 @@ ADDRESS can have the form \"xx:xx:xx:xx:xx:xx\" or \"[xx:xx:xx:xx:xx:xx]\"."
(cadr (assoc "port" (cadr mount-spec)))))
(ssl (tramp-gvfs-dbus-byte-array-to-string
(cadr (assoc "ssl" (cadr mount-spec)))))
(uri (tramp-gvfs-dbus-byte-array-to-string
(cadr (assoc "uri" (cadr mount-spec)))))
(prefix (concat
(tramp-gvfs-dbus-byte-array-to-string
(car mount-spec))
......@@ -1469,6 +1476,12 @@ ADDRESS can have the form \"xx:xx:xx:xx:xx:xx\" or \"[xx:xx:xx:xx:xx:xx]\"."
(setq method "davs"))
(when (string-equal "google-drive" method)
(setq method "gdrive"))
(when (and (string-equal "http" method) (stringp uri))
(setq uri (url-generic-parse-url uri)
method (url-type uri)
user (url-user uri)
host (url-host uri)
port (url-portspec uri)))
(with-parsed-tramp-file-name
(tramp-make-tramp-file-name method user domain host port "") nil
(tramp-message
......@@ -1537,6 +1550,8 @@ ADDRESS can have the form \"xx:xx:xx:xx:xx:xx\" or \"[xx:xx:xx:xx:xx:xx]\"."
(cadr (assoc "port" (cadr mount-spec)))))
(ssl (tramp-gvfs-dbus-byte-array-to-string
(cadr (assoc "ssl" (cadr mount-spec)))))
(uri (tramp-gvfs-dbus-byte-array-to-string
(cadr (assoc "uri" (cadr mount-spec)))))
(prefix (concat
(tramp-gvfs-dbus-byte-array-to-string
(car mount-spec))
......@@ -1554,6 +1569,12 @@ ADDRESS can have the form \"xx:xx:xx:xx:xx:xx\" or \"[xx:xx:xx:xx:xx:xx]\"."
(setq method "gdrive"))
(when (and (string-equal "synce" method) (zerop (length user)))
(setq user (or (tramp-file-name-user vec) "")))
(when (and (string-equal "http" method) (stringp uri))
(setq uri (url-generic-parse-url uri)
method (url-type uri)
user (url-user uri)
host (url-host uri)
port (url-portspec uri)))
(when (and
(string-equal method (tramp-file-name-method vec))
(string-equal user (tramp-file-name-user vec))
......@@ -1570,6 +1591,16 @@ ADDRESS can have the form \"xx:xx:xx:xx:xx:xx\" or \"[xx:xx:xx:xx:xx:xx]\"."
vec "default-location" default-location)
(throw 'mounted t)))))))
(defun tramp-gvfs-unmount (vec)
"Unmount the object identified by VEC."
(let ((vec (copy-tramp-file-name vec)))
(setf (tramp-file-name-localname vec) "/"
(tramp-file-name-hop vec) nil)
(when (tramp-gvfs-connection-mounted-p vec)
(tramp-gvfs-send-command
vec "gvfs-mount" "-u"
(tramp-gvfs-url-file-name (tramp-make-tramp-file-name vec))))))
(defun tramp-gvfs-mount-spec-entry (key value)
"Construct a mount-spec entry to be used in a mount_spec.
It was \"a(say)\", but has changed to \"a{sv})\"."
......@@ -1611,7 +1642,14 @@ It was \"a(say)\", but has changed to \"a{sv})\"."
((string-equal "gdrive" method)
(list (tramp-gvfs-mount-spec-entry "type" "google-drive")
(tramp-gvfs-mount-spec-entry "host" host)))
(t
((string-match "\\`http" method)
(list (tramp-gvfs-mount-spec-entry "type" "http")
(tramp-gvfs-mount-spec-entry
"uri"
(url-recreate-url
(url-parse-make-urlobj
method user nil host port "/" nil nil t)))))
(t
(list (tramp-gvfs-mount-spec-entry "type" method)
(tramp-gvfs-mount-spec-entry "host" host))))
,@(when user
......@@ -2033,6 +2071,8 @@ They are retrieved from the hal daemon."
;;; TODO:
;; * (Customizable) unmount when exiting Emacs. See tramp-archive.el.
;; * Host name completion for existing mount points (afp-server,
;; smb-server) or via smb-network.
;;
......
......@@ -2064,6 +2064,7 @@ pass to the OPERATION."
`(tramp-file-name-handler
tramp-vc-file-name-handler
tramp-completion-file-name-handler
tramp-archive-file-name-handler
cygwin-mount-name-hook-function
cygwin-mount-map-drive-hook-function
.
......@@ -2369,12 +2370,14 @@ remote file names."
;; loading of Tramp.
(dolist (fnh '(tramp-file-name-handler
tramp-completion-file-name-handler
tramp-archive-file-name-handler
tramp-autoload-file-name-handler))
(let ((a1 (rassq fnh file-name-handler-alist)))
(setq file-name-handler-alist (delq a1 file-name-handler-alist))))
;; Add the handlers. We do not add anything to the `operations'
;; property of `tramp-file-name-handler', this shall be done by the
;; property of `tramp-file-name-handler' and
;; `tramp-archive-file-name-handler', this shall be done by the
;; respective foreign handlers.
(add-to-list 'file-name-handler-alist
(cons tramp-file-name-regexp 'tramp-file-name-handler))
......@@ -2388,6 +2391,11 @@ remote file names."
(put 'tramp-completion-file-name-handler 'operations
(mapcar 'car tramp-completion-file-name-handler-alist))
(add-to-list 'file-name-handler-alist
(cons tramp-archive-file-name-regexp
'tramp-archive-file-name-handler))
(put 'tramp-archive-file-name-handler 'safe-magic t)
;; If jka-compr or epa-file are already loaded, move them to the
;; front of `file-name-handler-alist'.
(dolist (fnh '(epa-file-handler jka-compr-handler))
......@@ -2441,6 +2449,7 @@ Add operations defined in `HANDLER-alist' to `tramp-file-name-handler'."
"Unload Tramp file name handlers from `file-name-handler-alist'."
(dolist (fnh '(tramp-file-name-handler
tramp-completion-file-name-handler
tramp-archive-file-name-handler
tramp-autoload-file-name-handler))
(let ((a1 (rassq fnh file-name-handler-alist)))
(setq file-name-handler-alist (delq a1 file-name-handler-alist))))))
......@@ -3100,10 +3109,6 @@ User is always nil."
(defun tramp-handle-file-name-completion
(filename directory &optional predicate)
"Like `file-name-completion' for Tramp files."
(unless (tramp-tramp-file-p directory)
(error
"tramp-handle-file-name-completion invoked on non-tramp directory `%s'"
directory))
(let (hits-ignored-extensions)
(or
(try-completion
......
foo.txt
\ No newline at end of file
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment