X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/266a86bd7fedf743225c2497956b73ecb2245196..8d68c659a6e79745bc1350252751803cecb0e150:/lisp/net/tramp-sh.el diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 423b4fcbd5..9950709bd7 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -67,7 +67,7 @@ files conditionalize this setup based on the TERM environment variable." :group 'tramp :type 'string) -;; ksh on OpenBSD 4.5 requires, that PS1 contains a `#' character for +;; 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. @@ -91,7 +91,7 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-login-args (("%h") ("-l" "%u"))) (tramp-remote-sh "/bin/sh") (tramp-copy-program "rcp") - (tramp-copy-args (("-p" "%k") ("-r"))) + (tramp-copy-args (("%k" "-p") ("-r"))) (tramp-copy-keep-date t) (tramp-copy-recursive t))) ;;;###tramp-autoload @@ -101,17 +101,17 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-login-args (("%h") ("-l" "%u"))) (tramp-remote-sh "/bin/sh") (tramp-copy-program "rcp") - (tramp-copy-args (("-p" "%k"))) + (tramp-copy-args (("%k" "-p"))) (tramp-copy-keep-date t))) ;;;###tramp-autoload -(add-to-list - 'tramp-methods - '("scp" (tramp-login-program "ssh") +(add-to-list 'tramp-methods + '("scp" + (tramp-login-program "ssh") (tramp-login-args (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) (tramp-remote-sh "/bin/sh") (tramp-copy-program "scp") - (tramp-copy-args (("-P" "%p") ("-p" "%k") ("-q") ("-r"))) + (tramp-copy-args (("-P" "%p") ("%k" "-p") ("-q") ("-r"))) (tramp-copy-keep-date t) (tramp-copy-recursive t) (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null") @@ -127,7 +127,7 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-async-args (("-q"))) (tramp-remote-sh "/bin/sh") (tramp-copy-program "scp") - (tramp-copy-args (("-1") ("-P" "%p") ("-p" "%k") ("-q") ("-r"))) + (tramp-copy-args (("-1") ("-P" "%p") ("%k" "-p") ("-q") ("-r"))) (tramp-copy-keep-date t) (tramp-copy-recursive t) (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null") @@ -143,7 +143,7 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-async-args (("-q"))) (tramp-remote-sh "/bin/sh") (tramp-copy-program "scp") - (tramp-copy-args (("-2") ("-P" "%p") ("-p" "%k") ("-q") ("-r"))) + (tramp-copy-args (("-2") ("-P" "%p") ("%k" "-p") ("-q") ("-r"))) (tramp-copy-keep-date t) (tramp-copy-recursive t) (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null") @@ -161,10 +161,11 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-async-args (("-q"))) (tramp-remote-sh "/bin/sh") (tramp-copy-program "scp") - (tramp-copy-args (("-P" "%p") ("-p" "%k") ("-q") + (tramp-copy-args (("-P" "%p") ("%k" "-p") ("-q") ("-r") ("-o" "ControlPath=%t.%%r@%%h:%%p") ("-o" "ControlMaster=auto"))) (tramp-copy-keep-date t) + (tramp-copy-recursive t) (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null") ("-o" "UserKnownHostsFile=/dev/null") ("-o" "StrictHostKeyChecking=no"))) @@ -179,8 +180,9 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-async-args (("-q"))) (tramp-remote-sh "/bin/sh") (tramp-copy-program "scp") - (tramp-copy-args (("-p" "%k"))) + (tramp-copy-args (("-P" "%p") ("%k" "-p") ("-q") ("-r"))) (tramp-copy-keep-date t) + (tramp-copy-recursive t) (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null") ("-o" "UserKnownHostsFile=/dev/null") ("-o" "StrictHostKeyChecking=no"))) @@ -201,7 +203,7 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-async-args (("-q"))) (tramp-remote-sh "/bin/sh") (tramp-copy-program "rsync") - (tramp-copy-args (("-e" "ssh") ("-t" "%k") ("-r"))) + (tramp-copy-args (("-e" "ssh") ("%k" "-t") ("-r"))) (tramp-copy-keep-date t) (tramp-copy-keep-tmpfile t) (tramp-copy-recursive t))) @@ -216,7 +218,7 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-async-args (("-q"))) (tramp-remote-sh "/bin/sh") (tramp-copy-program "rsync") - (tramp-copy-args (("-t" "%k") ("-r"))) + (tramp-copy-args (("%k" "-t") ("-r"))) (tramp-copy-env (("RSYNC_RSH") (,(concat "ssh" @@ -305,6 +307,12 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-login-args (("-u" "%u") ("-s") ("-H") ("-p" "Password:"))) (tramp-remote-sh "/bin/sh"))) ;;;###tramp-autoload +(add-to-list 'tramp-methods + '("ksu" + (tramp-login-program "ksu") + (tramp-login-args (("%u") ("-q"))) + (tramp-remote-sh "/bin/sh"))) +;;;###tramp-autoload (add-to-list 'tramp-methods '("krlogin" (tramp-login-program "krlogin") @@ -346,8 +354,10 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%h"))) (tramp-remote-sh "/bin/sh") (tramp-copy-program "pscp") - (tramp-copy-args (("-P" "%p") ("-scp") ("-p" "%k"))) + (tramp-copy-args (("-P" "%p") ("-scp") ("%k" "-p") + ("-q") ("-r"))) (tramp-copy-keep-date t) + (tramp-copy-recursive t) (tramp-password-end-of-line "xy") ;see docstring for "xy" (tramp-default-port 22))) ;;;###tramp-autoload @@ -357,8 +367,10 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%h"))) (tramp-remote-sh "/bin/sh") (tramp-copy-program "pscp") - (tramp-copy-args (("-P" "%p") ("-sftp") ("-p" "%k"))) + (tramp-copy-args (("-P" "%p") ("-sftp") ("%k" "-p") + ("-q") ("-r"))) (tramp-copy-keep-date t) + (tramp-copy-recursive t) (tramp-password-end-of-line "xy"))) ;see docstring for "xy" ;;;###tramp-autoload (add-to-list 'tramp-methods @@ -367,16 +379,26 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-login-args (("%h") ("-l" "%u") ("sh" "-i"))) (tramp-remote-sh "/bin/sh -i") (tramp-copy-program "fcp") - (tramp-copy-args (("-p" "%k"))) + (tramp-copy-args (("%k" "-p"))) (tramp-copy-keep-date t))) +;;;###tramp-autoload (add-to-list 'tramp-default-method-alist `(,tramp-local-host-regexp "\\`root\\'" "su")) +;;;###tramp-autoload (add-to-list 'tramp-default-user-alist - '("\\`su\\(do\\)?\\'" nil "root")) + `(,(concat "\\`" (regexp-opt '("su" "sudo" "ksu")) "\\'") + nil "root")) +;; Do not add "ssh" based methods, otherwise ~/.ssh/config would be ignored. +;;;###tramp-autoload (add-to-list 'tramp-default-user-alist - `("\\`r\\(em\\)?\\(cp\\|sh\\)\\|telnet\\|plink1?\\'" + `(,(concat + "\\`" + (regexp-opt + '("rcp" "remcp" "rsh" "telnet" "krlogin" + "plink" "plink1" "pscp" "psftp" "fcp")) + "\\'") nil ,(user-login-name))) (defconst tramp-completion-function-alist-rsh @@ -433,6 +455,7 @@ detected as prompt when being sent on echoing hosts, therefore.") (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) @@ -620,7 +643,7 @@ passed to `format', so percent characters need to be doubled.") ;; unless this spits out a complete line, including the '\n' at the ;; end. ;; The device number is returned as "-1", because there will be a virtual -;; device number set in `tramp-handle-file-attributes'. +;; device number set in `tramp-sh-handle-file-attributes'. (defconst tramp-perl-file-attributes "%s -e ' @stat = lstat($ARGV[0]); @@ -867,62 +890,63 @@ This is used to map a mode number to a permission string.") ;; get-file-buffer. (defconst tramp-sh-file-name-handler-alist '((load . tramp-handle-load) - (make-symbolic-link . tramp-handle-make-symbolic-link) + (make-symbolic-link . tramp-sh-handle-make-symbolic-link) (file-name-as-directory . tramp-handle-file-name-as-directory) (file-name-directory . tramp-handle-file-name-directory) (file-name-nondirectory . tramp-handle-file-name-nondirectory) - (file-truename . tramp-handle-file-truename) - (file-exists-p . tramp-handle-file-exists-p) - (file-directory-p . tramp-handle-file-directory-p) - (file-executable-p . tramp-handle-file-executable-p) - (file-readable-p . tramp-handle-file-readable-p) + (file-truename . tramp-sh-handle-file-truename) + (file-exists-p . tramp-sh-handle-file-exists-p) + (file-directory-p . tramp-sh-handle-file-directory-p) + (file-executable-p . tramp-sh-handle-file-executable-p) + (file-readable-p . tramp-sh-handle-file-readable-p) (file-regular-p . tramp-handle-file-regular-p) (file-symlink-p . tramp-handle-file-symlink-p) - (file-writable-p . tramp-handle-file-writable-p) - (file-ownership-preserved-p . tramp-handle-file-ownership-preserved-p) - (file-newer-than-file-p . tramp-handle-file-newer-than-file-p) - (file-attributes . tramp-handle-file-attributes) + (file-writable-p . tramp-sh-handle-file-writable-p) + (file-ownership-preserved-p . tramp-sh-handle-file-ownership-preserved-p) + (file-newer-than-file-p . tramp-sh-handle-file-newer-than-file-p) + (file-attributes . tramp-sh-handle-file-attributes) (file-modes . tramp-handle-file-modes) (directory-files . tramp-handle-directory-files) - (directory-files-and-attributes . tramp-handle-directory-files-and-attributes) - (file-name-all-completions . tramp-handle-file-name-all-completions) + (directory-files-and-attributes + . tramp-sh-handle-directory-files-and-attributes) + (file-name-all-completions . tramp-sh-handle-file-name-all-completions) (file-name-completion . tramp-handle-file-name-completion) - (add-name-to-file . tramp-handle-add-name-to-file) - (copy-file . tramp-handle-copy-file) - (copy-directory . tramp-handle-copy-directory) - (rename-file . tramp-handle-rename-file) - (set-file-modes . tramp-handle-set-file-modes) - (set-file-times . tramp-handle-set-file-times) - (make-directory . tramp-handle-make-directory) - (delete-directory . tramp-handle-delete-directory) - (delete-file . tramp-handle-delete-file) + (add-name-to-file . tramp-sh-handle-add-name-to-file) + (copy-file . tramp-sh-handle-copy-file) + (copy-directory . tramp-sh-handle-copy-directory) + (rename-file . tramp-sh-handle-rename-file) + (set-file-modes . tramp-sh-handle-set-file-modes) + (set-file-times . tramp-sh-handle-set-file-times) + (make-directory . tramp-sh-handle-make-directory) + (delete-directory . tramp-sh-handle-delete-directory) + (delete-file . tramp-sh-handle-delete-file) (directory-file-name . tramp-handle-directory-file-name) ;; `executable-find' is not official yet. - (executable-find . tramp-handle-executable-find) - (start-file-process . tramp-handle-start-file-process) - (process-file . tramp-handle-process-file) - (shell-command . tramp-handle-shell-command) - (insert-directory . tramp-handle-insert-directory) - (expand-file-name . tramp-handle-expand-file-name) + (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) + (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) - (file-local-copy . tramp-handle-file-local-copy) + (file-local-copy . tramp-sh-handle-file-local-copy) (file-remote-p . tramp-handle-file-remote-p) (insert-file-contents . tramp-handle-insert-file-contents) (insert-file-contents-literally - . tramp-handle-insert-file-contents-literally) - (write-region . tramp-handle-write-region) + . tramp-sh-handle-insert-file-contents-literally) + (write-region . tramp-sh-handle-write-region) (find-backup-file-name . tramp-handle-find-backup-file-name) - (make-auto-save-file-name . tramp-handle-make-auto-save-file-name) + (make-auto-save-file-name . tramp-sh-handle-make-auto-save-file-name) (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory) - (dired-compress-file . tramp-handle-dired-compress-file) + (dired-compress-file . tramp-sh-handle-dired-compress-file) (dired-recursive-delete-directory - . tramp-handle-dired-recursive-delete-directory) + . tramp-sh-handle-dired-recursive-delete-directory) (dired-uncache . tramp-handle-dired-uncache) - (set-visited-file-modtime . tramp-handle-set-visited-file-modtime) - (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime) - (file-selinux-context . tramp-handle-file-selinux-context) - (set-file-selinux-context . tramp-handle-set-file-selinux-context) - (vc-registered . tramp-handle-vc-registered)) + (set-visited-file-modtime . tramp-sh-handle-set-visited-file-modtime) + (verify-visited-file-modtime . tramp-sh-handle-verify-visited-file-modtime) + (file-selinux-context . tramp-sh-handle-file-selinux-context) + (set-file-selinux-context . tramp-sh-handle-set-file-selinux-context) + (vc-registered . tramp-sh-handle-vc-registered)) "Alist of handler functions. Operations not mentioned here will be handled by the normal Emacs functions.") @@ -933,7 +957,7 @@ Operations not mentioned here will be handled by the normal Emacs functions.") ;;; File Name Handler Functions: -(defun tramp-handle-make-symbolic-link +(defun tramp-sh-handle-make-symbolic-link (filename linkname &optional ok-if-already-exists) "Like `make-symbolic-link' for Tramp files. If LINKNAME is a non-Tramp file, it is used verbatim as the target of @@ -988,71 +1012,7 @@ target of the symlink differ." (tramp-shell-quote-argument l-localname)) t)))) -(defun tramp-handle-load (file &optional noerror nomessage nosuffix must-suffix) - "Like `load' for Tramp files." - (with-parsed-tramp-file-name (expand-file-name file) nil - (unless nosuffix - (cond ((file-exists-p (concat file ".elc")) - (setq file (concat file ".elc"))) - ((file-exists-p (concat file ".el")) - (setq file (concat file ".el"))))) - (when must-suffix - ;; The first condition is always true for absolute file names. - ;; Included for safety's sake. - (unless (or (file-name-directory file) - (string-match "\\.elc?\\'" file)) - (tramp-error - v 'file-error - "File `%s' does not include a `.el' or `.elc' suffix" file))) - (unless noerror - (when (not (file-exists-p file)) - (tramp-error v 'file-error "Cannot load nonexistent file `%s'" file))) - (if (not (file-exists-p file)) - nil - (let ((tramp-message-show-message (not nomessage))) - (with-progress-reporter v 0 (format "Loading %s" file) - (let ((local-copy (file-local-copy file))) - ;; MUST-SUFFIX doesn't exist on XEmacs, so let it default to nil. - (unwind-protect - (load local-copy noerror t t) - (delete-file local-copy))))) - t))) - -;; Localname manipulation functions that grok Tramp localnames... -(defun tramp-handle-file-name-as-directory (file) - "Like `file-name-as-directory' but aware of Tramp files." - ;; `file-name-as-directory' would be sufficient except localname is - ;; the empty string. - (let ((v (tramp-dissect-file-name file t))) - ;; Run the command on the localname portion only. - (tramp-make-tramp-file-name - (tramp-file-name-method v) - (tramp-file-name-user v) - (tramp-file-name-host v) - (tramp-run-real-handler - 'file-name-as-directory (list (or (tramp-file-name-localname v) "")))))) - -(defun tramp-handle-file-name-directory (file) - "Like `file-name-directory' but aware of Tramp files." - ;; Everything except the last filename thing is the directory. We - ;; cannot apply `with-parsed-tramp-file-name', because this expands - ;; the remote file name parts. This is a problem when we are in - ;; file name completion. - (let ((v (tramp-dissect-file-name file t))) - ;; Run the command on the localname portion only. - (tramp-make-tramp-file-name - (tramp-file-name-method v) - (tramp-file-name-user v) - (tramp-file-name-host v) - (tramp-run-real-handler - 'file-name-directory (list (or (tramp-file-name-localname v) "")))))) - -(defun tramp-handle-file-name-nondirectory (file) - "Like `file-name-nondirectory' but aware of Tramp files." - (with-parsed-tramp-file-name file nil - (tramp-run-real-handler 'file-name-nondirectory (list localname)))) - -(defun tramp-handle-file-truename (filename &optional counter prev-dirs) +(defun tramp-sh-handle-file-truename (filename &optional counter prev-dirs) "Like `file-truename' for Tramp files." (with-parsed-tramp-file-name (expand-file-name filename) nil (with-file-property v localname "file-truename" @@ -1158,7 +1118,7 @@ target of the symlink differ." ;; Basic functions. -(defun tramp-handle-file-exists-p (filename) +(defun tramp-sh-handle-file-exists-p (filename) "Like `file-exists-p' for Tramp files." (with-parsed-tramp-file-name filename nil (with-file-property v localname "file-exists-p" @@ -1176,7 +1136,7 @@ target of the symlink differ." ;; CCC: This should check for an error condition and signal failure ;; when something goes wrong. ;; Daniel Pittman -(defun tramp-handle-file-attributes (filename &optional id-format) +(defun tramp-sh-handle-file-attributes (filename &optional id-format) "Like `file-attributes' for Tramp files." (unless id-format (setq id-format 'integer)) ;; Don't modify `last-coding-system-used' by accident. @@ -1252,8 +1212,7 @@ target of the symlink differ." ;; if symlink, find out file name pointed to (when symlinkp (search-forward "-> ") - (setq res-symlink-target - (buffer-substring (point) (tramp-compat-line-end-position)))) + (setq res-symlink-target (buffer-substring (point) (point-at-eol)))) ;; return data gathered (list ;; 0. t for directory, string (name linked to) for symbolic @@ -1304,7 +1263,7 @@ target of the symlink differ." (format ;; On Opsware, pdksh (which is the true name of ksh there) doesn't ;; parse correctly the sequence "((". Therefore, we add a space. - "( (%s %s || %s -h %s) && %s -c '( (\"%%N\") %%h %s %s %%X.0 %%Y.0 %%Z.0 %%s.0 \"%%A\" t %%i.0 -1)' %s || echo nil)" + "( (%s %s || %s -h %s) && %s -c '((\"%%N\") %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 \"%%A\" t %%ie0 -1)' %s || echo nil)" (tramp-get-file-exists-command vec) (tramp-shell-quote-argument localname) (tramp-get-test-command vec) @@ -1314,7 +1273,7 @@ target of the symlink differ." (if (eq id-format 'integer) "%g" "\"%G\"") (tramp-shell-quote-argument localname)))) -(defun tramp-handle-set-visited-file-modtime (&optional time-list) +(defun tramp-sh-handle-set-visited-file-modtime (&optional time-list) "Like `set-visited-file-modtime' for Tramp files." (unless (buffer-file-name) (error "Can't set-visited-file-modtime: buffer `%s' not visiting a file" @@ -1348,8 +1307,8 @@ target of the symlink differ." nil))))) ;; This function makes the same assumption as -;; `tramp-handle-set-visited-file-modtime'. -(defun tramp-handle-verify-visited-file-modtime (buf) +;; `tramp-sh-handle-set-visited-file-modtime'. +(defun tramp-sh-handle-verify-visited-file-modtime (buf) "Like `verify-visited-file-modtime' for Tramp files. At the time `verify-visited-file-modtime' calls this function, we already know that the buffer is visiting a file and that @@ -1366,8 +1325,8 @@ of." (not (tramp-file-name-handler 'file-remote-p f nil 'connected))) t (with-parsed-tramp-file-name f nil - (tramp-flush-file-property v localname) - (let* ((attr (file-attributes f)) + (let* ((remote-file-name-inhibit-cache t) + (attr (file-attributes f)) (modtime (nth 5 attr)) (mt (visited-file-modtime))) @@ -1401,7 +1360,7 @@ of." ;; only if that agrees with the buffer's record. (t (equal mt '(-1 65535)))))))))) -(defun tramp-handle-set-file-modes (filename mode) +(defun tramp-sh-handle-set-file-modes (filename mode) "Like `set-file-modes' for Tramp files." (with-parsed-tramp-file-name filename nil (tramp-flush-file-property v localname) @@ -1413,7 +1372,7 @@ of." (tramp-shell-quote-argument localname)) "Error while changing file's mode %s" filename))) -(defun tramp-handle-set-file-times (filename &optional time) +(defun tramp-sh-handle-set-file-times (filename &optional time) "Like `set-file-times' for Tramp files." (if (file-remote-p filename) (with-parsed-tramp-file-name filename nil @@ -1486,7 +1445,7 @@ and gid of the corresponding user is taken. Both parameters must be integers." vec (format "echo \\\"`%S`\\\"" result)) "Enforcing"))))) -(defun tramp-handle-file-selinux-context (filename) +(defun tramp-sh-handle-file-selinux-context (filename) "Like `file-selinux-context' for Tramp files." (with-parsed-tramp-file-name filename nil (with-file-property v localname "file-selinux-context" @@ -1501,13 +1460,13 @@ and gid of the corresponding user is taken. Both parameters must be integers." (tramp-shell-quote-argument localname)))) (with-current-buffer (tramp-get-connection-buffer v) (goto-char (point-min)) - (when (re-search-forward regexp (tramp-compat-line-end-position) t) + (when (re-search-forward regexp (point-at-eol) t) (setq context (list (match-string 1) (match-string 2) (match-string 3) (match-string 4)))))) ;; Return the context. context)))) -(defun tramp-handle-set-file-selinux-context (filename context) +(defun tramp-sh-handle-set-file-selinux-context (filename context) "Like `set-file-selinux-context' for Tramp files." (with-parsed-tramp-file-name filename nil (if (and (consp context) @@ -1530,7 +1489,7 @@ and gid of the corresponding user is taken. Both parameters must be integers." ;; Simple functions using the `test' command. -(defun tramp-handle-file-executable-p (filename) +(defun tramp-sh-handle-file-executable-p (filename) "Like `file-executable-p' for Tramp files." (with-parsed-tramp-file-name filename nil (with-file-property v localname "file-executable-p" @@ -1539,7 +1498,7 @@ and gid of the corresponding user is taken. Both parameters must be integers." (or (tramp-check-cached-permissions v ?x) (tramp-run-test "-x" filename))))) -(defun tramp-handle-file-readable-p (filename) +(defun tramp-sh-handle-file-readable-p (filename) "Like `file-readable-p' for Tramp files." (with-parsed-tramp-file-name filename nil (with-file-property v localname "file-readable-p" @@ -1553,7 +1512,7 @@ and gid of the corresponding user is taken. Both parameters must be integers." ;; expansion will also provide a `test' command which groks `-nt' (for ;; newer than). If this breaks, tell me about it and I'll try to do ;; something smarter about it. -(defun tramp-handle-file-newer-than-file-p (file1 file2) +(defun tramp-sh-handle-file-newer-than-file-p (file1 file2) "Like `file-newer-than-file-p' for Tramp files." (cond ((not (file-exists-p file1)) nil) @@ -1588,13 +1547,7 @@ and gid of the corresponding user is taken. Both parameters must be integers." ;; Functions implemented using the basic functions above. -(defun tramp-handle-file-modes (filename) - "Like `file-modes' for Tramp files." - (let ((truename (or (file-truename filename) filename))) - (when (file-exists-p truename) - (tramp-mode-string-to-int (nth 8 (file-attributes truename)))))) - -(defun tramp-handle-file-directory-p (filename) +(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 @@ -1608,23 +1561,7 @@ and gid of the corresponding user is taken. Both parameters must be integers." (with-file-property v localname "file-directory-p" (tramp-run-test "-d" filename)))) -(defun tramp-handle-file-regular-p (filename) - "Like `file-regular-p' for Tramp files." - (and (file-exists-p filename) - (eq ?- (aref (nth 8 (file-attributes filename)) 0)))) - -(defun tramp-handle-file-symlink-p (filename) - "Like `file-symlink-p' for Tramp files." - (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))))) - -(defun tramp-handle-file-writable-p (filename) +(defun tramp-sh-handle-file-writable-p (filename) "Like `file-writable-p' for Tramp files." (with-parsed-tramp-file-name filename nil (with-file-property v localname "file-writable-p" @@ -1637,7 +1574,7 @@ and gid of the corresponding user is taken. Both parameters must be integers." (and (tramp-run-test "-d" (file-name-directory filename)) (tramp-run-test "-w" (file-name-directory filename))))))) -(defun tramp-handle-file-ownership-preserved-p (filename) +(defun tramp-sh-handle-file-ownership-preserved-p (filename) "Like `file-ownership-preserved-p' for Tramp files." (with-parsed-tramp-file-name filename nil (with-file-property v localname "file-ownership-preserved-p" @@ -1647,45 +1584,9 @@ and gid of the corresponding user is taken. Both parameters must be integers." (or (null attributes) (= (nth 2 attributes) (tramp-get-remote-uid v 'integer))))))) -;; Other file name ops. - -(defun tramp-handle-directory-file-name (directory) - "Like `directory-file-name' for Tramp files." - ;; If localname component of filename is "/", leave it unchanged. - ;; Otherwise, remove any trailing slash from localname component. - ;; Method, host, etc, are unchanged. Does it make sense to try - ;; to avoid parsing the filename? - (with-parsed-tramp-file-name directory nil - (if (and (not (zerop (length localname))) - (eq (aref localname (1- (length localname))) ?/) - (not (string= localname "/"))) - (substring directory 0 -1) - directory))) - ;; Directory listings. -(defun tramp-handle-directory-files - (directory &optional full match nosort files-only) - "Like `directory-files' for Tramp files." - ;; FILES-ONLY is valid for XEmacs only. - (when (file-directory-p directory) - (setq directory (file-name-as-directory (expand-file-name directory))) - (let ((temp (nreverse (file-name-all-completions "" directory))) - result item) - - (while temp - (setq item (directory-file-name (pop temp))) - (when (and (or (null match) (string-match match item)) - (or (null files-only) - ;; Files only. - (and (equal files-only t) (file-regular-p item)) - ;; Directories only. - (file-directory-p item))) - (push (if full (concat directory item) item) - result))) - (if nosort result (sort result 'string<))))) - -(defun tramp-handle-directory-files-and-attributes +(defun tramp-sh-handle-directory-files-and-attributes (directory &optional full match nosort id-format) "Like `directory-files-and-attributes' for Tramp files." (unless id-format (setq id-format 'integer)) @@ -1750,7 +1651,7 @@ and gid of the corresponding user is taken. Both parameters must be integers." ;; but it does not work on all remote systems. Therefore, we ;; quote the filenames via sed. "cd %s; echo \"(\"; (%s -a | sed -e s/\\$/\\\"/g -e s/^/\\\"/g | xargs " - "%s -c '(\"%%n\" (\"%%N\") %%h %s %s %%X.0 %%Y.0 %%Z.0 %%s.0 \"%%A\" t %%i.0 -1)'); " + "%s -c '(\"%%n\" (\"%%N\") %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 \"%%A\" t %%ie0 -1)'); " "echo \")\"") (tramp-shell-quote-argument localname) (tramp-get-ls-command vec) @@ -1760,7 +1661,7 @@ and gid of the corresponding user is taken. Both parameters must be integers." ;; This function should return "foo/" for directories and "bar" for ;; files. -(defun tramp-handle-file-name-all-completions (filename directory) +(defun tramp-sh-handle-file-name-all-completions (filename directory) "Like `file-name-all-completions' for Tramp files." (unless (save-match-data (string-match "/" filename)) (with-parsed-tramp-file-name (expand-file-name directory) nil @@ -1770,46 +1671,39 @@ and gid of the corresponding user is taken. Both parameters must be integers." (mapcar 'list (or - ;; Try cache first - (and - ;; Ignore if expired - (or (not (integerp tramp-completion-reread-directory-timeout)) - (<= (tramp-time-diff - (current-time) - (tramp-get-file-property - v localname "last-completion" '(0 0 0))) - tramp-completion-reread-directory-timeout)) - - ;; 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 - - ;; This is inefficient for very long filenames, pity - ;; `reduce' is not available... - (car - (apply - 'append - (mapcar - (lambda (x) - (let ((cache-hit - (tramp-get-file-property - v - (concat localname (substring filename 0 x)) - "file-name-all-completions" - nil))) - (when cache-hit (list cache-hit)))) - (tramp-compat-number-sequence (length filename) 0 -1))))) + ;; 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 + ;; `reduce' is not available... + (car + (apply + 'append + (mapcar + (lambda (x) + (let ((cache-hit + (tramp-get-file-property + v + (concat localname (substring filename 0 x)) + "file-name-all-completions" + nil))) + (when cache-hit (list cache-hit)))) + (tramp-compat-number-sequence (length filename) 0 -1))))) ;; Cache expired or no matching cache entry found so we need - ;; to perform a remote operation + ;; to perform a remote operation. (let (result) ;; Get a list of directories and files, including reliably ;; tagging the directories with a trailing '/'. Because I ;; rock. --daniel@danann.net ;; Changed to perform `cd' in the same remote op and only - ;; get entries starting with `filename'. Capture any `cd' + ;; get entries starting with `filename'. Capture any `cd' ;; error messages. Ensure any `cd' and `echo' aliases are ;; ignored. (tramp-send-command @@ -1873,9 +1767,8 @@ and gid of the corresponding user is taken. Both parameters must be integers." (forward-line -1) (tramp-error v 'file-error - "tramp-handle-file-name-all-completions: %s" - (buffer-substring - (point) (tramp-compat-line-end-position)))) + "tramp-sh-handle-file-name-all-completions: %s" + (buffer-substring (point) (point-at-eol)))) ;; For peace of mind, if buffer doesn't end in `fail' ;; then it should end in `ok'. If neither are in the ;; buffer something went seriously wrong on the remote @@ -1884,13 +1777,11 @@ and gid of the corresponding user is taken. Both parameters must be integers." (tramp-error v 'file-error "\ -tramp-handle-file-name-all-completions: internal error accessing `%s': `%s'" +tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'" (tramp-shell-quote-argument localname) (buffer-string)))) (while (zerop (forward-line -1)) - (push (buffer-substring - (point) (tramp-compat-line-end-position)) - result))) + (push (buffer-substring (point) (point-at-eol)) result))) ;; Because the remote op went through OK we know the ;; directory we `cd'-ed to exists @@ -1904,31 +1795,15 @@ tramp-handle-file-name-all-completions: internal error accessing `%s': `%s'" v (concat localname entry) "file-exists-p" t)) result) - (tramp-set-file-property - v localname "last-completion" (current-time)) - ;; Store result in the cache (tramp-set-file-property v (concat localname filename) "file-name-all-completions" result)))))))) -(defun tramp-handle-file-name-completion - (filename directory &optional predicate) - "Like `file-name-completion' for Tramp files." - (unless (tramp-tramp-file-p directory) - (error - "tramp-handle-file-name-completion invoked on non-tramp directory `%s'" - directory)) - (try-completion - filename - (mapcar 'list (file-name-all-completions filename directory)) - (when predicate - (lambda (x) (funcall predicate (expand-file-name (car x) directory)))))) - ;; cp, mv and ln -(defun tramp-handle-add-name-to-file +(defun tramp-sh-handle-add-name-to-file (filename newname &optional ok-if-already-exists) "Like `add-name-to-file' for Tramp files." (unless (tramp-equal-remote filename newname) @@ -1960,7 +1835,7 @@ tramp-handle-file-name-all-completions: internal error accessing `%s': `%s'" "error with add-name-to-file, see buffer `%s' for details" (buffer-name)))))) -(defun tramp-handle-copy-file +(defun tramp-sh-handle-copy-file (filename newname &optional ok-if-already-exists keep-date preserve-uid-gid preserve-selinux-context) "Like `copy-file' for Tramp files." @@ -1987,7 +1862,8 @@ tramp-handle-file-name-all-completions: internal error accessing `%s': `%s'" (tramp-run-real-handler 'copy-file (list filename newname ok-if-already-exists keep-date))))) -(defun tramp-handle-copy-directory (dirname newname &optional keep-date parents) +(defun tramp-sh-handle-copy-directory + (dirname newname &optional keep-date parents) "Like `copy-directory' for Tramp files." (let ((t1 (tramp-tramp-file-p dirname)) (t2 (tramp-tramp-file-p newname))) @@ -2023,7 +1899,7 @@ tramp-handle-file-name-all-completions: internal error accessing `%s': `%s'" (tramp-flush-file-property v (file-name-directory localname)) (tramp-flush-file-property v localname)))))) -(defun tramp-handle-rename-file +(defun tramp-sh-handle-rename-file (filename newname &optional ok-if-already-exists) "Like `rename-file' for Tramp files." ;; Check if both files are local -- invoke normal rename-file. @@ -2051,9 +1927,10 @@ as FILENAME. PRESERVE-UID-GID, when non-nil, instructs to keep the uid and gid if both files are on the same host. PRESERVE-SELINUX-CONTEXT activates selinux commands. -This function is invoked by `tramp-handle-copy-file' and -`tramp-handle-rename-file'. It is an error if OP is neither of `copy' -and `rename'. FILENAME and NEWNAME must be absolute file names." +This function is invoked by `tramp-sh-handle-copy-file' and +`tramp-sh-handle-rename-file'. It is an error if OP is neither +of `copy' and `rename'. FILENAME and NEWNAME must be absolute +file names." (unless (memq op '(copy rename)) (error "Unknown operation `%s', must be `copy' or `rename'" op)) (let ((t1 (tramp-tramp-file-p filename)) @@ -2088,7 +1965,7 @@ and `rename'. FILENAME and NEWNAME must be absolute file names." ;; Try out-of-band operation. ((tramp-method-out-of-band-p - v1 (nth 7 (file-attributes filename))) + v1 (nth 7 (file-attributes (file-truename filename)))) (tramp-do-copy-or-rename-file-out-of-band op filename newname keep-date)) @@ -2116,7 +1993,8 @@ and `rename'. FILENAME and NEWNAME must be absolute file names." ;; If the Tramp file has an out-of-band method, the ;; corresponding copy-program can be invoked. - ((tramp-method-out-of-band-p v (nth 7 (file-attributes filename))) + ((tramp-method-out-of-band-p + v (nth 7 (file-attributes (file-truename filename)))) (tramp-do-copy-or-rename-file-out-of-band op filename newname keep-date)) @@ -2312,24 +2190,22 @@ the uid and gid from FILENAME." (list tmpfile localname2 ok-if-already-exists))))) ;; Save exit. - (condition-case nil - (delete-file tmpfile) - (error))))))))) + (ignore-errors (delete-file tmpfile))))))))) ;; Set the time and mode. Mask possible errors. - (condition-case nil + (ignore-errors (when keep-date (set-file-times newname file-times) - (set-file-modes newname file-modes)) - (error))))) + (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. The method used must be an out-of-band method." - (let ((t1 (tramp-tramp-file-p filename)) - (t2 (tramp-tramp-file-p newname)) - copy-program copy-args copy-env copy-keep-date port spec - source target) + (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 + source target) (with-parsed-tramp-file-name (if t1 filename newname) nil (if (and t1 t2) @@ -2349,12 +2225,17 @@ The method used must be an out-of-band method." (tramp-do-copy-or-rename-file-out-of-band 'rename tmpfile newname keep-date)) ;; Save exit. - (condition-case nil - (if dir-flag - (tramp-compat-delete-directory - (expand-file-name ".." tmpfile) 'recursive) - (delete-file tmpfile)) - (error)))) + (ignore-errors + (if dir-flag + (tramp-compat-delete-directory + (expand-file-name ".." tmpfile) 'recursive) + (delete-file tmpfile))))) + + ;; Set variables for computing the prompt for reading + ;; 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)) ;; Expand hops. Might be necessary for gateway methods. (setq v (car (tramp-compute-multi-hops v))) @@ -2388,16 +2269,20 @@ The method used must be an out-of-band method." copy-keep-date (tramp-get-method-parameter method 'tramp-copy-keep-date) copy-args - (delq - nil - (mapcar - (lambda (x) - (setq - x - ;; " " is indication for keep-date argument. - (delete " " (mapcar (lambda (y) (format-spec y spec)) x))) - (unless (member "" x) (mapconcat 'identity x " "))) - (tramp-get-method-parameter method 'tramp-copy-args))) + (delete + ;; " " has either been a replacement of "%k" (when + ;; keep-date argument is non-nil), or a replacemtent + ;; for the whole keep-date sublist. + " " + (dolist + (x + (tramp-get-method-parameter method 'tramp-copy-args) + copy-args) + (setq copy-args + (append + copy-args + (let ((y (mapcar (lambda (z) (format-spec z spec)) x))) + (if (zerop (length (car y))) '(" ") y)))))) copy-env (delq nil @@ -2415,14 +2300,8 @@ The method used must be an out-of-band method." (tramp-error v 'file-error "Cannot find copy program: %s" copy-program)) - ;; Set variables for computing the prompt for reading - ;; 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)) - - (unwind-protect - (with-temp-buffer + (with-temp-buffer + (unwind-protect ;; The default directory must be remote. (let ((default-directory (file-name-directory (if t1 filename newname))) @@ -2433,7 +2312,8 @@ The method used must be an out-of-band method." (tramp-set-connection-property v "process-buffer" (current-buffer)) (while copy-env - (tramp-message v 5 "%s=\"%s\"" (car copy-env) (cadr copy-env)) + (tramp-message + orig-vec 5 "%s=\"%s\"" (car copy-env) (cadr copy-env)) (setenv (pop copy-env) (pop copy-env))) ;; Use an asynchronous process. By this, password can @@ -2444,20 +2324,20 @@ The method used must be an out-of-band method." (let ((p (let ((default-directory (tramp-compat-temporary-file-directory))) (apply 'start-process - (tramp-get-connection-property - v "process-name" nil) - (tramp-get-connection-property - v "process-buffer" nil) + (tramp-get-connection-name v) + (tramp-get-connection-buffer v) copy-program (append copy-args (list source target)))))) (tramp-message - v 6 "%s" (mapconcat 'identity (process-command p) " ")) - (tramp-set-process-query-on-exit-flag p nil) - (tramp-process-actions p v tramp-actions-copy-out-of-band)))) + 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))) - ;; Reset the transfer process properties. - (tramp-set-connection-property v "process-name" nil) - (tramp-set-connection-property v "process-buffer" nil)) + ;; Reset the transfer process properties. + (tramp-message orig-vec 6 "%s" (buffer-string)) + (tramp-set-connection-property v "process-name" nil) + (tramp-set-connection-property v "process-buffer" nil))) ;; Handle KEEP-DATE argument. (when (and keep-date (not copy-keep-date)) @@ -2474,7 +2354,7 @@ The method used must be an out-of-band method." (delete-file filename) (tramp-compat-delete-directory filename 'recursive)))))) -(defun tramp-handle-make-directory (dir &optional parents) +(defun tramp-sh-handle-make-directory (dir &optional parents) "Like `make-directory' for Tramp files." (setq dir (expand-file-name dir)) (with-parsed-tramp-file-name dir nil @@ -2486,7 +2366,7 @@ The method used must be an out-of-band method." (tramp-shell-quote-argument localname)) "Couldn't make directory %s" dir)))) -(defun tramp-handle-delete-directory (directory &optional recursive) +(defun tramp-sh-handle-delete-directory (directory &optional recursive) "Like `delete-directory' for Tramp files." (setq directory (expand-file-name directory)) (with-parsed-tramp-file-name directory nil @@ -2498,7 +2378,7 @@ The method used must be an out-of-band method." (tramp-shell-quote-argument localname)) "Couldn't delete %s" directory))) -(defun tramp-handle-delete-file (filename &optional trash) +(defun tramp-sh-handle-delete-file (filename &optional trash) "Like `delete-file' for Tramp files." (setq filename (expand-file-name filename)) (with-parsed-tramp-file-name filename nil @@ -2514,7 +2394,7 @@ The method used must be an out-of-band method." ;; CCC: This does not seem to be enough. Something dies when ;; we try and delete two directories under Tramp :/ -(defun tramp-handle-dired-recursive-delete-directory (filename) +(defun tramp-sh-handle-dired-recursive-delete-directory (filename) "Recursively delete the directory given. This is like `dired-recursive-delete-directory' for Tramp files." (with-parsed-tramp-file-name filename nil @@ -2538,7 +2418,7 @@ This is like `dired-recursive-delete-directory' for Tramp files." (tramp-error v 'file-error "Failed to recursively delete %s" filename)))) -(defun tramp-handle-dired-compress-file (file &rest ok-flag) +(defun tramp-sh-handle-dired-compress-file (file &rest ok-flag) "Like `dired-compress-file' for Tramp files." ;; OK-FLAG is valid for XEmacs only, but not implemented. ;; Code stolen mainly from dired-aux.el. @@ -2592,14 +2472,7 @@ This is like `dired-recursive-delete-directory' for Tramp files." (concat file ".z")) (t nil)))))))))) -(defun tramp-handle-dired-uncache (dir &optional dir-p) - "Like `dired-uncache' for Tramp files." - ;; DIR-P is valid for XEmacs only. - (with-parsed-tramp-file-name - (if (or dir-p (file-directory-p dir)) dir (file-name-directory dir)) nil - (tramp-flush-directory-property v localname))) - -(defun tramp-handle-insert-directory +(defun tramp-sh-handle-insert-directory (filename switches &optional wildcard full-directory-p) "Like `insert-directory' for Tramp files." (setq filename (expand-file-name filename)) @@ -2673,7 +2546,7 @@ This is like `dired-recursive-delete-directory' for Tramp files." (forward-line -1)) (when (looking-at "//DIRED//\\s-+") (let ((databeg (match-end 0)) - (end (tramp-compat-line-end-position))) + (end (point-at-eol))) ;; Now read the numeric positions of file names. (goto-char databeg) (while (< (point) end) @@ -2683,7 +2556,7 @@ This is like `dired-recursive-delete-directory' for Tramp files." ;; End is followed by \n or by " -> ". (put-text-property start end 'dired-filename t)))))) ;; Remove trailing lines. - (goto-char (tramp-compat-line-beginning-position)) + (goto-char (point-at-bol)) (while (looking-at "//") (forward-line 1) (delete-region (match-beginning 0) (point))) @@ -2702,15 +2575,9 @@ This is like `dired-recursive-delete-directory' for Tramp files." (goto-char (point-max)))))) -(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 "~/")) - ;; Canonicalization of file names. -(defun tramp-handle-expand-file-name (name &optional dir) +(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." @@ -2748,8 +2615,7 @@ the result will be a local, non-Tramp, filename." v (format "cd %s; pwd" (tramp-shell-quote-argument uname))) (with-current-buffer (tramp-get-buffer v) (goto-char (point-min)) - (buffer-substring - (point) (tramp-compat-line-end-position))))) + (buffer-substring (point) (point-at-eol))))) (setq localname (concat uname fname)))) ;; There might be a double slash, for example when "~/" ;; expands to "/". Remove this. @@ -2769,41 +2635,9 @@ the result will be a local, non-Tramp, filename." (tramp-run-real-handler 'expand-file-name (list localname)))))))) -(defun tramp-handle-substitute-in-file-name (filename) - "Like `substitute-in-file-name' for Tramp files. -\"//\" and \"/~\" substitute only in the local filename part. -If the URL Tramp syntax is chosen, \"//\" as method delimeter and \"/~\" at -beginning of local filename are not substituted." - ;; First, we must replace environment variables. - (setq filename (tramp-replace-environment-variables filename)) - (with-parsed-tramp-file-name filename nil - (if (equal tramp-syntax 'url) - ;; We need to check localname only. The other parts cannot contain - ;; "//" or "/~". - (if (and (> (length localname) 1) - (or (string-match "//" localname) - (string-match "/~" localname 1))) - (tramp-run-real-handler 'substitute-in-file-name (list filename)) - (tramp-make-tramp-file-name - (when method (substitute-in-file-name method)) - (when user (substitute-in-file-name user)) - (when host (substitute-in-file-name host)) - (when localname - (tramp-run-real-handler - 'substitute-in-file-name (list localname))))) - ;; Ignore in LOCALNAME everything before "//" or "/~". - (when (and (stringp localname) (string-match ".+?/\\(/\\|~\\)" localname)) - (setq filename - (concat (file-remote-p filename) - (replace-match "\\1" nil nil localname))) - ;; "/m:h:~" does not work for completion. We use "/m:h:~/". - (when (string-match "~$" filename) - (setq filename (concat filename "/")))) - (tramp-run-real-handler 'substitute-in-file-name (list filename))))) - ;;; Remote commands: -(defun tramp-handle-executable-find (command) +(defun tramp-sh-handle-executable-find (command) "Like `executable-find' for Tramp files." (with-parsed-tramp-file-name default-directory nil (tramp-find-executable v command (tramp-get-remote-path v) t))) @@ -2819,66 +2653,70 @@ beginning of local filename are not substituted." ;; We use BUFFER also as connection buffer during setup. Because of ;; this, its original contents must be saved, and restored once ;; connection has been setup. -(defun tramp-handle-start-file-process (name buffer program &rest args) +(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 - (unwind-protect - ;; When PROGRAM is nil, we just provide a tty. - (let ((command - (when (stringp program) - (format "cd %s; exec %s" - (tramp-shell-quote-argument localname) - (mapconcat 'tramp-shell-quote-argument - (cons program args) " ")))) - (tramp-process-connection-type - (or (null program) tramp-process-connection-type)) - (name1 name) - (i 0)) - (unless buffer - ;; BUFFER can be nil. We use a temporary buffer. - (setq buffer (generate-new-buffer tramp-temp-buffer-name))) - (while (get-process name1) - ;; NAME must be unique as process name. - (setq i (1+ i) - name1 (format "%s<%d>" name i))) - (setq name name1) - ;; Set the new process properties. - (tramp-set-connection-property v "process-name" name) - (tramp-set-connection-property v "process-buffer" buffer) - ;; Activate narrowing in order to save BUFFER contents. - ;; Clear also the modification time; otherwise we might be - ;; interrupted by `verify-visited-file-modtime'. - (with-current-buffer (tramp-get-connection-buffer v) - (clear-visited-file-modtime) - (narrow-to-region (point-max) (point-max))) - (if command - ;; Send the command. - (tramp-send-command v command nil t) ; nooutput - ;; Check, whether a pty is associated. - (tramp-maybe-open-connection v) - (unless (tramp-compat-process-get - (tramp-get-connection-process v) 'remote-tty) - (tramp-error - 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) - (tramp-set-process-query-on-exit-flag p t) - ;; Return process. - p)) - ;; Save exit. - (with-current-buffer (tramp-get-connection-buffer v) - (if (string-match tramp-temp-buffer-name (buffer-name)) - (progn - (set-process-buffer (tramp-get-connection-process v) nil) - (kill-buffer (current-buffer))) - (widen) - (goto-char (point-max)))) - (tramp-set-connection-property v "process-name" nil) - (tramp-set-connection-property v "process-buffer" nil)))) - -(defun tramp-handle-process-file + ;; When PROGRAM is nil, we just provide a tty. + (let ((command + (when (stringp program) + (format "cd %s; exec %s" + (tramp-shell-quote-argument localname) + (mapconcat 'tramp-shell-quote-argument + (cons program args) " ")))) + (tramp-process-connection-type + (or (null program) tramp-process-connection-type)) + (bmp (and (buffer-live-p buffer) (buffer-modified-p buffer))) + (name1 name) + (i 0)) + (unwind-protect + (save-excursion + (save-restriction + (unless buffer + ;; BUFFER can be nil. We use a temporary buffer. + (setq buffer (generate-new-buffer tramp-temp-buffer-name))) + (while (get-process name1) + ;; NAME must be unique as process name. + (setq i (1+ i) + name1 (format "%s<%d>" name i))) + (setq name name1) + ;; Set the new process properties. + (tramp-set-connection-property v "process-name" name) + (tramp-set-connection-property v "process-buffer" buffer) + ;; Activate narrowing in order to save BUFFER contents. + ;; Clear also the modification time; otherwise we might + ;; be interrupted by `verify-visited-file-modtime'. + (with-current-buffer (tramp-get-connection-buffer v) + (let ((buffer-undo-list t)) + (clear-visited-file-modtime) + (narrow-to-region (point-max) (point-max)) + (if command + ;; Send the command. + (tramp-send-command v command nil t) ; nooutput + ;; Check, whether a pty is associated. + (tramp-maybe-open-connection v) + (unless (tramp-compat-process-get + (tramp-get-connection-process v) 'remote-tty) + (tramp-error + 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) + (tramp-compat-set-process-query-on-exit-flag p t) + ;; Return process. + p))) + ;; Save exit. + (with-current-buffer (tramp-get-connection-buffer v) + (if (string-match tramp-temp-buffer-name (buffer-name)) + (progn + (set-process-buffer (tramp-get-connection-process v) nil) + (kill-buffer (current-buffer))) + (set-buffer-modified-p bmp))) + (tramp-set-connection-property v "process-name" nil) + (tramp-set-connection-property v "process-buffer" nil))))) + +(defun tramp-sh-handle-process-file (program &optional infile destination display &rest args) "Like `process-file' for Tramp files." ;; The implementation is not complete yet. @@ -2991,7 +2829,7 @@ beginning of local filename are not substituted." (keyboard-quit) ret)))) -(defun tramp-handle-call-process-region +(defun tramp-sh-handle-call-process-region (start end program &optional delete buffer display &rest args) "Like `call-process-region' for Tramp files." (let ((tmpfile (tramp-compat-make-temp-file ""))) @@ -3001,7 +2839,7 @@ beginning of local filename are not substituted." (apply 'call-process program tmpfile buffer display args) (delete-file tmpfile)))) -(defun tramp-handle-shell-command +(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)) @@ -3082,16 +2920,15 @@ beginning of local filename are not substituted." (tramp-compat-funcall 'display-message-or-buffer output-buffer) (pop-to-buffer output-buffer)))))))) -(defun tramp-handle-file-local-copy (filename) +(defun tramp-sh-handle-file-local-copy (filename) "Like `file-local-copy' for Tramp files." - (with-parsed-tramp-file-name filename nil (unless (file-exists-p filename) (tramp-error v 'file-error "Cannot make local copy of non-existing file `%s'" filename)) - (let* ((size (nth 7 (file-attributes filename))) + (let* ((size (nth 7 (file-attributes (file-truename filename)))) (rem-enc (tramp-get-inline-coding v "remote-encoding" size)) (loc-dec (tramp-get-inline-coding v "local-decoding" size)) (tmpfile (tramp-compat-make-temp-file filename))) @@ -3163,131 +3000,8 @@ beginning of local filename are not substituted." (run-hooks 'tramp-handle-file-local-copy-hook) tmpfile))) -(defun tramp-handle-file-remote-p (filename &optional identification connected) - "Like `file-remote-p' for Tramp files." - (let ((tramp-verbose 3)) - (when (tramp-tramp-file-p filename) - (let* ((v (tramp-dissect-file-name filename)) - (p (tramp-get-connection-process v)) - (c (and p (processp p) (memq (process-status p) '(run open))))) - ;; We expand the file name only, if there is already a connection. - (with-parsed-tramp-file-name - (if c (expand-file-name filename) filename) nil - (and (or (not connected) c) - (cond - ((eq identification 'method) method) - ((eq identification 'user) user) - ((eq identification 'host) host) - ((eq identification 'localname) localname) - (t (tramp-make-tramp-file-name method user host ""))))))))) - -(defun tramp-handle-insert-file-contents - (filename &optional visit beg end replace) - "Like `insert-file-contents' for Tramp files." - (barf-if-buffer-read-only) - (setq filename (expand-file-name filename)) - (let (result local-copy remote-copy) - (with-parsed-tramp-file-name filename nil - (unwind-protect - (if (not (file-exists-p filename)) - ;; We don't raise a Tramp error, because it might be - ;; suppressed, like in `find-file-noselect-1'. - (signal 'file-error - (list "File not found on remote host" filename)) - - (if (and (tramp-local-host-p v) - (let (file-name-handler-alist) - (file-readable-p localname))) - ;; Short track: if we are on the local host, we can - ;; run directly. - (setq result - (tramp-run-real-handler - 'insert-file-contents - (list localname visit beg end replace))) - - ;; When we shall insert only a part of the file, we copy - ;; this part. - (when (or beg end) - (setq remote-copy (tramp-make-tramp-temp-file v)) - (tramp-send-command - v - (cond - ((and beg end) - (format "tail -c +%d %s | head -c +%d >%s" - (1+ beg) (tramp-shell-quote-argument localname) - (- end beg) remote-copy)) - (beg - (format "tail -c +%d %s >%s" - (1+ beg) (tramp-shell-quote-argument localname) - remote-copy)) - (end - (format "head -c +%d %s >%s" - (1+ end) (tramp-shell-quote-argument localname) - remote-copy))))) - - ;; `insert-file-contents-literally' takes care to avoid - ;; calling jka-compr. By let-binding - ;; `inhibit-file-name-operation', we propagate that care - ;; to the `file-local-copy' operation. - (setq local-copy - (let ((inhibit-file-name-operation - (when (eq inhibit-file-name-operation - 'insert-file-contents) - 'file-local-copy))) - (cond - ((stringp remote-copy) - (file-local-copy - (tramp-make-tramp-file-name - method user host remote-copy))) - ((stringp tramp-temp-buffer-file-name) - (copy-file filename tramp-temp-buffer-file-name 'ok) - tramp-temp-buffer-file-name) - (t (file-local-copy filename))))) - - ;; When the file is not readable for the owner, it - ;; cannot be inserted, even it is redable for the group - ;; or for everybody. - (set-file-modes local-copy (tramp-compat-octal-to-decimal "0600")) - - (when (and (null remote-copy) - (tramp-get-method-parameter - method 'tramp-copy-keep-tmpfile)) - ;; We keep the local file for performance reasons, - ;; useful for "rsync". - (setq tramp-temp-buffer-file-name local-copy) - (put 'tramp-temp-buffer-file-name 'permanent-local t)) - - (with-progress-reporter - v 3 (format "Inserting local temp file `%s'" local-copy) - ;; We must ensure that `file-coding-system-alist' - ;; matches `local-copy'. - (let ((file-coding-system-alist - (tramp-find-file-name-coding-system-alist - filename local-copy))) - (setq result - (insert-file-contents - local-copy nil nil nil replace)))))) - - ;; Save exit. - (progn - (when visit - (setq buffer-file-name filename) - (setq buffer-read-only (not (file-writable-p filename))) - (set-visited-file-modtime) - (set-buffer-modified-p nil)) - (when (and (stringp local-copy) - (or remote-copy (null tramp-temp-buffer-file-name))) - (delete-file local-copy)) - (when (stringp remote-copy) - (delete-file - (tramp-make-tramp-file-name method user host remote-copy)))))) - - ;; Result. - (list (expand-file-name filename) - (cadr result)))) - ;; This is needed for XEmacs only. Code stolen from files.el. -(defun tramp-handle-insert-file-contents-literally +(defun tramp-sh-handle-insert-file-contents-literally (filename &optional visit beg end replace) "Like `insert-file-contents-literally' for Tramp files." (let ((format-alist nil) @@ -3309,49 +3023,7 @@ beginning of local filename are not substituted." (fset 'find-buffer-file-type find-buffer-file-type-function) (fmakunbound 'find-buffer-file-type))))) -(defun tramp-handle-find-backup-file-name (filename) - "Like `find-backup-file-name' for Tramp files." - (with-parsed-tramp-file-name filename nil - ;; We set both variables. It doesn't matter whether it is - ;; Emacs or XEmacs. - (let ((backup-directory-alist - ;; Emacs case. - (when (boundp 'backup-directory-alist) - (if (symbol-value 'tramp-backup-directory-alist) - (mapcar - (lambda (x) - (cons - (car x) - (if (and (stringp (cdr x)) - (file-name-absolute-p (cdr x)) - (not (tramp-file-name-p (cdr x)))) - (tramp-make-tramp-file-name method user host (cdr x)) - (cdr x)))) - (symbol-value 'tramp-backup-directory-alist)) - (symbol-value 'backup-directory-alist)))) - - (bkup-backup-directory-info - ;; XEmacs case. - (when (boundp 'bkup-backup-directory-info) - (if (symbol-value 'tramp-bkup-backup-directory-info) - (mapcar - (lambda (x) - (nconc - (list (car x)) - (list - (if (and (stringp (car (cdr x))) - (file-name-absolute-p (car (cdr x))) - (not (tramp-file-name-p (car (cdr x))))) - (tramp-make-tramp-file-name - method user host (car (cdr x))) - (car (cdr x)))) - (cdr (cdr x)))) - (symbol-value 'tramp-bkup-backup-directory-info)) - (symbol-value 'bkup-backup-directory-info))))) - - (tramp-run-real-handler 'find-backup-file-name (list filename))))) - -(defun tramp-handle-make-auto-save-file-name () +(defun tramp-sh-handle-make-auto-save-file-name () "Like `make-auto-save-file-name' for Tramp files. Returns a file name in `tramp-auto-save-directory' for autosaving this file." (let ((tramp-auto-save-directory tramp-auto-save-directory) @@ -3393,11 +3065,8 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file." (tramp-run-real-handler 'make-auto-save-file-name nil) (ad-activate 'make-auto-save-file-name))))) -(defvar tramp-handle-write-region-hook nil - "Normal hook to be run at the end of `tramp-handle-write-region'.") - ;; CCC grok LOCKNAME -(defun tramp-handle-write-region +(defun tramp-sh-handle-write-region (start end filename &optional append visit lockname confirm) "Like `write-region' for Tramp files." (setq filename (expand-file-name filename)) @@ -3410,7 +3079,7 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file." ;; (unless (or (eq lockname nil) ;; (string= lockname filename)) ;; (error - ;; "tramp-handle-write-region: LOCKNAME must be nil or equal FILENAME")) + ;; "tramp-sh-handle-write-region: LOCKNAME must be nil or equal FILENAME")) ;; XEmacs takes a coding system as the seventh argument, not `confirm'. (when (and (not (featurep 'xemacs)) confirm (file-exists-p filename)) @@ -3659,7 +3328,7 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file." ;; can reset the file name handlers, and we make a second run of ;; `vc-registered', which returns the expected result without sending ;; any other remote command. -(defun tramp-handle-vc-registered (file) +(defun tramp-sh-handle-vc-registered (file) "Like `vc-registered' for Tramp files." (tramp-compat-with-temp-message "" (with-parsed-tramp-file-name file nil @@ -3669,7 +3338,7 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file." ;; There could be new files, created by the vc backend. We ;; cannot reuse the old cache entries, therefore. (let (tramp-vc-registered-file-names - (tramp-cache-inhibit-cache (current-time)) + (remote-file-name-inhibit-cache (current-time)) (file-name-handler-alist `((,tramp-file-name-regexp . tramp-vc-file-name-handler)))) @@ -3852,8 +3521,7 @@ This function expects to be in the right *tramp* buffer." (when (search-backward "tramp_executable " nil t) (skip-chars-forward "^ ") (skip-chars-forward " ") - (setq result (buffer-substring - (point) (tramp-compat-line-end-position))))) + (setq result (buffer-substring (point) (point-at-eol))))) result))) (defun tramp-set-remote-path (vec) @@ -4003,7 +3671,7 @@ process to set up. VEC specifies the connection." ;; the single quotes makes it work under `rc', too. We also unset ;; the variable $ENV because that is read by some sh ;; implementations (eg, bash when called as sh) on startup; this - ;; way, we avoid the startup file clobbering $PS1. $PROMP_COMMAND + ;; way, we avoid the startup file clobbering $PS1. $PROMPT_COMMAND ;; is another way to set the prompt in /bin/bash, it must be ;; discarded as well. (tramp-open-shell @@ -4050,10 +3718,10 @@ process to set up. VEC specifies the connection." (setq cs-encode (cdr cs)) (unless cs-decode (setq cs-decode 'undecided)) (unless cs-encode (setq cs-encode 'undecided)) - (setq cs-encode (tramp-coding-system-change-eol-conversion + (setq cs-encode (tramp-compat-coding-system-change-eol-conversion cs-encode 'unix)) (when (search-forward "\r" nil t) - (setq cs-decode (tramp-coding-system-change-eol-conversion + (setq cs-decode (tramp-compat-coding-system-change-eol-conversion cs-decode 'dos))) (tramp-compat-funcall 'set-buffer-process-coding-system cs-decode cs-encode) @@ -4065,9 +3733,7 @@ process to set up. VEC specifies the connection." ;; because we're running on a non-MULE Emacs. Let's try ;; stty, instead. (tramp-send-command vec "stty -onlcr" t)))) - ;; Dump stty settings in the traces. - (when (>= tramp-verbose 9) - (tramp-send-command vec "stty -a" t)) + (tramp-send-command vec "set +o vi +o emacs" t) ;; Check whether the output of "uname -sr" has been changed. If @@ -4085,7 +3751,7 @@ process to set up. VEC specifies the connection." ;; Keep the debug buffer. (rename-buffer (generate-new-buffer-name tramp-temp-buffer-name) 'unique) - (tramp-compat-funcall 'tramp-cleanup-connection vec) + (tramp-cleanup-connection vec) (if (= (point-min) (point-max)) (kill-buffer nil) (rename-buffer (tramp-debug-buffer-name vec) 'unique)) @@ -4138,12 +3804,21 @@ process to set up. VEC specifies the connection." (when (string-match "^IRIX64" (tramp-get-connection-property vec "uname" "")) (tramp-send-command vec "set +H" t)) + ;; On BSD-like systems, ?\t is expanded to spaces. Suppress this. + (when (string-match "BSD\\|Darwin" + (tramp-get-connection-property vec "uname" "")) + (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)))) + ;; Dump stty settings in the traces. + (when (>= tramp-verbose 9) + (tramp-send-command vec "stty -a" t)) + ;; Set the environment. (tramp-message vec 5 "Setting default environment") @@ -4207,7 +3882,11 @@ and end of region, and are expected to replace the region contents with the encoded or decoded results, respectively.") (defconst tramp-remote-coding-commands - '((b64 "base64" "base64 -d") + '((b64 "base64" "base64 -d -i") + ;; "-i" is more robust with older base64 from GNU coreutils. + ;; However, I don't know whether all base64 versions do supports + ;; this option. + (b64 "base64" "base64 -d") (b64 "mimencode -b" "mimencode -u -b") (b64 "mmencode -b" "mmencode -u -b") (b64 "recode data..base64" "recode base64..data") @@ -4457,22 +4136,10 @@ Gateway hops are already opened." (let ((gw (pop target-alist)) (hop (pop target-alist))) ;; Is the method prepared for gateways? - (unless (tramp-get-method-parameter - (tramp-file-name-method hop) 'tramp-default-port) + (unless (tramp-file-name-port hop) (tramp-error vec 'file-error - "Method `%s' is not supported for gateway access." - (tramp-file-name-method hop))) - ;; Add default port if needed. - (unless - (string-match - tramp-host-with-port-regexp (tramp-file-name-host hop)) - (aset hop 2 - (concat - (tramp-file-name-host hop) tramp-prefix-port-format - (number-to-string - (tramp-get-method-parameter - (tramp-file-name-method hop) 'tramp-default-port))))) + "Connection `%s' is not supported for gateway access." hop)) ;; Open the gateway connection. (add-to-list 'target-alist @@ -4592,7 +4259,7 @@ connection if a previous connection has died for some reason." (p (let ((default-directory (tramp-compat-temporary-file-directory))) (start-process - (or process-name (tramp-buffer-name vec)) + (tramp-get-connection-name vec) (tramp-get-connection-buffer vec) tramp-encoding-shell)))) @@ -4600,7 +4267,7 @@ connection if a previous connection has died for some reason." vec 6 "%s" (mapconcat 'identity (process-command p) " ")) ;; Check whether process is alive. - (tramp-set-process-query-on-exit-flag p nil) + (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) @@ -4708,6 +4375,11 @@ function waits for output unless NOOUTPUT is set." ;; We mark the command string that it can be erased in the output buffer. (tramp-set-connection-property p "check-remote-echo" t) (setq command (format "%s%s%s" tramp-echo-mark command tramp-echo-mark))) + (when (string-match "<<'EOF'" command) + ;; Unset $PS1 when using here documents, in order to avoid + ;; multiple prompts. + (setq command (concat "(PS1= ; " command "\n)"))) + ;; Send the command. (tramp-message vec 6 "%s" command) (tramp-send-string vec command) (unless nooutput (tramp-wait-for-output p)))) @@ -4731,8 +4403,7 @@ function waits for output unless NOOUTPUT is set." ;; A simple-minded busybox has sent " ^H" sequences. ;; Delete them. (goto-char (point-min)) - (when (re-search-forward - "^\\(.\b\\)+$" (tramp-compat-line-end-position) t) + (when (re-search-forward "^\\(.\b\\)+$" (point-at-eol) t) (forward-line 1) (delete-region (point-min) (point))) ;; Delete the prompt. @@ -4794,84 +4465,13 @@ In case there is no valid Lisp expression, it raises an error" (condition-case nil (prog1 (read (current-buffer)) ;; Error handling. - (when (re-search-forward "\\S-" (tramp-compat-line-end-position) t) + (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)))))) -(defun tramp-mode-string-to-int (mode-string) - "Converts a ten-letter `drwxrwxrwx'-style mode string into mode bits." - (let* (case-fold-search - (mode-chars (string-to-vector mode-string)) - (owner-read (aref mode-chars 1)) - (owner-write (aref mode-chars 2)) - (owner-execute-or-setid (aref mode-chars 3)) - (group-read (aref mode-chars 4)) - (group-write (aref mode-chars 5)) - (group-execute-or-setid (aref mode-chars 6)) - (other-read (aref mode-chars 7)) - (other-write (aref mode-chars 8)) - (other-execute-or-sticky (aref mode-chars 9))) - (save-match-data - (logior - (cond - ((char-equal owner-read ?r) (tramp-compat-octal-to-decimal "00400")) - ((char-equal owner-read ?-) 0) - (t (error "Second char `%c' must be one of `r-'" owner-read))) - (cond - ((char-equal owner-write ?w) (tramp-compat-octal-to-decimal "00200")) - ((char-equal owner-write ?-) 0) - (t (error "Third char `%c' must be one of `w-'" owner-write))) - (cond - ((char-equal owner-execute-or-setid ?x) - (tramp-compat-octal-to-decimal "00100")) - ((char-equal owner-execute-or-setid ?S) - (tramp-compat-octal-to-decimal "04000")) - ((char-equal owner-execute-or-setid ?s) - (tramp-compat-octal-to-decimal "04100")) - ((char-equal owner-execute-or-setid ?-) 0) - (t (error "Fourth char `%c' must be one of `xsS-'" - owner-execute-or-setid))) - (cond - ((char-equal group-read ?r) (tramp-compat-octal-to-decimal "00040")) - ((char-equal group-read ?-) 0) - (t (error "Fifth char `%c' must be one of `r-'" group-read))) - (cond - ((char-equal group-write ?w) (tramp-compat-octal-to-decimal "00020")) - ((char-equal group-write ?-) 0) - (t (error "Sixth char `%c' must be one of `w-'" group-write))) - (cond - ((char-equal group-execute-or-setid ?x) - (tramp-compat-octal-to-decimal "00010")) - ((char-equal group-execute-or-setid ?S) - (tramp-compat-octal-to-decimal "02000")) - ((char-equal group-execute-or-setid ?s) - (tramp-compat-octal-to-decimal "02010")) - ((char-equal group-execute-or-setid ?-) 0) - (t (error "Seventh char `%c' must be one of `xsS-'" - group-execute-or-setid))) - (cond - ((char-equal other-read ?r) - (tramp-compat-octal-to-decimal "00004")) - ((char-equal other-read ?-) 0) - (t (error "Eighth char `%c' must be one of `r-'" other-read))) - (cond - ((char-equal other-write ?w) (tramp-compat-octal-to-decimal "00002")) - ((char-equal other-write ?-) 0) - (t (error "Nineth char `%c' must be one of `w-'" other-write))) - (cond - ((char-equal other-execute-or-sticky ?x) - (tramp-compat-octal-to-decimal "00001")) - ((char-equal other-execute-or-sticky ?T) - (tramp-compat-octal-to-decimal "01000")) - ((char-equal other-execute-or-sticky ?t) - (tramp-compat-octal-to-decimal "01001")) - ((char-equal other-execute-or-sticky ?-) 0) - (t (error "Tenth char `%c' must be one of `xtT-'" - other-execute-or-sticky))))))) - (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. @@ -5034,30 +4634,6 @@ This is used internally by `tramp-file-mode-from-int'." (> size tramp-copy-size-limit) (null (tramp-get-inline-coding vec "remote-encoding" size))))) -(defun tramp-local-host-p (vec) - "Return t if this points to the local host, nil otherwise." - ;; We cannot use `tramp-file-name-real-host'. A port is an - ;; indication for an ssh tunnel or alike. - (let ((host (tramp-file-name-host vec))) - (and - (stringp host) - (string-match tramp-local-host-regexp host) - ;; The method shall be applied to one of the shell file name - ;; handler. `tramp-local-host-p' is also called for "smb" and - ;; alike, where it must fail. - (tramp-get-method-parameter - (tramp-file-name-method vec) 'tramp-login-program) - ;; The local temp directory must be writable for the other user. - (file-writable-p - (tramp-make-tramp-file-name - (tramp-file-name-method vec) - (tramp-file-name-user vec) - host - (tramp-compat-temporary-file-directory))) - ;; On some systems, chown runs only for root. - (or (zerop (user-uid)) - (zerop (tramp-get-remote-uid vec 'integer)))))) - ;; Variables local to connection. (defun tramp-get-remote-path (vec) @@ -5143,33 +4719,6 @@ This is used internally by `tramp-file-mode-from-int'." dir (tramp-error vec 'file-error "Directory %s not accessible" dir))))) -(defun tramp-make-tramp-temp-file (vec) - "Create a temporary file on the remote host identified by VEC. -Return the local name of the temporary file." - (let ((prefix - (tramp-make-tramp-file-name - (tramp-file-name-method vec) - (tramp-file-name-user vec) - (tramp-file-name-host vec) - (tramp-drop-volume-letter - (expand-file-name - tramp-temp-name-prefix (tramp-get-remote-tmpdir vec))))) - result) - (while (not result) - ;; `make-temp-file' would be the natural choice for - ;; implementation. But it calls `write-region' internally, - ;; which also needs a temporary file - we would end in an - ;; infinite loop. - (setq result (make-temp-name prefix)) - (if (file-exists-p result) - (setq result nil) - ;; This creates the file by side effect. - (set-file-times result) - (set-file-modes result (tramp-compat-octal-to-decimal "0700")))) - - ;; Return the local part. - (with-parsed-tramp-file-name result nil localname))) - (defun tramp-get-ls-command (vec) (with-connection-property vec "ls" (tramp-message vec 5 "Finding a suitable `ls' command") @@ -5368,54 +4917,57 @@ If no corresponding command is found, nil is returned. Otherwise, either a string is returned which contains a `%s' mark to be used for the respective input or output file; or a Lisp function cell is returned to be applied on a buffer." - (let ((coding - (with-connection-property vec prop - (tramp-find-inline-encoding vec) - (tramp-get-connection-property vec prop nil))) - (prop1 (if (string-match "encoding" prop) - "inline-compress" "inline-decompress")) - compress) - ;; The connection property might have been cached. So we must send - ;; the script to the remote side - maybe. - (when (and coding (symbolp coding) (string-match "remote" prop)) - (let ((name (symbol-name coding))) - (while (string-match (regexp-quote "-") name) - (setq name (replace-match "_" nil t name))) - (tramp-maybe-send-script vec (symbol-value coding) name) - (setq coding name))) - (when coding - ;; Check for the `compress' command. - (setq compress (tramp-get-inline-compress vec prop1 size)) - ;; Return the value. - (cond - ((and compress (symbolp coding)) - (if (string-match "decompress" prop1) + ;; We must catch the errors, because we want to return `nil', when + ;; no inline coding is found. + (ignore-errors + (let ((coding + (with-connection-property vec prop + (tramp-find-inline-encoding vec) + (tramp-get-connection-property vec prop nil))) + (prop1 (if (string-match "encoding" prop) + "inline-compress" "inline-decompress")) + compress) + ;; The connection property might have been cached. So we must + ;; send the script to the remote side - maybe. + (when (and coding (symbolp coding) (string-match "remote" prop)) + (let ((name (symbol-name coding))) + (while (string-match (regexp-quote "-") name) + (setq name (replace-match "_" nil t name))) + (tramp-maybe-send-script vec (symbol-value coding) name) + (setq coding name))) + (when coding + ;; Check for the `compress' command. + (setq compress (tramp-get-inline-compress vec prop1 size)) + ;; Return the value. + (cond + ((and compress (symbolp coding)) + (if (string-match "decompress" prop1) + `(lambda (beg end) + (,coding beg end) + (let ((coding-system-for-write 'binary) + (coding-system-for-read 'binary)) + (apply + 'call-process-region (point-min) (point-max) + (car (split-string ,compress)) t t nil + (cdr (split-string ,compress))))) `(lambda (beg end) - (,coding beg end) (let ((coding-system-for-write 'binary) (coding-system-for-read 'binary)) (apply - 'call-process-region (point-min) (point-max) + 'call-process-region beg end (car (split-string ,compress)) t t nil - (cdr (split-string ,compress))))) - `(lambda (beg end) - (let ((coding-system-for-write 'binary) - (coding-system-for-read 'binary)) - (apply - 'call-process-region beg end - (car (split-string ,compress)) t t nil - (cdr (split-string ,compress)))) - (,coding (point-min) (point-max))))) - ((symbolp coding) - coding) - ((and compress (string-match "decoding" prop)) - (format "(%s | %s >%%s)" coding compress)) - (compress - (format "(%s <%%s | %s)" compress coding)) - ((string-match "decoding" prop) - (format "%s >%%s" coding)) - (t - (format "%s <%%s" coding)))))) + (cdr (split-string ,compress)))) + (,coding (point-min) (point-max))))) + ((symbolp coding) + coding) + ((and compress (string-match "decoding" prop)) + (format "(%s | %s >%%s)" coding compress)) + (compress + (format "(%s <%%s | %s)" compress coding)) + ((string-match "decoding" prop) + (format "%s >%%s" coding)) + (t + (format "%s <%%s" coding))))))) ;;; Integration of eshell.el: