diff options
| author | Michael Albinus | 2013-10-28 20:30:40 +0100 |
|---|---|---|
| committer | Michael Albinus | 2013-10-28 20:30:40 +0100 |
| commit | 4efc33f01d0344a52670eb0c0250d5ef40bb7952 (patch) | |
| tree | e01a5db8601a1a291b98b4919faa41a99b3065dc | |
| parent | 5d3311e5bb8fba7a8151cc79d6651488946ac19d (diff) | |
| download | emacs-4efc33f01d0344a52670eb0c0250d5ef40bb7952.tar.gz emacs-4efc33f01d0344a52670eb0c0250d5ef40bb7952.zip | |
* net/tramp-sh.el (tramp-sh-handle-copy-directory):
* net/tramp-smb.el (tramp-smb-handle-copy-directory):
Handle COPY-CONTENTS. (Bug#15737)
| -rw-r--r-- | lisp/ChangeLog | 6 | ||||
| -rw-r--r-- | lisp/net/tramp-sh.el | 13 | ||||
| -rw-r--r-- | lisp/net/tramp-smb.el | 277 |
3 files changed, 158 insertions, 138 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index aac29e86ad6..34ac8ffd5e5 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2013-10-28 Michael Albinus <michael.albinus@gmx.de> | ||
| 2 | |||
| 3 | * net/tramp-sh.el (tramp-sh-handle-copy-directory): | ||
| 4 | * net/tramp-smb.el (tramp-smb-handle-copy-directory): | ||
| 5 | Handle COPY-CONTENTS. (Bug#15737) | ||
| 6 | |||
| 1 | 2013-10-28 Daiki Ueno <ueno@gnu.org> | 7 | 2013-10-28 Daiki Ueno <ueno@gnu.org> |
| 2 | 8 | ||
| 3 | * epa-file.el | 9 | * epa-file.el |
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 147113ba5a1..f69859ddb10 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el | |||
| @@ -1831,18 +1831,20 @@ tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'" | |||
| 1831 | 'copy-file (list filename newname ok-if-already-exists keep-date))))) | 1831 | 'copy-file (list filename newname ok-if-already-exists keep-date))))) |
| 1832 | 1832 | ||
| 1833 | (defun tramp-sh-handle-copy-directory | 1833 | (defun tramp-sh-handle-copy-directory |
| 1834 | (dirname newname &optional keep-date parents _copy-contents) | 1834 | (dirname newname &optional keep-date parents copy-contents) |
| 1835 | "Like `copy-directory' for Tramp files." | 1835 | "Like `copy-directory' for Tramp files." |
| 1836 | (let ((t1 (tramp-tramp-file-p dirname)) | 1836 | (let ((t1 (tramp-tramp-file-p dirname)) |
| 1837 | (t2 (tramp-tramp-file-p newname))) | 1837 | (t2 (tramp-tramp-file-p newname))) |
| 1838 | (with-parsed-tramp-file-name (if t1 dirname newname) nil | 1838 | (with-parsed-tramp-file-name (if t1 dirname newname) nil |
| 1839 | (if (and (tramp-get-method-parameter method 'tramp-copy-recursive) | 1839 | (if (and (not copy-contents) |
| 1840 | (tramp-get-method-parameter method 'tramp-copy-recursive) | ||
| 1840 | ;; When DIRNAME and NEWNAME are remote, they must have | 1841 | ;; When DIRNAME and NEWNAME are remote, they must have |
| 1841 | ;; the same method. | 1842 | ;; the same method. |
| 1842 | (or (null t1) (null t2) | 1843 | (or (null t1) (null t2) |
| 1843 | (string-equal | 1844 | (string-equal |
| 1844 | (tramp-file-name-method (tramp-dissect-file-name dirname)) | 1845 | (tramp-file-name-method (tramp-dissect-file-name dirname)) |
| 1845 | (tramp-file-name-method (tramp-dissect-file-name newname))))) | 1846 | (tramp-file-name-method |
| 1847 | (tramp-dissect-file-name newname))))) | ||
| 1846 | ;; scp or rsync DTRT. | 1848 | ;; scp or rsync DTRT. |
| 1847 | (progn | 1849 | (progn |
| 1848 | (setq dirname (directory-file-name (expand-file-name dirname)) | 1850 | (setq dirname (directory-file-name (expand-file-name dirname)) |
| @@ -1859,7 +1861,10 @@ tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'" | |||
| 1859 | 'copy dirname newname keep-date)) | 1861 | 'copy dirname newname keep-date)) |
| 1860 | ;; We must do it file-wise. | 1862 | ;; We must do it file-wise. |
| 1861 | (tramp-run-real-handler | 1863 | (tramp-run-real-handler |
| 1862 | 'copy-directory (list dirname newname keep-date parents))) | 1864 | 'copy-directory |
| 1865 | (if copy-contents | ||
| 1866 | (list dirname newname keep-date parents copy-contents) | ||
| 1867 | (list dirname newname keep-date parents)))) | ||
| 1863 | 1868 | ||
| 1864 | ;; When newname did exist, we have wrong cached values. | 1869 | ;; When newname did exist, we have wrong cached values. |
| 1865 | (when t2 | 1870 | (when t2 |
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index fe7097edbde..4f294050bb9 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el | |||
| @@ -387,141 +387,150 @@ pass to the OPERATION." | |||
| 387 | (throw 'tramp-action 'ok))))) | 387 | (throw 'tramp-action 'ok))))) |
| 388 | 388 | ||
| 389 | (defun tramp-smb-handle-copy-directory | 389 | (defun tramp-smb-handle-copy-directory |
| 390 | (dirname newname &optional keep-date parents _copy-contents) | 390 | (dirname newname &optional keep-date parents copy-contents) |
| 391 | "Like `copy-directory' for Tramp files." | 391 | "Like `copy-directory' for Tramp files." |
| 392 | (setq dirname (expand-file-name dirname) | 392 | (if copy-contents |
| 393 | newname (expand-file-name newname)) | 393 | ;; We must do it file-wise. |
| 394 | (let ((t1 (tramp-tramp-file-p dirname)) | 394 | (tramp-run-real-handler |
| 395 | (t2 (tramp-tramp-file-p newname))) | 395 | 'copy-directory (list dirname newname keep-date parents copy-contents)) |
| 396 | (with-parsed-tramp-file-name (if t1 dirname newname) nil | 396 | |
| 397 | (with-tramp-progress-reporter | 397 | (setq dirname (expand-file-name dirname) |
| 398 | v 0 (format "Copying %s to %s" dirname newname) | 398 | newname (expand-file-name newname)) |
| 399 | (cond | 399 | (let ((t1 (tramp-tramp-file-p dirname)) |
| 400 | ;; We must use a local temporary directory. | 400 | (t2 (tramp-tramp-file-p newname))) |
| 401 | ((and t1 t2) | 401 | (with-parsed-tramp-file-name (if t1 dirname newname) nil |
| 402 | (let ((tmpdir | 402 | (with-tramp-progress-reporter |
| 403 | (make-temp-name | 403 | v 0 (format "Copying %s to %s" dirname newname) |
| 404 | (expand-file-name | 404 | (cond |
| 405 | tramp-temp-name-prefix | 405 | ;; We must use a local temporary directory. |
| 406 | (tramp-compat-temporary-file-directory))))) | 406 | ((and t1 t2) |
| 407 | (unwind-protect | 407 | (let ((tmpdir |
| 408 | (progn | 408 | (make-temp-name |
| 409 | (tramp-compat-copy-directory dirname tmpdir keep-date parents) | 409 | (expand-file-name |
| 410 | (tramp-compat-copy-directory tmpdir newname keep-date parents)) | 410 | tramp-temp-name-prefix |
| 411 | (tramp-compat-delete-directory tmpdir 'recursive)))) | 411 | (tramp-compat-temporary-file-directory))))) |
| 412 | 412 | (unwind-protect | |
| 413 | ;; We can copy recursively. | 413 | (progn |
| 414 | ((or t1 t2) | 414 | (tramp-compat-copy-directory |
| 415 | (when (and (file-directory-p newname) | 415 | dirname tmpdir keep-date parents) |
| 416 | (not (string-equal (file-name-nondirectory dirname) | 416 | (tramp-compat-copy-directory |
| 417 | (file-name-nondirectory newname)))) | 417 | tmpdir newname keep-date parents)) |
| 418 | (setq newname | 418 | (tramp-compat-delete-directory tmpdir 'recursive)))) |
| 419 | (expand-file-name | 419 | |
| 420 | (file-name-nondirectory dirname) newname)) | 420 | ;; We can copy recursively. |
| 421 | (if t2 (setq v (tramp-dissect-file-name newname)))) | 421 | ((or t1 t2) |
| 422 | (if (not (file-directory-p newname)) | 422 | (when (and (file-directory-p newname) |
| 423 | (make-directory newname parents)) | 423 | (not (string-equal (file-name-nondirectory dirname) |
| 424 | 424 | (file-name-nondirectory newname)))) | |
| 425 | (setq tramp-current-method (tramp-file-name-method v) | 425 | (setq newname |
| 426 | tramp-current-user (tramp-file-name-user v) | 426 | (expand-file-name |
| 427 | tramp-current-host (tramp-file-name-real-host v)) | 427 | (file-name-nondirectory dirname) newname)) |
| 428 | 428 | (if t2 (setq v (tramp-dissect-file-name newname)))) | |
| 429 | (let* ((real-user (tramp-file-name-real-user v)) | 429 | (if (not (file-directory-p newname)) |
| 430 | (real-host (tramp-file-name-real-host v)) | 430 | (make-directory newname parents)) |
| 431 | (domain (tramp-file-name-domain v)) | 431 | |
| 432 | (port (tramp-file-name-port v)) | 432 | (setq tramp-current-method (tramp-file-name-method v) |
| 433 | (share (tramp-smb-get-share v)) | 433 | tramp-current-user (tramp-file-name-user v) |
| 434 | (localname (file-name-as-directory | 434 | tramp-current-host (tramp-file-name-real-host v)) |
| 435 | (tramp-compat-replace-regexp-in-string | 435 | |
| 436 | "\\\\" "/" (tramp-smb-get-localname v)))) | 436 | (let* ((real-user (tramp-file-name-real-user v)) |
| 437 | (tmpdir (make-temp-name | 437 | (real-host (tramp-file-name-real-host v)) |
| 438 | (expand-file-name | 438 | (domain (tramp-file-name-domain v)) |
| 439 | tramp-temp-name-prefix | 439 | (port (tramp-file-name-port v)) |
| 440 | (tramp-compat-temporary-file-directory)))) | 440 | (share (tramp-smb-get-share v)) |
| 441 | (args (list tramp-smb-program | 441 | (localname (file-name-as-directory |
| 442 | (concat "//" real-host "/" share) "-E"))) | 442 | (tramp-compat-replace-regexp-in-string |
| 443 | 443 | "\\\\" "/" (tramp-smb-get-localname v)))) | |
| 444 | (if (not (zerop (length real-user))) | 444 | (tmpdir (make-temp-name |
| 445 | (setq args (append args (list "-U" real-user))) | 445 | (expand-file-name |
| 446 | (setq args (append args (list "-N")))) | 446 | tramp-temp-name-prefix |
| 447 | 447 | (tramp-compat-temporary-file-directory)))) | |
| 448 | (when domain (setq args (append args (list "-W" domain)))) | 448 | (args (list tramp-smb-program |
| 449 | (when port (setq args (append args (list "-p" port)))) | 449 | (concat "//" real-host "/" share) "-E"))) |
| 450 | (when tramp-smb-conf | 450 | |
| 451 | (setq args (append args (list "-s" tramp-smb-conf)))) | 451 | (if (not (zerop (length real-user))) |
| 452 | (setq args | 452 | (setq args (append args (list "-U" real-user))) |
| 453 | (if t1 | 453 | (setq args (append args (list "-N")))) |
| 454 | ;; Source is remote. | 454 | |
| 455 | (append args | 455 | (when domain (setq args (append args (list "-W" domain)))) |
| 456 | (list "-D" (shell-quote-argument localname) | 456 | (when port (setq args (append args (list "-p" port)))) |
| 457 | "-c" (shell-quote-argument "tar qc - *") | 457 | (when tramp-smb-conf |
| 458 | "|" "tar" "xfC" "-" | 458 | (setq args (append args (list "-s" tramp-smb-conf)))) |
| 459 | (shell-quote-argument tmpdir))) | 459 | (setq args |
| 460 | ;; Target is remote. | 460 | (if t1 |
| 461 | (append (list "tar" "cfC" "-" (shell-quote-argument dirname) | 461 | ;; Source is remote. |
| 462 | "." "|") | 462 | (append args |
| 463 | args | 463 | (list "-D" (shell-quote-argument localname) |
| 464 | (list "-D" (shell-quote-argument localname) | 464 | "-c" (shell-quote-argument "tar qc - *") |
| 465 | "-c" (shell-quote-argument "tar qx -"))))) | 465 | "|" "tar" "xfC" "-" |
| 466 | 466 | (shell-quote-argument tmpdir))) | |
| 467 | (unwind-protect | 467 | ;; Target is remote. |
| 468 | (with-temp-buffer | 468 | (append (list "tar" "cfC" "-" |
| 469 | ;; Set the transfer process properties. | 469 | (shell-quote-argument dirname) "." "|") |
| 470 | (tramp-set-connection-property | 470 | args |
| 471 | v "process-name" (buffer-name (current-buffer))) | 471 | (list "-D" (shell-quote-argument localname) |
| 472 | (tramp-set-connection-property | 472 | "-c" (shell-quote-argument "tar qx -"))))) |
| 473 | v "process-buffer" (current-buffer)) | 473 | |
| 474 | 474 | (unwind-protect | |
| 475 | (when t1 | 475 | (with-temp-buffer |
| 476 | ;; The smbclient tar command creates always complete | 476 | ;; Set the transfer process properties. |
| 477 | ;; paths. We must emulate the directory structure, | 477 | (tramp-set-connection-property |
| 478 | ;; and symlink to the real target. | 478 | v "process-name" (buffer-name (current-buffer))) |
| 479 | (make-directory | 479 | (tramp-set-connection-property |
| 480 | (expand-file-name ".." (concat tmpdir localname)) 'parents) | 480 | v "process-buffer" (current-buffer)) |
| 481 | (make-symbolic-link | 481 | |
| 482 | newname (directory-file-name (concat tmpdir localname)))) | 482 | (when t1 |
| 483 | 483 | ;; The smbclient tar command creates always | |
| 484 | ;; Use an asynchronous processes. By this, password | 484 | ;; complete paths. We must emulate the |
| 485 | ;; can be handled. | 485 | ;; directory structure, and symlink to the real |
| 486 | (let* ((default-directory tmpdir) | 486 | ;; target. |
| 487 | (p (start-process-shell-command | 487 | (make-directory |
| 488 | (tramp-get-connection-name v) | 488 | (expand-file-name |
| 489 | (tramp-get-connection-buffer v) | 489 | ".." (concat tmpdir localname)) 'parents) |
| 490 | (mapconcat 'identity args " ")))) | 490 | (make-symbolic-link |
| 491 | 491 | newname (directory-file-name (concat tmpdir localname)))) | |
| 492 | (tramp-message | 492 | |
| 493 | v 6 "%s" (mapconcat 'identity (process-command p) " ")) | 493 | ;; Use an asynchronous processes. By this, |
| 494 | (tramp-set-connection-property p "vector" v) | 494 | ;; password can be handled. |
| 495 | (tramp-compat-set-process-query-on-exit-flag p nil) | 495 | (let* ((default-directory tmpdir) |
| 496 | (tramp-process-actions p v nil tramp-smb-actions-with-tar) | 496 | (p (start-process-shell-command |
| 497 | 497 | (tramp-get-connection-name v) | |
| 498 | (while (memq (process-status p) '(run open)) | 498 | (tramp-get-connection-buffer v) |
| 499 | (sit-for 0.1)) | 499 | (mapconcat 'identity args " ")))) |
| 500 | (tramp-message v 6 "\n%s" (buffer-string)))) | 500 | |
| 501 | 501 | (tramp-message | |
| 502 | ;; Reset the transfer process properties. | 502 | v 6 "%s" (mapconcat 'identity (process-command p) " ")) |
| 503 | (tramp-set-connection-property v "process-name" nil) | 503 | (tramp-set-connection-property p "vector" v) |
| 504 | (tramp-set-connection-property v "process-buffer" nil) | 504 | (tramp-compat-set-process-query-on-exit-flag p nil) |
| 505 | (when t1 (delete-directory tmpdir 'recurse)))) | 505 | (tramp-process-actions p v nil tramp-smb-actions-with-tar) |
| 506 | 506 | ||
| 507 | ;; Handle KEEP-DATE argument. | 507 | (while (memq (process-status p) '(run open)) |
| 508 | (when keep-date | 508 | (sit-for 0.1)) |
| 509 | (set-file-times newname (nth 5 (file-attributes dirname)))) | 509 | (tramp-message v 6 "\n%s" (buffer-string)))) |
| 510 | 510 | ||
| 511 | ;; Set the mode. | 511 | ;; Reset the transfer process properties. |
| 512 | (unless keep-date | 512 | (tramp-set-connection-property v "process-name" nil) |
| 513 | (set-file-modes newname (tramp-default-file-modes dirname))) | 513 | (tramp-set-connection-property v "process-buffer" nil) |
| 514 | 514 | (when t1 (delete-directory tmpdir 'recurse)))) | |
| 515 | ;; When newname did exist, we have wrong cached values. | 515 | |
| 516 | (when t2 | 516 | ;; Handle KEEP-DATE argument. |
| 517 | (with-parsed-tramp-file-name newname nil | 517 | (when keep-date |
| 518 | (tramp-flush-file-property v (file-name-directory localname)) | 518 | (set-file-times newname (nth 5 (file-attributes dirname)))) |
| 519 | (tramp-flush-file-property v localname)))) | 519 | |
| 520 | 520 | ;; Set the mode. | |
| 521 | ;; We must do it file-wise. | 521 | (unless keep-date |
| 522 | (t | 522 | (set-file-modes newname (tramp-default-file-modes dirname))) |
| 523 | (tramp-run-real-handler | 523 | |
| 524 | 'copy-directory (list dirname newname keep-date parents)))))))) | 524 | ;; When newname did exist, we have wrong cached values. |
| 525 | (when t2 | ||
| 526 | (with-parsed-tramp-file-name newname nil | ||
| 527 | (tramp-flush-file-property v (file-name-directory localname)) | ||
| 528 | (tramp-flush-file-property v localname)))) | ||
| 529 | |||
| 530 | ;; We must do it file-wise. | ||
| 531 | (t | ||
| 532 | (tramp-run-real-handler | ||
| 533 | 'copy-directory (list dirname newname keep-date parents))))))))) | ||
| 525 | 534 | ||
| 526 | (defun tramp-smb-handle-copy-file | 535 | (defun tramp-smb-handle-copy-file |
| 527 | (filename newname &optional ok-if-already-exists keep-date | 536 | (filename newname &optional ok-if-already-exists keep-date |