(eval-when-compile (require 'cl)) ; ignore-errors
(require 'tramp)
-(require 'shell)
;; Pacify byte-compiler. The function is needed on XEmacs only. I'm
;; not sure at all that this is the right way to do it, but let's hope
:group 'tramp
:type 'string)
+(defconst tramp-color-escape-sequence-regexp "\e[[;0-9]+m"
+ "Escape sequences produced by the \"ls\" command.")
+
;; ksh on OpenBSD 4.5 requires that $PS1 contains a `#' character for
;; root users. It uses the `$' character for other users. In order
;; to guarantee a proper prompt, we use "#$ " for the prompt.
'("rcp"
(tramp-login-program "rsh")
(tramp-login-args (("%h") ("-l" "%u")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-copy-program "rcp")
- (tramp-copy-args (("%k" "-p") ("-r")))
+ (tramp-copy-args (("-p" "%k") ("-r")))
(tramp-copy-keep-date t)
(tramp-copy-recursive t)))
;;;###tramp-autoload
'("remcp"
(tramp-login-program "remsh")
(tramp-login-args (("%h") ("-l" "%u")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-copy-program "rcp")
- (tramp-copy-args (("%k" "-p")))
+ (tramp-copy-args (("-p" "%k")))
(tramp-copy-keep-date t)))
;;;###tramp-autoload
(add-to-list 'tramp-methods
(tramp-login-program "ssh")
(tramp-login-args (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h")))
(tramp-async-args (("-q")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-copy-program "scp")
- (tramp-copy-args (("-P" "%p") ("%k" "-p") ("-q") ("-r")))
+ (tramp-copy-args (("-P" "%p") ("-p" "%k") ("-q") ("-r")))
(tramp-copy-keep-date t)
(tramp-copy-recursive t)
(tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null")
(tramp-login-args (("-l" "%u") ("-p" "%p")
("-1") ("-e" "none") ("%h")))
(tramp-async-args (("-q")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-copy-program "scp")
- (tramp-copy-args (("-1") ("-P" "%p") ("%k" "-p") ("-q") ("-r")))
+ (tramp-copy-args (("-1") ("-P" "%p") ("-p" "%k") ("-q") ("-r")))
(tramp-copy-keep-date t)
(tramp-copy-recursive t)
(tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null")
(tramp-login-args (("-l" "%u") ("-p" "%p")
("-2") ("-e" "none") ("%h")))
(tramp-async-args (("-q")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-copy-program "scp")
- (tramp-copy-args (("-2") ("-P" "%p") ("%k" "-p") ("-q") ("-r")))
+ (tramp-copy-args (("-2") ("-P" "%p") ("-p" "%k") ("-q") ("-r")))
(tramp-copy-keep-date t)
(tramp-copy-recursive t)
(tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null")
("-o" "ControlMaster=yes")
("-e" "none") ("%h")))
(tramp-async-args (("-q")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-copy-program "scp")
- (tramp-copy-args (("-P" "%p") ("%k" "-p") ("-q") ("-r")
+ (tramp-copy-args (("-P" "%p") ("-p" "%k") ("-q") ("-r")
("-o" "ControlPath=%t.%%r@%%h:%%p")
("-o" "ControlMaster=auto")))
(tramp-copy-keep-date t)
("-e" "none") ("-t" "-t")
("%h") ("/bin/sh")))
(tramp-async-args (("-q")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-copy-program "scp")
- (tramp-copy-args (("-P" "%p") ("%k" "-p") ("-q") ("-r")))
+ (tramp-copy-args (("-P" "%p") ("-p" "%k") ("-q") ("-r")))
(tramp-copy-keep-date t)
(tramp-copy-recursive t)
(tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null")
(tramp-login-program "ssh")
(tramp-login-args (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h")))
(tramp-async-args (("-q")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-copy-program "sftp")))
;;;###tramp-autoload
(add-to-list 'tramp-methods
(tramp-login-program "ssh")
(tramp-login-args (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h")))
(tramp-async-args (("-q")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-copy-program "rsync")
- (tramp-copy-args (("-e" "ssh") ("%k" "-t") ("-r")))
+ (tramp-copy-args (("-e" "ssh") ("-t" "%k") ("-r")))
(tramp-copy-keep-date t)
(tramp-copy-keep-tmpfile t)
(tramp-copy-recursive t)))
("-o" "ControlMaster=yes")
("-e" "none") ("%h")))
(tramp-async-args (("-q")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-copy-program "rsync")
- (tramp-copy-args (("%k" "-t") ("-r")))
+ (tramp-copy-args (("-t" "%k") ("-r")))
(tramp-copy-env (("RSYNC_RSH")
(,(concat
"ssh"
'("rsh"
(tramp-login-program "rsh")
(tramp-login-args (("%h") ("-l" "%u")))
- (tramp-remote-sh "/bin/sh")))
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))))
;;;###tramp-autoload
(add-to-list 'tramp-methods
'("remsh"
(tramp-login-program "remsh")
(tramp-login-args (("%h") ("-l" "%u")))
- (tramp-remote-sh "/bin/sh")))
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))))
;;;###tramp-autoload
(add-to-list 'tramp-methods
'("ssh"
(tramp-login-program "ssh")
(tramp-login-args (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h")))
(tramp-async-args (("-q")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null")
("-o" "UserKnownHostsFile=/dev/null")
("-o" "StrictHostKeyChecking=no")))
(tramp-login-args (("-l" "%u") ("-p" "%p")
("-1") ("-e" "none") ("%h")))
(tramp-async-args (("-q")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null")
("-o" "UserKnownHostsFile=/dev/null")
("-o" "StrictHostKeyChecking=no")))
(tramp-login-args (("-l" "%u") ("-p" "%p")
("-2") ("-e" "none") ("%h")))
(tramp-async-args (("-q")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null")
("-o" "UserKnownHostsFile=/dev/null")
("-o" "StrictHostKeyChecking=no")))
("-e" "none") ("-t" "-t")
("%h") ("/bin/sh")))
(tramp-async-args (("-q")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null")
("-o" "UserKnownHostsFile=/dev/null")
("-o" "StrictHostKeyChecking=no")))
'("telnet"
(tramp-login-program "telnet")
(tramp-login-args (("%h") ("%p")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-default-port 23)))
;;;###tramp-autoload
(add-to-list 'tramp-methods
'("su"
(tramp-login-program "su")
(tramp-login-args (("-") ("%u")))
- (tramp-remote-sh "/bin/sh")))
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))))
;;;###tramp-autoload
(add-to-list 'tramp-methods
'("sudo"
(tramp-login-program "sudo")
(tramp-login-args (("-u" "%u") ("-s") ("-H") ("-p" "Password:")))
- (tramp-remote-sh "/bin/sh")))
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))))
;;;###tramp-autoload
(add-to-list 'tramp-methods
'("ksu"
(tramp-login-program "ksu")
(tramp-login-args (("%u") ("-q")))
- (tramp-remote-sh "/bin/sh")))
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))))
;;;###tramp-autoload
(add-to-list 'tramp-methods
'("krlogin"
(tramp-login-program "krlogin")
(tramp-login-args (("%h") ("-l" "%u") ("-x")))
- (tramp-remote-sh "/bin/sh")))
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))))
;;;###tramp-autoload
(add-to-list 'tramp-methods
'("plink"
(tramp-login-program "plink")
(tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%h")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-password-end-of-line "xy") ;see docstring for "xy"
(tramp-default-port 22)))
;;;###tramp-autoload
'("plink1"
(tramp-login-program "plink")
(tramp-login-args (("-l" "%u") ("-P" "%p") ("-1" "-ssh") ("%h")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-password-end-of-line "xy") ;see docstring for "xy"
(tramp-default-port 22)))
;;;###tramp-autoload
tramp-terminal-type
tramp-initial-end-of-output))
("/bin/sh")))
- (tramp-remote-sh "/bin/sh")))
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))))
;;;###tramp-autoload
(add-to-list 'tramp-methods
'("pscp"
(tramp-login-program "plink")
(tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%h")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-copy-program "pscp")
- (tramp-copy-args (("-P" "%p") ("-scp") ("%k" "-p")
+ (tramp-copy-args (("-P" "%p") ("-scp") ("-p" "%k")
("-q") ("-r")))
(tramp-copy-keep-date t)
(tramp-copy-recursive t)
'("psftp"
(tramp-login-program "plink")
(tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%h")))
- (tramp-remote-sh "/bin/sh")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
(tramp-copy-program "pscp")
- (tramp-copy-args (("-P" "%p") ("-sftp") ("%k" "-p")
+ (tramp-copy-args (("-P" "%p") ("-sftp") ("-p" "%k")
("-q") ("-r")))
(tramp-copy-keep-date t)
(tramp-copy-recursive t)
'("fcp"
(tramp-login-program "fsh")
(tramp-login-args (("%h") ("-l" "%u") ("sh" "-i")))
- (tramp-remote-sh "/bin/sh -i")
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-i") ("-c"))
(tramp-copy-program "fcp")
- (tramp-copy-args (("%k" "-p")))
+ (tramp-copy-args (("-p" "%k")))
(tramp-copy-keep-date t)))
;;;###tramp-autoload
"\\'")
nil ,(user-login-name)))
+;;;###tramp-autoload
(defconst tramp-completion-function-alist-rsh
'((tramp-parse-rhosts "/etc/hosts.equiv")
(tramp-parse-rhosts "~/.rhosts"))
"Default list of (FUNCTION FILE) pairs to be examined for rsh methods.")
+;;;###tramp-autoload
(defconst tramp-completion-function-alist-ssh
'((tramp-parse-rhosts "/etc/hosts.equiv")
(tramp-parse-rhosts "/etc/shosts.equiv")
(tramp-parse-sknownhosts "~/.ssh2/knownhosts"))
"Default list of (FUNCTION FILE) pairs to be examined for ssh methods.")
+;;;###tramp-autoload
(defconst tramp-completion-function-alist-telnet
'((tramp-parse-hosts "/etc/hosts"))
"Default list of (FUNCTION FILE) pairs to be examined for telnet methods.")
+;;;###tramp-autoload
(defconst tramp-completion-function-alist-su
'((tramp-parse-passwd "/etc/passwd"))
"Default list of (FUNCTION FILE) pairs to be examined for su methods.")
+;;;###tramp-autoload
(defconst tramp-completion-function-alist-putty
'((tramp-parse-putty
"HKEY_CURRENT_USER\\Software\\SimonTatham\\PuTTY\\Sessions"))
"Default list of (FUNCTION REGISTRY) pairs to be examined for putty methods.")
-(tramp-set-completion-function "rcp" tramp-completion-function-alist-rsh)
-(tramp-set-completion-function "remcp" tramp-completion-function-alist-rsh)
-(tramp-set-completion-function "scp" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "scp1" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "scp2" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "scpc" 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 "rsyncc" 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)
-(tramp-set-completion-function "ssh" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "ssh1" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "ssh2" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "ssh1_old" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "ssh2_old" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "sshx" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "telnet" 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)
-(tramp-set-completion-function "krlogin" tramp-completion-function-alist-rsh)
-(tramp-set-completion-function "plink" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "plink1" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "plinkx" tramp-completion-function-alist-putty)
-(tramp-set-completion-function "pscp" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "fcp" tramp-completion-function-alist-ssh)
+;;;###tramp-autoload
+(eval-after-load 'tramp
+ '(progn
+ (tramp-set-completion-function "rcp" tramp-completion-function-alist-rsh)
+ (tramp-set-completion-function "remcp" tramp-completion-function-alist-rsh)
+ (tramp-set-completion-function "scp" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function "scp1" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function "scp2" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function "scpc" 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
+ "rsyncc" 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)
+ (tramp-set-completion-function "ssh" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function "ssh1" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function "ssh2" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function
+ "ssh1_old" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function
+ "ssh2_old" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function "sshx" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function
+ "telnet" 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)
+ (tramp-set-completion-function
+ "krlogin" tramp-completion-function-alist-rsh)
+ (tramp-set-completion-function "plink" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function
+ "plink1" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function
+ "plinkx" tramp-completion-function-alist-putty)
+ (tramp-set-completion-function "pscp" tramp-completion-function-alist-ssh)
+ (tramp-set-completion-function "fcp" tramp-completion-function-alist-ssh)))
;; "getconf PATH" yields:
;; HP-UX: /usr/bin:/usr/ccs/bin:/opt/ansic/bin:/opt/langtools/bin:/opt/fortran/bin
;; FreeBSD: /usr/bin:/bin:/usr/sbin:/sbin: - beware trailing ":"!
;; IRIX64: /usr/bin
(defcustom tramp-remote-path
- '(tramp-default-remote-path "/usr/sbin" "/usr/local/bin"
+ '(tramp-default-remote-path "/bin" "/usr/bin" "/usr/sbin" "/usr/local/bin"
"/local/bin" "/local/freeware/bin" "/local/gnu/bin"
"/usr/freeware/bin" "/usr/pkg/bin" "/usr/contrib/bin")
"*List of directories to search for executables on remote host.
(executable-find . tramp-sh-handle-executable-find)
(start-file-process . tramp-sh-handle-start-file-process)
(process-file . tramp-sh-handle-process-file)
- (shell-command . tramp-sh-handle-shell-command)
+ (shell-command . tramp-handle-shell-command)
(insert-directory . tramp-sh-handle-insert-directory)
(expand-file-name . tramp-sh-handle-expand-file-name)
(substitute-in-file-name . tramp-handle-substitute-in-file-name)
(save-excursion
(tramp-convert-file-attributes
v
- (cond
- ((tramp-get-remote-stat v)
- (tramp-do-file-attributes-with-stat v localname id-format))
- ((tramp-get-remote-perl v)
- (tramp-do-file-attributes-with-perl v localname id-format))
- (t
- (tramp-do-file-attributes-with-ls v localname id-format)))))))))
+ (or
+ (cond
+ ((tramp-get-remote-stat v)
+ (tramp-do-file-attributes-with-stat v localname id-format))
+ ((tramp-get-remote-perl v)
+ (tramp-do-file-attributes-with-perl v localname id-format))
+ (t nil))
+ ;; The scripts could fail, for example with huge file size.
+ (tramp-do-file-attributes-with-ls v localname id-format))))))))
(defun tramp-do-file-attributes-with-ls (vec localname &optional id-format)
"Implement `file-attributes' for Tramp files using the ls(1) command."
(defun tramp-sh-handle-file-directory-p (filename)
"Like `file-directory-p' for Tramp files."
- ;; Care must be taken that this function returns `t' for symlinks
- ;; pointing to directories. Surely the most obvious implementation
- ;; would be `test -d', but that returns false for such symlinks.
- ;; CCC: Stefan Monnier says that `test -d' follows symlinks. And
- ;; I now think he's right. So we could be using `test -d', couldn't
- ;; we?
- ;;
- ;; Alternatives: `cd %s', `test -d %s'
(with-parsed-tramp-file-name filename nil
- (with-file-property v localname "file-directory-p"
- (tramp-run-test "-d" filename))))
+ ;; `file-directory-p' is used as predicate for filename 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.
+ (or (zerop (length localname))
+ (with-file-property v localname "file-directory-p"
+ (tramp-run-test "-d" filename)))))
(defun tramp-sh-handle-file-writable-p (filename)
"Like `file-writable-p' for Tramp files."
"file-name-all-completions"
nil)))
(when cache-hit (list cache-hit))))
- (tramp-compat-number-sequence (length filename) 0 -1)))))
+ ;; We cannot use a length of 0, because file properties
+ ;; for "foo" and "foo/" are identical.
+ (tramp-compat-number-sequence (length filename) 1 -1)))))
;; Cache expired or no matching cache entry found so we need
;; to perform a remote operation.
(with-current-buffer (tramp-get-buffer v)
(goto-char (point-max))
- ;; Check result code, found in last line of output
+ ;; Check result code, found in last line of output.
(forward-line -1)
(if (looking-at "^fail$")
(progn
;; Grab error message from line before last line
- ;; (it was put there by `cd 2>&1')
+ ;; (it was put there by `cd 2>&1').
(forward-line -1)
(tramp-error
v 'file-error
(push (buffer-substring (point) (point-at-eol)) result)))
;; Because the remote op went through OK we know the
- ;; directory we `cd'-ed to exists
- (tramp-set-file-property
- v localname "file-exists-p" t)
+ ;; directory we `cd'-ed to exists.
+ (tramp-set-file-property v localname "file-exists-p" t)
;; Because the remote op went through OK we know every
;; file listed by `ls' exists.
v (concat localname entry) "file-exists-p" t))
result)
- ;; Store result in the cache
+ ;; Store result in the cache.
(tramp-set-file-property
v (concat localname filename)
- "file-name-all-completions"
- result))))))))
+ "file-name-all-completions" result))))))))
;; cp, mv and ln
(tramp-error
v 'file-already-exists "File %s already exists" newname))
- (with-progress-reporter
+ (tramp-with-progress-reporter
v 0 (format "%s %s to %s"
(if (eq op 'copy) "Copying" "Renaming")
filename newname)
;; password.
(setq tramp-current-method (tramp-file-name-method v)
tramp-current-user (tramp-file-name-user v)
- tramp-current-host (tramp-file-name-host v))
+ tramp-current-host (tramp-file-name-real-host v))
;; Expand hops. Might be necessary for gateway methods.
(setq v (car (tramp-compute-multi-hops v)))
'identity)
(if t2 (tramp-make-copy-program-file-name v) newname)))
- ;; Check for port number. Until now, there's no need for handling
- ;; like method, user, host.
- (setq host (tramp-file-name-real-host v)
- port (tramp-file-name-port v)
- port (or (and port (number-to-string port)) ""))
+ ;; Check for host and port number. We cannot use
+ ;; `tramp-file-name-port', because this returns also
+ ;; `tramp-default-port', which might clash with settings in
+ ;; "~/.ssh/config".
+ (setq host (tramp-file-name-host v)
+ port "")
+ (when (string-match tramp-host-with-port-regexp host)
+ (setq port (string-to-number (match-string 2 host))
+ host (string-to-number (match-string 1 host))))
;; Compose copy command.
(setq spec (format-spec-make
copy-args
(delete
;; " " has either been a replacement of "%k" (when
- ;; keep-date argument is non-nil), or a replacemtent
+ ;; keep-date argument is non-nil), or a replacement
;; for the whole keep-date sublist.
" "
(dolist
(append
copy-args
(let ((y (mapcar (lambda (z) (format-spec z spec)) x)))
- (if (zerop (length (car y))) '(" ") y))))))
+ (if (member "" y) '(" ") y))))))
copy-env
(delq
nil
(tramp-get-method-parameter method 'tramp-copy-env))))
;; Check for program.
- (when (and (fboundp 'executable-find)
- (not (let ((default-directory
- (tramp-compat-temporary-file-directory)))
- (executable-find copy-program))))
+ (unless (let ((default-directory
+ (tramp-compat-temporary-file-directory)))
+ (executable-find copy-program))
(tramp-error
v 'file-error "Cannot find copy program: %s" copy-program))
orig-vec 6 "%s"
(mapconcat 'identity (process-command p) " "))
(tramp-compat-set-process-query-on-exit-flag p nil)
- (tramp-process-actions p v tramp-actions-copy-out-of-band)))
+ (tramp-process-actions
+ p v nil tramp-actions-copy-out-of-band)))
;; Reset the transfer process properties.
(tramp-message orig-vec 6 "%s" (buffer-string))
nil)
((and suffix (nth 2 suffix))
;; We found an uncompression rule.
- (with-progress-reporter v 0 (format "Uncompressing %s" file)
+ (tramp-with-progress-reporter
+ v 0 (format "Uncompressing %s" file)
(when (tramp-send-command-and-check
v (concat (nth 2 suffix) " "
(tramp-shell-quote-argument localname)))
(t
;; We don't recognize the file as compressed, so compress it.
;; Try gzip.
- (with-progress-reporter v 0 (format "Compressing %s" file)
+ (tramp-with-progress-reporter v 0 (format "Compressing %s" file)
(when (tramp-send-command-and-check
v (concat "gzip -f "
(tramp-shell-quote-argument localname)))
(forward-line 1)
(delete-region (match-beginning 0) (point)))
+ ;; Some busyboxes are reluctant to discard colors.
+ (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 "")))
+
;; The inserted file could be from somewhere else.
(when (and (not wildcard) (not full-directory-p))
(goto-char (point-max))
(let ((vec (tramp-get-connection-property proc "vector" nil)))
(when vec
(tramp-message vec 5 "Sentinel called: `%s' `%s'" proc event)
+ (tramp-flush-connection-property proc)
(tramp-flush-directory-property vec "")))))
;; We use BUFFER also as connection buffer during setup. Because of
;; When PROGRAM is nil, we just provide a tty.
(let ((command
(when (stringp program)
- (format "cd %s; exec %s"
+ (format "cd %s; exec env PS1=%s %s"
(tramp-shell-quote-argument localname)
+ ;; Use a human-friendly prompt, for example for `shell'.
+ (tramp-shell-quote-argument
+ (format "%s %s"
+ (file-remote-p default-directory)
+ tramp-initial-end-of-output))
(mapconcat 'tramp-shell-quote-argument
(cons program args) " "))))
(tramp-process-connection-type
v 'file-error
"pty association is not supported for `%s'" name)))))
(let ((p (tramp-get-connection-process v)))
- ;; Set sentinel and query flag for this process.
- (tramp-set-connection-property p "vector" v)
- (set-process-sentinel p 'tramp-process-sentinel)
+ ;; Set query flag for this process.
(tramp-compat-set-process-query-on-exit-flag p t)
;; Return process.
p)))
;; `process-file-side-effects' has been introduced with GNU
;; Emacs 23.2. If set to `nil', no remote file will be changed
;; by `program'. If it doesn't exist, we assume its default
- ;; value 't'.
+ ;; value `t'.
(unless (and (boundp 'process-file-side-effects)
(not (symbol-value 'process-file-side-effects)))
(tramp-flush-directory-property v ""))
(apply 'call-process program tmpfile buffer display args)
(delete-file tmpfile))))
-(defun tramp-sh-handle-shell-command
- (command &optional output-buffer error-buffer)
- "Like `shell-command' for Tramp files."
- (let* ((asynchronous (string-match "[ \t]*&[ \t]*\\'" command))
- ;; We cannot use `shell-file-name' and `shell-command-switch',
- ;; they are variables of the local host.
- (args (list
- (tramp-get-method-parameter
- (tramp-file-name-method
- (tramp-dissect-file-name default-directory))
- 'tramp-remote-sh)
- "-c" (substring command 0 asynchronous)))
- current-buffer-p
- (output-buffer
- (cond
- ((bufferp output-buffer) output-buffer)
- ((stringp output-buffer) (get-buffer-create output-buffer))
- (output-buffer
- (setq current-buffer-p t)
- (current-buffer))
- (t (get-buffer-create
- (if asynchronous
- "*Async Shell Command*"
- "*Shell Command Output*")))))
- (error-buffer
- (cond
- ((bufferp error-buffer) error-buffer)
- ((stringp error-buffer) (get-buffer-create error-buffer))))
- (buffer
- (if (and (not asynchronous) error-buffer)
- (with-parsed-tramp-file-name default-directory nil
- (list output-buffer (tramp-make-tramp-temp-file v)))
- output-buffer))
- (p (get-buffer-process output-buffer)))
-
- ;; Check whether there is another process running. Tramp does not
- ;; support 2 (asynchronous) processes in parallel.
- (when p
- (if (yes-or-no-p "A command is running. Kill it? ")
- (ignore-errors (kill-process p))
- (error "Shell command in progress")))
-
- (if current-buffer-p
- (progn
- (barf-if-buffer-read-only)
- (push-mark nil t))
- (with-current-buffer output-buffer
- (setq buffer-read-only nil)
- (erase-buffer)))
-
- (if (and (not current-buffer-p) (integerp asynchronous))
- (prog1
- ;; Run the process.
- (apply 'start-file-process "*Async Shell*" buffer args)
- ;; Display output.
- (pop-to-buffer output-buffer)
- (setq mode-line-process '(":%s"))
- (shell-mode))
-
- (prog1
- ;; Run the process.
- (apply 'process-file (car args) nil buffer nil (cdr args))
- ;; Insert error messages if they were separated.
- (when (listp buffer)
- (with-current-buffer error-buffer
- (insert-file-contents (cadr buffer)))
- (delete-file (cadr buffer)))
- (if current-buffer-p
- ;; This is like exchange-point-and-mark, but doesn't
- ;; activate the mark. It is cleaner to avoid activation,
- ;; even though the command loop would deactivate the mark
- ;; because we inserted text.
- (goto-char (prog1 (mark t)
- (set-marker (mark-marker) (point)
- (current-buffer))))
- ;; There's some output, display it.
- (when (with-current-buffer output-buffer (> (point-max) (point-min)))
- (if (functionp 'display-message-or-buffer)
- (tramp-compat-funcall 'display-message-or-buffer output-buffer)
- (pop-to-buffer output-buffer))))))))
-
(defun tramp-sh-handle-file-local-copy (filename)
"Like `file-local-copy' for Tramp files."
(with-parsed-tramp-file-name filename nil
;; Use inline encoding for file transfer.
(rem-enc
(save-excursion
- (with-progress-reporter
+ (tramp-with-progress-reporter
v 3 (format "Encoding remote file %s" filename)
(tramp-barf-unless-okay
v (format rem-enc (tramp-shell-quote-argument localname))
(with-temp-buffer
(set-buffer-multibyte nil)
(insert-buffer-substring (tramp-get-buffer v))
- (with-progress-reporter
+ (tramp-with-progress-reporter
v 3 (format "Decoding remote file %s with function %s"
filename loc-dec)
(funcall loc-dec (point-min) (point-max))
(let (file-name-handler-alist
(coding-system-for-write 'binary))
(write-region (point-min) (point-max) tmpfile2))
- (with-progress-reporter
+ (tramp-with-progress-reporter
v 3 (format "Decoding remote file %s with command %s"
filename loc-dec)
(unwind-protect
(set-buffer-multibyte nil)
;; Use encoding function or command.
(if (functionp loc-enc)
- (with-progress-reporter
+ (tramp-with-progress-reporter
v 3 (format "Encoding region using function `%s'"
loc-enc)
(let ((coding-system-for-read 'binary))
(tramp-compat-temporary-file-directory)))
(funcall loc-enc (point-min) (point-max))))
- (with-progress-reporter
+ (tramp-with-progress-reporter
v 3 (format "Encoding region using command `%s'"
loc-enc)
(unless (zerop (tramp-call-local-coding-command
;; Send buffer into remote decoding command which
;; writes to remote file. Because this happens on
;; the remote host, we cannot use the function.
- (with-progress-reporter
+ (tramp-with-progress-reporter
v 3
(format "Decoding region into remote file %s" filename)
(goto-char (point-max))
"Like `vc-registered' for Tramp files."
(tramp-compat-with-temp-message ""
(with-parsed-tramp-file-name file nil
- (with-progress-reporter
+ (tramp-with-progress-reporter
v 3 (format "Checking `vc-registered' for %s" file)
;; There could be new files, created by the vc backend. We
(defun tramp-maybe-send-script (vec script name)
"Define in remote shell function NAME implemented as SCRIPT.
Only send the definition if it has not already been done."
- (let* ((p (tramp-get-connection-process vec))
- (scripts (tramp-get-connection-property p "scripts" nil)))
+ ;; We cannot let-bind (tramp-get-connection-process vec) because it
+ ;; might be nil.
+ (let ((scripts (tramp-get-connection-property
+ (tramp-get-connection-process vec) "scripts" nil)))
(unless (member name scripts)
- (with-progress-reporter vec 5 (format "Sending script `%s'" name)
+ (tramp-with-progress-reporter vec 5 (format "Sending script `%s'" name)
;; The script could contain a call of Perl. This is masked with `%s'.
(tramp-barf-unless-okay
vec
(format "%s () {\n%s\n}" name
(format script (tramp-get-remote-perl vec)))
"Script %s sending failed" name)
- (tramp-set-connection-property p "scripts" (cons name scripts))))))
+ (tramp-set-connection-property
+ (tramp-get-connection-process vec) "scripts" (cons name scripts))))))
(defun tramp-set-auto-save ()
(when (and ;; ange-ftp has its own auto-save mechanism
(defun tramp-open-shell (vec shell)
"Opens shell SHELL."
- (with-progress-reporter vec 5 (format "Opening remote shell `%s'" shell)
+ (tramp-with-progress-reporter
+ vec 5 (format "Opening remote shell `%s'" shell)
;; Find arguments for this shell.
(let ((tramp-end-of-output tramp-initial-end-of-output)
(alist tramp-sh-extra-args)
(when extra-args (setq shell (concat shell " " extra-args)))
(tramp-send-command
vec (format "exec env ENV='' PROMPT_COMMAND='' PS1=%s PS2='' PS3='' %s"
- (shell-quote-argument tramp-end-of-output) shell)
+ (tramp-shell-quote-argument tramp-end-of-output) shell)
t))
;; Setting prompts.
(tramp-send-command
- vec (format "PS1=%s" (shell-quote-argument tramp-end-of-output)) t)
+ 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)))
(tramp-send-command vec "echo ~root" t)
(cond
((or (string-match "^~root$" (buffer-string))
- ;; The default shell (ksh93) of OpenSolaris is buggy.
- (string-equal (tramp-get-connection-property vec "uname" "")
- "SunOS 5.11"))
+ ;; The default shell (ksh93) of OpenSolaris and Solaris
+ ;; is buggy. We've got reports for "SunOS 5.10" and
+ ;; "SunOS 5.11" so far.
+ (string-match (regexp-opt '("SunOS 5.10" "SunOS 5.11"))
+ (tramp-get-connection-property vec "uname" "")))
(setq shell
(or (tramp-find-executable
vec "bash" (tramp-get-remote-path vec) t t)
(tramp-set-connection-property
vec "remote-shell"
(tramp-get-method-parameter
- (tramp-file-name-method vec) 'tramp-remote-sh)))))))))
+ (tramp-file-name-method vec) 'tramp-remote-shell)))))))))
;; Utility functions.
;; discarded as well.
(tramp-open-shell
vec
- (tramp-get-method-parameter (tramp-file-name-method vec) 'tramp-remote-sh))
+ (tramp-get-method-parameter
+ (tramp-file-name-method vec) 'tramp-remote-shell))
;; Disable echo.
(tramp-message vec 5 "Setting up remote shell environment")
(tramp-message vec 5 "Setting shell prompt")
(tramp-send-command
- vec (format "PS1=%s" (shell-quote-argument tramp-end-of-output)) t)
+ 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)
(tramp-send-command vec "stty -oxtabs" t))
;; Set `remote-tty' process property.
- (ignore-errors
- (let ((tty (tramp-send-command-and-read vec "echo \\\"`tty`\\\"")))
- (unless (zerop (length tty))
- (tramp-compat-process-put proc 'remote-tty tty))))
+ (let ((tty (tramp-send-command-and-read vec "echo \\\"`tty`\\\"" 'noerror)))
+ (unless (zerop (length tty))
+ (tramp-compat-process-put proc 'remote-tty tty)))
;; Dump stty settings in the traces.
(when (>= tramp-verbose 9)
(defconst tramp-inline-compress-commands
'(("gzip" "gzip -d")
("bzip2" "bzip2 -d")
+ ("xz" "xz -d")
("compress" "compress -d"))
"List of compress and decompress commands for inline transfer.
Each item is a list that looks like this:
(catch 'uname-changed
(let ((p (tramp-get-connection-process vec))
(process-name (tramp-get-connection-property vec "process-name" nil))
- (process-environment (copy-sequence process-environment)))
+ (process-environment (copy-sequence process-environment))
+ (pos (with-current-buffer (tramp-get-connection-buffer vec) (point))))
;; If too much time has passed since last command was sent, look
;; whether process is still alive. If it isn't, kill it. When
;; We call `tramp-get-buffer' in order to get a debug buffer for
;; messages from the beginning.
(tramp-get-buffer vec)
- (with-progress-reporter
+ (tramp-with-progress-reporter
vec 3
(if (zerop (length (tramp-file-name-user vec)))
(format "Opening connection for %s using %s"
;; This must be done in order to avoid our file name handler.
(p (let ((default-directory
(tramp-compat-temporary-file-directory)))
- (start-process
+ (apply
+ 'start-process
(tramp-get-connection-name vec)
(tramp-get-connection-buffer vec)
- tramp-encoding-shell))))
+ (if tramp-encoding-command-interactive
+ (list tramp-encoding-shell
+ tramp-encoding-command-interactive)
+ (list tramp-encoding-shell))))))
+
+ ;; Set sentinel and query flag.
+ (tramp-set-connection-property p "vector" vec)
+ (set-process-sentinel p 'tramp-process-sentinel)
+ (tramp-compat-set-process-query-on-exit-flag p nil)
(tramp-message
vec 6 "%s" (mapconcat 'identity (process-command p) " "))
;; Check whether process is alive.
- (tramp-compat-set-process-query-on-exit-flag p nil)
(tramp-barf-if-no-shell-prompt
p 60 "Couldn't find local shell prompt %s" tramp-encoding-shell)
(gw (tramp-get-file-property hop "" "gateway" nil))
(g-method (and gw (tramp-file-name-method gw)))
(g-user (and gw (tramp-file-name-user gw)))
- (g-host (and gw (tramp-file-name-host gw)))
+ (g-host (and gw (tramp-file-name-real-host gw)))
(command login-program)
;; We don't create the temporary file. In fact,
;; it is just a prefix for the ControlPath option
(tramp-compat-temporary-file-directory)))))
spec)
- ;; Add arguments for asynchrononous processes.
+ ;; Add arguments for asynchronous processes.
(when (and process-name async-args)
(setq login-args (append async-args login-args)))
;; Send the command.
(tramp-message vec 3 "Sending command `%s'" command)
(tramp-send-command vec command t t)
- (tramp-process-actions p vec tramp-actions-before-shell 60)
+ (tramp-process-actions p vec pos tramp-actions-before-shell 60)
(tramp-message
vec 3 "Found remote shell prompt on `%s'" l-host))
;; Next hop.
"Run COMMAND, check exit status, throw error if exit status not okay.
Similar to `tramp-send-command-and-check' but accepts two more arguments
FMT and ARGS which are passed to `error'."
- (unless (tramp-send-command-and-check vec command)
- (apply 'tramp-error vec 'file-error fmt args)))
+ (or (tramp-send-command-and-check vec command)
+ (apply 'tramp-error vec 'file-error fmt args)))
-(defun tramp-send-command-and-read (vec command)
+(defun tramp-send-command-and-read (vec command &optional noerror)
"Run COMMAND and return the output, which must be a Lisp expression.
-In case there is no valid Lisp expression, it raises an error"
- (tramp-barf-unless-okay vec command "`%s' returns with error" command)
- (with-current-buffer (tramp-get-connection-buffer vec)
- ;; Read the expression.
- (goto-char (point-min))
- (condition-case nil
- (prog1 (read (current-buffer))
- ;; Error handling.
- (when (re-search-forward "\\S-" (point-at-eol) t)
- (error nil)))
- (error (tramp-error
- vec 'file-error
- "`%s' does not return a valid Lisp expression: `%s'"
- command (buffer-string))))))
+In case there is no valid Lisp expression and NOERROR is nil, it
+raises an error."
+ (when (if noerror
+ (tramp-send-command-and-check vec command)
+ (tramp-barf-unless-okay
+ vec command "`%s' returns with error" command))
+ (with-current-buffer (tramp-get-connection-buffer vec)
+ ;; Read the expression.
+ (goto-char (point-min))
+ (condition-case nil
+ (prog1 (read (current-buffer))
+ ;; Error handling.
+ (when (re-search-forward "\\S-" (point-at-eol) t)
+ (error nil)))
+ (error (unless noerror
+ (tramp-error
+ vec 'file-error
+ "`%s' does not return a valid Lisp expression: `%s'"
+ command (buffer-string))))))))
(defun tramp-convert-file-attributes (vec attr)
"Convert file-attributes ATTR generated by perl script, stat or ls.
Convert file mode bits to string and set virtual device number.
Return ATTR."
(when attr
+ ;; Remove color escape sequences from symlink.
+ (when (stringp (car attr))
+ (while (string-match tramp-color-escape-sequence-regexp (car attr))
+ (setcar attr (replace-match "" nil nil (car attr)))))
;; Convert last access time.
(unless (listp (nth 4 attr))
(setcar (nthcdr 4 attr)
(and
;; It shall be an out-of-band method.
(tramp-get-method-parameter (tramp-file-name-method vec) 'tramp-copy-program)
+ ;; There must be a size, otherwise the file doesn't exist.
+ (numberp size)
;; Either the file size is large enough, or (in rare cases) there
;; does not exist a remote encoding.
(or (null tramp-copy-size-limit)
(when elt1
(or
(tramp-send-command-and-read
- vec
- "x=`getconf PATH 2>/dev/null` && echo \\\"$x\\\" || echo nil")
+ vec "echo \\\"`getconf PATH 2>/dev/null`\\\"" 'noerror)
;; Default if "getconf" is not available.
(progn
(tramp-message
x))
remote-path)))))
-(defun tramp-get-remote-tmpdir (vec)
- (with-connection-property vec "tmp-directory"
- (let ((dir (tramp-shell-quote-argument "/tmp")))
- (if (and (tramp-send-command-and-check
- vec (format "%s -d %s" (tramp-get-test-command vec) dir))
- (tramp-send-command-and-check
- vec (format "%s -w %s" (tramp-get-test-command vec) dir)))
- dir
- (tramp-error vec 'file-error "Directory %s not accessible" dir)))))
-
(defun tramp-get-ls-command (vec)
(with-connection-property vec "ls"
(tramp-message vec 5 "Finding a suitable `ls' command")
(let ((result (tramp-find-executable
vec "stat" (tramp-get-remote-path vec)))
tmp)
- ;; Check whether stat(1) returns usable syntax. %s does not
+ ;; Check whether stat(1) returns usable syntax. "%s" does not
;; work on older AIX systems.
(when result
(setq tmp
- ;; We don't want to display an error message.
- (tramp-compat-with-temp-message (or (current-message) "")
- (ignore-errors
- (tramp-send-command-and-read
- vec (format "%s -c '(\"%%N\" %%s)' /" result)))))
+ (tramp-send-command-and-read
+ vec (format "%s -c '(\"%%N\" %%s)' /" result) 'noerror))
(unless (and (listp tmp) (stringp (car tmp))
(string-match "^./.$" (car tmp))
(integerp (cadr tmp)))
(let ((result (tramp-find-executable
vec "readlink" (tramp-get-remote-path vec))))
(when (and result
- ;; We don't want to display an error message.
- (tramp-compat-with-temp-message (or (current-message) "")
- (ignore-errors
- (tramp-send-command-and-check
- vec (format "%s --canonicalize-missing /" result)))))
+ (tramp-send-command-and-check
+ vec (format "%s --canonicalize-missing /" result)))
result))))
(defun tramp-get-remote-trash (vec)