diff options
| -rw-r--r-- | doc/misc/tramp.texi | 6 | ||||
| -rw-r--r-- | lisp/net/tramp-adb.el | 2 | ||||
| -rw-r--r-- | lisp/net/tramp-archive.el | 4 | ||||
| -rw-r--r-- | lisp/net/tramp-compat.el | 7 | ||||
| -rw-r--r-- | lisp/net/tramp-gvfs.el | 2 | ||||
| -rw-r--r-- | lisp/net/tramp-sh.el | 38 | ||||
| -rw-r--r-- | lisp/net/tramp.el | 35 | ||||
| -rw-r--r-- | test/lisp/net/tramp-tests.el | 23 |
8 files changed, 79 insertions, 38 deletions
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 31439043435..f0ea073ed09 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi | |||
| @@ -1408,8 +1408,10 @@ Opening @file{@trampfn{sudo,randomhost.your.domain,}} first connects | |||
| 1408 | to @samp{randomhost.your.domain} via @code{ssh} under your account | 1408 | to @samp{randomhost.your.domain} via @code{ssh} under your account |
| 1409 | name, and then performs @code{sudo -u root} on that host. | 1409 | name, and then performs @code{sudo -u root} on that host. |
| 1410 | 1410 | ||
| 1411 | It is key for the sudo method in the above example to be applied on | 1411 | It is key for the @option{sudo} method in the above example to be |
| 1412 | the host after reaching it and not on the local host. | 1412 | applied on the host after reaching it and not on the local host. |
| 1413 | @value{tramp} checks therefore, that the host name for such hops | ||
| 1414 | matches the host name of the previous hop. | ||
| 1413 | 1415 | ||
| 1414 | @var{host}, @var{user} and @var{proxy} can also take Lisp forms. These | 1416 | @var{host}, @var{user} and @var{proxy} can also take Lisp forms. These |
| 1415 | forms when evaluated must return either a string or @code{nil}. | 1417 | forms when evaluated must return either a string or @code{nil}. |
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index fbf6196ca46..f8edb27c516 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el | |||
| @@ -999,7 +999,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." | |||
| 999 | (when p | 999 | (when p |
| 1000 | (if (yes-or-no-p "A command is running. Kill it? ") | 1000 | (if (yes-or-no-p "A command is running. Kill it? ") |
| 1001 | (ignore-errors (kill-process p)) | 1001 | (ignore-errors (kill-process p)) |
| 1002 | (tramp-compat-user-error p "Shell command in progress"))) | 1002 | (tramp-user-error p "Shell command in progress"))) |
| 1003 | 1003 | ||
| 1004 | (if current-buffer-p | 1004 | (if current-buffer-p |
| 1005 | (progn | 1005 | (progn |
diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el index 0b8e8da9761..448cfca2ca1 100644 --- a/lisp/net/tramp-archive.el +++ b/lisp/net/tramp-archive.el | |||
| @@ -311,7 +311,7 @@ pass to the OPERATION." | |||
| 311 | (tramp-archive-run-real-handler operation args) | 311 | (tramp-archive-run-real-handler operation args) |
| 312 | ;; Now run the handler. | 312 | ;; Now run the handler. |
| 313 | (unless tramp-archive-enabled | 313 | (unless tramp-archive-enabled |
| 314 | (tramp-compat-user-error nil "Package `tramp-archive' not supported")) | 314 | (tramp-user-error nil "Package `tramp-archive' not supported")) |
| 315 | (let ((tramp-methods (cons `(,tramp-archive-method) tramp-methods)) | 315 | (let ((tramp-methods (cons `(,tramp-archive-method) tramp-methods)) |
| 316 | (tramp-gvfs-methods tramp-archive-all-gvfs-methods) | 316 | (tramp-gvfs-methods tramp-archive-all-gvfs-methods) |
| 317 | ;; Set uid and gid. gvfsd-archive could do it, but it doesn't. | 317 | ;; Set uid and gid. gvfsd-archive could do it, but it doesn't. |
| @@ -398,7 +398,7 @@ hexified archive name as host, and the localname. The archive | |||
| 398 | name is kept in slot `hop'" | 398 | name is kept in slot `hop'" |
| 399 | (save-match-data | 399 | (save-match-data |
| 400 | (unless (tramp-archive-file-name-p name) | 400 | (unless (tramp-archive-file-name-p name) |
| 401 | (tramp-compat-user-error nil "Not an archive file name: \"%s\"" name)) | 401 | (tramp-user-error nil "Not an archive file name: \"%s\"" name)) |
| 402 | (let* ((localname (tramp-archive-file-name-localname name)) | 402 | (let* ((localname (tramp-archive-file-name-localname name)) |
| 403 | (archive (file-truename (tramp-archive-file-name-archive name))) | 403 | (archive (file-truename (tramp-archive-file-name-archive name))) |
| 404 | (vec (make-tramp-file-name | 404 | (vec (make-tramp-file-name |
diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el index 4f564e6eb5c..aa0c99bf9cf 100644 --- a/lisp/net/tramp-compat.el +++ b/lisp/net/tramp-compat.el | |||
| @@ -97,13 +97,6 @@ Add the extension of F, if existing." | |||
| 97 | process-name)))) | 97 | process-name)))) |
| 98 | (setq result t))))))))) | 98 | (setq result t))))))))) |
| 99 | 99 | ||
| 100 | ;; `user-error' has appeared in Emacs 24.3. | ||
| 101 | (defsubst tramp-compat-user-error (vec-or-proc format &rest args) | ||
| 102 | "Signal a pilot error." | ||
| 103 | (apply | ||
| 104 | 'tramp-error vec-or-proc | ||
| 105 | (if (fboundp 'user-error) 'user-error 'error) format args)) | ||
| 106 | |||
| 107 | ;; `default-toplevel-value' has been declared in Emacs 24.4. | 100 | ;; `default-toplevel-value' has been declared in Emacs 24.4. |
| 108 | (unless (fboundp 'default-toplevel-value) | 101 | (unless (fboundp 'default-toplevel-value) |
| 109 | (defalias 'default-toplevel-value 'symbol-value)) | 102 | (defalias 'default-toplevel-value 'symbol-value)) |
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index d0385f3ba28..33af124458d 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el | |||
| @@ -751,7 +751,7 @@ Operations not mentioned here will be handled by the default Emacs primitives.") | |||
| 751 | First arg specifies the OPERATION, second arg is a list of arguments to | 751 | First arg specifies the OPERATION, second arg is a list of arguments to |
| 752 | pass to the OPERATION." | 752 | pass to the OPERATION." |
| 753 | (unless tramp-gvfs-enabled | 753 | (unless tramp-gvfs-enabled |
| 754 | (tramp-compat-user-error nil "Package `tramp-gvfs' not supported")) | 754 | (tramp-user-error nil "Package `tramp-gvfs' not supported")) |
| 755 | (let ((fn (assoc operation tramp-gvfs-file-name-handler-alist))) | 755 | (let ((fn (assoc operation tramp-gvfs-file-name-handler-alist))) |
| 756 | (if fn | 756 | (if fn |
| 757 | (save-match-data (apply (cdr fn) args)) | 757 | (save-match-data (apply (cdr fn) args)) |
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 4cdc39e0b6a..63275448ef8 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el | |||
| @@ -327,7 +327,6 @@ The string is used in `tramp-methods'.") | |||
| 327 | (add-to-list 'tramp-methods | 327 | (add-to-list 'tramp-methods |
| 328 | `("plink" | 328 | `("plink" |
| 329 | (tramp-login-program "plink") | 329 | (tramp-login-program "plink") |
| 330 | ;; ("%h") must be a single element, see `tramp-compute-multi-hops'. | ||
| 331 | (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("-t") | 330 | (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("-t") |
| 332 | ("%h") ("\"") | 331 | ("%h") ("\"") |
| 333 | (,(format | 332 | (,(format |
| @@ -4636,25 +4635,24 @@ Goes through the list `tramp-inline-compress-commands'." | |||
| 4636 | "Method `%s' is not supported for multi-hops." | 4635 | "Method `%s' is not supported for multi-hops." |
| 4637 | (tramp-file-name-method item))))) | 4636 | (tramp-file-name-method item))))) |
| 4638 | 4637 | ||
| 4639 | ;; In case the host name is not used for the remote shell | 4638 | ;; Some methods ("su", "sg", "sudo", "doas", "ksu") do not use the |
| 4640 | ;; command, the user could be misguided by applying a random | 4639 | ;; host name in their command template. In this case, the remote |
| 4641 | ;; host name. | 4640 | ;; file name must use either a local host name (first hop), or a |
| 4642 | (let* ((v (car target-alist)) | 4641 | ;; host name matching the previous hop. |
| 4643 | (method (tramp-file-name-method v)) | 4642 | (let ((previous-host tramp-local-host-regexp)) |
| 4644 | (host (tramp-file-name-host v))) | 4643 | (setq choices target-alist) |
| 4645 | (unless | 4644 | (while (setq item (pop choices)) |
| 4646 | (or | 4645 | (let ((host (tramp-file-name-host item))) |
| 4647 | ;; There are multi-hops. | 4646 | (unless |
| 4648 | (cdr target-alist) | 4647 | (or |
| 4649 | ;; The host name is used for the remote shell command. | 4648 | ;; The host name is used for the remote shell command. |
| 4650 | (member '("%h") (tramp-get-method-parameter v 'tramp-login-args)) | 4649 | (member |
| 4651 | ;; The host is local. We cannot use `tramp-local-host-p' | 4650 | '("%h") (tramp-get-method-parameter item 'tramp-login-args)) |
| 4652 | ;; here, because it opens a connection as well. | 4651 | ;; The host name must match previous hop. |
| 4653 | (string-match tramp-local-host-regexp host)) | 4652 | (string-match previous-host host)) |
| 4654 | (tramp-error | 4653 | (tramp-user-error |
| 4655 | v 'file-error | 4654 | item "Host name `%s' does not match `%s'" host previous-host)) |
| 4656 | "Host `%s' looks like a remote host, `%s' can only use the local host" | 4655 | (setq previous-host (concat "^" (regexp-quote host) "$"))))) |
| 4657 | host method))) | ||
| 4658 | 4656 | ||
| 4659 | ;; Result. | 4657 | ;; Result. |
| 4660 | target-alist)) | 4658 | target-alist)) |
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 4497802d770..43b5e77428a 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el | |||
| @@ -689,7 +689,7 @@ Used in user option `tramp-syntax'. There are further variables | |||
| 689 | to be set, depending on VALUE." | 689 | to be set, depending on VALUE." |
| 690 | ;; Check allowed values. | 690 | ;; Check allowed values. |
| 691 | (unless (memq value (tramp-syntax-values)) | 691 | (unless (memq value (tramp-syntax-values)) |
| 692 | (tramp-compat-user-error "Wrong `tramp-syntax' %s" tramp-syntax)) | 692 | (tramp-user-error "Wrong `tramp-syntax' %s" tramp-syntax)) |
| 693 | ;; Cleanup existing buffers. | 693 | ;; Cleanup existing buffers. |
| 694 | (unless (eq (symbol-value symbol) value) | 694 | (unless (eq (symbol-value symbol) value) |
| 695 | (tramp-cleanup-all-buffers)) | 695 | (tramp-cleanup-all-buffers)) |
| @@ -1348,7 +1348,7 @@ to their default values. For the other file name parts, no | |||
| 1348 | default values are used." | 1348 | default values are used." |
| 1349 | (save-match-data | 1349 | (save-match-data |
| 1350 | (unless (tramp-tramp-file-p name) | 1350 | (unless (tramp-tramp-file-p name) |
| 1351 | (tramp-compat-user-error nil "Not a Tramp file name: \"%s\"" name)) | 1351 | (tramp-user-error nil "Not a Tramp file name: \"%s\"" name)) |
| 1352 | (if (not (string-match (nth 0 tramp-file-name-structure) name)) | 1352 | (if (not (string-match (nth 0 tramp-file-name-structure) name)) |
| 1353 | (error "`tramp-file-name-structure' didn't match!") | 1353 | (error "`tramp-file-name-structure' didn't match!") |
| 1354 | (let ((method (match-string (nth 1 tramp-file-name-structure) name)) | 1354 | (let ((method (match-string (nth 1 tramp-file-name-structure) name)) |
| @@ -1608,12 +1608,12 @@ ARGUMENTS to actually emit the message (if applicable)." | |||
| 1608 | (regexp-opt | 1608 | (regexp-opt |
| 1609 | '("tramp-backtrace" | 1609 | '("tramp-backtrace" |
| 1610 | "tramp-compat-funcall" | 1610 | "tramp-compat-funcall" |
| 1611 | "tramp-compat-user-error" | ||
| 1612 | "tramp-condition-case-unless-debug" | 1611 | "tramp-condition-case-unless-debug" |
| 1613 | "tramp-debug-message" | 1612 | "tramp-debug-message" |
| 1614 | "tramp-error" | 1613 | "tramp-error" |
| 1615 | "tramp-error-with-buffer" | 1614 | "tramp-error-with-buffer" |
| 1616 | "tramp-message") | 1615 | "tramp-message" |
| 1616 | "tramp-user-error") | ||
| 1617 | t) | 1617 | t) |
| 1618 | "$") | 1618 | "$") |
| 1619 | fn))) | 1619 | fn))) |
| @@ -1753,6 +1753,31 @@ an input event arrives. The other arguments are passed to `tramp-error'." | |||
| 1753 | (when (tramp-file-name-equal-p vec (car tramp-current-connection)) | 1753 | (when (tramp-file-name-equal-p vec (car tramp-current-connection)) |
| 1754 | (setcdr tramp-current-connection (current-time))))))) | 1754 | (setcdr tramp-current-connection (current-time))))))) |
| 1755 | 1755 | ||
| 1756 | ;; We must make it a defun, because it is used earlier already. | ||
| 1757 | (defun tramp-user-error (vec-or-proc fmt-string &rest arguments) | ||
| 1758 | "Signal a pilot error." | ||
| 1759 | (unwind-protect | ||
| 1760 | (apply | ||
| 1761 | 'tramp-error vec-or-proc | ||
| 1762 | ;; `user-error' has appeared in Emacs 24.3. | ||
| 1763 | (if (fboundp 'user-error) 'user-error 'error) fmt-string arguments) | ||
| 1764 | ;; Save exit. | ||
| 1765 | (when (and tramp-message-show-message | ||
| 1766 | (not (zerop tramp-verbose)) | ||
| 1767 | ;; Do not show when flagged from outside. | ||
| 1768 | (not (tramp-completion-mode-p)) | ||
| 1769 | ;; Show only when Emacs has started already. | ||
| 1770 | (current-message)) | ||
| 1771 | (let ((enable-recursive-minibuffers t)) | ||
| 1772 | ;; `tramp-error' does not show messages. So we must do it ourselves. | ||
| 1773 | (apply 'message fmt-string arguments) | ||
| 1774 | (discard-input) | ||
| 1775 | (sit-for 30) | ||
| 1776 | ;; Reset timestamp. It would be wrong after waiting for a while. | ||
| 1777 | (when | ||
| 1778 | (tramp-file-name-equal-p vec-or-proc (car tramp-current-connection)) | ||
| 1779 | (setcdr tramp-current-connection (current-time))))))) | ||
| 1780 | |||
| 1756 | (defmacro tramp-with-demoted-errors (vec-or-proc format &rest body) | 1781 | (defmacro tramp-with-demoted-errors (vec-or-proc format &rest body) |
| 1757 | "Execute BODY while redirecting the error message to `tramp-message'. | 1782 | "Execute BODY while redirecting the error message to `tramp-message'. |
| 1758 | BODY is executed like wrapped by `with-demoted-errors'. FORMAT | 1783 | BODY is executed like wrapped by `with-demoted-errors'. FORMAT |
| @@ -3503,7 +3528,7 @@ support symbolic links." | |||
| 3503 | (when p | 3528 | (when p |
| 3504 | (if (yes-or-no-p "A command is running. Kill it? ") | 3529 | (if (yes-or-no-p "A command is running. Kill it? ") |
| 3505 | (ignore-errors (kill-process p)) | 3530 | (ignore-errors (kill-process p)) |
| 3506 | (tramp-compat-user-error p "Shell command in progress"))) | 3531 | (tramp-user-error p "Shell command in progress"))) |
| 3507 | 3532 | ||
| 3508 | (if current-buffer-p | 3533 | (if current-buffer-p |
| 3509 | (progn | 3534 | (progn |
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index dfb01126f70..5e79a4bce6f 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el | |||
| @@ -1722,6 +1722,28 @@ handled properly. BODY shall not contain a timeout." | |||
| 1722 | ;; Default values in tramp-smb.el. | 1722 | ;; Default values in tramp-smb.el. |
| 1723 | (should (string-equal (file-remote-p "/smb::" 'user) nil))) | 1723 | (should (string-equal (file-remote-p "/smb::" 'user) nil))) |
| 1724 | 1724 | ||
| 1725 | ;; The following test is inspired by Bug#30946. | ||
| 1726 | (ert-deftest tramp-test03-file-name-host-rules () | ||
| 1727 | "Check host name rules for host-less methods." | ||
| 1728 | (skip-unless (tramp--test-enabled)) | ||
| 1729 | (skip-unless (tramp--test-sh-p)) | ||
| 1730 | |||
| 1731 | ;; Host names must match rules in case the command template of a | ||
| 1732 | ;; method doesn't use them. | ||
| 1733 | (dolist (m '("su" "sg" "sudo" "doas" "ksu")) | ||
| 1734 | ;; Single hop. The host name must match `tramp-local-host-regexp'. | ||
| 1735 | (should-error | ||
| 1736 | (find-file (format "/%s:foo:" m)) | ||
| 1737 | :type 'user-error) | ||
| 1738 | ;; Multi hop. The host name must match the previous hop. | ||
| 1739 | (should-error | ||
| 1740 | (find-file | ||
| 1741 | (format | ||
| 1742 | "%s|%s:foo:" | ||
| 1743 | (substring (file-remote-p tramp-test-temporary-file-directory) nil -1) | ||
| 1744 | m)) | ||
| 1745 | :type 'user-error))) | ||
| 1746 | |||
| 1725 | (ert-deftest tramp-test04-substitute-in-file-name () | 1747 | (ert-deftest tramp-test04-substitute-in-file-name () |
| 1726 | "Check `substitute-in-file-name'." | 1748 | "Check `substitute-in-file-name'." |
| 1727 | (should (string-equal (substitute-in-file-name "/method:host:///foo") "/foo")) | 1749 | (should (string-equal (substitute-in-file-name "/method:host:///foo") "/foo")) |
| @@ -1836,6 +1858,7 @@ handled properly. BODY shall not contain a timeout." | |||
| 1836 | ;; Mark as failed until bug has been fixed. | 1858 | ;; Mark as failed until bug has been fixed. |
| 1837 | :expected-result :failed | 1859 | :expected-result :failed |
| 1838 | (skip-unless (tramp--test-enabled)) | 1860 | (skip-unless (tramp--test-enabled)) |
| 1861 | |||
| 1839 | ;; These are the methods the test doesn't fail. | 1862 | ;; These are the methods the test doesn't fail. |
| 1840 | (when (or (tramp--test-adb-p) (tramp--test-gvfs-p) | 1863 | (when (or (tramp--test-adb-p) (tramp--test-gvfs-p) |
| 1841 | (tramp-smb-file-name-p tramp-test-temporary-file-directory)) | 1864 | (tramp-smb-file-name-p tramp-test-temporary-file-directory)) |