]> code.delx.au - gnu-emacs/blobdiff - lisp/net/tramp-sh.el
* net/tramp-sh.el (tramp-methods): Add recursive options to "scpc"
[gnu-emacs] / lisp / net / tramp-sh.el
index 5e6cd9577c63dbd3babfb29a9fff9d9ca668385e..9950709bd7a08a3eba1debe3d92d333553e0aa56 100644 (file)
@@ -91,7 +91,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-args           (("%h") ("-l" "%u")))
     (tramp-remote-sh            "/bin/sh")
     (tramp-copy-program         "rcp")
-    (tramp-copy-args            (("-p" "%k") ("-r")))
+    (tramp-copy-args            (("%k" "-p") ("-r")))
     (tramp-copy-keep-date       t)
     (tramp-copy-recursive       t)))
 ;;;###tramp-autoload
@@ -101,17 +101,17 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-args           (("%h") ("-l" "%u")))
     (tramp-remote-sh            "/bin/sh")
     (tramp-copy-program         "rcp")
-    (tramp-copy-args            (("-p" "%k")))
+    (tramp-copy-args            (("%k" "-p")))
     (tramp-copy-keep-date       t)))
 ;;;###tramp-autoload
-(add-to-list
- 'tramp-methods
'("scp"   (tramp-login-program        "ssh")
+(add-to-list 'tramp-methods
+ '("scp"
+   (tramp-login-program        "ssh")
    (tramp-login-args           (("-l" "%u") ("-p" "%p")        ("-e" "none") ("%h")))
    (tramp-async-args           (("-q")))
    (tramp-remote-sh            "/bin/sh")
    (tramp-copy-program         "scp")
-   (tramp-copy-args            (("-P" "%p") ("-p" "%k")        ("-q") ("-r")))
+   (tramp-copy-args            (("-P" "%p") ("%k" "-p")        ("-q") ("-r")))
    (tramp-copy-keep-date       t)
    (tramp-copy-recursive       t)
    (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
@@ -127,7 +127,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-async-args           (("-q")))
     (tramp-remote-sh            "/bin/sh")
     (tramp-copy-program         "scp")
-    (tramp-copy-args            (("-1") ("-P" "%p") ("-p" "%k") ("-q") ("-r")))
+    (tramp-copy-args            (("-1") ("-P" "%p") ("%k" "-p") ("-q") ("-r")))
     (tramp-copy-keep-date       t)
     (tramp-copy-recursive       t)
     (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
@@ -143,7 +143,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-async-args           (("-q")))
     (tramp-remote-sh            "/bin/sh")
     (tramp-copy-program         "scp")
-    (tramp-copy-args            (("-2") ("-P" "%p") ("-p" "%k") ("-q") ("-r")))
+    (tramp-copy-args            (("-2") ("-P" "%p") ("%k" "-p") ("-q") ("-r")))
     (tramp-copy-keep-date       t)
     (tramp-copy-recursive       t)
     (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
@@ -161,10 +161,11 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-async-args           (("-q")))
     (tramp-remote-sh            "/bin/sh")
     (tramp-copy-program         "scp")
-    (tramp-copy-args            (("-P" "%p") ("-p" "%k") ("-q")
+    (tramp-copy-args            (("-P" "%p") ("%k" "-p") ("-q") ("-r")
                                 ("-o" "ControlPath=%t.%%r@%%h:%%p")
                                 ("-o" "ControlMaster=auto")))
     (tramp-copy-keep-date       t)
+    (tramp-copy-recursive       t)
     (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
                                 ("-o" "UserKnownHostsFile=/dev/null")
                                 ("-o" "StrictHostKeyChecking=no")))
@@ -179,8 +180,9 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-async-args           (("-q")))
     (tramp-remote-sh            "/bin/sh")
     (tramp-copy-program         "scp")
-    (tramp-copy-args            (("-p" "%k")))
+    (tramp-copy-args            (("-P" "%p") ("%k" "-p") ("-q") ("-r")))
     (tramp-copy-keep-date       t)
+    (tramp-copy-recursive       t)
     (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
                                 ("-o" "UserKnownHostsFile=/dev/null")
                                 ("-o" "StrictHostKeyChecking=no")))
@@ -201,7 +203,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-async-args           (("-q")))
     (tramp-remote-sh            "/bin/sh")
     (tramp-copy-program         "rsync")
