comparison lisp/net/tramp.el @ 89956:b9eee0a7bef5

Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-25 Merge from emacs--cvs-trunk--0 Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-459 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-463 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-464 Update from CVS: lisp/progmodes/make-mode.el: Fix comments. * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-465 Update from CVS
author Miles Bader <miles@gnu.org>
date Fri, 23 Jul 2004 04:30:44 +0000
parents 97905c4f1a42 6b42a91e3595
children d8411455de48
comparison
equal deleted inserted replaced
89955:7f8b53f94713 89956:b9eee0a7bef5
914 (defcustom tramp-process-alive-regexp 914 (defcustom tramp-process-alive-regexp
915 "" 915 ""
916 "Regular expression indicating a process has finished. 916 "Regular expression indicating a process has finished.
917 In fact this expression is empty by intention, it will be used only to 917 In fact this expression is empty by intention, it will be used only to
918 check regularly the status of the associated process. 918 check regularly the status of the associated process.
919 The answer will be provided by `tramp-action-process-alive' and 919 The answer will be provided by `tramp-action-process-alive',
920 `tramp-action-out-of-band', which see." 920 `tramp-multi-action-process-alive' and`tramp-action-out-of-band', which see."
921 :group 'tramp 921 :group 'tramp
922 :type 'regexp) 922 :type 'regexp)
923 923
924 (defcustom tramp-temp-name-prefix "tramp." 924 (defcustom tramp-temp-name-prefix "tramp."
925 "*Prefix to use for temporary files. 925 "*Prefix to use for temporary files.
1319 '((tramp-password-prompt-regexp tramp-multi-action-password) 1319 '((tramp-password-prompt-regexp tramp-multi-action-password)
1320 (tramp-login-prompt-regexp tramp-multi-action-login) 1320 (tramp-login-prompt-regexp tramp-multi-action-login)
1321 (shell-prompt-pattern tramp-multi-action-succeed) 1321 (shell-prompt-pattern tramp-multi-action-succeed)
1322 (tramp-shell-prompt-pattern tramp-multi-action-succeed) 1322 (tramp-shell-prompt-pattern tramp-multi-action-succeed)
1323 (tramp-wrong-passwd-regexp tramp-multi-action-permission-denied) 1323 (tramp-wrong-passwd-regexp tramp-multi-action-permission-denied)
1324 (tramp-process-alive-regexp tramp-action-process-alive)) 1324 (tramp-process-alive-regexp tramp-multi-action-process-alive))
1325 "List of pattern/action pairs. 1325 "List of pattern/action pairs.
1326 This list is used for each hop in multi-hop connections. 1326 This list is used for each hop in multi-hop connections.
1327 See `tramp-actions-before-shell' for more info." 1327 See `tramp-actions-before-shell' for more info."
1328 :group 'tramp 1328 :group 'tramp
1329 :type '(repeat (list variable function))) 1329 :type '(repeat (list variable function)))
2163 (defun tramp-handle-file-attributes (filename &optional id-format) 2163 (defun tramp-handle-file-attributes (filename &optional id-format)
2164 "Like `file-attributes' for tramp files." 2164 "Like `file-attributes' for tramp files."
2165 (let ((nonnumeric (and id-format (equal id-format 'string))) 2165 (let ((nonnumeric (and id-format (equal id-format 'string)))
2166 result) 2166 result)
2167 (with-parsed-tramp-file-name filename nil 2167 (with-parsed-tramp-file-name filename nil
2168 (when (tramp-handle-file-exists-p filename) 2168 (when (file-exists-p filename)
2169 ;; file exists, find out stuff 2169 ;; file exists, find out stuff
2170 (save-excursion 2170 (save-excursion
2171 (if (tramp-get-remote-perl multi-method method user host) 2171 (if (tramp-get-remote-perl multi-method method user host)
2172 (setq result 2172 (setq result
2173 (tramp-handle-file-attributes-with-perl 2173 (tramp-handle-file-attributes-with-perl
2329 ;; CCC continue here 2329 ;; CCC continue here
2330 2330
2331 ;; This function makes the same assumption as 2331 ;; This function makes the same assumption as
2332 ;; `tramp-handle-set-visited-file-modtime'. 2332 ;; `tramp-handle-set-visited-file-modtime'.
2333 (defun tramp-handle-verify-visited-file-modtime (buf) 2333 (defun tramp-handle-verify-visited-file-modtime (buf)
2334 "Like `verify-visited-file-modtime' for tramp files." 2334 "Like `verify-visited-file-modtime' for tramp files.
2335 At the time `verify-visited-file-modtime' calls this function, we
2336 already know that the buffer is visiting a file and that
2337 `visited-file-modtime' does not return 0. Do not call this
2338 function directly, unless those two cases are already taken care
2339 of."
2335 (with-current-buffer buf 2340 (with-current-buffer buf
2336 (let ((f (buffer-file-name))) 2341 (let ((f (buffer-file-name)))
2337 (with-parsed-tramp-file-name f nil 2342 (with-parsed-tramp-file-name f nil
2338 (let* ((attr (file-attributes f)) 2343 (let* ((attr (file-attributes f))
2339 (modtime (nth 5 attr))) 2344 (modtime (nth 5 attr)))
2507 x))))) 2512 x)))))
2508 2513
2509 (defun tramp-handle-file-writable-p (filename) 2514 (defun tramp-handle-file-writable-p (filename)
2510 "Like `file-writable-p' for tramp files." 2515 "Like `file-writable-p' for tramp files."
2511 (with-parsed-tramp-file-name filename nil 2516 (with-parsed-tramp-file-name filename nil
2512 (if (tramp-handle-file-exists-p filename) 2517 (if (file-exists-p filename)
2513 ;; Existing files must be writable. 2518 ;; Existing files must be writable.
2514 (zerop (tramp-run-test "-w" filename)) 2519 (zerop (tramp-run-test "-w" filename))
2515 ;; If file doesn't exist, check if directory is writable. 2520 ;; If file doesn't exist, check if directory is writable.
2516 (and (zerop (tramp-run-test 2521 (and (zerop (tramp-run-test
2517 "-d" (tramp-handle-file-name-directory filename))) 2522 "-d" (file-name-directory filename)))
2518 (zerop (tramp-run-test 2523 (zerop (tramp-run-test
2519 "-w" (tramp-handle-file-name-directory filename))))))) 2524 "-w" (file-name-directory filename)))))))
2520 2525
2521 (defun tramp-handle-file-ownership-preserved-p (filename) 2526 (defun tramp-handle-file-ownership-preserved-p (filename)
2522 "Like `file-ownership-preserved-p' for tramp files." 2527 "Like `file-ownership-preserved-p' for tramp files."
2523 (with-parsed-tramp-file-name filename nil 2528 (with-parsed-tramp-file-name filename nil
2524 (or (not (tramp-handle-file-exists-p filename)) 2529 (or (not (file-exists-p filename))
2525 ;; Existing files must be writable. 2530 ;; Existing files must be writable.
2526 (zerop (tramp-run-test "-O" filename))))) 2531 (zerop (tramp-run-test "-O" filename)))))
2527 2532
2528 ;; Other file name ops. 2533 ;; Other file name ops.
2529 2534
3062 "Recursively delete the directory given. 3067 "Recursively delete the directory given.
3063 This is like `dired-recursive-delete-directory' for tramp files." 3068 This is like `dired-recursive-delete-directory' for tramp files."
3064 (with-parsed-tramp-file-name filename nil 3069 (with-parsed-tramp-file-name filename nil
3065 ;; run a shell command 'rm -r <localname>' 3070 ;; run a shell command 'rm -r <localname>'
3066 ;; Code shamelessly stolen for the dired implementation and, um, hacked :) 3071 ;; Code shamelessly stolen for the dired implementation and, um, hacked :)
3067 (or (tramp-handle-file-exists-p filename) 3072 (or (file-exists-p filename)
3068 (signal 3073 (signal
3069 'file-error 3074 'file-error
3070 (list "Removing old file name" "no such directory" filename))) 3075 (list "Removing old file name" "no such directory" filename)))
3071 ;; Which is better, -r or -R? (-r works for me <daniel@danann.net>) 3076 ;; Which is better, -r or -R? (-r works for me <daniel@danann.net>)
3072 (tramp-send-command multi-method method user host 3077 (tramp-send-command multi-method method user host
3073 (format "rm -r %s" (tramp-shell-quote-argument localname))) 3078 (format "rm -r %s" (tramp-shell-quote-argument localname)))
3074 ;; Wait for the remote system to return to us... 3079 ;; Wait for the remote system to return to us...
3075 ;; This might take a while, allow it plenty of time. 3080 ;; This might take a while, allow it plenty of time.
3076 (tramp-wait-for-output 120) 3081 (tramp-wait-for-output 120)
3077 ;; Make sure that it worked... 3082 ;; Make sure that it worked...
3078 (and (tramp-handle-file-exists-p filename) 3083 (and (file-exists-p filename)
3079 (error "Failed to recusively delete %s" filename)))) 3084 (error "Failed to recusively delete %s" filename))))
3080 3085
3081 (defun tramp-handle-dired-call-process (program discard &rest arguments) 3086 (defun tramp-handle-dired-call-process (program discard &rest arguments)
3082 "Like `dired-call-process' for tramp files." 3087 "Like `dired-call-process' for tramp files."
3083 (with-parsed-tramp-file-name default-directory nil 3088 (with-parsed-tramp-file-name default-directory nil
3605 (second result)))))) 3610 (second result))))))
3606 3611
3607 3612
3608 (defun tramp-handle-find-backup-file-name (filename) 3613 (defun tramp-handle-find-backup-file-name (filename)
3609 "Like `find-backup-file-name' for tramp files." 3614 "Like `find-backup-file-name' for tramp files."
3610 3615 (with-parsed-tramp-file-name filename nil
3611 (if (or (and (not (featurep 'xemacs)) 3616 ;; We set both variables. It doesn't matter whether it is
3612 (not (boundp 'tramp-backup-directory-alist))) 3617 ;; Emacs or XEmacs
3613 (and (featurep 'xemacs) 3618 (let ((backup-directory-alist
3614 (not (boundp 'tramp-bkup-backup-directory-info)))) 3619 ;; Emacs case
3615 3620 (when (boundp 'backup-directory-alist)
3616 ;; No tramp backup directory alist defined, or nil 3621 (if (boundp 'tramp-backup-directory-alist)
3617 (tramp-run-real-handler 'find-backup-file-name (list filename)) 3622 (mapcar
3618 3623 '(lambda (x)
3619 (with-parsed-tramp-file-name filename nil 3624 (cons
3620 (let* ((backup-var 3625 (car x)
3621 (copy-tree 3626 (if (and (stringp (cdr x))
3622 (if (featurep 'xemacs) 3627 (file-name-absolute-p (cdr x))
3623 ;; XEmacs case 3628 (not (tramp-file-name-p (cdr x))))
3624 (symbol-value 'tramp-bkup-backup-directory-info) 3629 (tramp-make-tramp-file-name
3625 ;; Emacs case 3630 multi-method method user host (cdr x))
3626 (symbol-value 'tramp-backup-directory-alist)))) 3631 (cdr x))))
3627 3632 (symbol-value 'tramp-backup-directory-alist))
3628 ;; We set both variables. It doesn't matter whether it is 3633 (symbol-value 'backup-directory-alist))))
3629 ;; Emacs or XEmacs 3634
3630 (backup-directory-alist backup-var) 3635 (bkup-backup-directory-info
3631 (bkup-backup-directory-info backup-var)) 3636 ;; XEmacs case
3632 3637 (when (boundp 'bkup-backup-directory-info)
3633 (mapcar 3638 (if (boundp 'tramp-bkup-backup-directory-info)
3634 '(lambda (x) 3639 (mapcar
3635 (let ((dir (if (consp (cdr x)) (car (cdr x)) (cdr x)))) 3640 '(lambda (x)
3636 (when (and (stringp dir) 3641 (nconc
3637 (file-name-absolute-p dir) 3642 (list (car x))
3638 (not (tramp-file-name-p dir))) 3643 (list
3639 ;; Prepend absolute directory names with tramp prefix 3644 (if (and (stringp (car (cdr x)))
3640 (if (consp (cdr x)) 3645 (file-name-absolute-p (car (cdr x)))
3641 (setcar (cdr x) 3646 (not (tramp-file-name-p (car (cdr x)))))
3642 (tramp-make-tramp-file-name 3647 (tramp-make-tramp-file-name
3643 multi-method method user host dir)) 3648 multi-method method user host (car (cdr x)))
3644 (setcdr x (tramp-make-tramp-file-name 3649 (car (cdr x))))
3645 multi-method method user host dir)))))) 3650 (cdr (cdr x))))
3646 backup-var) 3651 (symbol-value 'tramp-bkup-backup-directory-info))
3647 3652 (symbol-value 'bkup-backup-directory-info)))))
3648 (tramp-run-real-handler 'find-backup-file-name (list filename)))))) 3653
3654 (tramp-run-real-handler 'find-backup-file-name (list filename)))))
3655
3649 3656
3650 ;; CCC grok APPEND, LOCKNAME, CONFIRM 3657 ;; CCC grok APPEND, LOCKNAME, CONFIRM
3651 (defun tramp-handle-write-region 3658 (defun tramp-handle-write-region
3652 (start end filename &optional append visit lockname confirm) 3659 (start end filename &optional append visit lockname confirm)
3653 "Like `write-region' for tramp files." 3660 "Like `write-region' for tramp files."
3687 tmpfil) 3694 tmpfil)
3688 ;; Write region into a tmp file. This isn't really needed if we 3695 ;; Write region into a tmp file. This isn't really needed if we
3689 ;; use an encoding function, but currently we use it always 3696 ;; use an encoding function, but currently we use it always
3690 ;; because this makes the logic simpler. 3697 ;; because this makes the logic simpler.
3691 (setq tmpfil (tramp-make-temp-file)) 3698 (setq tmpfil (tramp-make-temp-file))
3699 ;; Set current buffer. If connection wasn't open, `file-modes' has
3700 ;; changed it accidently.
3701 (set-buffer curbuf)
3692 ;; We say `no-message' here because we don't want the visited file 3702 ;; We say `no-message' here because we don't want the visited file
3693 ;; modtime data to be clobbered from the temp file. We call 3703 ;; modtime data to be clobbered from the temp file. We call
3694 ;; `set-visited-file-modtime' ourselves later on. 3704 ;; `set-visited-file-modtime' ourselves later on.
3695 (tramp-run-real-handler 3705 (tramp-run-real-handler
3696 'write-region 3706 'write-region
3970 (foreign (tramp-find-foreign-file-name-handler filename))) 3980 (foreign (tramp-find-foreign-file-name-handler filename)))
3971 (cond 3981 (cond
3972 (foreign (apply foreign operation args)) 3982 (foreign (apply foreign operation args))
3973 (t (tramp-run-real-handler operation args)))))) 3983 (t (tramp-run-real-handler operation args))))))
3974 3984
3985
3986 ;; In Emacs, there is some concurrency due to timers. If a timer
3987 ;; interrupts Tramp and wishes to use the same connection buffer as
3988 ;; the "main" Emacs, then garbage might occur in the connection
3989 ;; buffer. Therefore, we need to make sure that a timer does not use
3990 ;; the same connection buffer as the "main" Emacs. We implement a
3991 ;; cheap global lock, instead of locking each connection buffer
3992 ;; separately. The global lock is based on two variables,
3993 ;; `tramp-locked' and `tramp-locker'. `tramp-locked' is set to true
3994 ;; (with setq) to indicate a lock. But Tramp also calls itself during
3995 ;; processing of a single file operation, so we need to allow
3996 ;; recursive calls. That's where the `tramp-locker' variable comes in
3997 ;; -- it is let-bound to t during the execution of the current
3998 ;; handler. So if `tramp-locked' is t and `tramp-locker' is also t,
3999 ;; then we should just proceed because we have been called
4000 ;; recursively. But if `tramp-locker' is nil, then we are a timer
4001 ;; interrupting the "main" Emacs, and then we signal an error.
4002
4003 (defvar tramp-locked nil
4004 "If non-nil, then Tramp is currently busy.
4005 Together with `tramp-locker', this implements a locking mechanism
4006 preventing reentrant calls of Tramp.")
4007
4008 (defvar tramp-locker nil
4009 "If non-nil, then a caller has locked Tramp.
4010 Together with `tramp-locked', this implements a locking mechanism
4011 preventing reentrant calls of Tramp.")
4012
3975 (defun tramp-sh-file-name-handler (operation &rest args) 4013 (defun tramp-sh-file-name-handler (operation &rest args)
3976 "Invoke remote-shell Tramp file name handler. 4014 "Invoke remote-shell Tramp file name handler.
3977 Fall back to normal file name handler if no Tramp handler exists." 4015 Fall back to normal file name handler if no Tramp handler exists."
3978 (save-match-data 4016 (when (and tramp-locked (not tramp-locker))
3979 (let ((fn (assoc operation tramp-file-name-handler-alist))) 4017 (signal 'file-error "Forbidden reentrant call of Tramp"))
3980 (if fn 4018 (let ((tl tramp-locked))
3981 (apply (cdr fn) args) 4019 (unwind-protect
3982 (tramp-run-real-handler operation args))))) 4020 (progn
4021 (setq tramp-locked t)
4022 (let ((tramp-locker t))
4023 (save-match-data
4024 (let ((fn (assoc operation tramp-file-name-handler-alist)))
4025 (if fn
4026 (apply (cdr fn) args)
4027 (tramp-run-real-handler operation args))))))
4028 (setq tramp-locked tl))))
3983 4029
3984 ;;;###autoload 4030 ;;;###autoload
3985 (defun tramp-completion-file-name-handler (operation &rest args) 4031 (defun tramp-completion-file-name-handler (operation &rest args)
3986 "Invoke tramp file name completion handler. 4032 "Invoke tramp file name completion handler.
3987 Falls back to normal file name handler if no tramp file name handler exists." 4033 Falls back to normal file name handler if no tramp file name handler exists."
4060 (mapcar 4106 (mapcar
4061 (function (lambda (x) 4107 (function (lambda (x)
4062 (tramp-make-tramp-file-name multi-method method 4108 (tramp-make-tramp-file-name multi-method method
4063 user host x))) 4109 user host x)))
4064 (read (current-buffer)))))) 4110 (read (current-buffer))))))
4065 (list (tramp-handle-expand-file-name name)))))) 4111 (list (expand-file-name name))))))
4066 4112
4067 ;; Check for complete.el and override PC-expand-many-files if appropriate. 4113 ;; Check for complete.el and override PC-expand-many-files if appropriate.
4068 (eval-and-compile 4114 (eval-and-compile
4069 (defun tramp-save-PC-expand-many-files (name))); avoid compiler warning 4115 (defun tramp-save-PC-expand-many-files (name))); avoid compiler warning
4070 4116
4071 (defun tramp-setup-complete () 4117 (defun tramp-setup-complete ()
4072 (fset 'tramp-save-PC-expand-many-files 4118 (fset 'tramp-save-PC-expand-many-files
4073 (symbol-function 'PC-expand-many-files)) 4119 (symbol-function 'PC-expand-many-files))
4074 (defun PC-expand-many-files (name) 4120 (defun PC-expand-many-files (name)
4075 (if (tramp-tramp-file-p name) 4121 (if (tramp-tramp-file-p name)
4076 (tramp-handle-expand-many-files name) 4122 (expand-many-files name)
4077 (tramp-save-PC-expand-many-files name)))) 4123 (tramp-save-PC-expand-many-files name))))
4078 4124
4079 ;; Why isn't eval-after-load sufficient? 4125 ;; Why isn't eval-after-load sufficient?
4080 (if (fboundp 'PC-expand-many-files) 4126 (if (fboundp 'PC-expand-many-files)
4081 (tramp-setup-complete) 4127 (tramp-setup-complete)
4822 ;; is sometimes `/bin/test' and sometimes it's 4868 ;; is sometimes `/bin/test' and sometimes it's
4823 ;; `/usr/bin/test'. 4869 ;; `/usr/bin/test'.
4824 ;; `/usr/bin/test -e' In case `/bin/test' does not exist. 4870 ;; `/usr/bin/test -e' In case `/bin/test' does not exist.
4825 (unless (or 4871 (unless (or
4826 (and (setq tramp-file-exists-command "test -e %s") 4872 (and (setq tramp-file-exists-command "test -e %s")
4827 (tramp-handle-file-exists-p existing) 4873 (file-exists-p existing)
4828 (not (tramp-handle-file-exists-p nonexisting))) 4874 (not (file-exists-p nonexisting)))
4829 (and (setq tramp-file-exists-command "/bin/test -e %s") 4875 (and (setq tramp-file-exists-command "/bin/test -e %s")
4830 (tramp-handle-file-exists-p existing) 4876 (file-exists-p existing)
4831 (not (tramp-handle-file-exists-p nonexisting))) 4877 (not (file-exists-p nonexisting)))
4832 (and (setq tramp-file-exists-command "/usr/bin/test -e %s") 4878 (and (setq tramp-file-exists-command "/usr/bin/test -e %s")
4833 (tramp-handle-file-exists-p existing) 4879 (file-exists-p existing)
4834 (not (tramp-handle-file-exists-p nonexisting))) 4880 (not (file-exists-p nonexisting)))
4835 (and (setq tramp-file-exists-command "ls -d %s") 4881 (and (setq tramp-file-exists-command "ls -d %s")
4836 (tramp-handle-file-exists-p existing) 4882 (file-exists-p existing)
4837 (not (tramp-handle-file-exists-p nonexisting)))) 4883 (not (file-exists-p nonexisting))))
4838 (error "Couldn't find command to check if file exists.")))) 4884 (error "Couldn't find command to check if file exists."))))
4839 4885
4840 4886
4841 ;; CCC test ksh or bash found for tilde expansion? 4887 ;; CCC test ksh or bash found for tilde expansion?
4842 (defun tramp-find-shell (multi-method method user host) 4888 (defun tramp-find-shell (multi-method method user host)
4894 (defun tramp-check-ls-command (multi-method method user host cmd) 4940 (defun tramp-check-ls-command (multi-method method user host cmd)
4895 "Checks whether the given `ls' executable groks `-n'. 4941 "Checks whether the given `ls' executable groks `-n'.
4896 METHOD, USER and HOST specify the connection, CMD (the absolute file name of) 4942 METHOD, USER and HOST specify the connection, CMD (the absolute file name of)
4897 the `ls' executable. Returns t if CMD supports the `-n' option, nil 4943 the `ls' executable. Returns t if CMD supports the `-n' option, nil
4898 otherwise." 4944 otherwise."
4899 (tramp-message 9 "Checking remote `%s' command for `-n' option" 4945 (tramp-message 9 "Checking remote `%s' command for `-n' option" cmd)
4900 cmd) 4946 (when (file-executable-p
4901 (when (tramp-handle-file-executable-p
4902 (tramp-make-tramp-file-name multi-method method user host cmd)) 4947 (tramp-make-tramp-file-name multi-method method user host cmd))
4903 (let ((result nil)) 4948 (let ((result nil))
4904 (tramp-message 7 "Testing remote command `%s' for -n..." cmd) 4949 (tramp-message 7 "Testing remote command `%s' for -n..." cmd)
4905 (setq result 4950 (setq result
4906 (tramp-send-command-and-check 4951 (tramp-send-command-and-check
4954 4999
4955 (defun tramp-action-password (p multi-method method user host) 5000 (defun tramp-action-password (p multi-method method user host)
4956 "Query the user for a password." 5001 "Query the user for a password."
4957 (let ((pw-prompt (match-string 0))) 5002 (let ((pw-prompt (match-string 0)))
4958 (tramp-message 9 "Sending password") 5003 (tramp-message 9 "Sending password")
4959 (tramp-enter-password p pw-prompt))) 5004 (tramp-enter-password p pw-prompt user host)))
4960 5005
4961 (defun tramp-action-succeed (p multi-method method user host) 5006 (defun tramp-action-succeed (p multi-method method user host)
4962 "Signal success in finding shell prompt." 5007 "Signal success in finding shell prompt."
4963 (tramp-message 9 "Found remote shell prompt.") 5008 (tramp-message 9 "Found remote shell prompt.")
4964 (erase-buffer) 5009 (erase-buffer)
5032 (process-send-string p (concat user tramp-rsh-end-of-line))) 5077 (process-send-string p (concat user tramp-rsh-end-of-line)))
5033 5078
5034 (defun tramp-multi-action-password (p method user host) 5079 (defun tramp-multi-action-password (p method user host)
5035 "Query the user for a password." 5080 "Query the user for a password."
5036 (tramp-message 9 "Sending password") 5081 (tramp-message 9 "Sending password")
5037 (tramp-enter-password p (match-string 0))) 5082 (tramp-enter-password p (match-string 0) user host))
5038 5083
5039 (defun tramp-multi-action-succeed (p method user host) 5084 (defun tramp-multi-action-succeed (p method user host)
5040 "Signal success in finding shell prompt." 5085 "Signal success in finding shell prompt."
5041 (tramp-message 9 "Found shell prompt on `%s'" host) 5086 (tramp-message 9 "Found shell prompt on `%s'" host)
5042 (erase-buffer) 5087 (erase-buffer)
5046 "Signal permission denied." 5091 "Signal permission denied."
5047 (tramp-message 9 "Permission denied by remote host `%s'" host) 5092 (tramp-message 9 "Permission denied by remote host `%s'" host)
5048 (kill-process p) 5093 (kill-process p)
5049 (erase-buffer) 5094 (erase-buffer)
5050 (throw 'tramp-action 'permission-denied)) 5095 (throw 'tramp-action 'permission-denied))
5096
5097 (defun tramp-multi-action-process-alive (p method user host)
5098 "Check whether a process has finished."
5099 (unless (memq (process-status p) '(run open))
5100 (throw 'tramp-action 'process-died)))
5051 5101
5052 ;; Functions for processing the actions. 5102 ;; Functions for processing the actions.
5053 5103
5054 (defun tramp-process-one-action (p multi-method method user host actions) 5104 (defun tramp-process-one-action (p multi-method method user host actions)
5055 "Wait for output from the shell and perform one action." 5105 "Wait for output from the shell and perform one action."
5244 (tramp-find-method multi-method method user host) 5294 (tramp-find-method multi-method method user host)
5245 user host 'tramp-login-program)) 5295 user host 'tramp-login-program))
5246 (login-args (tramp-get-method-parameter 5296 (login-args (tramp-get-method-parameter
5247 multi-method 5297 multi-method
5248 (tramp-find-method multi-method method user host) 5298 (tramp-find-method multi-method method user host)
5249 user host 'tramp-login-args))) 5299 user host 'tramp-login-args))
5300 (real-host host))
5250 ;; The following should be changed. We need a more general 5301 ;; The following should be changed. We need a more general
5251 ;; mechanism to parse extra host args. 5302 ;; mechanism to parse extra host args.
5252 (when (string-match "\\([^#]*\\)#\\(.*\\)" host) 5303 (when (string-match "\\([^#]*\\)#\\(.*\\)" host)
5253 (setq login-args (cons "-p" (cons (match-string 2 host) login-args))) 5304 (setq login-args (cons "-p" (cons (match-string 2 host) login-args)))
5254 (setq host (match-string 1 host))) 5305 (setq real-host (match-string 1 host)))
5255 (setenv "TERM" tramp-terminal-type) 5306 (setenv "TERM" tramp-terminal-type)
5256 (let* ((default-directory (tramp-temporary-file-directory)) 5307 (let* ((default-directory (tramp-temporary-file-directory))
5257 ;; If we omit the conditional, we would use 5308 ;; If we omit the conditional, we would use
5258 ;; `undecided-dos' in some cases. With the conditional, 5309 ;; `undecided-dos' in some cases. With the conditional,
5259 ;; we use nil in these cases. Which one is right? 5310 ;; we use nil in these cases. Which one is right?
5260 (coding-system-for-read (unless (and (not (featurep 'xemacs)) 5311 (coding-system-for-read (unless (and (not (featurep 'xemacs))
5261 (> emacs-major-version 20)) 5312 (> emacs-major-version 20))
5262 tramp-dos-coding-system)) 5313 tramp-dos-coding-system))
5263 (p (if (and user (not (string= user ""))) 5314 (p (if (and user (not (string= user "")))
5264 (apply #'start-process bufnam buf login-program 5315 (apply #'start-process bufnam buf login-program
5265 host "-l" user login-args) 5316 real-host "-l" user login-args)
5266 (apply #'start-process bufnam buf login-program 5317 (apply #'start-process bufnam buf login-program
5267 host login-args))) 5318 real-host login-args)))
5268 (found nil)) 5319 (found nil))
5269 (tramp-set-process-query-on-exit-flag p nil) 5320 (tramp-set-process-query-on-exit-flag p nil)
5270 5321
5271 (set-buffer buf) 5322 (set-buffer buf)
5272 (tramp-process-actions p multi-method method user host 5323 (tramp-process-actions p multi-method method user host
5545 seconds. If not, it produces an error message with the given ERROR-ARGS." 5596 seconds. If not, it produces an error message with the given ERROR-ARGS."
5546 (unless (tramp-wait-for-shell-prompt proc timeout) 5597 (unless (tramp-wait-for-shell-prompt proc timeout)
5547 (pop-to-buffer (buffer-name)) 5598 (pop-to-buffer (buffer-name))
5548 (apply 'error error-args))) 5599 (apply 'error error-args)))
5549 5600
5550 (defun tramp-enter-password (p prompt) 5601 (defun tramp-enter-password (p prompt user host)
5551 "Prompt for a password and send it to the remote end. 5602 "Prompt for a password and send it to the remote end.
5552 Uses PROMPT as a prompt and sends the password to process P." 5603 Uses PROMPT as a prompt and sends the password to process P."
5553 (let ((pw (tramp-read-passwd prompt))) 5604 (let ((pw (tramp-read-passwd user host prompt)))
5554 (erase-buffer) 5605 (erase-buffer)
5555 (process-send-string 5606 (process-send-string
5556 p (concat pw 5607 p (concat pw
5557 (or (tramp-get-method-parameter 5608 (or (tramp-get-method-parameter
5558 tramp-current-multi-method 5609 tramp-current-multi-method
6715 ((file-exists-p "c:/temp") (file-name-as-directory "c:/temp")) 6766 ((file-exists-p "c:/temp") (file-name-as-directory "c:/temp"))
6716 (t (message (concat "Neither `temporary-file-directory' nor " 6767 (t (message (concat "Neither `temporary-file-directory' nor "
6717 "`temp-directory' is defined -- using /tmp.")) 6768 "`temp-directory' is defined -- using /tmp."))
6718 (file-name-as-directory "/tmp")))) 6769 (file-name-as-directory "/tmp"))))
6719 6770
6720 (defun tramp-read-passwd (prompt) 6771 (defun tramp-read-passwd (user host prompt)
6721 "Read a password from user (compat function). 6772 "Read a password from user (compat function).
6722 Invokes `password-read' if available, `read-passwd' else." 6773 Invokes `password-read' if available, `read-passwd' else."
6723 (if (functionp 'password-read) 6774 (if (functionp 'password-read)
6724 (let* ((user (or tramp-current-user (user-login-name))) 6775 (let* ((key (concat (or user (user-login-name)) "@" host))
6725 (host (or tramp-current-host (system-name)))
6726 (key (if (and (stringp user) (stringp host))
6727 (concat user "@" host)
6728 (concat "[" (mapconcat 'identity user "/") "]@["
6729 (mapconcat 'identity host "/") "]")))
6730 (password (apply #'password-read (list prompt key)))) 6776 (password (apply #'password-read (list prompt key))))
6731 (apply #'password-cache-add (list key password)) 6777 (apply #'password-cache-add (list key password))
6732 password) 6778 password)
6733 (read-passwd prompt))) 6779 (read-passwd prompt)))
6734 6780