From: Michael Albinus Date: Thu, 4 Oct 2007 20:09:32 +0000 (+0000) Subject: * net/tramp.el (tramp-make-temp-file): Move to tramp-compat.el. X-Git-Tag: emacs-pretest-23.0.90~10524 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=258800f85f19157263bfdbb96c526f108009364c;p=emacs.git * net/tramp.el (tramp-make-temp-file): Move to tramp-compat.el. (tramp-do-copy-or-rename-file-directly): Handle tmpfile only in the cond clauses where needed. (tramp-handle-write-region): Rearrange code for proper handling of tmpfile. * net/tramp-compat.el (tramp-compat-make-temp-file): New defsubst. * net/tramp.el: * net/tramp-fish.el: * net/tramp-ftp.el: * net/tramp-smb.el: Rename `tramp-make-temp-file' to `tramp-compat-make-temp-file'. --- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 0b3adf28023..4abf79b3457 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,19 @@ +2007-10-04 Michael Albinus + + * net/tramp.el (tramp-make-temp-file): Move to tramp-compat.el. + (tramp-do-copy-or-rename-file-directly): Handle tmpfile only in + the cond clauses where needed. + (tramp-handle-write-region): Rearrange code for proper handling of + tmpfile. + + * net/tramp-compat.el (tramp-compat-make-temp-file): New defsubst. + + * net/tramp.el: + * net/tramp-fish.el: + * net/tramp-ftp.el: + * net/tramp-smb.el: Rename `tramp-make-temp-file' to + `tramp-compat-make-temp-file'. + 2007-10-04 Juanma Barranquero * image-dired.el (image-dired-image-at-point-p): Fix typo in docstring. diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el index 620384eaf38..9808888399f 100644 --- a/lisp/net/tramp-compat.el +++ b/lisp/net/tramp-compat.el @@ -117,6 +117,42 @@ this is the function `temp-directory'." "`temp-directory' is defined -- using /tmp.")) (file-name-as-directory "/tmp")))) +;; `make-temp-file' exists in Emacs only. The third parameter SUFFIX +;; has been introduced with Emacs 22. We try it, if it fails, we fall +;; back to `make-temp-name', creating the temporary file immediately +;; in order to avoid a security hole. +(defsubst tramp-compat-make-temp-file (filename) + "Create a temporary file (compat function). +Add the extension of FILENAME, if existing." + (let ((prefix (expand-file-name + (symbol-value 'tramp-temp-name-prefix) + (tramp-compat-temporary-file-directory))) + (extension (file-name-extension filename t)) + result) + (condition-case nil + (setq result + (funcall (symbol-function 'make-temp-file) prefix nil extension)) + (error + ;; We use our own implementation, taken from files.el. + (while + (condition-case () + (progn + (setq result (concat (make-temp-name prefix) extension)) + (write-region + "" nil result nil 'silent nil + ;; 7th parameter is MUSTBENEW in Emacs, and + ;; CODING-SYSTEM in XEmacs. It is not a security + ;; hole in XEmacs if we cannot use this parameter, + ;; because XEmacs uses a user-specific subdirectory + ;; with 0700 permissions. + (when (not (featurep 'xemacs)) 'excl)) + nil) + (file-already-exists t)) + ;; The file was somehow created by someone else between + ;; `make-temp-name' and `write-region', let's try again. + nil))) + result)) + ;; `most-positive-fixnum' arrived in Emacs 22. Before, and in XEmacs, ;; it is a fixed value. (defsubst tramp-compat-most-positive-fixnum () diff --git a/lisp/net/tramp-fish.el b/lisp/net/tramp-fish.el index 8ae6af76d6b..055d6c9f5e2 100644 --- a/lisp/net/tramp-fish.el +++ b/lisp/net/tramp-fish.el @@ -475,7 +475,7 @@ pass to the OPERATION." (tramp-error v 'file-error "Cannot make local copy of non-existing file `%s'" filename)) - (let ((tmpfile (tramp-make-temp-file filename))) + (let ((tmpfile (tramp-compat-make-temp-file filename))) (tramp-message v 4 "Fetching %s to tmp file %s..." filename tmpfile) (when (tramp-fish-retrieve-data v) ;; Save file diff --git a/lisp/net/tramp-ftp.el b/lisp/net/tramp-ftp.el index cf98ecba7d5..85416d308d3 100644 --- a/lisp/net/tramp-ftp.el +++ b/lisp/net/tramp-ftp.el @@ -158,7 +158,7 @@ pass to the OPERATION." (not (tramp-ftp-file-name-p (cadr args)))) (let* ((filename (car args)) (newname (cadr args)) - (tmpfile (tramp-make-temp-file filename)) + (tmpfile (tramp-compat-make-temp-file filename)) (args (cddr args))) (apply operation filename tmpfile args) (rename-file tmpfile newname (car args)))) diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 6cbe4dbd61d..b4e68c77624 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -371,7 +371,7 @@ KEEP-DATE is not handled in case NEWNAME resides on an SMB server." "Like `file-local-copy' for Tramp files." (with-parsed-tramp-file-name filename nil (let ((file (tramp-smb-get-localname localname t)) - (tmpfile (tramp-make-temp-file filename))) + (tmpfile (tramp-compat-make-temp-file filename))) (unless (file-exists-p filename) (tramp-error v 'file-error @@ -587,7 +587,7 @@ Catches errors for shares like \"C$/\", which are common in Microsoft Windows." (tramp-flush-file-property v localname) (let ((file (tramp-smb-get-localname localname t)) (curbuf (current-buffer)) - (tmpfile (tramp-make-temp-file filename))) + (tmpfile (tramp-compat-make-temp-file filename))) ;; We say `no-message' here because we don't want the visited file ;; modtime data to be clobbered from the temp file. We call ;; `set-visited-file-modtime' ourselves later on. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index fcd18a2387c..b9689eba201 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -1974,13 +1974,6 @@ 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-temp-file (filename) - (concat - (make-temp-name - (expand-file-name - tramp-temp-name-prefix (tramp-compat-temporary-file-directory))) - (file-name-extension filename t))) - (defsubst tramp-make-tramp-temp-file (vec) (format "/tmp/%s%s" @@ -3071,8 +3064,7 @@ the uid and gid from FILENAME." (if t1 (tramp-handle-file-remote-p filename 'localname) filename)) (localname2 (if t2 (tramp-handle-file-remote-p newname 'localname) newname)) - (prefix (file-remote-p (if t1 filename newname))) - (tmpfile (tramp-make-temp-file localname1))) + (prefix (file-remote-p (if t1 filename newname)))) (cond ;; Both files are on a remote host, with same user. @@ -3124,40 +3116,41 @@ the uid and gid from FILENAME." ;; We need a temporary file in between. (t ;; Create the temporary file. - (cond - (t1 - (tramp-send-command - v (format - "%s %s %s" cmd - (tramp-shell-quote-argument localname1) - (tramp-shell-quote-argument tmpfile))) - ;; We must change the ownership as remote user. - (tramp-set-file-uid-gid - (concat prefix tmpfile) - (tramp-get-local-uid 'integer) - (tramp-get-local-gid 'integer))) - (t2 - (if (eq op 'copy) - (tramp-compat-copy-file - localname1 tmpfile ok-if-already-exists - keep-date preserve-uid-gid) - (rename-file localname1 tmpfile ok-if-already-exists)) - ;; We must change the ownership as local user. - (tramp-set-file-uid-gid - tmpfile - (tramp-get-remote-uid v 'integer) - (tramp-get-remote-gid v 'integer)))) - - ;; Move the temporary file to its destination. - (cond - (t2 - (tramp-send-command - v (format - "mv -f %s %s" - (tramp-shell-quote-argument tmpfile) - (tramp-shell-quote-argument localname2)))) - (t1 - (rename-file tmpfile localname2 ok-if-already-exists)))))))) + (let ((tmpfile (tramp-compat-make-temp-file localname1))) + (cond + (t1 + (tramp-send-command + v (format + "%s %s %s" cmd + (tramp-shell-quote-argument localname1) + (tramp-shell-quote-argument tmpfile))) + ;; We must change the ownership as remote user. + (tramp-set-file-uid-gid + (concat prefix tmpfile) + (tramp-get-local-uid 'integer) + (tramp-get-local-gid 'integer))) + (t2 + (if (eq op 'copy) + (tramp-compat-copy-file + localname1 tmpfile ok-if-already-exists + keep-date preserve-uid-gid) + (rename-file localname1 tmpfile ok-if-already-exists)) + ;; We must change the ownership as local user. + (tramp-set-file-uid-gid + tmpfile + (tramp-get-remote-uid v 'integer) + (tramp-get-remote-gid v 'integer)))) + + ;; Move the temporary file to its destination. + (cond + (t2 + (tramp-send-command + v (format + "mv -f %s %s" + (tramp-shell-quote-argument tmpfile) + (tramp-shell-quote-argument localname2)))) + (t1 + (rename-file tmpfile localname2 ok-if-already-exists))))))))) ;; Set the time and mode. Mask possible errors. ;; Won't be applied for 'rename. @@ -3736,7 +3729,7 @@ beginning of local filename are not substituted." (defun tramp-handle-call-process-region (start end program &optional delete buffer display &rest args) "Like `call-process-region' for Tramp files." - (let ((tmpfile (tramp-make-temp-file ""))) + (let ((tmpfile (tramp-compat-make-temp-file ""))) (write-region start end tmpfile) (when delete (delete-region start end)) (unwind-protect @@ -3798,7 +3791,7 @@ beginning of local filename are not substituted." (with-parsed-tramp-file-name filename nil (let ((rem-enc (tramp-get-remote-coding v "remote-encoding")) (loc-dec (tramp-get-local-coding v "local-decoding")) - (tmpfile (tramp-make-temp-file filename))) + (tmpfile (tramp-compat-make-temp-file filename))) (unless (file-exists-p filename) (tramp-error v 'file-error @@ -3837,7 +3830,7 @@ beginning of local filename are not substituted." (write-region (point-min) (point-max) tmpfile)))) ;; If tramp-decoding-function is not defined for this ;; method, we invoke tramp-decoding-command instead. - (let ((tmpfile2 (tramp-make-temp-file filename))) + (let ((tmpfile2 (tramp-compat-make-temp-file filename))) (let ((coding-system-for-write 'binary)) (write-region (point-min) (point-max) tmpfile2)) (tramp-message @@ -4055,28 +4048,28 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file." (unless (y-or-n-p (format "File %s exists; overwrite anyway? " filename)) (tramp-error v 'file-error "File not overwritten"))) - (let ((rem-dec (tramp-get-remote-coding v "remote-decoding")) - (loc-enc (tramp-get-local-coding v "local-encoding")) - (modes (save-excursion (file-modes filename))) - ;; We use this to save the value of `last-coding-system-used' - ;; after writing the tmp file. At the end of the function, - ;; we set `last-coding-system-used' to this saved value. - ;; This way, any intermediary coding systems used while - ;; talking to the remote shell or suchlike won't hose this - ;; variable. This approach was snarfed from ange-ftp.el. - coding-system-used - ;; Write region into a tmp file. This isn't really needed if we - ;; use an encoding function, but currently we use it always - ;; because this makes the logic simpler. - (tmpfile (tramp-make-temp-file filename))) - - (if (and (tramp-local-host-p v) - (file-writable-p (file-name-directory localname))) - ;; Short track: if we are on the local host, we can run directly. - (if confirm - (write-region - start end localname append 'no-message lockname confirm) - (write-region start end localname append 'no-message lockname)) + (if (and (tramp-local-host-p v) + (file-writable-p (file-name-directory localname))) + ;; Short track: if we are on the local host, we can run directly. + (if confirm + (write-region + start end localname append 'no-message lockname confirm) + (write-region start end localname append 'no-message lockname)) + + (let ((rem-dec (tramp-get-remote-coding v "remote-decoding")) + (loc-enc (tramp-get-local-coding v "local-encoding")) + (modes (save-excursion (file-modes filename))) + ;; We use this to save the value of `last-coding-system-used' + ;; after writing the tmp file. At the end of the function, + ;; we set `last-coding-system-used' to this saved value. + ;; This way, any intermediary coding systems used while + ;; talking to the remote shell or suchlike won't hose this + ;; variable. This approach was snarfed from ange-ftp.el. + coding-system-used + ;; Write region into a tmp file. This isn't really needed if we + ;; use an encoding function, but currently we use it always + ;; because this makes the logic simpler. + (tmpfile (tramp-compat-make-temp-file filename))) ;; We say `no-message' here because we don't want the visited file ;; modtime data to be clobbered from the temp file. We call @@ -4201,8 +4194,13 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file." v 'file-error (concat "Method `%s' should specify both encoding and " "decoding command or an rcp program") - method)))) + method))) + + ;; Make `last-coding-system-used' have the right value. + (when coding-system-used + (set 'last-coding-system-used coding-system-used))) + ;; Set file modification time. (when (or (eq visit t) (stringp visit)) (set-visited-file-modtime ;; We must pass modtime explicitely, because filename can be different @@ -4210,9 +4208,6 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file." (nth 5 (file-attributes filename)))) ;; Set the ownership. (tramp-set-file-uid-gid filename) - ;; Make `last-coding-system-used' have the right value. - (when coding-system-used - (set 'last-coding-system-used coding-system-used)) (when (or (eq visit t) (null visit) (stringp visit)) (tramp-message v 0 "Wrote %s" filename)) (run-hooks 'tramp-handle-write-region-hook)))) @@ -7558,12 +7553,6 @@ please ensure that the buffers are attached to your email.\n\n") ;; * When editing a remote CVS controlled file as a different user, VC ;; gets confused about the file locking status. Try to find out why ;; the workaround doesn't work. -;; * Change `copy-file' to grok the case where the filename handler -;; for the source and the target file are different. Right now, -;; it looks at the source file and then calls that handler, if -;; there is one. But since ange-ftp, for instance, does not know -;; about Tramp, it does not do the right thing if the target file -;; name is a Tramp name. ;; * Username and hostname completion. ;; ** Try to avoid usage of `last-input-event' in `tramp-completion-mode-p'. ;; ** Unify `tramp-parse-{rhosts,shosts,sconfig,hosts,passwd,netrc}'.