Mercurial > emacs
changeset 104097:0e24538056bf
* net/tramp.el (tramp-do-copy-or-rename-file): Add messages.
Simplify check for out-of-band methods.
(tramp-do-copy-or-rename-file-out-of-band): Allow both files to be
remote. Remove messages which are in `tramp-do-copy-or-rename-file'.
author | Michael Albinus <michael.albinus@gmx.de> |
---|---|
date | Tue, 28 Jul 2009 20:34:32 +0000 |
parents | ffb9ddb9ba16 |
children | 0f8325f90fb0 |
files | lisp/net/tramp.el |
diffstat | 1 files changed, 115 insertions(+), 102 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/net/tramp.el Tue Jul 28 15:27:44 2009 +0000 +++ b/lisp/net/tramp.el Tue Jul 28 20:34:32 2009 +0000 @@ -3118,6 +3118,9 @@ (tramp-error v 'file-already-exists "File %s already exists" newname))) + (with-parsed-tramp-file-name (if t1 filename newname) nil + (tramp-message v 0 "Transferring %s to %s..." filename newname)) + (prog1 (cond ;; Both are Tramp files. @@ -3133,13 +3136,8 @@ op filename newname ok-if-already-exists keep-date preserve-uid-gid)) - ;; If both source and target are Tramp files, - ;; both are using the same copy-program, then we - ;; can invoke rcp directly. Note that - ;; default-directory should point to a local - ;; directory if we want to invoke rcp. - ((and (equal v1-method v2-method) - (tramp-method-out-of-band-p v1) + ;; Try out-of-band operation. + ((and (tramp-method-out-of-band-p v1) (> (nth 7 (file-attributes filename)) tramp-copy-size-limit)) (tramp-do-copy-or-rename-file-out-of-band @@ -3192,7 +3190,10 @@ ;; When newname did exist, we have wrong cached values. (when t2 (with-parsed-tramp-file-name newname nil - (tramp-flush-file-property v localname)))))) + (tramp-flush-file-property v localname))) + + (with-parsed-tramp-file-name (if t1 filename newname) nil + (tramp-message v 0 "Transferring %s to %s...done" filename newname))))) (defun tramp-do-copy-or-rename-file-via-buffer (op filename newname keep-date) "Use an Emacs buffer to copy or rename a file. @@ -3376,106 +3377,117 @@ (defun tramp-do-copy-or-rename-file-out-of-band (op filename newname keep-date) "Invoke rcp program to copy. -One of FILENAME and NEWNAME must be a Tramp name, the other must -be a local filename. The method used must be an out-of-band method." +The method used must be an out-of-band method." (let ((t1 (tramp-tramp-file-p filename)) (t2 (tramp-tramp-file-p newname)) copy-program copy-args copy-keep-date port spec source target) (with-parsed-tramp-file-name (if t1 filename newname) nil - - ;; Expand hops. Might be necessary for gateway methods. - (setq v (car (tramp-compute-multi-hops v))) - (aset v 3 localname) - - ;; Check which ones of source and target are Tramp files. - (setq source (if t1 (tramp-make-copy-program-file-name v) filename) - target (if t2 (tramp-make-copy-program-file-name v) newname)) - - ;; Check for port number. Until now, there's no need for handling - ;; like method, user, host. - (setq host (tramp-file-name-real-host v) - port (tramp-file-name-port v) - port (or (and port (number-to-string port)) "")) - - ;; Compose copy command. - (setq spec `((?h . ,host) (?u . ,user) (?p . ,port) - (?t . ,(tramp-get-connection-property - (tramp-get-connection-process v) "temp-file" "")) - (?k . ,(if keep-date " " ""))) - copy-program (tramp-get-method-parameter - method 'tramp-copy-program) - copy-keep-date (tramp-get-method-parameter - method 'tramp-copy-keep-date) - copy-args - (delq - nil - (mapcar - '(lambda (x) - (setq - ;; " " is indication for keep-date argument. - x (delete " " (mapcar '(lambda (y) (format-spec y spec)) x))) - (unless (member "" x) (mapconcat 'identity x " "))) - (tramp-get-method-parameter method 'tramp-copy-args)))) - - ;; Check for program. - (when (and (fboundp 'executable-find) - (not (let ((default-directory - (tramp-compat-temporary-file-directory))) - (executable-find copy-program)))) - (tramp-error - v 'file-error "Cannot find copy program: %s" copy-program)) - - (tramp-message v 0 "Transferring %s to %s..." filename newname) - - (unwind-protect - (with-temp-buffer - ;; The default directory must be remote. - (let ((default-directory - (file-name-directory (if t1 filename newname)))) - ;; Set the transfer process properties. - (tramp-set-connection-property - v "process-name" (buffer-name (current-buffer))) - (tramp-set-connection-property - v "process-buffer" (current-buffer)) - - ;; Use an asynchronous process. By this, password can - ;; be handled. The default directory must be local, in - ;; order to apply the correct `copy-program'. We don't - ;; set a timeout, because the copying of large files can - ;; last longer than 60 secs. - (let ((p (let ((default-directory - (tramp-compat-temporary-file-directory))) - (apply 'start-process - (tramp-get-connection-property - v "process-name" nil) - (tramp-get-connection-property - v "process-buffer" nil) - copy-program - (append copy-args (list source target)))))) - (tramp-message - v 6 "%s" (mapconcat 'identity (process-command p) " ")) - (tramp-set-process-query-on-exit-flag p nil) - (tramp-process-actions p v tramp-actions-copy-out-of-band)))) - - ;; Reset the transfer process properties. - (tramp-set-connection-property v "process-name" nil) - (tramp-set-connection-property v "process-buffer" nil)) - - (tramp-message v 0 "Transferring %s to %s...done" filename newname) - - ;; Handle KEEP-DATE argument. - (when (and keep-date (not copy-keep-date)) - (set-file-times newname (nth 5 (file-attributes filename)))) - - ;; Set the mode. - (unless (and keep-date copy-keep-date) - (set-file-modes newname (tramp-default-file-modes filename)))) - - ;; If the operation was `rename', delete the original file. - (unless (eq op 'copy) - (delete-file filename)))) + (if (and t1 t2) + + ;; Both are Tramp files. We shall optimize it, when the + ;; methods for filename and newname are the same. + (let ((tmpfile (tramp-compat-make-temp-file localname))) + (unwind-protect + (progn + (tramp-do-copy-or-rename-file-out-of-band + op filename tmpfile keep-date) + (tramp-do-copy-or-rename-file-out-of-band + 'rename tmpfile newname keep-date)) + ;; Save exit. + (condition-case nil + (delete-file tmpfile) + (error)))) + + ;; Expand hops. Might be necessary for gateway methods. + (setq v (car (tramp-compute-multi-hops v))) + (aset v 3 localname) + + ;; Check which ones of source and target are Tramp files. + (setq source (if t1 (tramp-make-copy-program-file-name v) filename) + target (if t2 (tramp-make-copy-program-file-name v) newname)) + + ;; Check for port number. Until now, there's no need for handling + ;; like method, user, host. + (setq host (tramp-file-name-real-host v) + port (tramp-file-name-port v) + port (or (and port (number-to-string port)) "")) + + ;; Compose copy command. + (setq spec `((?h . ,host) (?u . ,user) (?p . ,port) + (?t . ,(tramp-get-connection-property + (tramp-get-connection-process v) "temp-file" "")) + (?k . ,(if keep-date " " ""))) + copy-program (tramp-get-method-parameter + method 'tramp-copy-program) + copy-keep-date (tramp-get-method-parameter + method 'tramp-copy-keep-date) + copy-args + (delq + nil + (mapcar + '(lambda (x) + (setq + x + ;; " " is indication for keep-date argument. + (delete " " (mapcar '(lambda (y) (format-spec y spec)) x))) + (unless (member "" x) (mapconcat 'identity x " "))) + (tramp-get-method-parameter method 'tramp-copy-args)))) + + ;; Check for program. + (when (and (fboundp 'executable-find) + (not (let ((default-directory + (tramp-compat-temporary-file-directory))) + (executable-find copy-program)))) + (tramp-error + v 'file-error "Cannot find copy program: %s" copy-program)) + + (unwind-protect + (with-temp-buffer + ;; The default directory must be remote. + (let ((default-directory + (file-name-directory (if t1 filename newname)))) + ;; Set the transfer process properties. + (tramp-set-connection-property + v "process-name" (buffer-name (current-buffer))) + (tramp-set-connection-property + v "process-buffer" (current-buffer)) + + ;; Use an asynchronous process. By this, password can + ;; be handled. The default directory must be local, in + ;; order to apply the correct `copy-program'. We don't + ;; set a timeout, because the copying of large files can + ;; last longer than 60 secs. + (let ((p (let ((default-directory + (tramp-compat-temporary-file-directory))) + (apply 'start-process + (tramp-get-connection-property + v "process-name" nil) + (tramp-get-connection-property + v "process-buffer" nil) + copy-program + (append copy-args (list source target)))))) + (tramp-message + v 6 "%s" (mapconcat 'identity (process-command p) " ")) + (tramp-set-process-query-on-exit-flag p nil) + (tramp-process-actions p v tramp-actions-copy-out-of-band)))) + + ;; Reset the transfer process properties. + (tramp-set-connection-property v "process-name" nil) + (tramp-set-connection-property v "process-buffer" nil)) + + ;; Handle KEEP-DATE argument. + (when (and keep-date (not copy-keep-date)) + (set-file-times newname (nth 5 (file-attributes filename)))) + + ;; Set the mode. + (unless (and keep-date copy-keep-date) + (set-file-modes newname (tramp-default-file-modes filename)))) + + ;; If the operation was `rename', delete the original file. + (unless (eq op 'copy) + (delete-file filename))))) (defun tramp-handle-make-directory (dir &optional parents) "Like `make-directory' for Tramp files." @@ -7855,6 +7867,7 @@ ;; tramp-server-local-variable-alist) to define any such variables ;; that they need to, which would then be let bound as appropriate ;; in tramp functions. (Jason Rumney) +;; * Optimize out-of-band copying, when both methods are scp-like. ;; Functions for file-name-handler-alist: ;; diff-latest-backup-file -- in diff.el