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