diff options
| author | Michael Albinus | 2009-08-27 13:47:55 +0000 |
|---|---|---|
| committer | Michael Albinus | 2009-08-27 13:47:55 +0000 |
| commit | 946a5aeb7d70dc0a2e206f0b00aae83b25bafe1c (patch) | |
| tree | eb0d61d1223d951522ba5df5644d7e2a7928fb9e | |
| parent | 0ff2d6c28efa369ae227c5f35bc2f22eef0f5a60 (diff) | |
| download | emacs-946a5aeb7d70dc0a2e206f0b00aae83b25bafe1c.tar.gz emacs-946a5aeb7d70dc0a2e206f0b00aae83b25bafe1c.zip | |
* net/tramp.el (tramp-methods): New method "rsyncc".
(top): Add completion function for "rsyncc".
(tramp-message-show-message): New defvar.
(tramp-message, tramp-error): Use it.
(tramp-do-copy-or-rename-file-directly): Extend check for direct
remote copying.
(tramp-do-copy-or-rename-file-out-of-band): Handle new
`tramp-methods' entry `copy-env' of "rsyncc".
((tramp-handle-process-file): Do not flush all
caches when `process-file-side-effects' is set.
tramp-vc-registered-read-file-names): New defconst.
(tramp-vc-registered-file-names): New defvar.
(tramp-handle-vc-registered): Implement optimization strategy.
(tramp-run-real-handler): Add `tramp-vc-file-name-handler'.
(tramp-vc-file-name-handler): New defun.
(tramp-get-ls-command, tramp-get-test-command)
(tramp-get-file-exists-command, tramp-get-remote-ln)
(tramp-get-remote-perl, tramp-get-remote-stat)
(tramp-get-remote-id): Remove
superfluous `with-current-buffer'.
| -rw-r--r-- | lisp/net/tramp.el | 310 |
1 files changed, 221 insertions, 89 deletions
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 16f9c5b182c..8453f678acc 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el | |||
| @@ -375,6 +375,21 @@ files conditionalize this setup based on the TERM environment variable." | |||
| 375 | (tramp-copy-args (("-e" "ssh") ("-t" "%k"))) | 375 | (tramp-copy-args (("-e" "ssh") ("-t" "%k"))) |
| 376 | (tramp-copy-keep-date t) | 376 | (tramp-copy-keep-date t) |
| 377 | (tramp-password-end-of-line nil)) | 377 | (tramp-password-end-of-line nil)) |
| 378 | ("rsyncc" (tramp-login-program "ssh") | ||
| 379 | (tramp-login-args (("%h") ("-l" "%u") ("-p" "%p") | ||
| 380 | ("-o" "ControlPath=%t.%%r@%%h:%%p") | ||
| 381 | ("-o" "ControlMaster=yes") | ||
| 382 | ("-e" "none"))) | ||
| 383 | (tramp-remote-sh "/bin/sh") | ||
| 384 | (tramp-copy-program "rsync") | ||
| 385 | (tramp-copy-args (("-t" "%k"))) | ||
| 386 | (tramp-copy-env (("RSYNC_RSH") | ||
| 387 | (,(concat | ||
| 388 | "ssh" | ||
| 389 | " -o ControlPath=%t.%%r@%%h:%%p" | ||
| 390 | " -o ControlMaster=auto")))) | ||
| 391 | (tramp-copy-keep-date t) | ||
| 392 | (tramp-password-end-of-line nil)) | ||
| 378 | ("remcp" (tramp-login-program "remsh") | 393 | ("remcp" (tramp-login-program "remsh") |
| 379 | (tramp-login-args (("%h") ("-l" "%u"))) | 394 | (tramp-login-args (("%h") ("-l" "%u"))) |
| 380 | (tramp-remote-sh "/bin/sh") | 395 | (tramp-remote-sh "/bin/sh") |
| @@ -850,6 +865,8 @@ the info pages.") | |||
| 850 | (tramp-set-completion-function | 865 | (tramp-set-completion-function |
| 851 | "rsync" tramp-completion-function-alist-ssh) | 866 | "rsync" tramp-completion-function-alist-ssh) |
| 852 | (tramp-set-completion-function | 867 | (tramp-set-completion-function |
| 868 | "rsyncc" tramp-completion-function-alist-ssh) | ||
| 869 | (tramp-set-completion-function | ||
| 853 | "remcp" tramp-completion-function-alist-rsh) | 870 | "remcp" tramp-completion-function-alist-rsh) |
| 854 | (tramp-set-completion-function | 871 | (tramp-set-completion-function |
| 855 | "rsh" tramp-completion-function-alist-rsh) | 872 | "rsh" tramp-completion-function-alist-rsh) |
| @@ -1788,6 +1805,25 @@ while (my $data = <STDIN>) { | |||
| 1788 | Escape sequence %s is replaced with name of Perl binary. | 1805 | Escape sequence %s is replaced with name of Perl binary. |
| 1789 | This string is passed to `format', so percent characters need to be doubled.") | 1806 | This string is passed to `format', so percent characters need to be doubled.") |
| 1790 | 1807 | ||
| 1808 | (defconst tramp-vc-registered-read-file-names | ||
| 1809 | "echo \"(\" | ||
| 1810 | for file in \"$@\"; do | ||
| 1811 | if %s $file; then | ||
| 1812 | echo \"(\\\"$file\\\" \\\"file-exists-p\\\" t)\" | ||
| 1813 | else | ||
| 1814 | echo \"(\\\"$file\\\" \\\"file-exists-p\\\" nil)\" | ||
| 1815 | fi | ||
| 1816 | if %s $file; then | ||
| 1817 | echo \"(\\\"$file\\\" \\\"file-readable-p\\\" t)\" | ||
| 1818 | else | ||
| 1819 | echo \"(\\\"$file\\\" \\\"file-readable-p\\\" nil)\" | ||
| 1820 | fi | ||
| 1821 | done | ||
| 1822 | echo \")\"" | ||
| 1823 | "Script to check existence of VC related files. | ||
| 1824 | It must be send formatted with two strings; the tests for file | ||
| 1825 | existence, and file readability.") | ||
| 1826 | |||
| 1791 | (defconst tramp-file-mode-type-map | 1827 | (defconst tramp-file-mode-type-map |
| 1792 | '((0 . "-") ; Normal file (SVID-v2 and XPG2) | 1828 | '((0 . "-") ; Normal file (SVID-v2 and XPG2) |
| 1793 | (1 . "p") ; fifo | 1829 | (1 . "p") ; fifo |
| @@ -1938,6 +1974,11 @@ ARGS to actually emit the message (if applicable)." | |||
| 1938 | ;; The message. | 1974 | ;; The message. |
| 1939 | (insert (apply 'format fmt-string args))))) | 1975 | (insert (apply 'format fmt-string args))))) |
| 1940 | 1976 | ||
| 1977 | (defvar tramp-message-show-message t | ||
| 1978 | "Show Tramp message in the minibuffer. | ||
| 1979 | This variable is used to disable messages from `tramp-error'. | ||
| 1980 | The messages are visible anyway, because an error is raised.") | ||
| 1981 | |||
| 1941 | (defsubst tramp-message (vec-or-proc level fmt-string &rest args) | 1982 | (defsubst tramp-message (vec-or-proc level fmt-string &rest args) |
| 1942 | "Emit a message depending on verbosity level. | 1983 | "Emit a message depending on verbosity level. |
| 1943 | VEC-OR-PROC identifies the Tramp buffer to use. It can be either a | 1984 | VEC-OR-PROC identifies the Tramp buffer to use. It can be either a |
| @@ -1956,7 +1997,7 @@ applicable)." | |||
| 1956 | ;; Match data must be preserved! | 1997 | ;; Match data must be preserved! |
| 1957 | (save-match-data | 1998 | (save-match-data |
| 1958 | ;; Display only when there is a minimum level. | 1999 | ;; Display only when there is a minimum level. |
| 1959 | (when (<= level 3) | 2000 | (when (and tramp-message-show-message (<= level 3)) |
| 1960 | (apply 'message | 2001 | (apply 'message |
| 1961 | (concat | 2002 | (concat |
| 1962 | (cond | 2003 | (cond |
| @@ -1987,11 +2028,14 @@ applicable)." | |||
| 1987 | VEC-OR-PROC identifies the connection to use, SIGNAL is the | 2028 | VEC-OR-PROC identifies the connection to use, SIGNAL is the |
| 1988 | signal identifier to be raised, remaining args passed to | 2029 | signal identifier to be raised, remaining args passed to |
| 1989 | `tramp-message'. Finally, signal SIGNAL is raised." | 2030 | `tramp-message'. Finally, signal SIGNAL is raised." |
| 1990 | (tramp-message | 2031 | (let (tramp-message-show-message) |
| 1991 | vec-or-proc 1 "%s" | 2032 | (tramp-message |
| 1992 | (error-message-string | 2033 | vec-or-proc 1 "%s" |
| 1993 | (list signal (get signal 'error-message) (apply 'format fmt-string args)))) | 2034 | (error-message-string |
| 1994 | (signal signal (list (apply 'format fmt-string args)))) | 2035 | (list signal |
| 2036 | (get signal 'error-message) | ||
| 2037 | (apply 'format fmt-string args)))) | ||
| 2038 | (signal signal (list (apply 'format fmt-string args))))) | ||
| 1995 | 2039 | ||
| 1996 | (defsubst tramp-error-with-buffer | 2040 | (defsubst tramp-error-with-buffer |
| 1997 | (buffer vec-or-proc signal fmt-string &rest args) | 2041 | (buffer vec-or-proc signal fmt-string &rest args) |
| @@ -3298,10 +3342,11 @@ the uid and gid from FILENAME." | |||
| 3298 | 'rename-file (list localname1 localname2 ok-if-already-exists)))) | 3342 | 'rename-file (list localname1 localname2 ok-if-already-exists)))) |
| 3299 | 3343 | ||
| 3300 | ;; We can do it directly with `tramp-send-command' | 3344 | ;; We can do it directly with `tramp-send-command' |
| 3301 | ((let (file-name-handler-alist) | 3345 | ((and (file-readable-p (concat prefix localname1)) |
| 3302 | (and (file-readable-p (concat prefix localname1)) | 3346 | (file-writable-p |
| 3303 | (file-writable-p | 3347 | (file-name-directory (concat prefix localname2))) |
| 3304 | (file-name-directory (concat prefix localname2))))) | 3348 | (or (file-directory-p (concat prefix localname2)) |
| 3349 | (file-writable-p (concat prefix localname2)))) | ||
| 3305 | (tramp-do-copy-or-rename-file-directly | 3350 | (tramp-do-copy-or-rename-file-directly |
| 3306 | op (concat prefix localname1) (concat prefix localname2) | 3351 | op (concat prefix localname1) (concat prefix localname2) |
| 3307 | ok-if-already-exists keep-date t) | 3352 | ok-if-already-exists keep-date t) |
| @@ -3392,7 +3437,7 @@ the uid and gid from FILENAME." | |||
| 3392 | The method used must be an out-of-band method." | 3437 | The method used must be an out-of-band method." |
| 3393 | (let ((t1 (tramp-tramp-file-p filename)) | 3438 | (let ((t1 (tramp-tramp-file-p filename)) |
| 3394 | (t2 (tramp-tramp-file-p newname)) | 3439 | (t2 (tramp-tramp-file-p newname)) |
| 3395 | copy-program copy-args copy-keep-date port spec | 3440 | copy-program copy-args copy-env copy-keep-date port spec |
| 3396 | source target) | 3441 | source target) |
| 3397 | 3442 | ||
| 3398 | (with-parsed-tramp-file-name (if t1 filename newname) nil | 3443 | (with-parsed-tramp-file-name (if t1 filename newname) nil |
| @@ -3445,7 +3490,15 @@ The method used must be an out-of-band method." | |||
| 3445 | ;; " " is indication for keep-date argument. | 3490 | ;; " " is indication for keep-date argument. |
| 3446 | (delete " " (mapcar '(lambda (y) (format-spec y spec)) x))) | 3491 | (delete " " (mapcar '(lambda (y) (format-spec y spec)) x))) |
| 3447 | (unless (member "" x) (mapconcat 'identity x " "))) | 3492 | (unless (member "" x) (mapconcat 'identity x " "))) |
| 3448 | (tramp-get-method-parameter method 'tramp-copy-args)))) | 3493 | (tramp-get-method-parameter method 'tramp-copy-args))) |
| 3494 | copy-env | ||
| 3495 | (delq | ||
| 3496 | nil | ||
| 3497 | (mapcar | ||
| 3498 | '(lambda (x) | ||
| 3499 | (setq x (mapcar '(lambda (y) (format-spec y spec)) x)) | ||
| 3500 | (unless (member "" x) (mapconcat 'identity x " "))) | ||
| 3501 | (tramp-get-method-parameter method 'tramp-copy-env)))) | ||
| 3449 | 3502 | ||
| 3450 | ;; Check for program. | 3503 | ;; Check for program. |
| 3451 | (when (and (fboundp 'executable-find) | 3504 | (when (and (fboundp 'executable-find) |
| @@ -3459,12 +3512,16 @@ The method used must be an out-of-band method." | |||
| 3459 | (with-temp-buffer | 3512 | (with-temp-buffer |
| 3460 | ;; The default directory must be remote. | 3513 | ;; The default directory must be remote. |
| 3461 | (let ((default-directory | 3514 | (let ((default-directory |
| 3462 | (file-name-directory (if t1 filename newname)))) | 3515 | (file-name-directory (if t1 filename newname))) |
| 3516 | (process-environment (copy-sequence process-environment))) | ||
| 3463 | ;; Set the transfer process properties. | 3517 | ;; Set the transfer process properties. |
| 3464 | (tramp-set-connection-property | 3518 | (tramp-set-connection-property |
| 3465 | v "process-name" (buffer-name (current-buffer))) | 3519 | v "process-name" (buffer-name (current-buffer))) |
| 3466 | (tramp-set-connection-property | 3520 | (tramp-set-connection-property |
| 3467 | v "process-buffer" (current-buffer)) | 3521 | v "process-buffer" (current-buffer)) |
| 3522 | (while copy-env | ||
| 3523 | (tramp-message v 5 "%s=\"%s\"" (car copy-env) (cadr copy-env)) | ||
| 3524 | (setenv (pop copy-env) (pop copy-env))) | ||
| 3468 | 3525 | ||
| 3469 | ;; Use an asynchronous process. By this, password can | 3526 | ;; Use an asynchronous process. By this, password can |
| 3470 | ;; be handled. The default directory must be local, in | 3527 | ;; be handled. The default directory must be local, in |
| @@ -4015,7 +4072,15 @@ beginning of local filename are not substituted." | |||
| 4015 | ;; Cleanup. We remove all file cache values for the connection, | 4072 | ;; Cleanup. We remove all file cache values for the connection, |
| 4016 | ;; because the remote process could have changed them. | 4073 | ;; because the remote process could have changed them. |
| 4017 | (when tmpinput (delete-file tmpinput)) | 4074 | (when tmpinput (delete-file tmpinput)) |
| 4018 | (tramp-flush-directory-property v "") | 4075 | |
| 4076 | ;; `process-file-side-effects' has been introduced with GNU | ||
| 4077 | ;; Emacs 23.2. If set to `nil', no remote file will be changed | ||
| 4078 | ;; by `program'. If it doesn't exist, we assume its default | ||
| 4079 | ;; value 't'. | ||
| 4080 | (unless (and (boundp 'process-file-side-effects) | ||
| 4081 | (not (symbol-value 'process-file-side-effects))) | ||
| 4082 | (tramp-flush-directory-property v "")) | ||
| 4083 | |||
| 4019 | ;; Return exit status. | 4084 | ;; Return exit status. |
| 4020 | (if (equal ret -1) | 4085 | (if (equal ret -1) |
| 4021 | (keyboard-quit) | 4086 | (keyboard-quit) |
| @@ -4664,12 +4729,61 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file." | |||
| 4664 | (tramp-message v 0 "Wrote %s" filename)) | 4729 | (tramp-message v 0 "Wrote %s" filename)) |
| 4665 | (run-hooks 'tramp-handle-write-region-hook))))) | 4730 | (run-hooks 'tramp-handle-write-region-hook))))) |
| 4666 | 4731 | ||
| 4732 | (defvar tramp-vc-registered-file-names nil | ||
| 4733 | "List used to collect file names, which are checked during `vc-registered'.") | ||
| 4734 | |||
| 4735 | ;; VC backends check for the existence of various different special | ||
| 4736 | ;; files. This is very time consuming, because every single check | ||
| 4737 | ;; requires a remote command (the file cache must be invalidated). | ||
| 4738 | ;; Therefore, we apply a kind of optimization. We install the file | ||
| 4739 | ;; name handler `tramp-vc-file-name-handler', which does nothing but | ||
| 4740 | ;; remembers all file names for which `file-exists-p' or | ||
| 4741 | ;; `file-readable-p' has been applied. A first run of `vc-registered' | ||
| 4742 | ;; is performed. Afterwards, a script is applied for all collected | ||
| 4743 | ;; file names, using just one remote command. The result of this | ||
| 4744 | ;; script is used to fill the file cache with actual values. Now we | ||
| 4745 | ;; can reset the file name handlers, and we make a second run of | ||
| 4746 | ;; `vc-registered', which returns the expected result without sending | ||
| 4747 | ;; any other remote command. | ||
| 4667 | (defun tramp-handle-vc-registered (file) | 4748 | (defun tramp-handle-vc-registered (file) |
| 4668 | "Like `vc-registered' for Tramp files." | 4749 | "Like `vc-registered' for Tramp files." |
| 4669 | ;; There could be new files, created by the vc backend. We disable | 4750 | ;; There could be new files, created by the vc backend. We cannot |
| 4670 | ;; the file cache therefore. | 4751 | ;; reuse the old cache entries, therefore. |
| 4671 | (let ((tramp-cache-inhibit-cache t)) | 4752 | (with-parsed-tramp-file-name file nil |
| 4672 | (tramp-run-real-handler 'vc-registered (list file)))) | 4753 | (let (tramp-vc-registered-file-names |
| 4754 | (tramp-cache-inhibit-cache (current-time)) | ||
| 4755 | (file-name-handler-alist | ||
| 4756 | `((,tramp-file-name-regexp . tramp-vc-file-name-handler)))) | ||
| 4757 | |||
| 4758 | ;; Here we collect only file names, which need an operation. | ||
| 4759 | (tramp-run-real-handler 'vc-registered (list file)) | ||
| 4760 | (tramp-message v 10 "\n%s" tramp-vc-registered-file-names) | ||
| 4761 | |||
| 4762 | ;; Send just one command, in order to fill the cache. | ||
| 4763 | (tramp-maybe-send-script | ||
| 4764 | v | ||
| 4765 | (format tramp-vc-registered-read-file-names | ||
| 4766 | (tramp-get-file-exists-command v) | ||
| 4767 | (format "%s -r" (tramp-get-test-command v))) | ||
| 4768 | "tramp_vc_registered_read_file_names") | ||
| 4769 | |||
| 4770 | (dolist | ||
| 4771 | (elt | ||
| 4772 | (tramp-send-command-and-read | ||
| 4773 | v | ||
| 4774 | (format | ||
| 4775 | "tramp_vc_registered_read_file_names %s" | ||
| 4776 | (mapconcat 'tramp-shell-quote-argument | ||
| 4777 | tramp-vc-registered-file-names | ||
| 4778 | " ")))) | ||
| 4779 | |||
| 4780 | (tramp-set-file-property v (car elt) (cadr elt) (cadr (cdr elt))))) | ||
| 4781 | |||
| 4782 | ;; Second run. Now all requests shall be answered from the file | ||
| 4783 | ;; cache. We unset `process-file-side-effects' in order to keep | ||
| 4784 | ;; the cache when `process-file' calls appear. | ||
| 4785 | (let (process-file-side-effects) | ||
| 4786 | (tramp-run-real-handler 'vc-registered (list file))))) | ||
| 4673 | 4787 | ||
| 4674 | ;;;###autoload | 4788 | ;;;###autoload |
| 4675 | (progn (defun tramp-run-real-handler (operation args) | 4789 | (progn (defun tramp-run-real-handler (operation args) |
| @@ -4678,6 +4792,7 @@ First arg specifies the OPERATION, second arg is a list of arguments to | |||
| 4678 | pass to the OPERATION." | 4792 | pass to the OPERATION." |
| 4679 | (let* ((inhibit-file-name-handlers | 4793 | (let* ((inhibit-file-name-handlers |
| 4680 | `(tramp-file-name-handler | 4794 | `(tramp-file-name-handler |
| 4795 | tramp-vc-file-name-handler | ||
| 4681 | tramp-completion-file-name-handler | 4796 | tramp-completion-file-name-handler |
| 4682 | cygwin-mount-name-hook-function | 4797 | cygwin-mount-name-hook-function |
| 4683 | cygwin-mount-map-drive-hook-function | 4798 | cygwin-mount-map-drive-hook-function |
| @@ -4881,6 +4996,30 @@ Fall back to normal file name handler if no Tramp handler exists." | |||
| 4881 | (tramp-run-real-handler operation args)))))) | 4996 | (tramp-run-real-handler operation args)))))) |
| 4882 | (setq tramp-locked tl)))) | 4997 | (setq tramp-locked tl)))) |
| 4883 | 4998 | ||
| 4999 | (defun tramp-vc-file-name-handler (operation &rest args) | ||
| 5000 | "Invoke special file name handler, which collects files to be handled." | ||
| 5001 | (save-match-data | ||
| 5002 | (let ((filename | ||
| 5003 | (tramp-replace-environment-variables | ||
| 5004 | (apply 'tramp-file-name-for-operation operation args))) | ||
| 5005 | (fn (assoc operation tramp-file-name-handler-alist))) | ||
| 5006 | (with-parsed-tramp-file-name filename nil | ||
| 5007 | (cond | ||
| 5008 | ;; That's what we want: file names, for which checks are | ||
| 5009 | ;; applied. We assume, that VC uses only `file-exists-p' and | ||
| 5010 | ;; `file-readable-p' checks; otherwise we must extend the | ||
| 5011 | ;; list. We do not perform any action, but return nil, in | ||
| 5012 | ;; order to keep `vc-registered' running. | ||
| 5013 | ((and fn (memq operation '(file-exists-p file-readable-p))) | ||
| 5014 | (add-to-list 'tramp-vc-registered-file-names localname 'append) | ||
| 5015 | nil) | ||
| 5016 | ;; Tramp file name handlers like `expand-file-name'. They | ||
| 5017 | ;; must still work. | ||
| 5018 | (fn | ||
| 5019 | (save-match-data (apply (cdr fn) args))) | ||
| 5020 | ;; Default file name handlers, we don't care. | ||
| 5021 | (t (tramp-run-real-handler operation args))))))) | ||
| 5022 | |||
| 4884 | ;;;###autoload | 5023 | ;;;###autoload |
| 4885 | (progn (defun tramp-completion-file-name-handler (operation &rest args) | 5024 | (progn (defun tramp-completion-file-name-handler (operation &rest args) |
| 4886 | "Invoke Tramp file name completion handler. | 5025 | "Invoke Tramp file name completion handler. |
| @@ -7369,24 +7508,19 @@ necessary only. This function will be used in file name completion." | |||
| 7369 | 7508 | ||
| 7370 | (defun tramp-get-ls-command (vec) | 7509 | (defun tramp-get-ls-command (vec) |
| 7371 | (with-connection-property vec "ls" | 7510 | (with-connection-property vec "ls" |
| 7372 | (with-current-buffer (tramp-get-buffer vec) | 7511 | (tramp-message vec 5 "Finding a suitable `ls' command") |
| 7373 | (tramp-message vec 5 "Finding a suitable `ls' command") | 7512 | (or |
| 7374 | (or | 7513 | (catch 'ls-found |
| 7375 | (catch 'ls-found | 7514 | (dolist (cmd '("ls" "gnuls" "gls")) |
| 7376 | (dolist (cmd '("ls" "gnuls" "gls")) | 7515 | (let ((dl (tramp-get-remote-path vec)) |
| 7377 | (let ((dl (tramp-get-remote-path vec)) | 7516 | result) |
| 7378 | result) | 7517 | (while (and dl (setq result (tramp-find-executable vec cmd dl t t))) |
| 7379 | (while | 7518 | ;; Check parameter. |
| 7380 | (and | 7519 | (when (zerop (tramp-send-command-and-check |
| 7381 | dl | 7520 | vec (format "%s -lnd /" result))) |
| 7382 | (setq result | 7521 | (throw 'ls-found result)) |
| 7383 | (tramp-find-executable vec cmd dl t t))) | 7522 | (setq dl (cdr dl)))))) |
| 7384 | ;; Check parameter. | 7523 | (tramp-error vec 'file-error "Couldn't find a proper `ls' command")))) |
| 7385 | (when (zerop (tramp-send-command-and-check | ||
| 7386 | vec (format "%s -lnd /" result))) | ||
| 7387 | (throw 'ls-found result)) | ||
| 7388 | (setq dl (cdr dl)))))) | ||
| 7389 | (tramp-error vec 'file-error "Couldn't find a proper `ls' command"))))) | ||
| 7390 | 7524 | ||
| 7391 | (defun tramp-get-ls-command-with-dired (vec) | 7525 | (defun tramp-get-ls-command-with-dired (vec) |
| 7392 | (save-match-data | 7526 | (save-match-data |
| @@ -7397,11 +7531,10 @@ necessary only. This function will be used in file name completion." | |||
| 7397 | 7531 | ||
| 7398 | (defun tramp-get-test-command (vec) | 7532 | (defun tramp-get-test-command (vec) |
| 7399 | (with-connection-property vec "test" | 7533 | (with-connection-property vec "test" |
| 7400 | (with-current-buffer (tramp-get-buffer vec) | 7534 | (tramp-message vec 5 "Finding a suitable `test' command") |
| 7401 | (tramp-message vec 5 "Finding a suitable `test' command") | 7535 | (if (zerop (tramp-send-command-and-check vec "test 0")) |
| 7402 | (if (zerop (tramp-send-command-and-check vec "test 0")) | 7536 | "test" |
| 7403 | "test" | 7537 | (tramp-find-executable vec "test" (tramp-get-remote-path vec))))) |
| 7404 | (tramp-find-executable vec "test" (tramp-get-remote-path vec)))))) | ||
| 7405 | 7538 | ||
| 7406 | (defun tramp-get-test-nt-command (vec) | 7539 | (defun tramp-get-test-nt-command (vec) |
| 7407 | ;; Does `test A -nt B' work? Use abominable `find' construct if it | 7540 | ;; Does `test A -nt B' work? Use abominable `find' construct if it |
| @@ -7426,65 +7559,56 @@ necessary only. This function will be used in file name completion." | |||
| 7426 | 7559 | ||
| 7427 | (defun tramp-get-file-exists-command (vec) | 7560 | (defun tramp-get-file-exists-command (vec) |
| 7428 | (with-connection-property vec "file-exists" | 7561 | (with-connection-property vec "file-exists" |
| 7429 | (with-current-buffer (tramp-get-buffer vec) | 7562 | (tramp-message vec 5 "Finding command to check if file exists") |
| 7430 | (tramp-message vec 5 "Finding command to check if file exists") | 7563 | (tramp-find-file-exists-command vec))) |
| 7431 | (tramp-find-file-exists-command vec)))) | ||
| 7432 | 7564 | ||
| 7433 | (defun tramp-get-remote-ln (vec) | 7565 | (defun tramp-get-remote-ln (vec) |
| 7434 | (with-connection-property vec "ln" | 7566 | (with-connection-property vec "ln" |
| 7435 | (with-current-buffer (tramp-get-buffer vec) | 7567 | (tramp-message vec 5 "Finding a suitable `ln' command") |
| 7436 | (tramp-message vec 5 "Finding a suitable `ln' command") | 7568 | (tramp-find-executable vec "ln" (tramp-get-remote-path vec)))) |
| 7437 | (tramp-find-executable vec "ln" (tramp-get-remote-path vec))))) | ||
| 7438 | 7569 | ||
| 7439 | (defun tramp-get-remote-perl (vec) | 7570 | (defun tramp-get-remote-perl (vec) |
| 7440 | (with-connection-property vec "perl" | 7571 | (with-connection-property vec "perl" |
| 7441 | (with-current-buffer (tramp-get-buffer vec) | 7572 | (tramp-message vec 5 "Finding a suitable `perl' command") |
| 7442 | (tramp-message vec 5 "Finding a suitable `perl' command") | 7573 | (or (tramp-find-executable vec "perl5" (tramp-get-remote-path vec)) |
| 7443 | (or (tramp-find-executable vec "perl5" (tramp-get-remote-path vec)) | 7574 | (tramp-find-executable vec "perl" (tramp-get-remote-path vec))))) |
| 7444 | (tramp-find-executable vec "perl" (tramp-get-remote-path vec)))))) | ||
| 7445 | 7575 | ||
| 7446 | (defun tramp-get-remote-stat (vec) | 7576 | (defun tramp-get-remote-stat (vec) |
| 7447 | (with-connection-property vec "stat" | 7577 | (with-connection-property vec "stat" |
| 7448 | (with-current-buffer (tramp-get-buffer vec) | 7578 | (tramp-message vec 5 "Finding a suitable `stat' command") |
| 7449 | (tramp-message vec 5 "Finding a suitable `stat' command") | 7579 | (let ((result (tramp-find-executable |
| 7450 | (let ((result (tramp-find-executable | 7580 | vec "stat" (tramp-get-remote-path vec))) |
| 7451 | vec "stat" (tramp-get-remote-path vec))) | 7581 | tmp) |
| 7452 | tmp) | 7582 | ;; Check whether stat(1) returns usable syntax. %s does not |
| 7453 | ;; Check whether stat(1) returns usable syntax. %s does not | 7583 | ;; work on older AIX systems. |
| 7454 | ;; work on older AIX systems. | 7584 | (when result |
| 7455 | (when result | 7585 | (setq tmp |
| 7456 | (setq tmp | 7586 | ;; We don't want to display an error message. |
| 7457 | ;; We don't want to display an error message. | 7587 | (with-temp-message (or (current-message) "") |
| 7458 | (with-temp-message (or (current-message) "") | 7588 | (condition-case nil |
| 7459 | (condition-case nil | 7589 | (tramp-send-command-and-read |
| 7460 | (tramp-send-command-and-read | 7590 | vec (format "%s -c '(\"%%N\" %%s)' /" result)) |
| 7461 | vec (format "%s -c '(\"%%N\" %%s)' /" result)) | 7591 | (error nil)))) |
| 7462 | (error nil)))) | 7592 | (unless (and (listp tmp) (stringp (car tmp)) |
| 7463 | (unless (and (listp tmp) (stringp (car tmp)) | 7593 | (string-match "^./.$" (car tmp)) |
| 7464 | (string-match "^./.$" (car tmp)) | 7594 | (integerp (cadr tmp))) |
| 7465 | (integerp (cadr tmp))) | 7595 | (setq result nil))) |
| 7466 | (setq result nil))) | 7596 | result))) |
| 7467 | result)))) | ||
| 7468 | 7597 | ||
| 7469 | (defun tramp-get-remote-id (vec) | 7598 | (defun tramp-get-remote-id (vec) |
| 7470 | (with-connection-property vec "id" | 7599 | (with-connection-property vec "id" |
| 7471 | (with-current-buffer (tramp-get-buffer vec) | 7600 | (tramp-message vec 5 "Finding POSIX `id' command") |
| 7472 | (tramp-message vec 5 "Finding POSIX `id' command") | 7601 | (or |
| 7473 | (or | 7602 | (catch 'id-found |
| 7474 | (catch 'id-found | 7603 | (let ((dl (tramp-get-remote-path vec)) |
| 7475 | (let ((dl (tramp-get-remote-path vec)) | 7604 | result) |
| 7476 | result) | 7605 | (while (and dl (setq result (tramp-find-executable vec "id" dl t t))) |
| 7477 | (while | 7606 | ;; Check POSIX parameter. |
| 7478 | (and | 7607 | (when (zerop (tramp-send-command-and-check |
| 7479 | dl | 7608 | vec (format "%s -u" result))) |
| 7480 | (setq result | 7609 | (throw 'id-found result)) |
| 7481 | (tramp-find-executable vec "id" dl t t))) | 7610 | (setq dl (cdr dl))))) |
| 7482 | ;; Check POSIX parameter. | 7611 | (tramp-error vec 'file-error "Couldn't find a POSIX `id' command")))) |
| 7483 | (when (zerop (tramp-send-command-and-check | ||
| 7484 | vec (format "%s -u" result))) | ||
| 7485 | (throw 'id-found result)) | ||
| 7486 | (setq dl (cdr dl))))) | ||
| 7487 | (tramp-error vec 'file-error "Couldn't find a POSIX `id' command"))))) | ||
| 7488 | 7612 | ||
| 7489 | (defun tramp-get-remote-uid (vec id-format) | 7613 | (defun tramp-get-remote-uid (vec id-format) |
| 7490 | (with-connection-property vec (format "uid-%s" id-format) | 7614 | (with-connection-property vec (format "uid-%s" id-format) |
| @@ -7939,7 +8063,15 @@ Only works for Bourne-like shells." | |||
| 7939 | ;; tramp-server-local-variable-alist) to define any such variables | 8063 | ;; tramp-server-local-variable-alist) to define any such variables |
| 7940 | ;; that they need to, which would then be let bound as appropriate | 8064 | ;; that they need to, which would then be let bound as appropriate |
| 7941 | ;; in tramp functions. (Jason Rumney) | 8065 | ;; in tramp functions. (Jason Rumney) |
| 7942 | ;; * Optimize out-of-band copying, when both methods are scp-like. | 8066 | ;; * Optimize out-of-band copying, when both methods are scp-like (not |
| 8067 | ;; rsync). | ||
| 8068 | ;; * Keep a second connection open for out-of-band methods like scp or | ||
| 8069 | ;; rsync. | ||
| 8070 | ;; * Partial completion completes word constituents. I find it | ||
| 8071 | ;; acceptable if method completion works only after :, so that we | ||
| 8072 | ;; have "/s: TAB" offer completion for the method first, filenames | ||
| 8073 | ;; afterwards. (David Kastrup) | ||
| 8074 | |||
| 7943 | 8075 | ||
| 7944 | ;; Functions for file-name-handler-alist: | 8076 | ;; Functions for file-name-handler-alist: |
| 7945 | ;; diff-latest-backup-file -- in diff.el | 8077 | ;; diff-latest-backup-file -- in diff.el |