1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-17 03:10:58 -08:00

* 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.
This commit is contained in:
Michael Albinus 2007-10-06 12:00:42 +00:00
parent ea3fc256d4
commit a6e9632782
4 changed files with 129 additions and 74 deletions

View file

@ -1,3 +1,21 @@
2007-10-06 Michael Albinus <michael.albinus@gmx.de>
* 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 <esr@snark.thyrsus.com> 2007-10-06 Eric S. Raymond <esr@snark.thyrsus.com>
* vc.el: workfile version -> focus version change. Port various * vc.el: workfile version -> focus version change. Port various

View file

@ -40,6 +40,32 @@
(require 'timer-funcs) (require 'timer-funcs)
(require 'timer)) (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. ;; Avoid byte-compiler warnings if the byte-compiler supports this.
;; Currently, XEmacs supports this. ;; Currently, XEmacs supports this.
(when (featurep 'xemacs) (when (featurep 'xemacs)

View file

@ -734,8 +734,8 @@ target of the symlink differ."
(error "Implementation does not handle immediate return")) (error "Implementation does not handle immediate return"))
(with-parsed-tramp-file-name default-directory nil (with-parsed-tramp-file-name default-directory nil
(let ((temp-name-prefix (tramp-make-tramp-temp-file v)) (let (command input tmpinput output tmpoutput stderr tmpstderr
command input output stderr outbuf tmpfile ret) outbuf tmpfile ret)
;; Compute command. ;; Compute command.
(setq command (mapconcat 'tramp-shell-quote-argument (setq command (mapconcat 'tramp-shell-quote-argument
(cons program args) " ")) (cons program args) " "))
@ -747,15 +747,14 @@ target of the symlink differ."
;; INFILE is on the same remote host. ;; INFILE is on the same remote host.
(setq input (with-parsed-tramp-file-name infile nil localname)) (setq input (with-parsed-tramp-file-name infile nil localname))
;; INFILE must be copied to remote host. ;; INFILE must be copied to remote host.
(setq input (concat temp-name-prefix ".in")) (setq input (tramp-make-tramp-temp-file v)
(copy-file tmpinput (tramp-make-tramp-file-name method user host input))
infile (copy-file infile tmpinput t)))
(tramp-make-tramp-file-name method user host input)
t)))
(when input (setq command (format "%s <%s" command input))) (when input (setq command (format "%s <%s" command input)))
;; Determine output. ;; 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 (cond
;; Just a buffer ;; Just a buffer
((bufferp destination) ((bufferp destination)
@ -781,7 +780,9 @@ target of the symlink differ."
(cadr destination) nil localname)) (cadr destination) nil localname))
;; stderr must be copied to remote host. The temporary ;; stderr must be copied to remote host. The temporary
;; file must be deleted after execution. ;; 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 ;; stderr to be discarded
((null (cadr destination)) ((null (cadr destination))
(setq stderr "/dev/null")))) (setq stderr "/dev/null"))))
@ -790,9 +791,6 @@ target of the symlink differ."
(setq outbuf (current-buffer)))) (setq outbuf (current-buffer))))
(when stderr (setq command (format "%s 2>%s" command stderr))) (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. ;; Goto working directory.
(unless (unless
(tramp-fish-send-command-and-check (tramp-fish-send-command-and-check
@ -821,16 +819,15 @@ target of the symlink differ."
;; We should show the output anyway. ;; We should show the output anyway.
(when outbuf (when outbuf
(with-current-buffer outbuf (insert-file-contents tmpfile)) (with-current-buffer outbuf (insert-file-contents tmpfile))
(when display (display-buffer outbuf))) (when display (display-buffer outbuf))))
;; Remove output file.
(delete-file (tramp-make-tramp-file-name method user host output)))
;; When the user did interrupt, we should do it also. ;; When the user did interrupt, we should do it also.
(error (setq ret 1))) (error (setq ret 1)))
(unless ret
;; Provide error file. ;; Provide error file.
(when (and stderr (string-match temp-name-prefix stderr)) (when tmpstderr (rename-file tmpstderr (cadr destination) t))
(rename-file (tramp-make-tramp-file-name method user host stderr) ;; Cleanup.
(cadr destination) t))) (when tmpinput (delete-file tmpinput))
(when tmpoutput (delete-file tmpoutput))
;; Return exit status. ;; Return exit status.
ret))) ret)))

