Function: tramp-compute-multi-hops
tramp-compute-multi-hops is a byte-compiled function defined in
tramp.el.gz.
Signature
(tramp-compute-multi-hops VEC)
Documentation
Expands VEC according to tramp-default-proxies-alist.
Source Code
;; Defined in /usr/src/emacs/lisp/net/tramp.el.gz
(defun tramp-compute-multi-hops (vec)
"Expands VEC according to `tramp-default-proxies-alist'."
(let ((saved-tdpa tramp-default-proxies-alist)
(target-alist `(,vec))
(hops (or (tramp-file-name-hop vec) ""))
(item vec)
choices proxy)
;; Ad-hoc proxy definitions.
(dolist (proxy (reverse (split-string hops tramp-postfix-hop-regexp 'omit)))
(let* ((host-port (tramp-file-name-host-port item))
(user-domain (tramp-file-name-user-domain item))
(proxy (concat
tramp-prefix-format proxy tramp-postfix-host-format))
(entry
(list (and (stringp host-port)
(concat "^" (regexp-quote host-port) "$"))
(and (stringp user-domain)
(concat "^" (regexp-quote user-domain) "$"))
(propertize proxy 'tramp-ad-hoc t))))
(tramp-message vec 5 "Add %S to `tramp-default-proxies-alist'" entry)
;; Add the hop.
(add-to-list 'tramp-default-proxies-alist entry)
(setq item (tramp-dissect-file-name proxy))))
;; Save the new value.
(when (and hops tramp-save-ad-hoc-proxies)
(customize-save-variable
'tramp-default-proxies-alist tramp-default-proxies-alist))
;; Look for proxy hosts to be passed.
(setq choices tramp-default-proxies-alist)
(while choices
(setq item (pop choices)
proxy (eval (nth 2 item) t))
(when (and
;; Host.
(string-match-p
(or (eval (nth 0 item) t) "")
(or (tramp-file-name-host-port (car target-alist)) ""))
;; User.
(string-match-p
(or (eval (nth 1 item) t) "")
(or (tramp-file-name-user-domain (car target-alist)) "")))
(if (null proxy)
;; No more hops needed.
(setq choices nil)
;; Replace placeholders.
(setq proxy
(format-spec
proxy
(format-spec-make
?u (or (tramp-file-name-user (car target-alist)) "")
?h (or (tramp-file-name-host (car target-alist)) ""))))
(with-parsed-tramp-file-name proxy l
;; Add the hop.
(push l target-alist)
;; Start next search.
(setq choices tramp-default-proxies-alist)))))
;; Foreign and out-of-band methods are not supported for multi-hops.
(when (cdr target-alist)
(setq choices target-alist)
(while (setq item (pop choices))
(unless (tramp-multi-hop-p item)
(setq tramp-default-proxies-alist saved-tdpa)
(tramp-user-error
vec "Method `%s' is not supported for multi-hops."
(tramp-file-name-method item)))))
;; Some methods ("su", "sg", "sudo", "doas", "ksu") do not use the
;; host name in their command template. In this case, the remote
;; file name must use either a local host name (first hop), or a
;; host name matching the previous hop.
(let ((previous-host (or tramp-local-host-regexp "")))
(setq choices target-alist)
(while (setq item (pop choices))
(let ((host (tramp-file-name-host item)))
(unless
(or
;; The host name is used for the remote shell command.
(member
'("%h") (tramp-get-method-parameter item 'tramp-login-args))
;; The host name must match previous hop.
(string-match-p previous-host host))
(setq tramp-default-proxies-alist saved-tdpa)
(tramp-user-error
vec "Host name `%s' does not match `%s'" host previous-host))
(setq previous-host (concat "^" (regexp-quote host) "$")))))
;; Result.
target-alist))