tramp-sh.el 230 KB
Newer Older
Michael Albinus's avatar
Michael Albinus committed
1
;;; tramp-sh.el --- Tramp access functions for (s)sh-like connections  -*- lexical-binding:t -*-
2

Paul Eggert's avatar
Paul Eggert committed
3
;; Copyright (C) 1998-2021 Free Software Foundation, Inc.
4 5 6 7 8

;; (copyright statements below in code to be updated with the above notice)

;; Author: Kai Großjohann <kai.grossjohann@gmx.net>
;;         Michael Albinus <michael.albinus@gmx.de>
9
;; Maintainer: Michael Albinus <michael.albinus@gmx.de>
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
;; Keywords: comm, processes
;; Package: tramp

;; This file is part of GNU Emacs.

;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
26
;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
27

28 29 30 31
;;; Commentary:

;; The file name handler implementation for ssh-alike remote connections.

32 33
;;; Code:

34
(eval-when-compile (require 'cl-lib))
35 36
(require 'tramp)

Michael Albinus's avatar
Michael Albinus committed
37 38
(declare-function dired-remove-file "dired-aux")
(defvar dired-compress-file-suffixes)
39
(defvar process-file-return-signal-string)
40 41 42 43
(defvar vc-handled-backends)
(defvar vc-bzr-program)
(defvar vc-git-program)
(defvar vc-hg-program)
44

45 46 47 48
;;;###tramp-autoload
(defconst tramp-default-remote-shell "/bin/sh"
  "The default remote shell Tramp applies.")

49
(defcustom tramp-inline-compress-start-size 4096
50
  "The minimum size of compressing where inline transfer.
51 52 53
When inline transfer, compress transferred data of file whose
size is this value or above (up to `tramp-copy-size-limit' for
out-of-band methods).
54 55
If it is nil, no compression at all will be applied."
  :group 'tramp
Michael Albinus's avatar
Michael Albinus committed
56
  :type '(choice (const nil) integer))
57 58

(defcustom tramp-copy-size-limit 10240
59
  "Maximum file size where inline copying is preferred to an out-of-the-band copy.
Michael Albinus's avatar
Michael Albinus committed
60
If it is nil, out-of-the-band copy will be used without a check."
61
  :group 'tramp
Michael Albinus's avatar
Michael Albinus committed
62
  :type '(choice (const nil) integer))
63

Michael Albinus's avatar
Michael Albinus committed
64
(defcustom tramp-histfile-override "~/.tramp_history"
65
  "When invoking a shell, override the HISTFILE with this value.
66 67 68
When setting to a string, it redirects the shell history to that
file.  Be careful when setting to \"/dev/null\"; this might
result in undesired results when using \"bash\" as shell.
69

Michael Albinus's avatar
Michael Albinus committed
70 71 72 73
The value t unsets any setting of HISTFILE, and sets both
HISTFILESIZE and HISTSIZE to 0.  If you set this variable to nil,
however, the *override* is disabled, so the history will go to
the default storage location, e.g. \"$HOME/.sh_history\"."
74
  :group 'tramp
Michael Albinus's avatar
Michael Albinus committed
75
  :version "25.2"
76
  :type '(choice (const :tag "Do not override HISTFILE" nil)
77
                 (const :tag "Unset HISTFILE" t)
Michael Albinus's avatar
Michael Albinus committed
78
                 (string :tag "Redirect to a file")))
79

80
;;;###tramp-autoload
Michael Albinus's avatar
Michael Albinus committed
81
(defconst tramp-display-escape-sequence-regexp "\e[[:digit:];[]+m"
Michael Albinus's avatar
Michael Albinus committed
82 83
  "Terminal control escape sequences for display attributes.")

Michael Albinus's avatar
Michael Albinus committed
84
(defconst tramp-device-escape-sequence-regexp "\e[[:digit:][]+n"
Michael Albinus's avatar
Michael Albinus committed
85
  "Terminal control escape sequences for device status.")
86

87
;; ksh on OpenBSD 4.5 requires that $PS1 contains a `#' character for
88
;; root users.  It uses the `$' character for other users.  In order
89
;; to guarantee a proper prompt, we use "#$ " for the prompt.
90 91 92 93 94 95

(defvar tramp-end-of-output
  (format
   "///%s#$"
   (md5 (concat (prin1-to-string process-environment) (current-time-string))))
  "String used to recognize end of output.
96
The `$' character at the end is quoted; the string cannot be
97 98 99 100 101 102
detected as prompt when being sent on echoing hosts, therefore.")

;;;###tramp-autoload
(defconst tramp-initial-end-of-output "#$ "
  "Prompt when establishing a connection.")

103 104 105
(defconst tramp-end-of-heredoc (md5 tramp-end-of-output)
  "String used to recognize end of heredoc strings.")

106
(defcustom tramp-use-ssh-controlmaster-options (not (eq system-type 'windows-nt))
Michael Albinus's avatar
Michael Albinus committed
107 108 109
  "Whether to use `tramp-ssh-controlmaster-options'.
Set it to nil, if you use Control* or Proxy* options in your ssh
configuration."
110
  :group 'tramp
111
  :version "28.1"
Michael Albinus's avatar
Michael Albinus committed
112
  :type 'boolean)
113 114 115 116 117

(defvar tramp-ssh-controlmaster-options nil
  "Which ssh Control* arguments to use.

If it is a string, it should have the form
118
\"-o ControlMaster=auto -o ControlPath=\\='tramp.%%r@%%h:%%p\\='
119 120 121 122 123 124 125 126 127
-o ControlPersist=no\".  Percent characters in the ControlPath
spec must be doubled, because the string is used as format string.

Otherwise, it will be auto-detected by Tramp, if
`tramp-use-ssh-controlmaster-options' is non-nil.  The value
depends on the installed local ssh version.

The string is used in `tramp-methods'.")

128 129 130 131 132 133 134 135 136
(defvar tramp-scp-strict-file-name-checking nil
  "Which scp strict file name checking argument to use.

It is the string \"-T\" if supported by the local scp (since
release 8.0), otherwise the string \"\".  If it is nil, it will
be auto-detected by Tramp.

The string is used in `tramp-methods'.")

137 138
;; Initialize `tramp-methods' with the supported methods.
;;;###tramp-autoload
139 140
(tramp--with-startup
 (add-to-list 'tramp-methods
141
              `("rcp"
142 143
                (tramp-login-program        "rsh")
                (tramp-login-args           (("%h") ("-l" "%u")))
144
                (tramp-remote-shell         ,tramp-default-remote-shell)
145 146 147 148 149 150 151
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))
                (tramp-copy-program         "rcp")
                (tramp-copy-args            (("-p" "%k") ("-r")))
                (tramp-copy-keep-date       t)
                (tramp-copy-recursive       t)))
 (add-to-list 'tramp-methods
152
              `("remcp"
153 154
                (tramp-login-program        "remsh")
                (tramp-login-args           (("%h") ("-l" "%u")))
155
                (tramp-remote-shell         ,tramp-default-remote-shell)
156 157 158 159 160 161
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))
                (tramp-copy-program         "rcp")
                (tramp-copy-args            (("-p" "%k")))
                (tramp-copy-keep-date       t)))
 (add-to-list 'tramp-methods
162
              `("scp"
163 164 165 166
                (tramp-login-program        "ssh")
                (tramp-login-args           (("-l" "%u") ("-p" "%p") ("%c")
				             ("-e" "none") ("%h")))
                (tramp-async-args           (("-q")))
167
                (tramp-direct-async         t)
168
                (tramp-remote-shell         ,tramp-default-remote-shell)
169 170 171
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))
                (tramp-copy-program         "scp")
172 173
                (tramp-copy-args            (("-P" "%p") ("-p" "%k")
					     ("%x") ("-q") ("-r") ("%c")))
174 175 176
                (tramp-copy-keep-date       t)
                (tramp-copy-recursive       t)))
 (add-to-list 'tramp-methods
177
              `("scpx"
178 179
                (tramp-login-program        "ssh")
                (tramp-login-args           (("-l" "%u") ("-p" "%p") ("%c")
180
				             ("-e" "none") ("-t" "-t")
181 182
					     ("-o" "RemoteCommand=\"%l\"")
					     ("%h")))
183
                (tramp-async-args           (("-q")))
184
                (tramp-remote-shell         ,tramp-default-remote-shell)
185 186 187 188
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))
                (tramp-copy-program         "scp")
                (tramp-copy-args            (("-P" "%p") ("-p" "%k")
189
				             ("%x") ("-q") ("-r") ("%c")))
190 191 192
                (tramp-copy-keep-date       t)
                (tramp-copy-recursive       t)))
 (add-to-list 'tramp-methods
193
              `("rsync"
194 195 196 197
                (tramp-login-program        "ssh")
                (tramp-login-args           (("-l" "%u") ("-p" "%p") ("%c")
				             ("-e" "none") ("%h")))
                (tramp-async-args           (("-q")))
198
                (tramp-direct-async         t)
199
                (tramp-remote-shell         ,tramp-default-remote-shell)
200 201 202
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))
                (tramp-copy-program         "rsync")
203 204
                (tramp-copy-args            (("-t" "%k") ("-p") ("-r") ("-s")
					     ("-c")))
205 206 207 208 209
                (tramp-copy-env             (("RSYNC_RSH") ("ssh" "%c")))
                (tramp-copy-keep-date       t)
                (tramp-copy-keep-tmpfile    t)
                (tramp-copy-recursive       t)))
 (add-to-list 'tramp-methods
210
              `("rsh"
211 212
                (tramp-login-program        "rsh")
                (tramp-login-args           (("%h") ("-l" "%u")))
213
                (tramp-remote-shell         ,tramp-default-remote-shell)
214 215 216
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))))
 (add-to-list 'tramp-methods
217
              `("remsh"
218 219
                (tramp-login-program        "remsh")
                (tramp-login-args           (("%h") ("-l" "%u")))
220
                (tramp-remote-shell         ,tramp-default-remote-shell)
221 222 223
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))))
 (add-to-list 'tramp-methods
224
              `("ssh"
225 226 227 228
                (tramp-login-program        "ssh")
                (tramp-login-args           (("-l" "%u") ("-p" "%p") ("%c")
				             ("-e" "none") ("%h")))
                (tramp-async-args           (("-q")))
229
                (tramp-direct-async         t)
230
                (tramp-remote-shell         ,tramp-default-remote-shell)
231 232 233
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))))
 (add-to-list 'tramp-methods
234
              `("sshx"
235 236
                (tramp-login-program        "ssh")
                (tramp-login-args           (("-l" "%u") ("-p" "%p") ("%c")
237
				             ("-e" "none") ("-t" "-t")
238 239
					     ("-o" "RemoteCommand=\"%l\"")
					     ("%h")))
240
                (tramp-async-args           (("-q")))
241
                (tramp-remote-shell         ,tramp-default-remote-shell)
242 243 244
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))))
 (add-to-list 'tramp-methods
245
              `("telnet"
246
                (tramp-login-program        "telnet")
247
                (tramp-login-args           (("%h") ("%p") ("%n")))
248
                (tramp-remote-shell         ,tramp-default-remote-shell)
249 250 251
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))))
 (add-to-list 'tramp-methods
252
              `("nc"
253
                (tramp-login-program        "telnet")
254
                (tramp-login-args           (("%h") ("%p") ("%n")))
255
                (tramp-remote-shell         ,tramp-default-remote-shell)
256 257 258 259 260 261 262 263 264
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))
                (tramp-copy-program         "nc")
                ;; We use "-v" for better error tracking.
                (tramp-copy-args            (("-w" "1") ("-v") ("%h") ("%r")))
                (tramp-remote-copy-program  "nc")
                ;; We use "-p" as required for newer busyboxes.  For older
                ;; busybox/nc versions, the value must be (("-l") ("%r")).  This
                ;; can be achieved by tweaking `tramp-connection-properties'.
265
                (tramp-remote-copy-args     (("-l") ("-p" "%r") ("%n")))))
