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)

    ;; `tramp-compute-multi-hops' could be called also for other file
    ;; name handlers, for example in `tramp-clear-passwd'.
    (when (tramp-sh-file-name-handler-p vec)

      ;; 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
		  (tramp-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", "surs", "sg", "sudo", "sudors", "doas",
      ;; "run0", "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" (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 (rx bol (literal host) eol))))))

    ;; Result.
    target-alist))