From ae5602c51c721196922620b263a490137bba7fe0 Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Sat, 1 Nov 2014 14:34:45 +0100 Subject: [PATCH] Backport Tramp changes from trunk. * net/tramp-adb.el (tramp-adb-sh-fix-ls-output): Use `bolp'. (tramp-adb-handle-write-region): Improve messages. (tramp-adb-maybe-open-connection): Don't set `tramp-current-*' variables. * net/tramp-cache.el (tramp-flush-file-function): Simplify check. Suppress debug messages. * net/tramp-ftp.el (top): Remove special handling for URL syntax. (tramp-ftp-file-name-handler): * net/tramp-gvfs.el (tramp-gvfs-methods) : Add. (tramp-gvfs-methods-mounttracker) (tramp-gvfs-mountlocation-signature): Check `tramp-gvfs-enabled' during initialization. (tramp-gvfs-handle-delete-file): Flush file properties, not directory properties. (tramp-gvfs-handle-file-attributes): Use `string-to-number' when reading "unix::mode". (tramp-gvfs-handle-file-name-all-completions): Use "-h" option for "gvfs-ls". (tramp-gvfs-url-file-name): Apply `cons' where appropriate. `user' and `localname' could be nil. (tramp-gvfs-send-command): Simplify traces. * net/tramp-sh.el (vc-handled-backends, vc-bzr-program) (vc-git-program, vc-hg-program): Declare. (tramp-methods) : Remove. It has never worked satisfactorily. (tramp-methods) : Add new method. (tramp-methods) : Redirect stderr to "/dev/null". (tramp-methods) : Improve `tramp-login-args'. (tramp-default-user-alist): Add "nc". (top): Remove completion function for "sftp". Add completion functions for "nc" and "psftp". (tramp-sh-handle-set-visited-file-modtime): (tramp-sh-handle-verify-visited-file-modtime): Use `point-at-eol'. (tramp-do-copy-or-rename-file-out-of-band): Use cached "remote-copy-args" value, if available. (Bug#18199) Tweak docstring. Implement support for "nc" method. (tramp-sh-handle-expand-file-name, tramp-local-coding-commands) (tramp-remote-coding-commands, tramp-call-local-coding-command): Tweak docstring. (tramp-sh-handle-start-file-process): Expand `default-directory'. (tramp-sh-handle-write-region): Tweak error message. (tramp-sh-handle-vc-registered): Remove backends when the remote binary does not exist. (tramp-open-connection-setup-interactive-shell): Prefer utf-8 coding. (Bug#17859) (tramp-find-inline-encoding): Do not raise an error. (tramp-make-copy-program-file-name): Tweak docstring. Handle also the "nc" case. Quote result also locally. (tramp-get-remote-id): Check also for "gid". (tramp-get-remote-python): * net/tramp-smb.el (tramp-smb-handle-copy-directory) (tramp-smb-handle-set-file-acl): Use `start-process'. (tramp-smb-handle-insert-directory): Use progress reporter. (tramp-smb-handle-rename-file): Flush also file properties of FILENAME. * net/tramp.el (tramp-methods): Tweak docstring. (tramp-file-name-handler): Apply `cons' where appropriate. (tramp-handle-file-accessible-directory-p): Check for `file-readable-p' instead of `file-executable-p'. (tramp-handle-shell-command): Use `display-buffer'. (Bug#18326) (tramp-handle-unhandled-file-name-directory): Return "/". (tramp-check-cached-permissions): Use `tramp-compat-file-attributes'. (tramp-call-process): Add new argument VEC. Adapt callees in all tramp*.el files. * net/trampver.el: Update release number. --- lisp/ChangeLog | 108 ++++++++++++ lisp/net/tramp-adb.el | 18 +- lisp/net/tramp-cache.el | 22 ++- lisp/net/tramp-ftp.el | 18 +- lisp/net/tramp-gvfs.el | 53 +++--- lisp/net/tramp-sh.el | 370 ++++++++++++++++++++++++++-------------- lisp/net/tramp-smb.el | 191 +++++++++++---------- lisp/net/tramp.el | 81 +++++---- lisp/net/trampver.el | 6 +- 9 files changed, 550 insertions(+), 317 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index f3d6f6cb446..2577f7fe02f 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,111 @@ +2014-11-01 Michael Albinus + + Backport Tramp changes from trunk. + + * net/tramp.el (tramp-methods): Tweak docstring. + (tramp-file-name-handler): Apply `cons' where appropriate. + (tramp-handle-file-accessible-directory-p): Check for + `file-readable-p' instead of `file-executable-p'. + (tramp-handle-shell-command): Use `display-buffer'. (Bug#18326) + (tramp-handle-unhandled-file-name-directory): Return "/". + (tramp-check-cached-permissions): + Use `tramp-compat-file-attributes'. + (tramp-call-process): Add new argument VEC. Adapt callees in all + tramp*.el files. + + * net/tramp-adb.el (tramp-adb-sh-fix-ls-output): Use `bolp'. + (tramp-adb-handle-write-region): Improve messages. + (tramp-adb-maybe-open-connection): Don't set + `tramp-current-*' variables. + + * net/tramp-cache.el (tramp-flush-file-function): Simplify check. + Suppress debug messages. + + * net/tramp-ftp.el (top): Remove special handling for URL syntax. + (tramp-ftp-file-name-handler): + + * net/tramp-gvfs.el (tramp-gvfs-methods) : Add. + (tramp-gvfs-methods-mounttracker) + (tramp-gvfs-mountlocation-signature): Check `tramp-gvfs-enabled' + during initialization. (Bug#18774) + (tramp-gvfs-handle-delete-file): Flush file properties, not + directory properties. + (tramp-gvfs-handle-file-attributes): Use `string-to-number' when + reading "unix::mode". + (tramp-gvfs-handle-file-name-all-completions): + Use "-h" option for "gvfs-ls". + (tramp-gvfs-url-file-name): Apply `cons' where appropriate. + `user' and `localname' could be nil. + (tramp-gvfs-send-command): Simplify traces. + + * net/tramp-sh.el (vc-handled-backends, vc-bzr-program) + (vc-git-program, vc-hg-program): Declare. + (tramp-methods) : Remove. It has never worked satisfactorily. + (tramp-methods) : Add new method. + (tramp-methods) : Redirect stderr to "/dev/null". + (tramp-methods) : Improve + `tramp-login-args'. + (tramp-default-user-alist): Add "nc". + (top): Remove completion function for "sftp". Add completion + functions for "nc" and "psftp". + (tramp-sh-handle-set-visited-file-modtime): + (tramp-sh-handle-verify-visited-file-modtime): Use `point-at-eol'. + (tramp-do-copy-or-rename-file-out-of-band): + Use cached "remote-copy-args" value, if available. (Bug#18199) + Tweak docstring. Implement support for "nc" method. + (tramp-sh-handle-expand-file-name, tramp-local-coding-commands) + (tramp-remote-coding-commands, tramp-call-local-coding-command): + Tweak docstring. + (tramp-sh-handle-start-file-process): Expand `default-directory'. + (tramp-sh-handle-write-region): Tweak error message. + (tramp-sh-handle-vc-registered): Remove backends when the remote + binary does not exist. + (tramp-open-connection-setup-interactive-shell): + Prefer utf-8 coding. (Bug#17859) + (tramp-find-inline-encoding): Do not raise an error. + (tramp-make-copy-program-file-name): Tweak docstring. Handle also + the "nc" case. Quote result also locally. + (tramp-get-remote-id): Check also for "gid". + (tramp-get-remote-python): + + * net/tramp-smb.el (tramp-smb-handle-copy-directory) + (tramp-smb-handle-set-file-acl): Use `start-process'. + (tramp-smb-handle-insert-directory): Use progress reporter. + (tramp-smb-handle-rename-file): Flush also file properties of + FILENAME. + + * net/trampver.el: Update release number. + +2014-11-01 Reuben Thomas + + * net/tramp.el (tramp-handle-file-symlink-p): + * net/tramp-ftp.el (tramp-ftp-file-name-handler): Remove a comment + about VMS, which we no longer support. + +2014-11-01 Stefan Monnier + + * net/tramp-sh.el (tramp-sh-handle-vc-registered): Don't modify + the global vc-handled-backends (bug#18535). + +2014-11-01 Jérémy Compostella + Michael Albinus + + * net/tramp-sh.el (tramp-open-connection-setup-interactive-shell): + Reduce the amount of set environment variable commands. + +2014-11-01 Paul Eggert + + * net/tramp-sh.el (tramp-get-remote-touch): Omit unnecessary call to + current-time. + +2014-11-01 Emilio C. Lopes + + * net/tramp-sh.el (tramp-get-remote-python): Also search for + executables named "python2" or "python3". + (tramp-get-remote-uid-with-python): Use parentheses around + arguments to `print' to make it compatible with Python 3. + (tramp-get-remote-gid-with-python): Ditto. (Bug#18118) + 2014-10-31 Stefan Monnier * simple.el (newline): Add assertions to try and help catch bug#18913. diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index 3d41750a92d..88e52fe0199 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -458,9 +458,7 @@ Emacs dired can't find files." (insert " " (mapconcat 'identity sorted-lines "\n "))) ;; Add final newline. (goto-char (point-max)) - (unless (= (point) (line-beginning-position)) - (insert "\n")))) - + (unless (bolp) (insert "\n")))) (defun tramp-adb-ls-output-time-less-p (a b) "Sort \"ls\" output by time, descending." @@ -609,10 +607,10 @@ But handle the case, if the \"test\" command is not available." 'write-region (list start end tmpfile append 'no-message lockname confirm)) (with-tramp-progress-reporter - v 3 (format "Moving tmp file %s to %s" tmpfile filename) + v 3 (format "Moving tmp file `%s' to `%s'" tmpfile filename) (unwind-protect (when (tramp-adb-execute-adb-command v "push" tmpfile localname) - (tramp-error v 'file-error "Cannot write: `%s' filename")) + (tramp-error v 'file-error "Cannot write: `%s'" filename)) (delete-file tmpfile))) (when (or (eq visit t) (stringp visit)) @@ -998,7 +996,8 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (with-temp-buffer (prog1 (unless - (zerop (apply 'tramp-call-process tramp-adb-program nil t nil args)) + (zerop + (apply 'tramp-call-process vec tramp-adb-program nil t nil args)) (buffer-string)) (tramp-message vec 6 "%s" (buffer-string))))) @@ -1031,7 +1030,7 @@ This happens for Android >= 4.0." (defun tramp-adb-send-command-and-check (vec command) - "Run COMMAND and and check its exit status. + "Run COMMAND and check its exit status. Sends `echo $?' along with the COMMAND for checking the exit status. If COMMAND is nil, just sends `echo $?'. Returns the exit status found." (tramp-adb-send-command @@ -1107,10 +1106,7 @@ connection if a previous connection has died for some reason." (and p (processp p) (memq (process-status p) '(run open))) (save-match-data (when (and p (processp p)) (delete-process p)) - (setq tramp-current-method (tramp-file-name-method vec) - tramp-current-user (tramp-file-name-user vec) - tramp-current-host (tramp-file-name-host vec) - devices (mapcar 'cadr (tramp-adb-parse-device-names nil))) + (setq devices (mapcar 'cadr (tramp-adb-parse-device-names nil))) (if (not devices) (tramp-error vec 'file-error "No device connected")) (if (and (> (length host) 0) (not (member host devices))) diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el index be66f18d9e4..056b1bdaf91 100644 --- a/lisp/net/tramp-cache.el +++ b/lisp/net/tramp-cache.el @@ -201,15 +201,21 @@ Remove also properties of all files in subdirectories." ;; Reverting or killing a buffer should also flush file properties. ;; They could have been changed outside Tramp. In eshell, "ls" would ;; not show proper directory contents when a file has been copied or -;; deleted before. +;; deleted before. We must apply `save-match-data', because it would +;; corrupt other packages otherwise (reported from org). (defun tramp-flush-file-function () - "Flush all Tramp cache properties from `buffer-file-name'." - (let ((bfn (if (stringp (buffer-file-name)) - (buffer-file-name) - default-directory))) - (when (tramp-tramp-file-p bfn) - (with-parsed-tramp-file-name bfn nil - (tramp-flush-file-property v localname))))) + "Flush all Tramp cache properties from `buffer-file-name'. +This is suppressed for temporary buffers." + (save-match-data + (unless (or (null (buffer-name)) + (string-match "^\\( \\|\\*\\)" (buffer-name))) + (let ((bfn (if (stringp (buffer-file-name)) + (buffer-file-name) + default-directory)) + (tramp-verbose 0)) + (when (tramp-tramp-file-p bfn) + (with-parsed-tramp-file-name bfn nil + (tramp-flush-file-property v localname))))))) (add-hook 'before-revert-hook 'tramp-flush-file-function) (add-hook 'eshell-pre-command-hook 'tramp-flush-file-function) diff --git a/lisp/net/tramp-ftp.el b/lisp/net/tramp-ftp.el index dc84a524ba0..a723e57f296 100644 --- a/lisp/net/tramp-ftp.el +++ b/lisp/net/tramp-ftp.el @@ -120,17 +120,6 @@ present for backward compatibility." tramp-ftp-method '((tramp-parse-netrc "~/.netrc")))) -;; If there is URL syntax, `substitute-in-file-name' needs special -;; handling. -(put 'substitute-in-file-name 'ange-ftp 'tramp-handle-substitute-in-file-name) -(add-hook 'tramp-ftp-unload-hook - (lambda () - (setplist 'substitute-in-file-name - (delete 'ange-ftp - (delete 'tramp-handle-substitute-in-file-name - (symbol-plist - 'substitute-in-file-name)))))) - ;;;###tramp-autoload (defun tramp-ftp-file-name-handler (operation &rest args) "Invoke the Ange-FTP handler for OPERATION. @@ -189,12 +178,7 @@ pass to the OPERATION." (ignore-errors (delete-file tmpfile))))) ;; Normally, the handlers must be discarded. - ;; `inhibit-file-name-handlers' isn't sufficient, because the - ;; local file name could be in Tramp syntax as well (for - ;; example, returning VMS file names like "/DISK$CAM:/AAA"). - ;; That's why we set also `tramp-mode' to nil. - (t (let* (;(tramp-mode nil) - (inhibit-file-name-handlers + (t (let* ((inhibit-file-name-handlers (list 'tramp-file-name-handler 'tramp-completion-file-name-handler (and (eq inhibit-file-name-operation operation) diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index 52189e091fb..1b4c1694a92 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el @@ -49,14 +49,14 @@ ;; The customer option `tramp-gvfs-methods' contains the list of ;; supported connection methods. Per default, these are "dav", -;; "davs", "obex" and "synce". Note that with "obex" it might be -;; necessary to pair with the other bluetooth device, if it hasn't +;; "davs", "obex", "sftp" and "synce". Note that with "obex" it might +;; be necessary to pair with the other bluetooth 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", "sftp" 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 +;; 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. ;; GVFS offers even more connection methods. The complete list of @@ -110,7 +110,7 @@ (require 'custom)) ;;;###tramp-autoload -(defcustom tramp-gvfs-methods '("dav" "davs" "obex" "synce") +(defcustom tramp-gvfs-methods '("dav" "davs" "obex" "sftp" "synce") "List of methods for remote files, accessed with GVFS." :group 'tramp :version "23.2" @@ -167,9 +167,10 @@ ;; Introspection data exist since GVFS 1.14. If there are no such ;; data, we expect an earlier interface. (defconst tramp-gvfs-methods-mounttracker - (dbus-introspect-get-method-names - :session tramp-gvfs-service-daemon tramp-gvfs-path-mounttracker - tramp-gvfs-interface-mounttracker) + (and tramp-gvfs-enabled + (dbus-introspect-get-method-names + :session tramp-gvfs-service-daemon tramp-gvfs-path-mounttracker + tramp-gvfs-interface-mounttracker)) "The list of supported methods of the mount tracking interface.") (defconst tramp-gvfs-listmounts @@ -187,9 +188,10 @@ It has been changed in GVFS 1.14.") It has been changed in GVFS 1.14.") (defconst tramp-gvfs-mountlocation-signature - (dbus-introspect-get-signature - :session tramp-gvfs-service-daemon tramp-gvfs-path-mounttracker - tramp-gvfs-interface-mounttracker tramp-gvfs-mountlocation) + (and tramp-gvfs-enabled + (dbus-introspect-get-signature + :session tramp-gvfs-service-daemon tramp-gvfs-path-mounttracker + tramp-gvfs-interface-mounttracker tramp-gvfs-mountlocation)) "The D-Bus signature of the \"mountLocation\" method. It has been changed in GVFS 1.14.") @@ -661,7 +663,7 @@ is no information where to trace the message.") "Like `delete-file' for Tramp files." (with-parsed-tramp-file-name filename nil (tramp-flush-file-property v (file-name-directory localname)) - (tramp-flush-directory-property v localname) + (tramp-flush-file-property v localname) (unless (tramp-gvfs-send-command v (if (and trash delete-by-moving-to-trash) "gvfs-trash" "gvfs-rm") @@ -794,7 +796,8 @@ is no information where to trace the message.") (goto-char (point-min)) (setq res-filemodes (if (re-search-forward "unix::mode:\\s-+\\([0-9]+\\)" nil t) - (tramp-file-mode-from-int (match-string 1)) + (tramp-file-mode-from-int + (string-to-number (match-string 1))) (if dirp "drwx------" "-rwx------"))) ;; ... inode and device (goto-char (point-min)) @@ -899,7 +902,7 @@ is no information where to trace the message.") entry) ;; Get a list of directories and files. (tramp-gvfs-send-command - v "gvfs-ls" (tramp-gvfs-url-file-name directory)) + v "gvfs-ls" "-h" (tramp-gvfs-url-file-name directory)) ;; Now grab the output. (with-temp-buffer @@ -1107,7 +1110,7 @@ is no information where to trace the message.") (defun tramp-gvfs-url-file-name (filename) "Return FILENAME in URL syntax." ;; "/" must NOT be hexlified. - (let ((url-unreserved-chars (append '(?/) url-unreserved-chars)) + (let ((url-unreserved-chars (cons ?/ url-unreserved-chars)) result) (setq result @@ -1118,9 +1121,9 @@ is no information where to trace the message.") (setq user (concat (match-string 2 user) ";" (match-string 1 user)))) (url-parse-make-urlobj - method (url-hexify-string user) nil + method (and user (url-hexify-string user)) nil (tramp-file-name-real-host v) (tramp-file-name-port v) - (url-hexify-string localname) nil nil t)) + (and localname (url-hexify-string localname)) nil nil t)) (url-parse-make-urlobj "file" nil nil nil nil (url-hexify-string (file-truename filename)) nil nil t)))) @@ -1555,14 +1558,10 @@ connection if a previous connection has died for some reason." "Send the COMMAND with its ARGS to connection VEC. COMMAND is usually a command from the gvfs-* utilities. `call-process' is applied, and it returns `t' if the return code is zero." - (let (result) - (with-current-buffer (tramp-get-connection-buffer vec) - (tramp-gvfs-maybe-open-connection vec) - (erase-buffer) - (tramp-message vec 6 "%s %s" command (mapconcat 'identity args " ")) - (setq result (apply 'tramp-call-process command nil t nil args)) - (tramp-message vec 6 "\n%s" (buffer-string)) - (zerop result)))) + (with-current-buffer (tramp-get-connection-buffer vec) + (tramp-gvfs-maybe-open-connection vec) + (erase-buffer) + (zerop (apply 'tramp-call-process vec command nil t nil args)))) ;; D-Bus BLUEZ functions. @@ -1671,7 +1670,7 @@ be used." (list user host))) (zeroconf-list-services "_webdav._tcp"))) -;; Add completion function for DAV and DAVS methods. +;; Add completion function for SFTP, DAV and DAVS methods. (when (and tramp-gvfs-enabled (member zeroconf-service-avahi (dbus-list-known-names :system))) (zeroconf-init tramp-gvfs-zeroconf-domain) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 6f55b86e9e5..1976e0e7f66 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -35,6 +35,10 @@ (defvar directory-sep-char) (defvar tramp-gw-tunnel-method) (defvar tramp-gw-socks-method) +(defvar vc-handled-backends) +(defvar vc-bzr-program) +(defvar vc-git-program) +(defvar vc-hg-program) (defcustom tramp-inline-compress-start-size 4096 "The minimum size of compressing where inline transfer. @@ -141,17 +145,6 @@ detected as prompt when being sent on echoing hosts, therefore.") ("-o" "StrictHostKeyChecking=no"))) (tramp-default-port 22))) ;;;###tramp-autoload -(add-to-list 'tramp-methods - '("sftp" - (tramp-login-program "ssh") - (tramp-login-args (("-l" "%u") ("-p" "%p") ("%c") - ("-e" "none") ("%h"))) - (tramp-async-args (("-q"))) - (tramp-remote-shell "/bin/sh") - (tramp-remote-shell-args ("-c")) - (tramp-copy-program "sftp") - (tramp-copy-args ("%c")))) - ;;;###tramp-autoload (add-to-list 'tramp-methods '("rsync" (tramp-login-program "ssh") @@ -210,11 +203,27 @@ detected as prompt when being sent on echoing hosts, therefore.") (add-to-list 'tramp-methods '("telnet" (tramp-login-program "telnet") - (tramp-login-args (("%h") ("%p"))) + (tramp-login-args (("%h") ("%p") ("2>/dev/null"))) (tramp-remote-shell "/bin/sh") (tramp-remote-shell-args ("-c")) (tramp-default-port 23))) ;;;###tramp-autoload +(add-to-list 'tramp-methods + '("nc" + (tramp-login-program "telnet") + (tramp-login-args (("%h") ("%p") ("2>/dev/null"))) + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) + (tramp-copy-program "nc") + ;; We use "-v" for better error tracking. + (tramp-copy-args (("-w" "1") ("-v") ("%h") ("%r"))) + (tramp-remote-copy-program "nc") + ;; We use "-p" as required for newer busyboxes. For older + ;; busybox/nc versions, the value must be (("-l") ("%r")). This + ;; can be achieved by tweaking `tramp-connection-properties'. + (tramp-remote-copy-args (("-l") ("-p" "%r"))) + (tramp-default-port 23))) +;;;###tramp-autoload (add-to-list 'tramp-methods '("su" (tramp-login-program "su") @@ -249,9 +258,16 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-remote-shell-args ("-c")))) ;;;###tramp-autoload (add-to-list 'tramp-methods - '("plink" + `("plink" (tramp-login-program "plink") - (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%h"))) + ;; ("%h") must be a single element, see `tramp-compute-multi-hops'. + (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("-t") + ("%h") ("\"") + (,(format + "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'" + tramp-terminal-type + tramp-initial-end-of-output)) + ("/bin/sh") ("\""))) (tramp-remote-shell "/bin/sh") (tramp-remote-shell-args ("-c")) (tramp-default-port 22))) @@ -259,21 +275,25 @@ detected as prompt when being sent on echoing hosts, therefore.") (add-to-list 'tramp-methods `("plinkx" (tramp-login-program "plink") - ;; ("%h") must be a single element, see - ;; `tramp-compute-multi-hops'. - (tramp-login-args (("-load") ("%h") ("-t") + (tramp-login-args (("-load") ("%h") ("-t") ("\"") (,(format "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'" tramp-terminal-type tramp-initial-end-of-output)) - ("/bin/sh"))) + ("/bin/sh") ("\""))) (tramp-remote-shell "/bin/sh") (tramp-remote-shell-args ("-c")))) ;;;###tramp-autoload (add-to-list 'tramp-methods - '("pscp" + `("pscp" (tramp-login-program "plink") - (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%h"))) + (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("-t") + ("%h") ("\"") + (,(format + "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'" + tramp-terminal-type + tramp-initial-end-of-output)) + ("/bin/sh") ("\""))) (tramp-remote-shell "/bin/sh") (tramp-remote-shell-args ("-c")) (tramp-copy-program "pscp") @@ -284,9 +304,15 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-default-port 22))) ;;;###tramp-autoload (add-to-list 'tramp-methods - '("psftp" + `("psftp" (tramp-login-program "plink") - (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%h"))) + (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("-t") + ("%h") ("\"") + (,(format + "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'" + tramp-terminal-type + tramp-initial-end-of-output)) + ("/bin/sh") ("\""))) (tramp-remote-shell "/bin/sh") (tramp-remote-shell-args ("-c")) (tramp-copy-program "pscp") @@ -319,7 +345,8 @@ detected as prompt when being sent on echoing hosts, therefore.") (add-to-list 'tramp-default-user-alist `(,(concat "\\`" - (regexp-opt '("rcp" "remcp" "rsh" "telnet" "krlogin" "fcp")) + (regexp-opt + '("rcp" "remcp" "rsh" "telnet" "nc" "krlogin" "fcp")) "\\'") nil ,(user-login-name))) @@ -370,7 +397,6 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-set-completion-function "remcp" tramp-completion-function-alist-rsh) (tramp-set-completion-function "scp" tramp-completion-function-alist-ssh) (tramp-set-completion-function "scpx" tramp-completion-function-alist-ssh) - (tramp-set-completion-function "sftp" tramp-completion-function-alist-ssh) (tramp-set-completion-function "rsync" tramp-completion-function-alist-ssh) (tramp-set-completion-function "rsh" tramp-completion-function-alist-rsh) (tramp-set-completion-function "remsh" tramp-completion-function-alist-rsh) @@ -378,6 +404,7 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-set-completion-function "sshx" tramp-completion-function-alist-ssh) (tramp-set-completion-function "telnet" tramp-completion-function-alist-telnet) + (tramp-set-completion-function "nc" tramp-completion-function-alist-telnet) (tramp-set-completion-function "su" tramp-completion-function-alist-su) (tramp-set-completion-function "sudo" tramp-completion-function-alist-su) (tramp-set-completion-function "ksu" tramp-completion-function-alist-su) @@ -387,6 +414,7 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-set-completion-function "plinkx" tramp-completion-function-alist-putty) (tramp-set-completion-function "pscp" tramp-completion-function-alist-ssh) + (tramp-set-completion-function "psftp" tramp-completion-function-alist-ssh) (tramp-set-completion-function "fcp" tramp-completion-function-alist-ssh))) ;; "getconf PATH" yields: @@ -1239,8 +1267,7 @@ target of the symlink differ." (format "%s -ild %s" (tramp-get-ls-command v) (tramp-shell-quote-argument localname))) - (setq attr (buffer-substring (point) - (progn (end-of-line) (point))))) + (setq attr (buffer-substring (point) (point-at-eol)))) (tramp-set-file-property v localname "visited-file-modtime-ild" attr)) (when (boundp 'last-coding-system-used) @@ -1291,8 +1318,7 @@ of." (tramp-get-ls-command v) (tramp-shell-quote-argument localname))) (with-current-buffer (tramp-get-buffer v) - (setq attr (buffer-substring - (point) (progn (end-of-line) (point))))) + (setq attr (buffer-substring (point) (point-at-eol)))) (equal attr (tramp-get-file-property @@ -1346,7 +1372,7 @@ of." ;; We are local, so we don't need the UTC settings. (zerop (tramp-call-process - "touch" nil nil nil "-t" + nil "touch" nil nil nil "-t" (format-time-string "%Y%m%d%H%M.%S" time) (tramp-shell-quote-argument filename))))) @@ -1380,7 +1406,7 @@ be non-negative integers." (let ((uid (or (and (natnump uid) uid) (tramp-get-local-uid 'integer))) (gid (or (and (natnump gid) gid) (tramp-get-local-gid 'integer)))) (tramp-call-process - "chown" nil nil nil + nil "chown" nil nil nil (format "%d:%d" uid gid) (tramp-shell-quote-argument filename)))))) (defun tramp-remote-selinux-p (vec) @@ -1542,7 +1568,7 @@ be non-negative integers." (defun tramp-sh-handle-file-directory-p (filename) "Like `file-directory-p' for Tramp files." (with-parsed-tramp-file-name filename nil - ;; `file-directory-p' is used as predicate for filename completion. + ;; `file-directory-p' is used as predicate for file name completion. ;; Sometimes, when a connection is not established yet, it is ;; desirable to return t immediately for "/method:foo:". It can ;; be expected that this is always a directory. @@ -1644,10 +1670,10 @@ be non-negative integers." vec (format (concat - ;; We must care about filenames with spaces, or starting with + ;; We must care about file names with spaces, or starting with ;; "-"; this would confuse xargs. "ls -aQ" might be a solution, ;; but it does not work on all remote systems. Therefore, we - ;; quote the filenames via sed. + ;; quote the file names via sed. "cd %s; echo \"(\"; (%s -a | sed -e s/\\$/\\\"/g -e s/^/\\\"/g | " "xargs %s -c " "'(\"%%n\" (\"%%N\") %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 \"%%A\" t %%ie0 -1)'" @@ -1670,15 +1696,15 @@ be non-negative integers." (mapcar 'list (or - ;; Try cache entries for filename, filename with last - ;; character removed, filename with last two characters + ;; Try cache entries for `filename', `filename' with last + ;; character removed, `filename' with last two characters ;; removed, ..., and finally the empty string - all ;; concatenated to the local directory name. (let ((remote-file-name-inhibit-cache (or remote-file-name-inhibit-cache tramp-completion-reread-directory-timeout))) - ;; This is inefficient for very long filenames, pity + ;; This is inefficient for very long file names, pity ;; `reduce' is not available... (car (apply @@ -1742,7 +1768,7 @@ be non-negative integers." (tramp-shell-quote-argument localname) (tramp-get-ls-command v) ;; When `filename' is empty, just `ls' without - ;; filename argument is more efficient than `ls *' + ;; `filename' argument is more efficient than `ls *' ;; for very large directories and might avoid the ;; `Argument list too long' error. ;; @@ -1981,7 +2007,7 @@ file names." ;; create a new buffer, insert the contents of the ;; source file into it, then write out the buffer to ;; the target file. The advantage is that it doesn't - ;; matter which filename handlers are used for the + ;; matter which file name handlers are used for the ;; source and target file. (t (tramp-do-copy-or-rename-file-via-buffer @@ -2212,19 +2238,19 @@ the uid and gid from FILENAME." (set-file-modes newname file-modes)))))) (defun tramp-do-copy-or-rename-file-out-of-band (op filename newname keep-date) - "Invoke rcp program to copy. + "Invoke `scp' program to copy. The method used must be an out-of-band method." (let* ((t1 (tramp-tramp-file-p filename)) (t2 (tramp-tramp-file-p newname)) (orig-vec (tramp-dissect-file-name (if t1 filename newname))) - copy-program copy-args copy-env copy-keep-date port spec - options source target) + copy-program copy-args copy-env copy-keep-date port listener spec + options source target remote-copy-program remote-copy-args) (with-parsed-tramp-file-name (if t1 filename newname) nil (if (and t1 t2) ;; Both are Tramp files. We shall optimize it when the - ;; methods for filename and newname are the same. + ;; methods for FILENAME and NEWNAME are the same. (let* ((dir-flag (file-directory-p filename)) (tmpfile (tramp-compat-make-temp-file localname dir-flag))) (if dir-flag @@ -2285,6 +2311,13 @@ The method used must be an out-of-band method." (setq user (or (tramp-file-name-user v) (tramp-get-connection-property v "login-as" nil))) + ;; Check for listener port. + (when (tramp-get-method-parameter method 'tramp-remote-copy-args) + (setq listener (number-to-string (+ 50000 (random 10000)))) + (while + (zerop (tramp-call-process v "nc" nil nil nil "-z" host listener)) + (setq listener (number-to-string (+ 50000 (random 10000)))))) + ;; Compose copy command. (setq host (or host "") user (or user "") @@ -2297,12 +2330,13 @@ The method used must be an out-of-band method." tramp-ssh-controlmaster-options "") spec) spec (format-spec-make - ?h host ?u user ?p port ?c options + ?h host ?u user ?p port ?r listener ?c options ?k (if keep-date " " "")) copy-program (tramp-get-method-parameter method 'tramp-copy-program) copy-keep-date (tramp-get-method-parameter method 'tramp-copy-keep-date) + copy-args (delete ;; " " has either been a replacement of "%k" (when @@ -2318,6 +2352,7 @@ The method used must be an out-of-band method." copy-args (let ((y (mapcar (lambda (z) (format-spec z spec)) x))) (if (member "" y) '(" ") y)))))) + copy-env (delq nil @@ -2325,12 +2360,54 @@ The method used must be an out-of-band method." (lambda (x) (setq x (mapcar (lambda (y) (format-spec y spec)) x)) (unless (member "" x) (mapconcat 'identity x " "))) - (tramp-get-method-parameter method 'tramp-copy-env)))) + (tramp-get-method-parameter method 'tramp-copy-env))) + + remote-copy-program + (tramp-get-method-parameter method 'tramp-remote-copy-program)) - ;; Check for program. + (dolist + (x + (or + (tramp-get-connection-property v "remote-copy-args" nil) + (tramp-get-method-parameter method 'tramp-remote-copy-args))) + (setq remote-copy-args + (append + remote-copy-args + (let ((y (mapcar (lambda (z) (format-spec z spec)) x))) + (if (member "" y) '(" ") y))))) + + ;; Check for local copy program. (unless (executable-find copy-program) (tramp-error - v 'file-error "Cannot find copy program: %s" copy-program)) + v 'file-error "Cannot find local copy program: %s" copy-program)) + + ;; Install listener on the remote side. The prompt must be + ;; consumed later on, when the process does not listen anymore. + (when remote-copy-program + (unless (with-tramp-connection-property + v (concat "remote-copy-program-" remote-copy-program) + (tramp-find-executable + v remote-copy-program (tramp-get-remote-path v))) + (tramp-error + v 'file-error + "Cannot find remote listener: %s" remote-copy-program)) + (setq remote-copy-program + (mapconcat + 'identity + (append + (list remote-copy-program) remote-copy-args + (list (if t1 (concat "<" source) (concat ">" target)) "&")) + " ")) + (tramp-send-command v remote-copy-program) + (with-timeout + (1 (tramp-error + v 'file-error + "Listener process not running on remote host: `%s'" + remote-copy-program)) + (tramp-send-command v (format "netstat -l | grep -q :%s" listener)) + (while (not (tramp-send-command-and-check v nil)) + (tramp-send-command + v (format "netstat -l | grep -q :%s" listener))))) (with-temp-buffer (unwind-protect @@ -2347,24 +2424,26 @@ The method used must be an out-of-band method." (tramp-message orig-vec 6 "%s=\"%s\"" (car copy-env) (cadr copy-env)) (setenv (pop copy-env) (pop copy-env))) + (setq + copy-args + (append + copy-args + (if remote-copy-program + (list (if t1 (concat ">" target) (concat "<" source))) + (list source target)))) ;; Use an asynchronous process. By this, password can - ;; be handled. The default directory must be local, in - ;; order to apply the correct `copy-program'. We don't - ;; set a timeout, because the copying of large files can - ;; last longer than 60 secs. - (let ((p (let ((default-directory - (tramp-compat-temporary-file-directory))) - (apply 'start-process-shell-command - (tramp-get-connection-name v) - (tramp-get-connection-buffer v) - copy-program - (append - copy-args - (list - source target - "&&" "echo" "tramp_exit_status" "0" - "||" "echo" "tramp_exit_status" "1")))))) + ;; be handled. We don't set a timeout, because the + ;; copying of large files can last longer than 60 + ;; secs. + (let ((p (apply 'start-process-shell-command + (tramp-get-connection-name v) + (tramp-get-connection-buffer v) + copy-program + (append + copy-args + (list "&&" "echo" "tramp_exit_status" "0" + "||" "echo" "tramp_exit_status" "1"))))) (tramp-message orig-vec 6 "%s" (mapconcat 'identity (process-command p) " ")) @@ -2391,7 +2470,14 @@ The method used must be an out-of-band method." ;; Reset the transfer process properties. (tramp-set-connection-property v "process-name" nil) - (tramp-set-connection-property v "process-buffer" nil))) + (tramp-set-connection-property v "process-buffer" nil) + ;; Clear the remote prompt. + (when (and remote-copy-program + (not (tramp-send-command-and-check v nil))) + ;; Houston, we have a problem! Likely, the listener is + ;; still running, so let's clear everything (but the + ;; cached password). + (tramp-cleanup-connection v 'keep-debug 'keep-password)))) ;; Handle KEEP-DATE argument. (when (and keep-date (not copy-keep-date)) @@ -2621,7 +2707,8 @@ This is like `dired-recursive-delete-directory' for Tramp files." (delete-region (match-beginning 0) (point))) ;; Some busyboxes are reluctant to discard colors. - (unless (string-match "color" (tramp-get-connection-property v "ls" "")) + (unless + (string-match "color" (tramp-get-connection-property v "ls" "")) (goto-char beg) (while (re-search-forward tramp-color-escape-sequence-regexp nil t) (replace-match ""))) @@ -2651,9 +2738,9 @@ This is like `dired-recursive-delete-directory' for Tramp files." (defun tramp-sh-handle-expand-file-name (name &optional dir) "Like `expand-file-name' for Tramp files. -If the localname part of the given filename starts with \"/../\" then -the result will be a local, non-Tramp, filename." - ;; If DIR is not given, use DEFAULT-DIRECTORY or "/". +If the localname part of the given file name starts with \"/../\" then +the result will be a local, non-Tramp, file name." + ;; If DIR is not given, use `default-directory' or "/". (setq dir (or dir default-directory "/")) ;; Unless NAME is absolute, concat DIR and NAME. (unless (file-name-absolute-p name) @@ -2724,7 +2811,7 @@ the result will be a local, non-Tramp, filename." ;; connection has been setup. (defun tramp-sh-handle-start-file-process (name buffer program &rest args) "Like `start-file-process' for Tramp files." - (with-parsed-tramp-file-name default-directory nil + (with-parsed-tramp-file-name (expand-file-name default-directory) nil (let* (;; When PROGRAM matches "*sh", and the first arg is "-c", ;; it might be that the arguments exceed the command line ;; length. Therefore, we modify the command. @@ -3133,7 +3220,7 @@ the result will be a local, non-Tramp, filename." (symbol-value 'last-coding-system-used)))) ;; The permissions of the temporary file should be set. If - ;; filename does not exist (eq modes nil) it has been + ;; FILENAME does not exist (eq modes nil) it has been ;; renamed to the backup file. This case `save-buffer' ;; handles permissions. ;; Ensure that it is still readable. @@ -3144,7 +3231,7 @@ the result will be a local, non-Tramp, filename." ;; This is a bit lengthy due to the different methods ;; possible for file transfer. First, we check whether the - ;; method uses an rcp program. If so, we call it. + ;; method uses an scp program. If so, we call it. ;; Otherwise, both encoding and decoding command must be ;; specified. However, if the method _also_ specifies an ;; encoding function, then that is used for encoding the @@ -3238,7 +3325,7 @@ the result will be a local, non-Tramp, filename." (erase-buffer) (and ;; cksum runs locally, if possible. - (zerop (tramp-call-process "cksum" tmpfile t)) + (zerop (tramp-call-process v "cksum" tmpfile t)) ;; cksum runs remotely. (tramp-send-command-and-check v @@ -3264,7 +3351,7 @@ the result will be a local, non-Tramp, filename." (tramp-error v 'file-error (concat "Method `%s' should specify both encoding and " - "decoding command or an rcp program") + "decoding command or an scp program") method)))) ;; Make `last-coding-system-used' have the right value. @@ -3281,7 +3368,7 @@ the result will be a local, non-Tramp, filename." (when (or (eq visit t) (stringp visit)) (let ((file-attr (tramp-compat-file-attributes filename 'integer))) (set-visited-file-modtime - ;; We must pass modtime explicitly, because filename can + ;; We must pass modtime explicitly, because FILENAME can ;; be different from (buffer-file-name), f.e. if ;; `file-precious-flag' is set. (nth 5 file-attr)) @@ -3369,7 +3456,28 @@ the result will be a local, non-Tramp, filename." ;; calls shall be answered from the file cache. We unset ;; `process-file-side-effects' and `remote-file-name-inhibit-cache' ;; in order to keep the cache. - (let (remote-file-name-inhibit-cache process-file-side-effects) + (let ((vc-handled-backends vc-handled-backends) + remote-file-name-inhibit-cache process-file-side-effects) + ;; Reduce `vc-handled-backends' in order to minimize process calls. + (when (and (memq 'Bzr vc-handled-backends) + (boundp 'vc-bzr-program) + (not (with-tramp-connection-property v vc-bzr-program + (tramp-find-executable + v vc-bzr-program (tramp-get-remote-path v))))) + (setq vc-handled-backends (remq 'Bzr vc-handled-backends))) + (when (and (memq 'Git vc-handled-backends) + (boundp 'vc-git-program) + (not (with-tramp-connection-property v vc-git-program + (tramp-find-executable + v vc-git-program (tramp-get-remote-path v))))) + (setq vc-handled-backends (remq 'Git vc-handled-backends))) + (when (and (memq 'Hg vc-handled-backends) + (boundp 'vc-hg-program) + (not (with-tramp-connection-property v vc-hg-program + (tramp-find-executable + v vc-hg-program (tramp-get-remote-path v))))) + (setq vc-handled-backends (remq 'Hg vc-handled-backends))) + ;; Run. (ignore-errors (tramp-run-real-handler 'vc-registered (list file)))))))) @@ -3847,23 +3955,22 @@ process to set up. VEC specifies the connection." (tramp-message vec 5 "Setting shell prompt") (tramp-send-command - vec (format "PS1=%s" (tramp-shell-quote-argument tramp-end-of-output)) t) - (tramp-send-command vec "PS2=''" t) - (tramp-send-command vec "PS3=''" t) - (tramp-send-command vec "PROMPT_COMMAND=''" t) + vec (format "PS1=%s PS2='' PS3='' PROMPT_COMMAND=''" + (tramp-shell-quote-argument tramp-end-of-output)) t) ;; Try to set up the coding system correctly. ;; CCC this can't be the right way to do it. Hm. (tramp-message vec 5 "Determining coding system") - (tramp-send-command vec "echo foo ; echo bar" t) (with-current-buffer (process-buffer proc) - (goto-char (point-min)) (if (featurep 'mule) ;; Use MULE to select the right EOL convention for communicating ;; with the process. - (let* ((cs (or (tramp-compat-funcall 'process-coding-system proc) - (cons 'undecided 'undecided))) - cs-decode cs-encode) + (let ((cs (or (when (string-match + "utf8" (or (tramp-get-remote-locale vec) "")) + (cons 'utf-8 'utf-8)) + (tramp-compat-funcall 'process-coding-system proc) + (cons 'undecided 'undecided))) + cs-decode cs-encode) (when (symbolp cs) (setq cs (cons cs cs))) (setq cs-decode (car cs)) (setq cs-encode (cdr cs)) @@ -3871,6 +3978,8 @@ process to set up. VEC specifies the connection." (unless cs-encode (setq cs-encode 'undecided)) (setq cs-encode (tramp-compat-coding-system-change-eol-conversion cs-encode 'unix)) + (tramp-send-command vec "echo foo ; echo bar" t) + (goto-char (point-min)) (when (search-forward "\r" nil t) (setq cs-decode (tramp-compat-coding-system-change-eol-conversion cs-decode 'dos))) @@ -3967,15 +4076,22 @@ process to set up. VEC specifies the connection." (let ((env (append (when (tramp-get-remote-locale vec) ; Discard `(nil)'. `(,(tramp-get-remote-locale vec))) (copy-sequence tramp-remote-process-environment))) - unset item) + unset vars item) (while env (setq item (tramp-compat-split-string (car env) "=")) (setcdr item (mapconcat 'identity (cdr item) "=")) (if (and (stringp (cdr item)) (not (string-equal (cdr item) ""))) - (tramp-send-command - vec (format "%s=%s; export %s" (car item) (cdr item) (car item)) t) + (push (format "%s %s" (car item) (cdr item)) vars) (push (car item) unset)) (setq env (cdr env))) + (when vars + (tramp-send-command + vec + (format "while read var val; do export $var=$val; done <<'%s'\n%s\n%s" + tramp-end-of-heredoc + (mapconcat 'identity vars "\n") + tramp-end-of-heredoc) + t)) (when unset (tramp-send-command vec (format "unset %s" (mapconcat 'identity unset " ")) t)))) @@ -4010,7 +4126,7 @@ FORMAT is symbol describing the encoding/decoding format. It can be ENCODING and DECODING can be strings, giving commands, or symbols, giving functions. If they are strings, then they can contain the \"%s\" format specifier. If that specifier is present, the input -filename will be put into the command line at that spot. If the +file name will be put into the command line at that spot. If the specifier is not present, the input should be read from standard input. @@ -4045,7 +4161,7 @@ FORMAT is a symbol describing the encoding/decoding format. It can be ENCODING and DECODING can be strings, giving commands, or symbols, giving variables. If they are strings, then they can contain the \"%s\" format specifier. If that specifier is present, the input -filename will be put into the command line at that spot. If the +file name will be put into the command line at that spot. If the specifier is not present, the input should be read from standard input. @@ -4171,32 +4287,28 @@ Goes through the list `tramp-local-coding-commands' and (setq rem-dec (nth 2 ritem)) (setq found t))))))) - ;; Did we find something? - (unless found - (tramp-error - vec 'file-error "Couldn't find an inline transfer encoding")) - - ;; Set connection properties. Since the commands are risky (due - ;; to output direction), we cache them in the process cache. - (tramp-message vec 5 "Using local encoding `%s'" loc-enc) - (tramp-set-connection-property p "local-encoding" loc-enc) - (tramp-message vec 5 "Using local decoding `%s'" loc-dec) - (tramp-set-connection-property p "local-decoding" loc-dec) - (tramp-message vec 5 "Using remote encoding `%s'" rem-enc) - (tramp-set-connection-property p "remote-encoding" rem-enc) - (tramp-message vec 5 "Using remote decoding `%s'" rem-dec) - (tramp-set-connection-property p "remote-decoding" rem-dec)))) + (when found + ;; Set connection properties. Since the commands are risky + ;; (due to output direction), we cache them in the process cache. + (tramp-message vec 5 "Using local encoding `%s'" loc-enc) + (tramp-set-connection-property p "local-encoding" loc-enc) + (tramp-message vec 5 "Using local decoding `%s'" loc-dec) + (tramp-set-connection-property p "local-decoding" loc-dec) + (tramp-message vec 5 "Using remote encoding `%s'" rem-enc) + (tramp-set-connection-property p "remote-encoding" rem-enc) + (tramp-message vec 5 "Using remote decoding `%s'" rem-dec) + (tramp-set-connection-property p "remote-decoding" rem-dec))))) (defun tramp-call-local-coding-command (cmd input output) "Call the local encoding or decoding command. If CMD contains \"%s\", provide input file INPUT there in command. Otherwise, INPUT is passed via standard input. INPUT can also be nil which means `/dev/null'. -OUTPUT can be a string (which specifies a filename), or t (which +OUTPUT can be a string (which specifies a file name), or t (which means standard output and thus the current buffer), or nil (which means discard it)." (tramp-call-process - tramp-encoding-shell + nil tramp-encoding-shell (when (and input (not (string-match "%s" cmd))) input) (if (eq output t) t nil) nil @@ -4844,15 +4956,18 @@ Return ATTR." "")) (defun tramp-make-copy-program-file-name (vec) - "Create a file name suitable to be passed to `rcp' and workalikes." - (let ((user (tramp-file-name-user vec)) + "Create a file name suitable to be passed to `scp' or `nc' and workalikes." + (let ((method (tramp-file-name-method vec)) + (user (tramp-file-name-user vec)) (host (tramp-file-name-real-host vec)) (localname (tramp-shell-quote-argument (tramp-file-name-localname vec)))) - (shell-quote-argument - (if (not (zerop (length user))) - (format "%s@%s:%s" user host localname) - (format "%s:%s" host localname))))) + (cond + ((tramp-get-method-parameter method 'tramp-remote-copy-program) + localname) + ((not (zerop (length user))) + (shell-quote-argument (format "%s@%s:%s" user host localname))) + (t (shell-quote-argument (format "%s:%s" host localname)))))) (defun tramp-method-out-of-band-p (vec size) "Return t if this is an out-of-band method, nil otherwise." @@ -5098,7 +5213,7 @@ Return ATTR." (format "%s -t %s %s" result - (format-time-string "%Y%m%d%H%M.%S" (current-time)) + (format-time-string "%Y%m%d%H%M.%S") (tramp-file-name-handler 'file-remote-p tmpfile 'localname)))) (delete-file tmpfile)) result))) @@ -5118,13 +5233,14 @@ Return ATTR." (with-tramp-connection-property vec "id" (tramp-message vec 5 "Finding POSIX `id' command") (catch 'id-found - (let ((dl (tramp-get-remote-path vec)) - result) - (while (and dl (setq result (tramp-find-executable vec "id" dl t t))) - ;; Check POSIX parameter. - (when (tramp-send-command-and-check vec (format "%s -u" result)) - (throw 'id-found result)) - (setq dl (cdr dl))))))) + (dolist (cmd '("id" "gid")) + (let ((dl (tramp-get-remote-path vec)) + result) + (while (and dl (setq result (tramp-find-executable vec cmd dl t t))) + ;; Check POSIX parameter. + (when (tramp-send-command-and-check vec (format "%s -u" result)) + (throw 'id-found result)) + (setq dl (cdr dl)))))))) (defun tramp-get-remote-uid-with-id (vec id-format) (tramp-send-command-and-read @@ -5147,7 +5263,9 @@ Return ATTR." (defun tramp-get-remote-python (vec) (with-tramp-connection-property vec "python" (tramp-message vec 5 "Finding a suitable `python' command") - (tramp-find-executable vec "python" (tramp-get-remote-path vec)))) + (or (tramp-find-executable vec "python" (tramp-get-remote-path vec)) + (tramp-find-executable vec "python2" (tramp-get-remote-path vec)) + (tramp-find-executable vec "python3" (tramp-get-remote-path vec))))) (defun tramp-get-remote-uid-with-python (vec id-format) (tramp-send-command-and-read @@ -5155,8 +5273,8 @@ Return ATTR." (format "%s -c \"%s\"" (tramp-get-remote-python vec) (if (equal id-format 'integer) - "import os; print os.getuid()" - "import os, pwd; print '\\\"' + pwd.getpwuid(os.getuid())[0] + '\\\"'")))) + "import os; print (os.getuid())" + "import os, pwd; print ('\\\"' + pwd.getpwuid(os.getuid())[0] + '\\\"')")))) (defun tramp-get-remote-uid (vec id-format) (with-tramp-connection-property vec (format "uid-%s" id-format) @@ -5196,8 +5314,8 @@ Return ATTR." (format "%s -c \"%s\"" (tramp-get-remote-python vec) (if (equal id-format 'integer) - "import os; print os.getgid()" - "import os, grp; print '\\\"' + grp.getgrgid(os.getgid())[0] + '\\\"'")))) + "import os; print (os.getgid())" + "import os, grp; print ('\\\"' + grp.getgrgid(os.getgid())[0] + '\\\"')")))) (defun tramp-get-remote-gid (vec id-format) (with-tramp-connection-property vec (format "gid-%s" id-format) @@ -5371,9 +5489,5 @@ function cell is returned to be applied on a buffer." ;; rsync). ;; * Keep a second connection open for out-of-band methods like scp or ;; rsync. -;; * Try telnet+curl as new method. It might be useful for busybox, -;; without built-in uuencode/uudecode. -;; * Try telnet+nc as new method. It might be useful for busybox, -;; without built-in uuencode/uudecode. ;;; tramp-sh.el ends here diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index fa5e72dfb3e..15ae9ed6fa8 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -447,8 +447,7 @@ pass to the OPERATION." (expand-file-name tramp-temp-name-prefix (tramp-compat-temporary-file-directory)))) - (args (list tramp-smb-program - (concat "//" real-host "/" share) "-E"))) + (args (list (concat "//" real-host "/" share) "-E"))) (if (not (zerop (length real-user))) (setq args (append args (list "-U" real-user))) @@ -495,10 +494,11 @@ pass to the OPERATION." ;; Use an asynchronous processes. By this, ;; password can be handled. (let* ((default-directory tmpdir) - (p (start-process-shell-command + (p (apply + 'start-process (tramp-get-connection-name v) (tramp-get-connection-buffer v) - (mapconcat 'identity args " ")))) + tramp-smb-program args))) (tramp-message v 6 "%s" (mapconcat 'identity (process-command p) " ")) @@ -938,99 +938,100 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (setq filename (file-name-as-directory filename)) (setq filename (directory-file-name filename))) (with-parsed-tramp-file-name filename nil - (save-match-data - (let ((base (file-name-nondirectory filename)) - ;; We should not destroy the cache entry. - (entries (copy-sequence - (tramp-smb-get-file-entries - (file-name-directory filename))))) - - (when wildcard - (string-match "\\." base) - (setq base (replace-match "\\\\." nil nil base)) - (string-match "\\*" base) - (setq base (replace-match ".*" nil nil base)) - (string-match "\\?" base) - (setq base (replace-match ".?" nil nil base))) - - ;; Filter entries. - (setq entries - (delq - nil - (if (or wildcard (zerop (length base))) - ;; Check for matching entries. - (mapcar - (lambda (x) - (when (string-match - (format "^%s" base) (nth 0 x)) - x)) - entries) - ;; We just need the only and only entry FILENAME. - (list (assoc base entries))))) - - ;; Sort entries. - (setq entries - (sort - entries - (lambda (x y) - (if (string-match "t" switches) - ;; Sort by date. - (tramp-time-less-p (nth 3 y) (nth 3 x)) - ;; Sort by name. - (string-lessp (nth 0 x) (nth 0 y)))))) - - ;; Handle "-F" switch. - (when (string-match "F" switches) + (with-tramp-progress-reporter v 0 (format "Opening directory %s" filename) + (save-match-data + (let ((base (file-name-nondirectory filename)) + ;; We should not destroy the cache entry. + (entries (copy-sequence + (tramp-smb-get-file-entries + (file-name-directory filename))))) + + (when wildcard + (string-match "\\." base) + (setq base (replace-match "\\\\." nil nil base)) + (string-match "\\*" base) + (setq base (replace-match ".*" nil nil base)) + (string-match "\\?" base) + (setq base (replace-match ".?" nil nil base))) + + ;; Filter entries. + (setq entries + (delq + nil + (if (or wildcard (zerop (length base))) + ;; Check for matching entries. + (mapcar + (lambda (x) + (when (string-match + (format "^%s" base) (nth 0 x)) + x)) + entries) + ;; We just need the only and only entry FILENAME. + (list (assoc base entries))))) + + ;; Sort entries. + (setq entries + (sort + entries + (lambda (x y) + (if (string-match "t" switches) + ;; Sort by date. + (tramp-time-less-p (nth 3 y) (nth 3 x)) + ;; Sort by name. + (string-lessp (nth 0 x) (nth 0 y)))))) + + ;; Handle "-F" switch. + (when (string-match "F" switches) + (mapc + (lambda (x) + (when (not (zerop (length (car x)))) + (cond + ((char-equal ?d (string-to-char (nth 1 x))) + (setcar x (concat (car x) "/"))) + ((char-equal ?x (string-to-char (nth 1 x))) + (setcar x (concat (car x) "*")))))) + entries)) + + ;; Print entries. (mapc (lambda (x) - (when (not (zerop (length (car x)))) - (cond - ((char-equal ?d (string-to-char (nth 1 x))) - (setcar x (concat (car x) "/"))) - ((char-equal ?x (string-to-char (nth 1 x))) - (setcar x (concat (car x) "*")))))) - entries)) - - ;; Print entries. - (mapc - (lambda (x) - (when (not (zerop (length (nth 0 x)))) - (when (string-match "l" switches) - (let ((attr - (when (tramp-smb-get-stat-capability v) - (ignore-errors - (file-attributes filename 'string))))) + (when (not (zerop (length (nth 0 x)))) + (when (string-match "l" switches) + (let ((attr + (when (tramp-smb-get-stat-capability v) + (ignore-errors + (file-attributes filename 'string))))) + (insert + (format + "%10s %3d %-8s %-8s %8s %s " + (or (nth 8 attr) (nth 1 x)) ; mode + (or (nth 1 attr) 1) ; inode + (or (nth 2 attr) "nobody") ; uid + (or (nth 3 attr) "nogroup") ; gid + (or (nth 7 attr) (nth 2 x)) ; size + (format-time-string + (if (tramp-time-less-p + (tramp-time-subtract (current-time) (nth 3 x)) + tramp-half-a-year) + "%b %e %R" + "%b %e %Y") + (nth 3 x)))))) ; date + + ;; We mark the file name. The inserted name could be + ;; from somewhere else, so we use the relative file name + ;; of `default-directory'. + (let ((start (point))) (insert (format - "%10s %3d %-8s %-8s %8s %s " - (or (nth 8 attr) (nth 1 x)) ; mode - (or (nth 1 attr) 1) ; inode - (or (nth 2 attr) "nobody") ; uid - (or (nth 3 attr) "nogroup") ; gid - (or (nth 7 attr) (nth 2 x)) ; size - (format-time-string - (if (tramp-time-less-p - (tramp-time-subtract (current-time) (nth 3 x)) - tramp-half-a-year) - "%b %e %R" - "%b %e %Y") - (nth 3 x)))))) ; date - - ;; We mark the file name. The inserted name could be - ;; from somewhere else, so we use the relative file name - ;; of `default-directory'. - (let ((start (point))) - (insert - (format - "%s\n" - (file-relative-name - (expand-file-name - (nth 0 x) (file-name-directory filename)) - (when full-directory-p (file-name-directory filename))))) - (put-text-property start (1- (point)) 'dired-filename t)) - (forward-line) - (beginning-of-line))) - entries))))) + "%s\n" + (file-relative-name + (expand-file-name + (nth 0 x) (file-name-directory filename)) + (when full-directory-p (file-name-directory filename))))) + (put-text-property start (1- (point)) 'dired-filename t)) + (forward-line) + (beginning-of-line))) + entries)))))) (defun tramp-smb-handle-make-directory (dir &optional parents) "Like `make-directory' for Tramp files." @@ -1277,6 +1278,8 @@ target of the symlink differ." ;; We must also flush the cache of the directory, because ;; `file-attributes' reads the values from there. + (tramp-flush-file-property v1 (file-name-directory v1-localname)) + (tramp-flush-file-property v1 v1-localname) (tramp-flush-file-property v2 (file-name-directory v2-localname)) (tramp-flush-file-property v2 v2-localname) (unless (tramp-smb-get-share v2) @@ -1349,7 +1352,7 @@ target of the symlink differ." ;; Use an asynchronous processes. By this, password can ;; be handled. (let ((p (apply - 'start-process-shell-command + 'start-process (tramp-get-connection-name v) (tramp-get-connection-buffer v) tramp-smb-acl-program args))) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 9a97d824528..e3fb177b0c5 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -240,7 +240,7 @@ pair of the form (KEY VALUE). The following KEYs are defined: tamper the process output. * `tramp-copy-program' This specifies the name of the program to use for remotely copying - the file; this might be the absolute filename of rcp or the name of + the file; this might be the absolute filename of scp or the name of a workalike program. It is always applied on the local host. * `tramp-copy-args' This specifies the list of parameters to pass to the above mentioned @@ -248,6 +248,13 @@ pair of the form (KEY VALUE). The following KEYs are defined: * `tramp-copy-env' A list of environment variables and their values, which will be set when calling `tramp-copy-program'. + * `tramp-remote-copy-program' + The listener program to be applied on remote side, if needed. + * `tramp-remote-copy-args' + The list of parameters to pass to the listener program, the hints + for `tramp-login-args' also apply here. Additionally, \"%r\" could + be used here and in `tramp-copy-args'. It denotes a randomly + chosen port for the remote listener. * `tramp-copy-keep-date' This specifies whether the copying program when the preserves the timestamp of the original file. @@ -275,7 +282,7 @@ pair of the form (KEY VALUE). The following KEYs are defined: What does all this mean? Well, you should specify `tramp-login-program' for all methods; this program is used to log in to the remote site. Then, there are two ways to actually transfer the files between the local and the -remote side. One way is using an additional rcp-like program. If you want +remote side. One way is using an additional scp-like program. If you want to do this, set `tramp-copy-program' in the method. Another possibility for file transfer is inline transfer, i.e. the @@ -1762,7 +1769,7 @@ Example: (and (memq system-type '(cygwin windows-nt)) (zerop (tramp-call-process - "reg" nil nil nil "query" (nth 1 (car v))))) + v "reg" nil nil nil "query" (nth 1 (car v))))) ;; Configuration file. (file-exists-p (nth 1 (car v))))) (setq r (delete (car v) r))) @@ -2141,13 +2148,13 @@ Falls back to normal file name handler if no Tramp file name handler exists." ((eq result 'non-essential) (tramp-message v 5 "Non-essential received in operation %s" - (append (list operation) args)) + (cons operation args)) (tramp-run-real-handler operation args)) ((eq result 'suppress) (let (tramp-message-show-message) (tramp-message v 1 "Suppress received in operation %s" - (append (list operation) args)) + (cons operation args)) (tramp-cleanup-connection v t) (tramp-run-real-handler operation args))) (t result))) @@ -2157,7 +2164,7 @@ Falls back to normal file name handler if no Tramp file name handler exists." (let (tramp-message-show-message) (tramp-message v 1 "Interrupt received in operation %s" - (append (list operation) args))) + (cons operation args))) ;; Propagate the quit signal. (signal (car err) (cdr err))) @@ -2816,7 +2823,7 @@ User is always nil." (if (memq system-type '(windows-nt)) (with-temp-buffer (when (zerop (tramp-call-process - "reg" nil t nil "query" registry-or-dirname)) + nil "reg" nil t nil "query" registry-or-dirname)) (goto-char (point-min)) (loop while (not (eobp)) collect (tramp-parse-putty-group registry-or-dirname)))) @@ -2895,7 +2902,7 @@ User is always nil." (defun tramp-handle-file-accessible-directory-p (filename) "Like `file-accessible-directory-p' for Tramp files." (and (file-directory-p filename) - (file-executable-p filename))) + (file-readable-p filename))) (defun tramp-handle-file-exists-p (filename) "Like `file-exists-p' for Tramp files." @@ -2991,8 +2998,6 @@ User is always nil." (with-parsed-tramp-file-name filename nil (let ((x (car (file-attributes filename)))) (when (stringp x) - ;; When Tramp is running on VMS, then `file-name-absolute-p' - ;; might do weird things. (if (file-name-absolute-p x) (tramp-make-tramp-file-name method user host x) x))))) @@ -3284,11 +3289,12 @@ User is always nil." ;; Run the process. (setq p (apply 'start-file-process "*Async Shell*" buffer args)) ;; Display output. - (pop-to-buffer output-buffer) - (setq mode-line-process '(":%s")) - (shell-mode) - (set-process-sentinel p 'shell-command-sentinel) - (set-process-filter p 'comint-output-filter)) + (with-current-buffer output-buffer + (display-buffer output-buffer '(nil (allow-no-window . t))) + (setq mode-line-process '(":%s")) + (shell-mode) + (set-process-sentinel p 'shell-command-sentinel) + (set-process-filter p 'comint-output-filter))) (prog1 ;; Run the process. @@ -3333,8 +3339,9 @@ User is always nil." (defun tramp-handle-unhandled-file-name-directory (_filename) "Like `unhandled-file-name-directory' for Tramp files." ;; With Emacs 23, we could simply return `nil'. But we must keep it - ;; for backward compatibility. - (expand-file-name "~/")) + ;; for backward compatibility. "~/" cannot be returned, because + ;; there might be machines without a HOME directory (like hydra). + "/") (defun tramp-handle-set-visited-file-modtime (&optional time-list) "Like `set-visited-file-modtime' for Tramp files." @@ -3905,7 +3912,7 @@ be granted." (tramp-get-file-property vec (tramp-file-name-localname vec) (concat "file-attributes-" suffix) nil) - (file-attributes + (tramp-compat-file-attributes (tramp-make-tramp-file-name (tramp-file-name-method vec) (tramp-file-name-user vec) @@ -4117,18 +4124,34 @@ ALIST is of the form ((FROM . TO) ...)." ;;; Compatibility functions section: (defun tramp-call-process - (program &optional infile destination display &rest args) + (vec program &optional infile destination display &rest args) "Calls `call-process' on the local host. -This is needed because for some Emacs flavors Tramp has -defadvised `call-process' to behave like `process-file'. The -Lisp error raised when PROGRAM is nil is trapped also, returning 1. -Furthermore, traces are written with verbosity of 6." - (tramp-message - (vector tramp-current-method tramp-current-user tramp-current-host nil nil) - 6 "`%s %s' %s %s" program (mapconcat 'identity args " ") infile destination) - (if (executable-find program) - (apply 'call-process program infile destination display args) - 1)) +It always returns a return code. The Lisp error raised when +PROGRAM is nil is trapped also, returning 1. Furthermore, traces +are written with verbosity of 6." + (let ((v (or vec + (vector tramp-current-method tramp-current-user + tramp-current-host nil nil))) + (destination (if (eq destination t) (current-buffer) destination)) + result) + (tramp-message + v 6 "`%s %s' %s %s" + program (mapconcat 'identity args " ") infile destination) + (condition-case err + (with-temp-buffer + (setq result + (apply + 'call-process program infile (or destination t) display args)) + ;; `result' could also be an error string. + (when (stringp result) + (signal 'file-error (list result))) + (with-current-buffer + (if (bufferp destination) destination (current-buffer)) + (tramp-message v 6 "%d\n%s" result (buffer-string)))) + (error + (setq result 1) + (tramp-message v 6 "%d\n%s" result (error-message-string err)))) + result)) ;;;###tramp-autoload (defun tramp-read-passwd (proc &optional prompt) diff --git a/lisp/net/trampver.el b/lisp/net/trampver.el index 1ee6e6ad025..065c3f33ebe 100644 --- a/lisp/net/trampver.el +++ b/lisp/net/trampver.el @@ -24,14 +24,14 @@ ;;; Code: -;; In the Tramp CVS repository, the version number and the bug report +;; In the Tramp GIT repository, the version number and the bug report ;; address are auto-frobbed from configure.ac, so you should edit that ;; file and run "autoconf && ./configure" to change them. (X)Emacs ;; version check is defined in macro AC_EMACS_INFO of aclocal.m4; ;; should be changed only there. ;;;###tramp-autoload -(defconst tramp-version "2.2.9-24.4" +(defconst tramp-version "2.2.11-pre" "This version of Tramp.") ;;;###tramp-autoload @@ -44,7 +44,7 @@ (= emacs-major-version 21) (>= emacs-minor-version 4))) "ok" - (format "Tramp 2.2.9-24.4 is not fit for %s" + (format "Tramp 2.2.11-pre is not fit for %s" (when (string-match "^.*$" (emacs-version)) (match-string 0 (emacs-version))))))) (unless (string-match "\\`ok\\'" x) (error "%s" x))) -- 2.39.5