-    (tramp-copy-args            (("-e" "ssh") ("-t" "%k") ("-r")))
+    (tramp-copy-args            (("-e" "ssh") ("%k" "-t") ("-r")))
     (tramp-copy-keep-date       t)
     (tramp-copy-keep-tmpfile    t)
     (tramp-copy-recursive       t)))
@@ -216,7 +218,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-async-args           (("-q")))
     (tramp-remote-sh            "/bin/sh")
     (tramp-copy-program         "rsync")
-    (tramp-copy-args            (("-t" "%k") ("-r")))
+    (tramp-copy-args            (("%k" "-t") ("-r")))
     (tramp-copy-env             (("RSYNC_RSH")
                                 (,(concat
                                    "ssh"
@@ -305,6 +307,12 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-args           (("-u" "%u") ("-s") ("-H") ("-p" "Password:")))
     (tramp-remote-sh            "/bin/sh")))
 ;;;###tramp-autoload
+(add-to-list 'tramp-methods
+  '("ksu"
+    (tramp-login-program        "ksu")
+    (tramp-login-args           (("%u") ("-q")))
+    (tramp-remote-sh            "/bin/sh")))
+;;;###tramp-autoload
 (add-to-list 'tramp-methods
   '("krlogin"
     (tramp-login-program        "krlogin")
@@ -346,8 +354,10 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-args           (("-l" "%u") ("-P" "%p") ("-ssh") ("%h")))
     (tramp-remote-sh            "/bin/sh")
     (tramp-copy-program         "pscp")
-    (tramp-copy-args            (("-P" "%p") ("-scp") ("-p" "%k")))
+    (tramp-copy-args            (("-P" "%p") ("-scp") ("%k" "-p")
+                                ("-q") ("-r")))
     (tramp-copy-keep-date       t)
+    (tramp-copy-recursive       t)
     (tramp-password-end-of-line "xy") ;see docstring for "xy"
     (tramp-default-port         22)))
 ;;;###tramp-autoload
@@ -357,8 +367,10 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-args           (("-l" "%u") ("-P" "%p") ("-ssh") ("%h")))
     (tramp-remote-sh            "/bin/sh")
     (tramp-copy-program         "pscp")
-    (tramp-copy-args            (("-P" "%p") ("-sftp") ("-p" "%k")))
+    (tramp-copy-args            (("-P" "%p") ("-sftp") ("%k" "-p")
+                                ("-q") ("-r")))
     (tramp-copy-keep-date       t)
+    (tramp-copy-recursive       t)
     (tramp-password-end-of-line "xy"))) ;see docstring for "xy"
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
@@ -367,16 +379,26 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-args           (("%h") ("-l" "%u") ("sh" "-i")))
     (tramp-remote-sh            "/bin/sh -i")
     (tramp-copy-program         "fcp")
-    (tramp-copy-args            (("-p" "%k")))
+    (tramp-copy-args            (("%k" "-p")))
     (tramp-copy-keep-date       t)))
 
+;;;###tramp-autoload
 (add-to-list 'tramp-default-method-alist
             `(,tramp-local-host-regexp "\\`root\\'" "su"))
 
+;;;###tramp-autoload
 (add-to-list 'tramp-default-user-alist
-            '("\\`su\\(do\\)?\\'" nil "root"))
+            `(,(concat "\\`" (regexp-opt '("su" "sudo" "ksu")) "\\'")
+              nil "root"))
+;; Do not add "ssh" based methods, otherwise ~/.ssh/config would be ignored.
+;;;###tramp-autoload
 (add-to-list 'tramp-default-user-alist
-            `("\\`r\\(em\\)?\\(cp\\|sh\\)\\|telnet\\|plink1?\\'"
+            `(,(concat
+                "\\`"
+                (regexp-opt
+                 '("rcp" "remcp" "rsh" "telnet" "krlogin"
+                   "plink" "plink1" "pscp" "psftp" "fcp"))
+                "\\'")
               nil ,(user-login-name)))
 
 (defconst tramp-completion-function-alist-rsh
@@ -433,6 +455,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
 (tramp-set-completion-function "telnet" tramp-completion-function-alist-telnet)
 (tramp-set-completion-function "su" tramp-completion-function-alist-su)
 (tramp-set-completion-function "sudo" tramp-completion-function-alist-su)
+(tramp-set-completion-function "ksu" tramp-completion-function-alist-su)
 (tramp-set-completion-function "krlogin" tramp-completion-function-alist-rsh)
 (tramp-set-completion-function "plink" tramp-completion-function-alist-ssh)
 (tramp-set-completion-function "plink1" tramp-completion-function-alist-ssh)
@@ -1942,7 +1965,7 @@ file names."
 
               ;; Try out-of-band operation.
               ((tramp-method-out-of-band-p
-                v1 (nth 7 (file-attributes filename)))
+                v1 (nth 7 (file-attributes (file-truename filename))))
                (tramp-do-copy-or-rename-file-out-of-band
                 op filename newname keep-date))
 
