Mercurial > emacs
comparison lisp/net/tramp.el @ 91367:c70e45a7acfd
Merge from emacs--devo--0
Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-324
author | Miles Bader <miles@gnu.org> |
---|---|
date | Wed, 30 Jan 2008 07:57:28 +0000 |
parents | 606f2d163a64 948a005afe18 |
children |
comparison
equal
deleted
inserted
replaced
91366:86f3a8f0a3a6 | 91367:c70e45a7acfd |
---|---|
439 (tramp-copy-args nil) | 439 (tramp-copy-args nil) |
440 (tramp-copy-keep-date nil) | 440 (tramp-copy-keep-date nil) |
441 (tramp-password-end-of-line nil)) | 441 (tramp-password-end-of-line nil)) |
442 ("sudo" (tramp-login-program "sudo") | 442 ("sudo" (tramp-login-program "sudo") |
443 (tramp-login-args (("-u" "%u") | 443 (tramp-login-args (("-u" "%u") |
444 ("-s" "-p" "Password:"))) | 444 ("-s") ("-H") ("-p" "Password:"))) |
445 (tramp-remote-sh "/bin/sh") | 445 (tramp-remote-sh "/bin/sh") |
446 (tramp-copy-program nil) | 446 (tramp-copy-program nil) |
447 (tramp-copy-args nil) | 447 (tramp-copy-args nil) |
448 (tramp-copy-keep-date nil) | 448 (tramp-copy-keep-date nil) |
449 (tramp-password-end-of-line nil)) | 449 (tramp-password-end-of-line nil)) |
517 (tramp-copy-keep-date nil) | 517 (tramp-copy-keep-date nil) |
518 (tramp-password-end-of-line "xy") ;see docstring for "xy" | 518 (tramp-password-end-of-line "xy") ;see docstring for "xy" |
519 (tramp-default-port 22)) | 519 (tramp-default-port 22)) |
520 ("plinkx" | 520 ("plinkx" |
521 (tramp-login-program "plink") | 521 (tramp-login-program "plink") |
522 (tramp-login-args (("-load" "%h") ("-t") | 522 ;; ("%h") must be a single element, see |
523 ;; `tramp-compute-multi-hops'. | |
524 (tramp-login-args (("-load") ("%h") ("-t") | |
523 (,(format | 525 (,(format |
524 "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=$ '" | 526 "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=$ '" |
525 tramp-terminal-type)) | 527 tramp-terminal-type)) |
526 ("/bin/sh"))) | 528 ("/bin/sh"))) |
527 (tramp-remote-sh "/bin/sh") | 529 (tramp-remote-sh "/bin/sh") |
912 :type '(repeat (choice | 914 :type '(repeat (choice |
913 (const :tag "Default Directories" tramp-default-remote-path) | 915 (const :tag "Default Directories" tramp-default-remote-path) |
914 (string :tag "Directory")))) | 916 (string :tag "Directory")))) |
915 | 917 |
916 (defcustom tramp-remote-process-environment | 918 (defcustom tramp-remote-process-environment |
917 `("HISTFILE=$HOME/.tramp_history" "HISTSIZE=1" "LC_CTYPE=C" "LC_TIME=C" | 919 `("HISTFILE=$HOME/.tramp_history" "HISTSIZE=1" "LC_ALL=C" |
918 ,(concat "TERM=" tramp-terminal-type) | 920 ,(concat "TERM=" tramp-terminal-type) |
919 "CDPATH=" "HISTORY=" "MAIL=" "MAILCHECK=" "MAILPATH=" | 921 "CDPATH=" "HISTORY=" "MAIL=" "MAILCHECK=" "MAILPATH=" |
920 "autocorrect=" "correct=") | 922 "autocorrect=" "correct=") |
921 | 923 |
922 "*List of environment variables to be set on the remote host. | 924 "*List of environment variables to be set on the remote host. |
1431 :type '(choice (const nil) integer)) | 1433 :type '(choice (const nil) integer)) |
1432 | 1434 |
1433 ;;; Internal Variables: | 1435 ;;; Internal Variables: |
1434 | 1436 |
1435 (defvar tramp-end-of-output | 1437 (defvar tramp-end-of-output |
1436 (concat | 1438 (format |
1437 "///" (md5 (concat | 1439 "%s///%s%s" |
1438 (prin1-to-string process-environment) (current-time-string)))) | 1440 tramp-rsh-end-of-line |
1441 (md5 (concat (prin1-to-string process-environment) (current-time-string))) | |
1442 tramp-rsh-end-of-line) | |
1439 "String used to recognize end of output.") | 1443 "String used to recognize end of output.") |
1440 | 1444 |
1441 (defvar tramp-current-method nil | 1445 (defvar tramp-current-method nil |
1442 "Connection method for this *tramp* buffer.") | 1446 "Connection method for this *tramp* buffer.") |
1443 | 1447 |
3030 | 3034 |
3031 (t | 3035 (t |
3032 ;; One of them must be a Tramp file. | 3036 ;; One of them must be a Tramp file. |
3033 (error "Tramp implementation says this cannot happen"))) | 3037 (error "Tramp implementation says this cannot happen"))) |
3034 | 3038 |
3039 ;; In case of `rename', we must flush the cache of the source file. | |
3040 (when (and t1 (eq op 'rename)) | |
3041 (with-parsed-tramp-file-name filename nil | |
3042 (tramp-flush-file-property v localname))) | |
3043 | |
3035 ;; When newname did exist, we have wrong cached values. | 3044 ;; When newname did exist, we have wrong cached values. |
3036 (when t2 | 3045 (when t2 |
3037 (with-parsed-tramp-file-name newname nil | 3046 (with-parsed-tramp-file-name newname nil |
3038 (tramp-flush-file-property v localname)))))) | 3047 (tramp-flush-file-property v localname)))))) |
3039 | 3048 |
3772 | 3781 |
3773 (defun tramp-handle-shell-command | 3782 (defun tramp-handle-shell-command |
3774 (command &optional output-buffer error-buffer) | 3783 (command &optional output-buffer error-buffer) |
3775 "Like `shell-command' for Tramp files." | 3784 "Like `shell-command' for Tramp files." |
3776 (let* ((asynchronous (string-match "[ \t]*&[ \t]*\\'" command)) | 3785 (let* ((asynchronous (string-match "[ \t]*&[ \t]*\\'" command)) |
3777 (args (split-string (substring command 0 asynchronous) " ")) | 3786 ;; We cannot use `shell-file-name' and `shell-command-switch', |
3787 ;; they are variables of the local host. | |
3788 (args (list "/bin/sh" "-c" (substring command 0 asynchronous))) | |
3778 (output-buffer | 3789 (output-buffer |
3779 (cond | 3790 (cond |
3780 ((bufferp output-buffer) output-buffer) | 3791 ((bufferp output-buffer) output-buffer) |
3781 ((stringp output-buffer) (get-buffer-create output-buffer)) | 3792 ((stringp output-buffer) (get-buffer-create output-buffer)) |
3782 (output-buffer (current-buffer)) | 3793 (output-buffer (current-buffer)) |
3783 (t (generate-new-buffer | 3794 (t (get-buffer-create |
3784 (if asynchronous | 3795 (if asynchronous |
3785 "*Async Shell Command*" | 3796 "*Async Shell Command*" |
3786 "*Shell Command Output*"))))) | 3797 "*Shell Command Output*"))))) |
3787 (error-buffer | 3798 (error-buffer |
3788 (cond | 3799 (cond |
3790 ((stringp error-buffer) (get-buffer-create error-buffer)))) | 3801 ((stringp error-buffer) (get-buffer-create error-buffer)))) |
3791 (buffer | 3802 (buffer |
3792 (if (and (not asynchronous) error-buffer) | 3803 (if (and (not asynchronous) error-buffer) |
3793 (with-parsed-tramp-file-name default-directory nil | 3804 (with-parsed-tramp-file-name default-directory nil |
3794 (list output-buffer (tramp-make-tramp-temp-file v))) | 3805 (list output-buffer (tramp-make-tramp-temp-file v))) |
3795 output-buffer))) | 3806 output-buffer)) |
3796 | 3807 (proc (get-buffer-process output-buffer))) |
3797 (prog1 | 3808 |
3798 ;; Run the process. | 3809 ;; Check whether there is another process running. Tramp does not |
3799 (if (integerp asynchronous) | 3810 ;; support 2 (asynchronous) processes in parallel. |
3811 (when proc | |
3812 (if (yes-or-no-p "A command is running. Kill it? ") | |
3813 (ignore-errors (kill-process proc)) | |
3814 (error "Shell command in progress"))) | |
3815 | |
3816 (with-current-buffer output-buffer | |
3817 (setq buffer-read-only nil | |
3818 buffer-undo-list t) | |
3819 (erase-buffer)) | |
3820 | |
3821 (if (integerp asynchronous) | |
3822 (prog1 | |
3823 ;; Run the process. | |
3800 (apply 'start-file-process "*Async Shell*" buffer args) | 3824 (apply 'start-file-process "*Async Shell*" buffer args) |
3801 (apply 'process-file (car args) nil buffer nil (cdr args))) | 3825 ;; Display output. |
3802 ;; Insert error messages if they were separated. | 3826 (pop-to-buffer output-buffer)) |
3803 (when (listp buffer) | 3827 |
3804 (with-current-buffer error-buffer (insert-file-contents (cadr buffer))) | 3828 (prog1 |
3805 (delete-file (cadr buffer))) | 3829 ;; Run the process. |
3806 ;; There's some output, display it. | 3830 (apply 'process-file (car args) nil buffer nil (cdr args)) |
3807 (when (with-current-buffer output-buffer (> (point-max) (point-min))) | 3831 ;; Insert error messages if they were separated. |
3808 (if (functionp 'display-message-or-buffer) | 3832 (when (listp buffer) |
3809 (funcall (symbol-function 'display-message-or-buffer) output-buffer) | 3833 (with-current-buffer error-buffer |
3810 (pop-to-buffer output-buffer)))))) | 3834 (insert-file-contents (cadr buffer))) |
3835 (delete-file (cadr buffer))) | |
3836 ;; There's some output, display it. | |
3837 (when (with-current-buffer output-buffer (> (point-max) (point-min))) | |
3838 (if (functionp 'display-message-or-buffer) | |
3839 (funcall (symbol-function 'display-message-or-buffer) | |
3840 output-buffer) | |
3841 (pop-to-buffer output-buffer))))))) | |
3811 | 3842 |
3812 ;; File Editing. | 3843 ;; File Editing. |
3813 | 3844 |
3814 (defvar tramp-handle-file-local-copy-hook nil | 3845 (defvar tramp-handle-file-local-copy-hook nil |
3815 "Normal hook to be run at the end of `tramp-handle-file-local-copy'.") | 3846 "Normal hook to be run at the end of `tramp-handle-file-local-copy'.") |
5358 (let ((tramp-end-of-output "$ ")) | 5389 (let ((tramp-end-of-output "$ ")) |
5359 (tramp-send-command | 5390 (tramp-send-command |
5360 vec | 5391 vec |
5361 (format "PROMPT_COMMAND='' PS1='$ ' PS2='' PS3='' exec %s" shell) | 5392 (format "PROMPT_COMMAND='' PS1='$ ' PS2='' PS3='' exec %s" shell) |
5362 t)) | 5393 t)) |
5394 ;; Setting prompts. | |
5363 (tramp-message vec 5 "Setting remote shell prompt...") | 5395 (tramp-message vec 5 "Setting remote shell prompt...") |
5364 ;; Douglas Gray Stephens <DGrayStephens@slb.com> says that we | 5396 (tramp-send-command vec (format "PS1='%s'" tramp-end-of-output) t) |
5365 ;; must use "\n" here, not tramp-rsh-end-of-line. Kai left the | |
5366 ;; last tramp-rsh-end-of-line, Douglas wanted to replace that, | |
5367 ;; as well. | |
5368 (tramp-send-command | |
5369 vec | |
5370 (format "PS1='%s%s%s'" | |
5371 tramp-rsh-end-of-line | |
5372 tramp-end-of-output | |
5373 tramp-rsh-end-of-line) | |
5374 t) | |
5375 (tramp-send-command vec "PS2=''" t) | 5397 (tramp-send-command vec "PS2=''" t) |
5376 (tramp-send-command vec "PS3=''" t) | 5398 (tramp-send-command vec "PS3=''" t) |
5377 (tramp-send-command vec "PROMPT_COMMAND=''" t) | 5399 (tramp-send-command vec "PROMPT_COMMAND=''" t) |
5378 (tramp-message vec 5 "Setting remote shell prompt...done")) | 5400 (tramp-message vec 5 "Setting remote shell prompt...done")) |
5401 | |
5379 (t (tramp-message | 5402 (t (tramp-message |
5380 vec 5 "Remote `%s' groks tilde expansion, good" | 5403 vec 5 "Remote `%s' groks tilde expansion, good" |
5381 (tramp-get-method-parameter | 5404 (tramp-get-method-parameter |
5382 (tramp-file-name-method vec) 'tramp-remote-sh)) | 5405 (tramp-file-name-method vec) 'tramp-remote-sh)) |
5383 (tramp-set-connection-property | 5406 (tramp-set-connection-property |
5666 | 5689 |
5667 (tramp-message vec 5 "Setting shell prompt") | 5690 (tramp-message vec 5 "Setting shell prompt") |
5668 ;; We can set $PS1 to `tramp-end-of-output' only when the echo has | 5691 ;; We can set $PS1 to `tramp-end-of-output' only when the echo has |
5669 ;; been disabled. Otherwise, the echo of the command would be | 5692 ;; been disabled. Otherwise, the echo of the command would be |
5670 ;; regarded as prompt already. | 5693 ;; regarded as prompt already. |
5671 (tramp-send-command | 5694 (tramp-send-command vec (format "PS1='%s'" tramp-end-of-output) t) |
5672 vec | |
5673 (format "PS1='%s%s%s'" | |
5674 tramp-rsh-end-of-line | |
5675 tramp-end-of-output | |
5676 tramp-rsh-end-of-line) | |
5677 t) | |
5678 (tramp-send-command vec "PS2=''" t) | 5695 (tramp-send-command vec "PS2=''" t) |
5679 (tramp-send-command vec "PS3=''" t) | 5696 (tramp-send-command vec "PS3=''" t) |
5680 (tramp-send-command vec "PROMPT_COMMAND=''" t) | 5697 (tramp-send-command vec "PROMPT_COMMAND=''" t) |
5681 | 5698 |
5682 ;; Try to set up the coding system correctly. | 5699 ;; Try to set up the coding system correctly. |
6057 (tramp-error | 6074 (tramp-error |
6058 vec 'file-error | 6075 vec 'file-error |
6059 "Method `%s' is not supported for multi-hops." | 6076 "Method `%s' is not supported for multi-hops." |
6060 (tramp-file-name-method item))))) | 6077 (tramp-file-name-method item))))) |
6061 | 6078 |
6079 ;; In case the host name is not used for the remote shell | |
6080 ;; command, the user could be misguided by applying a random | |
6081 ;; hostname. | |
6082 (let* ((v (car target-alist)) | |
6083 (method (tramp-file-name-method v)) | |
6084 (host (tramp-file-name-host v))) | |
6085 (unless | |
6086 (or | |
6087 ;; There are multi-hops. | |
6088 (cdr target-alist) | |
6089 ;; The host name is used for the remote shell command. | |
6090 (member | |
6091 '("%h") (tramp-get-method-parameter method 'tramp-login-args)) | |
6092 ;; The host is local. We cannot use `tramp-local-host-p' | |
6093 ;; here, because it opens a connection as well. | |
6094 (string-match | |
6095 (concat "^" (regexp-opt (list "localhost" (system-name)) t) "$") | |
6096 host)) | |
6097 (tramp-error | |
6098 v 'file-error | |
6099 "Host `%s' looks like a remote host, `%s' can only use the local host" | |
6100 host method))) | |
6101 | |
6062 ;; Result. | 6102 ;; Result. |
6063 target-alist)) | 6103 target-alist)) |
6064 | 6104 |
6065 (defun tramp-maybe-open-connection (vec) | 6105 (defun tramp-maybe-open-connection (vec) |
6066 "Maybe open a connection VEC. | 6106 "Maybe open a connection VEC. |
6247 (defun tramp-wait-for-output (proc &optional timeout) | 6287 (defun tramp-wait-for-output (proc &optional timeout) |
6248 "Wait for output from remote rsh command." | 6288 "Wait for output from remote rsh command." |
6249 (with-current-buffer (process-buffer proc) | 6289 (with-current-buffer (process-buffer proc) |
6250 ;; Initially, `tramp-end-of-output' is "$ ". There might be | 6290 ;; Initially, `tramp-end-of-output' is "$ ". There might be |
6251 ;; leading escape sequences, which must be ignored. | 6291 ;; leading escape sequences, which must be ignored. |
6252 (let* ((regexp (format "^[^$\n]*%s\r?$" (regexp-quote tramp-end-of-output))) | 6292 (let* ((regexp |
6293 (if (string-match (regexp-quote "\n") tramp-end-of-output) | |
6294 (mapconcat | |
6295 'identity (split-string tramp-end-of-output "\n") "\r?\n") | |
6296 (format "^[^$\n]*%s\r?$" (regexp-quote tramp-end-of-output)))) | |
6253 (found (tramp-wait-for-regexp proc timeout regexp))) | 6297 (found (tramp-wait-for-regexp proc timeout regexp))) |
6254 (if found | 6298 (if found |
6255 (let (buffer-read-only) | 6299 (let (buffer-read-only) |
6256 (goto-char (point-max)) | 6300 (goto-char (point-max)) |
6257 (re-search-backward regexp nil t) | 6301 (re-search-backward regexp nil t) |
6664 (unless match (error "Not a Tramp file name: %s" name)) | 6708 (unless match (error "Not a Tramp file name: %s" name)) |
6665 (let ((method (match-string (nth 1 tramp-file-name-structure) name)) | 6709 (let ((method (match-string (nth 1 tramp-file-name-structure) name)) |
6666 (user (match-string (nth 2 tramp-file-name-structure) name)) | 6710 (user (match-string (nth 2 tramp-file-name-structure) name)) |
6667 (host (match-string (nth 3 tramp-file-name-structure) name)) | 6711 (host (match-string (nth 3 tramp-file-name-structure) name)) |
6668 (localname (match-string (nth 4 tramp-file-name-structure) name))) | 6712 (localname (match-string (nth 4 tramp-file-name-structure) name))) |
6713 (when (member method '("multi" "multiu")) | |
6714 (error | |
6715 "`%s' method is no longer supported, see (info \"(tramp)Multi-hops\")" | |
6716 method)) | |
6669 (if nodefault | 6717 (if nodefault |
6670 (vector method user host localname) | 6718 (vector method user host localname) |
6671 (vector | 6719 (vector |
6672 (tramp-find-method method user host) | 6720 (tramp-find-method method user host) |
6673 (tramp-find-user method user host) | 6721 (tramp-find-user method user host) |
6729 "Return t if this is an out-of-band method, nil otherwise." | 6777 "Return t if this is an out-of-band method, nil otherwise." |
6730 (tramp-get-method-parameter (tramp-file-name-method vec) 'tramp-copy-program)) | 6778 (tramp-get-method-parameter (tramp-file-name-method vec) 'tramp-copy-program)) |
6731 | 6779 |
6732 (defun tramp-local-host-p (vec) | 6780 (defun tramp-local-host-p (vec) |
6733 "Return t if this points to the local host, nil otherwise." | 6781 "Return t if this points to the local host, nil otherwise." |
6734 (let ((host (tramp-file-name-real-host vec))) | 6782 ;; We cannot use `tramp-file-name-real-host'. A port is an |
6783 ;; indication for an ssh tunnel or alike. | |
6784 (let ((host (tramp-file-name-host vec))) | |
6735 (and | 6785 (and |
6736 (stringp host) | 6786 (stringp host) |
6737 (string-match | 6787 (string-match |
6738 (concat "^" (regexp-opt (list "localhost" (system-name)) t) "$") host)))) | 6788 (concat "^" (regexp-opt (list "localhost" (system-name)) t) "$") host) |
6789 ;; The local temp directory must be writable for the other user. | |
6790 (file-writable-p | |
6791 (tramp-make-tramp-file-name | |
6792 (tramp-file-name-method vec) | |
6793 (tramp-file-name-user vec) | |
6794 host | |
6795 (tramp-compat-temporary-file-directory)))))) | |
6739 | 6796 |
6740 ;; Variables local to connection. | 6797 ;; Variables local to connection. |
6741 | 6798 |
6742 (defun tramp-get-remote-path (vec) | 6799 (defun tramp-get-remote-path (vec) |
6743 (with-connection-property vec "remote-path" | 6800 (with-connection-property vec "remote-path" |
6829 (progn | 6886 (progn |
6830 (tramp-send-command | 6887 (tramp-send-command |
6831 vec (format "( %s / -nt / )" (tramp-get-test-command vec))) | 6888 vec (format "( %s / -nt / )" (tramp-get-test-command vec))) |
6832 (with-current-buffer (tramp-get-buffer vec) | 6889 (with-current-buffer (tramp-get-buffer vec) |
6833 (goto-char (point-min)) | 6890 (goto-char (point-min)) |
6834 (when (looking-at | 6891 (when (looking-at (regexp-quote tramp-end-of-output)) |
6835 (format "\n%s\r?\n" (regexp-quote tramp-end-of-output))) | |
6836 (format "%s %%s -nt %%s" (tramp-get-test-command vec))))) | 6892 (format "%s %%s -nt %%s" (tramp-get-test-command vec))))) |
6837 (progn | 6893 (progn |
6838 (tramp-send-command | 6894 (tramp-send-command |
6839 vec | 6895 vec |
6840 (format | 6896 (format |