View file

@ -149,16 +149,7 @@
(add-hook 'tramp-unload-hook (add-hook 'tramp-unload-hook
'(lambda () '(lambda ()
(when (featurep 'tramp-gw) (when (featurep 'tramp-gw)
(unload-feature 'tramp-gw 'force))))) (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)))))))
;;; User Customizable Internal Variables: ;;; 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 'lisp-indent-function 2)
(put 'tramp-let-maybe 'edebug-form-spec t) (put 'tramp-let-maybe 'edebug-form-spec t)
(defsubst tramp-make-tramp-temp-file (vec) (defsubst tramp-make-tramp-temp-file (vec &optional dont-create)
(format "Create a temporary file on the remote host identified by VEC.
"/tmp/%s%s" Return the local name of the temporary file.
tramp-temp-name-prefix If DONT-CREATE is non-nil, just the file name is returned without
(if (get-buffer-process (tramp-get-connection-buffer vec)) creation of the temporary file. This is not the preferred way to run,
(process-id (get-buffer-process (tramp-get-connection-buffer vec))) but it is necessary during connection setup, because we cannot create
(emacs-pid)))) 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: ;;; Config Manipulation Functions:
@ -3188,7 +3208,7 @@ be a local filename. The method used must be an out-of-band method."
;; Compose copy command. ;; Compose copy command.
(setq spec `((?h . ,host) (?u . ,user) (?p . ,port) (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 " " ""))) (?k . ,(if keep-date " " "")))
copy-program (tramp-get-method-parameter copy-program (tramp-get-method-parameter
method 'tramp-copy-program) method 'tramp-copy-program)
@ -3639,8 +3659,7 @@ beginning of local filename are not substituted."
(error "Implementation does not handle immediate return")) (error "Implementation does not handle immediate return"))
(with-parsed-tramp-file-name default-directory nil (with-parsed-tramp-file-name default-directory nil
(let ((temp-name-prefix (tramp-make-tramp-temp-file v)) (let (command input tmpinput stderr tmpstderr outbuf ret)
command input stderr outbuf ret)
;; Compute command. ;; Compute command.
(setq command (mapconcat 'tramp-shell-quote-argument (setq command (mapconcat 'tramp-shell-quote-argument
(cons program args) " ")) (cons program args) " "))
@ -3652,11 +3671,9 @@ beginning of local filename are not substituted."
;; INFILE is on the same remote host. ;; INFILE is on the same remote host.
(setq input (with-parsed-tramp-file-name infile nil localname)) (setq input (with-parsed-tramp-file-name infile nil localname))
;; INFILE must be copied to remote host. ;; INFILE must be copied to remote host.
(setq input (concat temp-name-prefix ".in")) (setq input (tramp-make-tramp-temp-file v)
(copy-file tmpinput (tramp-make-tramp-file-name method user host input))
infile (copy-file infile tmpinput t)))
(tramp-make-tramp-file-name method user host input)
t)))
(when input (setq command (format "%s <%s" command input))) (when input (setq command (format "%s <%s" command input)))
;; Determine output. ;; Determine output.
@ -3685,7 +3702,9 @@ beginning of local filename are not substituted."
(cadr destination) nil localname)) (cadr destination) nil localname))
;; stderr must be copied to remote host. The temporary ;; stderr must be copied to remote host. The temporary
;; file must be deleted after execution. ;; 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 ;; stderr to be discarded
((null (cadr destination)) ((null (cadr destination))
(setq stderr "/dev/null")))) (setq stderr "/dev/null"))))
@ -3694,9 +3713,6 @@ beginning of local filename are not substituted."
(setq outbuf (current-buffer)))) (setq outbuf (current-buffer))))
(when stderr (setq command (format "%s 2>%s" command stderr))) (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. ;; Goto working directory.
(tramp-send-command (tramp-send-command
v (format "cd %s" (tramp-shell-quote-argument localname))) v (format "cd %s" (tramp-shell-quote-argument localname)))
@ -3716,13 +3732,13 @@ beginning of local filename are not substituted."
(error (error
(kill-buffer (tramp-get-connection-buffer v)) (kill-buffer (tramp-get-connection-buffer v))
(setq ret 1))) (setq ret 1)))
(unless ret
;; Check return code. ;; Check return code.
(setq ret (tramp-send-command-and-check v nil)) (unless ret (setq ret (tramp-send-command-and-check v nil)))
;; Provide error file. ;; Provide error file.
(when (and stderr (string-match temp-name-prefix stderr)) (when tmpstderr (rename-file tmpstderr (cadr destination) t))
(rename-file (tramp-make-tramp-file-name method user host stderr) ;; Cleanup.
(cadr destination) t))) (when tmpinput (delete-file tmpinput))
;; Return exit status. ;; Return exit status.
ret))) ret)))
@ -4555,7 +4571,15 @@ Falls back to normal file name handler if no tramp file name handler exists."
(add-hook 'tramp-unload-hook (add-hook 'tramp-unload-hook
'(lambda () (ad-unadvise 'PC-expand-many-files))))) '(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 <TAB>, <SPACE> 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 ;; Necessary because `tramp-file-name-regexp-unified' and
;; `tramp-completion-file-name-regexp-unified' aren't different. If ;; `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 () (defun tramp-completion-mode-p ()
"Checks whether method / user name / host name completion is active." "Checks whether method / user name / host name completion is active."
(or (or
;; Emacs ;; Signal from outside.
tramp-completion-mode
;; Emacs.
(equal last-input-event 'tab) (equal last-input-event 'tab)
(and (natnump last-input-event) (and (natnump last-input-event)
(or (or
;; ?\t has event-modifier 'control ;; ?\t has event-modifier 'control.
(char-equal last-input-event ?\t) (char-equal last-input-event ?\t)
(and (not (event-modifiers last-input-event)) (and (not (event-modifiers last-input-event))
(or (char-equal last-input-event ?\?) (or (char-equal last-input-event ?\?)
(char-equal last-input-event ?\ ))))) (char-equal last-input-event ?\ )))))
;; XEmacs ;; XEmacs.
(and (featurep 'xemacs) (and (featurep 'xemacs)
;; `last-input-event' might be nil. ;; `last-input-event' might be nil.
(not (null last-input-event)) (not (null last-input-event))
;; `last-input-event' may have no character approximation. ;; `last-input-event' may have no character approximation.
(funcall (symbol-function 'event-to-character) last-input-event) (funcall (symbol-function 'event-to-character) last-input-event)
(or (or
;; ?\t has event-modifier 'control ;; ?\t has event-modifier 'control.
(char-equal (char-equal
(funcall (symbol-function 'event-to-character) (funcall (symbol-function 'event-to-character)
last-input-event) ?\t) last-input-event) ?\t)
@ -6151,7 +6177,7 @@ connection if a previous connection has died for some reason."
l-user (or l-user "") l-user (or l-user "")
l-port (or l-port "") l-port (or l-port "")
spec `((?h . ,l-host) (?u . ,l-user) (?p . ,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 command
(concat (concat
command " " command " "
@ -7468,18 +7494,6 @@ please ensure that the buffers are attached to your email.\n\n")
(provide 'tramp) (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: ;;; TODO:
;; * Allow putting passwords in the filename. ;; * Allow putting passwords in the filename.