@@ -1970,7 +1993,8 @@ file names."
 
           ;; If the Tramp file has an out-of-band method, the
           ;; corresponding copy-program can be invoked.
-          ((tramp-method-out-of-band-p v (nth 7 (file-attributes filename)))
+          ((tramp-method-out-of-band-p
+            v (nth 7 (file-attributes (file-truename filename))))
            (tramp-do-copy-or-rename-file-out-of-band
             op filename newname keep-date))
 
@@ -2166,24 +2190,22 @@ the uid and gid from FILENAME."
                       (list tmpfile localname2 ok-if-already-exists)))))
 
                ;; Save exit.
-               (condition-case nil
-                   (delete-file tmpfile)
-                 (error)))))))))
+               (ignore-errors (delete-file tmpfile)))))))))
 
       ;; Set the time and mode. Mask possible errors.
-      (condition-case nil
+      (ignore-errors
          (when keep-date
            (set-file-times newname file-times)
-           (set-file-modes newname file-modes))
-       (error)))))
+           (set-file-modes newname file-modes))))))
 
 (defun tramp-do-copy-or-rename-file-out-of-band (op filename newname keep-date)
   "Invoke rcp program to copy.
 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-env copy-keep-date port spec
-       source target)
+  (let* ((t1 (tramp-tramp-file-p filename))
+        (t2 (tramp-tramp-file-p newname))
+        (orig-vec (tramp-dissect-file-name (if t1 filename newname)))
+        copy-program copy-args copy-env copy-keep-date port spec
+        source target)
 
     (with-parsed-tramp-file-name (if t1 filename newname) nil
       (if (and t1 t2)
@@ -2203,12 +2225,17 @@ The method used must be an out-of-band method."
                  (tramp-do-copy-or-rename-file-out-of-band
                   'rename tmpfile newname keep-date))
              ;; Save exit.
-             (condition-case nil
-                 (if dir-flag
-                     (tramp-compat-delete-directory
-                      (expand-file-name ".." tmpfile) 'recursive)
-                   (delete-file tmpfile))
-               (error))))
+             (ignore-errors
+               (if dir-flag
+                   (tramp-compat-delete-directory
+                    (expand-file-name ".." tmpfile) 'recursive)
+                 (delete-file tmpfile)))))
+
+       ;; Set variables for computing the prompt for reading
+       ;; password.
+       (setq tramp-current-method (tramp-file-name-method v)
+             tramp-current-user   (tramp-file-name-user v)
+             tramp-current-host   (tramp-file-name-host v))
 
        ;; Expand hops.  Might be necessary for gateway methods.
        (setq v (car (tramp-compute-multi-hops v)))
@@ -2242,16 +2269,20 @@ The method used must be an out-of-band method."
              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)))
