From: Michael Albinus Date: Sat, 6 Oct 2007 12:00:42 +0000 (+0000) Subject: * net/tramp.el (top): Move loading of tramp-util.el and X-Git-Tag: emacs-pretest-23.0.90~10507 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=a6e9632782dec4435e8b85a7a262443d62d6e2cc;p=emacs.git * 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. --- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 9a6b052042f..21df22350de 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,21 @@ +2007-10-06 Michael Albinus + + * 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. + 2007-10-06 Eric S. Raymond * vc.el: workfile version -> focus version change. Port various diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el index 9808888399f..19d25f43515 100644 --- a/lisp/net/tramp-compat.el +++ b/lisp/net/tramp-compat.el @@ -40,6 +40,32 @@ (require 'timer-funcs) (require 'timer)) + ;; tramp-util offers integration into other (X)Emacs packages like + ;; compile.el, gud.el etc. Not necessary in Emacs 23. + (eval-after-load "tramp" + ;; We check whether `start-file-process' is an alias. + '(when (or (not (fboundp 'start-file-process)) + (symbolp (symbol-function 'start-file-process))) + (require 'tramp-util) + (add-hook 'tramp-unload-hook + '(lambda () + (when (featurep 'tramp-util) + (unload-feature 'tramp-util 'force)))))) + + ;; Make sure that we get integration with the VC package. When it + ;; is loaded, we need to pull in the integration module. Not + ;; necessary in Emacs 23. + (eval-after-load "vc" + (eval-after-load "tramp" + ;; We check whether `start-file-process' is an alias. + '(when (or (not (fboundp 'start-file-process)) + (symbolp (symbol-function 'start-file-process))) + (require 'tramp-vc) + (add-hook 'tramp-unload-hook + '(lambda () + (when (featurep 'tramp-vc) + (unload-feature 'tramp-vc 'force))))))) + ;; Avoid byte-compiler warnings if the byte-compiler supports this. ;; Currently, XEmacs supports this. (when (featurep 'xemacs) diff --git a/lisp/net/tramp-fish.el b/lisp/net/tramp-fish.el index 055d6c9f5e2..7116d144061 100644 --- a/lisp/net/tramp-fish.el +++ b/lisp/net/tramp-fish.el @@ -734,8 +734,8 @@ target of the symlink differ." (error "Implementation does not handle immediate return")) (with-parsed-tramp-file-name default-directory nil - (let ((temp-name-prefix (tramp-make-tramp-temp-file v)) - command input output stderr outbuf tmpfile ret) + (let (command input tmpinput output tmpoutput stderr tmpstderr + outbuf tmpfile ret) ;; Compute command. (setq command (mapconcat 'tramp-shell-quote-argument (cons program args) " ")) @@ -747,15 +747,14 @@ target of the symlink differ." ;; INFILE is on the same remote host. (setq input (with-parsed-tramp-file-name infile nil localname)) ;; INFILE must be copied to remote host. - (setq input (concat temp-name-prefix ".in")) - (copy-file - infile - (tramp-make-tramp-file-name method user host input) - t))) + (setq input (tramp-make-tramp-temp-file v) + tmpinput (tramp-make-tramp-file-name method user host input)) + (copy-file infile tmpinput t))) (when input (setq command (format "%s <%s" command input))) ;; Determine output. - (setq output (concat temp-name-prefix ".out")) + (setq output (tramp-make-tramp-temp-file v) + tmpoutput (tramp-make-tramp-file-name method user host output)) (cond ;; Just a buffer ((bufferp destination) @@ -781,7 +780,9 @@ target of the symlink differ." (cadr destination) nil localname)) ;; stderr must be copied to remote host. The temporary ;; file must be deleted after execution. - (setq stderr (concat temp-name-prefix ".err")))) + (setq stderr (tramp-make-tramp-temp-file v) + tmpstderr (tramp-make-tramp-file-name + method user host stderr)))) ;; stderr to be discarded ((null (cadr destination)) (setq stderr "/dev/null")))) @@ -790,9 +791,6 @@ target of the symlink differ." (setq outbuf (current-buffer)))) (when stderr (setq command (format "%s 2>%s" command stderr))) - ;; If we have a temporary file, it must be removed after operation. - (when (and input (string-match temp-name-prefix input)) - (setq command (format "%s; rm %s" command input))) ;; Goto working directory. (unless (tramp-fish-send-command-and-check @@ -821,16 +819,15 @@ target of the symlink differ." ;; We should show the output anyway. (when outbuf (with-current-buffer outbuf (insert-file-contents tmpfile)) - (when display (display-buffer outbuf))) - ;; Remove output file. - (delete-file (tramp-make-tramp-file-name method user host output))) + (when display (display-buffer outbuf)))) ;; When the user did interrupt, we should do it also. (error (setq ret 1))) - (unless ret - ;; Provide error file. - (when (and stderr (string-match temp-name-prefix stderr)) - (rename-file (tramp-make-tramp-file-name method user host stderr) - (cadr destination) t))) + + ;; Provide error file. + (when tmpstderr (rename-file tmpstderr (cadr destination) t)) + ;; Cleanup. + (when tmpinput (delete-file tmpinput)) + (when tmpoutput (delete-file tmpoutput)) ;; Return exit status. ret))) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index b9689eba201..9a20e9a81c6 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -149,16 +149,7 @@ (add-hook 'tramp-unload-hook '(lambda () (when (featurep 'tramp-gw) - (unload-feature 'tramp-gw 'force))))) - - ;; tramp-util offers integration into other (X)Emacs packages like - ;; compile.el, gud.el etc. Not necessary in Emacs 23. - (unless (functionp 'start-file-process) - (require 'tramp-util) - (add-hook 'tramp-unload-hook - '(lambda () - (when (featurep 'tramp-util) - (unload-feature 'tramp-util 'force))))))) + (unload-feature 'tramp-gw 'force))))))) ;;; User Customizable Internal Variables: @@ -1974,13 +1965,42 @@ The intent is to protect against `obsolete variable' warnings." (put 'tramp-let-maybe 'lisp-indent-function 2) (put 'tramp-let-maybe 'edebug-form-spec t) -(defsubst tramp-make-tramp-temp-file (vec) - (format - "/tmp/%s%s" - tramp-temp-name-prefix - (if (get-buffer-process (tramp-get-connection-buffer vec)) - (process-id (get-buffer-process (tramp-get-connection-buffer vec))) - (emacs-pid)))) +(defsubst tramp-make-tramp-temp-file (vec &optional dont-create) + "Create a temporary file on the remote host identified by VEC. +Return the local name of the temporary file. +If DONT-CREATE is non-nil, just the file name is returned without +creation of the temporary file. This is not the preferred way to run, +but it is necessary during connection setup, because we cannot create +a remote file at this time. This parameter shall NOT be set to +non-nil else." + (if dont-create + ;; It sounds a little bit stupid to create a LOCAL file name. + ;; But we intend to use the remote directory "/tmp", and we have + ;; no chance to check whether a temporary file exists already + ;; remotely, because we have no working connection yet. + (make-temp-name (expand-file-name tramp-temp-name-prefix "/tmp")) + + (let ((prefix + (tramp-make-tramp-file-name + (tramp-file-name-method vec) + (tramp-file-name-user vec) + (tramp-file-name-host vec) + (expand-file-name tramp-temp-name-prefix "/tmp"))) + result) + (while (not result) + ;; `make-temp-file' would be the first choice for + ;; implementation. But it calls `write-region' internally, + ;; which also needs a temporary file - we would end in an + ;; infinite loop. + (setq result (make-temp-name prefix)) + (if (file-exists-p result) + (setq result nil) + ;; This creates the file by side effect. + (set-file-times result) + (set-file-modes result (tramp-octal-to-decimal "0700")))) + + ;; Return the local part. + (with-parsed-tramp-file-name result nil localname)))) ;;; Config Manipulation Functions: @@ -3188,7 +3208,7 @@ be a local filename. The method used must be an out-of-band method." ;; Compose copy command. (setq spec `((?h . ,host) (?u . ,user) (?p . ,port) - (?t . ,(tramp-make-tramp-temp-file v)) + (?t . ,(tramp-make-tramp-temp-file v 'dont-create)) (?k . ,(if keep-date " " ""))) copy-program (tramp-get-method-parameter method 'tramp-copy-program) @@ -3639,8 +3659,7 @@ beginning of local filename are not substituted." (error "Implementation does not handle immediate return")) (with-parsed-tramp-file-name default-directory nil - (let ((temp-name-prefix (tramp-make-tramp-temp-file v)) - command input stderr outbuf ret) + (let (command input tmpinput stderr tmpstderr outbuf ret) ;; Compute command. (setq command (mapconcat 'tramp-shell-quote-argument (cons program args) " ")) @@ -3652,11 +3671,9 @@ beginning of local filename are not substituted." ;; INFILE is on the same remote host. (setq input (with-parsed-tramp-file-name infile nil localname)) ;; INFILE must be copied to remote host. - (setq input (concat temp-name-prefix ".in")) - (copy-file - infile - (tramp-make-tramp-file-name method user host input) - t))) + (setq input (tramp-make-tramp-temp-file v) + tmpinput (tramp-make-tramp-file-name method user host input)) + (copy-file infile tmpinput t))) (when input (setq command (format "%s <%s" command input))) ;; Determine output. @@ -3685,7 +3702,9 @@ beginning of local filename are not substituted." (cadr destination) nil localname)) ;; stderr must be copied to remote host. The temporary ;; file must be deleted after execution. - (setq stderr (concat temp-name-prefix ".err")))) + (setq stderr (tramp-make-tramp-temp-file v) + tmpstderr (tramp-make-tramp-file-name + method user host stderr)))) ;; stderr to be discarded ((null (cadr destination)) (setq stderr "/dev/null")))) @@ -3694,9 +3713,6 @@ beginning of local filename are not substituted." (setq outbuf (current-buffer)))) (when stderr (setq command (format "%s 2>%s" command stderr))) - ;; If we have a temporary file, it must be removed after operation. - (when (and input (string-match temp-name-prefix input)) - (setq command (format "%s; rm %s" command input))) ;; Goto working directory. (tramp-send-command v (format "cd %s" (tramp-shell-quote-argument localname))) @@ -3716,13 +3732,13 @@ beginning of local filename are not substituted." (error (kill-buffer (tramp-get-connection-buffer v)) (setq ret 1))) - (unless ret - ;; Check return code. - (setq ret (tramp-send-command-and-check v nil)) - ;; Provide error file. - (when (and stderr (string-match temp-name-prefix stderr)) - (rename-file (tramp-make-tramp-file-name method user host stderr) - (cadr destination) t))) + + ;; Check return code. + (unless ret (setq ret (tramp-send-command-and-check v nil))) + ;; Provide error file. + (when tmpstderr (rename-file tmpstderr (cadr destination) t)) + ;; Cleanup. + (when tmpinput (delete-file tmpinput)) ;; Return exit status. ret))) @@ -4555,7 +4571,15 @@ Falls back to normal file name handler if no tramp file name handler exists." (add-hook 'tramp-unload-hook '(lambda () (ad-unadvise 'PC-expand-many-files))))) -;;; File name handler functions for completion mode +;;; File name handler functions for completion mode. + +(defvar tramp-completion-mode nil + "If non-nil, external packages signal that they are in file name completion. + +This is necessary, because Tramp uses a heuristic depending on last +input event. This fails when external packages use other characters +but , or ?\\? for file name completion. This variable +should never be set globally, the intention is to let-bind it.") ;; Necessary because `tramp-file-name-regexp-unified' and ;; `tramp-completion-file-name-regexp-unified' aren't different. If @@ -4571,23 +4595,25 @@ Falls back to normal file name handler if no tramp file name handler exists." (defun tramp-completion-mode-p () "Checks whether method / user name / host name completion is active." (or - ;; Emacs + ;; Signal from outside. + tramp-completion-mode + ;; Emacs. (equal last-input-event 'tab) (and (natnump last-input-event) (or - ;; ?\t has event-modifier 'control + ;; ?\t has event-modifier 'control. (char-equal last-input-event ?\t) (and (not (event-modifiers last-input-event)) (or (char-equal last-input-event ?\?) (char-equal last-input-event ?\ ))))) - ;; XEmacs + ;; XEmacs. (and (featurep 'xemacs) ;; `last-input-event' might be nil. (not (null last-input-event)) ;; `last-input-event' may have no character approximation. (funcall (symbol-function 'event-to-character) last-input-event) (or - ;; ?\t has event-modifier 'control + ;; ?\t has event-modifier 'control. (char-equal (funcall (symbol-function 'event-to-character) last-input-event) ?\t) @@ -6151,7 +6177,7 @@ connection if a previous connection has died for some reason." l-user (or l-user "") l-port (or l-port "") spec `((?h . ,l-host) (?u . ,l-user) (?p . ,l-port) - (?t . ,(tramp-make-tramp-temp-file vec))) + (?t . ,(tramp-make-tramp-temp-file vec 'dont-create))) command (concat command " " @@ -7468,18 +7494,6 @@ please ensure that the buffers are attached to your email.\n\n") (provide 'tramp) -;; Make sure that we get integration with the VC package. -;; When it is loaded, we need to pull in the integration module. -;; This must come after (provide 'tramp) because tramp-vc.el -;; requires tramp. Not necessary in Emacs 23. -(eval-after-load "vc" - '(unless (functionp 'start-file-process) - (require 'tramp-vc) - (add-hook 'tramp-unload-hook - '(lambda () - (when (featurep 'tramp-vc) - (unload-feature 'tramp-vc 'force)))))) - ;;; TODO: ;; * Allow putting passwords in the filename.