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))
	(item vec)
	choices proxy)

    ;; Ad-hoc proxy definitions.
    (tramp-add-hops vec)

    ;; 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-compat-flatten-tree
		      (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 (tramp-compat-rx bol (literal host) eol)))))

    ;; Result.
    target-alist))