266
 (add-to-list 'tramp-methods
267
              `("su"
268 269
                (tramp-login-program        "su")
                (tramp-login-args           (("-") ("%u")))
270
                (tramp-remote-shell         ,tramp-default-remote-shell)
271 272 273 274
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))
                (tramp-connection-timeout   10)))
 (add-to-list 'tramp-methods
275
              `("sg"
276 277
                (tramp-login-program        "sg")
                (tramp-login-args           (("-") ("%u")))
278
                (tramp-remote-shell         ,tramp-default-remote-shell)
279 280 281
                (tramp-remote-shell-args    ("-c"))
                (tramp-connection-timeout   10)))
 (add-to-list 'tramp-methods
282
              `("sudo"
283
                (tramp-login-program        "sudo")
284 285 286
                ;; The password template must be masked.  Otherwise,
                ;; it could be interpreted as password prompt if the
                ;; remote host echoes the command.
287
                (tramp-login-args           (("-u" "%u") ("-s") ("-H")
288 289
				             ("-p" "P\"\"a\"\"s\"\"s\"\"w\"\"o\"\"r\"\"d\"\":")
                                             ("%l")))
290
                (tramp-remote-shell         ,tramp-default-remote-shell)
291 292 293 294 295
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))
                (tramp-connection-timeout   10)
                (tramp-session-timeout      300)))
 (add-to-list 'tramp-methods
296
              `("doas"
297 298
                (tramp-login-program        "doas")
                (tramp-login-args           (("-u" "%u") ("-s")))
299
                (tramp-remote-shell         ,tramp-default-remote-shell)
300 301 302 303
                (tramp-remote-shell-args    ("-c"))
                (tramp-connection-timeout   10)
                (tramp-session-timeout      300)))
 (add-to-list 'tramp-methods
304
              `("ksu"
305 306
                (tramp-login-program        "ksu")
                (tramp-login-args           (("%u") ("-q")))
307
                (tramp-remote-shell         ,tramp-default-remote-shell)
308 309 310 311
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))
                (tramp-connection-timeout   10)))
 (add-to-list 'tramp-methods
312
              `("krlogin"
313 314
                (tramp-login-program        "krlogin")
                (tramp-login-args           (("%h") ("-l" "%u") ("-x")))
315
                (tramp-remote-shell         ,tramp-default-remote-shell)
316 317 318 319 320
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))))
 (add-to-list 'tramp-methods
              `("plink"
                (tramp-login-program        "plink")
321 322
                (tramp-login-args           (("-l" "%u") ("-P" "%p") ("-ssh")
					     ("-t") ("%h") ("\"")
323 324 325 326
				             (,(format
				                "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'"
				                tramp-terminal-type
				                tramp-initial-end-of-output))
327 328
				             ("%l") ("\"")))
                (tramp-remote-shell         ,tramp-default-remote-shell)
329 330 331 332 333 334 335 336 337 338
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))))
 (add-to-list 'tramp-methods
              `("plinkx"
                (tramp-login-program        "plink")
                (tramp-login-args           (("-load") ("%h") ("-t") ("\"")
				             (,(format
				                "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'"
				                tramp-terminal-type
				                tramp-initial-end-of-output))
339 340
				             ("%l") ("\"")))
                (tramp-remote-shell         ,tramp-default-remote-shell)
341 342 343 344 345
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))))
 (add-to-list 'tramp-methods
              `("pscp"
                (tramp-login-program        "plink")
346 347
                (tramp-login-args           (("-l" "%u") ("-P" "%p") ("-ssh")
					     ("-t") ("%h") ("\"")
348 349 350 351
				             (,(format
				                "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'"
				                tramp-terminal-type
				                tramp-initial-end-of-output))
352 353
				             ("%l") ("\"")))
                (tramp-remote-shell         ,tramp-default-remote-shell)
354 355 356
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))
                (tramp-copy-program         "pscp")
357 358
                (tramp-copy-args            (("-l" "%u") ("-P" "%p") ("-scp")
					     ("-p" "%k") ("-q") ("-r")))
359 360 361 362 363
                (tramp-copy-keep-date       t)
                (tramp-copy-recursive       t)))
 (add-to-list 'tramp-methods
              `("psftp"
                (tramp-login-program        "plink")
364 365
                (tramp-login-args           (("-l" "%u") ("-P" "%p") ("-ssh")
					     ("-t") ("%h") ("\"")
366 367 368 369
				             (,(format
				                "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'"
				                tramp-terminal-type
				                tramp-initial-end-of-output))
370 371
				             ("%l") ("\"")))
                (tramp-remote-shell         ,tramp-default-remote-shell)
372 373 374
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-c"))
                (tramp-copy-program         "pscp")
375 376
                (tramp-copy-args            (("-l" "%u") ("-P" "%p") ("-sftp")
					     ("-p" "%k") ("-q")))
377 378
                (tramp-copy-keep-date       t)))
 (add-to-list 'tramp-methods
379
              `("fcp"
380 381
                (tramp-login-program        "fsh")
                (tramp-login-args           (("%h") ("-l" "%u") ("sh" "-i")))
382
                (tramp-remote-shell         ,tramp-default-remote-shell)
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
                (tramp-remote-shell-login   ("-l"))
                (tramp-remote-shell-args    ("-i") ("-c"))
                (tramp-copy-program         "fcp")
                (tramp-copy-args            (("-p" "%k")))
                (tramp-copy-keep-date       t)))

 (add-to-list 'tramp-default-method-alist
	      `(,tramp-local-host-regexp "\\`root\\'" "su"))

 (add-to-list 'tramp-default-user-alist
	      `(,(concat "\\`" (regexp-opt '("su" "sudo" "doas" "ksu")) "\\'")
	        nil "root"))
 ;; Do not add "ssh" based methods, otherwise ~/.ssh/config would be ignored.
 ;; Do not add "plink" based methods, they ask interactively for the user.
 (add-to-list 'tramp-default-user-alist
	      `(,(concat
		  "\\`"
		  (regexp-opt
		   '("rcp" "remcp" "rsh" "telnet" "nc" "krlogin" "fcp"))
		  "\\'")
403
	        nil ,(user-login-name))))
