916 |
"Regular expression indicating a process has finished. |
"Regular expression indicating a process has finished. |
917 |
In fact this expression is empty by intention, it will be used only to |
In fact this expression is empty by intention, it will be used only to |
918 |
check regularly the status of the associated process. |
check regularly the status of the associated process. |
919 |
The answer will be provided by `tramp-action-process-alive' and |
The answer will be provided by `tramp-action-process-alive', |
920 |
`tramp-action-out-of-band', which see." |
`tramp-multi-action-process-alive' and`tramp-action-out-of-band', which see." |
921 |
:group 'tramp |
:group 'tramp |
922 |
:type 'regexp) |
:type 'regexp) |
923 |
|
|
1321 |
(shell-prompt-pattern tramp-multi-action-succeed) |
(shell-prompt-pattern tramp-multi-action-succeed) |
1322 |
(tramp-shell-prompt-pattern tramp-multi-action-succeed) |
(tramp-shell-prompt-pattern tramp-multi-action-succeed) |
1323 |
(tramp-wrong-passwd-regexp tramp-multi-action-permission-denied) |
(tramp-wrong-passwd-regexp tramp-multi-action-permission-denied) |
1324 |
(tramp-process-alive-regexp tramp-action-process-alive)) |
(tramp-process-alive-regexp tramp-multi-action-process-alive)) |
1325 |
"List of pattern/action pairs. |
"List of pattern/action pairs. |
1326 |
This list is used for each hop in multi-hop connections. |
This list is used for each hop in multi-hop connections. |
1327 |
See `tramp-actions-before-shell' for more info." |
See `tramp-actions-before-shell' for more info." |
2165 |
(let ((nonnumeric (and id-format (equal id-format 'string))) |
(let ((nonnumeric (and id-format (equal id-format 'string))) |
2166 |
result) |
result) |
2167 |
(with-parsed-tramp-file-name filename nil |
(with-parsed-tramp-file-name filename nil |
2168 |
(when (tramp-handle-file-exists-p filename) |
(when (file-exists-p filename) |
2169 |
;; file exists, find out stuff |
;; file exists, find out stuff |
2170 |
(save-excursion |
(save-excursion |
2171 |
(if (tramp-get-remote-perl multi-method method user host) |
(if (tramp-get-remote-perl multi-method method user host) |
2331 |
;; This function makes the same assumption as |
;; This function makes the same assumption as |
2332 |
;; `tramp-handle-set-visited-file-modtime'. |
;; `tramp-handle-set-visited-file-modtime'. |
2333 |
(defun tramp-handle-verify-visited-file-modtime (buf) |
(defun tramp-handle-verify-visited-file-modtime (buf) |
2334 |
"Like `verify-visited-file-modtime' for tramp files." |
"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." |
2340 |
(with-current-buffer buf |
(with-current-buffer buf |
2341 |
(let ((f (buffer-file-name))) |
(let ((f (buffer-file-name))) |
2342 |
(with-parsed-tramp-file-name f nil |
(with-parsed-tramp-file-name f nil |
2514 |
(defun tramp-handle-file-writable-p (filename) |
(defun tramp-handle-file-writable-p (filename) |
2515 |
"Like `file-writable-p' for tramp files." |
"Like `file-writable-p' for tramp files." |
2516 |
(with-parsed-tramp-file-name filename nil |
(with-parsed-tramp-file-name filename nil |
2517 |
(if (tramp-handle-file-exists-p filename) |
(if (file-exists-p filename) |
2518 |
;; Existing files must be writable. |
;; Existing files must be writable. |
2519 |
(zerop (tramp-run-test "-w" filename)) |
(zerop (tramp-run-test "-w" filename)) |
2520 |
;; If file doesn't exist, check if directory is writable. |
;; If file doesn't exist, check if directory is writable. |
2521 |
(and (zerop (tramp-run-test |
(and (zerop (tramp-run-test |
2522 |
"-d" (tramp-handle-file-name-directory filename))) |
"-d" (file-name-directory filename))) |
2523 |
(zerop (tramp-run-test |
(zerop (tramp-run-test |
2524 |
"-w" (tramp-handle-file-name-directory filename))))))) |
"-w" (file-name-directory filename))))))) |
2525 |
|
|
2526 |
(defun tramp-handle-file-ownership-preserved-p (filename) |
(defun tramp-handle-file-ownership-preserved-p (filename) |
2527 |
"Like `file-ownership-preserved-p' for tramp files." |
"Like `file-ownership-preserved-p' for tramp files." |
2528 |
(with-parsed-tramp-file-name filename nil |
(with-parsed-tramp-file-name filename nil |
2529 |
(or (not (tramp-handle-file-exists-p filename)) |
(or (not (file-exists-p filename)) |
2530 |
;; Existing files must be writable. |
;; Existing files must be writable. |
2531 |
(zerop (tramp-run-test "-O" filename))))) |
(zerop (tramp-run-test "-O" filename))))) |
2532 |
|
|
3069 |
(with-parsed-tramp-file-name filename nil |
(with-parsed-tramp-file-name filename nil |
3070 |
;; run a shell command 'rm -r <localname>' |
;; run a shell command 'rm -r <localname>' |
3071 |
;; Code shamelessly stolen for the dired implementation and, um, hacked :) |
;; Code shamelessly stolen for the dired implementation and, um, hacked :) |
3072 |
(or (tramp-handle-file-exists-p filename) |
(or (file-exists-p filename) |
3073 |
(signal |
(signal |
3074 |
'file-error |
'file-error |
3075 |
(list "Removing old file name" "no such directory" filename))) |
(list "Removing old file name" "no such directory" filename))) |
3080 |
;; This might take a while, allow it plenty of time. |
;; This might take a while, allow it plenty of time. |
3081 |
(tramp-wait-for-output 120) |
(tramp-wait-for-output 120) |
3082 |
;; Make sure that it worked... |
;; Make sure that it worked... |
3083 |
(and (tramp-handle-file-exists-p filename) |
(and (file-exists-p filename) |
3084 |
(error "Failed to recusively delete %s" filename)))) |
(error "Failed to recusively delete %s" filename)))) |
3085 |
|
|
3086 |
(defun tramp-handle-dired-call-process (program discard &rest arguments) |
(defun tramp-handle-dired-call-process (program discard &rest arguments) |
3612 |
|
|
3613 |
(defun tramp-handle-find-backup-file-name (filename) |
(defun tramp-handle-find-backup-file-name (filename) |
3614 |
"Like `find-backup-file-name' for tramp files." |
"Like `find-backup-file-name' for tramp files." |
3615 |
|
(with-parsed-tramp-file-name filename nil |
3616 |
|
;; We set both variables. It doesn't matter whether it is |
3617 |
|
;; Emacs or XEmacs |
3618 |
|
(let ((backup-directory-alist |
3619 |
|
;; Emacs case |
3620 |
|
(when (boundp 'backup-directory-alist) |
3621 |
|
(if (boundp 'tramp-backup-directory-alist) |
3622 |
|
(mapcar |
3623 |
|
'(lambda (x) |
3624 |
|
(cons |
3625 |
|
(car x) |
3626 |
|
(if (and (stringp (cdr x)) |
3627 |
|
(file-name-absolute-p (cdr x)) |
3628 |
|
(not (tramp-file-name-p (cdr x)))) |
3629 |
|
(tramp-make-tramp-file-name |
3630 |
|
multi-method method user host (cdr x)) |
3631 |
|
(cdr x)))) |
3632 |
|
(symbol-value 'tramp-backup-directory-alist)) |
3633 |
|
(symbol-value 'backup-directory-alist)))) |
3634 |
|
|
3635 |
|
(bkup-backup-directory-info |
3636 |
|
;; XEmacs case |
3637 |
|
(when (boundp 'bkup-backup-directory-info) |
3638 |
|
(if (boundp 'tramp-bkup-backup-directory-info) |
3639 |
|
(mapcar |
3640 |
|
'(lambda (x) |
3641 |
|
(nconc |
3642 |
|
(list (car x)) |
3643 |
|
(list |
3644 |
|
(if (and (stringp (car (cdr x))) |
3645 |
|
(file-name-absolute-p (car (cdr x))) |
3646 |
|
(not (tramp-file-name-p (car (cdr x))))) |
3647 |
|
(tramp-make-tramp-file-name |
3648 |
|
multi-method method user host (car (cdr x))) |
3649 |
|
(car (cdr x)))) |
3650 |
|
(cdr (cdr x)))) |
3651 |
|
(symbol-value 'tramp-bkup-backup-directory-info)) |
3652 |
|
(symbol-value 'bkup-backup-directory-info))))) |
3653 |
|
|
3654 |
(if (or (and (not (featurep 'xemacs)) |
(tramp-run-real-handler 'find-backup-file-name (list filename))))) |
|
(not (boundp 'tramp-backup-directory-alist))) |
|
|
(and (featurep 'xemacs) |
|
|
(not (boundp 'tramp-bkup-backup-directory-info)))) |
|
|
|
|
|
;; No tramp backup directory alist defined, or nil |
|
|
(tramp-run-real-handler 'find-backup-file-name (list filename)) |
|
|
|
|
|
(with-parsed-tramp-file-name filename nil |
|
|
(let* ((backup-var |
|
|
(copy-tree |
|
|
(if (featurep 'xemacs) |
|
|
;; XEmacs case |
|
|
(symbol-value 'tramp-bkup-backup-directory-info) |
|
|
;; Emacs case |
|
|
(symbol-value 'tramp-backup-directory-alist)))) |
|
|
|
|
|
;; We set both variables. It doesn't matter whether it is |
|
|
;; Emacs or XEmacs |
|
|
(backup-directory-alist backup-var) |
|
|
(bkup-backup-directory-info backup-var)) |
|
|
|
|
|
(mapcar |
|
|
'(lambda (x) |
|
|
(let ((dir (if (consp (cdr x)) (car (cdr x)) (cdr x)))) |
|
|
(when (and (stringp dir) |
|
|
(file-name-absolute-p dir) |
|
|
(not (tramp-file-name-p dir))) |
|
|
;; Prepend absolute directory names with tramp prefix |
|
|
(if (consp (cdr x)) |
|
|
(setcar (cdr x) |
|
|
(tramp-make-tramp-file-name |
|
|
multi-method method user host dir)) |
|
|
(setcdr x (tramp-make-tramp-file-name |
|
|
multi-method method user host dir)))))) |
|
|
backup-var) |
|
3655 |
|
|
|
(tramp-run-real-handler 'find-backup-file-name (list filename)))))) |
|
3656 |
|
|
3657 |
;; CCC grok APPEND, LOCKNAME, CONFIRM |
;; CCC grok APPEND, LOCKNAME, CONFIRM |
3658 |
(defun tramp-handle-write-region |
(defun tramp-handle-write-region |
3696 |
;; use an encoding function, but currently we use it always |
;; use an encoding function, but currently we use it always |
3697 |
;; because this makes the logic simpler. |
;; because this makes the logic simpler. |
3698 |
(setq tmpfil (tramp-make-temp-file)) |
(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) |
3702 |
;; We say `no-message' here because we don't want the visited file |
;; We say `no-message' here because we don't want the visited file |
3703 |
;; modtime data to be clobbered from the temp file. We call |
;; modtime data to be clobbered from the temp file. We call |
3704 |
;; `set-visited-file-modtime' ourselves later on. |
;; `set-visited-file-modtime' ourselves later on. |
3982 |
(foreign (apply foreign operation args)) |
(foreign (apply foreign operation args)) |
3983 |
(t (tramp-run-real-handler operation args)))))) |
(t (tramp-run-real-handler operation args)))))) |
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 |
|
|
4013 |
(defun tramp-sh-file-name-handler (operation &rest args) |
(defun tramp-sh-file-name-handler (operation &rest args) |
4014 |
"Invoke remote-shell Tramp file name handler. |
"Invoke remote-shell Tramp file name handler. |
4015 |
Fall back to normal file name handler if no Tramp handler exists." |
Fall back to normal file name handler if no Tramp handler exists." |
4016 |
(save-match-data |
(when (and tramp-locked (not tramp-locker)) |
4017 |
(let ((fn (assoc operation tramp-file-name-handler-alist))) |
(signal 'file-error "Forbidden reentrant call of Tramp")) |
4018 |
(if fn |
(let ((tl tramp-locked)) |
4019 |
(apply (cdr fn) args) |
(unwind-protect |
4020 |
(tramp-run-real-handler operation args))))) |
(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)))) |
4029 |
|
|
4030 |
;;;###autoload |
;;;###autoload |
4031 |
(defun tramp-completion-file-name-handler (operation &rest args) |
(defun tramp-completion-file-name-handler (operation &rest args) |
4108 |
(tramp-make-tramp-file-name multi-method method |
(tramp-make-tramp-file-name multi-method method |
4109 |
user host x))) |
user host x))) |
4110 |
(read (current-buffer)))))) |
(read (current-buffer)))))) |
4111 |
(list (tramp-handle-expand-file-name name)))))) |
(list (expand-file-name name)))))) |
4112 |
|
|
4113 |
;; Check for complete.el and override PC-expand-many-files if appropriate. |
;; Check for complete.el and override PC-expand-many-files if appropriate. |
4114 |
(eval-and-compile |
(eval-and-compile |
4119 |
(symbol-function 'PC-expand-many-files)) |
(symbol-function 'PC-expand-many-files)) |
4120 |
(defun PC-expand-many-files (name) |
(defun PC-expand-many-files (name) |
4121 |
(if (tramp-tramp-file-p name) |
(if (tramp-tramp-file-p name) |
4122 |
(tramp-handle-expand-many-files name) |
(expand-many-files name) |
4123 |
(tramp-save-PC-expand-many-files name)))) |
(tramp-save-PC-expand-many-files name)))) |
4124 |
|
|
4125 |
;; Why isn't eval-after-load sufficient? |
;; Why isn't eval-after-load sufficient? |
4870 |
;; `/usr/bin/test -e' In case `/bin/test' does not exist. |
;; `/usr/bin/test -e' In case `/bin/test' does not exist. |
4871 |
(unless (or |
(unless (or |
4872 |
(and (setq tramp-file-exists-command "test -e %s") |
(and (setq tramp-file-exists-command "test -e %s") |
4873 |
(tramp-handle-file-exists-p existing) |
(file-exists-p existing) |
4874 |
(not (tramp-handle-file-exists-p nonexisting))) |
(not (file-exists-p nonexisting))) |
4875 |
(and (setq tramp-file-exists-command "/bin/test -e %s") |
(and (setq tramp-file-exists-command "/bin/test -e %s") |
4876 |
(tramp-handle-file-exists-p existing) |
(file-exists-p existing) |
4877 |
(not (tramp-handle-file-exists-p nonexisting))) |
(not (file-exists-p nonexisting))) |
4878 |
(and (setq tramp-file-exists-command "/usr/bin/test -e %s") |
(and (setq tramp-file-exists-command "/usr/bin/test -e %s") |
4879 |
(tramp-handle-file-exists-p existing) |
(file-exists-p existing) |
4880 |
(not (tramp-handle-file-exists-p nonexisting))) |
(not (file-exists-p nonexisting))) |
4881 |
(and (setq tramp-file-exists-command "ls -d %s") |
(and (setq tramp-file-exists-command "ls -d %s") |
4882 |
(tramp-handle-file-exists-p existing) |
(file-exists-p existing) |
4883 |
(not (tramp-handle-file-exists-p nonexisting)))) |
(not (file-exists-p nonexisting)))) |
4884 |
(error "Couldn't find command to check if file exists.")))) |
(error "Couldn't find command to check if file exists.")))) |
4885 |
|
|
4886 |
|
|
4942 |
METHOD, USER and HOST specify the connection, CMD (the absolute file name of) |
METHOD, USER and HOST specify the connection, CMD (the absolute file name of) |
4943 |
the `ls' executable. Returns t if CMD supports the `-n' option, nil |
the `ls' executable. Returns t if CMD supports the `-n' option, nil |
4944 |
otherwise." |
otherwise." |
4945 |
(tramp-message 9 "Checking remote `%s' command for `-n' option" |
(tramp-message 9 "Checking remote `%s' command for `-n' option" cmd) |
4946 |
cmd) |
(when (file-executable-p |
|
(when (tramp-handle-file-executable-p |
|
4947 |
(tramp-make-tramp-file-name multi-method method user host cmd)) |
(tramp-make-tramp-file-name multi-method method user host cmd)) |
4948 |
(let ((result nil)) |
(let ((result nil)) |
4949 |
(tramp-message 7 "Testing remote command `%s' for -n..." cmd) |
(tramp-message 7 "Testing remote command `%s' for -n..." cmd) |
5001 |
"Query the user for a password." |
"Query the user for a password." |
5002 |
(let ((pw-prompt (match-string 0))) |
(let ((pw-prompt (match-string 0))) |
5003 |
(tramp-message 9 "Sending password") |
(tramp-message 9 "Sending password") |
5004 |
(tramp-enter-password p pw-prompt))) |
(tramp-enter-password p pw-prompt user host))) |
5005 |
|
|
5006 |
(defun tramp-action-succeed (p multi-method method user host) |
(defun tramp-action-succeed (p multi-method method user host) |
5007 |
"Signal success in finding shell prompt." |
"Signal success in finding shell prompt." |
5079 |
(defun tramp-multi-action-password (p method user host) |
(defun tramp-multi-action-password (p method user host) |
5080 |
"Query the user for a password." |
"Query the user for a password." |
5081 |
(tramp-message 9 "Sending password") |
(tramp-message 9 "Sending password") |
5082 |
(tramp-enter-password p (match-string 0))) |
(tramp-enter-password p (match-string 0) user host)) |
5083 |
|
|
5084 |
(defun tramp-multi-action-succeed (p method user host) |
(defun tramp-multi-action-succeed (p method user host) |
5085 |
"Signal success in finding shell prompt." |
"Signal success in finding shell prompt." |
5094 |
(erase-buffer) |
(erase-buffer) |
5095 |
(throw 'tramp-action 'permission-denied)) |
(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))) |
5101 |
|
|
5102 |
;; Functions for processing the actions. |
;; Functions for processing the actions. |
5103 |
|
|
5104 |
(defun tramp-process-one-action (p multi-method method user host actions) |
(defun tramp-process-one-action (p multi-method method user host actions) |
5296 |
(login-args (tramp-get-method-parameter |
(login-args (tramp-get-method-parameter |
5297 |
multi-method |
multi-method |
5298 |
(tramp-find-method multi-method method user host) |
(tramp-find-method multi-method method user host) |
5299 |
user host 'tramp-login-args))) |
user host 'tramp-login-args)) |
5300 |
|
(real-host host)) |
5301 |
;; The following should be changed. We need a more general |
;; The following should be changed. We need a more general |
5302 |
;; mechanism to parse extra host args. |
;; mechanism to parse extra host args. |
5303 |
(when (string-match "\\([^#]*\\)#\\(.*\\)" host) |
(when (string-match "\\([^#]*\\)#\\(.*\\)" host) |
5304 |
(setq login-args (cons "-p" (cons (match-string 2 host) login-args))) |
(setq login-args (cons "-p" (cons (match-string 2 host) login-args))) |
5305 |
(setq host (match-string 1 host))) |
(setq real-host (match-string 1 host))) |
5306 |
(setenv "TERM" tramp-terminal-type) |
(setenv "TERM" tramp-terminal-type) |
5307 |
(let* ((default-directory (tramp-temporary-file-directory)) |
(let* ((default-directory (tramp-temporary-file-directory)) |
5308 |
;; If we omit the conditional, we would use |
;; If we omit the conditional, we would use |
5313 |
tramp-dos-coding-system)) |
tramp-dos-coding-system)) |
5314 |
(p (if (and user (not (string= user ""))) |
(p (if (and user (not (string= user ""))) |
5315 |
(apply #'start-process bufnam buf login-program |
(apply #'start-process bufnam buf login-program |
5316 |
host "-l" user login-args) |
real-host "-l" user login-args) |
5317 |
(apply #'start-process bufnam buf login-program |
(apply #'start-process bufnam buf login-program |
5318 |
host login-args))) |
real-host login-args))) |
5319 |
(found nil)) |
(found nil)) |
5320 |
(tramp-set-process-query-on-exit-flag p nil) |
(tramp-set-process-query-on-exit-flag p nil) |
5321 |
|
|
5598 |
(pop-to-buffer (buffer-name)) |
(pop-to-buffer (buffer-name)) |
5599 |
(apply 'error error-args))) |
(apply 'error error-args))) |
5600 |
|
|
5601 |
(defun tramp-enter-password (p prompt) |
(defun tramp-enter-password (p prompt user host) |
5602 |
"Prompt for a password and send it to the remote end. |
"Prompt for a password and send it to the remote end. |
5603 |
Uses PROMPT as a prompt and sends the password to process P." |
Uses PROMPT as a prompt and sends the password to process P." |
5604 |
(let ((pw (tramp-read-passwd prompt))) |
(let ((pw (tramp-read-passwd user host prompt))) |
5605 |
(erase-buffer) |
(erase-buffer) |
5606 |
(process-send-string |
(process-send-string |
5607 |
p (concat pw |
p (concat pw |
6768 |
"`temp-directory' is defined -- using /tmp.")) |
"`temp-directory' is defined -- using /tmp.")) |
6769 |
(file-name-as-directory "/tmp")))) |
(file-name-as-directory "/tmp")))) |
6770 |
|
|
6771 |
(defun tramp-read-passwd (prompt) |
(defun tramp-read-passwd (user host prompt) |
6772 |
"Read a password from user (compat function). |
"Read a password from user (compat function). |
6773 |
Invokes `password-read' if available, `read-passwd' else." |
Invokes `password-read' if available, `read-passwd' else." |
6774 |
(if (functionp 'password-read) |
(if (functionp 'password-read) |
6775 |
(let* ((user (or tramp-current-user (user-login-name))) |
(let* ((key (concat (or user (user-login-name)) "@" host)) |
|
(host (or tramp-current-host (system-name))) |
|
|
(key (if (and (stringp user) (stringp host)) |
|
|
(concat user "@" host) |
|
|
(concat "[" (mapconcat 'identity user "/") "]@[" |
|
|
(mapconcat 'identity host "/") "]"))) |
|
6776 |
(password (apply #'password-read (list prompt key)))) |
(password (apply #'password-read (list prompt key)))) |
6777 |
(apply #'password-cache-add (list key password)) |
(apply #'password-cache-add (list key password)) |
6778 |
password) |
password) |