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))