comparison lisp/net/tramp.el @ 85067:4636000015c5

* net/tramp.el (top): Move loading of tramp-util.el and tramp-vc.el to tramp-compat.el. (tramp-make-tramp-temp-file): Complete rewrite. Create remote temporary file if possible, in order to avoid a security hole. (tramp-do-copy-or-rename-file-out-of-band) (tramp-maybe-open-connection): Call `tramp-make-tramp-temp-file' with DONT-CREATE, because the connection is not setup yet. (tramp-handle-process-file): Rewrite temporary file handling. (tramp-completion-mode): New defvar. (tramp-completion-mode-p): Use it. * net/tramp-compat.el (top): Load tramp-util.el and tramp-vc.el. * net/tramp-fish.el (tramp-fish-handle-process-file): Rewrite temporary file handling.
author Michael Albinus <michael.albinus@gmx.de>
date Sat, 06 Oct 2007 12:00:42 +0000
parents a42b8750a992
children 8fb95bcda144
comparison
equal deleted inserted replaced
85066:875aa6bd4755 85067:4636000015c5
147 (when (functionp 'make-network-process) 147 (when (functionp 'make-network-process)
148 (require 'tramp-gw) 148 (require 'tramp-gw)
149 (add-hook 'tramp-unload-hook 149 (add-hook 'tramp-unload-hook
150 '(lambda () 150 '(lambda ()
151 (when (featurep 'tramp-gw) 151 (when (featurep 'tramp-gw)
152 (unload-feature 'tramp-gw 'force))))) 152 (unload-feature 'tramp-gw 'force)))))))
153
154 ;; tramp-util offers integration into other (X)Emacs packages like
155 ;; compile.el, gud.el etc. Not necessary in Emacs 23.
156 (unless (functionp 'start-file-process)
157 (require 'tramp-util)
158 (add-hook 'tramp-unload-hook
159 '(lambda ()
160 (when (featurep 'tramp-util)
161 (unload-feature 'tramp-util 'force)))))))
162 153
163 ;;; User Customizable Internal Variables: 154 ;;; User Customizable Internal Variables:
164 155
165 (defgroup tramp nil 156 (defgroup tramp nil
166 "Edit remote files with a combination of rsh and rcp or similar programs." 157 "Edit remote files with a combination of rsh and rcp or similar programs."
1972 (let ((,variable ,value)) 1963 (let ((,variable ,value))
1973 ,@body))) 1964 ,@body)))
1974 (put 'tramp-let-maybe 'lisp-indent-function 2) 1965 (put 'tramp-let-maybe 'lisp-indent-function 2)
1975 (put 'tramp-let-maybe 'edebug-form-spec t) 1966 (put 'tramp-let-maybe 'edebug-form-spec t)
1976 1967
1977 (defsubst tramp-make-tramp-temp-file (vec) 1968 (defsubst tramp-make-tramp-temp-file (vec &optional dont-create)
1978 (format 1969 "Create a temporary file on the remote host identified by VEC.
1979 "/tmp/%s%s" 1970 Return the local name of the temporary file.
1980 tramp-temp-name-prefix 1971 If DONT-CREATE is non-nil, just the file name is returned without
1981 (if (get-buffer-process (tramp-get-connection-buffer vec)) 1972 creation of the temporary file. This is not the preferred way to run,
1982 (process-id (get-buffer-process (tramp-get-connection-buffer vec))) 1973 but it is necessary during connection setup, because we cannot create
1983 (emacs-pid)))) 1974 a remote file at this time. This parameter shall NOT be set to
1975 non-nil else."
1976 (if dont-create
1977 ;; It sounds a little bit stupid to create a LOCAL file name.
1978 ;; But we intend to use the remote directory "/tmp", and we have
1979 ;; no chance to check whether a temporary file exists already
1980 ;; remotely, because we have no working connection yet.
1981 (make-temp-name (expand-file-name tramp-temp-name-prefix "/tmp"))
1982
1983 (let ((prefix
1984 (tramp-make-tramp-file-name
1985 (tramp-file-name-method vec)
1986 (tramp-file-name-user vec)
1987 (tramp-file-name-host vec)
1988 (expand-file-name tramp-temp-name-prefix "/tmp")))
1989 result)
1990 (while (not result)
1991 ;; `make-temp-file' would be the first choice for
1992 ;; implementation. But it calls `write-region' internally,
1993 ;; which also needs a temporary file - we would end in an
1994 ;; infinite loop.
1995 (setq result (make-temp-name prefix))
1996 (if (file-exists-p result)
1997 (setq result nil)
1998 ;; This creates the file by side effect.
1999 (set-file-times result)
2000 (set-file-modes result (tramp-octal-to-decimal "0700"))))
2001
2002 ;; Return the local part.
2003 (with-parsed-tramp-file-name result nil localname))))
1984 2004
1985 2005
1986 ;;; Config Manipulation Functions: 2006 ;;; Config Manipulation Functions:
1987 2007
1988 (defun tramp-set-completion-function (method function-list) 2008 (defun tramp-set-completion-function (method function-list)
3186 port (tramp-file-name-port v) 3206 port (tramp-file-name-port v)
3187 port (or (and port (number-to-string port)) "")) 3207 port (or (and port (number-to-string port)) ""))
3188 3208
3189 ;; Compose copy command. 3209 ;; Compose copy command.
3190 (setq spec `((?h . ,host) (?u . ,user) (?p . ,port) 3210 (setq spec `((?h . ,host) (?u . ,user) (?p . ,port)
3191 (?t . ,(tramp-make-tramp-temp-file v)) 3211 (?t . ,(tramp-make-tramp-temp-file v 'dont-create))
3192 (?k . ,(if keep-date " " ""))) 3212 (?k . ,(if keep-date " " "")))
3193 copy-program (tramp-get-method-parameter 3213 copy-program (tramp-get-method-parameter
3194 method 'tramp-copy-program) 3214 method 'tramp-copy-program)
3195 copy-keep-date (tramp-get-method-parameter 3215 copy-keep-date (tramp-get-method-parameter
3196 method 'tramp-copy-keep-date) 3216 method 'tramp-copy-keep-date)
3637 ;; The implementation is not complete yet. 3657 ;; The implementation is not complete yet.
3638 (when (and (numberp destination) (zerop destination)) 3658 (when (and (numberp destination) (zerop destination))
3639 (error "Implementation does not handle immediate return")) 3659 (error "Implementation does not handle immediate return"))
3640 3660
3641 (with-parsed-tramp-file-name default-directory nil 3661 (with-parsed-tramp-file-name default-directory nil
3642 (let ((temp-name-prefix (tramp-make-tramp-temp-file v)) 3662 (let (command input tmpinput stderr tmpstderr outbuf ret)
3643 command input stderr outbuf ret)
3644 ;; Compute command. 3663 ;; Compute command.
3645 (setq command (mapconcat 'tramp-shell-quote-argument 3664 (setq command (mapconcat 'tramp-shell-quote-argument
3646 (cons program args) " ")) 3665 (cons program args) " "))
3647 ;; Determine input. 3666 ;; Determine input.
3648 (if (null infile) 3667 (if (null infile)
3650 (setq infile (expand-file-name infile)) 3669 (setq infile (expand-file-name infile))
3651 (if (tramp-equal-remote default-directory infile) 3670 (if (tramp-equal-remote default-directory infile)
3652 ;; INFILE is on the same remote host. 3671 ;; INFILE is on the same remote host.
3653 (setq input (with-parsed-tramp-file-name infile nil localname)) 3672 (setq input (with-parsed-tramp-file-name infile nil localname))
3654 ;; INFILE must be copied to remote host. 3673 ;; INFILE must be copied to remote host.
3655 (setq input (concat temp-name-prefix ".in")) 3674 (setq input (tramp-make-tramp-temp-file v)
3656 (copy-file 3675 tmpinput (tramp-make-tramp-file-name method user host input))
3657 infile 3676 (copy-file infile tmpinput t)))
3658 (tramp-make-tramp-file-name method user host input)
3659 t)))
3660 (when input (setq command (format "%s <%s" command input))) 3677 (when input (setq command (format "%s <%s" command input)))
3661 3678
3662 ;; Determine output. 3679 ;; Determine output.
3663 (cond 3680 (cond
3664 ;; Just a buffer 3681 ;; Just a buffer
3683 ;; stderr is on the same remote host. 3700 ;; stderr is on the same remote host.
3684 (setq stderr (with-parsed-tramp-file-name 3701 (setq stderr (with-parsed-tramp-file-name
3685 (cadr destination) nil localname)) 3702 (cadr destination) nil localname))
3686 ;; stderr must be copied to remote host. The temporary 3703 ;; stderr must be copied to remote host. The temporary
3687 ;; file must be deleted after execution. 3704 ;; file must be deleted after execution.
3688 (setq stderr (concat temp-name-prefix ".err")))) 3705 (setq stderr (tramp-make-tramp-temp-file v)
3706 tmpstderr (tramp-make-tramp-file-name
3707 method user host stderr))))
3689 ;; stderr to be discarded 3708 ;; stderr to be discarded
3690 ((null (cadr destination)) 3709 ((null (cadr destination))
3691 (setq stderr "/dev/null")))) 3710 (setq stderr "/dev/null"))))
3692 ;; 't 3711 ;; 't
3693 (destination 3712 (destination
3694 (setq outbuf (current-buffer)))) 3713 (setq outbuf (current-buffer))))
3695 (when stderr (setq command (format "%s 2>%s" command stderr))) 3714 (when stderr (setq command (format "%s 2>%s" command stderr)))
3696 3715
3697 ;; If we have a temporary file, it must be removed after operation.
3698 (when (and input (string-match temp-name-prefix input))
3699 (setq command (format "%s; rm %s" command input)))
3700 ;; Goto working directory. 3716 ;; Goto working directory.
3701 (tramp-send-command 3717 (tramp-send-command
3702 v (format "cd %s" (tramp-shell-quote-argument localname))) 3718 v (format "cd %s" (tramp-shell-quote-argument localname)))
3703 ;; Send the command. It might not return in time, so we protect it. 3719 ;; Send the command. It might not return in time, so we protect it.
3704 (condition-case nil 3720 (condition-case nil
3714 (when display (display-buffer outbuf)))) 3730 (when display (display-buffer outbuf))))
3715 ;; When the user did interrupt, we should do it also. 3731 ;; When the user did interrupt, we should do it also.
3716 (error 3732 (error
3717 (kill-buffer (tramp-get-connection-buffer v)) 3733 (kill-buffer (tramp-get-connection-buffer v))
3718 (setq ret 1))) 3734 (setq ret 1)))
3719 (unless ret 3735
3720 ;; Check return code. 3736 ;; Check return code.
3721 (setq ret (tramp-send-command-and-check v nil)) 3737 (unless ret (setq ret (tramp-send-command-and-check v nil)))
3722 ;; Provide error file. 3738 ;; Provide error file.
3723 (when (and stderr (string-match temp-name-prefix stderr)) 3739 (when tmpstderr (rename-file tmpstderr (cadr destination) t))
3724 (rename-file (tramp-make-tramp-file-name method user host stderr) 3740 ;; Cleanup.
3725 (cadr destination) t))) 3741 (when tmpinput (delete-file tmpinput))
3726 ;; Return exit status. 3742 ;; Return exit status.
3727 ret))) 3743 ret)))
3728 3744
3729 (defun tramp-handle-call-process-region 3745 (defun tramp-handle-call-process-region
3730 (start end program &optional delete buffer display &rest args) 3746 (start end program &optional delete buffer display &rest args)
4553 (setq ad-return-value (tramp-handle-expand-many-files name)) 4569 (setq ad-return-value (tramp-handle-expand-many-files name))
4554 ad-do-it)) 4570 ad-do-it))
4555 (add-hook 'tramp-unload-hook 4571 (add-hook 'tramp-unload-hook
4556 '(lambda () (ad-unadvise 'PC-expand-many-files))))) 4572 '(lambda () (ad-unadvise 'PC-expand-many-files)))))
4557 4573
4558 ;;; File name handler functions for completion mode 4574 ;;; File name handler functions for completion mode.
4575
4576 (defvar tramp-completion-mode nil
4577 "If non-nil, external packages signal that they are in file name completion.
4578
4579 This is necessary, because Tramp uses a heuristic depending on last
4580 input event. This fails when external packages use other characters
4581 but <TAB>, <SPACE> or ?\\? for file name completion. This variable
4582 should never be set globally, the intention is to let-bind it.")
4559 4583
4560 ;; Necessary because `tramp-file-name-regexp-unified' and 4584 ;; Necessary because `tramp-file-name-regexp-unified' and
4561 ;; `tramp-completion-file-name-regexp-unified' aren't different. If 4585 ;; `tramp-completion-file-name-regexp-unified' aren't different. If
4562 ;; nil, `tramp-completion-run-real-handler' is called (i.e. forwarding 4586 ;; nil, `tramp-completion-run-real-handler' is called (i.e. forwarding
4563 ;; to `tramp-file-name-handler'). Otherwise, it takes 4587 ;; to `tramp-file-name-handler'). Otherwise, it takes
4569 ;; overwriting this check in such cases. Or we change tramp file name 4593 ;; overwriting this check in such cases. Or we change tramp file name
4570 ;; syntax in order to avoid ambiguities, like in XEmacs ... 4594 ;; syntax in order to avoid ambiguities, like in XEmacs ...
4571 (defun tramp-completion-mode-p () 4595 (defun tramp-completion-mode-p ()
4572 "Checks whether method / user name / host name completion is active." 4596 "Checks whether method / user name / host name completion is active."
4573 (or 4597 (or
4574 ;; Emacs 4598 ;; Signal from outside.
4599 tramp-completion-mode
4600 ;; Emacs.
4575 (equal last-input-event 'tab) 4601 (equal last-input-event 'tab)
4576 (and (natnump last-input-event) 4602 (and (natnump last-input-event)
4577 (or 4603 (or
4578 ;; ?\t has event-modifier 'control 4604 ;; ?\t has event-modifier 'control.
4579 (char-equal last-input-event ?\t) 4605 (char-equal last-input-event ?\t)
4580 (and (not (event-modifiers last-input-event)) 4606 (and (not (event-modifiers last-input-event))
4581 (or (char-equal last-input-event ?\?) 4607 (or (char-equal last-input-event ?\?)
4582 (char-equal last-input-event ?\ ))))) 4608 (char-equal last-input-event ?\ )))))
4583 ;; XEmacs 4609 ;; XEmacs.
4584 (and (featurep 'xemacs) 4610 (and (featurep 'xemacs)
4585 ;; `last-input-event' might be nil. 4611 ;; `last-input-event' might be nil.
4586 (not (null last-input-event)) 4612 (not (null last-input-event))
4587 ;; `last-input-event' may have no character approximation. 4613 ;; `last-input-event' may have no character approximation.
4588 (funcall (symbol-function 'event-to-character) last-input-event) 4614 (funcall (symbol-function 'event-to-character) last-input-event)
4589 (or 4615 (or
4590 ;; ?\t has event-modifier 'control 4616 ;; ?\t has event-modifier 'control.
4591 (char-equal 4617 (char-equal
4592 (funcall (symbol-function 'event-to-character) 4618 (funcall (symbol-function 'event-to-character)
4593 last-input-event) ?\t) 4619 last-input-event) ?\t)
4594 (and (not (event-modifiers last-input-event)) 4620 (and (not (event-modifiers last-input-event))
4595 (or (char-equal 4621 (or (char-equal
6149 (setq 6175 (setq
6150 l-host (or l-host "") 6176 l-host (or l-host "")
6151 l-user (or l-user "") 6177 l-user (or l-user "")
6152 l-port (or l-port "") 6178 l-port (or l-port "")
6153 spec `((?h . ,l-host) (?u . ,l-user) (?p . ,l-port) 6179 spec `((?h . ,l-host) (?u . ,l-user) (?p . ,l-port)
6154 (?t . ,(tramp-make-tramp-temp-file vec))) 6180 (?t . ,(tramp-make-tramp-temp-file vec 'dont-create)))
6155 command 6181 command
6156 (concat 6182 (concat
6157 command " " 6183 command " "
6158 (mapconcat 6184 (mapconcat
6159 '(lambda (x) 6185 '(lambda (x)
7465 (condition-case nil 7491 (condition-case nil
7466 (unload-feature 'tramp 'force) 7492 (unload-feature 'tramp 'force)
7467 (error nil))) 7493 (error nil)))
7468 7494
7469 (provide 'tramp) 7495 (provide 'tramp)
7470
7471 ;; Make sure that we get integration with the VC package.
7472 ;; When it is loaded, we need to pull in the integration module.
7473 ;; This must come after (provide 'tramp) because tramp-vc.el
7474 ;; requires tramp. Not necessary in Emacs 23.
7475 (eval-after-load "vc"
7476 '(unless (functionp 'start-file-process)
7477 (require 'tramp-vc)
7478 (add-hook 'tramp-unload-hook
7479 '(lambda ()
7480 (when (featurep 'tramp-vc)
7481 (unload-feature 'tramp-vc 'force))))))
7482 7496
7483 ;;; TODO: 7497 ;;; TODO:
7484 7498
7485 ;; * Allow putting passwords in the filename. 7499 ;; * Allow putting passwords in the filename.
7486 ;; This should be implemented via a general mechanism to add 7500 ;; This should be implemented via a general mechanism to add