NEWS update for landmark.
[bpt/emacs.git] / lisp / net / tramp.el
CommitLineData
b1a2b924 1;;; tramp.el --- Transparent Remote Access, Multiple Protocol
fb7933a3 2
acaf905b 3;; Copyright (C) 1998-2012 Free Software Foundation, Inc.
fb7933a3 4
cdd44874 5;; Author: Kai Großjohann <kai.grossjohann@gmx.net>
d2a2c17f 6;; Michael Albinus <michael.albinus@gmx.de>
fb7933a3 7;; Keywords: comm, processes
0f34aa77 8;; Package: tramp
fb7933a3
KG
9
10;; This file is part of GNU Emacs.
11
874a927a 12;; GNU Emacs is free software: you can redistribute it and/or modify
fb7933a3 13;; it under the terms of the GNU General Public License as published by
874a927a
GM
14;; the Free Software Foundation, either version 3 of the License, or
15;; (at your option) any later version.
fb7933a3
KG
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
874a927a 23;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
fb7933a3
KG
24
25;;; Commentary:
26
27;; This package provides remote file editing, similar to ange-ftp.
28;; The difference is that ange-ftp uses FTP to transfer files between
29;; the local and the remote host, whereas tramp.el uses a combination
30;; of rsh and rcp or other work-alike programs, such as ssh/scp.
31;;
b1a2b924 32;; For more detailed instructions, please see the info file.
fb7933a3
KG
33;;
34;; Notes:
35;; -----
bf247b6e 36;;
b533bc97 37;; This package only works for Emacs 22.1 and higher, and for XEmacs 21.4
00d6fd04 38;; and higher. For XEmacs 21, you need the package `fsf-compat' for
7f4d4a97 39;; the `with-timeout' macro.
fb7933a3 40;;
fb7933a3
KG
41;; Also see the todo list at the bottom of this file.
42;;
b1a2b924 43;; The current version of Tramp can be retrieved from the following URL:
340b8d4f 44;; http://ftp.gnu.org/gnu/tramp/
fb7933a3
KG
45;;
46;; There's a mailing list for this, as well. Its name is:
340b8d4f
MA
47;; tramp-devel@gnu.org
48;; You can use the Web to subscribe, under the following URL:
49;; http://lists.gnu.org/mailman/listinfo/tramp-devel
fb7933a3
KG
50;;
51;; For the adventurous, the current development sources are available
52;; via CVS. You can find instructions about this at the following URL:
c62c9d08 53;; http://savannah.gnu.org/projects/tramp/
fb7933a3
KG
54;; Click on "CVS" in the navigation bar near the top.
55;;
56;; Don't forget to put on your asbestos longjohns, first!
57
58;;; Code:
59
9e6ab520 60(require 'tramp-compat)
fb7933a3 61
fb7933a3
KG
62;;; User Customizable Internal Variables:
63
64(defgroup tramp nil
65 "Edit remote files with a combination of rsh and rcp or similar programs."
589d30dd 66 :group 'files
26f4b8ab 67 :group 'comm
bf247b6e 68 :version "22.1")
fb7933a3 69
2e271195
MA
70;; Maybe we need once a real Tramp mode, with key bindings etc.
71;;;###autoload
72(defcustom tramp-mode t
73 "*Whether Tramp is enabled.
74If it is set to nil, all remote file names are used literally."
75 :group 'tramp
76 :type 'boolean)
77
00d6fd04 78(defcustom tramp-verbose 3
263c02ef 79 "*Verbosity level for Tramp messages.
00d6fd04
MA
80Any level x includes messages for all levels 1 .. x-1. The levels are
81
82 0 silent (no tramp messages at all)
83 1 errors
84 2 warnings
85 3 connection to remote hosts (default level)
86 4 activities
87 5 internal
88 6 sent and received strings
89 7 file caching
90 8 connection properties
8fbcce2d 91 9 test commands
00d6fd04 9210 traces (huge)."
fb7933a3
KG
93 :group 'tramp
94 :type 'integer)
95
263c02ef 96;; Emacs case.
38c65fca
KG
97(eval-and-compile
98 (when (boundp 'backup-directory-alist)
99 (defcustom tramp-backup-directory-alist nil
100 "Alist of filename patterns and backup directory names.
101Each element looks like (REGEXP . DIRECTORY), with the same meaning like
102in `backup-directory-alist'. If a Tramp file is backed up, and DIRECTORY
103is a local file name, the backup directory is prepended with Tramp file
00d6fd04 104name prefix \(method, user, host\) of file.
38c65fca
KG
105
106\(setq tramp-backup-directory-alist backup-directory-alist\)
107
108gives the same backup policy for Tramp files on their hosts like the
109policy for local files."
110 :group 'tramp
111 :type '(repeat (cons (regexp :tag "Regexp matching filename")
112 (directory :tag "Backup directory name"))))))
113
114;; XEmacs case. We cannot check for `bkup-backup-directory-info', because
115;; the package "backup-dir" might not be loaded yet.
116(eval-and-compile
117 (when (featurep 'xemacs)
118 (defcustom tramp-bkup-backup-directory-info nil
119 "*Alist of (FILE-REGEXP BACKUP-DIR OPTIONS ...))
120It has the same meaning like `bkup-backup-directory-info' from package
121`backup-dir'. If a Tramp file is backed up, and BACKUP-DIR is a local
122file name, the backup directory is prepended with Tramp file name prefix
00d6fd04 123\(method, user, host\) of file.
38c65fca
KG
124
125\(setq tramp-bkup-backup-directory-info bkup-backup-directory-info\)
126
127gives the same backup policy for Tramp files on their hosts like the
128policy for local files."
bf247b6e 129 :type '(repeat
38c65fca
KG
130 (list (regexp :tag "File regexp")
131 (string :tag "Backup Dir")
132 (set :inline t
133 (const ok-create)
134 (const full-path)
135 (const prepend-name)
136 (const search-upward))))
137 :group 'tramp)))
138
fb7933a3
KG
139(defcustom tramp-auto-save-directory nil
140 "*Put auto-save files in this directory, if set.
141The idea is to use a local directory so that auto-saving is faster."
142 :group 'tramp
00d6fd04 143 :type '(choice (const nil) string))
fb7933a3 144
16674e4f
KG
145(defcustom tramp-encoding-shell
146 (if (memq system-type '(windows-nt))
147 (getenv "COMSPEC")
148 "/bin/sh")
149 "*Use this program for encoding and decoding commands on the local host.
150This shell is used to execute the encoding and decoding command on the
151local host, so if you want to use `~' in those commands, you should
152choose a shell here which groks tilde expansion. `/bin/sh' normally
153does not understand tilde expansion.
154
4c36be58 155For encoding and decoding, commands like the following are executed:
16674e4f
KG
156
157 /bin/sh -c COMMAND < INPUT > OUTPUT
158
159This variable can be used to change the \"/bin/sh\" part. See the
00d6fd04 160variable `tramp-encoding-command-switch' for the \"-c\" part.
fb7933a3 161
36b148cf
MA
162If the shell must be forced to be interactive, see
163`tramp-encoding-command-interactive'.
164
fb7933a3
KG
165Note that this variable is not used for remote commands. There are
166mechanisms in tramp.el which automatically determine the right shell to
167use for the remote host."
168 :group 'tramp
169 :type '(file :must-match t))
170
16674e4f
KG
171(defcustom tramp-encoding-command-switch
172 (if (string-match "cmd\\.exe" tramp-encoding-shell)
173 "/c"
174 "-c")
175 "*Use this switch together with `tramp-encoding-shell' for local commands.
176See the variable `tramp-encoding-shell' for more information."
177 :group 'tramp
178 :type 'string)
179
36b148cf
MA
180(defcustom tramp-encoding-command-interactive
181 (unless (string-match "cmd\\.exe" tramp-encoding-shell) "-i")
182 "*Use this switch together with `tramp-encoding-shell' for interactive shells.
183See the variable `tramp-encoding-shell' for more information."
184 :group 'tramp
185 :type '(choice (const nil) string))
186
0f34aa77 187;;;###tramp-autoload
03c1ad43 188(defvar tramp-methods nil
fb7933a3
KG
189 "*Alist of methods for remote files.
190This is a list of entries of the form (NAME PARAM1 PARAM2 ...).
191Each NAME stands for a remote access method. Each PARAM is a
192pair of the form (KEY VALUE). The following KEYs are defined:
f5e29b9b 193 * `tramp-remote-shell'
710dec63
MA
194 This specifies the shell to use on the remote host. This
195 MUST be a Bourne-like shell. It is normally not necessary to
196 set this to any value other than \"/bin/sh\": Tramp wants to
197 use a shell which groks tilde expansion, but it can search
198 for it. Also note that \"/bin/sh\" exists on all Unixen,
199 this might not be true for the value that you decide to use.
200 You Have Been Warned.
f5e29b9b
MA
201 * `tramp-remote-shell-args'
202 For implementation of `shell-command', this specifies the
710dec63 203 arguments to let `tramp-remote-shell' run a single command.
b25a52cc
KG
204 * `tramp-login-program'
205 This specifies the name of the program to use for logging in to the
00d6fd04
MA
206 remote host. This may be the name of rsh or a workalike program,
207 or the name of telnet or a workalike, or the name of su or a workalike.
b25a52cc 208 * `tramp-login-args'
fb7933a3 209 This specifies the list of arguments to pass to the above
00d6fd04 210 mentioned program. Please note that this is a list of list of arguments,
fb7933a3 211 that is, normally you don't want to put \"-a -b\" or \"-f foo\"
00d6fd04
MA
212 here. Instead, you want a list (\"-a\" \"-b\"), or (\"-f\" \"foo\").
213 There are some patterns: \"%h\" in this list is replaced by the host
214 name, \"%u\" is replaced by the user name, \"%p\" is replaced by the
215 port number, and \"%%\" can be used to obtain a literal percent character.
216 If a list containing \"%h\", \"%u\" or \"%p\" is unchanged during
217 expansion (i.e. no host or no user specified), this list is not used as
218 argument. By this, arguments like (\"-l\" \"%u\") are optional.
219 \"%t\" is replaced by the temporary file name produced with
220 `tramp-make-tramp-temp-file'. \"%k\" indicates the keep-date
221 parameter of a program, if exists.
a7723e05
MA
222 * `tramp-async-args'
223 When an asynchronous process is started, we know already that
224 the connection works. Therefore, we can pass additional
225 parameters to suppress diagnostic messages, in order not to
226 tamper the process output.
b25a52cc
KG
227 * `tramp-copy-program'
228 This specifies the name of the program to use for remotely copying
229 the file; this might be the absolute filename of rcp or the name of
230 a workalike program.
231 * `tramp-copy-args'
fb7933a3 232 This specifies the list of parameters to pass to the above mentioned
b25a52cc 233 program, the hints for `tramp-login-args' also apply here.
00d6fd04
MA
234 * `tramp-copy-keep-date'
235 This specifies whether the copying program when the preserves the
236 timestamp of the original file.
b88f2d0a
MA
237 * `tramp-copy-keep-tmpfile'
238 This specifies whether a temporary local file shall be kept
239 for optimization reasons (useful for \"rsync\" methods).
240 * `tramp-copy-recursive'
241 Whether the operation copies directories recursively.
00d6fd04
MA
242 * `tramp-default-port'
243 The default port of a method is needed in case of gateway connections.
244 Additionally, it is used as indication which method is prepared for
245 passing gateways.
246 * `tramp-gw-args'
247 As the attribute name says, additional arguments are specified here
248 when a method is applied via a gateway.
90f8dc03
KG
249 * `tramp-password-end-of-line'
250 This specifies the string to use for terminating the line after
251 submitting the password. If this method parameter is nil, then the
252 value of the normal variable `tramp-default-password-end-of-line'
253 is used. This parameter is necessary because the \"plink\" program
254 requires any two characters after sending the password. These do
255 not have to be newline or carriage return characters. Other login
256 programs are happy with just one character, the newline character.
257 We use \"xy\" as the value for methods using \"plink\".
710dec63
MA
258 * `tramp-tmpdir'
259 A directory on the remote host for temporary files. If not
260 specified, \"/tmp\" is taken as default.
b25a52cc
KG
261
262What does all this mean? Well, you should specify `tramp-login-program'
263for all methods; this program is used to log in to the remote site. Then,
264there are two ways to actually transfer the files between the local and the
265remote side. One way is using an additional rcp-like program. If you want
266to do this, set `tramp-copy-program' in the method.
fb7933a3
KG
267
268Another possibility for file transfer is inline transfer, i.e. the
b25a52cc 269file is passed through the same buffer used by `tramp-login-program'. In
fb7933a3 270this case, the file contents need to be protected since the
b25a52cc 271`tramp-login-program' might use escape codes or the connection might not
fb7933a3 272be eight-bit clean. Therefore, file contents are encoded for transit.
00d6fd04
MA
273See the variables `tramp-local-coding-commands' and
274`tramp-remote-coding-commands' for details.
fb7933a3 275
16674e4f 276So, to summarize: if the method is an out-of-band method, then you
b25a52cc 277must specify `tramp-copy-program' and `tramp-copy-args'. If it is an
00d6fd04
MA
278inline method, then these two parameters should be nil. Methods which
279are fit for gateways must have `tramp-default-port' at least.
fb7933a3
KG
280
281Notes:
282
00d6fd04
MA
283When using `su' or `sudo' the phrase `open connection to a remote
284host' sounds strange, but it is used nevertheless, for consistency.
285No connection is opened to a remote host, but `su' or `sudo' is
286started on the local host. You should specify a remote host
287`localhost' or the name of the local host. Another host name is
288useful only in combination with `tramp-default-proxies-alist'.")
fb7933a3 289
a92375d9
MA
290(defun tramp-detect-ssh-controlmaster ()
291 "Call ssh to detect whether it supports the ControlMaster argument.
292This function may return nil when the argument is supported, but
293shouldn't return t when it isn't."
294 (ignore-errors
295 (with-temp-buffer
296 (call-process "ssh" nil t nil "-o" "ControlMaster")
297 (goto-char (point-min))
298 (search-forward-regexp "Missing ControlMaster argument" nil t))))
299
b25a52cc 300(defcustom tramp-default-method
fa463103
PE
301 ;; An external copy method seems to be preferred, because it performs
302 ;; much better for large files, and it hasn't too serious delays
83e20b5c
MA
303 ;; for small files. But it must be ensured that there aren't
304 ;; permanent password queries. Either a password agent like
263c02ef
MA
305 ;; "ssh-agent" or "Pageant" shall run, or the optional
306 ;; password-cache.el or auth-sources.el packages shall be active for
a92375d9
MA
307 ;; password caching. "scpc" is chosen if we detect that the user is
308 ;; running OpenSSH 4.0 or newer.
00d6fd04 309 (cond
362b9d48
GM
310 ;; PuTTY is installed. We don't take it, if it is installed on a
311 ;; non-windows system, or pscp from the pssh (parallel ssh) package
312 ;; is found.
313 ((and (eq system-type 'windows-nt)
314 (executable-find "pscp"))
00d6fd04 315 (if (or (fboundp 'password-read)
263c02ef 316 (fboundp 'auth-source-user-or-password)
563790b6 317 (fboundp 'auth-source-search)
00d6fd04 318 ;; Pageant is running.
70c11b0b 319 (tramp-compat-process-running-p "Pageant"))
00d6fd04
MA
320 "pscp"
321 "plink"))
322 ;; There is an ssh installation.
323 ((executable-find "scp")
a92375d9
MA
324 (cond
325 ((tramp-detect-ssh-controlmaster) "scpc")
326 ((or (fboundp 'password-read)
327 (fboundp 'auth-source-user-or-password)
563790b6 328 (fboundp 'auth-source-search)
a92375d9
MA
329 ;; ssh-agent is running.
330 (getenv "SSH_AUTH_SOCK")
331 (getenv "SSH_AGENT_PID"))
332 "scp")
333 (t "ssh")))
00d6fd04
MA
334 ;; Fallback.
335 (t "ftp"))
fb7933a3 336 "*Default method to use for transferring files.
c62c9d08 337See `tramp-methods' for possibilities.
4007ba5b 338Also see `tramp-default-method-alist'."
c62c9d08
KG
339 :group 'tramp
340 :type 'string)
341
b191c9d9 342;;;###tramp-autoload
03c1ad43 343(defcustom tramp-default-method-alist nil
00d6fd04 344 "*Default method to use for specific host/user pairs.
c62c9d08
KG
345This is an alist of items (HOST USER METHOD). The first matching item
346specifies the method to use for a file name which does not specify a
347method. HOST and USER are regular expressions or nil, which is
348interpreted as a regular expression which always matches. If no entry
349matches, the variable `tramp-default-method' takes effect.
350
351If the file name does not specify the user, lookup is done using the
352empty string for the user name.
353
354See `tramp-methods' for a list of possibilities for METHOD."
355 :group 'tramp
e40fc745
MA
356 :type '(repeat (list (choice :tag "Host regexp" regexp sexp)
357 (choice :tag "User regexp" regexp sexp)
358 (choice :tag "Method name" string (const nil)))))
c62c9d08 359
03c1ad43 360(defcustom tramp-default-user nil
00d6fd04
MA
361 "*Default user to use for transferring files.
362It is nil by default; otherwise settings in configuration files like
363\"~/.ssh/config\" would be overwritten. Also see `tramp-default-user-alist'.
364
365This variable is regarded as obsolete, and will be removed soon."
366 :group 'tramp
367 :type '(choice (const nil) string))
368
b191c9d9 369;;;###tramp-autoload
03c1ad43 370(defcustom tramp-default-user-alist nil
00d6fd04
MA
371 "*Default user to use for specific method/host pairs.
372This is an alist of items (METHOD HOST USER). The first matching item
373specifies the user to use for a file name which does not specify a
374user. METHOD and USER are regular expressions or nil, which is
375interpreted as a regular expression which always matches. If no entry
376matches, the variable `tramp-default-user' takes effect.
377
378If the file name does not specify the method, lookup is done using the
379empty string for the method name."
380 :group 'tramp
e40fc745
MA
381 :type '(repeat (list (choice :tag "Method regexp" regexp sexp)
382 (choice :tag " Host regexp" regexp sexp)
383 (choice :tag " User name" string (const nil)))))
00d6fd04 384
03c1ad43 385(defcustom tramp-default-host (system-name)
00d6fd04
MA
386 "*Default host to use for transferring files.
387Useful for su and sudo methods mostly."
388 :group 'tramp
389 :type 'string)
390
391(defcustom tramp-default-proxies-alist nil
392 "*Route to be followed for specific host/user pairs.
393This is an alist of items (HOST USER PROXY). The first matching
394item specifies the proxy to be passed for a file name located on
395a remote target matching USER@HOST. HOST and USER are regular
70c11b0b
MA
396expressions. PROXY must be a Tramp filename without a localname
397part. Method and user name on PROXY are optional, which is
398interpreted with the default values. PROXY can contain the
399patterns %h and %u, which are replaced by the strings matching
400HOST or USER, respectively.
401
402HOST, USER or PROXY could also be Lisp forms, which will be
403evaluated. The result must be a string or nil, which is
404interpreted as a regular expression which always matches."
00d6fd04 405 :group 'tramp
70c11b0b
MA
406 :type '(repeat (list (choice :tag "Host regexp" regexp sexp)
407 (choice :tag "User regexp" regexp sexp)
e40fc745 408 (choice :tag " Proxy name" string (const nil)))))
00d6fd04 409
b191c9d9 410;;;###tramp-autoload
b96e6899
MA
411(defconst tramp-local-host-regexp
412 (concat
66feec8b
MA
413 "\\`"
414 (regexp-opt
415 (list "localhost" "localhost6" (system-name) "127\.0\.0\.1" "::1") t)
416 "\\'")
b96e6899
MA
417 "*Host names which are regarded as local host.")
418
5ec2cc41 419(defvar tramp-completion-function-alist nil
16674e4f 420 "*Alist of methods for remote files.
b533bc97 421This is a list of entries of the form \(NAME PAIR1 PAIR2 ...\).
16674e4f 422Each NAME stands for a remote access method. Each PAIR is of the form
b533bc97 423\(FUNCTION FILE\). FUNCTION is responsible to extract user names and host
16674e4f
KG
424names from FILE for completion. The following predefined FUNCTIONs exists:
425
5ec2cc41
KG
426 * `tramp-parse-rhosts' for \"~/.rhosts\" like files,
427 * `tramp-parse-shosts' for \"~/.ssh/known_hosts\" like files,
428 * `tramp-parse-sconfig' for \"~/.ssh/config\" like files,
429 * `tramp-parse-shostkeys' for \"~/.ssh2/hostkeys/*\" like files,
430 * `tramp-parse-sknownhosts' for \"~/.ssh2/knownhosts/*\" like files,
431 * `tramp-parse-hosts' for \"/etc/hosts\" like files,
432 * `tramp-parse-passwd' for \"/etc/passwd\" like files.
433 * `tramp-parse-netrc' for \"~/.netrc\" like files.
00d6fd04 434 * `tramp-parse-putty' for PuTTY registry keys.
5ec2cc41
KG
435
436FUNCTION can also be a customer defined function. For more details see
437the info pages.")
438
674da028
MA
439(defconst tramp-echo-mark-marker "_echo"
440 "String marker to surround echoed commands.")
441
68712eb6
MA
442(defconst tramp-echo-mark-marker-length (length tramp-echo-mark-marker)
443 "String length of `tramp-echo-mark-marker'.")
444
445(defconst tramp-echo-mark
446 (concat tramp-echo-mark-marker
447 (make-string tramp-echo-mark-marker-length ?\b))
00d6fd04
MA
448 "String mark to be transmitted around shell commands.
449Used to separate their echo from the output they produce. This
450will only be used if we cannot disable remote echo via stty.
451This string must have no effect on the remote shell except for
452producing some echo which can later be detected by
674da028
MA
453`tramp-echoed-echo-mark-regexp'. Using `tramp-echo-mark-marker',
454followed by an equal number of backspaces to erase them will
455usually suffice.")
00d6fd04 456
68712eb6
MA
457(defconst tramp-echoed-echo-mark-regexp
458 (format "%s\\(\b\\( \b\\)?\\)\\{%d\\}"
459 tramp-echo-mark-marker tramp-echo-mark-marker-length)
00d6fd04
MA
460 "Regexp which matches `tramp-echo-mark' as it gets echoed by
461the remote shell.")
462
4cb0aa75
MA
463(defcustom tramp-local-end-of-line
464 (if (memq system-type '(windows-nt)) "\r\n" "\n")
465 "*String used for end of line in local processes."
466 :group 'tramp
467 :type 'string)
468
fb7933a3
KG
469(defcustom tramp-rsh-end-of-line "\n"
470 "*String used for end of line in rsh connections.
471I don't think this ever needs to be changed, so please tell me about it
16674e4f 472if you need to change this.
90f8dc03
KG
473Also see the method parameter `tramp-password-end-of-line' and the normal
474variable `tramp-default-password-end-of-line'."
16674e4f
KG
475 :group 'tramp
476 :type 'string)
477
90f8dc03
KG
478(defcustom tramp-default-password-end-of-line
479 tramp-rsh-end-of-line
16674e4f 480 "*String used for end of line after sending a password.
90f8dc03
KG
481This variable provides the default value for the method parameter
482`tramp-password-end-of-line', see `tramp-methods' for more details.
483
16674e4f
KG
484It seems that people using plink under Windows need to send
485\"\\r\\n\" (carriage-return, then newline) after a password, but just
486\"\\n\" after all other lines. This variable can be used for the
487password, see `tramp-rsh-end-of-line' for the other cases.
488
489The default value is to use the same value as `tramp-rsh-end-of-line'."
fb7933a3
KG
490 :group 'tramp
491 :type 'string)
492
fb7933a3 493(defcustom tramp-login-prompt-regexp
bc103d00 494 ".*ogin\\( .*\\)?: *"
fb7933a3 495 "*Regexp matching login-like prompts.
bc103d00
MA
496The regexp should match at end of buffer.
497
498Sometimes the prompt is reported to look like \"login as:\"."
fb7933a3
KG
499 :group 'tramp
500 :type 'regexp)
501
821e6e36 502(defcustom tramp-shell-prompt-pattern
aa485f7c 503 ;; Allow a prompt to start right after a ^M since it indeed would be
b81a0b56
MA
504 ;; displayed at the beginning of the line (and Zsh uses it). This
505 ;; regexp works only for GNU Emacs.
506 (concat (if (featurep 'xemacs) "" "\\(?:^\\|\r\\)")
507 "[^#$%>\n]*#?[#$%>] *\\(\e\\[[0-9;]*[a-zA-Z] *\\)*")
821e6e36
KG
508 "Regexp to match prompts from remote shell.
509Normally, Tramp expects you to configure `shell-prompt-pattern'
510correctly, but sometimes it happens that you are connecting to a
511remote host which sends a different kind of shell prompt. Therefore,
512Tramp recognizes things matched by `shell-prompt-pattern' as prompt,
513and also things matched by this variable. The default value of this
b25a52cc 514variable is similar to the default value of `shell-prompt-pattern',
dab816a9
MA
515which should work well in many cases.
516
517This regexp must match both `tramp-initial-end-of-output' and
518`tramp-end-of-output'."
821e6e36
KG
519 :group 'tramp
520 :type 'regexp)
521
fb7933a3 522(defcustom tramp-password-prompt-regexp
00d6fd04 523 "^.*\\([pP]assword\\|[pP]assphrase\\).*:\^@? *"
fb7933a3 524 "*Regexp matching password-like prompts.
ac474af1 525The regexp should match at end of buffer.
fb7933a3
KG
526
527The `sudo' program appears to insert a `^@' character into the prompt."
528 :group 'tramp
529 :type 'regexp)
530
531(defcustom tramp-wrong-passwd-regexp
b1d06e75
KG
532 (concat "^.*"
533 ;; These strings should be on the last line
a4aeb9a4 534 (regexp-opt '("Permission denied"
b1d06e75
KG
535 "Login incorrect"
536 "Login Incorrect"
537 "Connection refused"
27e813fe 538 "Connection closed"
7e5686f0 539 "Timeout, server not responding."
b1d06e75
KG
540 "Sorry, try again."
541 "Name or service not known"
00d6fd04 542 "Host key verification failed."
70c11b0b 543 "No supported authentication methods left to try!") t)
b1d06e75
KG
544 ".*"
545 "\\|"
546 "^.*\\("
547 ;; Here comes a list of regexes, separated by \\|
548 "Received signal [0-9]+"
549 "\\).*")
fb7933a3 550 "*Regexp matching a `login failed' message.
ac474af1
KG
551The regexp should match at end of buffer."
552 :group 'tramp
553 :type 'regexp)
554
555(defcustom tramp-yesno-prompt-regexp
3cdaec13
KG
556 (concat
557 (regexp-opt '("Are you sure you want to continue connecting (yes/no)?") t)
558 "\\s-*")
559 "Regular expression matching all yes/no queries which need to be confirmed.
ac474af1 560The confirmation should be done with yes or no.
3cdaec13
KG
561The regexp should match at end of buffer.
562See also `tramp-yn-prompt-regexp'."
fb7933a3
KG
563 :group 'tramp
564 :type 'regexp)
565
3cdaec13 566(defcustom tramp-yn-prompt-regexp
658052a2
MA
567 (concat
568 (regexp-opt '("Store key in cache? (y/n)"
569 "Update cached key? (y/n, Return cancels connection)") t)
570 "\\s-*")
3cdaec13
KG
571 "Regular expression matching all y/n queries which need to be confirmed.
572The confirmation should be done with y or n.
573The regexp should match at end of buffer.
574See also `tramp-yesno-prompt-regexp'."
575 :group 'tramp
576 :type 'regexp)
487f4fb7
KG
577
578(defcustom tramp-terminal-prompt-regexp
579 (concat "\\("
580 "TERM = (.*)"
581 "\\|"
582 "Terminal type\\? \\[.*\\]"
583 "\\)\\s-*")
584 "Regular expression matching all terminal setting prompts.
585The regexp should match at end of buffer.
586The answer will be provided by `tramp-action-terminal', which see."
587 :group 'tramp
588 :type 'regexp)
3cdaec13 589
01917a18
MA
590(defcustom tramp-operation-not-permitted-regexp
591 (concat "\\(" "preserving times.*" "\\|" "set mode" "\\)" ":\\s-*"
592 (regexp-opt '("Operation not permitted") t))
593 "Regular expression matching keep-date problems in (s)cp operations.
594Copying has been performed successfully already, so this message can
595be ignored safely."
596 :group 'tramp
597 :type 'regexp)
598
6b2633cc
LH
599(defcustom tramp-copy-failed-regexp
600 (concat "\\(.+: "
601 (regexp-opt '("Permission denied"
602 "not a regular file"
603 "is a directory"
604 "No such file or directory") t)
605 "\\)\\s-*")
606 "Regular expression matching copy problems in (s)cp operations."
607 :group 'tramp
608 :type 'regexp)
609
19a87064 610(defcustom tramp-process-alive-regexp
38c65fca 611 ""
19a87064 612 "Regular expression indicating a process has finished.
38c65fca
KG
613In fact this expression is empty by intention, it will be used only to
614check regularly the status of the associated process.
07dfe738 615The answer will be provided by `tramp-action-process-alive',
00d6fd04 616`tramp-action-out-of-band', which see."
38c65fca
KG
617 :group 'tramp
618 :type 'regexp)
619
03c1ad43 620(defconst tramp-temp-name-prefix "tramp."
fb7933a3
KG
621 "*Prefix to use for temporary files.
622If this is a relative file name (such as \"tramp.\"), it is considered
623relative to the directory name returned by the function
9e6ab520 624`tramp-compat-temporary-file-directory' (which see). It may also be an
fb7933a3 625absolute file name; don't forget to include a prefix for the filename
03c1ad43 626part, though.")
fb7933a3 627
2296b54d
MA
628(defconst tramp-temp-buffer-name " *tramp temp*"
629 "Buffer name for a temporary buffer.
630It shall be used in combination with `generate-new-buffer-name'.")
631
b88f2d0a
MA
632(defvar tramp-temp-buffer-file-name nil
633 "File name of a persistent local temporary file.
634Useful for \"rsync\" like methods.")
635(make-variable-buffer-local 'tramp-temp-buffer-file-name)
d68b0220 636(put 'tramp-temp-buffer-file-name 'permanent-local t)
b88f2d0a 637
00d6fd04
MA
638;; XEmacs is distributed with few Lisp packages. Further packages are
639;; installed using EFS. If we use a unified filename format, then
640;; Tramp is required in addition to EFS. (But why can't Tramp just
641;; disable EFS when Tramp is loaded? Then XEmacs can ship with EFS
642;; just like before.) Another reason for using a separate filename
643;; syntax on XEmacs is that EFS hooks into XEmacs in many places, but
644;; Tramp only knows how to deal with `file-name-handler-alist', not
645;; the other places.
646
647;; Currently, we have the choice between 'ftp, 'sep, and 'url.
648;;;###autoload
649(defcustom tramp-syntax
650 (if (featurep 'xemacs) 'sep 'ftp)
651 "Tramp filename syntax to be used.
652
653It can have the following values:
654
655 'ftp -- Ange-FTP respective EFS like syntax (GNU Emacs default)
656 'sep -- Syntax as defined for XEmacs (not available yet for GNU Emacs)
657 'url -- URL-like syntax."
16674e4f 658 :group 'tramp
00d6fd04
MA
659 :type (if (featurep 'xemacs)
660 '(choice (const :tag "EFS" ftp)
661 (const :tag "XEmacs" sep)
662 (const :tag "URL" url))
663 '(choice (const :tag "Ange-FTP" ftp)
664 (const :tag "URL" url))))
665
666(defconst tramp-prefix-format
667 (cond ((equal tramp-syntax 'ftp) "/")
668 ((equal tramp-syntax 'sep) "/[")
669 ((equal tramp-syntax 'url) "/")
670 (t (error "Wrong `tramp-syntax' defined")))
a4aeb9a4 671 "*String matching the very beginning of Tramp file names.
00d6fd04 672Used in `tramp-make-tramp-file-name'.")
16674e4f 673
00d6fd04 674(defconst tramp-prefix-regexp
16674e4f 675 (concat "^" (regexp-quote tramp-prefix-format))
a4aeb9a4 676 "*Regexp matching the very beginning of Tramp file names.
00d6fd04 677Should always start with \"^\". Derived from `tramp-prefix-format'.")
16674e4f 678
00d6fd04 679(defconst tramp-method-regexp
16674e4f 680 "[a-zA-Z_0-9-]+"
00d6fd04 681 "*Regexp matching methods identifiers.")
16674e4f 682
00d6fd04
MA
683(defconst tramp-postfix-method-format
684 (cond ((equal tramp-syntax 'ftp) ":")
685 ((equal tramp-syntax 'sep) "/")
686 ((equal tramp-syntax 'url) "://")
687 (t (error "Wrong `tramp-syntax' defined")))
51aba3f3 688 "*String matching delimiter between method and user or host names.
00d6fd04 689Used in `tramp-make-tramp-file-name'.")
16674e4f 690
00d6fd04
MA
691(defconst tramp-postfix-method-regexp
692 (regexp-quote tramp-postfix-method-format)
51aba3f3 693 "*Regexp matching delimiter between method and user or host names.
00d6fd04 694Derived from `tramp-postfix-method-format'.")
16674e4f 695
03c1ad43 696(defconst tramp-user-regexp "[^:/ \t]+"
00d6fd04 697 "*Regexp matching user names.")
16674e4f 698
b191c9d9 699;;;###tramp-autoload
b96e6899 700(defconst tramp-prefix-domain-format "%"
51aba3f3 701 "*String matching delimiter between user and domain names.")
b96e6899 702
b191c9d9 703;;;###tramp-autoload
b96e6899
MA
704(defconst tramp-prefix-domain-regexp
705 (regexp-quote tramp-prefix-domain-format)
51aba3f3 706 "*Regexp matching delimiter between user and domain names.
b96e6899
MA
707Derived from `tramp-prefix-domain-format'.")
708
03c1ad43 709(defconst tramp-domain-regexp "[-a-zA-Z0-9_.]+"
b96e6899
MA
710 "*Regexp matching domain names.")
711
712(defconst tramp-user-with-domain-regexp
713 (concat "\\(" tramp-user-regexp "\\)"
714 tramp-prefix-domain-regexp
715 "\\(" tramp-domain-regexp "\\)")
716 "*Regexp matching user names with domain names.")
717
03c1ad43 718(defconst tramp-postfix-user-format "@"
51aba3f3 719 "*String matching delimiter between user and host names.
00d6fd04 720Used in `tramp-make-tramp-file-name'.")
16674e4f 721
00d6fd04 722(defconst tramp-postfix-user-regexp
16674e4f 723 (regexp-quote tramp-postfix-user-format)
51aba3f3 724 "*Regexp matching delimiter between user and host names.
00d6fd04
MA
725Derived from `tramp-postfix-user-format'.")
726
03c1ad43 727(defconst tramp-host-regexp "[a-zA-Z0-9_.-]+"
00d6fd04
MA
728 "*Regexp matching host names.")
729
b96e6899
MA
730(defconst tramp-prefix-ipv6-format
731 (cond ((equal tramp-syntax 'ftp) "[")
732 ((equal tramp-syntax 'sep) "")
733 ((equal tramp-syntax 'url) "[")
734 (t (error "Wrong `tramp-syntax' defined")))
735 "*String matching left hand side of IPv6 addresses.
736Used in `tramp-make-tramp-file-name'.")
737
738(defconst tramp-prefix-ipv6-regexp
739 (regexp-quote tramp-prefix-ipv6-format)
740 "*Regexp matching left hand side of IPv6 addresses.
741Derived from `tramp-prefix-ipv6-format'.")
742
e0b6e3b9
MA
743;; The following regexp is a bit sloppy. But it shall serve our
744;; purposes. It covers also IPv4 mapped IPv6 addresses, like in
745;; "::ffff:192.168.0.1".
b96e6899 746(defconst tramp-ipv6-regexp
e0b6e3b9 747 "\\(?:\\(?:[a-zA-Z0-9]+\\)?:\\)+[a-zA-Z0-9.]+"
b96e6899
MA
748 "*Regexp matching IPv6 addresses.")
749
750(defconst tramp-postfix-ipv6-format
751 (cond ((equal tramp-syntax 'ftp) "]")
752 ((equal tramp-syntax 'sep) "")
753 ((equal tramp-syntax 'url) "]")
754 (t (error "Wrong `tramp-syntax' defined")))
755 "*String matching right hand side of IPv6 addresses.
756Used in `tramp-make-tramp-file-name'.")
757
758(defconst tramp-postfix-ipv6-regexp
759 (regexp-quote tramp-postfix-ipv6-format)
760 "*Regexp matching right hand side of IPv6 addresses.
761Derived from `tramp-postfix-ipv6-format'.")
762
00d6fd04
MA
763(defconst tramp-prefix-port-format
764 (cond ((equal tramp-syntax 'ftp) "#")
765 ((equal tramp-syntax 'sep) "#")
766 ((equal tramp-syntax 'url) ":")
767 (t (error "Wrong `tramp-syntax' defined")))
51aba3f3 768 "*String matching delimiter between host names and port numbers.")
00d6fd04
MA
769
770(defconst tramp-prefix-port-regexp
771 (regexp-quote tramp-prefix-port-format)
51aba3f3 772 "*Regexp matching delimiter between host names and port numbers.
00d6fd04
MA
773Derived from `tramp-prefix-port-format'.")
774
03c1ad43 775(defconst tramp-port-regexp "[0-9]+"
00d6fd04
MA
776 "*Regexp matching port numbers.")
777
778(defconst tramp-host-with-port-regexp
779 (concat "\\(" tramp-host-regexp "\\)"
780 tramp-prefix-port-regexp
781 "\\(" tramp-port-regexp "\\)")
782 "*Regexp matching host names with port numbers.")
783
784(defconst tramp-postfix-host-format
785 (cond ((equal tramp-syntax 'ftp) ":")
786 ((equal tramp-syntax 'sep) "]")
787 ((equal tramp-syntax 'url) "")
788 (t (error "Wrong `tramp-syntax' defined")))
51aba3f3 789 "*String matching delimiter between host names and localnames.
00d6fd04 790Used in `tramp-make-tramp-file-name'.")
16674e4f 791
00d6fd04 792(defconst tramp-postfix-host-regexp
16674e4f 793 (regexp-quote tramp-postfix-host-format)
51aba3f3 794 "*Regexp matching delimiter between host names and localnames.
00d6fd04 795Derived from `tramp-postfix-host-format'.")
16674e4f 796
03c1ad43 797(defconst tramp-localname-regexp ".*$"
00d6fd04 798 "*Regexp matching localnames.")
16674e4f 799
4a93e698 800;;; File name format:
505edaeb 801
00d6fd04 802(defconst tramp-file-name-structure
16674e4f
KG
803 (list
804 (concat
805 tramp-prefix-regexp
00d6fd04
MA
806 "\\(" "\\(" tramp-method-regexp "\\)" tramp-postfix-method-regexp "\\)?"
807 "\\(" "\\(" tramp-user-regexp "\\)" tramp-postfix-user-regexp "\\)?"
b96e6899
MA
808 "\\(" "\\(" tramp-host-regexp
809 "\\|"
810 tramp-prefix-ipv6-regexp tramp-ipv6-regexp
811 tramp-postfix-ipv6-regexp "\\)"
812 "\\(" tramp-prefix-port-regexp tramp-port-regexp "\\)?" "\\)?"
00d6fd04
MA
813 tramp-postfix-host-regexp
814 "\\(" tramp-localname-regexp "\\)")
b96e6899 815 2 4 5 8)
16674e4f 816
fb7933a3 817 "*List of five elements (REGEXP METHOD USER HOST FILE), detailing \
a4aeb9a4 818the Tramp file name structure.
fb7933a3 819
a4aeb9a4 820The first element REGEXP is a regular expression matching a Tramp file
fb7933a3
KG
821name. The regex should contain parentheses around the method name,
822the user name, the host name, and the file name parts.
823
824The second element METHOD is a number, saying which pair of
825parentheses matches the method name. The third element USER is
826similar, but for the user name. The fourth element HOST is similar,
827but for the host name. The fifth element FILE is for the file name.
828These numbers are passed directly to `match-string', which see. That
829means the opening parentheses are counted to identify the pair.
830
00d6fd04 831See also `tramp-file-name-regexp'.")
fb7933a3
KG
832
833;;;###autoload
505edaeb 834(defconst tramp-file-name-regexp-unified
1eb5ca1c
MA
835 (if (memq system-type '(cygwin windows-nt))
836 "\\`/\\([^[/:]\\{2,\\}\\|[^/]\\{2,\\}]\\):"
837 "\\`/\\([^[/:]+\\|[^/]+]\\):")
505edaeb
KG
838 "Value for `tramp-file-name-regexp' for unified remoting.
839Emacs (not XEmacs) uses a unified filename syntax for Ange-FTP and
1eb5ca1c
MA
840Tramp. See `tramp-file-name-structure' for more explanations.
841
842On W32 systems, the volume letter must be ignored.")
505edaeb
KG
843
844;;;###autoload
03c1ad43 845(defconst tramp-file-name-regexp-separate "\\`/\\[.*\\]"
505edaeb
KG
846 "Value for `tramp-file-name-regexp' for separate remoting.
847XEmacs uses a separate filename syntax for Tramp and EFS.
00d6fd04 848See `tramp-file-name-structure' for more explanations.")
505edaeb
KG
849
850;;;###autoload
03c1ad43 851(defconst tramp-file-name-regexp-url "\\`/[^/:]+://"
00d6fd04
MA
852 "Value for `tramp-file-name-regexp' for URL-like remoting.
853See `tramp-file-name-structure' for more explanations.")
854
855;;;###autoload
856(defconst tramp-file-name-regexp
857 (cond ((equal tramp-syntax 'ftp) tramp-file-name-regexp-unified)
858 ((equal tramp-syntax 'sep) tramp-file-name-regexp-separate)
859 ((equal tramp-syntax 'url) tramp-file-name-regexp-url)
860 (t (error "Wrong `tramp-syntax' defined")))
94be87e8 861 "*Regular expression matching file names handled by Tramp.
a4aeb9a4 862This regexp should match Tramp file names but no other file names.
b533bc97 863When tramp.el is loaded, this regular expression is prepended to
fb7933a3 864`file-name-handler-alist', and that is searched sequentially. Thus,
a4aeb9a4
MA
865if the Tramp entry appears rather early in the `file-name-handler-alist'
866and is a bit too general, then some files might be considered Tramp
00d6fd04 867files which are not really Tramp files.
fb7933a3
KG
868
869Please note that the entry in `file-name-handler-alist' is made when
b533bc97 870this file \(tramp.el\) is loaded. This means that this variable must be set
fb7933a3
KG
871before loading tramp.el. Alternatively, `file-name-handler-alist' can be
872updated after changing this variable.
873
00d6fd04 874Also see `tramp-file-name-structure'.")
fb7933a3 875
8a798e41
MA
876;;;###autoload
877(defconst tramp-completion-file-name-regexp-unified
1eb5ca1c 878 (if (memq system-type '(cygwin windows-nt))
5bc3b51d 879 "\\`/[^/]\\{2,\\}\\'" "\\`/[^/]*\\'")
16674e4f 880 "Value for `tramp-completion-file-name-regexp' for unified remoting.
8a798e41 881GNU Emacs uses a unified filename syntax for Tramp and Ange-FTP.
1eb5ca1c
MA
882See `tramp-file-name-structure' for more explanations.
883
884On W32 systems, the volume letter must be ignored.")
fb7933a3 885
16674e4f
KG
886;;;###autoload
887(defconst tramp-completion-file-name-regexp-separate
5bc3b51d 888 "\\`/\\([[][^]]*\\)?\\'"
16674e4f
KG
889 "Value for `tramp-completion-file-name-regexp' for separate remoting.
890XEmacs uses a separate filename syntax for Tramp and EFS.
00d6fd04 891See `tramp-file-name-structure' for more explanations.")
fb7933a3 892
16674e4f 893;;;###autoload
00d6fd04 894(defconst tramp-completion-file-name-regexp-url
5bc3b51d 895 "\\`/[^/:]+\\(:\\(/\\(/[^/]*\\)?\\)?\\)?\\'"
00d6fd04
MA
896 "Value for `tramp-completion-file-name-regexp' for URL-like remoting.
897See `tramp-file-name-structure' for more explanations.")
898
899;;;###autoload
900(defconst tramp-completion-file-name-regexp
901 (cond ((equal tramp-syntax 'ftp) tramp-completion-file-name-regexp-unified)
902 ((equal tramp-syntax 'sep) tramp-completion-file-name-regexp-separate)
903 ((equal tramp-syntax 'url) tramp-completion-file-name-regexp-url)
904 (t (error "Wrong `tramp-syntax' defined")))
a4aeb9a4
MA
905 "*Regular expression matching file names handled by Tramp completion.
906This regexp should match partial Tramp file names only.
16674e4f
KG
907
908Please note that the entry in `file-name-handler-alist' is made when
909this file (tramp.el) is loaded. This means that this variable must be set
910before loading tramp.el. Alternatively, `file-name-handler-alist' can be
911updated after changing this variable.
912
00d6fd04 913Also see `tramp-file-name-structure'.")
fb7933a3 914
00d6fd04 915;; Chunked sending kludge. We set this to 500 for black-listed constellations
7432277c 916;; known to have a bug in `process-send-string'; some ssh connections appear
7177e2a3
MA
917;; to drop bytes when data is sent too quickly. There is also a connection
918;; buffer local variable, which is computed depending on remote host properties
919;; when `tramp-chunksize' is zero or nil.
7432277c
KG
920(defcustom tramp-chunksize
921 (when (and (not (featurep 'xemacs))
922 (memq system-type '(hpux)))
923 500)
55880756
MA
924;; Parentheses in docstring starting at beginning of line are escaped.
925;; Fontification is messed up when
926;; `open-paren-in-column-0-is-defun-start' set to t.
7432277c
KG
927 "*If non-nil, chunksize for sending input to local process.
928It is necessary only on systems which have a buggy `process-send-string'
929implementation. The necessity, whether this variable must be set, can be
930checked via the following code:
931
932 (with-temp-buffer
11948172
MA
933 (let* ((user \"xxx\") (host \"yyy\")
934 (init 0) (step 50)
935 (sent init) (received init))
936 (while (= sent received)
937 (setq sent (+ sent step))
938 (erase-buffer)
939 (let ((proc (start-process (buffer-name) (current-buffer)
940 \"ssh\" \"-l\" user host \"wc\" \"-c\")))
941 (when (memq (process-status proc) '(run open))
942 (process-send-string proc (make-string sent ?\\ ))
943 (process-send-eof proc)
944 (process-send-eof proc))
945 (while (not (progn (goto-char (point-min))
946 (re-search-forward \"\\\\w+\" (point-max) t)))
947 (accept-process-output proc 1))
948 (when (memq (process-status proc) '(run open))
949 (setq received (string-to-number (match-string 0)))
950 (delete-process proc)
951 (message \"Bytes sent: %s\\tBytes received: %s\" sent received)
952 (sit-for 0))))
953 (if (> sent (+ init step))
954 (message \"You should set `tramp-chunksize' to a maximum of %s\"
955 (- sent step))
956 (message \"Test does not work\")
957 (display-buffer (current-buffer))
958 (sit-for 30))))
959
960In the Emacs normally running Tramp, evaluate the above code
55880756 961\(replace \"xxx\" and \"yyy\" by the remote user and host name,
b533bc97 962respectively\). You can do this, for example, by pasting it into
11948172
MA
963the `*scratch*' buffer and then hitting C-j with the cursor after the
964last closing parenthesis. Note that it works only if you have configured
b533bc97 965\"ssh\" to run without password query, see ssh-agent\(1\).
11948172
MA
966
967You will see the number of bytes sent successfully to the remote host.
968If that number exceeds 1000, you can stop the execution by hitting
969C-g, because your Emacs is likely clean.
970
11948172 971When it is necessary to set `tramp-chunksize', you might consider to
b533bc97
MA
972use an out-of-the-band method \(like \"scp\"\) instead of an internal one
973\(like \"ssh\"\), because setting `tramp-chunksize' to non-nil decreases
11948172 974performance.
c951aecb 975
00d6fd04
MA
976If your Emacs is buggy, the code stops and gives you an indication
977about the value `tramp-chunksize' should be set. Maybe you could just
978experiment a bit, e.g. changing the values of `init' and `step'
979in the third line of the code.
980
7432277c
KG
981Please raise a bug report via \"M-x tramp-bug\" if your system needs
982this variable to be set as well."
983 :group 'tramp
b1a2b924 984 :type '(choice (const nil) integer))
7432277c 985
5ec2cc41
KG
986;; Logging in to a remote host normally requires obtaining a pty. But
987;; Emacs on MacOS X has process-connection-type set to nil by default,
988;; so on those systems Tramp doesn't obtain a pty. Here, we allow
989;; for an override of the system default.
990(defcustom tramp-process-connection-type t
991 "Overrides `process-connection-type' for connections from Tramp.
992Tramp binds process-connection-type to the value given here before
993opening a connection to a remote host."
994 :group 'tramp
995 :type '(choice (const nil) (const t) (const pty)))
996
b50dd0d2
MA
997(defcustom tramp-completion-reread-directory-timeout 10
998 "Defines seconds since last remote command before rereading a directory.
999A remote directory might have changed its contents. In order to
1000make it visible during file name completion in the minibuffer,
1001Tramp flushes its cache and rereads the directory contents when
1002more than `tramp-completion-reread-directory-timeout' seconds
4bc3c53d
MA
1003have been gone since last remote command execution. A value of `t'
1004would require an immediate reread during filename completion, `nil'
b50dd0d2
MA
1005means to use always cached values for the directory contents."
1006 :group 'tramp
1007 :type '(choice (const nil) integer))
1008
fb7933a3
KG
1009;;; Internal Variables:
1010
fb7933a3 1011(defvar tramp-current-method nil
00d6fd04 1012 "Connection method for this *tramp* buffer.")
fb7933a3
KG
1013
1014(defvar tramp-current-user nil
00d6fd04 1015 "Remote login name for this *tramp* buffer.")
fb7933a3
KG
1016
1017(defvar tramp-current-host nil
00d6fd04
MA
1018 "Remote host for this *tramp* buffer.")
1019
a01b1e22 1020;;;###autoload
16674e4f 1021(defconst tramp-completion-file-name-handler-alist
a01b1e22 1022 '((file-name-all-completions . tramp-completion-handle-file-name-all-completions)
41c8e348 1023 (file-name-completion . tramp-completion-handle-file-name-completion))
16674e4f 1024 "Alist of completion handler functions.
03c1ad43
MA
1025Used for file names matching `tramp-file-name-regexp'. Operations
1026not mentioned here will be handled by Tramp's file name handler
1027functions, or the normal Emacs functions.")
16674e4f 1028
4007ba5b 1029;; Handlers for foreign methods, like FTP or SMB, shall be plugged here.
0f34aa77 1030;;;###tramp-autoload
03c1ad43 1031(defvar tramp-foreign-file-name-handler-alist nil
4007ba5b
KG
1032 "Alist of elements (FUNCTION . HANDLER) for foreign methods handled specially.
1033If (FUNCTION FILENAME) returns non-nil, then all I/O on that file is done by
1034calling HANDLER.")
1035
0664ff72 1036;;; Internal functions which must come first:
fb7933a3 1037
0f34aa77
MA
1038;; Conversion functions between external representation and
1039;; internal data structure. Convenience functions for internal
1040;; data structure.
1041
1042(defun tramp-file-name-p (vec)
1043 "Check, whether VEC is a Tramp object."
1044 (and (vectorp vec) (= 4 (length vec))))
1045
1046(defun tramp-file-name-method (vec)
1047 "Return method component of VEC."
1048 (and (tramp-file-name-p vec) (aref vec 0)))
1049
1050(defun tramp-file-name-user (vec)
1051 "Return user component of VEC."
1052 (and (tramp-file-name-p vec) (aref vec 1)))
1053
1054(defun tramp-file-name-host (vec)
1055 "Return host component of VEC."
1056 (and (tramp-file-name-p vec) (aref vec 2)))
1057
1058(defun tramp-file-name-localname (vec)
1059 "Return localname component of VEC."
1060 (and (tramp-file-name-p vec) (aref vec 3)))
1061
1062;; The user part of a Tramp file name vector can be of kind
1063;; "user%domain". Sometimes, we must extract these parts.
1064(defun tramp-file-name-real-user (vec)
1065 "Return the user name of VEC without domain."
1066 (save-match-data
1067 (let ((user (tramp-file-name-user vec)))
1068 (if (and (stringp user)
1069 (string-match tramp-user-with-domain-regexp user))
1070 (match-string 1 user)
1071 user))))
1072
1073(defun tramp-file-name-domain (vec)
1074 "Return the domain name of VEC."
1075 (save-match-data
1076 (let ((user (tramp-file-name-user vec)))
1077 (and (stringp user)
1078 (string-match tramp-user-with-domain-regexp user)
1079 (match-string 2 user)))))
1080
1081;; The host part of a Tramp file name vector can be of kind
1082;; "host#port". Sometimes, we must extract these parts.
1083(defun tramp-file-name-real-host (vec)
1084 "Return the host name of VEC without port."
1085 (save-match-data
1086 (let ((host (tramp-file-name-host vec)))
1087 (if (and (stringp host)
1088 (string-match tramp-host-with-port-regexp host))
1089 (match-string 1 host)
1090 host))))
1091
1092(defun tramp-file-name-port (vec)
1093 "Return the port number of VEC."
1094 (save-match-data
66feec8b
MA
1095 (let ((method (tramp-file-name-method vec))
1096 (host (tramp-file-name-host vec)))
1097 (or (and (stringp host)
1098 (string-match tramp-host-with-port-regexp host)
1099 (string-to-number (match-string 2 host)))
1100 (tramp-get-method-parameter method 'tramp-default-port)))))
0f34aa77
MA
1101
1102;;;###tramp-autoload
1103(defun tramp-tramp-file-p (name)
1104 "Return t if NAME is a string with Tramp file name syntax."
1105 (save-match-data
1106 (and (stringp name) (string-match tramp-file-name-regexp name))))
1107
1108(defun tramp-find-method (method user host)
1109 "Return the right method string to use.
1110This is METHOD, if non-nil. Otherwise, do a lookup in
1111`tramp-default-method-alist'."
1112 (or method
1113 (let ((choices tramp-default-method-alist)
1114 lmethod item)
1115 (while choices
1116 (setq item (pop choices))
1117 (when (and (string-match (or (nth 0 item) "") (or host ""))
1118 (string-match (or (nth 1 item) "") (or user "")))
1119 (setq lmethod (nth 2 item))
1120 (setq choices nil)))
1121 lmethod)
1122 tramp-default-method))
1123
1124(defun tramp-find-user (method user host)
1125 "Return the right user string to use.
1126This is USER, if non-nil. Otherwise, do a lookup in
1127`tramp-default-user-alist'."
1128 (or user
1129 (let ((choices tramp-default-user-alist)
1130 luser item)
1131 (while choices
1132 (setq item (pop choices))
1133 (when (and (string-match (or (nth 0 item) "") (or method ""))
1134 (string-match (or (nth 1 item) "") (or host "")))
1135 (setq luser (nth 2 item))
1136 (setq choices nil)))
1137 luser)
1138 tramp-default-user))
1139
1140(defun tramp-find-host (method user host)
1141 "Return the right host string to use.
1142This is HOST, if non-nil. Otherwise, it is `tramp-default-host'."
1143 (or (and (> (length host) 0) host)
1144 tramp-default-host))
1145
1146(defun tramp-dissect-file-name (name &optional nodefault)
1147 "Return a `tramp-file-name' structure.
1148The structure consists of remote method, remote user, remote host
1149and localname (file name on remote host). If NODEFAULT is
1150non-nil, the file name parts are not expanded to their default
1151values."
1152 (save-match-data
1153 (let ((match (string-match (nth 0 tramp-file-name-structure) name)))
1154 (unless match (error "Not a Tramp file name: %s" name))
1155 (let ((method (match-string (nth 1 tramp-file-name-structure) name))
1156 (user (match-string (nth 2 tramp-file-name-structure) name))
1157 (host (match-string (nth 3 tramp-file-name-structure) name))
1158 (localname (match-string (nth 4 tramp-file-name-structure) name)))
0f34aa77
MA
1159 (when host
1160 (when (string-match tramp-prefix-ipv6-regexp host)
1161 (setq host (replace-match "" nil t host)))
1162 (when (string-match tramp-postfix-ipv6-regexp host)
1163 (setq host (replace-match "" nil t host))))
1164 (if nodefault
1165 (vector method user host localname)
1166 (vector
1167 (tramp-find-method method user host)
1168 (tramp-find-user method user host)
1169 (tramp-find-host method user host)
1170 localname))))))
1171
1172(defun tramp-buffer-name (vec)
1173 "A name for the connection buffer VEC."
1174 ;; We must use `tramp-file-name-real-host', because for gateway
1175 ;; methods the default port will be expanded later on, which would
1176 ;; tamper the name.
1177 (let ((method (tramp-file-name-method vec))
1178 (user (tramp-file-name-user vec))
1179 (host (tramp-file-name-real-host vec)))
1180 (if (not (zerop (length user)))
1181 (format "*tramp/%s %s@%s*" method user host)
1182 (format "*tramp/%s %s*" method host))))
1183
1184(defun tramp-make-tramp-file-name (method user host localname)
1185 "Constructs a Tramp file name from METHOD, USER, HOST and LOCALNAME."
1186 (concat tramp-prefix-format
1187 (when (not (zerop (length method)))
1188 (concat method tramp-postfix-method-format))
1189 (when (not (zerop (length user)))
1190 (concat user tramp-postfix-user-format))
1191 (when host
1192 (if (string-match tramp-ipv6-regexp host)
1193 (concat tramp-prefix-ipv6-format host tramp-postfix-ipv6-format)
1194 host))
1195 tramp-postfix-host-format
1196 (when localname localname)))
1197
1198(defun tramp-completion-make-tramp-file-name (method user host localname)
1199 "Constructs a Tramp file name from METHOD, USER, HOST and LOCALNAME.
1200It must not be a complete Tramp file name, but as long as there are
1201necessary only. This function will be used in file name completion."
1202 (concat tramp-prefix-format
1203 (when (not (zerop (length method)))
1204 (concat method tramp-postfix-method-format))
1205 (when (not (zerop (length user)))
1206 (concat user tramp-postfix-user-format))
1207 (when (not (zerop (length host)))
1208 (concat
1209 (if (string-match tramp-ipv6-regexp host)
03c1ad43
MA
1210 (concat
1211 tramp-prefix-ipv6-format host tramp-postfix-ipv6-format)
0f34aa77
MA
1212 host)
1213 tramp-postfix-host-format))
1214 (when localname localname)))
1215
1216(defun tramp-get-buffer (vec)
1217 "Get the connection buffer to be used for VEC."
1218 (or (get-buffer (tramp-buffer-name vec))
1219 (with-current-buffer (get-buffer-create (tramp-buffer-name vec))
1220 (setq buffer-undo-list t)
1221 (setq default-directory
1222 (tramp-make-tramp-file-name
1223 (tramp-file-name-method vec)
1224 (tramp-file-name-user vec)
1225 (tramp-file-name-host vec)
1226 "/"))
1227 (current-buffer))))
1228
1229(defun tramp-get-connection-buffer (vec)
1230 "Get the connection buffer to be used for VEC.
1231In case a second asynchronous communication has been started, it is different
1232from `tramp-get-buffer'."
1233 (or (tramp-get-connection-property vec "process-buffer" nil)
1234 (tramp-get-buffer vec)))
1235
66feec8b
MA
1236(defun tramp-get-connection-name (vec)
1237 "Get the connection name to be used for VEC.
1238In case a second asynchronous communication has been started, it is different
1239from the default one."
1240 (or (tramp-get-connection-property vec "process-name" nil)
1241 (tramp-buffer-name vec)))
1242
0f34aa77
MA
1243(defun tramp-get-connection-process (vec)
1244 "Get the connection process to be used for VEC.
1245In case a second asynchronous communication has been started, it is different
1246from the default one."
66feec8b 1247 (get-process (tramp-get-connection-name vec)))
0f34aa77
MA
1248
1249(defun tramp-debug-buffer-name (vec)
1250 "A name for the debug buffer for VEC."
1251 ;; We must use `tramp-file-name-real-host', because for gateway
1252 ;; methods the default port will be expanded later on, which would
1253 ;; tamper the name.
1254 (let ((method (tramp-file-name-method vec))
1255 (user (tramp-file-name-user vec))
1256 (host (tramp-file-name-real-host vec)))
1257 (if (not (zerop (length user)))
1258 (format "*debug tramp/%s %s@%s*" method user host)
1259 (format "*debug tramp/%s %s*" method host))))
1260
1261(defconst tramp-debug-outline-regexp
03c1ad43
MA
1262 "[0-9]+:[0-9]+:[0-9]+\\.[0-9]+ [a-z0-9-]+ (\\([0-9]+\\)) #"
1263 "Used for highlighting Tramp debug buffers in `outline-mode'.")
1264
1265(defun tramp-debug-outline-level ()
1266 "Return the depth to which a statement is nested in the outline.
1267Point must be at the beginning of a header line.
1268
1269The outline level is equal to the verbosity of the Tramp message."
1270 (1+ (string-to-number (match-string 1))))
0f34aa77
MA
1271
1272(defun tramp-get-debug-buffer (vec)
1273 "Get the debug buffer for VEC."
1274 (with-current-buffer
1275 (get-buffer-create (tramp-debug-buffer-name vec))
1276 (when (bobp)
1277 (setq buffer-undo-list t)
1278 ;; Activate `outline-mode'. This runs `text-mode-hook' and
1279 ;; `outline-mode-hook'. We must prevent that local processes
1280 ;; die. Yes: I've seen `flyspell-mode', which starts "ispell".
1281 ;; Furthermore, `outline-regexp' must have the correct value
1282 ;; already, because it is used by `font-lock-compile-keywords'.
1283 (let ((default-directory (tramp-compat-temporary-file-directory))
1284 (outline-regexp tramp-debug-outline-regexp))
1285 (outline-mode))
1286 (set (make-local-variable 'outline-regexp) tramp-debug-outline-regexp)
03c1ad43 1287 (set (make-local-variable 'outline-level) 'tramp-debug-outline-level))
0f34aa77
MA
1288 (current-buffer)))
1289
00d6fd04
MA
1290(defsubst tramp-debug-message (vec fmt-string &rest args)
1291 "Append message to debug buffer.
1292Message is formatted with FMT-STRING as control string and the remaining
1293ARGS to actually emit the message (if applicable)."
1294 (when (get-buffer (tramp-buffer-name vec))
1295 (with-current-buffer (tramp-get-debug-buffer vec)
1296 (goto-char (point-max))
70c11b0b
MA
1297 ;; Headline.
1298 (when (bobp)
1299 (insert
1300 (format
1301 ";; %sEmacs: %s Tramp: %s -*- mode: outline; -*-"
1302 (if (featurep 'sxemacs) "SX" (if (featurep 'xemacs) "X" "GNU "))
1303 emacs-version tramp-version)))
00d6fd04
MA
1304 (unless (bolp)
1305 (insert "\n"))
70c11b0b 1306 ;; Timestamp.
736ac90f
MA
1307 (let ((now (current-time)))
1308 (insert (format-time-string "%T." now))
1309 (insert (format "%06d " (nth 2 now))))
56761182
MA
1310 ;; Calling Tramp function. We suppress compat and trace
1311 ;; functions from being displayed.
00d6fd04
MA
1312 (let ((btn 1) btf fn)
1313 (while (not fn)
1314 (setq btf (nth 1 (backtrace-frame btn)))
1315 (if (not btf)
1316 (setq fn "")
1317 (when (symbolp btf)
1318 (setq fn (symbol-name btf))
56761182
MA
1319 (unless
1320 (and
1321 (string-match "^tramp" fn)
1322 (not
1323 (string-match
1324 (concat
1325 "^"
1326 (regexp-opt
1327 '("tramp-compat-funcall"
1328 "tramp-compat-with-temp-message"
1329 "tramp-debug-message"
1330 "tramp-error"
1331 "tramp-error-with-buffer"
def722bf
MA
1332 "tramp-message"
1333 "tramp-with-progress-reporter")
56761182
MA
1334 t)
1335 "$")
1336 fn)))
00d6fd04
MA
1337 (setq fn nil)))
1338 (setq btn (1+ btn))))
1339 ;; The following code inserts filename and line number.
e9a452d9 1340 ;; Should be inactive by default, because it is time
00d6fd04
MA
1341 ;; consuming.
1342; (let ((ffn (find-function-noselect (intern fn))))
1343; (insert
1344; (format
1345; "%s:%d: "
1346; (file-name-nondirectory (buffer-file-name (car ffn)))
1347; (with-current-buffer (car ffn)
1348; (1+ (count-lines (point-min) (cdr ffn)))))))
1349 (insert (format "%s " fn)))
70c11b0b 1350 ;; The message.
00d6fd04
MA
1351 (insert (apply 'format fmt-string args)))))
1352
946a5aeb
MA
1353(defvar tramp-message-show-message t
1354 "Show Tramp message in the minibuffer.
1355This variable is used to disable messages from `tramp-error'.
1356The messages are visible anyway, because an error is raised.")
1357
00d6fd04 1358(defsubst tramp-message (vec-or-proc level fmt-string &rest args)
fb7933a3 1359 "Emit a message depending on verbosity level.
a4aeb9a4 1360VEC-OR-PROC identifies the Tramp buffer to use. It can be either a
00d6fd04
MA
1361vector or a process. LEVEL says to be quiet if `tramp-verbose' is
1362less than LEVEL. The message is emitted only if `tramp-verbose' is
1363greater than or equal to LEVEL.
1364
1365The message is also logged into the debug buffer when `tramp-verbose'
1366is greater than or equal 4.
1367
1368Calls functions `message' and `tramp-debug-message' with FMT-STRING as
1369control string and the remaining ARGS to actually emit the message (if
1370applicable)."
03c1ad43
MA
1371 (ignore-errors
1372 (when (<= level tramp-verbose)
1373 ;; Match data must be preserved!
1374 (save-match-data
1375 ;; Display only when there is a minimum level.
1376 (when (and tramp-message-show-message (<= level 3))
1377 (apply 'message
1378 (concat
1379 (cond
1380 ((= level 0) "")
1381 ((= level 1) "")
1382 ((= level 2) "Warning: ")
1383 (t "Tramp: "))
1384 fmt-string)
1385 args))
1386 ;; Log only when there is a minimum level.
1387 (when (>= tramp-verbose 4)
1388 (when (and vec-or-proc
1389 (processp vec-or-proc)
1390 (buffer-name (process-buffer vec-or-proc)))
1391 (with-current-buffer (process-buffer vec-or-proc)
1392 ;; Translate proc to vec.
1393 (setq vec-or-proc (tramp-dissect-file-name default-directory))))
1394 (when (and vec-or-proc (vectorp vec-or-proc))
1395 (apply 'tramp-debug-message
1396 vec-or-proc
1397 (concat (format "(%d) # " level) fmt-string)
1398 args)))))))
00d6fd04
MA
1399
1400(defsubst tramp-error (vec-or-proc signal fmt-string &rest args)
1401 "Emit an error.
1402VEC-OR-PROC identifies the connection to use, SIGNAL is the
1403signal identifier to be raised, remaining args passed to
1404`tramp-message'. Finally, signal SIGNAL is raised."
946a5aeb
MA
1405 (let (tramp-message-show-message)
1406 (tramp-message
1407 vec-or-proc 1 "%s"
1408 (error-message-string
1409 (list signal
1410 (get signal 'error-message)
1411 (apply 'format fmt-string args))))
1412 (signal signal (list (apply 'format fmt-string args)))))
00d6fd04
MA
1413
1414(defsubst tramp-error-with-buffer
1415 (buffer vec-or-proc signal fmt-string &rest args)
1416 "Emit an error, and show BUFFER.
1417If BUFFER is nil, show the connection buffer. Wait for 30\", or until
1418an input event arrives. The other arguments are passed to `tramp-error'."
1419 (save-window-excursion
1420 (unwind-protect
1421 (apply 'tramp-error vec-or-proc signal fmt-string args)
4874f5e6
MA
1422 (when (and vec-or-proc
1423 (not (zerop tramp-verbose))
1424 (not (tramp-completion-mode-p)))
00d6fd04
MA
1425 (let ((enable-recursive-minibuffers t))
1426 (pop-to-buffer
1427 (or (and (bufferp buffer) buffer)
1428 (and (processp vec-or-proc) (process-buffer vec-or-proc))
1429 (tramp-get-buffer vec-or-proc)))
1430 (sit-for 30))))))
fb7933a3 1431
c62c9d08
KG
1432(defmacro with-parsed-tramp-file-name (filename var &rest body)
1433 "Parse a Tramp filename and make components available in the body.
1434
1435First arg FILENAME is evaluated and dissected into its components.
1436Second arg VAR is a symbol. It is used as a variable name to hold
1437the filename structure. It is also used as a prefix for the variables
1438holding the components. For example, if VAR is the symbol `foo', then
00d6fd04
MA
1439`foo' will be bound to the whole structure, `foo-method' will be bound to
1440the method component, and so on for `foo-user', `foo-host', `foo-localname'.
c62c9d08
KG
1441
1442Remaining args are Lisp expressions to be evaluated (inside an implicit
1443`progn').
1444
00d6fd04
MA
1445If VAR is nil, then we bind `v' to the structure and `method', `user',
1446`host', `localname' to the components."
c62c9d08 1447 `(let* ((,(or var 'v) (tramp-dissect-file-name ,filename))
c62c9d08
KG
1448 (,(if var (intern (concat (symbol-name var) "-method")) 'method)
1449 (tramp-file-name-method ,(or var 'v)))
1450 (,(if var (intern (concat (symbol-name var) "-user")) 'user)
1451 (tramp-file-name-user ,(or var 'v)))
1452 (,(if var (intern (concat (symbol-name var) "-host")) 'host)
1453 (tramp-file-name-host ,(or var 'v)))
7432277c
KG
1454 (,(if var (intern (concat (symbol-name var) "-localname")) 'localname)
1455 (tramp-file-name-localname ,(or var 'v))))
c62c9d08
KG
1456 ,@body))
1457
1458(put 'with-parsed-tramp-file-name 'lisp-indent-function 2)
00d6fd04 1459(put 'with-parsed-tramp-file-name 'edebug-form-spec '(form symbolp body))
6139f995
MA
1460(tramp-compat-font-lock-add-keywords
1461 'emacs-lisp-mode '("\\<with-parsed-tramp-file-name\\>"))
00d6fd04 1462
9e021389
MA
1463(defun tramp-progress-reporter-update (reporter &optional value)
1464 (let* ((parameters (cdr reporter))
1465 (message (aref parameters 3)))
1466 (when (string-match message (or (current-message) ""))
6139f995 1467 (tramp-compat-funcall 'progress-reporter-update reporter value))))
9e021389 1468
7d520089 1469(defmacro tramp-with-progress-reporter (vec level message &rest body)
b6827fff
MA
1470 "Executes BODY, spinning a progress reporter with MESSAGE.
1471If LEVEL does not fit for visible messages, or if this is a
1472nested call of the macro, there are only traces without a visible
1473progress reporter."
7d520089 1474 (declare (indent 3) (debug t))
a94d821f
MA
1475 `(let (pr tm)
1476 (tramp-message ,vec ,level "%s..." ,message)
1477 ;; We start a pulsing progress reporter after 3 seconds. Feature
1478 ;; introduced in Emacs 24.1.
3b30ccda
MA
1479 (when (and tramp-message-show-message
1480 ;; Display only when there is a minimum level.
1481 (<= ,level (min tramp-verbose 3)))
03c1ad43
MA
1482 (ignore-errors
1483 (setq pr (tramp-compat-funcall 'make-progress-reporter ,message)
1484 tm (when pr
1485 (run-at-time 3 0.1 'tramp-progress-reporter-update pr)))))
a94d821f 1486 (unwind-protect
b6827fff
MA
1487 ;; Execute the body. Unset `tramp-message-show-message' when
1488 ;; the timer object is created, in order to suppress
1489 ;; concurrent timers.
3b30ccda
MA
1490 (let ((tramp-message-show-message
1491 (and tramp-message-show-message (not tm))))
1492 ,@body)
a94d821f 1493 ;; Stop progress reporter.
0d5852cf 1494 (if tm (tramp-compat-funcall 'cancel-timer tm))
a94d821f
MA
1495 (tramp-message ,vec ,level "%s...done" ,message))))
1496
6139f995 1497(tramp-compat-font-lock-add-keywords
7d520089 1498 'emacs-lisp-mode '("\\<tramp-with-progress-reporter\\>"))
a94d821f 1499
5bc3b51d 1500(defalias 'tramp-drop-volume-letter
628c97b2 1501 (if (memq system-type '(cygwin windows-nt))
5bc3b51d 1502 (lambda (name)
628c97b2 1503 "Cut off unnecessary drive letter from file NAME.
66feec8b 1504The functions `tramp-*-handle-expand-file-name' call `expand-file-name'
628c97b2
GM
1505locally on a remote file name. When the local system is a W32 system
1506but the remote system is Unix, this introduces a superfluous drive
1507letter into the file name. This function removes it."
1508 (save-match-data
5bc3b51d 1509 (if (string-match "\\`[a-zA-Z]:/" name)
628c97b2
GM
1510 (replace-match "/" nil t name)
1511 name)))
1512
5bc3b51d 1513 'identity))
628c97b2 1514
16674e4f
KG
1515;;; Config Manipulation Functions:
1516
f8f91c2b 1517;;;###tramp-autoload
16674e4f
KG
1518(defun tramp-set-completion-function (method function-list)
1519 "Sets the list of completion functions for METHOD.
1520FUNCTION-LIST is a list of entries of the form (FUNCTION FILE).
1521The FUNCTION is intended to parse FILE according its syntax.
1522It might be a predefined FUNCTION, or a user defined FUNCTION.
1523Predefined FUNCTIONs are `tramp-parse-rhosts', `tramp-parse-shosts',
8fc29035 1524`tramp-parse-sconfig', `tramp-parse-hosts', `tramp-parse-passwd',
8daea7fc
KG
1525and `tramp-parse-netrc'.
1526
16674e4f
KG
1527Example:
1528
1529 (tramp-set-completion-function
1530 \"ssh\"
8daea7fc
KG
1531 '((tramp-parse-sconfig \"/etc/ssh_config\")
1532 (tramp-parse-sconfig \"~/.ssh/config\")))"
16674e4f 1533
5ec2cc41
KG
1534 (let ((r function-list)
1535 (v function-list))
1536 (setq tramp-completion-function-alist
1537 (delete (assoc method tramp-completion-function-alist)
1538 tramp-completion-function-alist))
1539
1540 (while v
00d6fd04 1541 ;; Remove double entries.
5ec2cc41
KG
1542 (when (member (car v) (cdr v))
1543 (setcdr v (delete (car v) (cdr v))))
00d6fd04 1544 ;; Check for function and file or registry key.
5ec2cc41 1545 (unless (and (functionp (nth 0 (car v)))
00d6fd04
MA
1546 (if (string-match "^HKEY_CURRENT_USER" (nth 1 (car v)))
1547 ;; Windows registry.
1548 (and (memq system-type '(cygwin windows-nt))
a4aeb9a4 1549 (zerop
0f34aa77 1550 (tramp-compat-call-process
a4aeb9a4 1551 "reg" nil nil nil "query" (nth 1 (car v)))))
00d6fd04
MA
1552 ;; Configuration file.
1553 (file-exists-p (nth 1 (car v)))))
5ec2cc41
KG
1554 (setq r (delete (car v) r)))
1555 (setq v (cdr v)))
1556
1557 (when r
4007ba5b 1558 (add-to-list 'tramp-completion-function-alist
5ec2cc41 1559 (cons method r)))))
16674e4f
KG
1560
1561(defun tramp-get-completion-function (method)
00d6fd04 1562 "Returns a list of completion functions for METHOD.
16674e4f 1563For definition of that list see `tramp-set-completion-function'."
00d6fd04
MA
1564 (cons
1565 ;; Hosts visited once shall be remembered.
1566 `(tramp-parse-connection-properties ,method)
1567 ;; The method related defaults.
1568 (cdr (assoc method tramp-completion-function-alist))))
16674e4f 1569
d037d501 1570
0664ff72 1571;;; Fontification of `read-file-name':
d037d501 1572
0664ff72 1573;; rfn-eshadow.el is part of Emacs 22. It is autoloaded.
d037d501
MA
1574(defvar tramp-rfn-eshadow-overlay)
1575(make-variable-buffer-local 'tramp-rfn-eshadow-overlay)
1576
1577(defun tramp-rfn-eshadow-setup-minibuffer ()
1578 "Set up a minibuffer for `file-name-shadow-mode'.
1579Adds another overlay hiding filename parts according to Tramp's
1580special handling of `substitute-in-file-name'."
9ce8462a 1581 (when (symbol-value 'minibuffer-completing-file-name)
d037d501 1582 (setq tramp-rfn-eshadow-overlay
0d5852cf
MA
1583 (tramp-compat-funcall
1584 'make-overlay
1585 (tramp-compat-funcall 'minibuffer-prompt-end)
1586 (tramp-compat-funcall 'minibuffer-prompt-end)))
d037d501 1587 ;; Copy rfn-eshadow-overlay properties.
0d5852cf
MA
1588 (let ((props (tramp-compat-funcall
1589 'overlay-properties (symbol-value 'rfn-eshadow-overlay))))
d037d501 1590 (while props
c6309045
MA
1591 ;; The `field' property prevents correct minibuffer
1592 ;; completion; we exclude it.
1593 (if (not (eq (car props) 'field))
1594 (tramp-compat-funcall
1595 'overlay-put tramp-rfn-eshadow-overlay (pop props) (pop props))
1596 (pop props) (pop props))))))
d037d501
MA
1597
1598(when (boundp 'rfn-eshadow-setup-minibuffer-hook)
1599 (add-hook 'rfn-eshadow-setup-minibuffer-hook
48846dc5
MA
1600 'tramp-rfn-eshadow-setup-minibuffer)
1601 (add-hook 'tramp-unload-hook
aa485f7c
MA
1602 (lambda ()
1603 (remove-hook 'rfn-eshadow-setup-minibuffer-hook
1604 'tramp-rfn-eshadow-setup-minibuffer))))
d037d501 1605
adcbca53
MA
1606(defconst tramp-rfn-eshadow-update-overlay-regexp
1607 (format "[^%s/~]*\\(/\\|~\\)" tramp-postfix-host-format))
1608
d037d501
MA
1609(defun tramp-rfn-eshadow-update-overlay ()
1610 "Update `rfn-eshadow-overlay' to cover shadowed part of minibuffer input.
1611This is intended to be used as a minibuffer `post-command-hook' for
1612`file-name-shadow-mode'; the minibuffer should have already
1613been set up by `rfn-eshadow-setup-minibuffer'."
1614 ;; In remote files name, there is a shadowing just for the local part.
28dbc92f
MA
1615 (ignore-errors
1616 (let ((end (or (tramp-compat-funcall
1617 'overlay-end (symbol-value 'rfn-eshadow-overlay))
1618 (tramp-compat-funcall 'minibuffer-prompt-end))))
1619 (when
1620 (file-remote-p
1621 (tramp-compat-funcall
1622 'buffer-substring-no-properties end (point-max)))
1623 (save-excursion
1624 (save-restriction
1625 (narrow-to-region
1626 (1+ (or (string-match
1627 tramp-rfn-eshadow-update-overlay-regexp
1628 (buffer-string) end)
1629 end))
1630 (point-max))
1631 (let ((rfn-eshadow-overlay tramp-rfn-eshadow-overlay)
1632 (rfn-eshadow-update-overlay-hook nil)
1633 file-name-handler-alist)
1634 (tramp-compat-funcall
1635 'move-overlay rfn-eshadow-overlay (point-max) (point-max))
1636 (tramp-compat-funcall 'rfn-eshadow-update-overlay))))))))
d037d501
MA
1637
1638(when (boundp 'rfn-eshadow-update-overlay-hook)
1639 (add-hook 'rfn-eshadow-update-overlay-hook
b88f2d0a
MA
1640 'tramp-rfn-eshadow-update-overlay)
1641 (add-hook 'tramp-unload-hook
1642 (lambda ()
1643 (remove-hook 'rfn-eshadow-update-overlay-hook
1644 'tramp-rfn-eshadow-update-overlay))))
d037d501 1645
00d6fd04
MA
1646;; Inodes don't exist for some file systems. Therefore we must
1647;; generate virtual ones. Used in `find-buffer-visiting'. The method
1648;; applied might be not so efficient (Ange-FTP uses hashes). But
1649;; performance isn't the major issue given that file transfer will
1650;; take time.
1651(defvar tramp-inodes nil
1652 "Keeps virtual inodes numbers.")
1653
8daea7fc
KG
1654;; Devices must distinguish physical file systems. The device numbers
1655;; provided by "lstat" aren't unique, because we operate on different hosts.
1656;; So we use virtual device numbers, generated by Tramp. Both Ange-FTP and
1657;; EFS use device number "-1". In order to be different, we use device number
b946a456 1658;; (-1 . x), whereby "x" is unique for a given (method user host).
8daea7fc
KG
1659(defvar tramp-devices nil
1660 "Keeps virtual device numbers.")
1661
b86c1cd8
MA
1662(defun tramp-default-file-modes (filename)
1663 "Return file modes of FILENAME as integer.
1664If the file modes of FILENAME cannot be determined, return the
974647ac
MA
1665value of `default-file-modes', without execute permissions."
1666 (or (file-modes filename)
0f34aa77 1667 (logand (default-file-modes) (tramp-compat-octal-to-decimal "0666"))))
b86c1cd8 1668
c23c3394
MA
1669(defun tramp-replace-environment-variables (filename)
1670 "Replace environment variables in FILENAME.
1671Return the string with the replaced variables."
2e271195 1672 (save-match-data
ec5145d6 1673 (let ((idx (string-match "$\\(\\w+\\)" filename)))
2e271195 1674 ;; `$' is coded as `$$'.
ec5145d6
MA
1675 (when (and idx
1676 (or (zerop idx) (not (eq ?$ (aref filename (1- idx)))))
1677 (getenv (match-string 1 filename)))
2e271195
MA
1678 (setq filename
1679 (replace-match
1680 (substitute-in-file-name (match-string 0 filename))
1681 t nil filename)))
1682 filename)))
c23c3394 1683
00d6fd04
MA
1684;; In XEmacs, electricity is implemented via a key map for ?/ and ?~,
1685;; which calls corresponding functions (see minibuf.el).
1686(when (fboundp 'minibuffer-electric-separator)
9e6ab520 1687 (mapc
aa485f7c
MA
1688 (lambda (x)
1689 (eval
1690 `(defadvice ,x
1691 (around ,(intern (format "tramp-advice-%s" x)) activate)
1692 "Invoke `substitute-in-file-name' for Tramp files."
1693 (if (and (symbol-value 'minibuffer-electric-file-name-behavior)
1694 (tramp-tramp-file-p (buffer-substring)))
1695 ;; We don't need to handle `last-input-event', because
1696 ;; due to the key map we know it must be ?/ or ?~.
1697 (let ((s (concat (buffer-substring (point-min) (point))
1698 (string last-command-char))))
1699 (delete-region (point-min) (point))
1700 (insert (substitute-in-file-name s))
1701 (setq ad-return-value last-command-char))
d7ec1df7
MA
1702 ad-do-it)))
1703 (eval
1704 `(add-hook
1705 'tramp-unload-hook
1706 (lambda ()
1707 (ad-remove-advice ',x 'around ',(intern (format "tramp-advice-%s" x)))
1708 (ad-activate ',x)))))
00d6fd04
MA
1709
1710 '(minibuffer-electric-separator
1711 minibuffer-electric-tilde)))
1712
eb562962
MA
1713(defun tramp-find-file-name-coding-system-alist (filename tmpname)
1714 "Like `find-operation-coding-system' for Tramp filenames.
1715Tramp's `insert-file-contents' and `write-region' work over
1716temporary file names. If `file-coding-system-alist' contains an
1717expression, which matches more than the file name suffix, the
1718coding system might not be determined. This function repairs it."
1719 (let (result)
1720 (dolist (elt file-coding-system-alist result)
1721 (when (and (consp elt) (string-match (car elt) filename))
1722 ;; We found a matching entry in `file-coding-system-alist'.
1723 ;; So we add a similar entry, but with the temporary file name
1724 ;; as regexp.
1725 (add-to-list
1726 'result (cons (regexp-quote tmpname) (cdr elt)) 'append)))))
1727
a01b1e22
MA
1728;;;###autoload
1729(progn (defun tramp-run-real-handler (operation args)
fb7933a3 1730 "Invoke normal file name handler for OPERATION.
c62c9d08
KG
1731First arg specifies the OPERATION, second arg is a list of arguments to
1732pass to the OPERATION."
4007ba5b
KG
1733 (let* ((inhibit-file-name-handlers
1734 `(tramp-file-name-handler
946a5aeb 1735 tramp-vc-file-name-handler
4007ba5b
KG
1736 tramp-completion-file-name-handler
1737 cygwin-mount-name-hook-function
1738 cygwin-mount-map-drive-hook-function
1739 .
1740 ,(and (eq inhibit-file-name-operation operation)
1741 inhibit-file-name-handlers)))
1742 (inhibit-file-name-operation operation))
a01b1e22 1743 (apply operation args))))
16674e4f 1744
a01b1e22
MA
1745;;;###autoload
1746(progn (defun tramp-completion-run-real-handler (operation args)
16674e4f
KG
1747 "Invoke `tramp-file-name-handler' for OPERATION.
1748First arg specifies the OPERATION, second arg is a list of arguments to
1749pass to the OPERATION."
4007ba5b
KG
1750 (let* ((inhibit-file-name-handlers
1751 `(tramp-completion-file-name-handler
1752 cygwin-mount-name-hook-function
1753 cygwin-mount-map-drive-hook-function
1754 .
1755 ,(and (eq inhibit-file-name-operation operation)
1756 inhibit-file-name-handlers)))
1757 (inhibit-file-name-operation operation))
a01b1e22 1758 (apply operation args))))
fb7933a3 1759
4007ba5b
KG
1760;; We handle here all file primitives. Most of them have the file
1761;; name as first parameter; nevertheless we check for them explicitly
04bf5b65 1762;; in order to be signaled if a new primitive appears. This
4007ba5b
KG
1763;; scenario is needed because there isn't a way to decide by
1764;; syntactical means whether a foreign method must be called. It would
19a87064 1765;; ease the life if `file-name-handler-alist' would support a decision
4007ba5b
KG
1766;; function as well but regexp only.
1767(defun tramp-file-name-for-operation (operation &rest args)
1768 "Return file name related to OPERATION file primitive.
1769ARGS are the arguments OPERATION has been called with."
1770 (cond
b533bc97 1771 ;; FILE resp DIRECTORY.
4007ba5b
KG
1772 ((member operation
1773 (list 'access-file 'byte-compiler-base-file-name 'delete-directory
1774 'delete-file 'diff-latest-backup-file 'directory-file-name
1775 'directory-files 'directory-files-and-attributes
1776 'dired-compress-file 'dired-uncache
1777 'file-accessible-directory-p 'file-attributes
1778 'file-directory-p 'file-executable-p 'file-exists-p
25f14cdb 1779 'file-local-copy 'file-remote-p 'file-modes
19a87064
MA
1780 'file-name-as-directory 'file-name-directory
1781 'file-name-nondirectory 'file-name-sans-versions
1782 'file-ownership-preserved-p 'file-readable-p
1783 'file-regular-p 'file-symlink-p 'file-truename
1784 'file-writable-p 'find-backup-file-name 'find-file-noselect
1785 'get-file-buffer 'insert-directory 'insert-file-contents
1786 'load 'make-directory 'make-directory-internal
1787 'set-file-modes 'substitute-in-file-name
1788 'unhandled-file-name-directory 'vc-registered
b533bc97 1789 ;; Emacs 22+ only.
ce3f516f 1790 'set-file-times
25f14cdb
MA
1791 ;; Emacs 24+ only.
1792 'file-selinux-context 'set-file-selinux-context
b533bc97 1793 ;; XEmacs only.
4007ba5b
KG
1794 'abbreviate-file-name 'create-file-buffer
1795 'dired-file-modtime 'dired-make-compressed-filename
1796 'dired-recursive-delete-directory 'dired-set-file-modtime
1797 'dired-shell-unhandle-file-name 'dired-uucode-file
5615d63f 1798 'insert-file-contents-literally 'make-temp-name 'recover-file
4007ba5b 1799 'vm-imap-check-mail 'vm-pop-check-mail 'vm-spool-check-mail))
8daea7fc
KG
1800 (if (file-name-absolute-p (nth 0 args))
1801 (nth 0 args)
1802 (expand-file-name (nth 0 args))))
b533bc97 1803 ;; FILE DIRECTORY resp FILE1 FILE2.
4007ba5b
KG
1804 ((member operation
1805 (list 'add-name-to-file 'copy-file 'expand-file-name
1806 'file-name-all-completions 'file-name-completion
1807 'file-newer-than-file-p 'make-symbolic-link 'rename-file
b533bc97 1808 ;; Emacs 23+ only.
263c02ef 1809 'copy-directory
b533bc97 1810 ;; XEmacs only.
4007ba5b
KG
1811 'dired-make-relative-symlink
1812 'vm-imap-move-mail 'vm-pop-move-mail 'vm-spool-move-mail))
1813 (save-match-data
1814 (cond
1815 ((string-match tramp-file-name-regexp (nth 0 args)) (nth 0 args))
1816 ((string-match tramp-file-name-regexp (nth 1 args)) (nth 1 args))
1817 (t (buffer-file-name (current-buffer))))))
b533bc97 1818 ;; START END FILE.
4007ba5b
KG
1819 ((eq operation 'write-region)
1820 (nth 2 args))
b533bc97 1821 ;; BUFFER.
4007ba5b 1822 ((member operation
00d6fd04 1823 (list 'set-visited-file-modtime 'verify-visited-file-modtime
b533bc97 1824 ;; Emacs 22+ only.
00d6fd04 1825 'make-auto-save-file-name
b533bc97 1826 ;; XEmacs only.
4007ba5b
KG
1827 'backup-buffer))
1828 (buffer-file-name
1829 (if (bufferp (nth 0 args)) (nth 0 args) (current-buffer))))
b533bc97 1830 ;; COMMAND.
4007ba5b 1831 ((member operation
b533bc97 1832 (list ;; not in Emacs 23+.
00d6fd04 1833 'dired-call-process
b533bc97 1834 ;; Emacs only.
b71c9e75 1835 'shell-command
b533bc97 1836 ;; Emacs 22+ only.
0457dd55 1837 'process-file
b533bc97 1838 ;; Emacs 23+ only.
00d6fd04 1839 'start-file-process
b533bc97 1840 ;; XEmacs only.
00d6fd04 1841 'dired-print-file 'dired-shell-call-process
b533bc97 1842 ;; nowhere yet.
b81a0b56
MA
1843 'executable-find 'start-process
1844 'call-process 'call-process-region))
4007ba5b 1845 default-directory)
b533bc97 1846 ;; Unknown file primitive.
4007ba5b
KG
1847 (t (error "unknown file I/O primitive: %s" operation))))
1848
1849(defun tramp-find-foreign-file-name-handler (filename)
1850 "Return foreign file name handler if exists."
b533bc97 1851 (when (tramp-tramp-file-p filename)
9ce8462a
MA
1852 (let ((v (tramp-dissect-file-name filename t))
1853 (handler tramp-foreign-file-name-handler-alist)
1854 elt res)
1855 ;; When we are not fully sure that filename completion is safe,
1856 ;; we should not return a handler.
1857 (when (or (tramp-file-name-method v) (tramp-file-name-user v)
1834b39f
MA
1858 (and (tramp-file-name-host v)
1859 (not (member (tramp-file-name-host v)
1860 (mapcar 'car tramp-methods))))
9ce8462a
MA
1861 (not (tramp-completion-mode-p)))
1862 (while handler
1863 (setq elt (car handler)
1864 handler (cdr handler))
1865 (when (funcall (car elt) filename)
1866 (setq handler nil
1867 res (cdr elt))))
1868 res))))
4007ba5b 1869
fb7933a3
KG
1870;; Main function.
1871;;;###autoload
1872(defun tramp-file-name-handler (operation &rest args)
ea9d1443 1873 "Invoke Tramp file name handler.
a4aeb9a4 1874Falls back to normal file name handler if no Tramp file name handler exists."
2e271195
MA
1875 (if tramp-mode
1876 (save-match-data
1877 (let* ((filename
1878 (tramp-replace-environment-variables
1879 (apply 'tramp-file-name-for-operation operation args)))
1880 (completion (tramp-completion-mode-p))
1881 (foreign (tramp-find-foreign-file-name-handler filename)))
1882 (with-parsed-tramp-file-name filename nil
4874f5e6
MA
1883 ;; Call the backend function.
1884 (if foreign
1885 (condition-case err
11d074b2
MA
1886 (let ((sf (symbol-function foreign)))
1887 ;; Some packages set the default directory to a
1888 ;; remote path, before respective Tramp packages
1889 ;; are already loaded. This results in
1890 ;; recursive loading. Therefore, we load the
1891 ;; Tramp packages locally.
1892 (when (and (listp sf) (eq (car sf) 'autoload))
1893 (let ((default-directory
1894 (tramp-compat-temporary-file-directory)))
6a80b297 1895 (load (cadr sf) 'noerror 'nomessage)))
11d074b2 1896 (apply foreign operation args))
af4b9ae5 1897
51aba3f3 1898 ;; Trace that somebody has interrupted the operation.
56f2d1e1 1899 ((debug quit)
af4b9ae5
MA
1900 (let (tramp-message-show-message)
1901 (tramp-message
1902 v 1 "Interrupt received in operation %s"
1903 (append (list operation) args)))
1904 ;; Propagate the quit signal.
1905 (signal (car err) (cdr err)))
1906
1907 ;; When we are in completion mode, some failed
1908 ;; operations shall return at least a default value
1909 ;; in order to give the user a chance to correct the
1910 ;; file name in the minibuffer.
4cb0aa75 1911 ;; We cannot use `debug' as error handler. In order
56f2d1e1
MA
1912 ;; to get a full backtrace, one could apply
1913 ;; (setq debug-on-error t debug-on-signal t)
4874f5e6
MA
1914 (error
1915 (cond
4874f5e6
MA
1916 ((and completion (zerop (length localname))
1917 (memq operation '(file-exists-p file-directory-p)))
1918 t)
1919 ((and completion (zerop (length localname))
1920 (memq operation
1921 '(expand-file-name file-name-as-directory)))
1922 filename)
1923 ;; Propagate the error.
1924 (t (signal (car err) (cdr err))))))
af4b9ae5 1925
4874f5e6
MA
1926 ;; Nothing to do for us.
1927 (tramp-run-real-handler operation args)))))
1928
2e271195
MA
1929 ;; When `tramp-mode' is not enabled, we don't do anything.
1930 (tramp-run-real-handler operation args)))
fb7933a3 1931
07dfe738
KG
1932;; In Emacs, there is some concurrency due to timers. If a timer
1933;; interrupts Tramp and wishes to use the same connection buffer as
1934;; the "main" Emacs, then garbage might occur in the connection
1935;; buffer. Therefore, we need to make sure that a timer does not use
1936;; the same connection buffer as the "main" Emacs. We implement a
1937;; cheap global lock, instead of locking each connection buffer
1938;; separately. The global lock is based on two variables,
1939;; `tramp-locked' and `tramp-locker'. `tramp-locked' is set to true
1940;; (with setq) to indicate a lock. But Tramp also calls itself during
1941;; processing of a single file operation, so we need to allow
1942;; recursive calls. That's where the `tramp-locker' variable comes in
1943;; -- it is let-bound to t during the execution of the current
1944;; handler. So if `tramp-locked' is t and `tramp-locker' is also t,
1945;; then we should just proceed because we have been called
1946;; recursively. But if `tramp-locker' is nil, then we are a timer
1947;; interrupting the "main" Emacs, and then we signal an error.
1948
1949(defvar tramp-locked nil
1950 "If non-nil, then Tramp is currently busy.
1951Together with `tramp-locker', this implements a locking mechanism
1952preventing reentrant calls of Tramp.")
1953
1954(defvar tramp-locker nil
1955 "If non-nil, then a caller has locked Tramp.
1956Together with `tramp-locked', this implements a locking mechanism
1957preventing reentrant calls of Tramp.")
1958
16674e4f 1959;;;###autoload
1ecc6145 1960(progn (defun tramp-completion-file-name-handler (operation &rest args)
a4aeb9a4
MA
1961 "Invoke Tramp file name completion handler.
1962Falls back to normal file name handler if no Tramp file name handler exists."
57671b72
MA
1963 ;; We bind `directory-sep-char' here for XEmacs on Windows, which
1964 ;; would otherwise use backslash.
aff67808
MA
1965 (let ((directory-sep-char ?/)
1966 (fn (assoc operation tramp-completion-file-name-handler-alist)))
aa485f7c
MA
1967 (if (and
1968 ;; When `tramp-mode' is not enabled, we don't do anything.
1969 fn tramp-mode
1970 ;; For other syntaxes than `sep', the regexp matches many common
1971 ;; situations where the user doesn't actually want to use Tramp.
1972 ;; So to avoid autoloading Tramp after typing just "/s", we
1973 ;; disable this part of the completion, unless the user implicitly
1974 ;; indicated his interest in using a fancier completion system.
1975 (or (eq tramp-syntax 'sep)
a94d821f
MA
1976 (featurep 'tramp) ;; If it's loaded, we may as well use it.
1977 ;; `partial-completion-mode' does not exist in XEmacs.
1978 ;; It is obsoleted with Emacs 24.1.
0d5852cf
MA
1979 (and (boundp 'partial-completion-mode)
1980 (symbol-value 'partial-completion-mode))
aa485f7c
MA
1981 ;; FIXME: These may have been loaded even if the user never
1982 ;; intended to use them.
1983 (featurep 'ido)
1984 (featurep 'icicles)))
aff67808
MA
1985 (save-match-data (apply (cdr fn) args))
1986 (tramp-completion-run-real-handler operation args)))))
a01b1e22 1987
b25a52cc 1988;;;###autoload
aa485f7c
MA
1989(progn (defun tramp-register-file-name-handlers ()
1990 "Add Tramp file name handlers to `file-name-handler-alist'."
1991 ;; Remove autoloaded handlers from file name handler alist. Useful,
00d6fd04
MA
1992 ;; if `tramp-syntax' has been changed.
1993 (let ((a1 (rassq 'tramp-file-name-handler file-name-handler-alist)))
aa485f7c
MA
1994 (setq file-name-handler-alist (delq a1 file-name-handler-alist)))
1995 (let ((a1 (rassq
1996 'tramp-completion-file-name-handler file-name-handler-alist)))
1997 (setq file-name-handler-alist (delq a1 file-name-handler-alist)))
1998 ;; Add the handlers.
a01b1e22
MA
1999 (add-to-list 'file-name-handler-alist
2000 (cons tramp-file-name-regexp 'tramp-file-name-handler))
0c0b61f1 2001 (put 'tramp-file-name-handler 'safe-magic t)
aa485f7c
MA
2002 (add-to-list 'file-name-handler-alist
2003 (cons tramp-completion-file-name-regexp
2004 'tramp-completion-file-name-handler))
2005 (put 'tramp-completion-file-name-handler 'safe-magic t)
2006 ;; If jka-compr or epa-file are already loaded, move them to the
2007 ;; front of `file-name-handler-alist'.
2008 (dolist (fnh '(epa-file-handler jka-compr-handler))
2009 (let ((entry (rassoc fnh file-name-handler-alist)))
2010 (when entry
2011 (setq file-name-handler-alist
2012 (cons entry (delete entry file-name-handler-alist))))))))
69cee873 2013
00d6fd04
MA
2014;; `tramp-file-name-handler' must be registered before evaluation of
2015;; site-start and init files, because there might exist remote files
2016;; already, f.e. files kept via recentf-mode.
4a93e698 2017;;;###autoload
aa485f7c 2018(tramp-register-file-name-handlers)
b25a52cc 2019
4a93e698
MA
2020(defun tramp-exists-file-name-handler (operation &rest args)
2021 "Check, whether OPERATION runs a file name handler."
2022 ;; The file name handler is determined on base of either an
2023 ;; argument, `buffer-file-name', or `default-directory'.
2024 (ignore-errors
2025 (let* ((buffer-file-name "/")
2026 (default-directory "/")
2027 (fnha file-name-handler-alist)
2028 (check-file-name-operation operation)
2029 (file-name-handler-alist
2030 (list
2031 (cons "/"
2032 (lambda (operation &rest args)
2033 "Returns OPERATION if it is the one to be checked."
2034 (if (equal check-file-name-operation operation)
2035 operation
2036 (let ((file-name-handler-alist fnha))
2037 (apply operation args))))))))
2038 (equal (apply operation args) operation))))
2039
fb7933a3 2040;;;###autoload
8c04e197 2041(defun tramp-unload-file-name-handlers ()
a69c01a0
MA
2042 (setq file-name-handler-alist
2043 (delete (rassoc 'tramp-file-name-handler
2044 file-name-handler-alist)
2045 (delete (rassoc 'tramp-completion-file-name-handler
2046 file-name-handler-alist)
2047 file-name-handler-alist))))
2048
8c04e197 2049(add-hook 'tramp-unload-hook 'tramp-unload-file-name-handlers)
a69c01a0 2050
0664ff72 2051;;; File name handler functions for completion mode:
a6e96327
MA
2052
2053(defvar tramp-completion-mode nil
2054 "If non-nil, external packages signal that they are in file name completion.
2055
2056This is necessary, because Tramp uses a heuristic depending on last
2057input event. This fails when external packages use other characters
2058but <TAB>, <SPACE> or ?\\? for file name completion. This variable
2059should never be set globally, the intention is to let-bind it.")
16674e4f
KG
2060
2061;; Necessary because `tramp-file-name-regexp-unified' and
00d6fd04
MA
2062;; `tramp-completion-file-name-regexp-unified' aren't different. If
2063;; nil, `tramp-completion-run-real-handler' is called (i.e. forwarding
2064;; to `tramp-file-name-handler'). Otherwise, it takes
2065;; `tramp-run-real-handler'. Using `last-input-event' is a little bit
2066;; risky, because completing a file might require loading other files,
2067;; like "~/.netrc", and for them it shouldn't be decided based on that
2068;; variable. On the other hand, those files shouldn't have partial
a4aeb9a4
MA
2069;; Tramp file name syntax. Maybe another variable should be introduced
2070;; overwriting this check in such cases. Or we change Tramp file name
00d6fd04 2071;; syntax in order to avoid ambiguities, like in XEmacs ...
0f34aa77 2072;;;###tramp-autoload
6c4e47fa 2073(defun tramp-completion-mode-p ()
a94d821f 2074 "Check, whether method / user name / host name completion is active."
6c4e47fa 2075 (or
5f2b693f
MA
2076 ;; Signal from outside. `non-essential' has been introduced in Emacs 24.
2077 (and (boundp 'non-essential) (symbol-value 'non-essential))
a6e96327
MA
2078 tramp-completion-mode
2079 ;; Emacs.
94be87e8 2080 (equal last-input-event 'tab)
6c4e47fa 2081 (and (natnump last-input-event)
94be87e8 2082 (or
a6e96327 2083 ;; ?\t has event-modifier 'control.
800a97b8 2084 (equal last-input-event ?\t)
94be87e8 2085 (and (not (event-modifiers last-input-event))
800a97b8
SM
2086 (or (equal last-input-event ?\?)
2087 (equal last-input-event ?\ )))))
a6e96327 2088 ;; XEmacs.
6c4e47fa
MA
2089 (and (featurep 'xemacs)
2090 ;; `last-input-event' might be nil.
2091 (not (null last-input-event))
2092 ;; `last-input-event' may have no character approximation.
0d5852cf 2093 (tramp-compat-funcall 'event-to-character last-input-event)
94be87e8 2094 (or
a6e96327 2095 ;; ?\t has event-modifier 'control.
800a97b8 2096 (equal
0d5852cf 2097 (tramp-compat-funcall 'event-to-character last-input-event) ?\t)
94be87e8 2098 (and (not (event-modifiers last-input-event))
800a97b8 2099 (or (equal
0d5852cf
MA
2100 (tramp-compat-funcall 'event-to-character last-input-event)
2101 ?\?)
800a97b8 2102 (equal
0d5852cf
MA
2103 (tramp-compat-funcall 'event-to-character last-input-event)
2104 ?\ )))))))
16674e4f 2105
acd1f317
MA
2106(defun tramp-connectable-p (filename)
2107 "Check, whether it is possible to connect the remote host w/o side-effects.
2108This is true, if either the remote host is already connected, or if we are
2109not in completion mode."
2110 (and (tramp-tramp-file-p filename)
2111 (with-parsed-tramp-file-name filename nil
305c07f6
MA
2112 (or (not (tramp-completion-mode-p))
2113 (let ((p (tramp-get-connection-process v)))
2114 (and p (processp p) (memq (process-status p) '(run open))))))))
acd1f317 2115
16674e4f
KG
2116;; Method, host name and user name completion.
2117;; `tramp-completion-dissect-file-name' returns a list of
2118;; tramp-file-name structures. For all of them we return possible completions.
a01b1e22 2119;;;###autoload
16674e4f 2120(defun tramp-completion-handle-file-name-all-completions (filename directory)
00d6fd04 2121 "Like `file-name-all-completions' for partial Tramp files."
16674e4f 2122
00d6fd04
MA
2123 (let* ((fullname (tramp-drop-volume-letter
2124 (expand-file-name filename directory)))
2125 ;; Possible completion structures.
2126 (v (tramp-completion-dissect-file-name fullname))
2127 result result1)
2128
2129 (while v
2130 (let* ((car (car v))
2131 (method (tramp-file-name-method car))
2132 (user (tramp-file-name-user car))
2133 (host (tramp-file-name-host car))
2134 (localname (tramp-file-name-localname car))
2135 (m (tramp-find-method method user host))
2136 (tramp-current-user user) ; see `tramp-parse-passwd'
2137 all-user-hosts)
2138
2139 (unless localname ;; Nothing to complete.
2140
2141 (if (or user host)
2142
2143 ;; Method dependent user / host combinations.
2144 (progn
9e6ab520 2145 (mapc
00d6fd04
MA
2146 (lambda (x)
2147 (setq all-user-hosts
2148 (append all-user-hosts
2149 (funcall (nth 0 x) (nth 1 x)))))
2150 (tramp-get-completion-function m))
2151
9e6ab520
MA
2152 (setq result
2153 (append result
2154 (mapcar
2155 (lambda (x)
2156 (tramp-get-completion-user-host
2157 method user host (nth 0 x) (nth 1 x)))
2158 (delq nil all-user-hosts)))))
00d6fd04
MA
2159
2160 ;; Possible methods.
2161 (setq result
2162 (append result (tramp-get-completion-methods m)))))
2163
2164 (setq v (cdr v))))
2165
2166 ;; Unify list, remove nil elements.
2167 (while result
2168 (let ((car (car result)))
2169 (when car
2170 (add-to-list
2171 'result1
2172 (substring car (length (tramp-drop-volume-letter directory)))))
2173 (setq result (cdr result))))
2174
2175 ;; Complete local parts.
2176 (append
2177 result1
03c1ad43
MA
2178 (ignore-errors
2179 (apply (if (tramp-connectable-p fullname)
2180 'tramp-completion-run-real-handler
2181 'tramp-run-real-handler)
2182 'file-name-all-completions (list (list filename directory)))))))
16674e4f
KG
2183
2184;; Method, host name and user name completion for a file.
a01b1e22 2185;;;###autoload
e1e17cae
MA
2186(defun tramp-completion-handle-file-name-completion
2187 (filename directory &optional predicate)
00d6fd04 2188 "Like `file-name-completion' for Tramp files."
e1e17cae
MA
2189 (try-completion
2190 filename
2191 (mapcar 'list (file-name-all-completions filename directory))
acd1f317
MA
2192 (when (and predicate
2193 (tramp-connectable-p (expand-file-name filename directory)))
83e20b5c 2194 (lambda (x) (funcall predicate (expand-file-name (car x) directory))))))
16674e4f
KG
2195
2196;; I misuse a little bit the tramp-file-name structure in order to handle
2197;; completion possibilities for partial methods / user names / host names.
2198;; Return value is a list of tramp-file-name structures according to possible
00d6fd04 2199;; completions. If "localname" is non-nil it means there
16674e4f
KG
2200;; shouldn't be a completion anymore.
2201
2202;; Expected results:
2203
00d6fd04
MA
2204;; "/x" "/[x" "/x@" "/[x@" "/x@y" "/[x@y"
2205;; [nil nil "x" nil] [nil "x" nil nil] [nil "x" "y" nil]
2206;; [nil "x" nil nil]
2207;; ["x" nil nil nil]
2208
2209;; "/x:" "/x:y" "/x:y:"
2210;; [nil nil "x" ""] [nil nil "x" "y"] ["x" nil "y" ""]
2211;; "/[x/" "/[x/y"
2212;; ["x" nil "" nil] ["x" nil "y" nil]
2213;; ["x" "" nil nil] ["x" "y" nil nil]
2214
2215;; "/x:y@" "/x:y@z" "/x:y@z:"
2216;; [nil nil "x" "y@"] [nil nil "x" "y@z"] ["x" "y" "z" ""]
2217;; "/[x/y@" "/[x/y@z"
2218;; ["x" nil "y" nil] ["x" "y" "z" nil]
16674e4f
KG
2219(defun tramp-completion-dissect-file-name (name)
2220 "Returns a list of `tramp-file-name' structures.
2221They are collected by `tramp-completion-dissect-file-name1'."
2222
2223 (let* ((result)
4007ba5b 2224 (x-nil "\\|\\(\\)")
b96e6899
MA
2225 (tramp-completion-ipv6-regexp
2226 (format
2227 "[^%s]*"
2228 (if (zerop (length tramp-postfix-ipv6-format))
2229 tramp-postfix-host-format
2230 tramp-postfix-ipv6-format)))
4007ba5b
KG
2231 ;; "/method" "/[method"
2232 (tramp-completion-file-name-structure1
2233 (list (concat tramp-prefix-regexp "\\(" tramp-method-regexp x-nil "\\)$")
2234 1 nil nil nil))
2235 ;; "/user" "/[user"
2236 (tramp-completion-file-name-structure2
2237 (list (concat tramp-prefix-regexp "\\(" tramp-user-regexp x-nil "\\)$")
2238 nil 1 nil nil))
2239 ;; "/host" "/[host"
2240 (tramp-completion-file-name-structure3
2241 (list (concat tramp-prefix-regexp "\\(" tramp-host-regexp x-nil "\\)$")
2242 nil nil 1 nil))
b96e6899 2243 ;; "/[ipv6" "/[ipv6"
4007ba5b 2244 (tramp-completion-file-name-structure4
b96e6899
MA
2245 (list (concat tramp-prefix-regexp
2246 tramp-prefix-ipv6-regexp
2247 "\\(" tramp-completion-ipv6-regexp x-nil "\\)$")
2248 nil nil 1 nil))
2249 ;; "/user@host" "/[user@host"
2250 (tramp-completion-file-name-structure5
4007ba5b
KG
2251 (list (concat tramp-prefix-regexp
2252 "\\(" tramp-user-regexp "\\)" tramp-postfix-user-regexp
2253 "\\(" tramp-host-regexp x-nil "\\)$")
2254 nil 1 2 nil))
b96e6899
MA
2255 ;; "/user@[ipv6" "/[user@ipv6"
2256 (tramp-completion-file-name-structure6
2257 (list (concat tramp-prefix-regexp
2258 "\\(" tramp-user-regexp "\\)" tramp-postfix-user-regexp
2259 tramp-prefix-ipv6-regexp
2260 "\\(" tramp-completion-ipv6-regexp x-nil "\\)$")
2261 nil 1 2 nil))
00d6fd04 2262 ;; "/method:user" "/[method/user" "/method://user"
b96e6899 2263 (tramp-completion-file-name-structure7
4007ba5b 2264 (list (concat tramp-prefix-regexp
00d6fd04 2265 "\\(" tramp-method-regexp "\\)" tramp-postfix-method-regexp
4007ba5b
KG
2266 "\\(" tramp-user-regexp x-nil "\\)$")
2267 1 2 nil nil))
00d6fd04 2268 ;; "/method:host" "/[method/host" "/method://host"
b96e6899 2269 (tramp-completion-file-name-structure8
4007ba5b 2270 (list (concat tramp-prefix-regexp
00d6fd04 2271 "\\(" tramp-method-regexp "\\)" tramp-postfix-method-regexp
4007ba5b
KG
2272 "\\(" tramp-host-regexp x-nil "\\)$")
2273 1 nil 2 nil))
b96e6899
MA
2274 ;; "/method:[ipv6" "/[method/ipv6" "/method://[ipv6"
2275 (tramp-completion-file-name-structure9
2276 (list (concat tramp-prefix-regexp
2277 "\\(" tramp-method-regexp "\\)" tramp-postfix-method-regexp
2278 tramp-prefix-ipv6-regexp
2279 "\\(" tramp-completion-ipv6-regexp x-nil "\\)$")
2280 1 nil 2 nil))
00d6fd04 2281 ;; "/method:user@host" "/[method/user@host" "/method://user@host"
b96e6899 2282 (tramp-completion-file-name-structure10
4007ba5b 2283 (list (concat tramp-prefix-regexp
00d6fd04 2284 "\\(" tramp-method-regexp "\\)" tramp-postfix-method-regexp
4007ba5b
KG
2285 "\\(" tramp-user-regexp "\\)" tramp-postfix-user-regexp
2286 "\\(" tramp-host-regexp x-nil "\\)$")
00d6fd04 2287 1 2 3 nil))
b96e6899
MA
2288 ;; "/method:user@[ipv6" "/[method/user@ipv6" "/method://user@[ipv6"
2289 (tramp-completion-file-name-structure11
2290 (list (concat tramp-prefix-regexp
2291 "\\(" tramp-method-regexp "\\)" tramp-postfix-method-regexp
2292 "\\(" tramp-user-regexp "\\)" tramp-postfix-user-regexp
2293 tramp-prefix-ipv6-regexp
2294 "\\(" tramp-completion-ipv6-regexp x-nil "\\)$")
2295 1 2 3 nil))
00d6fd04 2296 ;; "/method: "/method:/"
b96e6899 2297 (tramp-completion-file-name-structure12
00d6fd04
MA
2298 (list
2299 (if (equal tramp-syntax 'url)
2300 (concat tramp-prefix-regexp
2301 "\\(" tramp-method-regexp "\\)"
2302 "\\(" (substring tramp-postfix-method-regexp 0 1)
2303 "\\|" (substring tramp-postfix-method-regexp 1 2) "\\)"
2304 "\\(" "\\)$")
2305 ;; Should not match if not URL syntax.
2306 (concat tramp-prefix-regexp "/$"))
2307 1 3 nil nil))
2308 ;; "/method: "/method:/"
b96e6899 2309 (tramp-completion-file-name-structure13
00d6fd04
MA
2310 (list
2311 (if (equal tramp-syntax 'url)
2312 (concat tramp-prefix-regexp
2313 "\\(" tramp-method-regexp "\\)"
2314 "\\(" (substring tramp-postfix-method-regexp 0 1)
2315 "\\|" (substring tramp-postfix-method-regexp 1 2) "\\)"
2316 "\\(" "\\)$")
2317 ;; Should not match if not URL syntax.
2318 (concat tramp-prefix-regexp "/$"))
2319 1 nil 3 nil)))
4007ba5b 2320
9e6ab520 2321 (mapc (lambda (regexp)
16674e4f
KG
2322 (add-to-list 'result
2323 (tramp-completion-dissect-file-name1 regexp name)))
2324 (list
2325 tramp-completion-file-name-structure1
2326 tramp-completion-file-name-structure2
2327 tramp-completion-file-name-structure3
2328 tramp-completion-file-name-structure4
2329 tramp-completion-file-name-structure5
2330 tramp-completion-file-name-structure6
2331 tramp-completion-file-name-structure7
00d6fd04
MA
2332 tramp-completion-file-name-structure8
2333 tramp-completion-file-name-structure9
b96e6899
MA
2334 tramp-completion-file-name-structure10
2335 tramp-completion-file-name-structure11
2336 tramp-completion-file-name-structure12
2337 tramp-completion-file-name-structure13
16674e4f
KG
2338 tramp-file-name-structure))
2339
2340 (delq nil result)))
2341
2342(defun tramp-completion-dissect-file-name1 (structure name)
2343 "Returns a `tramp-file-name' structure matching STRUCTURE.
00d6fd04 2344The structure consists of remote method, remote user,
7432277c 2345remote host and localname (filename on remote host)."
fb7933a3 2346
00d6fd04
MA
2347 (save-match-data
2348 (when (string-match (nth 0 structure) name)
2349 (let ((method (and (nth 1 structure)
2350 (match-string (nth 1 structure) name)))
2351 (user (and (nth 2 structure)
2352 (match-string (nth 2 structure) name)))
2353 (host (and (nth 3 structure)
2354 (match-string (nth 3 structure) name)))
2355 (localname (and (nth 4 structure)
2356 (match-string (nth 4 structure) name))))
2357 (vector method user host localname)))))
16674e4f
KG
2358
2359;; This function returns all possible method completions, adding the
51aba3f3 2360;; trailing method delimiter.
16674e4f
KG
2361(defun tramp-get-completion-methods (partial-method)
2362 "Returns all method completions for PARTIAL-METHOD."
4007ba5b
KG
2363 (mapcar
2364 (lambda (method)
2365 (and method
2366 (string-match (concat "^" (regexp-quote partial-method)) method)
00d6fd04
MA
2367 (tramp-completion-make-tramp-file-name method nil nil nil)))
2368 (mapcar 'car tramp-methods)))
16674e4f
KG
2369
2370;; Compares partial user and host names with possible completions.
2371(defun tramp-get-completion-user-host (method partial-user partial-host user host)
2372 "Returns the most expanded string for user and host name completion.
2373PARTIAL-USER must match USER, PARTIAL-HOST must match HOST."
2374 (cond
2375
2376 ((and partial-user partial-host)
2377 (if (and host
2378 (string-match (concat "^" (regexp-quote partial-host)) host)
2379 (string-equal partial-user (or user partial-user)))
2380 (setq user partial-user)
2381 (setq user nil
2382 host nil)))
2383
2384 (partial-user
2385 (setq host nil)
2386 (unless
2387 (and user (string-match (concat "^" (regexp-quote partial-user)) user))
2388 (setq user nil)))
2389
2390 (partial-host
2391 (setq user nil)
2392 (unless
2393 (and host (string-match (concat "^" (regexp-quote partial-host)) host))
2394 (setq host nil)))
2395
2396 (t (setq user nil
2397 host nil)))
2398
292ffc15 2399 (unless (zerop (+ (length user) (length host)))
00d6fd04 2400 (tramp-completion-make-tramp-file-name method user host nil)))
16674e4f 2401
f8f91c2b 2402;;;###tramp-autoload
16674e4f
KG
2403(defun tramp-parse-rhosts (filename)
2404 "Return a list of (user host) tuples allowed to access.
292ffc15 2405Either user or host may be nil."
00d6fd04
MA
2406 ;; On Windows, there are problems in completion when
2407 ;; `default-directory' is remote.
9e6ab520 2408 (let ((default-directory (tramp-compat-temporary-file-directory))
00d6fd04 2409 res)
8daea7fc 2410 (when (file-readable-p filename)
16674e4f
KG
2411 (with-temp-buffer
2412 (insert-file-contents filename)
2413 (goto-char (point-min))
2414 (while (not (eobp))
292ffc15 2415 (push (tramp-parse-rhosts-group) res))))
16674e4f
KG
2416 res))
2417
16674e4f
KG
2418(defun tramp-parse-rhosts-group ()
2419 "Return a (user host) tuple allowed to access.
292ffc15 2420Either user or host may be nil."
16674e4f
KG
2421 (let ((result)
2422 (regexp
2423 (concat
2424 "^\\(" tramp-host-regexp "\\)"
2425 "\\([ \t]+" "\\(" tramp-user-regexp "\\)" "\\)?")))
6e060cee 2426 (narrow-to-region (point) (point-at-eol))
16674e4f
KG
2427 (when (re-search-forward regexp nil t)
2428 (setq result (append (list (match-string 3) (match-string 1)))))
2429 (widen)
2430 (forward-line 1)
2431 result))
2432
f8f91c2b 2433;;;###tramp-autoload
16674e4f
KG
2434(defun tramp-parse-shosts (filename)
2435 "Return a list of (user host) tuples allowed to access.
2436User is always nil."
00d6fd04
MA
2437 ;; On Windows, there are problems in completion when
2438 ;; `default-directory' is remote.
9e6ab520 2439 (let ((default-directory (tramp-compat-temporary-file-directory))
00d6fd04 2440 res)
8daea7fc 2441 (when (file-readable-p filename)
16674e4f
KG
2442 (with-temp-buffer
2443 (insert-file-contents filename)
2444 (goto-char (point-min))
2445 (while (not (eobp))
292ffc15 2446 (push (tramp-parse-shosts-group) res))))
16674e4f
KG
2447 res))
2448
2449(defun tramp-parse-shosts-group ()
2450 "Return a (user host) tuple allowed to access.
2451User is always nil."
16674e4f
KG
2452 (let ((result)
2453 (regexp (concat "^\\(" tramp-host-regexp "\\)")))
6e060cee 2454 (narrow-to-region (point) (point-at-eol))
16674e4f
KG
2455 (when (re-search-forward regexp nil t)
2456 (setq result (list nil (match-string 1))))
2457 (widen)
2458 (or
2459 (> (skip-chars-forward ",") 0)
2460 (forward-line 1))
2461 result))
2462
f8f91c2b 2463;;;###tramp-autoload
8daea7fc
KG
2464(defun tramp-parse-sconfig (filename)
2465 "Return a list of (user host) tuples allowed to access.
2466User is always nil."
00d6fd04
MA
2467 ;; On Windows, there are problems in completion when
2468 ;; `default-directory' is remote.
9e6ab520 2469 (let ((default-directory (tramp-compat-temporary-file-directory))
00d6fd04 2470 res)
8daea7fc
KG
2471 (when (file-readable-p filename)
2472 (with-temp-buffer
2473 (insert-file-contents filename)
2474 (goto-char (point-min))
2475 (while (not (eobp))
2476 (push (tramp-parse-sconfig-group) res))))
2477 res))
2478
2479(defun tramp-parse-sconfig-group ()
2480 "Return a (user host) tuple allowed to access.
2481User is always nil."
8daea7fc
KG
2482 (let ((result)
2483 (regexp (concat "^[ \t]*Host[ \t]+" "\\(" tramp-host-regexp "\\)")))
6e060cee 2484 (narrow-to-region (point) (point-at-eol))
8daea7fc
KG
2485 (when (re-search-forward regexp nil t)
2486 (setq result (list nil (match-string 1))))
2487 (widen)
2488 (or
2489 (> (skip-chars-forward ",") 0)
2490 (forward-line 1))
2491 result))
2492
f8f91c2b 2493;;;###tramp-autoload
5ec2cc41
KG
2494(defun tramp-parse-shostkeys (dirname)
2495 "Return a list of (user host) tuples allowed to access.
2496User is always nil."
00d6fd04
MA
2497 ;; On Windows, there are problems in completion when
2498 ;; `default-directory' is remote.
9e6ab520 2499 (let* ((default-directory (tramp-compat-temporary-file-directory))
00d6fd04
MA
2500 (regexp (concat "^key_[0-9]+_\\(" tramp-host-regexp "\\)\\.pub$"))
2501 (files (when (file-directory-p dirname) (directory-files dirname)))
2502 result)
5ec2cc41
KG
2503 (while files
2504 (when (string-match regexp (car files))
2505 (push (list nil (match-string 1 (car files))) result))
2506 (setq files (cdr files)))
2507 result))
2508
2509(defun tramp-parse-sknownhosts (dirname)
2510 "Return a list of (user host) tuples allowed to access.
2511User is always nil."
00d6fd04
MA
2512 ;; On Windows, there are problems in completion when
2513 ;; `default-directory' is remote.
9e6ab520 2514 (let* ((default-directory (tramp-compat-temporary-file-directory))
00d6fd04
MA
2515 (regexp (concat "^\\(" tramp-host-regexp
2516 "\\)\\.ssh-\\(dss\\|rsa\\)\\.pub$"))
2517 (files (when (file-directory-p dirname) (directory-files dirname)))
2518 result)
5ec2cc41
KG
2519 (while files
2520 (when (string-match regexp (car files))
2521 (push (list nil (match-string 1 (car files))) result))
2522 (setq files (cdr files)))
2523 result))
2524
f8f91c2b 2525;;;###tramp-autoload
16674e4f
KG
2526(defun tramp-parse-hosts (filename)
2527 "Return a list of (user host) tuples allowed to access.
2528User is always nil."
00d6fd04
MA
2529 ;; On Windows, there are problems in completion when
2530 ;; `default-directory' is remote.
9e6ab520 2531 (let ((default-directory (tramp-compat-temporary-file-directory))
00d6fd04 2532 res)
8daea7fc 2533 (when (file-readable-p filename)
16674e4f
KG
2534 (with-temp-buffer
2535 (insert-file-contents filename)
2536 (goto-char (point-min))
2537 (while (not (eobp))
292ffc15 2538 (push (tramp-parse-hosts-group) res))))
16674e4f
KG
2539 res))
2540
2541(defun tramp-parse-hosts-group ()
2542 "Return a (user host) tuple allowed to access.
2543User is always nil."
16674e4f 2544 (let ((result)
b96e6899
MA
2545 (regexp
2546 (concat "^\\(" tramp-ipv6-regexp "\\|" tramp-host-regexp "\\)")))
6e060cee 2547 (narrow-to-region (point) (point-at-eol))
16674e4f 2548 (when (re-search-forward regexp nil t)
b96e6899 2549 (setq result (list nil (match-string 1))))
16674e4f
KG
2550 (widen)
2551 (or
2552 (> (skip-chars-forward " \t") 0)
2553 (forward-line 1))
2554 result))
2555
8daea7fc
KG
2556;; For su-alike methods it would be desirable to return "root@localhost"
2557;; as default. Unfortunately, we have no information whether any user name
00d6fd04 2558;; has been typed already. So we use `tramp-current-user' as indication,
8daea7fc 2559;; assuming it is set in `tramp-completion-handle-file-name-all-completions'.
f8f91c2b 2560;;;###tramp-autoload
16674e4f
KG
2561(defun tramp-parse-passwd (filename)
2562 "Return a list of (user host) tuples allowed to access.
2563Host is always \"localhost\"."
00d6fd04
MA
2564 ;; On Windows, there are problems in completion when
2565 ;; `default-directory' is remote.
9e6ab520 2566 (let ((default-directory (tramp-compat-temporary-file-directory))
00d6fd04 2567 res)
8daea7fc 2568 (if (zerop (length tramp-current-user))
16674e4f 2569 '(("root" nil))
8daea7fc 2570 (when (file-readable-p filename)
16674e4f
KG
2571 (with-temp-buffer
2572 (insert-file-contents filename)
2573 (goto-char (point-min))
2574 (while (not (eobp))
292ffc15 2575 (push (tramp-parse-passwd-group) res))))
16674e4f
KG
2576 res)))
2577
2578(defun tramp-parse-passwd-group ()
2579 "Return a (user host) tuple allowed to access.
292ffc15 2580Host is always \"localhost\"."
16674e4f
KG
2581 (let ((result)
2582 (regexp (concat "^\\(" tramp-user-regexp "\\):")))
6e060cee 2583 (narrow-to-region (point) (point-at-eol))
16674e4f
KG
2584 (when (re-search-forward regexp nil t)
2585 (setq result (list (match-string 1) "localhost")))
2586 (widen)
2587 (forward-line 1)
2588 result))
2589
f8f91c2b 2590;;;###tramp-autoload
292ffc15
KG
2591(defun tramp-parse-netrc (filename)
2592 "Return a list of (user host) tuples allowed to access.
2593User may be nil."
00d6fd04
MA
2594 ;; On Windows, there are problems in completion when
2595 ;; `default-directory' is remote.
9e6ab520 2596 (let ((default-directory (tramp-compat-temporary-file-directory))
00d6fd04 2597 res)
8daea7fc 2598 (when (file-readable-p filename)
292ffc15
KG
2599 (with-temp-buffer
2600 (insert-file-contents filename)
2601 (goto-char (point-min))
2602 (while (not (eobp))
2603 (push (tramp-parse-netrc-group) res))))
2604 res))
2605
2606(defun tramp-parse-netrc-group ()
2607 "Return a (user host) tuple allowed to access.
2608User may be nil."
292ffc15
KG
2609 (let ((result)
2610 (regexp
2611 (concat
2612 "^[ \t]*machine[ \t]+" "\\(" tramp-host-regexp "\\)"
2613 "\\([ \t]+login[ \t]+" "\\(" tramp-user-regexp "\\)" "\\)?")))
6e060cee 2614 (narrow-to-region (point) (point-at-eol))
292ffc15
KG
2615 (when (re-search-forward regexp nil t)
2616 (setq result (list (match-string 3) (match-string 1))))
2617 (widen)
2618 (forward-line 1)
2619 result))
2620
f8f91c2b 2621;;;###tramp-autoload
00d6fd04
MA
2622(defun tramp-parse-putty (registry)
2623 "Return a list of (user host) tuples allowed to access.
2624User is always nil."
2625 ;; On Windows, there are problems in completion when
2626 ;; `default-directory' is remote.
9e6ab520 2627 (let ((default-directory (tramp-compat-temporary-file-directory))
00d6fd04
MA
2628 res)
2629 (with-temp-buffer
0f34aa77 2630 (when (zerop (tramp-compat-call-process "reg" nil t nil "query" registry))
00d6fd04
MA
2631 (goto-char (point-min))
2632 (while (not (eobp))
2633 (push (tramp-parse-putty-group registry) res))))
2634 res))
2635
2636(defun tramp-parse-putty-group (registry)
2637 "Return a (user host) tuple allowed to access.
2638User is always nil."
2639 (let ((result)
2640 (regexp (concat (regexp-quote registry) "\\\\\\(.+\\)")))
6e060cee 2641 (narrow-to-region (point) (point-at-eol))
00d6fd04
MA
2642 (when (re-search-forward regexp nil t)
2643 (setq result (list nil (match-string 1))))
2644 (widen)
2645 (forward-line 1)
2646 result))
2647
4a93e698 2648;;; Common file name handler functions for different backends:
b88f2d0a 2649
4a93e698
MA
2650(defvar tramp-handle-file-local-copy-hook nil
2651 "Normal hook to be run at the end of `tramp-*-handle-file-local-copy'.")
2652
2653(defvar tramp-handle-write-region-hook nil
2654 "Normal hook to be run at the end of `tramp-*-handle-write-region'.")
2655
2656(defun tramp-handle-directory-file-name (directory)
2657 "Like `directory-file-name' for Tramp files."
2658 ;; If localname component of filename is "/", leave it unchanged.
2659 ;; Otherwise, remove any trailing slash from localname component.
2660 ;; Method, host, etc, are unchanged. Does it make sense to try
2661 ;; to avoid parsing the filename?
2662 (with-parsed-tramp-file-name directory nil
2663 (if (and (not (zerop (length localname)))
2664 (eq (aref localname (1- (length localname))) ?/)
2665 (not (string= localname "/")))
2666 (substring directory 0 -1)
2667 directory)))
2668
2669(defun tramp-handle-directory-files
2670 (directory &optional full match nosort files-only)
2671 "Like `directory-files' for Tramp files."
2672 ;; FILES-ONLY is valid for XEmacs only.
2673 (when (file-directory-p directory)
2674 (setq directory (file-name-as-directory (expand-file-name directory)))
2675 (let ((temp (nreverse (file-name-all-completions "" directory)))
2676 result item)
2677
2678 (while temp
2679 (setq item (directory-file-name (pop temp)))
2680 (when (and (or (null match) (string-match match item))
2681 (or (null files-only)
2682 ;; Files only.
2683 (and (equal files-only t) (file-regular-p item))
2684 ;; Directories only.
2685 (file-directory-p item)))
2686 (push (if full (concat directory item) item)
2687 result)))
2688 (if nosort result (sort result 'string<)))))
2689
bd8fadca
MA
2690(defun tramp-handle-directory-files-and-attributes
2691 (directory &optional full match nosort id-format)
2692 "Like `directory-files-and-attributes' for Tramp files."
2693 (mapcar
2694 (lambda (x)
2695 (cons x (tramp-compat-file-attributes
2696 (if full x (expand-file-name x directory)) id-format)))
2697 (directory-files directory full match nosort)))
2698
4a93e698
MA
2699(defun tramp-handle-dired-uncache (dir &optional dir-p)
2700 "Like `dired-uncache' for Tramp files."
2701 ;; DIR-P is valid for XEmacs only.
2702 (with-parsed-tramp-file-name
2703 (if (or dir-p (file-directory-p dir)) dir (file-name-directory dir)) nil
2704 (tramp-flush-directory-property v localname)))
2705
bd8fadca
MA
2706(defun tramp-handle-file-exists-p (filename)
2707 "Like `file-exists-p' for Tramp files."
2708 (not (null (file-attributes filename))))
2709
4a93e698
MA
2710(defun tramp-handle-file-modes (filename)
2711 "Like `file-modes' for Tramp files."
2712 (let ((truename (or (file-truename filename) filename)))
2713 (when (file-exists-p truename)
2714 (tramp-mode-string-to-int (nth 8 (file-attributes truename))))))
2715
2716;; Localname manipulation functions that grok Tramp localnames...
2717(defun tramp-handle-file-name-as-directory (file)
2718 "Like `file-name-as-directory' but aware of Tramp files."
2719 ;; `file-name-as-directory' would be sufficient except localname is
2720 ;; the empty string.
2721 (let ((v (tramp-dissect-file-name file t)))
2722 ;; Run the command on the localname portion only.
2723 (tramp-make-tramp-file-name
2724 (tramp-file-name-method v)
2725 (tramp-file-name-user v)
2726 (tramp-file-name-host v)
2727 (tramp-run-real-handler
2728 'file-name-as-directory (list (or (tramp-file-name-localname v) ""))))))
2729
2730(defun tramp-handle-file-name-completion
2731 (filename directory &optional predicate)
2732 "Like `file-name-completion' for Tramp files."
2733 (unless (tramp-tramp-file-p directory)
2734 (error
2735 "tramp-handle-file-name-completion invoked on non-tramp directory `%s'"
2736 directory))
2737 (try-completion
2738 filename
2739 (mapcar 'list (file-name-all-completions filename directory))
2740 (when predicate
2741 (lambda (x) (funcall predicate (expand-file-name (car x) directory))))))
2742
2743(defun tramp-handle-file-name-directory (file)
2744 "Like `file-name-directory' but aware of Tramp files."
2745 ;; Everything except the last filename thing is the directory. We
2746 ;; cannot apply `with-parsed-tramp-file-name', because this expands
2747 ;; the remote file name parts. This is a problem when we are in
2748 ;; file name completion.
2749 (let ((v (tramp-dissect-file-name file t)))
2750 ;; Run the command on the localname portion only.
2751 (tramp-make-tramp-file-name
2752 (tramp-file-name-method v)
2753 (tramp-file-name-user v)
2754 (tramp-file-name-host v)
2755 (tramp-run-real-handler
2756 'file-name-directory (list (or (tramp-file-name-localname v) ""))))))
2757
2758(defun tramp-handle-file-name-nondirectory (file)
2759 "Like `file-name-nondirectory' but aware of Tramp files."
2760 (with-parsed-tramp-file-name file nil
2761 (tramp-run-real-handler 'file-name-nondirectory (list localname))))
2762
bd8fadca
MA
2763(defun tramp-handle-file-newer-than-file-p (file1 file2)
2764 "Like `file-newer-than-file-p' for Tramp files."
2765 (cond
2766 ((not (file-exists-p file1)) nil)
2767 ((not (file-exists-p file2)) t)
2768 (t (tramp-time-less-p (nth 5 (file-attributes file2))
2769 (nth 5 (file-attributes file1))))))
2770
4a93e698
MA
2771(defun tramp-handle-file-regular-p (filename)
2772 "Like `file-regular-p' for Tramp files."
2773 (and (file-exists-p filename)
2774 (eq ?- (aref (nth 8 (file-attributes filename)) 0))))
2775
2776(defun tramp-handle-file-remote-p (filename &optional identification connected)
2777 "Like `file-remote-p' for Tramp files."
2778 (let ((tramp-verbose 3))
2779 (when (tramp-tramp-file-p filename)
2780 (let* ((v (tramp-dissect-file-name filename))
2781 (p (tramp-get-connection-process v))
2782 (c (and p (processp p) (memq (process-status p) '(run open)))))
2783 ;; We expand the file name only, if there is already a connection.
2784 (with-parsed-tramp-file-name
2785 (if c (expand-file-name filename) filename) nil
2786 (and (or (not connected) c)
2787 (cond
2788 ((eq identification 'method) method)
2789 ((eq identification 'user) user)
2790 ((eq identification 'host) host)
2791 ((eq identification 'localname) localname)
2792 (t (tramp-make-tramp-file-name method user host "")))))))))
2793
2794(defun tramp-handle-file-symlink-p (filename)
2795 "Like `file-symlink-p' for Tramp files."
2796 (with-parsed-tramp-file-name filename nil
2797 (let ((x (car (file-attributes filename))))
2798 (when (stringp x)
2799 ;; When Tramp is running on VMS, then `file-name-absolute-p'
2800 ;; might do weird things.
2801 (if (file-name-absolute-p x)
2802 (tramp-make-tramp-file-name method user host x)
2803 x)))))
2804
2805(defun tramp-handle-find-backup-file-name (filename)
2806 "Like `find-backup-file-name' for Tramp files."
2807 (with-parsed-tramp-file-name filename nil
2808 ;; We set both variables. It doesn't matter whether it is
2809 ;; Emacs or XEmacs.
2810 (let ((backup-directory-alist
2811 ;; Emacs case.
2812 (when (boundp 'backup-directory-alist)
2813 (if (symbol-value 'tramp-backup-directory-alist)
2814 (mapcar
2815 (lambda (x)
2816 (cons
2817 (car x)
2818 (if (and (stringp (cdr x))
2819 (file-name-absolute-p (cdr x))
2820 (not (tramp-file-name-p (cdr x))))
2821 (tramp-make-tramp-file-name method user host (cdr x))
2822 (cdr x))))
2823 (symbol-value 'tramp-backup-directory-alist))
2824 (symbol-value 'backup-directory-alist))))
2825
2826 (bkup-backup-directory-info
2827 ;; XEmacs case.
2828 (when (boundp 'bkup-backup-directory-info)
2829 (if (symbol-value 'tramp-bkup-backup-directory-info)
2830 (mapcar
2831 (lambda (x)
2832 (nconc
2833 (list (car x))
2834 (list
2835 (if (and (stringp (car (cdr x)))
2836 (file-name-absolute-p (car (cdr x)))
2837 (not (tramp-file-name-p (car (cdr x)))))
2838 (tramp-make-tramp-file-name
2839 method user host (car (cdr x)))
2840 (car (cdr x))))
2841 (cdr (cdr x))))
2842 (symbol-value 'tramp-bkup-backup-directory-info))
2843 (symbol-value 'bkup-backup-directory-info)))))
2844
2845 (tramp-run-real-handler 'find-backup-file-name (list filename)))))
2846
2847(defun tramp-handle-insert-file-contents
2848 (filename &optional visit beg end replace)
2849 "Like `insert-file-contents' for Tramp files."
2850 (barf-if-buffer-read-only)
2851 (setq filename (expand-file-name filename))
2852 (let (result local-copy remote-copy)
2853 (with-parsed-tramp-file-name filename nil
2854 (unwind-protect
2855 (if (not (file-exists-p filename))
2856 ;; We don't raise a Tramp error, because it might be
2857 ;; suppressed, like in `find-file-noselect-1'.
2858 (signal 'file-error
2859 (list "File not found on remote host" filename))
2860
2861 (if (and (tramp-local-host-p v)
2862 (let (file-name-handler-alist)
2863 (file-readable-p localname)))
2864 ;; Short track: if we are on the local host, we can
2865 ;; run directly.
2866 (setq result
2867 (tramp-run-real-handler
2868 'insert-file-contents
2869 (list localname visit beg end replace)))
2870
2871 ;; When we shall insert only a part of the file, we copy
2872 ;; this part.
2873 (when (or beg end)
2874 (setq remote-copy (tramp-make-tramp-temp-file v))
2875 ;; This is defined in tramp-sh.el. Let's assume this
2876 ;; is loaded already.
2877 (tramp-compat-funcall 'tramp-send-command
2878 v
2879 (cond
2880 ((and beg end)
7c1d9aa0
MA
2881 (format "dd bs=1 skip=%d if=%s count=%d of=%s"
2882 beg (tramp-shell-quote-argument localname)
4a93e698
MA
2883 (- end beg) remote-copy))
2884 (beg
7c1d9aa0
MA
2885 (format "dd bs=1 skip=%d if=%s of=%s"
2886 beg (tramp-shell-quote-argument localname)
4a93e698
MA
2887 remote-copy))
2888 (end
7c1d9aa0
MA
2889 (format "dd bs=1 count=%d if=%s of=%s"
2890 end (tramp-shell-quote-argument localname)
4a93e698
MA
2891 remote-copy)))))
2892
2893 ;; `insert-file-contents-literally' takes care to avoid
2894 ;; calling jka-compr. By let-binding
2895 ;; `inhibit-file-name-operation', we propagate that care
2896 ;; to the `file-local-copy' operation.
2897 (setq local-copy
2898 (let ((inhibit-file-name-operation
2899 (when (eq inhibit-file-name-operation
2900 'insert-file-contents)
2901 'file-local-copy)))
2902 (cond
2903 ((stringp remote-copy)
2904 (file-local-copy
2905 (tramp-make-tramp-file-name
2906 method user host remote-copy)))
2907 ((stringp tramp-temp-buffer-file-name)
2908 (copy-file filename tramp-temp-buffer-file-name 'ok)
2909 tramp-temp-buffer-file-name)
2910 (t (file-local-copy filename)))))
2911
2912 ;; When the file is not readable for the owner, it
d68b0220
MA
2913 ;; cannot be inserted, even if it is readable for the
2914 ;; group or for everybody.
4a93e698
MA
2915 (set-file-modes local-copy (tramp-compat-octal-to-decimal "0600"))
2916
2917 (when (and (null remote-copy)
2918 (tramp-get-method-parameter
2919 method 'tramp-copy-keep-tmpfile))
2920 ;; We keep the local file for performance reasons,
2921 ;; useful for "rsync".
d68b0220 2922 (setq tramp-temp-buffer-file-name local-copy))
4a93e698 2923
7d520089 2924 (tramp-with-progress-reporter
4a93e698
MA
2925 v 3 (format "Inserting local temp file `%s'" local-copy)
2926 ;; We must ensure that `file-coding-system-alist'
2927 ;; matches `local-copy'.
2928 (let ((file-coding-system-alist
2929 (tramp-find-file-name-coding-system-alist
2930 filename local-copy)))
2931 (setq result
2932 (insert-file-contents
2933 local-copy nil nil nil replace))))))
2934
2935 ;; Save exit.
2936 (progn
2937 (when visit
2938 (setq buffer-file-name filename)
2939 (setq buffer-read-only (not (file-writable-p filename)))
2940 (set-visited-file-modtime)
e274eb13 2941 (set-buffer-modified-p nil))
4a93e698
MA
2942 (when (and (stringp local-copy)
2943 (or remote-copy (null tramp-temp-buffer-file-name)))
2944 (delete-file local-copy))
2945 (when (stringp remote-copy)
2946 (delete-file
2947 (tramp-make-tramp-file-name method user host remote-copy))))))
2948
2949 ;; Result.
2950 (list (expand-file-name filename)
2951 (cadr result))))
2952
2953(defun tramp-handle-load (file &optional noerror nomessage nosuffix must-suffix)
2954 "Like `load' for Tramp files."
2955 (with-parsed-tramp-file-name (expand-file-name file) nil
2956 (unless nosuffix
2957 (cond ((file-exists-p (concat file ".elc"))
2958 (setq file (concat file ".elc")))
2959 ((file-exists-p (concat file ".el"))
2960 (setq file (concat file ".el")))))
2961 (when must-suffix
2962 ;; The first condition is always true for absolute file names.
2963 ;; Included for safety's sake.
2964 (unless (or (file-name-directory file)
2965 (string-match "\\.elc?\\'" file))
2966 (tramp-error
2967 v 'file-error
2968 "File `%s' does not include a `.el' or `.elc' suffix" file)))
2969 (unless noerror
2970 (when (not (file-exists-p file))
2971 (tramp-error v 'file-error "Cannot load nonexistent file `%s'" file)))
2972 (if (not (file-exists-p file))
2973 nil
2974 (let ((tramp-message-show-message (not nomessage)))
7d520089 2975 (tramp-with-progress-reporter v 0 (format "Loading %s" file)
4a93e698
MA
2976 (let ((local-copy (file-local-copy file)))
2977 ;; MUST-SUFFIX doesn't exist on XEmacs, so let it default to nil.
2978 (unwind-protect
2979 (load local-copy noerror t t)
2980 (delete-file local-copy)))))
2981 t)))
2982
f5e29b9b
MA
2983(defun tramp-handle-shell-command
2984 (command &optional output-buffer error-buffer)
2985 "Like `shell-command' for Tramp files."
2986 (let* ((asynchronous (string-match "[ \t]*&[ \t]*\\'" command))
2987 ;; We cannot use `shell-file-name' and `shell-command-switch',
2988 ;; they are variables of the local host.
2989 (args (append
2990 (cons
2991 (tramp-get-method-parameter
2992 (tramp-file-name-method
2993 (tramp-dissect-file-name default-directory))
2994 'tramp-remote-shell)
2995 (tramp-get-method-parameter
2996 (tramp-file-name-method
2997 (tramp-dissect-file-name default-directory))
2998 'tramp-remote-shell-args))
2999 (list (substring command 0 asynchronous))))
3000 current-buffer-p
3001 (output-buffer
3002 (cond
3003 ((bufferp output-buffer) output-buffer)
3004 ((stringp output-buffer) (get-buffer-create output-buffer))
3005 (output-buffer
3006 (setq current-buffer-p t)
3007 (current-buffer))
3008 (t (get-buffer-create
3009 (if asynchronous
3010 "*Async Shell Command*"
3011 "*Shell Command Output*")))))
3012 (error-buffer
3013 (cond
3014 ((bufferp error-buffer) error-buffer)
3015 ((stringp error-buffer) (get-buffer-create error-buffer))))
3016 (buffer
3017 (if (and (not asynchronous) error-buffer)
3018 (with-parsed-tramp-file-name default-directory nil
3019 (list output-buffer (tramp-make-tramp-temp-file v)))
3020 output-buffer))
3021 (p (get-buffer-process output-buffer)))
3022
3023 ;; Check whether there is another process running. Tramp does not
3024 ;; support 2 (asynchronous) processes in parallel.
3025 (when p
3026 (if (yes-or-no-p "A command is running. Kill it? ")
3027 (ignore-errors (kill-process p))
3028 (error "Shell command in progress")))
3029
3030 (if current-buffer-p
3031 (progn
3032 (barf-if-buffer-read-only)
3033 (push-mark nil t))
3034 (with-current-buffer output-buffer
3035 (setq buffer-read-only nil)
3036 (erase-buffer)))
3037
3038 (if (and (not current-buffer-p) (integerp asynchronous))
3039 (prog1
3040 ;; Run the process.
a7b88dc6 3041 (setq p (apply 'start-file-process "*Async Shell*" buffer args))
f5e29b9b
MA
3042 ;; Display output.
3043 (pop-to-buffer output-buffer)
3044 (setq mode-line-process '(":%s"))
a7b88dc6
MA
3045 (shell-mode)
3046 (set-process-sentinel p 'shell-command-sentinel)
3047 (set-process-filter p 'comint-output-filter))
f5e29b9b
MA
3048
3049 (prog1
3050 ;; Run the process.
3051 (apply 'process-file (car args) nil buffer nil (cdr args))
3052 ;; Insert error messages if they were separated.
3053 (when (listp buffer)
3054 (with-current-buffer error-buffer
3055 (insert-file-contents (cadr buffer)))
3056 (delete-file (cadr buffer)))
3057 (if current-buffer-p
3058 ;; This is like exchange-point-and-mark, but doesn't
3059 ;; activate the mark. It is cleaner to avoid activation,
3060 ;; even though the command loop would deactivate the mark
3061 ;; because we inserted text.
3062 (goto-char (prog1 (mark t)
3063 (set-marker (mark-marker) (point)
3064 (current-buffer))))
3065 ;; There's some output, display it.
3066 (when (with-current-buffer output-buffer (> (point-max) (point-min)))
3067 (if (functionp 'display-message-or-buffer)
3068 (tramp-compat-funcall 'display-message-or-buffer output-buffer)
3069 (pop-to-buffer output-buffer))))))))
3070
4a93e698
MA
3071(defun tramp-handle-substitute-in-file-name (filename)
3072 "Like `substitute-in-file-name' for Tramp files.
3073\"//\" and \"/~\" substitute only in the local filename part.
51aba3f3 3074If the URL Tramp syntax is chosen, \"//\" as method delimiter and \"/~\" at
4a93e698
MA
3075beginning of local filename are not substituted."
3076 ;; First, we must replace environment variables.
3077 (setq filename (tramp-replace-environment-variables filename))
3078 (with-parsed-tramp-file-name filename nil
3079 (if (equal tramp-syntax 'url)
3080 ;; We need to check localname only. The other parts cannot contain
3081 ;; "//" or "/~".
3082 (if (and (> (length localname) 1)
3083 (or (string-match "//" localname)
3084 (string-match "/~" localname 1)))
3085 (tramp-run-real-handler 'substitute-in-file-name (list filename))
3086 (tramp-make-tramp-file-name
3087 (when method (substitute-in-file-name method))
3088 (when user (substitute-in-file-name user))
3089 (when host (substitute-in-file-name host))
3090 (when localname
3091 (tramp-run-real-handler
3092 'substitute-in-file-name (list localname)))))
3093 ;; Ignore in LOCALNAME everything before "//" or "/~".
3094 (when (and (stringp localname) (string-match ".+?/\\(/\\|~\\)" localname))
3095 (setq filename
3096 (concat (file-remote-p filename)
3097 (replace-match "\\1" nil nil localname)))
3098 ;; "/m:h:~" does not work for completion. We use "/m:h:~/".
3099 (when (string-match "~$" filename)
3100 (setq filename (concat filename "/"))))
3101 (tramp-run-real-handler 'substitute-in-file-name (list filename)))))
3102
3103(defun tramp-handle-unhandled-file-name-directory (filename)
3104 "Like `unhandled-file-name-directory' for Tramp files."
3105 ;; With Emacs 23, we could simply return `nil'. But we must keep it
3106 ;; for backward compatibility.
3107 (expand-file-name "~/"))
b88f2d0a 3108
4a93e698 3109;;; Functions for establishing connection:
fb7933a3 3110
ac474af1
KG
3111;; The following functions are actions to be taken when seeing certain
3112;; prompts from the remote host. See the variable
3113;; `tramp-actions-before-shell' for usage of these functions.
3114
00d6fd04 3115(defun tramp-action-login (proc vec)
ac474af1 3116 "Send the login name."
00d6fd04 3117 (when (not (stringp tramp-current-user))
a5509865
MA
3118 (setq tramp-current-user
3119 (with-connection-property vec "login-as"
3120 (save-window-excursion
3121 (let ((enable-recursive-minibuffers t))
3122 (pop-to-buffer (tramp-get-connection-buffer vec))
3123 (read-string (match-string 0)))))))
00d6fd04
MA
3124 (with-current-buffer (tramp-get-connection-buffer vec)
3125 (tramp-message vec 6 "\n%s" (buffer-string)))
a5509865 3126 (tramp-message vec 3 "Sending login name `%s'" tramp-current-user)
4cb0aa75 3127 (tramp-send-string vec (concat tramp-current-user tramp-local-end-of-line)))
00d6fd04
MA
3128
3129(defun tramp-action-password (proc vec)
ac474af1 3130 "Query the user for a password."
70c11b0b
MA
3131 (with-current-buffer (process-buffer proc)
3132 (tramp-check-for-regexp proc tramp-password-prompt-regexp)
bb6aba9c
MA
3133 (tramp-message vec 3 "Sending %s" (match-string 1))
3134 (tramp-enter-password proc)
3135 ;; Hide password prompt.
3136 (narrow-to-region (point-max) (point-max))))
00d6fd04
MA
3137
3138(defun tramp-action-succeed (proc vec)
ac474af1 3139 "Signal success in finding shell prompt."
ac474af1
KG
3140 (throw 'tramp-action 'ok))
3141
00d6fd04 3142(defun tramp-action-permission-denied (proc vec)
ac474af1 3143 "Signal permission denied."
00d6fd04 3144 (kill-process proc)
ac474af1
KG
3145 (throw 'tramp-action 'permission-denied))
3146
00d6fd04 3147(defun tramp-action-yesno (proc vec)
3cdaec13
KG
3148 "Ask the user for confirmation using `yes-or-no-p'.
3149Send \"yes\" to remote process on confirmation, abort otherwise.
3150See also `tramp-action-yn'."
ac474af1 3151 (save-window-excursion
00d6fd04
MA
3152 (let ((enable-recursive-minibuffers t))
3153 (save-match-data (pop-to-buffer (tramp-get-connection-buffer vec)))
3154 (unless (yes-or-no-p (match-string 0))
3155 (kill-process proc)
3156 (throw 'tramp-action 'permission-denied))
3157 (with-current-buffer (tramp-get-connection-buffer vec)
3158 (tramp-message vec 6 "\n%s" (buffer-string)))
4cb0aa75 3159 (tramp-send-string vec (concat "yes" tramp-local-end-of-line)))))
00d6fd04
MA
3160
3161(defun tramp-action-yn (proc vec)
3cdaec13
KG
3162 "Ask the user for confirmation using `y-or-n-p'.
3163Send \"y\" to remote process on confirmation, abort otherwise.
3164See also `tramp-action-yesno'."
3165 (save-window-excursion
00d6fd04
MA
3166 (let ((enable-recursive-minibuffers t))
3167 (save-match-data (pop-to-buffer (tramp-get-connection-buffer vec)))
3168 (unless (y-or-n-p (match-string 0))
3169 (kill-process proc)
3170 (throw 'tramp-action 'permission-denied))
3171 (with-current-buffer (tramp-get-connection-buffer vec)
3172 (tramp-message vec 6 "\n%s" (buffer-string)))
4cb0aa75 3173 (tramp-send-string vec (concat "y" tramp-local-end-of-line)))))
00d6fd04
MA
3174
3175(defun tramp-action-terminal (proc vec)
487f4fb7
KG
3176 "Tell the remote host which terminal type to use.
3177The terminal type can be configured with `tramp-terminal-type'."
00d6fd04 3178 (tramp-message vec 5 "Setting `%s' as terminal type." tramp-terminal-type)
7e780ff1
MA
3179 (with-current-buffer (tramp-get-connection-buffer vec)
3180 (tramp-message vec 6 "\n%s" (buffer-string)))
4cb0aa75 3181 (tramp-send-string vec (concat tramp-terminal-type tramp-local-end-of-line)))
487f4fb7 3182
00d6fd04 3183(defun tramp-action-process-alive (proc vec)
a94d821f 3184 "Check, whether a process has finished."
00d6fd04 3185 (unless (memq (process-status proc) '(run open))
19a87064
MA
3186 (throw 'tramp-action 'process-died)))
3187
00d6fd04 3188(defun tramp-action-out-of-band (proc vec)
a94d821f 3189 "Check, whether an out-of-band copy has finished."
00d6fd04
MA
3190 (cond ((and (memq (process-status proc) '(stop exit))
3191 (zerop (process-exit-status proc)))
3192 (tramp-message vec 3 "Process has finished.")
38c65fca 3193 (throw 'tramp-action 'ok))
00d6fd04
MA
3194 ((or (and (memq (process-status proc) '(stop exit))
3195 (not (zerop (process-exit-status proc))))
3196 (memq (process-status proc) '(signal)))
01917a18
MA
3197 ;; `scp' could have copied correctly, but set modes could have failed.
3198 ;; This can be ignored.
00d6fd04
MA
3199 (with-current-buffer (process-buffer proc)
3200 (goto-char (point-min))
3201 (if (re-search-forward tramp-operation-not-permitted-regexp nil t)
3202 (progn
3203 (tramp-message vec 5 "'set mode' error ignored.")
3204 (tramp-message vec 3 "Process has finished.")
3205 (throw 'tramp-action 'ok))
3206 (tramp-message vec 3 "Process has died.")
3207 (throw 'tramp-action 'process-died))))
38c65fca
KG
3208 (t nil)))
3209
4a93e698 3210;;; Functions for processing the actions:
ac474af1 3211
00d6fd04 3212(defun tramp-process-one-action (proc vec actions)
ac474af1 3213 "Wait for output from the shell and perform one action."
00d6fd04 3214 (let (found todo item pattern action)
e6466697 3215 (while (not found)
00d6fd04
MA
3216 ;; Reread output once all actions have been performed.
3217 ;; Obviously, the output was not complete.
3218 (tramp-accept-process-output proc 1)
e6466697
MA
3219 (setq todo actions)
3220 (while todo
e6466697 3221 (setq item (pop todo))
95d610cb 3222 (setq pattern (format "\\(%s\\)\\'" (symbol-value (nth 0 item))))
e6466697 3223 (setq action (nth 1 item))
00d6fd04
MA
3224 (tramp-message
3225 vec 5 "Looking for regexp \"%s\" from remote shell" pattern)
3226 (when (tramp-check-for-regexp proc pattern)
3227 (tramp-message vec 5 "Call `%s'" (symbol-name action))
3228 (setq found (funcall action proc vec)))))
e6466697
MA
3229 found))
3230
bfd31217
MA
3231(defun tramp-process-actions (proc vec pos actions &optional timeout)
3232 "Perform ACTIONS until success or TIMEOUT.
3233PROC and VEC indicate the remote connection to be used. POS, if
3234set, is the starting point of the region to be deleted in the
3235connection buffer."
9e021389 3236 ;; Preserve message for `progress-reporter'.
6139f995 3237 (tramp-compat-with-temp-message ""
2fb0a219
MA
3238 ;; Enable auth-source and password-cache. We must use
3239 ;; tramp-current-* variables in case we have several hops.
3240 (tramp-set-connection-property
3241 (tramp-dissect-file-name
3242 (tramp-make-tramp-file-name
3243 tramp-current-method tramp-current-user tramp-current-host ""))
3244 "first-password-request" t)
158d5945
MA
3245 (save-restriction
3246 (let (exit)
3247 (while (not exit)
3248 (tramp-message proc 3 "Waiting for prompts from remote shell")
3249 (setq exit
3250 (catch 'tramp-action
3251 (if timeout
3252 (with-timeout (timeout)
3253 (tramp-process-one-action proc vec actions))
3254 (tramp-process-one-action proc vec actions)))))
3255 (with-current-buffer (tramp-get-connection-buffer vec)
3256 (widen)
3257 (tramp-message vec 6 "\n%s" (buffer-string)))
3258 (unless (eq exit 'ok)
3259 (tramp-clear-passwd vec)
3260 (tramp-error-with-buffer
3261 nil vec 'file-error
3262 (cond
3263 ((eq exit 'permission-denied) "Permission denied")
3264 ((eq exit 'process-died) "Process died")
bfd31217
MA
3265 (t "Login failed"))))
3266 (when (numberp pos)
3267 (with-current-buffer (tramp-get-connection-buffer vec)
3268 (let (buffer-read-only) (delete-region pos (point)))))))))
fb7933a3 3269
4a93e698 3270:;; Utility functions:
fb7933a3 3271
00d6fd04 3272(defun tramp-accept-process-output (&optional proc timeout timeout-msecs)
d2a2c17f
MA
3273 "Like `accept-process-output' for Tramp processes.
3274This is needed in order to hide `last-coding-system-used', which is set
3275for process communication also."
00d6fd04
MA
3276 (with-current-buffer (process-buffer proc)
3277 (tramp-message proc 10 "%s %s" proc (process-status proc))
3278 (let (buffer-read-only last-coding-system-used)
3279 ;; Under Windows XP, accept-process-output doesn't return
3280 ;; sometimes. So we add an additional timeout.
3281 (with-timeout ((or timeout 1))
3282 (accept-process-output proc timeout timeout-msecs)))
3283 (tramp-message proc 10 "\n%s" (buffer-string))))
3284
3285(defun tramp-check-for-regexp (proc regexp)
a94d821f 3286 "Check, whether REGEXP is contained in process buffer of PROC.
00d6fd04
MA
3287Erase echoed commands if exists."
3288 (with-current-buffer (process-buffer proc)
3289 (goto-char (point-min))
674da028 3290
00d6fd04
MA
3291 ;; Check whether we need to remove echo output.
3292 (when (and (tramp-get-connection-property proc "check-remote-echo" nil)
3293 (re-search-forward tramp-echoed-echo-mark-regexp nil t))
3294 (let ((begin (match-beginning 0)))
3295 (when (re-search-forward tramp-echoed-echo-mark-regexp nil t)
3296 ;; Discard echo from remote output.
3297 (tramp-set-connection-property proc "check-remote-echo" nil)
3298 (tramp-message proc 5 "echo-mark found")
b533bc97 3299 (forward-line 1)
00d6fd04
MA
3300 (delete-region begin (point))
3301 (goto-char (point-min)))))
674da028 3302
68712eb6
MA
3303 (when (or (not (tramp-get-connection-property proc "check-remote-echo" nil))
3304 ;; Sometimes, the echo string is suppressed on the remote side.
3305 (not (string-equal
0d5852cf
MA
3306 (tramp-compat-funcall
3307 'substring-no-properties tramp-echo-mark-marker
68712eb6 3308 0 (min tramp-echo-mark-marker-length (1- (point-max))))
0d5852cf
MA
3309 (tramp-compat-funcall
3310 'buffer-substring-no-properties
68712eb6 3311 1 (min (1+ tramp-echo-mark-marker-length) (point-max))))))
70c11b0b 3312 ;; No echo to be handled, now we can look for the regexp.
674da028 3313 (goto-char (point-min))
00d6fd04 3314 (re-search-forward regexp nil t))))
d2a2c17f 3315
fb7933a3
KG
3316(defun tramp-wait-for-regexp (proc timeout regexp)
3317 "Wait for a REGEXP to appear from process PROC within TIMEOUT seconds.
3318Expects the output of PROC to be sent to the current buffer. Returns
3319the string that matched, or nil. Waits indefinitely if TIMEOUT is
3320nil."
00d6fd04
MA
3321 (with-current-buffer (process-buffer proc)
3322 (let ((found (tramp-check-for-regexp proc regexp))
3323 (start-time (current-time)))
3324 (cond (timeout
3325 ;; Work around a bug in XEmacs 21, where the timeout
3326 ;; expires faster than it should. This degenerates
3327 ;; to polling for buggy XEmacsen, but oh, well.
3328 (while (and (not found)
3329 (< (tramp-time-diff (current-time) start-time)
3330 timeout))
3331 (with-timeout (timeout)
3332 (while (not found)
3333 (tramp-accept-process-output proc 1)
3334 (unless (memq (process-status proc) '(run open))
3335 (tramp-error-with-buffer
3336 nil proc 'file-error "Process has died"))
3337 (setq found (tramp-check-for-regexp proc regexp))))))
3338 (t
3339 (while (not found)
3340 (tramp-accept-process-output proc 1)
3341 (unless (memq (process-status proc) '(run open))
3342 (tramp-error-with-buffer
3343 nil proc 'file-error "Process has died"))
3344 (setq found (tramp-check-for-regexp proc regexp)))))
3345 (tramp-message proc 6 "\n%s" (buffer-string))
fb7933a3 3346 (when (not found)
00d6fd04
MA
3347 (if timeout
3348 (tramp-error
3349 proc 'file-error "[[Regexp `%s' not found in %d secs]]"
3350 regexp timeout)
3351 (tramp-error proc 'file-error "[[Regexp `%s' not found]]" regexp)))
3352 found)))
fb7933a3 3353
7e780ff1
MA
3354;; We don't call `tramp-send-string' in order to hide the password
3355;; from the debug buffer, and because end-of-line handling of the
3356;; string.
3357(defun tramp-enter-password (proc)
00d6fd04
MA
3358 "Prompt for a password and send it to the remote end."
3359 (process-send-string
7e780ff1
MA
3360 proc (concat (tramp-read-passwd proc)
3361 (or (tramp-get-method-parameter
3362 tramp-current-method
3363 'tramp-password-end-of-line)
3364 tramp-default-password-end-of-line))))
00d6fd04 3365
7432277c
KG
3366;; It seems that Tru64 Unix does not like it if long strings are sent
3367;; to it in one go. (This happens when sending the Perl
3368;; `file-attributes' implementation, for instance.) Therefore, we
27e813fe 3369;; have this function which sends the string in chunks.
00d6fd04
MA
3370(defun tramp-send-string (vec string)
3371 "Send the STRING via connection VEC.
7432277c
KG
3372
3373The STRING is expected to use Unix line-endings, but the lines sent to
3374the remote host use line-endings as defined in the variable
00d6fd04
MA
3375`tramp-rsh-end-of-line'. The communication buffer is erased before sending."
3376 (let* ((p (tramp-get-connection-process vec))
3377 (chunksize (tramp-get-connection-property p "chunksize" nil)))
3378 (unless p
3379 (tramp-error
3380 vec 'file-error "Can't send string to remote host -- not logged in"))
3381 (tramp-set-connection-property p "last-cmd-time" (current-time))
3382 (tramp-message vec 10 "%s" string)
3383 (with-current-buffer (tramp-get-connection-buffer vec)
3384 ;; Clean up the buffer. We cannot call `erase-buffer' because
3385 ;; narrowing might be in effect.
3386 (let (buffer-read-only) (delete-region (point-min) (point-max)))
27e813fe 3387 ;; Replace "\n" by `tramp-rsh-end-of-line'.
00d6fd04
MA
3388 (setq string
3389 (mapconcat 'identity
70c11b0b 3390 (tramp-compat-split-string string "\n")
00d6fd04
MA
3391 tramp-rsh-end-of-line))
3392 (unless (or (string= string "")
3393 (string-equal (substring string -1) tramp-rsh-end-of-line))
3394 (setq string (concat string tramp-rsh-end-of-line)))
27e813fe 3395 ;; Send the string.
00d6fd04
MA
3396 (if (and chunksize (not (zerop chunksize)))
3397 (let ((pos 0)
3398 (end (length string)))
3399 (while (< pos end)
3400 (tramp-message
3401 vec 10 "Sending chunk from %s to %s"
3402 pos (min (+ pos chunksize) end))
3403 (process-send-string
3404 p (substring string pos (min (+ pos chunksize) end)))
3405 (setq pos (+ pos chunksize))))
3406 (process-send-string p string)))))
fb7933a3 3407
ce3f516f 3408(defun tramp-get-inode (vec)
00d6fd04
MA
3409 "Returns the virtual inode number.
3410If it doesn't exist, generate a new one."
ce3f516f
MA
3411 (let ((string (tramp-make-tramp-file-name
3412 (tramp-file-name-method vec)
3413 (tramp-file-name-user vec)
3414 (tramp-file-name-host vec)
3415 "")))
00d6fd04
MA
3416 (unless (assoc string tramp-inodes)
3417 (add-to-list 'tramp-inodes
3418 (list string (length tramp-inodes))))
3419 (nth 1 (assoc string tramp-inodes))))
3420
3421(defun tramp-get-device (vec)
c82c5727
LH
3422 "Returns the virtual device number.
3423If it doesn't exist, generate a new one."
00d6fd04
MA
3424 (let ((string (tramp-make-tramp-file-name
3425 (tramp-file-name-method vec)
3426 (tramp-file-name-user vec)
3427 (tramp-file-name-host vec)
3428 "")))
c82c5727
LH
3429 (unless (assoc string tramp-devices)
3430 (add-to-list 'tramp-devices
3431 (list string (length tramp-devices))))
b946a456 3432 (cons -1 (nth 1 (assoc string tramp-devices)))))
fb7933a3 3433
00d6fd04 3434(defun tramp-equal-remote (file1 file2)
a94d821f 3435 "Check, whether the remote parts of FILE1 and FILE2 are identical.
00d6fd04
MA
3436The check depends on method, user and host name of the files. If
3437one of the components is missing, the default values are used.
3438The local file name parts of FILE1 and FILE2 are not taken into
3439account.
fb7933a3 3440
00d6fd04
MA
3441Example:
3442
3443 (tramp-equal-remote \"/ssh::/etc\" \"/<your host name>:/home\")
3444
3445would yield `t'. On the other hand, the following check results in nil:
3446
3447 (tramp-equal-remote \"/sudo::/etc\" \"/su::/etc\")"
9e6ab520
MA
3448 (and (stringp (file-remote-p file1))
3449 (stringp (file-remote-p file2))
94be87e8 3450 (string-equal (file-remote-p file1) (file-remote-p file2))))
00d6fd04 3451
00d6fd04 3452(defun tramp-get-method-parameter (method param)
c951aecb 3453 "Return the method parameter PARAM.
6a29a838 3454If the `tramp-methods' entry does not exist, return nil."
00d6fd04
MA
3455 (let ((entry (assoc param (assoc method tramp-methods))))
3456 (when entry (cadr entry))))
90f8dc03 3457
4a93e698
MA
3458(defun tramp-mode-string-to-int (mode-string)
3459 "Converts a ten-letter `drwxrwxrwx'-style mode string into mode bits."
3460 (let* (case-fold-search
3461 (mode-chars (string-to-vector mode-string))
3462 (owner-read (aref mode-chars 1))
3463 (owner-write (aref mode-chars 2))
3464 (owner-execute-or-setid (aref mode-chars 3))
3465 (group-read (aref mode-chars 4))
3466 (group-write (aref mode-chars 5))
3467 (group-execute-or-setid (aref mode-chars 6))
3468 (other-read (aref mode-chars 7))
3469 (other-write (aref mode-chars 8))
3470 (other-execute-or-sticky (aref mode-chars 9)))
3471 (save-match-data
3472 (logior
3473 (cond
3474 ((char-equal owner-read ?r) (tramp-compat-octal-to-decimal "00400"))
3475 ((char-equal owner-read ?-) 0)
3476 (t (error "Second char `%c' must be one of `r-'" owner-read)))
3477 (cond
3478 ((char-equal owner-write ?w) (tramp-compat-octal-to-decimal "00200"))
3479 ((char-equal owner-write ?-) 0)
3480 (t (error "Third char `%c' must be one of `w-'" owner-write)))
3481 (cond
3482 ((char-equal owner-execute-or-setid ?x)
3483 (tramp-compat-octal-to-decimal "00100"))
3484 ((char-equal owner-execute-or-setid ?S)
3485 (tramp-compat-octal-to-decimal "04000"))
3486 ((char-equal owner-execute-or-setid ?s)
3487 (tramp-compat-octal-to-decimal "04100"))
3488 ((char-equal owner-execute-or-setid ?-) 0)
3489 (t (error "Fourth char `%c' must be one of `xsS-'"
3490 owner-execute-or-setid)))
3491 (cond
3492 ((char-equal group-read ?r) (tramp-compat-octal-to-decimal "00040"))
3493 ((char-equal group-read ?-) 0)
3494 (t (error "Fifth char `%c' must be one of `r-'" group-read)))
3495 (cond
3496 ((char-equal group-write ?w) (tramp-compat-octal-to-decimal "00020"))
3497 ((char-equal group-write ?-) 0)
3498 (t (error "Sixth char `%c' must be one of `w-'" group-write)))
3499 (cond
3500 ((char-equal group-execute-or-setid ?x)
3501 (tramp-compat-octal-to-decimal "00010"))
3502 ((char-equal group-execute-or-setid ?S)
3503 (tramp-compat-octal-to-decimal "02000"))
3504 ((char-equal group-execute-or-setid ?s)
3505 (tramp-compat-octal-to-decimal "02010"))
3506 ((char-equal group-execute-or-setid ?-) 0)
3507 (t (error "Seventh char `%c' must be one of `xsS-'"
3508 group-execute-or-setid)))
3509 (cond
3510 ((char-equal other-read ?r)
3511 (tramp-compat-octal-to-decimal "00004"))
3512 ((char-equal other-read ?-) 0)
3513 (t (error "Eighth char `%c' must be one of `r-'" other-read)))
3514 (cond
3515 ((char-equal other-write ?w) (tramp-compat-octal-to-decimal "00002"))
3516 ((char-equal other-write ?-) 0)
6196cffe 3517 (t (error "Ninth char `%c' must be one of `w-'" other-write)))
4a93e698
MA
3518 (cond
3519 ((char-equal other-execute-or-sticky ?x)
3520 (tramp-compat-octal-to-decimal "00001"))
3521 ((char-equal other-execute-or-sticky ?T)
3522 (tramp-compat-octal-to-decimal "01000"))
3523 ((char-equal other-execute-or-sticky ?t)
3524 (tramp-compat-octal-to-decimal "01001"))
3525 ((char-equal other-execute-or-sticky ?-) 0)
3526 (t (error "Tenth char `%c' must be one of `xtT-'"
3527 other-execute-or-sticky)))))))
3528
3529(defun tramp-local-host-p (vec)
3530 "Return t if this points to the local host, nil otherwise."
3531 ;; We cannot use `tramp-file-name-real-host'. A port is an
3532 ;; indication for an ssh tunnel or alike.
3533 (let ((host (tramp-file-name-host vec)))
3534 (and
3535 (stringp host)
3536 (string-match tramp-local-host-regexp host)
3537 ;; The method shall be applied to one of the shell file name
3538 ;; handler. `tramp-local-host-p' is also called for "smb" and
3539 ;; alike, where it must fail.
3540 (tramp-get-method-parameter
3541 (tramp-file-name-method vec) 'tramp-login-program)
3542 ;; The local temp directory must be writable for the other user.
3543 (file-writable-p
3544 (tramp-make-tramp-file-name
3545 (tramp-file-name-method vec)
3546 (tramp-file-name-user vec)
3547 host
3548 (tramp-compat-temporary-file-directory)))
3549 ;; On some systems, chown runs only for root.
3550 (or (zerop (user-uid))
3551 ;; This is defined in tramp-sh.el. Let's assume this is
3552 ;; loaded already.
3553 (zerop (tramp-compat-funcall 'tramp-get-remote-uid vec 'integer))))))
3554
710dec63
MA
3555(defun tramp-get-remote-tmpdir (vec)
3556 "Return directory for temporary files on the remote host identified by VEC."
3557 (with-connection-property vec "tmpdir"
3558 (let ((dir (tramp-make-tramp-file-name
3559 (tramp-file-name-method vec)
3560 (tramp-file-name-user vec)
3561 (tramp-file-name-host vec)
3562 (or
3563 (tramp-get-method-parameter
3564 (tramp-file-name-method vec) 'tramp-tmpdir)
3565 "/tmp"))))
3566 (if (and (file-directory-p dir) (file-writable-p dir))
3567 dir
3568 (tramp-error vec 'file-error "Directory %s not accessible" dir)))))
3569
4a93e698
MA
3570(defun tramp-make-tramp-temp-file (vec)
3571 "Create a temporary file on the remote host identified by VEC.
3572Return the local name of the temporary file."
710dec63
MA
3573 (let ((prefix (expand-file-name
3574 tramp-temp-name-prefix (tramp-get-remote-tmpdir vec)))
4a93e698
MA
3575 result)
3576 (while (not result)
3577 ;; `make-temp-file' would be the natural choice for
3578 ;; implementation. But it calls `write-region' internally,
3579 ;; which also needs a temporary file - we would end in an
3580 ;; infinite loop.
3581 (setq result (make-temp-name prefix))
3582 (if (file-exists-p result)
3583 (setq result nil)
3584 ;; This creates the file by side effect.
3585 (set-file-times result)
3586 (set-file-modes result (tramp-compat-octal-to-decimal "0700"))))
3587
3588 ;; Return the local part.
3589 (with-parsed-tramp-file-name result nil localname)))
fb7933a3 3590
4a93e698
MA
3591(defun tramp-delete-temp-file-function ()
3592 "Remove temporary files related to current buffer."
3593 (when (stringp tramp-temp-buffer-file-name)
3594 (ignore-errors (delete-file tramp-temp-buffer-file-name))))
3595
3596(add-hook 'kill-buffer-hook 'tramp-delete-temp-file-function)
f5e29b9b 3597(add-hook 'tramp-unload-hook
4a93e698
MA
3598 (lambda ()
3599 (remove-hook 'kill-buffer-hook
3600 'tramp-delete-temp-file-function)))
3601
3602;;; Auto saving to a special directory:
c1105d05
MA
3603
3604(unless (tramp-exists-file-name-handler 'make-auto-save-file-name)
3605 (defadvice make-auto-save-file-name
3606 (around tramp-advice-make-auto-save-file-name () activate)
03c1ad43 3607 "Invoke `tramp-*-handle-make-auto-save-file-name' for Tramp files."
b533bc97 3608 (if (tramp-tramp-file-p (buffer-file-name))
7f49fe46
MA
3609 ;; We cannot call `tramp-handle-make-auto-save-file-name'
3610 ;; directly, because this would bypass the locking mechanism.
3611 (setq ad-return-value
3612 (tramp-file-name-handler 'make-auto-save-file-name))
a69c01a0 3613 ad-do-it))
191bb792
MA
3614 (add-hook
3615 'tramp-unload-hook
3616 (lambda ()
3617 (ad-remove-advice
3618 'make-auto-save-file-name
d7ec1df7
MA
3619 'around 'tramp-advice-make-auto-save-file-name)
3620 (ad-activate 'make-auto-save-file-name))))
fb7933a3 3621
b533bc97
MA
3622;; In XEmacs < 21.5, autosaved remote files have permission 0666 minus
3623;; umask. This is a security threat.
414da5ab
MA
3624
3625(defun tramp-set-auto-save-file-modes ()
3626 "Set permissions of autosaved remote files to the original permissions."
3627 (let ((bfn (buffer-file-name)))
b533bc97 3628 (when (and (tramp-tramp-file-p bfn)
b50dd0d2 3629 (buffer-modified-p)
414da5ab 3630 (stringp buffer-auto-save-file-name)
340b8d4f
MA
3631 (not (equal bfn buffer-auto-save-file-name)))
3632 (unless (file-exists-p buffer-auto-save-file-name)
3633 (write-region "" nil buffer-auto-save-file-name))
3634 ;; Permissions should be set always, because there might be an old
3635 ;; auto-saved file belonging to another original file. This could
3636 ;; be a security threat.
0f34aa77
MA
3637 (set-file-modes
3638 buffer-auto-save-file-name
3639 (or (file-modes bfn) (tramp-compat-octal-to-decimal "0600"))))))
414da5ab 3640
b533bc97
MA
3641(unless (and (featurep 'xemacs)
3642 (= emacs-major-version 21)
3643 (> emacs-minor-version 4))
a69c01a0
MA
3644 (add-hook 'auto-save-hook 'tramp-set-auto-save-file-modes)
3645 (add-hook 'tramp-unload-hook
aa485f7c
MA
3646 (lambda ()
3647 (remove-hook 'auto-save-hook 'tramp-set-auto-save-file-modes))))
414da5ab 3648
fb7933a3
KG
3649(defun tramp-subst-strs-in-string (alist string)
3650 "Replace all occurrences of the string FROM with TO in STRING.
3651ALIST is of the form ((FROM . TO) ...)."
3652 (save-match-data
3653 (while alist
3654 (let* ((pr (car alist))
3655 (from (car pr))
3656 (to (cdr pr)))
3657 (while (string-match (regexp-quote from) string)
3658 (setq string (replace-match to t t string)))
3659 (setq alist (cdr alist))))
3660 string))
3661
4a93e698 3662;;; Compatibility functions section:
fb7933a3 3663
00d6fd04 3664(defun tramp-read-passwd (proc &optional prompt)
fb7933a3 3665 "Read a password from user (compat function).
5615d63f 3666Consults the auth-source package.
5ec2cc41 3667Invokes `password-read' if available, `read-passwd' else."
00d6fd04
MA
3668 (let* ((key (tramp-make-tramp-file-name
3669 tramp-current-method tramp-current-user
3670 tramp-current-host ""))
3671 (pw-prompt
3672 (or prompt
3673 (with-current-buffer (process-buffer proc)
3674 (tramp-check-for-regexp proc tramp-password-prompt-regexp)
563790b6
TZ
3675 (format "%s for %s " (capitalize (match-string 1)) key))))
3676 auth-info auth-passwd)
7540f029
MA
3677 (with-parsed-tramp-file-name key nil
3678 (prog1
3679 (or
7a6ebb1a
MA
3680 ;; See if auth-sources contains something useful, if it's
3681 ;; bound. `auth-source-user-or-password' is an obsoleted
3682 ;; function, it has been replaced by `auth-source-search'.
7540f029
MA
3683 (and (boundp 'auth-sources)
3684 (tramp-get-connection-property v "first-password-request" nil)
3685 ;; Try with Tramp's current method.
563790b6 3686 (if (fboundp 'auth-source-search)
7a6ebb1a 3687 (setq auth-info
2fb0a219
MA
3688 (tramp-compat-funcall
3689 'auth-source-search
3690 :max 1
3691 :user (or tramp-current-user t)
3692 :host tramp-current-host
3693 :port tramp-current-method)
3694 auth-passwd (plist-get (nth 0 auth-info) :secret)
3695 auth-passwd (if (functionp auth-passwd)
3696 (funcall auth-passwd)
3697 auth-passwd))
563790b6
TZ
3698 (tramp-compat-funcall
3699 'auth-source-user-or-password
3700 "password" tramp-current-host tramp-current-method)))
7540f029
MA
3701 ;; Try the password cache.
3702 (when (functionp 'password-read)
3703 (unless (tramp-get-connection-property
3704 v "first-password-request" nil)
0d5852cf 3705 (tramp-compat-funcall 'password-cache-remove key))
7540f029 3706 (let ((password
0d5852cf
MA
3707 (tramp-compat-funcall 'password-read pw-prompt key)))
3708 (tramp-compat-funcall 'password-cache-add key password)
7540f029
MA
3709 password))
3710 ;; Else, get the password interactively.
3711 (read-passwd pw-prompt))
3712 (tramp-set-connection-property v "first-password-request" nil)))))
00d6fd04 3713
9c13938d
MA
3714(defun tramp-clear-passwd (vec)
3715 "Clear password cache for connection related to VEC."
0d5852cf
MA
3716 (tramp-compat-funcall
3717 'password-cache-remove
3718 (tramp-make-tramp-file-name
3719 (tramp-file-name-method vec)
3720 (tramp-file-name-user vec)
3721 (tramp-file-name-host vec)
3722 "")))
00d6fd04
MA
3723
3724;; Snarfed code from time-date.el and parse-time.el
3725
3726(defconst tramp-half-a-year '(241 17024)
3727"Evaluated by \"(days-to-time 183)\".")
3728
3729(defconst tramp-parse-time-months
3730 '(("jan" . 1) ("feb" . 2) ("mar" . 3)
3731 ("apr" . 4) ("may" . 5) ("jun" . 6)
3732 ("jul" . 7) ("aug" . 8) ("sep" . 9)
3733 ("oct" . 10) ("nov" . 11) ("dec" . 12))
3734 "Alist mapping month names to integers.")
3735
3736(defun tramp-time-less-p (t1 t2)
3737 "Say whether time value T1 is less than time value T2."
3738 (unless t1 (setq t1 '(0 0)))
3739 (unless t2 (setq t2 '(0 0)))
3740 (or (< (car t1) (car t2))
3741 (and (= (car t1) (car t2))
3742 (< (nth 1 t1) (nth 1 t2)))))
3743
3744(defun tramp-time-subtract (t1 t2)
3745 "Subtract two time values.
3746Return the difference in the format of a time value."
3747 (unless t1 (setq t1 '(0 0)))
3748 (unless t2 (setq t2 '(0 0)))
3749 (let ((borrow (< (cadr t1) (cadr t2))))
3750 (list (- (car t1) (car t2) (if borrow 1 0))
3751 (- (+ (if borrow 65536 0) (cadr t1)) (cadr t2)))))
fb7933a3
KG
3752
3753(defun tramp-time-diff (t1 t2)
3754 "Return the difference between the two times, in seconds.
1a762140 3755T1 and T2 are time values (as returned by `current-time' for example)."
ea9d1443
KG
3756 (cond ((and (fboundp 'subtract-time)
3757 (fboundp 'float-time))
0d5852cf
MA
3758 (tramp-compat-funcall
3759 'float-time (tramp-compat-funcall 'subtract-time t1 t2)))
ea9d1443
KG
3760 ((and (fboundp 'subtract-time)
3761 (fboundp 'time-to-seconds))
0d5852cf
MA
3762 (tramp-compat-funcall
3763 'time-to-seconds (tramp-compat-funcall 'subtract-time t1 t2)))
fb7933a3 3764 ((fboundp 'itimer-time-difference)
0d5852cf
MA
3765 (tramp-compat-funcall
3766 'itimer-time-difference
3767 (if (< (length t1) 3) (append t1 '(0)) t1)
3768 (if (< (length t2) 3) (append t2 '(0)) t2)))
fb7933a3 3769 (t
00d6fd04 3770 (let ((time (tramp-time-subtract t1 t2)))
ea9d1443
KG
3771 (+ (* (car time) 65536.0)
3772 (cadr time)
3773 (/ (or (nth 2 time) 0) 1000000.0))))))
fb7933a3 3774
fb7933a3
KG
3775;; Currently (as of Emacs 20.5), the function `shell-quote-argument'
3776;; does not deal well with newline characters. Newline is replaced by
3777;; backslash newline. But if, say, the string `a backslash newline b'
3778;; is passed to a shell, the shell will expand this into "ab",
3779;; completely omitting the newline. This is not what was intended.
3780;; It does not appear to be possible to make the function
3781;; `shell-quote-argument' work with newlines without making it
3782;; dependent on the shell used. But within this package, we know that
3783;; we will always use a Bourne-like shell, so we use an approach which
3784;; groks newlines.
3785;;
3786;; The approach is simple: we call `shell-quote-argument', then
3787;; massage the newline part of the result.
3788;;
3789;; This function should produce a string which is grokked by a Unix
3790;; shell, even if the Emacs is running on Windows. Since this is the
3791;; kludges section, we bind `system-type' in such a way that
3792;; `shell-quote-arguments' behaves as if on Unix.
3793;;
3794;; Thanks to Mario DeWeerd for the hint that it is sufficient for this
3795;; function to work with Bourne-like shells.
3796;;
3797;; CCC: This function should be rewritten so that
3798;; `shell-quote-argument' is not used. This way, we are safe from
3799;; changes in `shell-quote-argument'.
0f34aa77 3800;;;###tramp-autoload
fb7933a3
KG
3801(defun tramp-shell-quote-argument (s)
3802 "Similar to `shell-quote-argument', but groks newlines.
3803Only works for Bourne-like shells."
3804 (let ((system-type 'not-windows))
3805 (save-match-data
3806 (let ((result (shell-quote-argument s))
3807 (nl (regexp-quote (format "\\%s" tramp-rsh-end-of-line))))
3808 (when (and (>= (length result) 2)
3809 (string= (substring result 0 2) "\\~"))
3810 (setq result (substring result 1)))
3811 (while (string-match nl result)
3812 (setq result (replace-match (format "'%s'" tramp-rsh-end-of-line)
3813 t t result)))
3814 result))))
3815
a69c01a0
MA
3816;; Checklist for `tramp-unload-hook'
3817;; - Unload all `tramp-*' packages
3818;; - Reset `file-name-handler-alist'
3819;; - Cleanup hooks where Tramp functions are in
3820;; - Cleanup advised functions
3821;; - Cleanup autoloads
3822;;;###autoload
3823(defun tramp-unload-tramp ()
08b1eb21 3824 "Discard Tramp from loading remote files."
a69c01a0 3825 (interactive)
a69c01a0 3826 ;; ange-ftp settings must be enabled.
0d5852cf 3827 (tramp-compat-funcall 'tramp-ftp-enable-ange-ftp)
0f34aa77 3828 ;; Maybe it's not loaded yet.
03c1ad43 3829 (ignore-errors (unload-feature 'tramp 'force)))
ccb4a481 3830
fb7933a3
KG
3831(provide 'tramp)
3832
fb7933a3
KG
3833;;; TODO:
3834
fb7933a3 3835;; * Rewrite `tramp-shell-quote-argument' to abstain from using
b1d06e75 3836;; `shell-quote-argument'.
fb7933a3
KG
3837;; * In Emacs 21, `insert-directory' shows total number of bytes used
3838;; by the files in that directory. Add this here.
3839;; * Avoid screen blanking when hitting `g' in dired. (Eli Tziperman)
3840;; * Make ffap.el grok Tramp filenames. (Eli Tziperman)
fb7933a3 3841;; * abbreviate-file-name
8e754ea2 3842;; * Better error checking. At least whenever we see something
fb7933a3
KG
3843;; strange when doing zerop, we should kill the process and start
3844;; again. (Greg Stark)
3cdaec13 3845;; * Username and hostname completion.
6c4e47fa 3846;; ** Try to avoid usage of `last-input-event' in `tramp-completion-mode-p'.
8daea7fc 3847;; ** Unify `tramp-parse-{rhosts,shosts,sconfig,hosts,passwd,netrc}'.
16674e4f 3848;; Code is nearly identical.
00d6fd04 3849;; * Make `tramp-default-user' obsolete.
3e2fa353
MA
3850;; * Implement a general server-local-variable mechanism, as there are
3851;; probably other variables that need different values for different
3852;; servers too. The user could then configure a variable (such as
3853;; tramp-server-local-variable-alist) to define any such variables
3854;; that they need to, which would then be let bound as appropriate
6e4f5731 3855;; in tramp functions. (Jason Rumney)
7e5686f0
MA
3856;; * IMHO, it's a drawback that currently Tramp doesn't support
3857;; Unicode in Dired file names by default. Is it possible to
3858;; improve Tramp to set LC_ALL to "C" only for commands where Tramp
3859;; expects English? Or just to set LC_MESSAGES to "C" if Tramp
6e4f5731 3860;; expects only English messages? (Juri Linkov)
7e5686f0 3861;; * Make shadowfile.el grok Tramp filenames. (Bug#4526, Bug#4846)
58179cce 3862;; * I was wondering if it would be possible to use tramp even if I'm
44ffae96
MA
3863;; actually using sshfs. But when I launch a command I would like
3864;; to get it executed on the remote machine where the files really
3865;; are. (Andrea Crotti)
3866;; * Run emerge on two remote files. Bug is described here:
3867;; <http://www.mail-archive.com/tramp-devel@nongnu.org/msg01041.html>.
3868;; (Bug#6850)
56f2d1e1
MA
3869;; * It would be very useful if it were possible to load or save a
3870;; buffer using Tramp in a non-blocking way so that use of Emacs on
3871;; other buffers could continue. (Bug#9617)
fb7933a3
KG
3872
3873;;; tramp.el ends here
57671b72
MA
3874
3875;; Local Variables:
3876;; mode: Emacs-Lisp
3877;; coding: utf-8
3878;; End: