for it. Also note that \"/bin/sh\" exists on all Unixen,
this might not be true for the value that you decide to use.
You Have Been Warned.
+ * `tramp-remote-shell-login'
+ This specifies the arguments to let `tramp-remote-shell' run
+ as a login shell. It defaults to (\"-l\"), but some shells,
+ like ksh, require another argument. See
+ `tramp-connection-properties' for a way to overwrite the
+ default value.
* `tramp-remote-shell-args'
For implementation of `shell-command', this specifies the
arguments to let `tramp-remote-shell' run a single command.
;; internal data structure. Convenience functions for internal
;; data structure.
-(defun tramp-get-method-parameter (method param)
+(defun tramp-get-method-parameter (vec param)
"Return the method parameter PARAM.
-If the `tramp-methods' entry does not exist, return nil."
- (let ((entry (assoc param (assoc method tramp-methods))))
- (when entry (cadr entry))))
+If VEC is a vector, check first in connection properties.
+Afterwards, check in `tramp-methods'. If the `tramp-methods'
+entry does not exist, return nil."
+ (let ((hash-entry
+ (tramp-compat-replace-regexp-in-string
+ "^tramp-" "" (symbol-name param))))
+ (if (tramp-connection-property-p vec hash-entry)
+ ;; We use the cached property.
+ (tramp-get-connection-property vec hash-entry nil)
+ ;; Use the static value from `tramp-methods'.
+ (let ((methods-entry
+ (assoc param (assoc (tramp-file-name-method vec) tramp-methods))))
+ (when methods-entry (cadr methods-entry))))))
(defun tramp-file-name-p (vec)
"Check, whether VEC is a Tramp object."
(or (and (stringp host)
(string-match tramp-host-with-port-regexp host)
(string-to-number (match-string 2 host)))
- (tramp-get-method-parameter method 'tramp-default-port)))))
+ (tramp-get-method-parameter vec 'tramp-default-port)))))
;;;###tramp-autoload
(defun tramp-tramp-file-p (name)
; (1+ (count-lines (point-min) (cdr ffn)))))))
(insert (format "%s " fn)))
;; The message.
- (insert (apply 'format fmt-string arguments))))
+ (insert (apply #'format-message fmt-string arguments))))
(defvar tramp-message-show-message t
"Show Tramp message in the minibuffer.
(error-message-string
(list signal
(get signal 'error-message)
- (apply 'format fmt-string arguments)))))
- (signal signal (list (apply 'format fmt-string arguments)))))
+ (apply #'format-message fmt-string arguments)))))
+ (signal signal (list (apply #'format-message fmt-string arguments)))))
(defsubst tramp-error-with-buffer
(buf vec-or-proc signal fmt-string &rest arguments)
(tramp-set-completion-function
\"ssh\"
- '((tramp-parse-sconfig \"/etc/ssh_config\")
+ \\='((tramp-parse-sconfig \"/etc/ssh_config\")
(tramp-parse-sconfig \"~/.ssh/config\")))"
(let ((r function-list)
(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) ""))))))
+ 'file-name-as-directory (list (or (tramp-file-name-localname v) "")))
+ (tramp-file-name-hop v))))
(defun tramp-handle-file-name-completion
(filename directory &optional predicate)
(tramp-file-name-user v)
(tramp-file-name-host v)
(tramp-run-real-handler
- 'file-name-directory (list (or (tramp-file-name-localname v) ""))))))
+ 'file-name-directory (list (or (tramp-file-name-localname v) "")))
+ (tramp-file-name-hop v))))
(defun tramp-handle-file-name-nondirectory (file)
"Like `file-name-nondirectory' but aware of Tramp files."
((eq identification 'user) user)
((eq identification 'host) host)
((eq identification 'localname) localname)
- (t (tramp-make-tramp-file-name method user host "")))))))))
+ ((eq identification 'hop) hop)
+ (t (tramp-make-tramp-file-name method user host "" hop)))))))))
(defun tramp-handle-file-symlink-p (filename)
"Like `file-symlink-p' for Tramp files."
v 'file-error "File `%s' not found on remote host" filename)
(with-tramp-progress-reporter
- v 3 (format "Inserting `%s'" filename)
+ v 3 (format-message "Inserting `%s'" filename)
(condition-case err
(if (and (tramp-local-host-p v)
(let (file-name-handler-alist)
;; name handlers.
(when (and (or beg end)
(tramp-get-method-parameter
- (tramp-file-name-method v)
- 'tramp-login-program))
+ v 'tramp-login-program))
(setq remote-copy (tramp-make-tramp-temp-file v))
;; This is defined in tramp-sh.el. Let's assume
;; this is loaded already.
(when (and (null remote-copy)
(tramp-get-method-parameter
- method 'tramp-copy-keep-tmpfile))
+ v 'tramp-copy-keep-tmpfile))
;; We keep the local file for performance reasons,
;; useful for "rsync".
(setq tramp-temp-buffer-file-name local-copy))
(args (append
(cons
(tramp-get-method-parameter
- (tramp-file-name-method
- (tramp-dissect-file-name default-directory))
+ (tramp-dissect-file-name default-directory)
'tramp-remote-shell)
(tramp-get-method-parameter
- (tramp-file-name-method
- (tramp-dissect-file-name default-directory))
+ (tramp-dissect-file-name default-directory)
'tramp-remote-shell-args))
(list (substring command 0 asynchronous))))
current-buffer-p
(cond
((eq exit 'permission-denied) "Permission denied")
((eq exit 'process-died)
- (concat
- "Tramp failed to connect. If this happens repeatedly, try\n"
- " `M-x tramp-cleanup-this-connection'"))
+ (substitute-command-keys
+ (concat
+ "Tramp failed to connect. If this happens repeatedly, try\n"
+ " `\\[tramp-cleanup-this-connection]'")))
((eq exit 'timeout)
- (format
+ (format-message
"Timeout reached, see buffer `%s' for details"
(tramp-get-connection-buffer vec)))
(t "Login failed")))))
;; The method shall be applied to one of the shell file name
;; handlers. `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)
+ (tramp-get-method-parameter vec 'tramp-login-program)
;; The local temp directory must be writable for the other user.
(file-writable-p
(tramp-make-tramp-file-name
(defun tramp-get-remote-tmpdir (vec)
"Return directory for temporary files on the remote host identified by VEC."
- (with-tramp-connection-property vec "tmpdir"
- (let ((dir (tramp-make-tramp-file-name
- (tramp-file-name-method vec)
- (tramp-file-name-user vec)
- (tramp-file-name-host vec)
- (or
- (tramp-get-method-parameter
- (tramp-file-name-method vec) 'tramp-tmpdir)
- "/tmp"))))
- (if (and (file-directory-p dir) (file-writable-p dir))
- dir
- (tramp-error vec 'file-error "Directory %s not accessible" dir)))))
+ (when (file-remote-p (tramp-get-connection-property vec "tmpdir" ""))
+ ;; Compatibility code: Cached value shall be the local path only.
+ (tramp-set-connection-property vec "tmpdir" 'undef))
+ (let ((dir (tramp-make-tramp-file-name
+ (tramp-file-name-method vec)
+ (tramp-file-name-user vec)
+ (tramp-file-name-host vec)
+ (or (tramp-get-method-parameter vec 'tramp-tmpdir) "/tmp"))))
+ (with-tramp-connection-property vec "tmpdir"
+ (or (and (file-directory-p dir) (file-writable-p dir)
+ (file-remote-p dir 'localname))
+ (tramp-error vec 'file-error "Directory %s not accessible" dir)))
+ dir))
;;;###tramp-autoload
(defun tramp-make-tramp-temp-file (vec)
;;;###tramp-autoload
(defun tramp-clear-passwd (vec)
"Clear password cache for connection related to VEC."
+ (let ((hop (tramp-file-name-hop vec)))
+ (when hop
+ ;; Clear also the passwords of the hops.
+ (tramp-clear-passwd
+ (tramp-dissect-file-name
+ (concat
+ tramp-prefix-format
+ (tramp-compat-replace-regexp-in-string
+ (concat tramp-postfix-hop-regexp "$")
+ tramp-postfix-host-format hop))))))
(tramp-compat-funcall
'password-cache-remove
(tramp-make-tramp-file-name