404

405
;;;###tramp-autoload
406 407 408 409 410
(defconst tramp-completion-function-alist-rsh
  '((tramp-parse-rhosts "/etc/hosts.equiv")
    (tramp-parse-rhosts "~/.rhosts"))
  "Default list of (FUNCTION FILE) pairs to be examined for rsh methods.")

411
;;;###tramp-autoload
412
(defconst tramp-completion-function-alist-ssh
413
  `((tramp-parse-rhosts      "/etc/hosts.equiv")
414
    (tramp-parse-rhosts      "/etc/shosts.equiv")
415 416 417 418 419 420 421 422 423 424 425
    ;; On W32 systems, the ssh directory is located somewhere else.
    (tramp-parse-shosts      ,(expand-file-name
			       "ssh/ssh_known_hosts"
			       (or (and (eq system-type 'windows-nt)
					(getenv "ProgramData"))
				   "/etc/")))
    (tramp-parse-sconfig     ,(expand-file-name
			       "ssh/ssh_config"
			       (or (and (eq system-type 'windows-nt)
					(getenv "ProgramData"))
				   "/etc/")))
426 427 428 429
    (tramp-parse-shostkeys   "/etc/ssh2/hostkeys")
    (tramp-parse-sknownhosts "/etc/ssh2/knownhosts")
    (tramp-parse-rhosts      "~/.rhosts")
    (tramp-parse-rhosts      "~/.shosts")
430 431 432 433 434 435 436 437 438 439 440
    ;; On W32 systems, the .ssh directory is located somewhere else.
    (tramp-parse-shosts      ,(expand-file-name
			       ".ssh/known_hosts"
			       (or (and (eq system-type 'windows-nt)
					(getenv "USERPROFILE"))
				   "~/")))
    (tramp-parse-sconfig     ,(expand-file-name
			       ".ssh/config"
			       (or (and (eq system-type 'windows-nt)
					(getenv "USERPROFILE"))
				   "~/")))
441 442 443 444
    (tramp-parse-shostkeys   "~/.ssh2/hostkeys")
    (tramp-parse-sknownhosts "~/.ssh2/knownhosts"))
  "Default list of (FUNCTION FILE) pairs to be examined for ssh methods.")

445
;;;###tramp-autoload
446 447 448 449
(defconst tramp-completion-function-alist-telnet
  '((tramp-parse-hosts "/etc/hosts"))
  "Default list of (FUNCTION FILE) pairs to be examined for telnet methods.")

450
;;;###tramp-autoload
451 452 453 454
(defconst tramp-completion-function-alist-su
  '((tramp-parse-passwd "/etc/passwd"))
  "Default list of (FUNCTION FILE) pairs to be examined for su methods.")

Michael Albinus's avatar
Michael Albinus committed
455 456 457 458 459
;;;###tramp-autoload
(defconst tramp-completion-function-alist-sg
  '((tramp-parse-etc-group "/etc/group"))
  "Default list of (FUNCTION FILE) pairs to be examined for sg methods.")

460
;;;###tramp-autoload
461
(defconst tramp-completion-function-alist-putty
Michael Albinus's avatar
Michael Albinus committed
462
  `((tramp-parse-putty
463
     ,(if (eq system-type 'windows-nt)
Michael Albinus's avatar
Michael Albinus committed
464 465
	  "HKEY_CURRENT_USER\\Software\\SimonTatham\\PuTTY\\Sessions"
	"~/.putty/sessions")))
Michael Albinus's avatar
Michael Albinus committed
466
 "Default list of (FUNCTION REGISTRY) pairs to be examined for putty sessions.")
467

468
;;;###tramp-autoload
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
(tramp--with-startup
 (tramp-set-completion-function "rcp" tramp-completion-function-alist-rsh)
 (tramp-set-completion-function "remcp" tramp-completion-function-alist-rsh)
 (tramp-set-completion-function "scp" tramp-completion-function-alist-ssh)
 (tramp-set-completion-function "scpx" tramp-completion-function-alist-ssh)
 (tramp-set-completion-function "rsync" tramp-completion-function-alist-ssh)
 (tramp-set-completion-function "rsh" tramp-completion-function-alist-rsh)
 (tramp-set-completion-function "remsh" tramp-completion-function-alist-rsh)
 (tramp-set-completion-function "ssh" tramp-completion-function-alist-ssh)
 (tramp-set-completion-function "sshx" tramp-completion-function-alist-ssh)
 (tramp-set-completion-function
  "telnet" tramp-completion-function-alist-telnet)
 (tramp-set-completion-function "nc" 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 "doas" tramp-completion-function-alist-su)
 (tramp-set-completion-function "ksu" tramp-completion-function-alist-su)
 (tramp-set-completion-function "sg" tramp-completion-function-alist-sg)
 (tramp-set-completion-function
  "krlogin" tramp-completion-function-alist-rsh)
 (tramp-set-completion-function "plink" tramp-completion-function-alist-ssh)
 (tramp-set-completion-function
  "plinkx" tramp-completion-function-alist-putty)
 (tramp-set-completion-function "pscp" tramp-completion-function-alist-ssh)
 (tramp-set-completion-function "psftp" tramp-completion-function-alist-ssh)
 (tramp-set-completion-function "fcp" tramp-completion-function-alist-ssh))
495

496
(defcustom tramp-sh-extra-args
497
  '(("/bash\\'" . "-noediting -norc -noprofile")
498
    ("/zsh\\'" . "-f +Z -V"))
499
  "Alist specifying extra arguments to pass to the remote shell.
500 501
Entries are (REGEXP . ARGS) where REGEXP is a regular expression
matching the shell file name and ARGS is a string specifying the
502 503
arguments.  These arguments shall disable line editing, see
`tramp-open-shell'.
504 505 506 507 508

This variable is only used when Tramp needs to start up another shell
for tilde expansion.  The extra arguments should typically prevent the
shell from reading its init file."
  :group 'tramp
509
  :version "27.1"
Michael Albinus's avatar
Michael Albinus committed
510
  :type '(alist :key-type regexp :value-type string))
511 512 513 514 515 516 517 518 519 520

(defconst tramp-actions-before-shell
  '((tramp-login-prompt-regexp tramp-action-login)
    (tramp-password-prompt-regexp tramp-action-password)
    (tramp-wrong-passwd-regexp tramp-action-permission-denied)
    (shell-prompt-pattern tramp-action-succeed)
    (tramp-shell-prompt-pattern tramp-action-succeed)
    (tramp-yesno-prompt-regexp tramp-action-yesno)
    (tramp-yn-prompt-regexp tramp-action-yn)
    (tramp-terminal-prompt-regexp tramp-action-terminal)
521
    (tramp-antispoof-regexp tramp-action-confirm-message)
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545
    (tramp-process-alive-regexp tramp-action-process-alive))
  "List of pattern/action pairs.
Whenever a pattern matches, the corresponding action is performed.
Each item looks like (PATTERN ACTION).

The PATTERN should be a symbol, a variable.  The value of this
variable gives the regular expression to search for.  Note that the
regexp must match at the end of the buffer, \"\\'\" is implicitly
appended to it.

The ACTION should also be a symbol, but a function.  When the
corresponding PATTERN matches, the ACTION function is called.")

(defconst tramp-actions-copy-out-of-band
  '((tramp-password-prompt-regexp tramp-action-password)
    (tramp-wrong-passwd-regexp tramp-action-permission-denied)
    (tramp-copy-failed-regexp tramp-action-permission-denied)
    (tramp-process-alive-regexp tramp-action-out-of-band))
  "List of pattern/action pairs.
This list is used for copying/renaming with out-of-band methods.

See `tramp-actions-before-shell' for more info.")

(defconst tramp-uudecode
Michael Albinus's avatar
Michael Albinus committed
546 547 548
  "(echo begin 600 %t; tail -n +2) | uudecode
cat %t
rm -f %t"
549 550 551
  "Shell function to implement `uudecode' to standard output.
Many systems support `uudecode -o /dev/stdout' or `uudecode -o -'
for this or `uudecode -p', but some systems don't, and for them
552 553 554
we have this shell function.
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
555 556

(defconst tramp-perl-file-truename
557
  "%p -e '
558 559 560
use File::Spec;
use Cwd \"realpath\";

561 562
sub myrealpath {
    my ($file) = @_;
563
    return realpath($file) if (-e $file || -l $file);
564 565
}

566 567
sub recursive {
    my ($volume, @dirs) = @_;
568
    my $real = myrealpath(File::Spec->catpath(
569 570 571 572 573 574 575 576 577 578 579 580 581
                   $volume, File::Spec->catdir(@dirs), \"\"));
    if ($real) {
        my ($vol, $dir) = File::Spec->splitpath($real, 1);
        return ($vol, File::Spec->splitdir($dir));
    }
    else {
        my $last = pop(@dirs);
        ($volume, @dirs) = recursive($volume, @dirs);
        push(@dirs, $last);
        return ($volume, @dirs);
    }
}

582
$result = myrealpath($ARGV[0]);
583 584 585 586 587 588 589
if (!$result) {
    my ($vol, $dir) = File::Spec->splitpath($ARGV[0], 1);
    ($vol, @dirs) = recursive($vol, File::Spec->splitdir($dir));

    $result = File::Spec->catpath($vol, File::Spec->catdir(@dirs), \"\");
}

590
$result =~ s/\"/\\\\\"/g;
591
print \"\\\"$result\\\"\\n\";
592
' \"$1\" %n"
593 594
  "Perl script to produce output suitable for use with `file-truename'
on the remote file system.
595 596
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
597 598

(defconst tramp-perl-file-name-all-completions
599
  "%p -e '
600 601 602
opendir(d, $ARGV[0]) || die(\"$ARGV[0]: $!\\nfail\\n\");
@files = readdir(d); closedir(d);
foreach $f (@files) {
Michael Albinus's avatar
Michael Albinus committed
603 604 605 606 607
 if (-d \"$ARGV[0]/$f\") {
  print \"$f/\\n\";
 }
 else {
  print \"$f\\n\";
608 609 610
 }
}
print \"ok\\n\"
611
' \"$1\" %n"
612
  "Perl script to produce output suitable for use with
613 614 615
`file-name-all-completions' on the remote file system.
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
616 617 618 619 620 621

;; Perl script to implement `file-attributes' in a Lisp `read'able
;; output.  If you are hacking on this, note that you get *no* output
;; unless this spits out a complete line, including the '\n' at the
;; end.
;; The device number is returned as "-1", because there will be a virtual
622
;; device number set in `tramp-sh-handle-file-attributes'.
623
(defconst tramp-perl-file-attributes
624
  "%p -e '
625 626 627 628 629 630 631 632
@stat = lstat($ARGV[0]);
if (!@stat) {
    print \"nil\\n\";
    exit 0;
}
if (($stat[2] & 0170000) == 0120000)
{
    $type = readlink($ARGV[0]);
Michael Albinus's avatar
Michael Albinus committed
633
    $type =~ s/\"/\\\\\"/g;
634 635 636 637 638 639 640 641 642 643 644 645 646
    $type = \"\\\"$type\\\"\";
}
elsif (($stat[2] & 0170000) == 040000)
{
    $type = \"t\";
}
else
{
    $type = \"nil\"
};
$uid = ($ARGV[1] eq \"integer\") ? $stat[4] : \"\\\"\" . getpwuid($stat[4]) . \"\\\"\";
$gid = ($ARGV[1] eq \"integer\") ? $stat[5] : \"\\\"\" . getgrgid($stat[5]) . \"\\\"\";
printf(
647
    \"(%%s %%u %%s %%s (%%u %%u) (%%u %%u) (%%u %%u) %%u %%u t %%u -1)\\n\",
648 649 650 651 652 653 654 655 656 657 658 659
    $type,
    $stat[3],
    $uid,
    $gid,
    $stat[8] >> 16 & 0xffff,
    $stat[8] & 0xffff,
    $stat[9] >> 16 & 0xffff,
    $stat[9] & 0xffff,
    $stat[10] >> 16 & 0xffff,
    $stat[10] & 0xffff,
    $stat[7],
    $stat[2],
Michael Albinus's avatar
Michael Albinus committed
660
    $stat[1]
661
);' \"$1\" \"$2\" %n"
662 663
  "Perl script to produce output suitable for use with `file-attributes'
on the remote file system.
664 665
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
666 667

(defconst tramp-perl-directory-files-and-attributes
668
  "%p -e '
669 670 671 672 673 674 675 676 677 678 679 680 681
chdir($ARGV[0]) or printf(\"\\\"Cannot change to $ARGV[0]: $''!''\\\"\\n\"), exit();
opendir(DIR,\".\") or printf(\"\\\"Cannot open directory $ARGV[0]: $''!''\\\"\\n\"), exit();
@list = readdir(DIR);
closedir(DIR);
$n = scalar(@list);
printf(\"(\\n\");
for($i = 0; $i < $n; $i++)
{
    $filename = $list[$i];
    @stat = lstat($filename);
    if (($stat[2] & 0170000) == 0120000)
    {
        $type = readlink($filename);
Michael Albinus's avatar
Michael Albinus committed
682
        $type =~ s/\"/\\\\\"/g;
683 684 685 686 687 688 689 690 691 692 693 694
        $type = \"\\\"$type\\\"\";
    }
    elsif (($stat[2] & 0170000) == 040000)
    {
        $type = \"t\";
    }
    else
    {
        $type = \"nil\"
    };
    $uid = ($ARGV[1] eq \"integer\") ? $stat[4] : \"\\\"\" . getpwuid($stat[4]) . \"\\\"\";
    $gid = ($ARGV[1] eq \"integer\") ? $stat[5] : \"\\\"\" . getgrgid($stat[5]) . \"\\\"\";
Michael Albinus's avatar
Michael Albinus committed
695
    $filename =~ s/\"/\\\\\"/g;
696
    printf(
697
        \"(\\\"%%s\\\" %%s %%u %%s %%s (%%u %%u) (%%u %%u) (%%u %%u) %%u %%u t %%u -1)\\n\",
698 699 700 701 702 703 704 705 706 707 708 709 710
        $filename,
        $type,
        $stat[3],
        $uid,
        $gid,
        $stat[8] >> 16 & 0xffff,
        $stat[8] & 0xffff,
        $stat[9] >> 16 & 0xffff,
        $stat[9] & 0xffff,
        $stat[10] >> 16 & 0xffff,
        $stat[10] & 0xffff,
        $stat[7],
        $stat[2],
711
        $stat[1]);
712
}
713
printf(\")\\n\");' \"$1\" \"$2\" %n"
714
  "Perl script implementing `directory-files-and-attributes' as Lisp `read'able
715
output.
716 717
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
718 719 720

;; These two use base64 encoding.
(defconst tramp-perl-encode-with-module
721
  "%p -MMIME::Base64 -0777 -ne 'print encode_base64($_)' %n"
722 723
  "Perl program to use for encoding a file.
This implementation requires the MIME::Base64 Perl module to be installed
724 725 726
on the remote host.
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
727 728

(defconst tramp-perl-decode-with-module
729
  "%p -MMIME::Base64 -0777 -ne 'print decode_base64($_)' %n"
730 731
  "Perl program to use for decoding a file.
This implementation requires the MIME::Base64 Perl module to be installed
732 733 734
on the remote host.
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
735 736

(defconst tramp-perl-encode
737
  "%p -e '
738
# This script contributed by Juanma Barranquero <lektu@terra.es>.
Paul Eggert's avatar
Paul Eggert committed
739
# Copyright (C) 2002-2021 Free Software Foundation, Inc.
740 741 742 743 744 745 746
use strict;

my %%trans = do {
    my $i = 0;
    map {(substr(unpack(q(B8), chr $i++), 2, 6), $_)}
      split //, q(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/);
};
747
my $data;
748 749 750

# We read in chunks of 54 bytes, to generate output lines
# of 72 chars (plus end of line)
751
while (read STDIN, $data, 54) {
752 753
    my $pad = q();

754 755
    # Only for the last chunk, and only if did not fill the last
    # three-byte packet
756 757 758 759 760 761 762 763 764 765 766 767 768 769
    if (eof) {
        my $mod = length($data) %% 3;
        $pad = q(=) x (3 - $mod) if $mod;
    }

    # Not the fastest method, but it is simple: unpack to binary string, split
    # by groups of 6 bits and convert back from binary to byte; then map into
    # the translation table
    print
      join q(),
        map($trans{$_},
            (substr(unpack(q(B*), $data) . q(00000), 0, 432) =~ /....../g)),
              $pad,
                qq(\\n);
770
}' %n"
771
  "Perl program to use for encoding a file.
772 773
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
774 775

(defconst tramp-perl-decode
776
  "%p -e '
777
# This script contributed by Juanma Barranquero <lektu@terra.es>.
Paul Eggert's avatar
Paul Eggert committed
778
# Copyright (C) 2002-2021 Free Software Foundation, Inc.
779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813
use strict;

my %%trans = do {
    my $i = 0;
    map {($_, substr(unpack(q(B8), chr $i++), 2, 6))}
      split //, q(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/)
};

my %%bytes = map {(unpack(q(B8), chr $_), chr $_)} 0 .. 255;

binmode(\\*STDOUT);

# We are going to accumulate into $pending to accept any line length
# (we do not check they are <= 76 chars as the RFC says)
my $pending = q();

while (my $data = <STDIN>) {
    chomp $data;

    # If we find one or two =, we have reached the end and
    # any following data is to be discarded
    my $finished = $data =~ s/(==?).*/$1/;
    $pending .= $data;

    my $len = length($pending);
    my $chunk = substr($pending, 0, $len & ~3);
    $pending = substr($pending, $len & ~3 + 1);

    # Easy method: translate from chars to (pregenerated) six-bit packets, join,
    # split in 8-bit chunks and convert back to char.
    print join q(),
      map $bytes{$_},
        ((join q(), map {$trans{$_} || q()} split //, $chunk) =~ /......../g);

    last if $finished;
814
}' %n"
815
  "Perl program to use for decoding a file.
816 817
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
818

819
(defconst tramp-perl-pack
820
  "%p -e 'binmode STDIN; binmode STDOUT; print pack(q{u*}, join q{}, <>)' %n"
821
  "Perl program to use for encoding a file.
822 823
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
824 825

(defconst tramp-perl-unpack
826
  "%p -e 'binmode STDIN; binmode STDOUT; print unpack(q{u*}, join q{}, <>)' %n"
827
  "Perl program to use for decoding a file.
828 829
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
830

831 832
(defconst tramp-hexdump-encode "%h -v -e '16/1 \" %%02x\" \"\\n\"'"
  "`hexdump' program to use for encoding a file.
833 834
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
835

836
(defconst tramp-awk-encode
837
  "%a '\\
838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866
BEGIN {
  b64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"
  b16 = \"0123456789abcdef\"
}
{
  for (c=1; c<=length($0); c++) {
    d=index(b16, substr($0,c,1))
    if (d--) {
      for (b=1; b<=4; b++) {
        o=o*2+int(d/8); d=(d*2)%%16
        if (++obc==6) {
          printf substr(b64,o+1,1)
          if (++rc>75) { printf \"\\n\"; rc=0 }
          obc=0; o=0
        }
      }
    }
  }
}
END {
  if (obc) {
    tail=(obc==2) ? \"==\\n\" : \"=\\n\"
    while (obc++<6) { o=o*2 }
    printf \"%%c\", substr(b64,o+1,1)
  } else {
    tail=\"\\n\"
  }
  printf tail
}'"
867
  "`awk' program to use for encoding a file.
868 869
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
870 871 872 873

(defconst tramp-hexdump-awk-encode
  (format "%s | %s" tramp-hexdump-encode tramp-awk-encode)
  "`hexdump' / `awk' pipe to use for encoding a file.
874 875
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
876 877 878

(defconst tramp-od-encode "%o -v -t x1 -A n"
  "`od' program to use for encoding a file.
879 880
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
881

882
(defconst tramp-od-awk-encode (format "%s | %s" tramp-od-encode tramp-awk-encode)
883
  "`od' / `awk' pipe to use for encoding a file.
884 885
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
886 887

(defconst tramp-awk-decode
888
  "%a '\\
889 890 891 892 893 894 895 896 897 898 899 900 901
BEGIN {
  b64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"
}
{
  for (i=1; i<=length($0); i++) {
    c=index(b64, substr($0,i,1))
    if(c--) {
      for(b=0; b<6; b++) {
        o=o*2+int(c/32); c=(c*2)%%64
        if(++obc==8) {
          if (o) {
            printf \"%%c\", o
          } else {
902
            system(\"dd if=/dev/zero bs=1 count=1 %n\")
903 904 905 906 907 908 909 910
          }
          obc=0; o=0
        }
      }
    }
  }
}'"
  "Awk program to use for decoding a file.
911 912
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
913

914 915 916
(defconst tramp-vc-registered-read-file-names
  "echo \"(\"
while read file; do
Michael Albinus's avatar
Michael Albinus committed
917
    quoted=`echo \"$file\" | sed -e \"s/\\\"/\\\\\\\\\\\\\\\\\\\"/\"`
918
    if %s \"$file\"; then
Michael Albinus's avatar
Michael Albinus committed
919
	echo \"(\\\"$quoted\\\" \\\"file-exists-p\\\" t)\"
920
    else
Michael Albinus's avatar
Michael Albinus committed
921
	echo \"(\\\"$quoted\\\" \\\"file-exists-p\\\" nil)\"
922 923
    fi
    if %s \"$file\"; then
Michael Albinus's avatar
Michael Albinus committed
924
	echo \"(\\\"$quoted\\\" \\\"file-readable-p\\\" t)\"
925
    else
Michael Albinus's avatar
Michael Albinus committed
926
	echo \"(\\\"$quoted\\\" \\\"file-readable-p\\\" nil)\"
927 928 929 930 931 932 933
    fi
done
echo \")\""
  "Script to check existence of VC related files.
It must be send formatted with two strings; the tests for file
existence, and file readability.  Input shall be read via
here-document, otherwise the command could exceed maximum length
934 935
of command line.
Format specifiers \"%s\" are replaced before the script is used.")
936

Michael Albinus's avatar
Michael Albinus committed
937
;; New handlers should be added here.
Michael Albinus's avatar
Michael Albinus committed
938
;;;###tramp-autoload
939
(defconst tramp-sh-file-name-handler-alist
940
  '((access-file . tramp-handle-access-file)
941
    (add-name-to-file . tramp-sh-handle-add-name-to-file)
Michael Albinus's avatar
Michael Albinus committed
942
    ;; `byte-compiler-base-file-name' performed by default handler.
943
    (copy-directory . tramp-sh-handle-copy-directory)
Michael Albinus's avatar
Michael Albinus committed
944
    (copy-file . tramp-sh-handle-copy-file)
945 946
    (delete-directory . tramp-sh-handle-delete-directory)
    (delete-file . tramp-sh-handle-delete-file)
Michael Albinus's avatar
Michael Albinus committed
947
    ;; `diff-latest-backup-file' performed by default handler.
948
    (directory-file-name . tramp-handle-directory-file-name)
Michael Albinus's avatar
Michael Albinus committed
949 950 951 952 953
    (directory-files . tramp-handle-directory-files)
    (directory-files-and-attributes
     . tramp-sh-handle-directory-files-and-attributes)
    (dired-compress-file . tramp-sh-handle-dired-compress-file)
    (dired-uncache . tramp-handle-dired-uncache)
954
    (exec-path . tramp-sh-handle-exec-path)
955
    (expand-file-name . tramp-sh-handle-expand-file-name)
Michael Albinus's avatar
Michael Albinus committed
956 957 958 959
    (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
    (file-acl . tramp-sh-handle-file-acl)
    (file-attributes . tramp-sh-handle-file-attributes)
    (file-directory-p . tramp-sh-handle-file-directory-p)
960
    (file-equal-p . tramp-handle-file-equal-p)
Michael Albinus's avatar
Michael Albinus committed
961 962
    (file-executable-p . tramp-sh-handle-file-executable-p)
    (file-exists-p . tramp-sh-handle-file-exists-p)
963
    (file-in-directory-p . tramp-handle-file-in-directory-p)
964
    (file-local-copy . tramp-sh-handle-file-local-copy)
965
    (file-locked-p . tramp-handle-file-locked-p)
Michael Albinus's avatar
Michael Albinus committed
966 967 968
    (file-modes . tramp-handle-file-modes)
    (file-name-all-completions . tramp-sh-handle-file-name-all-completions)
    (file-name-as-directory . tramp-handle-file-name-as-directory)
969
    (file-name-case-insensitive-p . tramp-handle-file-name-case-insensitive-p)
Michael Albinus's avatar
Michael Albinus committed
970 971 972 973
    (file-name-completion . tramp-handle-file-name-completion)
    (file-name-directory . tramp-handle-file-name-directory)
    (file-name-nondirectory . tramp-handle-file-name-nondirectory)