aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Albinus2013-10-28 20:30:40 +0100
committerMichael Albinus2013-10-28 20:30:40 +0100
commit4efc33f01d0344a52670eb0c0250d5ef40bb7952 (patch)
treee01a5db8601a1a291b98b4919faa41a99b3065dc
parent5d3311e5bb8fba7a8151cc79d6651488946ac19d (diff)
downloademacs-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/ChangeLog6
-rw-r--r--lisp/net/tramp-sh.el13
-rw-r--r--lisp/net/tramp-smb.el277
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 @@
12013-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
12013-10-28 Daiki Ueno <ueno@gnu.org> 72013-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