From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Michael Albinus Newsgroups: gmane.emacs.help Subject: Re: Dired command on same host Date: Fri, 07 Jan 2022 16:50:00 +0100 Message-ID: <87bl0n8s0n.fsf@gmx.de> References: <877dbf94su.fsf@elite.giraud> <87czl77j7e.fsf@gmx.de> <87iluz79ja.fsf@elite.giraud> <878rvv73mr.fsf@gmx.de> <87k0ffp9mp.fsf@gnu.org> <877dbe7cf9.fsf@elite.giraud> <87iluxnb79.fsf@logand.com> <87ee5l5drh.fsf@gmx.de> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="34842"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux) Cc: help-gnu-emacs@gnu.org, Tomas Hlavaty , Tassilo Horn To: Manuel Giraud Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Fri Jan 07 16:56:49 2022 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1n5rbk-0008sC-LL for geh-help-gnu-emacs@m.gmane-mx.org; Fri, 07 Jan 2022 16:56:48 +0100 Original-Received: from localhost ([::1]:59468 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n5rbi-0001B0-TH for geh-help-gnu-emacs@m.gmane-mx.org; Fri, 07 Jan 2022 10:56:46 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:51856) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n5rVd-0002oW-E9 for help-gnu-emacs@gnu.org; Fri, 07 Jan 2022 10:50:30 -0500 Original-Received: from mout.gmx.net ([212.227.17.21]:33237) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n5rVX-0006Xm-5o; Fri, 07 Jan 2022 10:50:29 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1641570603; bh=uB9zco92pVP5MRyBc709/UvSBPbo/P/ge4q00/fGJTU=; h=X-UI-Sender-Class:From:To:Cc:Subject:References:Date:In-Reply-To; b=E61LRUkP71VfNaaxCpHnN4JYcthMz1a6xx7g0VCu5eBK3VCSZ6bd5AhBm8F63Mz+w sPttETvoNgsxqRsIZR1q4HdavwreRanwOrCn8s4P/S9SjPYG0FEWY7aDiVDA6/qrz2 FPLjRoCXExK/eA3gN0cYub3fUJa66aKDuUC8QLJs= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Original-Received: from gandalf.gmx.de ([217.70.140.19]) by mail.gmx.net (mrgmx105 [212.227.17.168]) with ESMTPSA (Nemesis) id 1N3bSt-1mOj3x2nsR-010ayB; Fri, 07 Jan 2022 16:50:02 +0100 In-Reply-To: <87ee5l5drh.fsf@gmx.de> (Michael Albinus's message of "Thu, 06 Jan 2022 12:01:38 +0100") X-Provags-ID: V03:K1:1U8/z1wEXkL4KWTGMKfO2VBaQEYtuVLwP7CYGQWjv2DCoKqkl1q wzWA7fyeF3AVR+VvsWQQbYSr8nopzJRhHKUfRoTXbEocDXTYgWhYgHJ8qD+hKmihPuMn7dN kboK4GZ/L9DtkPk6SQnf7/1HuPXCFBYP7hYMYWhVgFtWrxPkn9u7dR+7EGIe7tWPtvh0qG7 +GV+4uiKT+YSH1lKuyU1A== X-UI-Out-Filterresults: notjunk:1;V03:K0:/QuefO2klNM=:066KllNaFRWWl1nBz778qf FoMspnV+G/8EE7MiBKCXwGoEbbszgcrGsLp54LGwoVtq+o2qZPY67RdLcN/h7lZtPj5h8C/j7 YdKgm6zvCr/PfRlHMzYBxqU+6S4T2EX8+xWDaJzDmul5g8Zn48hT9JPgzX5WAf1o0/tQf2wai DvSTZme9EtXOKKXQ8KpY1piaSxYKkylwf5yZoauiLWnmNqI3pVjy5Qjo9sUxyMEqHQ5eT5sln 1OG2Q6g+axuZIdKtb9HQSa9wlAD9hVRLmAg2/yE8WlHxLdNSxa9AgcsrNikiF2s+0MzSftDkI ktkRuMTFRsnFNK5lfV26+NAkeRWpE6Az7+hLEQAAj3j2rJnsu7Uw1df2ja8gs3DZ3F5c3emHp 99Ag3aWocFDHQFyVHKsZzHmtfDjZBnQiA37ItweSTg9Far3fluGbTZ3dYoBkTjlvFT2Pl05Wa CWmaP51e9kuPj1AQaJrqxUVoQJEeDLRBjZ456XpvmD7MR2KYlUNR62ekxkXw9/J0VB5WI5f6S 31Wh6XBDiWCOGU6eQmTgKaY267yF9cJeHhMVV9ys/AihKJ6JVep6PGbw1HiFVcsTYU02wtZco JdVqMK5zu8n8PBqs5gMXVKZHzEZkyss2rEX8K64E1vRhtvGPlxubPh5C4lX3AkO+ArNAfho3S BqwwZQK4En5NSycwn/OTyi8LuJ8hq59AmCl2LUsbgDHh+SEHc6G26x489/CVGQFD0WCHKYLu6 OzguUOlWk5BFqvIvYarawzbbzclACDz8NTQYGFYafPTkO4PGW5TO/abewoJZ+6SVLjavvAt8 Received-SPF: pass client-ip=212.227.17.21; envelope-from=michael.albinus@gmx.de; helo=mout.gmx.net X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "help-gnu-emacs" Xref: news.gmane.io gmane.emacs.help:135123 Archived-At: --=-=-= Content-Type: text/plain Michael Albinus writes: Hi everybody, >> ssh is able to identify the host using host keys: >> >> /etc/ssh/ssh_host_ed25519_key.pub >> /etc/ssh/ssh_host_rsa_key.pub > > Thanks, these can be accessed via ssh-keyscan. Will use it in Tramp. I've implemented a proof-of-concept, see appended patch to tramp-sh.el. It is towards Emacs 29.0.50, but might also apply for Emacs 28.0.90 (for testing). After loading Tramp, there is a new user option tramp-use-scp-direct-remote-copying which must be set to non-nil. Direct scp copying between two remote servers shall happen then. Could people test it? Setting tramp-verbose to 6 shall show the scp command in the debug buffer, like in my case --8<---------------cut here---------------start------------->8--- 16:41:38.755570 tramp-do-copy-or-rename-file-out-of-band (6) # scp -p -T -R -q -r gandalf:/home/albinus/Downloads/CentOS-8.4.2105-x86_64-dvd1.iso detlef:/tmp/CentOS-8.4.2105-x86_64-dvd1.iso --8<---------------cut here---------------end--------------->8--- Best regards, Michael. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment Content-Transfer-Encoding: quoted-printable *** /tmp/ediffuxUjdM 2022-01-07 16:33:41.019095060 +0100 =2D-- /home/albinus/src/tramp/lisp/tramp-sh.el 2022-01-07 16:26:54.6869310= 60 +0100 *************** *** 136,141 **** =2D-- 136,157 ---- The string is used in `tramp-methods'.") + (defcustom tramp-use-scp-direct-remote-copying nil + "Whether to use direct copying between two remote hosts." + :group 'tramp + :version "29.1" + :type 'boolean) + + (defvar tramp-scp-direct-remote-copying nil + "Which scp direct remote copying argument to use. + + It is the string \"-R\" if supported by the local scp (since + release 8.7), otherwise the string \"\". If it is nil, it will + be auto-detected by Tramp, if + `tramp-use-scp-direct-remote-copying' is non-nil.. + + The string is used in `tramp-methods'.") + ;; Initialize `tramp-methods' with the supported methods. ;;;###tramp-autoload (tramp--with-startup *************** *** 172,178 **** (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") (tramp-copy-args (("-P" "%p") ("-p" "%k") ! ("%x") ("-q") ("-r") ("%c"))) (tramp-copy-keep-date t) (tramp-copy-recursive t))) (add-to-list 'tramp-methods =2D-- 188,194 ---- (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") (tramp-copy-args (("-P" "%p") ("-p" "%k") ! ("%x") ("%y") ("-q") ("-r") ("%c"))) (tramp-copy-keep-date t) (tramp-copy-recursive t))) (add-to-list 'tramp-methods *************** *** 188,194 **** (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") (tramp-copy-args (("-P" "%p") ("-p" "%k") ! ("%x") ("-q") ("-r") ("%c"))) (tramp-copy-keep-date t) (tramp-copy-recursive t))) (add-to-list 'tramp-methods =2D-- 204,210 ---- (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") (tramp-copy-args (("-P" "%p") ("-p" "%k") ! ("%x") ("%y") ("-q") ("-r") ("%c"))) (tramp-copy-keep-date t) (tramp-copy-recursive t))) (add-to-list 'tramp-methods *************** *** 2241,2259 **** (op filename newname ok-if-already-exists keep-date) "Invoke `scp' 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)) ! (orig-vec (tramp-dissect-file-name (if t1 filename newname))) copy-program copy-args copy-env copy-keep-date listener spec options source target remote-copy-program remote-copy-args p) ! (with-parsed-tramp-file-name (if t1 filename newname) nil ! (if (and t1 t2) ! ;; Both are Tramp files. We shall optimize it when the ! ;; methods for FILENAME and NEWNAME are the same. (let* ((dir-flag (file-directory-p filename)) ! (tmpfile (tramp-compat-make-temp-file localname dir-flag))) (if dir-flag (setq tmpfile (expand-file-name =2D-- 2257,2277 ---- (op filename newname ok-if-already-exists keep-date) "Invoke `scp' program to copy. The method used must be an out-of-band method." ! (let* ((v1 (and (tramp-tramp-file-p filename) ! (tramp-dissect-file-name filename))) ! (v2 (and (tramp-tramp-file-p newname) ! (tramp-dissect-file-name newname))) ! (v (or v1 v2)) copy-program copy-args copy-env copy-keep-date listener spec options source target remote-copy-program remote-copy-args p) ! ; (with-parsed-tramp-file-name (if v1 filename newname) nil ! (if (and v1 v2 (not (tramp-scp-direct-remote-copying-p v1 v2))) ! ;; Both are Tramp files. We cannot use direct remote copying. (let* ((dir-flag (file-directory-p filename)) ! (tmpfile (tramp-compat-make-temp-file ! (tramp-file-name-localname v1) dir-flag))) (if dir-flag (setq tmpfile (expand-file-name *************** *** 2273,2299 **** ;; Check which ones of source and target are Tramp files. (setq source (funcall ! (if (and (string-equal method "rsync") (file-directory-p filename) (not (file-exists-p newname))) #'file-name-as-directory #'identity) ! (if t1 ! (tramp-make-copy-program-file-name v) (tramp-compat-file-name-unquote filename))) ! target (if t2 ! (tramp-make-copy-program-file-name v) (tramp-compat-file-name-unquote newname))) ;; Check for user. There might be an interactive setting. ! (setq user (or (tramp-file-name-user v) ! (tramp-get-connection-property v "login-as" nil))) ;; Check for listener port. (when (tramp-get-method-parameter v 'tramp-remote-copy-args) (setq listener (number-to-string (+ 50000 (random 10000)))) (while ! (zerop (tramp-call-process v "nc" nil nil nil "-z" host listener)= ) (setq listener (number-to-string (+ 50000 (random 10000)))))) ;; Compose copy command. =2D-- 2291,2318 ---- ;; Check which ones of source and target are Tramp files. (setq source (funcall ! (if (and (string-equal (tramp-file-name-method v) "rsync") (file-directory-p filename) (not (file-exists-p newname))) #'file-name-as-directory #'identity) ! (if v1 ! (tramp-make-copy-program-file-name v1) (tramp-compat-file-name-unquote filename))) ! target (if v2 ! (tramp-make-copy-program-file-name v2) (tramp-compat-file-name-unquote newname))) ;; Check for user. There might be an interactive setting. ! ; (setq user (or (tramp-file-name-user v) ! ; (tramp-get-connection-property v "login-as" nil))) ;; Check for listener port. (when (tramp-get-method-parameter v 'tramp-remote-copy-args) (setq listener (number-to-string (+ 50000 (random 10000)))) (while ! (zerop (tramp-call-process ! v "nc" nil nil nil "-z" (tramp-file-name-host v) listener)) (setq listener (number-to-string (+ 50000 (random 10000)))))) ;; Compose copy command. *************** *** 2304,2313 **** ?t (tramp-get-connection-property (tramp-get-connection-process v) "temp-file" ""))) spec (list ! ?h (or host "") ?u (or user "") ?p (or port "") ?r listener ?c options ?k (if keep-date " " "") ?n (concat "2>" (tramp-get-remote-null-device v)) ! ?x (tramp-scp-strict-file-name-checking v)) copy-program (tramp-get-method-parameter v 'tramp-copy-program) copy-keep-date (tramp-get-method-parameter v 'tramp-copy-keep-date) =2D-- 2323,2335 ---- ?t (tramp-get-connection-property (tramp-get-connection-process v) "temp-file" ""))) spec (list ! ?h (or (tramp-file-name-host v) "") ! ?u (or (tramp-file-name-user v) "") ! ?p (or (tramp-file-name-port v) "") ?r listener ?c options ?k (if keep-date " " "") ?n (concat "2>" (tramp-get-remote-null-device v)) ! ?x (tramp-scp-strict-file-name-checking v) ! ?y (tramp-scp-direct-remote-copying v)) copy-program (tramp-get-method-parameter v 'tramp-copy-program) copy-keep-date (tramp-get-method-parameter v 'tramp-copy-keep-date) *************** *** 2350,2356 **** #'identity (append (list remote-copy-program) remote-copy-args ! (list (if t1 (concat "<" source) (concat ">" target)) "&")) " ")) (tramp-send-command v remote-copy-program) (with-timeout =2D-- 2372,2378 ---- #'identity (append (list remote-copy-program) remote-copy-args ! (list (if v1 (concat "<" source) (concat ">" target)) "&")) " ")) (tramp-send-command v remote-copy-program) (with-timeout *************** *** 2367,2373 **** (unwind-protect ;; The default directory must be remote. (let ((default-directory ! (file-name-directory (if t1 filename newname))) (process-environment (copy-sequence process-environment))) ;; Set the transfer process properties. (tramp-set-connection-property =2D-- 2389,2395 ---- (unwind-protect ;; The default directory must be remote. (let ((default-directory ! (file-name-directory (if v1 filename newname))) (process-environment (copy-sequence process-environment))) ;; Set the transfer process properties. (tramp-set-connection-property *************** *** 2376,2382 **** v "process-buffer" (current-buffer)) (when copy-env (tramp-message ! orig-vec 6 "%s=3D\"%s\"" (car copy-env) (string-join (cdr copy-env) " ")) (setenv (car copy-env) (string-join (cdr copy-env) " "))) (setq =2D-- 2398,2404 ---- v "process-buffer" (current-buffer)) (when copy-env (tramp-message ! v 6 "%s=3D\"%s\"" (car copy-env) (string-join (cdr copy-env) " ")) (setenv (car copy-env) (string-join (cdr copy-env) " "))) (setq *************** *** 2384,2403 **** (append copy-args (if remote-copy-program ! (list (if t1 (concat ">" target) (concat "<" source))) (list source target))) ;; Use an asynchronous process. By this, password ;; can be handled. We don't set a timeout, because ;; the copying of large files can last longer than 60 ;; secs. ! p (let ((default-directory tramp-compat-temporary-file-directory)) (apply #'start-process (tramp-get-connection-name v) (tramp-get-connection-buffer v) copy-program copy-args))) ! (tramp-message orig-vec 6 "%s" (string-join (process-command p) " ")) ! (process-put p 'vector orig-vec) (process-put p 'adjust-window-size-function #'ignore) (set-process-query-on-exit-flag p nil) =2D-- 2406,2426 ---- (append copy-args (if remote-copy-program ! (list (if v1 (concat ">" target) (concat "<" source))) (list source target))) ;; Use an asynchronous process. By this, password ;; can be handled. We don't set a timeout, because ;; the copying of large files can last longer than 60 ;; secs. ! p (let ((default-directory ! tramp-compat-temporary-file-directory)) (apply #'start-process (tramp-get-connection-name v) (tramp-get-connection-buffer v) copy-program copy-args))) ! (tramp-message v 6 "%s" (string-join (process-command p) " ")) ! (process-put p 'vector v) (process-put p 'adjust-window-size-function #'ignore) (set-process-query-on-exit-flag p nil) *************** *** 2434,2440 **** (unless (eq op 'copy) (if (file-regular-p filename) (delete-file filename) ! (delete-directory filename 'recursive)))))) (defun tramp-sh-handle-make-directory (dir &optional parents) "Like `make-directory' for Tramp files." =2D-- 2457,2463 ---- (unless (eq op 'copy) (if (file-regular-p filename) (delete-file filename) ! (delete-directory filename 'recursive)))));) (defun tramp-sh-handle-make-directory (dir &optional parents) "Like `make-directory' for Tramp files." *************** *** 4824,4829 **** =2D-- 4847,4912 ---- (setq tramp-scp-strict-file-name-checking "-T"))))))) tramp-scp-strict-file-name-checking))) + (defun tramp-scp-direct-remote-copying-p (vec1 vec2) + "Check, whether direct remote copying between VEC1 and VEC2 is possibl= e." + (and tramp-use-scp-direct-remote-copying + (assoc "%y" (tramp-get-method-parameter vec1 'tramp-copy-args)) + (assoc "%y" (tramp-get-method-parameter vec2 'tramp-copy-args)) + (with-tramp-connection-property + (tramp-get-process vec1) + (concat "direct-remote-copying-" + (tramp-make-tramp-file-name vec2 'local 'hop)) + (let ((command + (if (tramp-file-name-port vec2) + `("ssh-keyscan" ,(tramp-file-name-host vec2) + "-p" ,(tramp-file-name-port vec2)) + `("ssh-keyscan" ,(tramp-file-name-host vec2)))) + found string) + (with-temp-buffer + ;; Check hostkey of VEC2, seen from VEC1. + (tramp-send-command vec1 (mapconcat #'identity command " ")) + ;; Check hostkey of VEC2, seen locally. + (apply + #'tramp-call-process vec1 (car command) nil t nil (cdr command)) + (goto-char (point-min)) + (while (and (not found) (not (eobp))) + (setq string (buffer-substring + (line-beginning-position) (line-end-position)) + found (and (not (string-match-p "^#" string)) + (with-current-buffer (tramp-get-buffer vec1) + (goto-char (point-min)) + (search-forward string nil 'noerror)))) + (forward-line)) + ;; Result. + found))))) + + (defun tramp-scp-direct-remote-copying (vec) + "Return the direct remote copying argument of the local scp." + (cond + ;; No options to be computed. + ((null (assoc "%y" (tramp-get-method-parameter vec 'tramp-copy-args))= ) + "") + + ;; There is already a value to be used. + ((stringp tramp-scp-direct-remote-copying) + tramp-scp-direct-remote-copying) + + ;; Determine the options. + (t (setq tramp-scp-direct-remote-copying "") + (let ((case-fold-search t)) + (ignore-errors + (when (executable-find "scp") + (with-tramp-progress-reporter + vec 4 "Computing direct remote copying argument" + (with-temp-buffer + (tramp-call-process vec "scp" nil t nil "-R") + (goto-char (point-min)) + (unless + (search-forward-regexp + "\\(illegal\\|unknown\\) option -- R" nil t) + (setq tramp-scp-strict-file-name-checking "-R"))))))) + tramp-scp-strict-file-name-checking))) + (defun tramp-timeout-session (vec) "Close the connection VEC after a session timeout. If there is just some editing, retry it after 5 seconds." *************** *** 5977,5985 **** ;; ;; * Use lsh instead of ssh. (Alfred M. Szmidt) ;; - ;; * Optimize out-of-band copying when both methods are scp-like (not - ;; rsync). - ;; ;; * Keep a second connection open for out-of-band methods like scp or ;; rsync. ;; =2D-- 6060,6065 ---- --=-=-=--