Mercurial > emacs
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 |