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