+             (delete
+              ;; " " has either been a replacement of "%k" (when
+              ;; keep-date argument is non-nil), or a replacemtent
+              ;; for the whole keep-date sublist.
+              " "
+              (dolist
+                  (x
+                   (tramp-get-method-parameter method 'tramp-copy-args)
+                   copy-args)
+                (setq copy-args
+                      (append
+                       copy-args
+                       (let ((y (mapcar (lambda (z) (format-spec z spec)) x)))
+                         (if (zerop (length (car y))) '(" ") y))))))
              copy-env
              (delq
               nil
@@ -2269,14 +2300,8 @@ The method used must be an out-of-band method."
          (tramp-error
           v 'file-error "Cannot find copy program: %s" copy-program))
 
-       ;; Set variables for computing the prompt for reading
-       ;; password.
-       (setq tramp-current-method (tramp-file-name-method v)
-             tramp-current-user   (tramp-file-name-user v)
-             tramp-current-host   (tramp-file-name-host v))
-
-       (unwind-protect
-           (with-temp-buffer
+       (with-temp-buffer
+         (unwind-protect
              ;; The default directory must be remote.
              (let ((default-directory
                      (file-name-directory (if t1 filename newname)))
@@ -2287,7 +2312,8 @@ The method used must be an out-of-band method."
                (tramp-set-connection-property
                 v "process-buffer" (current-buffer))
                (while copy-env
-                 (tramp-message v 5 "%s=\"%s\"" (car copy-env) (cadr copy-env))
+                 (tramp-message
+                  orig-vec 5 "%s=\"%s\"" (car copy-env) (cadr copy-env))
                  (setenv (pop copy-env) (pop copy-env)))
 
                ;; Use an asynchronous process.  By this, password can
@@ -2298,20 +2324,20 @@ The method used must be an out-of-band method."
                (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)
+                                 (tramp-get-connection-name v)
+                                 (tramp-get-connection-buffer v)
                                  copy-program
                                  (append copy-args (list source target))))))
                  (tramp-message
-                  v 6 "%s" (mapconcat 'identity (process-command p) " "))
+                  orig-vec 6 "%s"
+                  (mapconcat 'identity (process-command p) " "))
                  (tramp-compat-set-process-query-on-exit-flag p nil)
-                 (tramp-process-actions p v tramp-actions-copy-out-of-band))))
+                 (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))
+           ;; Reset the transfer process properties.
+           (tramp-message orig-vec 6 "%s" (buffer-string))
+           (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))
@@ -2630,61 +2656,65 @@ the result will be a local, non-Tramp, filename."
 (defun tramp-sh-handle-start-file-process (name buffer program &rest args)
   "Like `start-file-process' for Tramp files."
   (with-parsed-tramp-file-name default-directory nil
-    (unwind-protect
-       ;; When PROGRAM is nil, we just provide a tty.
-       (let ((command
-              (when (stringp program)
-                (format "cd %s; exec %s"
-                        (tramp-shell-quote-argument localname)
-                        (mapconcat 'tramp-shell-quote-argument
-                                   (cons program args) " "))))
-             (tramp-process-connection-type
-              (or (null program) tramp-process-connection-type))
-             (name1 name)
-             (i 0))
-         (unless buffer
-           ;; BUFFER can be nil.  We use a temporary buffer.
-           (setq buffer (generate-new-buffer tramp-temp-buffer-name)))
-         (while (get-process name1)
-           ;; NAME must be unique as process name.
-           (setq i (1+ i)
-                 name1 (format "%s<%d>" name i)))
-         (setq name name1)
-         ;; Set the new process properties.
-         (tramp-set-connection-property v "process-name" name)
-         (tramp-set-connection-property v "process-buffer" buffer)
-         ;; Activate narrowing in order to save BUFFER contents.
-         ;; Clear also the modification time; otherwise we might be
-         ;; interrupted by `verify-visited-file-modtime'.
-         (with-current-buffer (tramp-get-connection-buffer v)
-           (clear-visited-file-modtime)
-           (narrow-to-region (point-max) (point-max)))
-         (if command
-             ;; Send the command.
-             (tramp-send-command v command nil t) ; nooutput
-           ;; Check, whether a pty is associated.
-           (tramp-maybe-open-connection v)
-           (unless (tramp-compat-process-get
-                    (tramp-get-connection-process v) 'remote-tty)
-             (tramp-error
-              v 'file-error "pty association is not supported for `%s'" name)))
-         (let ((p (tramp-get-connection-process v)))
-           ;; Set sentinel and query flag for this process.
-           (tramp-set-connection-property p "vector" v)
-           (set-process-sentinel p 'tramp-process-sentinel)
-           (tramp-compat-set-process-query-on-exit-flag p t)
-           ;; Return process.
-           p))
-      ;; Save exit.
-      (with-current-buffer (tramp-get-connection-buffer v)
-       (if (string-match tramp-temp-buffer-name (buffer-name))
-           (progn
-             (set-process-buffer (tramp-get-connection-process v) nil)
-             (kill-buffer (current-buffer)))
-         (widen)
-         (goto-char (point-max))))
-      (tramp-set-connection-property v "process-name" nil)
-      (tramp-set-connection-property v "process-buffer" nil))))
+    ;; When PROGRAM is nil, we just provide a tty.
+    (let ((command
+          (when (stringp program)
+            (format "cd %s; exec %s"
+                    (tramp-shell-quote-argument localname)
+                    (mapconcat 'tramp-shell-quote-argument
+                               (cons program args) " "))))
+         (tramp-process-connection-type
+          (or (null program) tramp-process-connection-type))
+         (bmp (and (buffer-live-p buffer) (buffer-modified-p buffer)))
+         (name1 name)
+         (i 0))
+      (unwind-protect
+         (save-excursion
+           (save-restriction
+             (unless buffer
+               ;; BUFFER can be nil.  We use a temporary buffer.
+               (setq buffer (generate-new-buffer tramp-temp-buffer-name)))
+             (while (get-process name1)
+               ;; NAME must be unique as process name.
+               (setq i (1+ i)
+                     name1 (format "%s<%d>" name i)))
+             (setq name name1)
+             ;; Set the new process properties.
+             (tramp-set-connection-property v "process-name" name)
+             (tramp-set-connection-property v "process-buffer" buffer)
+             ;; Activate narrowing in order to save BUFFER contents.
+             ;; Clear also the modification time; otherwise we might
+             ;; be interrupted by `verify-visited-file-modtime'.
+             (with-current-buffer (tramp-get-connection-buffer v)
+               (let ((buffer-undo-list t))
+                 (clear-visited-file-modtime)
+                 (narrow-to-region (point-max) (point-max))
+                 (if command
+                     ;; Send the command.
+                     (tramp-send-command v command nil t) ; nooutput
+                   ;; Check, whether a pty is associated.
+                   (tramp-maybe-open-connection v)
+                   (unless (tramp-compat-process-get
+                            (tramp-get-connection-process v) 'remote-tty)
+                     (tramp-error
+                      v 'file-error
+                      "pty association is not supported for `%s'" name)))))
+             (let ((p (tramp-get-connection-process v)))
+               ;; Set sentinel and query flag for this process.
+               (tramp-set-connection-property p "vector" v)
+               (set-process-sentinel p 'tramp-process-sentinel)
+               (tramp-compat-set-process-query-on-exit-flag p t)
+               ;; Return process.
+               p)))
+       ;; Save exit.
+       (with-current-buffer (tramp-get-connection-buffer v)
+         (if (string-match tramp-temp-buffer-name (buffer-name))
+             (progn
+               (set-process-buffer (tramp-get-connection-process v) nil)
+               (kill-buffer (current-buffer)))
+           (set-buffer-modified-p bmp)))
+       (tramp-set-connection-property v "process-name" nil)
+       (tramp-set-connection-property v "process-buffer" nil)))))
 
 (defun tramp-sh-handle-process-file
   (program &optional infile destination display &rest args)
@@ -2898,7 +2928,7 @@ the result will be a local, non-Tramp, filename."
        v 'file-error
        "Cannot make local copy of non-existing file `%s'" filename))
 
-    (let* ((size (nth 7 (file-attributes filename)))
+    (let* ((size (nth 7 (file-attributes (file-truename filename))))
           (rem-enc (tramp-get-inline-coding v "remote-encoding" size))
           (loc-dec (tramp-get-inline-coding v "local-decoding" size))
           (tmpfile (tramp-compat-make-temp-file filename)))
@@ -4106,22 +4136,10 @@ Gateway hops are already opened."
       (let ((gw (pop target-alist))
            (hop (pop target-alist)))
        ;; Is the method prepared for gateways?
-       (unless (tramp-get-method-parameter
-                (tramp-file-name-method hop) 'tramp-default-port)
+       (unless (tramp-file-name-port hop)
          (tramp-error
           vec 'file-error
-          "Method `%s' is not supported for gateway access."
-          (tramp-file-name-method hop)))
-       ;; Add default port if needed.
-       (unless
-           (string-match
-            tramp-host-with-port-regexp (tramp-file-name-host hop))
-         (aset hop 2
-               (concat
-                (tramp-file-name-host hop) tramp-prefix-port-format
-                (number-to-string
-                 (tramp-get-method-parameter
-                  (tramp-file-name-method hop) 'tramp-default-port)))))
+          "Connection `%s' is not supported for gateway access." hop))
        ;; Open the gateway connection.
        (add-to-list
         'target-alist
@@ -4241,7 +4259,7 @@ connection if a previous connection has died for some reason."
                 (p (let ((default-directory
                            (tramp-compat-temporary-file-directory)))
                      (start-process
-                      (or process-name (tramp-buffer-name vec))
+                      (tramp-get-connection-name vec)
                       (tramp-get-connection-buffer vec)
                       tramp-encoding-shell))))
 
@@ -5039,6 +5057,5 @@ function cell is returned to be applied on a buffer."
 ;;   rsync.
 ;; * Try telnet+curl as new method.  It might be useful for busybox,
 ;;   without built-in uuencode/uudecode.
-;; * Try ssh+netcat as out-of-band method.
 
 ;;; tramp-sh.el ends here