(thing-at-point-uri-schemes): New variable.
[bpt/emacs.git] / lisp / net / tramp.el
CommitLineData
dba28077 1;;; tramp.el --- Transparent Remote Access, Multiple Protocol -*- coding: iso-8859-1; -*-
fb7933a3
KG
2
3;; Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
4
5;; Author: Kai.Grossjohann@CS.Uni-Dortmund.DE
6;; Keywords: comm, processes
7
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation; either version 2, or (at your option)
13;; any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs; see the file COPYING. If not, write to the
22;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23;; Boston, MA 02111-1307, USA.
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;;
32;; For more detailed instructions, please see the info file, which is
33;; included in the file `tramp.tar.gz' mentioned below.
34;;
35;; Notes:
36;; -----
37;;
38;; This package only works for Emacs 20 and higher, and for XEmacs 21
39;; and higher. (XEmacs 20 is missing the `with-timeout' macro. Emacs
40;; 19 is reported to have other problems. For XEmacs 21, you need the
41;; package `fsf-compat' for the `with-timeout' macro.)
42;;
43;; This version might not work with pre-Emacs 21 VC unless VC is
44;; loaded before tramp.el. Could you please test this and tell me about
45;; the result? Thanks.
46;;
47;; Also see the todo list at the bottom of this file.
48;;
49;; The current version of tramp.el can be retrieved from the following
50;; URL: ftp://ls6-ftp.cs.uni-dortmund.de/pub/src/emacs/tramp.tar.gz
51;; For your convenience, the *.el file is available separately from
52;; the same directory.
53;;
54;; There's a mailing list for this, as well. Its name is:
c62c9d08 55;; tramp-devel@mail.freesoftware.fsf.org
fb7933a3
KG
56;; Send a mail with `help' in the subject (!) to the administration
57;; address for instructions on joining the list. The administration
58;; address is:
c62c9d08 59;; tramp-devel-request@mail.freesoftware.fsf.org
fb7933a3 60;; You can also use the Web to subscribe, under the following URL:
c62c9d08 61;; http://mail.freesoftware.fsf.org/mailman/listinfo/tramp-devel
fb7933a3
KG
62;;
63;; For the adventurous, the current development sources are available
64;; via CVS. You can find instructions about this at the following URL:
c62c9d08 65;; http://savannah.gnu.org/projects/tramp/
fb7933a3
KG
66;; Click on "CVS" in the navigation bar near the top.
67;;
68;; Don't forget to put on your asbestos longjohns, first!
69
70;;; Code:
71
b1d06e75
KG
72;; In the Tramp CVS repository, the version numer is auto-frobbed from
73;; the Makefile, so you should edit the top-level Makefile to change
74;; the version number.
3b89d388 75(defconst tramp-version "2.0.24"
fb7933a3 76 "This version of tramp.")
ac474af1 77
fb7933a3
KG
78(defconst tramp-bug-report-address "tramp-devel@mail.freesoftware.fsf.org"
79 "Email address to send bug reports to.")
80
81(require 'timer)
82(require 'format-spec) ;from Gnus 5.8, also in tar ball
dba28077
KG
83;; The explicit check is not necessary in Emacs, which provides the
84;; feature even if implemented in C, but it appears to be necessary
85;; in XEmacs.
86(unless (and (fboundp 'base64-encode-region)
87 (fboundp 'base64-decode-region))
88 (require 'base64)) ;for the mimencode methods
fb7933a3
KG
89(require 'shell)
90(require 'advice)
91
16674e4f
KG
92(autoload 'tramp-uuencode-region "tramp-uu"
93 "Implementation of `uuencode' in Lisp.")
94
95(unless (fboundp 'uudecode-decode-region)
96 (autoload 'uudecode-decode-region "uudecode"))
97
fb7933a3
KG
98;; ;; It does not work to load EFS after loading TRAMP.
99;; (when (fboundp 'efs-file-handler-function)
100;; (require 'efs))
101
102(eval-when-compile
103 (require 'cl)
104 (require 'custom)
105 ;; Emacs 19.34 compatibility hack -- is this needed?
106 (or (>= emacs-major-version 20)
107 (load "cl-seq")))
108
109(unless (boundp 'custom-print-functions)
110 (defvar custom-print-functions nil)) ; not autoloaded before Emacs 20.4
111
16674e4f
KG
112;; XEmacs is distributed with few Lisp packages. Further packages are
113;; installed using EFS. If we use a unified filename format, then
114;; Tramp is required in addition to EFS. (But why can't Tramp just
115;; disable EFS when Tramp is loaded? Then XEmacs can ship with EFS
116;; just like before.) Another reason for using a separate filename
117;; syntax on XEmacs is that EFS hooks into XEmacs in many places, but
118;; Tramp only knows how to deal with `file-name-handler-alist', not
119;; the other places.
94deafda 120;;;###autoload
16674e4f
KG
121(defvar tramp-unified-filenames (not (featurep 'xemacs))
122 "Non-nil means to use unified Ange-FTP/Tramp filename syntax.
123Nil means to use a separate filename syntax for Tramp.")
124
fb7933a3
KG
125;;; User Customizable Internal Variables:
126
127(defgroup tramp nil
128 "Edit remote files with a combination of rsh and rcp or similar programs."
129 :group 'files)
130
821e6e36 131(defcustom tramp-verbose 9
fb7933a3
KG
132 "*Verbosity level for tramp.el. 0 means be silent, 10 is most verbose."
133 :group 'tramp
134 :type 'integer)
135
136(defcustom tramp-debug-buffer nil
137 "*Whether to send all commands and responses to a debug buffer."
138 :group 'tramp
139 :type 'boolean)
140
141(defcustom tramp-auto-save-directory nil
142 "*Put auto-save files in this directory, if set.
143The idea is to use a local directory so that auto-saving is faster."
144 :group 'tramp
145 :type '(choice (const nil)
146 string))
147
16674e4f
KG
148(defcustom tramp-encoding-shell
149 (if (memq system-type '(windows-nt))
150 (getenv "COMSPEC")
151 "/bin/sh")
152 "*Use this program for encoding and decoding commands on the local host.
153This shell is used to execute the encoding and decoding command on the
154local host, so if you want to use `~' in those commands, you should
155choose a shell here which groks tilde expansion. `/bin/sh' normally
156does not understand tilde expansion.
157
158For encoding and deocding, commands like the following are executed:
159
160 /bin/sh -c COMMAND < INPUT > OUTPUT
161
162This variable can be used to change the \"/bin/sh\" part. See the
163variable `tramp-encoding-command-switch' for the \"-c\" part. Also, see the
164variable `tramp-encoding-reads-stdin' to specify whether the commands read
165standard input or a file.
fb7933a3
KG
166
167Note that this variable is not used for remote commands. There are
168mechanisms in tramp.el which automatically determine the right shell to
169use for the remote host."
170 :group 'tramp
171 :type '(file :must-match t))
172
16674e4f
KG
173(defcustom tramp-encoding-command-switch
174 (if (string-match "cmd\\.exe" tramp-encoding-shell)
175 "/c"
176 "-c")
177 "*Use this switch together with `tramp-encoding-shell' for local commands.
178See the variable `tramp-encoding-shell' for more information."
179 :group 'tramp
180 :type 'string)
181
182(defcustom tramp-encoding-reads-stdin t
183 "*If non-nil, encoding commands read from standard input.
184If nil, the filename is the last argument.
185
186Note that the commands always must write to standard output."
187 :group 'tramp
188 :type 'boolean)
189
90dc758d 190(defcustom tramp-multi-sh-program
16674e4f 191 tramp-encoding-shell
90dc758d 192 "*Use this program for bootstrapping multi-hop connections.
16674e4f 193This variable is similar to `tramp-encoding-shell', but it is only used
90dc758d
KG
194when initializing a multi-hop connection. Therefore, the set of
195commands sent to this shell is quite restricted, and if you are
196careful it works to use CMD.EXE under Windows (instead of a Bourne-ish
197shell which does not normally exist on Windows anyway).
198
199To use multi-hop methods from Windows, you also need suitable entries
200in `tramp-multi-connection-function-alist' for the first hop.
201
16674e4f 202This variable defaults to the value of `tramp-encoding-shell'."
90dc758d
KG
203 :group 'tramp
204 :type '(file :must-match t))
205
fb7933a3
KG
206;; CCC I have changed all occurrences of comint-quote-filename with
207;; tramp-shell-quote-argument, except in tramp-handle-expand-many-files.
208;; There, comint-quote-filename was removed altogether. If it turns
209;; out to be necessary there, something will need to be done.
210;;-(defcustom tramp-file-name-quote-list
211;;- '(?] ?[ ?\| ?& ?< ?> ?\( ?\) ?\; ?\ ?\* ?\? ?\! ?\" ?\' ?\` ?# ?\@ ?\+ )
212;;- "*Protect these characters from the remote shell.
213;;-Any character in this list is quoted (preceded with a backslash)
214;;-because it means something special to the shell. This takes effect
215;;-when sending file and directory names to the remote shell.
216;;-
217;;-See `comint-file-name-quote-list' for details."
218;;- :group 'tramp
219;;- :type '(repeat character))
220
221(defcustom tramp-methods
222 '( ("rcp" (tramp-connection-function tramp-open-connection-rsh)
223 (tramp-rsh-program "rsh")
224 (tramp-rcp-program "rcp")
225 (tramp-remote-sh "/bin/sh")
226 (tramp-rsh-args nil)
227 (tramp-rcp-args nil)
228 (tramp-rcp-keep-date-arg "-p")
229 (tramp-su-program nil)
230 (tramp-su-args nil)
fb7933a3
KG
231 (tramp-telnet-program nil)
232 (tramp-telnet-args nil))
233 ("scp" (tramp-connection-function tramp-open-connection-rsh)
234 (tramp-rsh-program "ssh")
235 (tramp-rcp-program "scp")
236 (tramp-remote-sh "/bin/sh")
237 (tramp-rsh-args ("-e" "none"))
238 (tramp-rcp-args nil)
239 (tramp-rcp-keep-date-arg "-p")
240 (tramp-su-program nil)
241 (tramp-su-args nil)
fb7933a3
KG
242 (tramp-telnet-program nil)
243 (tramp-telnet-args nil))
244 ("scp1" (tramp-connection-function tramp-open-connection-rsh)
90dc758d
KG
245 (tramp-rsh-program "ssh")
246 (tramp-rcp-program "scp")
247 (tramp-remote-sh "/bin/sh")
248 (tramp-rsh-args ("-1" "-e" "none"))
249 (tramp-rcp-args ("-1"))
250 (tramp-rcp-keep-date-arg "-p")
251 (tramp-su-program nil)
252 (tramp-su-args nil)
90dc758d
KG
253 (tramp-telnet-program nil)
254 (tramp-telnet-args nil))
255 ("scp2" (tramp-connection-function tramp-open-connection-rsh)
256 (tramp-rsh-program "ssh")
257 (tramp-rcp-program "scp")
258 (tramp-remote-sh "/bin/sh")
259 (tramp-rsh-args ("-2" "-e" "none"))
260 (tramp-rcp-args ("-2"))
261 (tramp-rcp-keep-date-arg "-p")
262 (tramp-su-program nil)
263 (tramp-su-args nil)
90dc758d
KG
264 (tramp-telnet-program nil)
265 (tramp-telnet-args nil))
3b89d388 266 ("scp1_old"
ac474af1 267 (tramp-connection-function tramp-open-connection-rsh)
fb7933a3
KG
268 (tramp-rsh-program "ssh1")
269 (tramp-rcp-program "scp1")
270 (tramp-remote-sh "/bin/sh")
271 (tramp-rsh-args ("-e" "none"))
272 (tramp-rcp-args nil)
273 (tramp-rcp-keep-date-arg "-p")
274 (tramp-su-program nil)
275 (tramp-su-args nil)
fb7933a3
KG
276 (tramp-telnet-program nil)
277 (tramp-telnet-args nil))
3b89d388 278 ("scp2_old"
ac474af1 279 (tramp-connection-function tramp-open-connection-rsh)
fb7933a3
KG
280 (tramp-rsh-program "ssh2")
281 (tramp-rcp-program "scp2")
282 (tramp-remote-sh "/bin/sh")
283 (tramp-rsh-args ("-e" "none"))
284 (tramp-rcp-args nil)
285 (tramp-rcp-keep-date-arg "-p")
286 (tramp-su-program nil)
287 (tramp-su-args nil)
fb7933a3
KG
288 (tramp-telnet-program nil)
289 (tramp-telnet-args nil))
290 ("rsync" (tramp-connection-function tramp-open-connection-rsh)
291 (tramp-rsh-program "ssh")
292 (tramp-rcp-program "rsync")
293 (tramp-remote-sh "/bin/sh")
294 (tramp-rsh-args ("-e" "none"))
295 (tramp-rcp-args ("-e" "ssh"))
296 (tramp-rcp-keep-date-arg "-t")
297 (tramp-su-program nil)
298 (tramp-su-args nil)
fb7933a3
KG
299 (tramp-telnet-program nil)
300 (tramp-telnet-args nil))
ac474af1 301 ("rsh" (tramp-connection-function tramp-open-connection-rsh)
fb7933a3
KG
302 (tramp-rsh-program "rsh")
303 (tramp-rcp-program nil)
304 (tramp-remote-sh "/bin/sh")
305 (tramp-rsh-args nil)
306 (tramp-rcp-args nil)
307 (tramp-rcp-keep-date-arg nil)
308 (tramp-su-program nil)
309 (tramp-su-args nil)
fb7933a3
KG
310 (tramp-telnet-program nil)
311 (tramp-telnet-args nil))
ac474af1 312 ("ssh" (tramp-connection-function tramp-open-connection-rsh)
fb7933a3
KG
313 (tramp-rsh-program "ssh")
314 (tramp-rcp-program nil)
315 (tramp-remote-sh "/bin/sh")
316 (tramp-rsh-args ("-e" "none"))
317 (tramp-rcp-args nil)
318 (tramp-rcp-keep-date-arg nil)
319 (tramp-su-program nil)
320 (tramp-su-args nil)
fb7933a3
KG
321 (tramp-telnet-program nil)
322 (tramp-telnet-args nil))
ac474af1 323 ("ssh1" (tramp-connection-function tramp-open-connection-rsh)
90dc758d
KG
324 (tramp-rsh-program "ssh")
325 (tramp-rcp-program nil)
326 (tramp-remote-sh "/bin/sh")
327 (tramp-rsh-args ("-1" "-e" "none"))
328 (tramp-rcp-args ("-1"))
329 (tramp-rcp-keep-date-arg nil)
330 (tramp-su-program nil)
331 (tramp-su-args nil)
90dc758d
KG
332 (tramp-telnet-program nil)
333 (tramp-telnet-args nil))
ac474af1 334 ("ssh2" (tramp-connection-function tramp-open-connection-rsh)
90dc758d
KG
335 (tramp-rsh-program "ssh")
336 (tramp-rcp-program nil)
337 (tramp-remote-sh "/bin/sh")
338 (tramp-rsh-args ("-2" "-e" "none"))
339 (tramp-rcp-args ("-2"))
340 (tramp-rcp-keep-date-arg nil)
341 (tramp-su-program nil)
342 (tramp-su-args nil)
90dc758d
KG
343 (tramp-telnet-program nil)
344 (tramp-telnet-args nil))
3b89d388 345 ("ssh1_old"
ac474af1 346 (tramp-connection-function tramp-open-connection-rsh)
fb7933a3
KG
347 (tramp-rsh-program "ssh1")
348 (tramp-rcp-program nil)
349 (tramp-remote-sh "/bin/sh")
350 (tramp-rsh-args ("-e" "none"))
351 (tramp-rcp-args nil)
352 (tramp-rcp-keep-date-arg nil)
353 (tramp-su-program nil)
354 (tramp-su-args nil)
fb7933a3
KG
355 (tramp-telnet-program nil)
356 (tramp-telnet-args nil))
3b89d388 357 ("ssh2_old"
ac474af1 358 (tramp-connection-function tramp-open-connection-rsh)
fb7933a3
KG
359 (tramp-rsh-program "ssh2")
360 (tramp-rcp-program nil)
361 (tramp-remote-sh "/bin/sh")
362 (tramp-rsh-args ("-e" "none"))
363 (tramp-rcp-args nil)
364 (tramp-rcp-keep-date-arg nil)
365 (tramp-su-program nil)
366 (tramp-su-args nil)
90dc758d
KG
367 (tramp-telnet-program nil)
368 (tramp-telnet-args nil))
ac474af1
KG
369 ("telnet"
370 (tramp-connection-function tramp-open-connection-telnet)
fb7933a3
KG
371 (tramp-rsh-program nil)
372 (tramp-rcp-program nil)
373 (tramp-remote-sh "/bin/sh")
374 (tramp-rsh-args nil)
375 (tramp-rcp-args nil)
376 (tramp-rcp-keep-date-arg nil)
377 (tramp-su-program nil)
378 (tramp-su-args nil)
fb7933a3
KG
379 (tramp-telnet-program "telnet")
380 (tramp-telnet-args nil))
ac474af1 381 ("su" (tramp-connection-function tramp-open-connection-su)
fb7933a3
KG
382 (tramp-rsh-program nil)
383 (tramp-rcp-program nil)
384 (tramp-remote-sh "/bin/sh")
385 (tramp-rsh-args nil)
386 (tramp-rcp-args nil)
387 (tramp-rcp-keep-date-arg nil)
388 (tramp-su-program "su")
389 (tramp-su-args ("-" "%u"))
fb7933a3
KG
390 (tramp-telnet-program nil)
391 (tramp-telnet-args nil))
ac474af1 392 ("sudo" (tramp-connection-function tramp-open-connection-su)
fb7933a3
KG
393 (tramp-rsh-program nil)
394 (tramp-rcp-program nil)
395 (tramp-remote-sh "/bin/sh")
396 (tramp-rsh-args nil)
397 (tramp-rcp-args nil)
398 (tramp-rcp-keep-date-arg nil)
399 (tramp-su-program "sudo")
400 (tramp-su-args ("-u" "%u" "-s"))
fb7933a3
KG
401 (tramp-telnet-program nil)
402 (tramp-telnet-args nil))
403 ("multi" (tramp-connection-function tramp-open-connection-multi)
404 (tramp-rsh-program nil)
405 (tramp-rcp-program nil)
406 (tramp-remote-sh "/bin/sh")
407 (tramp-rsh-args nil)
408 (tramp-rcp-args nil)
409 (tramp-rcp-keep-date-arg nil)
410 (tramp-su-program nil)
411 (tramp-su-args nil)
fb7933a3
KG
412 (tramp-telnet-program nil)
413 (tramp-telnet-args nil))
414 ("scpx" (tramp-connection-function tramp-open-connection-rsh)
415 (tramp-rsh-program "ssh")
416 (tramp-rcp-program "scp")
417 (tramp-remote-sh "/bin/sh")
418 (tramp-rsh-args ("-e" "none" "-t" "-t" "/bin/sh"))
419 (tramp-rcp-args nil)
420 (tramp-rcp-keep-date-arg "-p")
fb7933a3
KG
421 (tramp-telnet-program nil)
422 (tramp-telnet-args nil))
ac474af1 423 ("sshx" (tramp-connection-function tramp-open-connection-rsh)
fb7933a3
KG
424 (tramp-rsh-program "ssh")
425 (tramp-rcp-program nil)
426 (tramp-remote-sh "/bin/sh")
427 (tramp-rsh-args ("-e" "none" "-t" "-t" "/bin/sh"))
428 (tramp-rcp-args nil)
429 (tramp-rcp-keep-date-arg nil)
430 (tramp-su-program nil)
431 (tramp-su-args nil)
fb7933a3
KG
432 (tramp-telnet-program nil)
433 (tramp-telnet-args nil))
ac474af1 434 ("krlogin"
fb7933a3
KG
435 (tramp-connection-function tramp-open-connection-rsh)
436 (tramp-rsh-program "krlogin")
437 (tramp-rcp-program nil)
438 (tramp-remote-sh "/bin/sh")
439 (tramp-rsh-args ("-x"))
440 (tramp-rcp-args nil)
441 (tramp-rcp-keep-date-arg nil)
442 (tramp-su-program nil)
443 (tramp-su-args nil)
fb7933a3
KG
444 (tramp-telnet-program nil)
445 (tramp-telnet-args nil))
ac474af1 446 ("plink"
fb7933a3
KG
447 (tramp-connection-function tramp-open-connection-rsh)
448 (tramp-rsh-program "plink")
449 (tramp-rcp-program nil)
450 (tramp-remote-sh "/bin/sh")
451 (tramp-rsh-args ("-ssh")) ;optionally add "-v"
452 (tramp-rcp-args nil)
453 (tramp-rcp-keep-date-arg nil)
454 (tramp-su-program nil)
455 (tramp-su-args nil)
fb7933a3
KG
456 (tramp-telnet-program nil)
457 (tramp-telnet-args nil))
458 ("pscp"
459 (tramp-connection-function tramp-open-connection-rsh)
460 (tramp-rsh-program "plink")
461 (tramp-rcp-program "pscp")
462 (tramp-remote-sh "/bin/sh")
463 (tramp-rsh-args ("-ssh"))
464 (tramp-rcp-args nil)
465 (tramp-rcp-keep-date-arg "-p")
466 (tramp-su-program nil)
467 (tramp-su-args nil)
fb7933a3
KG
468 (tramp-telnet-program nil)
469 (tramp-telnet-args nil))
470 ("fcp"
471 (tramp-connection-function tramp-open-connection-rsh)
472 (tramp-rsh-program "fsh")
473 (tramp-rcp-program "fcp")
474 (tramp-remote-sh "/bin/sh -i")
475 (tramp-rsh-args ("sh" "-i"))
476 (tramp-rcp-args nil)
477 (tramp-rcp-keep-date-arg "-p")
478 (tramp-su-program nil)
479 (tramp-su-args nil)
fb7933a3
KG
480 (tramp-telnet-program nil)
481 (tramp-telnet-args nil))
482 )
483 "*Alist of methods for remote files.
484This is a list of entries of the form (NAME PARAM1 PARAM2 ...).
485Each NAME stands for a remote access method. Each PARAM is a
486pair of the form (KEY VALUE). The following KEYs are defined:
16674e4f 487 * `tramp-connection-function'
fb7933a3
KG
488 This specifies the function to use to connect to the remote host.
489 Currently, `tramp-open-connection-rsh', `tramp-open-connection-telnet'
490 and `tramp-open-connection-su' are defined. See the documentation
491 of these functions for more details.
492 * `tramp-remote-sh'
493 This specifies the Bourne shell to use on the remote host. This
494 MUST be a Bourne-like shell. It is normally not necessary to set
495 this to any value other than \"/bin/sh\": tramp wants to use a shell
496 which groks tilde expansion, but it can search for it. Also note
497 that \"/bin/sh\" exists on all Unixen, this might not be true for
498 the value that you decide to use. You Have Been Warned.
499 * `tramp-rsh-program'
500 This specifies the name of the program to use for rsh; this might be
501 the full path to rsh or the name of a workalike program.
502 * `tramp-rsh-args'
503 This specifies the list of arguments to pass to the above
504 mentioned program. Please note that this is a list of arguments,
505 that is, normally you don't want to put \"-a -b\" or \"-f foo\"
506 here. Instead, you want two list elements, one for \"-a\" and one
507 for \"-b\", or one for \"-f\" and one for \"foo\".
508 * `tramp-rcp-program'
509 This specifies the name of the program to use for rcp; this might be
510 the full path to rcp or the name of a workalike program.
511 * `tramp-rcp-args'
512 This specifies the list of parameters to pass to the above mentioned
513 program, the hints for `tramp-rsh-args' also apply here.
514 * `tramp-rcp-keep-date-arg'
515 This specifies the parameter to use for `rcp' when the timestamp
516 of the original file should be kept. For `rcp', use `-p', for
517 `rsync', use `-t'.
518 * `tramp-su-program'
519 This specifies the name of the program to use for `su'.
520 * `tramp-su-args'
521 This specifies the list of arguments to pass to `su'.
522 \"%u\" is replaced by the user name, use \"%%\" for a literal
523 percent character.
fb7933a3
KG
524 * `tramp-telnet-program'
525 Specifies the telnet program to use when using
526 `tramp-open-connection-telnet' to log in.
527 * `tramp-telnet-args'
528 Specifies list of arguments to pass to `telnet'. The hints for
529 `tramp-rsh-args' also apply here.
530
531What does all this mean? Well, you should specify `tramp-rsh-program',
532`tramp-telnet-program' or `tramp-su-program' for all methods; this program
533is used to log in to the remote site. Then, there are two ways to
534actually transfer the files between the local and the remote side.
535One way is using an additional rcp-like program. If you want to do
536this, set `tramp-rcp-program' in the method.
537
538Another possibility for file transfer is inline transfer, i.e. the
539file is passed through the same buffer used by `tramp-rsh-program'. In
540this case, the file contents need to be protected since the
541`tramp-rsh-program' might use escape codes or the connection might not
542be eight-bit clean. Therefore, file contents are encoded for transit.
16674e4f 543See the variable `tramp-coding-commands' for details.
fb7933a3 544
16674e4f
KG
545So, to summarize: if the method is an out-of-band method, then you
546must specify `tramp-rcp-program' and `tramp-rcp-args'. If it is an
547inline method, then these two parameters should be nil. Every method,
548inline or out of band, must specify `tramp-connection-function' plus
549the associated arguments (for example, the telnet program if you chose
fb7933a3
KG
550`tramp-open-connection-telnet').
551
552Notes:
553
554When using `tramp-open-connection-su' the phrase `open connection to a
555remote host' sounds strange, but it is used nevertheless, for
556consistency. No connection is opened to a remote host, but `su' is
557started on the local host. You are not allowed to specify a remote
16674e4f 558host other than `localhost' or the name of the local host."
fb7933a3
KG
559 :group 'tramp
560 :type '(repeat
561 (cons string
562 (set (list (const tramp-connection-function) function)
563 (list (const tramp-rsh-program)
564 (choice (const nil) string))
565 (list (const tramp-rcp-program)
566 (choice (const nil) string))
567 (list (const tramp-remote-sh)
568 (choice (const nil) string))
569 (list (const tramp-rsh-args) (repeat string))
570 (list (const tramp-rcp-args) (repeat string))
571 (list (const tramp-rcp-keep-date-arg)
572 (choice (const nil) string))
573 (list (const tramp-su-program)
574 (choice (const nil) string))
575 (list (const tramp-su-args) (repeat string))
576 (list (const tramp-encoding-command)
577 (choice (const nil) string))
578 (list (const tramp-decoding-command)
579 (choice (const nil) string))
580 (list (const tramp-encoding-function)
581 (choice (const nil) function))
582 (list (const tramp-decoding-function)
583 (choice (const nil) function))
584 (list (const tramp-telnet-program)
585 (choice (const nil) string))
586 (list (const tramp-telnet-args) (repeat string))))))
587
588(defcustom tramp-multi-methods '("multi" "multiu")
589 "*List of multi-hop methods.
590Each entry in this list should be a method name as mentioned in the
591variable `tramp-methods'."
592 :group 'tramp
593 :type '(repeat string))
594
595(defcustom tramp-multi-connection-function-alist
596 '(("telnet" tramp-multi-connect-telnet "telnet %h%n")
597 ("rsh" tramp-multi-connect-rlogin "rsh %h -l %u%n")
598 ("ssh" tramp-multi-connect-rlogin "ssh %h -l %u%n")
599 ("su" tramp-multi-connect-su "su - %u%n")
600 ("sudo" tramp-multi-connect-su "sudo -u %u -s%n"))
601 "*List of connection functions for multi-hop methods.
602Each list item is a list of three items (METHOD FUNCTION COMMAND),
603where METHOD is the name as used in the file name, FUNCTION is the
604function to be executed, and COMMAND is the shell command used for
605connecting.
606
607COMMAND may contain percent escapes. `%u' will be replaced with the
608user name, `%h' will be replaced with the host name, and `%n' will be
609replaced with an end-of-line character, as specified in the variable
610`tramp-rsh-end-of-line'. Use `%%' for a literal percent character.
611Note that the interpretation of the percent escapes also depends on
612the FUNCTION. For example, the `%u' escape is forbidden with the
613function `tramp-multi-connect-telnet'. See the documentation of the
614various functions for details."
615 :group 'tramp
616 :type '(repeat (list string function string)))
617
b1d06e75 618(defcustom tramp-default-method "ssh"
fb7933a3 619 "*Default method to use for transferring files.
c62c9d08 620See `tramp-methods' for possibilities.
505edaeb
KG
621Also see `tramp-default-method-alist'.
622
623Emacs uses a unified filename syntax for Tramp and Ange-FTP.
624For backward compatibility, the default value of this variable
625is \"ftp\" on Emacs. But XEmacs uses a separate filename syntax
626for Tramp and EFS, so there the default method is \"sm\"."
c62c9d08
KG
627 :group 'tramp
628 :type 'string)
629
505edaeb 630(defcustom tramp-default-method-alist
16674e4f 631 (when tramp-unified-filenames
505edaeb 632 '(("\\`ftp\\." "" "ftp")
3b89d388
KG
633 ("" "\\`\\(anonymous\\|ftp\\)\\'" "ftp")
634 ("\\`localhost\\'" "\\`root\\'" "su")))
c62c9d08
KG
635 "*Default method to use for specific user/host pairs.
636This is an alist of items (HOST USER METHOD). The first matching item
637specifies the method to use for a file name which does not specify a
638method. HOST and USER are regular expressions or nil, which is
639interpreted as a regular expression which always matches. If no entry
640matches, the variable `tramp-default-method' takes effect.
641
642If the file name does not specify the user, lookup is done using the
643empty string for the user name.
644
645See `tramp-methods' for a list of possibilities for METHOD."
646 :group 'tramp
647 :type '(repeat (list (regexp :tag "Host regexp")
648 (regexp :tag "User regexp")
649 (string :tag "Method"))))
650
651(defcustom tramp-ftp-method "ftp"
652 "*When this method name is used, forward all calls to Ange-FTP."
fb7933a3
KG
653 :group 'tramp
654 :type 'string)
655
16674e4f
KG
656;; Default values for non-Unices seeked
657(defconst tramp-completion-function-alist-rsh
658 (unless (memq system-type '(windows-nt))
659 '((tramp-parse-rhosts "/etc/hosts.equiv")
660 (tramp-parse-rhosts "~/.rhosts")))
292ffc15 661 "Default list of (FUNCTION FILE) pairs to be examined for rsh methods."
16674e4f
KG
662)
663
664;; Default values for non-Unices seeked
665(defconst tramp-completion-function-alist-ssh
666 (unless (memq system-type '(windows-nt))
667 '((tramp-parse-rhosts "/etc/hosts.equiv")
668 (tramp-parse-rhosts "/etc/shosts.equiv")
669 (tramp-parse-shosts "/etc/ssh_known_hosts")
670 (tramp-parse-rhosts "~/.rhosts")
671 (tramp-parse-rhosts "~/.shosts")
672 (tramp-parse-shosts "~/.ssh/known_hosts")))
292ffc15 673 "Default list of (FUNCTION FILE) pairs to be examined for ssh methods."
16674e4f
KG
674)
675
676;; Default values for non-Unices seeked
677(defconst tramp-completion-function-alist-telnet
678 (unless (memq system-type '(windows-nt))
679 '((tramp-parse-hosts "/etc/hosts")))
292ffc15 680 "Default list of (FUNCTION FILE) pairs to be examined for telnet methods."
16674e4f
KG
681)
682
683;; Default values for non-Unices seeked
684(defconst tramp-completion-function-alist-su
685 (unless (memq system-type '(windows-nt))
686 '((tramp-parse-passwd "/etc/passwd")))
292ffc15
KG
687 "Default list of (FUNCTION FILE) pairs to be examined for su methods."
688)
689
690;; Default values for non-Unices seeked
691(defconst tramp-completion-function-alist-ftp
692 (unless (memq system-type '(windows-nt))
693 '((tramp-parse-netrc "~/.netrc")))
694 "Default list of (FUNCTION FILE) pairs to be examined for ftp methods."
16674e4f
KG
695)
696
697(defcustom tramp-completion-function-alist
698 (list (cons "rcp" tramp-completion-function-alist-rsh)
699 (cons "scp" tramp-completion-function-alist-ssh)
700 (cons "scp1" tramp-completion-function-alist-ssh)
701 (cons "scp2" tramp-completion-function-alist-ssh)
3b89d388
KG
702 (cons "scp1_old" tramp-completion-function-alist-ssh)
703 (cons "scp2_old" tramp-completion-function-alist-ssh)
16674e4f
KG
704 (cons "rsync" tramp-completion-function-alist-rsh)
705 (cons "rsh" tramp-completion-function-alist-rsh)
706 (cons "ssh" tramp-completion-function-alist-ssh)
707 (cons "ssh1" tramp-completion-function-alist-ssh)
708 (cons "ssh2" tramp-completion-function-alist-ssh)
3b89d388
KG
709 (cons "ssh1_old" tramp-completion-function-alist-ssh)
710 (cons "ssh2_old" tramp-completion-function-alist-ssh)
16674e4f
KG
711 (cons "telnet" tramp-completion-function-alist-telnet)
712 (cons "su" tramp-completion-function-alist-su)
713 (cons "sudo" tramp-completion-function-alist-su)
714 (cons "multi" nil)
715 (cons "scpx" tramp-completion-function-alist-ssh)
716 (cons "sshx" tramp-completion-function-alist-ssh)
717 (cons "krlogin" tramp-completion-function-alist-rsh)
718 (cons "plink" tramp-completion-function-alist-ssh)
719 (cons "pscp" tramp-completion-function-alist-ssh)
3b89d388 720 (cons "fcp" tramp-completion-function-alist-ssh)
292ffc15 721 (cons "ftp" tramp-completion-function-alist-ftp)
16674e4f
KG
722 )
723 "*Alist of methods for remote files.
724This is a list of entries of the form (NAME PAIR1 PAIR2 ...).
725Each NAME stands for a remote access method. Each PAIR is of the form
726\(FUNCTION FILE). FUNCTION is responsible to extract user names and host
727names from FILE for completion. The following predefined FUNCTIONs exists:
728
729 * `tramp-parse-rhosts' for \".rhosts\" like files,
730 * `tramp-parse-shosts' for \"ssh_known_hosts\" like files,
731 * `tramp-parse-hosts' for \"/etc/hosts\" like files, and
732 * `tramp-parse-passwd' for \"/etc/passwd\" like files.
292ffc15 733 * `tramp-parse-netrc ' for \".netrc\" like files.
16674e4f
KG
734
735FUNCTION can also see a customer defined function. For more details see
736the info pages."
737 :group 'tramp
738 :type '(repeat
739 (cons string
740 (choice (const nil) (repeat (list function file))))))
741
fb7933a3
KG
742(defcustom tramp-rsh-end-of-line "\n"
743 "*String used for end of line in rsh connections.
744I don't think this ever needs to be changed, so please tell me about it
16674e4f
KG
745if you need to change this.
746Also see `tramp-password-end-of-line'."
747 :group 'tramp
748 :type 'string)
749
750(defcustom tramp-password-end-of-line tramp-rsh-end-of-line
751 "*String used for end of line after sending a password.
752It seems that people using plink under Windows need to send
753\"\\r\\n\" (carriage-return, then newline) after a password, but just
754\"\\n\" after all other lines. This variable can be used for the
755password, see `tramp-rsh-end-of-line' for the other cases.
756
757The default value is to use the same value as `tramp-rsh-end-of-line'."
fb7933a3
KG
758 :group 'tramp
759 :type 'string)
760
761(defcustom tramp-remote-path
762 '("/bin" "/usr/bin" "/usr/sbin" "/usr/local/bin" "/usr/ccs/bin"
763 "/local/bin" "/local/freeware/bin" "/local/gnu/bin"
764 "/usr/freeware/bin" "/usr/pkg/bin" "/usr/contrib/bin")
765 "*List of directories to search for executables on remote host.
766Please notify me about other semi-standard directories to include here.
767
768You can use `~' in this list, but when searching for a shell which groks
769tilde expansion, all directory names starting with `~' will be ignored."
770 :group 'tramp
771 :type '(repeat string))
772
773(defcustom tramp-login-prompt-regexp
ac474af1 774 ".*ogin: *"
fb7933a3 775 "*Regexp matching login-like prompts.
ac474af1 776The regexp should match at end of buffer."
fb7933a3
KG
777 :group 'tramp
778 :type 'regexp)
779
821e6e36
KG
780(defcustom tramp-shell-prompt-pattern
781 "^[^#$%>\n]*[#$%>] *"
782 "Regexp to match prompts from remote shell.
783Normally, Tramp expects you to configure `shell-prompt-pattern'
784correctly, but sometimes it happens that you are connecting to a
785remote host which sends a different kind of shell prompt. Therefore,
786Tramp recognizes things matched by `shell-prompt-pattern' as prompt,
787and also things matched by this variable. The default value of this
788variable is the same as the default value of `shell-prompt-pattern',
789which should work well in many cases."
790 :group 'tramp
791 :type 'regexp)
792
fb7933a3 793(defcustom tramp-password-prompt-regexp
ac474af1 794 "^.*\\([pP]assword\\|passphrase.*\\):\^@? *"
fb7933a3 795 "*Regexp matching password-like prompts.
ac474af1 796The regexp should match at end of buffer.
fb7933a3
KG
797
798The `sudo' program appears to insert a `^@' character into the prompt."
799 :group 'tramp
800 :type 'regexp)
801
802(defcustom tramp-wrong-passwd-regexp
b1d06e75
KG
803 (concat "^.*"
804 ;; These strings should be on the last line
805 (regexp-opt '("Permission denied."
806 "Login incorrect"
807 "Login Incorrect"
808 "Connection refused"
809 "Connection closed"
810 "Sorry, try again."
811 "Name or service not known"
812 "Host key verification failed.") t)
813 ".*"
814 "\\|"
815 "^.*\\("
816 ;; Here comes a list of regexes, separated by \\|
817 "Received signal [0-9]+"
818 "\\).*")
fb7933a3 819 "*Regexp matching a `login failed' message.
ac474af1
KG
820The regexp should match at end of buffer."
821 :group 'tramp
822 :type 'regexp)
823
824(defcustom tramp-yesno-prompt-regexp
3cdaec13
KG
825 (concat
826 (regexp-opt '("Are you sure you want to continue connecting (yes/no)?") t)
827 "\\s-*")
828 "Regular expression matching all yes/no queries which need to be confirmed.
ac474af1 829The confirmation should be done with yes or no.
3cdaec13
KG
830The regexp should match at end of buffer.
831See also `tramp-yn-prompt-regexp'."
fb7933a3
KG
832 :group 'tramp
833 :type 'regexp)
834
3cdaec13
KG
835(defcustom tramp-yn-prompt-regexp
836 (concat (regexp-opt '("Store key in cache? (y/n)") t)
837 "\\s-*")
838 "Regular expression matching all y/n queries which need to be confirmed.
839The confirmation should be done with y or n.
840The regexp should match at end of buffer.
841See also `tramp-yesno-prompt-regexp'."
842 :group 'tramp
843 :type 'regexp)
844
845
fb7933a3
KG
846(defcustom tramp-temp-name-prefix "tramp."
847 "*Prefix to use for temporary files.
848If this is a relative file name (such as \"tramp.\"), it is considered
849relative to the directory name returned by the function
850`tramp-temporary-file-directory' (which see). It may also be an
851absolute file name; don't forget to include a prefix for the filename
852part, though."
853 :group 'tramp
854 :type 'string)
855
856(defcustom tramp-discard-garbage nil
857 "*If non-nil, try to discard garbage sent by remote shell.
858Some shells send such garbage upon connection setup."
859 :group 'tramp
860 :type 'boolean)
861
c62c9d08
KG
862(defcustom tramp-sh-extra-args '(("/bash\\'" . "--norc"))
863 "*Alist specifying extra arguments to pass to the remote shell.
864Entries are (REGEXP . ARGS) where REGEXP is a regular expression
865matching the shell file name and ARGS is a string specifying the
866arguments.
867
868This variable is only used when Tramp needs to start up another shell
869for tilde expansion. The extra arguments should typically prevent the
870shell from reading its init file."
871 :group 'tramp
872 :type '(alist :key-type string :value-type string))
873
16674e4f
KG
874(defcustom tramp-prefix-format
875 (if tramp-unified-filenames "/" "/[")
876 "*String matching the very beginning of tramp file names.
877Used in `tramp-make-tramp-file-name' and `tramp-make-tramp-multi-file-name'."
878 :group 'tramp
879 :type 'string)
880
881(defcustom tramp-prefix-regexp
882 (concat "^" (regexp-quote tramp-prefix-format))
883 "*Regexp matching the very beginning of tramp file names.
884Should always start with \"^\". Derived from `tramp-prefix-format'."
885 :group 'tramp
886 :type 'regexp)
887
888(defcustom tramp-method-regexp
889 "[a-zA-Z_0-9-]+"
890 "*Regexp matching methods identifiers."
891 :group 'tramp
892 :type 'regexp)
893
894;; It is a little bit annoying that in XEmacs case this delimeter is different
895;; for single-hop and multi-hop cases.
896(defcustom tramp-postfix-single-method-format
897 (if tramp-unified-filenames ":" "/")
898 "*String matching delimeter between method and user or host names.
899Applicable for single-hop methods.
900Used in `tramp-make-tramp-file-name'."
901 :group 'tramp
902 :type 'string)
903
904(defcustom tramp-postfix-single-method-regexp
905 (regexp-quote tramp-postfix-single-method-format)
906 "*Regexp matching delimeter between method and user or host names.
907Applicable for single-hop methods.
908Derived from `tramp-postfix-single-method-format'."
909 :group 'tramp
910 :type 'regexp)
911
912(defcustom tramp-postfix-multi-method-format
913 ":"
914 "*String matching delimeter between method and user or host names.
915Applicable for multi-hop methods.
916Used in `tramp-make-tramp-multi-file-name'."
917 :group 'tramp
918 :type 'string)
919
920(defcustom tramp-postfix-multi-method-regexp
921 (regexp-quote tramp-postfix-multi-method-format)
922 "*Regexp matching delimeter between method and user or host names.
923Applicable for multi-hop methods.
924Derived from `tramp-postfix-multi-method-format'."
925 :group 'tramp
926 :type 'regexp)
fb7933a3 927
16674e4f
KG
928(defcustom tramp-postfix-multi-hop-format
929 (if tramp-unified-filenames ":" "/")
930 "*String matching delimeter between path and next method.
931Applicable for multi-hop methods.
932Used in `tramp-make-tramp-multi-file-name'."
933 :group 'tramp
934 :type 'string)
935
936(defcustom tramp-postfix-multi-hop-regexp
937 (regexp-quote tramp-postfix-multi-hop-format)
938 "*Regexp matching delimeter between path and next method.
939Applicable for multi-hop methods.
940Derived from `tramp-postfix-multi-hop-format'."
941 :group 'tramp
942 :type 'regexp)
943
944(defcustom tramp-user-regexp
292ffc15 945 "[^:@/ \t]*"
16674e4f
KG
946 "*Regexp matching user names."
947 :group 'tramp
948 :type 'regexp)
949
950(defcustom tramp-postfix-user-format
951 "@"
952 "*String matching delimeter between user and host names.
953Used in `tramp-make-tramp-file-name' and `tramp-make-tramp-multi-file-name'."
954 :group 'tramp
955 :type 'string)
956
957(defcustom tramp-postfix-user-regexp
958 (regexp-quote tramp-postfix-user-format)
959 "*Regexp matching delimeter between user and host names.
960Derived from `tramp-postfix-user-format'."
961 :group 'tramp
962 :type 'regexp)
963
964(defcustom tramp-host-regexp
3b89d388 965 "[a-zA-Z0-9_.#-]*"
16674e4f
KG
966 "*Regexp matching host names."
967 :group 'tramp
968 :type 'regexp)
969
970(defcustom tramp-postfix-host-format
971 (if tramp-unified-filenames ":" "]")
972 "*String matching delimeter between host names and paths.
973Used in `tramp-make-tramp-file-name' and `tramp-make-tramp-multi-file-name'."
974 :group 'tramp
975 :type 'string)
976
977(defcustom tramp-postfix-host-regexp
978 (regexp-quote tramp-postfix-host-format)
979 "*Regexp matching delimeter between host names and paths.
980Derived from `tramp-postfix-host-format'."
981 :group 'tramp
982 :type 'regexp)
983
984(defcustom tramp-path-regexp
985 ".*$"
986 "*Regexp matching paths."
987 :group 'tramp
988 :type 'regexp)
989
990;; File name format.
505edaeb
KG
991
992(defcustom tramp-file-name-structure
16674e4f
KG
993 (list
994 (concat
995 tramp-prefix-regexp
996 "\\(" "\\(" tramp-method-regexp "\\)" tramp-postfix-single-method-regexp "\\)?"
997 "\\(" "\\(" tramp-user-regexp "\\)" tramp-postfix-user-regexp "\\)?"
998 "\\(" tramp-host-regexp "\\)" tramp-postfix-host-regexp
999 "\\(" tramp-path-regexp "\\)")
1000 2 4 5 6)
1001
fb7933a3
KG
1002 "*List of five elements (REGEXP METHOD USER HOST FILE), detailing \
1003the tramp file name structure.
1004
1005The first element REGEXP is a regular expression matching a tramp file
1006name. The regex should contain parentheses around the method name,
1007the user name, the host name, and the file name parts.
1008
1009The second element METHOD is a number, saying which pair of
1010parentheses matches the method name. The third element USER is
1011similar, but for the user name. The fourth element HOST is similar,
1012but for the host name. The fifth element FILE is for the file name.
1013These numbers are passed directly to `match-string', which see. That
1014means the opening parentheses are counted to identify the pair.
1015
16674e4f 1016See also `tramp-file-name-regexp'."
fb7933a3
KG
1017 :group 'tramp
1018 :type '(list (regexp :tag "File name regexp")
1019 (integer :tag "Paren pair for method name")
1020 (integer :tag "Paren pair for user name ")
1021 (integer :tag "Paren pair for host name ")
1022 (integer :tag "Paren pair for file name ")))
1023
1024;;;###autoload
505edaeb
KG
1025(defconst tramp-file-name-regexp-unified
1026 "\\`/[^/:]+:"
1027 "Value for `tramp-file-name-regexp' for unified remoting.
1028Emacs (not XEmacs) uses a unified filename syntax for Ange-FTP and
1029Tramp. See `tramp-file-name-structure-unified' for more explanations.")
1030
1031;;;###autoload
1032(defconst tramp-file-name-regexp-separate
1033 "\\`/\\[.*\\]"
1034 "Value for `tramp-file-name-regexp' for separate remoting.
1035XEmacs uses a separate filename syntax for Tramp and EFS.
1036See `tramp-file-name-structure-separate' for more explanations.")
1037
1038;;;###autoload
1039(defcustom tramp-file-name-regexp
16674e4f
KG
1040 (if tramp-unified-filenames
1041 tramp-file-name-regexp-unified
1042 tramp-file-name-regexp-separate)
fb7933a3
KG
1043 "*Regular expression matching file names handled by tramp.
1044This regexp should match tramp file names but no other file names.
1045\(When tramp.el is loaded, this regular expression is prepended to
1046`file-name-handler-alist', and that is searched sequentially. Thus,
1047if the tramp entry appears rather early in the `file-name-handler-alist'
1048and is a bit too general, then some files might be considered tramp
1049files which are not really tramp files.
1050
1051Please note that the entry in `file-name-handler-alist' is made when
1052this file (tramp.el) is loaded. This means that this variable must be set
1053before loading tramp.el. Alternatively, `file-name-handler-alist' can be
1054updated after changing this variable.
1055
16674e4f 1056Also see `tramp-file-name-structure'."
fb7933a3
KG
1057 :group 'tramp
1058 :type 'regexp)
1059
16674e4f
KG
1060;;;###autoload
1061(defconst tramp-completion-file-name-regexp-unified
1062 "^/[^/]*$"
1063 "Value for `tramp-completion-file-name-regexp' for unified remoting.
1064Emacs (not XEmacs) uses a unified filename syntax for Ange-FTP and
1065Tramp. See `tramp-file-name-structure-unified' for more explanations.")
fb7933a3 1066
16674e4f
KG
1067;;;###autoload
1068(defconst tramp-completion-file-name-regexp-separate
1069 "^/\\([[][^]]*\\)?$"
1070 "Value for `tramp-completion-file-name-regexp' for separate remoting.
1071XEmacs uses a separate filename syntax for Tramp and EFS.
1072See `tramp-file-name-structure-separate' for more explanations.")
fb7933a3 1073
16674e4f
KG
1074;;;###autoload
1075(defcustom tramp-completion-file-name-regexp
1076 (if tramp-unified-filenames
1077 tramp-completion-file-name-regexp-unified
1078 tramp-completion-file-name-regexp-separate)
1079 "*Regular expression matching file names handled by tramp completion.
1080This regexp should match partial tramp file names only.
1081
1082Please note that the entry in `file-name-handler-alist' is made when
1083this file (tramp.el) is loaded. This means that this variable must be set
1084before loading tramp.el. Alternatively, `file-name-handler-alist' can be
1085updated after changing this variable.
1086
1087Also see `tramp-file-name-structure'."
1088 :group 'tramp
1089 :type 'regexp)
505edaeb
KG
1090
1091(defcustom tramp-multi-file-name-structure
16674e4f
KG
1092 (list
1093 (concat
1094 tramp-prefix-regexp
1095 "\\(" "\\(" tramp-method-regexp "\\)" "\\)?"
1096 "\\(" "\\(" tramp-postfix-multi-hop-regexp "%s" "\\)+" "\\)?"
1097 tramp-postfix-host-regexp "\\(" tramp-path-regexp "\\)")
1098 2 3 -1)
fb7933a3
KG
1099 "*Describes the file name structure of `multi' files.
1100Multi files allow you to contact a remote host in several hops.
1101This is a list of four elements (REGEXP METHOD HOP PATH).
1102
1103The first element, REGEXP, gives a regular expression to match against
1104the file name. In this regular expression, `%s' is replaced with the
1105value of `tramp-multi-file-name-hop-structure'. (Note: in order to
1106allow multiple hops, you normally want to use something like
1107\"\\\\(\\\\(%s\\\\)+\\\\)\" in the regular expression. The outer pair
1108of parentheses is used for the HOP element, see below.)
1109
1110All remaining elements are numbers. METHOD gives the number of the
1111paren pair which matches the method name. HOP gives the number of the
1112paren pair which matches the hop sequence. PATH gives the number of
1113the paren pair which matches the path name on the remote host.
1114
1115PATH can also be negative, which means to count from the end. Ie, a
1116value of -1 means the last paren pair.
1117
1118I think it would be good if the regexp matches the whole of the
1119string, but I haven't actually tried what happens if it doesn't..."
1120 :group 'tramp
1121 :type '(list (regexp :tag "File name regexp")
1122 (integer :tag "Paren pair for method name")
1123 (integer :tag "Paren pair for hops")
1124 (integer :tag "Paren pair to match path")))
1125
505edaeb 1126(defcustom tramp-multi-file-name-hop-structure
16674e4f
KG
1127 (list
1128 (concat
1129 "\\(" tramp-method-regexp "\\)" tramp-postfix-multi-method-regexp
1130 "\\(" tramp-user-regexp "\\)" tramp-postfix-user-regexp
1131 "\\(" tramp-host-regexp "\\)")
1132 1 2 3)
fb7933a3
KG
1133 "*Describes the structure of a hop in multi files.
1134This is a list of four elements (REGEXP METHOD USER HOST). First
1135element REGEXP is used to match against the hop. Pair number METHOD
1136matches the method of one hop, pair number USER matches the user of
1137one hop, pair number HOST matches the host of one hop.
1138
1139This regular expression should match exactly all of one hop."
1140 :group 'tramp
1141 :type '(list (regexp :tag "Hop regexp")
1142 (integer :tag "Paren pair for method name")
1143 (integer :tag "Paren pair for user name")
1144 (integer :tag "Paren pair for host name")))
1145
505edaeb 1146(defcustom tramp-make-multi-tramp-file-format
16674e4f
KG
1147 (list
1148 (concat tramp-prefix-format "%m")
1149 (concat tramp-postfix-multi-hop-format
1150 "%m" tramp-postfix-multi-method-format
1151 "%u" tramp-postfix-user-format
1152 "%h")
1153 (concat tramp-postfix-host-format "%p"))
fb7933a3
KG
1154 "*Describes how to construct a `multi' file name.
1155This is a list of three elements PREFIX, HOP and PATH.
1156
1157The first element PREFIX says how to construct the prefix, the second
1158element HOP specifies what each hop looks like, and the final element
1159PATH says how to construct the path name.
1160
1161In PREFIX, `%%' means `%' and `%m' means the method name.
1162
1163In HOP, `%%' means `%' and `%m', `%u', `%h' mean the hop method, hop
1164user and hop host, respectively.
1165
1166In PATH, `%%' means `%' and `%p' means the path name.
1167
1168The resulting file name always contains one copy of PREFIX and one
1169copy of PATH, but there is one copy of HOP for each hop in the file
1170name.
1171
1172Note: the current implementation requires the prefix to contain the
1173method name, followed by all the hops, and the path name must come
1174last."
1175 :group 'tramp
1176 :type '(list string string string))
1177
1178(defcustom tramp-terminal-type "dumb"
1179 "*Value of TERM environment variable for logging in to remote host.
1180Because Tramp wants to parse the output of the remote shell, it is easily
1181confused by ANSI color escape sequences and suchlike. Often, shell init
1182files conditionalize this setup based on the TERM environment variable."
1183 :group 'tramp
1184 :type 'string)
1185
1186(defcustom tramp-completion-without-shell-p nil
1187 "*If nil, use shell wildcards for completion, else rely on Lisp only.
1188Using shell wildcards for completions has the advantage that it can be
1189fast even in large directories, but completion is always
1190case-sensitive. Relying on Lisp only means that case-insensitive
1191completion is possible (subject to the variable `completion-ignore-case'),
1192but it might be slow on large directories."
1193 :group 'tramp
1194 :type 'boolean)
1195
ac474af1
KG
1196(defcustom tramp-actions-before-shell
1197 '((tramp-password-prompt-regexp tramp-action-password)
1198 (tramp-login-prompt-regexp tramp-action-login)
1199 (shell-prompt-pattern tramp-action-succeed)
821e6e36 1200 (tramp-shell-prompt-pattern tramp-action-succeed)
ac474af1 1201 (tramp-wrong-passwd-regexp tramp-action-permission-denied)
3cdaec13
KG
1202 (tramp-yesno-prompt-regexp tramp-action-yesno)
1203 (tramp-yn-prompt-regexp tramp-action-yn))
ac474af1
KG
1204 "List of pattern/action pairs.
1205Whenever a pattern matches, the corresponding action is performed.
1206Each item looks like (PATTERN ACTION).
1207
1208The PATTERN should be a symbol, a variable. The value of this
1209variable gives the regular expression to search for. Note that the
1210regexp must match at the end of the buffer, \"\\'\" is implicitly
1211appended to it.
1212
1213The ACTION should also be a symbol, but a function. When the
1214corresponding PATTERN matches, the ACTION function is called."
1215 :group 'tramp
1216 :type '(repeat (list variable function)))
1217
1218(defcustom tramp-multi-actions
1219 '((tramp-password-prompt-regexp tramp-multi-action-password)
1220 (tramp-login-prompt-regexp tramp-multi-action-login)
1221 (shell-prompt-pattern tramp-multi-action-succeed)
821e6e36 1222 (tramp-shell-prompt-pattern tramp-multi-action-succeed)
ac474af1
KG
1223 (tramp-wrong-passwd-regexp tramp-multi-action-permission-denied))
1224 "List of pattern/action pairs.
1225This list is used for each hop in multi-hop connections.
1226See `tramp-actions-before-shell' for more info."
1227 :group 'tramp
1228 :type '(repeat (list variable function)))
1229
fb7933a3
KG
1230;;; Internal Variables:
1231
1232(defvar tramp-buffer-file-attributes nil
1233 "Holds the `ls -ild' output for the current buffer.
1234This variable is local to each buffer. It is not used if the remote
1235machine groks Perl. If it is used, it's used as an emulation for
1236the visited file modtime.")
1237(make-variable-buffer-local 'tramp-buffer-file-attributes)
1238
1239(defvar tramp-end-of-output "/////"
1240 "String used to recognize end of output.")
1241
1242(defvar tramp-connection-function nil
1243 "This internal variable holds a parameter for `tramp-methods'.
1244In the connection buffer, this variable has the value of the like-named
1245method parameter, as specified in `tramp-methods' (which see).")
1246
1247(defvar tramp-remote-sh nil
1248 "This internal variable holds a parameter for `tramp-methods'.
1249In the connection buffer, this variable has the value of the like-named
1250method parameter, as specified in `tramp-methods' (which see).")
1251
1252(defvar tramp-rsh-program nil
1253 "This internal variable holds a parameter for `tramp-methods'.
1254In the connection buffer, this variable has the value of the like-named
1255method parameter, as specified in `tramp-methods' (which see).")
1256
1257(defvar tramp-rsh-args nil
1258 "This internal variable holds a parameter for `tramp-methods'.
1259In the connection buffer, this variable has the value of the like-named
1260method parameter, as specified in `tramp-methods' (which see).")
1261
1262(defvar tramp-rcp-program nil
1263 "This internal variable holds a parameter for `tramp-methods'.
1264In the connection buffer, this variable has the value of the like-named
1265method parameter, as specified in `tramp-methods' (which see).")
1266
1267(defvar tramp-rcp-args nil
1268 "This internal variable holds a parameter for `tramp-methods'.
1269In the connection buffer, this variable has the value of the like-named
1270method parameter, as specified in `tramp-methods' (which see).")
1271
1272(defvar tramp-rcp-keep-date-arg nil
1273 "This internal variable holds a parameter for `tramp-methods'.
1274In the connection buffer, this variable has the value of the like-named
1275method parameter, as specified in `tramp-methods' (which see).")
1276
1277(defvar tramp-encoding-command nil
1278 "This internal variable holds a parameter for `tramp-methods'.
1279In the connection buffer, this variable has the value of the like-named
1280method parameter, as specified in `tramp-methods' (which see).")
1281
1282(defvar tramp-decoding-command nil
1283 "This internal variable holds a parameter for `tramp-methods'.
1284In the connection buffer, this variable has the value of the like-named
1285method parameter, as specified in `tramp-methods' (which see).")
1286
1287(defvar tramp-encoding-function nil
1288 "This internal variable holds a parameter for `tramp-methods'.
1289In the connection buffer, this variable has the value of the like-named
1290method parameter, as specified in `tramp-methods' (which see).")
1291
1292(defvar tramp-decoding-function nil
1293 "This internal variable holds a parameter for `tramp-methods'.
1294In the connection buffer, this variable has the value of the like-named
1295method parameter, as specified in `tramp-methods' (which see).")
1296
1297(defvar tramp-telnet-program nil
1298 "This internal variable holds a parameter for `tramp-methods'.
1299In the connection buffer, this variable has the value of the like-named
1300method parameter, as specified in `tramp-methods' (which see).")
1301
1302(defvar tramp-telnet-args nil
1303 "This internal variable holds a parameter for `tramp-methods'.
1304In the connection buffer, this variable has the value of the like-named
1305method parameter, as specified in `tramp-methods' (which see).")
1306
b1d06e75
KG
1307(defvar tramp-su-program nil
1308 "This internal variable holds a parameter for `tramp-methods'.
1309In the connection buffer, this variable has the value of the like-named
1310method parameter, as specified in `tramp-methods' (which see).")
1311
fb7933a3
KG
1312;; CCC `local in each buffer'?
1313(defvar tramp-ls-command nil
1314 "This command is used to get a long listing with numeric user and group ids.
1315This variable is automatically made buffer-local to each rsh process buffer
1316upon opening the connection.")
1317
1318(defvar tramp-current-multi-method nil
1319 "Name of `multi' connection method for this *tramp* buffer, or nil if not multi.
1320This variable is automatically made buffer-local to each rsh process buffer
1321upon opening the connection.")
1322
1323(defvar tramp-current-method nil
1324 "Connection method for this *tramp* buffer.
1325This variable is automatically made buffer-local to each rsh process buffer
1326upon opening the connection.")
1327
1328(defvar tramp-current-user nil
1329 "Remote login name for this *tramp* buffer.
1330This variable is automatically made buffer-local to each rsh process buffer
1331upon opening the connection.")
1332
1333(defvar tramp-current-host nil
1334 "Remote host for this *tramp* buffer.
1335This variable is automatically made buffer-local to each rsh process buffer
1336upon opening the connection.")
1337
1338(defvar tramp-test-groks-nt nil
1339 "Whether the `test' command groks the `-nt' switch.
1340\(`test A -nt B' tests if file A is newer than file B.)
1341This variable is automatically made buffer-local to each rsh process buffer
1342upon opening the connection.")
1343
1344(defvar tramp-file-exists-command nil
1345 "Command to use for checking if a file exists.
1346This variable is automatically made buffer-local to each rsh process buffer
1347upon opening the connection.")
1348
fabf2143
KG
1349(defconst tramp-uudecode "\
1350tramp_uudecode () {
1351\(echo begin 600 /tmp/tramp.$$; tail +2) | uudecode
1352cat /tmp/tramp.$$
1353rm -f /tmp/tramp.$$
1354}"
1355 "Shell function to implement `uudecode' to standard output.
1356Many systems support `uudecode -o -' for this or `uudecode -p', but
1357some systems don't, and for them we have this shell function.")
1358
1359;; Perl script to implement `file-attributes' in a Lisp `read'able
1360;; output. If you are hacking on this, note that you get *no* output
1361;; unless this spits out a complete line, including the '\n' at the
1362;; end.
5beaf831
KG
1363(defconst tramp-perl-file-attributes "\
1364$f = $ARGV[0];
fb7933a3
KG
1365@s = lstat($f);
1366if (($s[2] & 0170000) == 0120000) { $l = readlink($f); $l = \"\\\"$l\\\"\"; }
1367elsif (($s[2] & 0170000) == 040000) { $l = \"t\"; }
1368else { $l = \"nil\" };
5beaf831 1369printf(\"(%s %u %d %d (%u %u) (%u %u) (%u %u) %u %u t (%u . %u) (%u %u))\\n\",
fb7933a3
KG
1370$l, $s[3], $s[4], $s[5], $s[8] >> 16 & 0xffff, $s[8] & 0xffff,
1371$s[9] >> 16 & 0xffff, $s[9] & 0xffff, $s[10] >> 16 & 0xffff, $s[10] & 0xffff,
1372$s[7], $s[2], $s[1] >> 16 & 0xffff, $s[1] & 0xffff, $s[0] >> 16 & 0xffff, $s[0] & 0xffff);"
fb7933a3
KG
1373 "Perl script to produce output suitable for use with `file-attributes'
1374on the remote file system.")
1375
ac474af1
KG
1376;; ;; These two use uu encoding.
1377;; (defvar tramp-perl-encode "%s -e'\
1378;; print qq(begin 644 xxx\n);
1379;; my $s = q();
1380;; my $res = q();
1381;; while (read(STDIN, $s, 45)) {
1382;; print pack(q(u), $s);
1383;; }
1384;; print qq(`\n);
1385;; print qq(end\n);
1386;; '"
1387;; "Perl program to use for encoding a file.
1388;; Escape sequence %s is replaced with name of Perl binary.")
1389
1390;; (defvar tramp-perl-decode "%s -ne '
1391;; print unpack q(u), $_;
1392;; '"
1393;; "Perl program to use for decoding a file.
1394;; Escape sequence %s is replaced with name of Perl binary.")
1395
1396;; These two use base64 encoding.
b1d06e75 1397(defvar tramp-perl-encode-with-module
ac474af1
KG
1398 "perl -MMIME::Base64 -0777 -ne 'print encode_base64($_)'"
1399 "Perl program to use for encoding a file.
b1d06e75 1400Escape sequence %s is replaced with name of Perl binary.
89509ea0 1401This string is passed to `format', so percent characters need to be doubled.
b1d06e75
KG
1402This implementation requires the MIME::Base64 Perl module to be installed
1403on the remote host.")
1404
1405(defvar tramp-perl-decode-with-module
1406 "perl -MMIME::Base64 -0777 -ne 'print decode_base64($_)'"
1407 "Perl program to use for decoding a file.
1408Escape sequence %s is replaced with name of Perl binary.
89509ea0 1409This string is passed to `format', so percent characters need to be doubled.
b1d06e75
KG
1410This implementation requires the MIME::Base64 Perl module to be installed
1411on the remote host.")
1412
1413(defvar tramp-perl-encode
1414 "%s -e '
1415# This script contributed by Juanma Barranquero <lektu@terra.es>.
1416# Copyright (C) 2002 Free Software Foundation, Inc.
1417use strict;
1418
fa32e96a 1419my %%trans = do {
b1d06e75
KG
1420 my $i = 0;
1421 map {(substr(unpack(q(B8), chr $i++), 2, 6), $_)}
1422 split //, q(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/);
1423};
1424
36541701 1425binmode(\\*STDIN);
b1d06e75
KG
1426
1427# We read in chunks of 54 bytes, to generate output lines
1428# of 72 chars (plus end of line)
36541701 1429$/ = \\54;
b1d06e75
KG
1430
1431while (my $data = <STDIN>) {
1432 my $pad = q();
1433
1434 # Only for the last chunk, and only if did not fill the last three-byte packet
1435 if (eof) {
fa32e96a 1436 my $mod = length($data) %% 3;
b1d06e75
KG
1437 $pad = q(=) x (3 - $mod) if $mod;
1438 }
1439
1440 # Not the fastest method, but it is simple: unpack to binary string, split
1441 # by groups of 6 bits and convert back from binary to byte; then map into
1442 # the translation table
1443 print
1444 join q(),
1445 map($trans{$_},
1446 (substr(unpack(q(B*), $data) . q(00000), 0, 432) =~ /....../g)),
1447 $pad,
36541701 1448 qq(\\n);
b1d06e75
KG
1449}
1450'"
1451 "Perl program to use for encoding a file.
fa32e96a 1452Escape sequence %s is replaced with name of Perl binary.
ccf29586 1453This string is passed to `format', so percent characters need to be doubled.")
ac474af1
KG
1454
1455(defvar tramp-perl-decode
b1d06e75
KG
1456 "%s -e '
1457# This script contributed by Juanma Barranquero <lektu@terra.es>.
1458# Copyright (C) 2002 Free Software Foundation, Inc.
1459use strict;
1460
fa32e96a 1461my %%trans = do {
b1d06e75 1462 my $i = 0;
16674e4f 1463 map {($_, substr(unpack(q(B8), chr $i++), 2, 6))}
b1d06e75
KG
1464 split //, q(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/)
1465};
1466
fa32e96a 1467my %%bytes = map {(unpack(q(B8), chr $_), chr $_)} 0 .. 255;
b1d06e75 1468
36541701 1469binmode(\\*STDOUT);
b1d06e75
KG
1470
1471# We are going to accumulate into $pending to accept any line length
1472# (we do not check they are <= 76 chars as the RFC says)
1473my $pending = q();
1474
1475while (my $data = <STDIN>) {
1476 chomp $data;
1477
1478 # If we find one or two =, we have reached the end and
1479 # any following data is to be discarded
1480 my $finished = $data =~ s/(==?).*/$1/;
1481 $pending .= $data;
1482
1483 my $len = length($pending);
16674e4f 1484 my $chunk = substr($pending, 0, $len & ~3);
b1d06e75
KG
1485
1486 # Easy method: translate from chars to (pregenerated) six-bit packets, join,
1487 # split in 8-bit chunks and convert back to char.
1488 print join q(),
1489 map $bytes{$_},
1490 ((join q(), map {$trans{$_} || q()} split //, $chunk) =~ /......../g);
1491
1492 last if $finished;
1493}
1494'"
ac474af1 1495 "Perl program to use for decoding a file.
fa32e96a 1496Escape sequence %s is replaced with name of Perl binary.
ccf29586 1497This string is passed to `format', so percent characters need to be doubled.")
fb7933a3
KG
1498
1499; These values conform to `file-attributes' from XEmacs 21.2.
1500; GNU Emacs and other tools not checked.
1501(defconst tramp-file-mode-type-map '((0 . "-") ; Normal file (SVID-v2 and XPG2)
1502 (1 . "p") ; fifo
1503 (2 . "c") ; character device
1504 (3 . "m") ; multiplexed character device (v7)
1505 (4 . "d") ; directory
1506 (5 . "?") ; Named special file (XENIX)
1507 (6 . "b") ; block device
1508 (7 . "?") ; multiplexed block device (v7)
1509 (8 . "-") ; regular file
1510 (9 . "n") ; network special file (HP-UX)
1511 (10 . "l") ; symlink
1512 (11 . "?") ; ACL shadow inode (Solaris, not userspace)
1513 (12 . "s") ; socket
1514 (13 . "D") ; door special (Solaris)
1515 (14 . "w")) ; whiteout (BSD)
1516 "A list of file types returned from the `stat' system call.
1517This is used to map a mode number to a permission string.")
1518
1519(defvar tramp-dos-coding-system
1520 (if (and (fboundp 'coding-system-p)
1521 (funcall 'coding-system-p '(dos)))
1522 'dos
1523 'undecided-dos)
1524 "Some Emacsen know the `dos' coding system, others need `undecided-dos'.")
1525
ac474af1
KG
1526(defvar tramp-last-cmd-time nil
1527 "Internal Tramp variable recording the time when the last cmd was sent.
1528This variable is buffer-local in every buffer.")
1529(make-variable-buffer-local 'tramp-last-cmd-time)
fb7933a3 1530
dba28077
KG
1531;; This variable does not have the right value in XEmacs. What should
1532;; I use instead of find-operation-coding-system in XEmacs?
3cdaec13 1533(defvar tramp-feature-write-region-fix
16674e4f 1534 (when (fboundp 'find-operation-coding-system)
dba28077
KG
1535 (let ((file-coding-system-alist '(("test" emacs-mule))))
1536 (find-operation-coding-system 'write-region 0 0 "" nil "test")))
1537 "Internal variable to say if `write-region' chooses the right coding.
3cdaec13
KG
1538Older versions of Emacs chose the coding system for `write-region' based
1539on the FILENAME argument, even if VISIT was a string.")
1540
fb7933a3
KG
1541;; New handlers should be added here. The following operations can be
1542;; handled using the normal primitives: file-name-as-directory,
1543;; file-name-directory, file-name-nondirectory,
1544;; file-name-sans-versions, get-file-buffer.
1545(defconst tramp-file-name-handler-alist
1546 '(
1547 (load . tramp-handle-load)
1548 (make-symbolic-link . tramp-handle-make-symbolic-link)
1549 (file-name-directory . tramp-handle-file-name-directory)
1550 (file-name-nondirectory . tramp-handle-file-name-nondirectory)
1551 (file-truename . tramp-handle-file-truename)
1552 (file-exists-p . tramp-handle-file-exists-p)
1553 (file-directory-p . tramp-handle-file-directory-p)
1554 (file-executable-p . tramp-handle-file-executable-p)
1555 (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
1556 (file-readable-p . tramp-handle-file-readable-p)
1557 (file-regular-p . tramp-handle-file-regular-p)
1558 (file-symlink-p . tramp-handle-file-symlink-p)
1559 (file-writable-p . tramp-handle-file-writable-p)
1560 (file-ownership-preserved-p . tramp-handle-file-ownership-preserved-p)
1561 (file-newer-than-file-p . tramp-handle-file-newer-than-file-p)
1562 (file-attributes . tramp-handle-file-attributes)
1563 (file-modes . tramp-handle-file-modes)
1564 (file-directory-files . tramp-handle-file-directory-files)
1565 (directory-files . tramp-handle-directory-files)
1566 (file-name-all-completions . tramp-handle-file-name-all-completions)
1567 (file-name-completion . tramp-handle-file-name-completion)
1568 (add-name-to-file . tramp-handle-add-name-to-file)
1569 (copy-file . tramp-handle-copy-file)
1570 (rename-file . tramp-handle-rename-file)
1571 (set-file-modes . tramp-handle-set-file-modes)
1572 (make-directory . tramp-handle-make-directory)
1573 (delete-directory . tramp-handle-delete-directory)
1574 (delete-file . tramp-handle-delete-file)
1575 (directory-file-name . tramp-handle-directory-file-name)
1576 (shell-command . tramp-handle-shell-command)
1577 (insert-directory . tramp-handle-insert-directory)
1578 (expand-file-name . tramp-handle-expand-file-name)
1579 (file-local-copy . tramp-handle-file-local-copy)
1580 (insert-file-contents . tramp-handle-insert-file-contents)
1581 (write-region . tramp-handle-write-region)
1582 (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
1583 (dired-call-process . tramp-handle-dired-call-process)
1584 (dired-recursive-delete-directory
1585 . tramp-handle-dired-recursive-delete-directory)
1586 (set-visited-file-modtime . tramp-handle-set-visited-file-modtime)
1587 (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime))
1588 "Alist of handler functions.
1589Operations not mentioned here will be handled by the normal Emacs functions.")
1590
16674e4f
KG
1591;; Handlers for partial tramp file names. For GNU Emacs just
1592;; `file-name-all-completions' is needed. The other ones are necessary
1593;; for XEmacs.
1594(defconst tramp-completion-file-name-handler-alist
1595 '(
1596 (file-name-directory . tramp-completion-handle-file-name-directory)
1597 (file-name-nondirectory . tramp-completion-handle-file-name-nondirectory)
1598 (file-exists-p . tramp-completion-handle-file-exists-p)
1599 (file-name-all-completions . tramp-completion-handle-file-name-all-completions)
1600 (file-name-completion . tramp-completion-handle-file-name-completion)
1601 (expand-file-name . tramp-completion-handle-expand-file-name))
1602 "Alist of completion handler functions.
1603Used for file names matching `tramp-file-name-regexp'. Operations not
1604mentioned here will be handled by `tramp-file-name-handler-alist' or the
1605normal Emacs functions.")
1606
fb7933a3
KG
1607;;; Internal functions which must come first.
1608
1609(defsubst tramp-message (level fmt-string &rest args)
1610 "Emit a message depending on verbosity level.
1611First arg LEVEL says to be quiet if `tramp-verbose' is less than LEVEL. The
1612message is emitted only if `tramp-verbose' is greater than or equal to LEVEL.
1613Calls function `message' with FMT-STRING as control string and the remaining
1614ARGS to actually emit the message (if applicable).
1615
1616This function expects to be called from the tramp buffer only!"
1617 (when (<= level tramp-verbose)
1618 (apply #'message (concat "tramp: " fmt-string) args)
1619 (when tramp-debug-buffer
1620 (save-excursion
1621 (set-buffer
1622 (tramp-get-debug-buffer
1623 tramp-current-multi-method tramp-current-method
1624 tramp-current-user tramp-current-host))
1625 (goto-char (point-max))
1626 (tramp-insert-with-face
1627 'italic
1628 (concat "# " (apply #'format fmt-string args) "\n"))))))
1629
1630(defun tramp-message-for-buffer
1631 (multi-method method user host level fmt-string &rest args)
1632 "Like `tramp-message' but temporarily switches to the tramp buffer.
1633First three args METHOD, USER, and HOST identify the tramp buffer to use,
1634remaining args passed to `tramp-message'."
1635 (save-excursion
1636 (set-buffer (tramp-get-buffer multi-method method user host))
1637 (apply 'tramp-message level fmt-string args)))
1638
1639(defsubst tramp-line-end-position nil
1640 "Return point at end of line.
1641Calls `line-end-position' or `point-at-eol' if defined, else
1642own implementation."
1643 (cond
1644 ((fboundp 'line-end-position) (funcall 'line-end-position))
1645 ((fboundp 'point-at-eol) (funcall 'point-at-eol))
1646 (t (save-excursion (end-of-line) (point)))))
1647
c62c9d08
KG
1648(defmacro with-parsed-tramp-file-name (filename var &rest body)
1649 "Parse a Tramp filename and make components available in the body.
1650
1651First arg FILENAME is evaluated and dissected into its components.
1652Second arg VAR is a symbol. It is used as a variable name to hold
1653the filename structure. It is also used as a prefix for the variables
1654holding the components. For example, if VAR is the symbol `foo', then
1655`foo' will be bound to the whole structure, `foo-multi-method' will
1656be bound to the multi-method component, and so on for `foo-method',
1657`foo-user', `foo-host', `foo-path'.
1658
1659Remaining args are Lisp expressions to be evaluated (inside an implicit
1660`progn').
1661
1662If VAR is nil, then we bind `v' to the structure and `multi-method',
1663`method', `user', `host', `path' to the components."
1664 `(let* ((,(or var 'v) (tramp-dissect-file-name ,filename))
1665 (,(if var (intern (concat (symbol-name var) "-multi-method")) 'multi-method)
1666 (tramp-file-name-multi-method ,(or var 'v)))
1667 (,(if var (intern (concat (symbol-name var) "-method")) 'method)
1668 (tramp-file-name-method ,(or var 'v)))
1669 (,(if var (intern (concat (symbol-name var) "-user")) 'user)
1670 (tramp-file-name-user ,(or var 'v)))
1671 (,(if var (intern (concat (symbol-name var) "-host")) 'host)
1672 (tramp-file-name-host ,(or var 'v)))
1673 (,(if var (intern (concat (symbol-name var) "-path")) 'path)
1674 (tramp-file-name-path ,(or var 'v))))
1675 ,@body))
1676
1677(put 'with-parsed-tramp-file-name 'lisp-indent-function 2)
1678
16674e4f
KG
1679;;; Config Manipulation Functions:
1680
1681(defun tramp-set-completion-function (method function-list)
1682 "Sets the list of completion functions for METHOD.
1683FUNCTION-LIST is a list of entries of the form (FUNCTION FILE).
1684The FUNCTION is intended to parse FILE according its syntax.
1685It might be a predefined FUNCTION, or a user defined FUNCTION.
1686Predefined FUNCTIONs are `tramp-parse-rhosts', `tramp-parse-shosts',
1687`tramp-parse-hosts', and `tramp-parse-passwd'.
1688Example:
1689
1690 (tramp-set-completion-function
1691 \"ssh\"
1692 '((tramp-parse-shosts \"/etc/ssh_known_hosts\")
1693 (tramp-parse-shosts \"~/.ssh/known_hosts\")))"
1694
1695 (let ((v (cdr (assoc method tramp-completion-function-alist))))
1696 (when v (setcdr v function-list))))
1697
1698(defun tramp-get-completion-function (method)
1699 "Returns list of completion functions for METHOD.
1700For definition of that list see `tramp-set-completion-function'."
1701 (cdr (assoc method tramp-completion-function-alist)))
1702
fb7933a3
KG
1703;;; File Name Handler Functions:
1704
fb7933a3
KG
1705(defun tramp-handle-make-symbolic-link
1706 (filename linkname &optional ok-if-already-exists)
1707 "Like `make-symbolic-link' for tramp files.
cebb4ec6
KG
1708If LINKNAME is a non-Tramp file, it is used verbatim as the target of
1709the symlink. If LINKNAME is a Tramp file, only the path component is
1710used as the target of the symlink.
1711
1712If LINKNAME is a Tramp file and the path component is relative, then
1713it is expanded first, before the path component is taken. Note that
1714this can give surprising results if the user/host for the source and
1715target of the symlink differ."
c62c9d08 1716 (with-parsed-tramp-file-name linkname l
3b89d388 1717 (when (tramp-ange-ftp-file-name-p l-multi-method l-method l-user l-host)
c62c9d08
KG
1718 (tramp-invoke-ange-ftp 'make-symbolic-link
1719 filename linkname ok-if-already-exists))
487fa986 1720 (let ((ln (tramp-get-remote-ln l-multi-method l-method l-user l-host))
c62c9d08
KG
1721 (cwd (file-name-directory l-path)))
1722 (unless ln
1723 (signal 'file-error
1724 (list "Making a symbolic link."
1725 "ln(1) does not exist on the remote host.")))
1726
1727 ;; Do the 'confirm if exists' thing.
cebb4ec6 1728 (when (file-exists-p linkname)
c62c9d08
KG
1729 ;; What to do?
1730 (if (or (null ok-if-already-exists) ; not allowed to exist
1731 (and (numberp ok-if-already-exists)
1732 (not (yes-or-no-p
1733 (format
1734 "File %s already exists; make it a link anyway? "
1735 l-path)))))
cebb4ec6
KG
1736 (signal 'file-already-exists (list "File already exists" l-path))
1737 (delete-file linkname)))
1738
1739 ;; If FILENAME is a Tramp name, use just the path component.
1740 (when (tramp-tramp-file-p filename)
1741 (setq filename (tramp-file-name-path
1742 (tramp-dissect-file-name
1743 (expand-file-name filename)))))
fb7933a3 1744
c62c9d08
KG
1745 ;; Right, they are on the same host, regardless of user, method, etc.
1746 ;; We now make the link on the remote machine. This will occur as the user
1747 ;; that FILENAME belongs to.
1748 (zerop
1749 (tramp-send-command-and-check
487fa986 1750 l-multi-method l-method l-user l-host
c62c9d08
KG
1751 (format "cd %s && %s -sf %s %s"
1752 cwd ln
cebb4ec6
KG
1753 filename
1754 l-path)
c62c9d08 1755 t)))))
fb7933a3
KG
1756
1757
1758(defun tramp-handle-load (file &optional noerror nomessage nosuffix must-suffix)
1759 "Like `load' for tramp files. Not implemented!"
1760 (unless (file-name-absolute-p file)
1761 (error "Tramp cannot `load' files without absolute path name"))
c62c9d08 1762 (with-parsed-tramp-file-name file nil
3b89d388 1763 (when (tramp-ange-ftp-file-name-p multi-method method user host)
c62c9d08
KG
1764 (tramp-invoke-ange-ftp 'load
1765 file noerror nomessage nosuffix must-suffix))
1766 (unless nosuffix
1767 (cond ((file-exists-p (concat file ".elc"))
1768 (setq file (concat file ".elc")))
1769 ((file-exists-p (concat file ".el"))
1770 (setq file (concat file ".el")))))
1771 (when must-suffix
1772 ;; The first condition is always true for absolute file names.
1773 ;; Included for safety's sake.
1774 (unless (or (file-name-directory file)
1775 (string-match "\\.elc?\\'" file))
1776 (error "File `%s' does not include a `.el' or `.elc' suffix"
1777 file)))
1778 (unless noerror
1779 (when (not (file-exists-p file))
1780 (error "Cannot load nonexistant file `%s'" file)))
1781 (if (not (file-exists-p file))
1782 nil
1783 (unless nomessage
1784 (message "Loading %s..." file))
1785 (let ((local-copy (file-local-copy file)))
1786 ;; MUST-SUFFIX doesn't exist on XEmacs, so let it default to nil.
1787 (load local-copy noerror t t)
1788 (delete-file local-copy))
1789 (unless nomessage
1790 (message "Loading %s...done" file))
1791 t)))
fb7933a3
KG
1792
1793;; Path manipulation functions that grok TRAMP paths...
1794(defun tramp-handle-file-name-directory (file)
1795 "Like `file-name-directory' but aware of TRAMP files."
1796 ;; everything except the last filename thing is the directory
c62c9d08 1797 (with-parsed-tramp-file-name file nil
3b89d388 1798 (when (tramp-ange-ftp-file-name-p multi-method method user host)
c62c9d08 1799 (tramp-invoke-ange-ftp 'file-name-directory file))
505edaeb
KG
1800 ;; For the following condition, two possibilities should be tried:
1801 ;; (1) (string= path "")
1802 ;; (2) (or (string= path "") (string= path "/"))
1803 ;; The second variant fails when completing a "/" directory on
1804 ;; the remote host, that is a filename which looks like
1805 ;; "/user@host:/". But maybe wildcards fail with the first variant.
1806 ;; We should do some investigation.
1807 (if (string= path "")
fb7933a3
KG
1808 ;; For a filename like "/[foo]", we return "/". The `else'
1809 ;; case would return "/[foo]" unchanged. But if we do that,
1810 ;; then `file-expand-wildcards' ceases to work. It's not
1811 ;; quite clear to me what's the intuition that tells that this
1812 ;; behavior is the right behavior, but oh, well.
1813 "/"
1814 ;; run the command on the path portion only
1815 ;; CCC: This should take into account the remote machine type, no?
1816 ;; --daniel <daniel@danann.net>
1817 (tramp-make-tramp-file-name multi-method method user host
1818 ;; This will not recurse...
1819 (or (file-name-directory path) "")))))
1820
1821(defun tramp-handle-file-name-nondirectory (file)
1822 "Like `file-name-nondirectory' but aware of TRAMP files."
c62c9d08 1823 (with-parsed-tramp-file-name file nil
3b89d388 1824 (when (tramp-ange-ftp-file-name-p multi-method method user host)
c62c9d08
KG
1825 (tramp-invoke-ange-ftp 'file-name-nondirectory file))
1826 (file-name-nondirectory path)))
fb7933a3
KG
1827
1828(defun tramp-handle-file-truename (filename &optional counter prev-dirs)
1829 "Like `file-truename' for tramp files."
c62c9d08 1830 (with-parsed-tramp-file-name filename nil
b1d06e75
KG
1831 ;; Ange-FTP does not support truename processing, but for
1832 ;; convenience we pretend it did and forward the call to Ange-FTP
1833 ;; anyway. Ange-FTP then just invokes `identity'.
3b89d388 1834 (when (tramp-ange-ftp-file-name-p multi-method method user host)
b1d06e75 1835 (tramp-invoke-ange-ftp 'file-truename filename))
c62c9d08
KG
1836 (let* ((steps (tramp-split-string path "/"))
1837 (pathdir (let ((directory-sep-char ?/))
1838 (file-name-as-directory path)))
1839 (is-dir (string= path pathdir))
1840 (thisstep nil)
1841 (numchase 0)
1842 ;; Don't make the following value larger than necessary.
1843 ;; People expect an error message in a timely fashion when
1844 ;; something is wrong; otherwise they might think that Emacs
1845 ;; is hung. Of course, correctness has to come first.
1846 (numchase-limit 20)
1847 (result nil) ;result steps in reverse order
c62c9d08 1848 symlink-target)
fb7933a3
KG
1849 (tramp-message-for-buffer
1850 multi-method method user host
c62c9d08
KG
1851 10 "Finding true name for `%s'" filename)
1852 (while (and steps (< numchase numchase-limit))
1853 (setq thisstep (pop steps))
1854 (tramp-message-for-buffer
1855 multi-method method user host
1856 10 "Check %s"
1857 (mapconcat 'identity
1858 (append '("") (reverse result) (list thisstep))
1859 "/"))
1860 (setq symlink-target
1861 (nth 0 (tramp-handle-file-attributes
1862 (tramp-make-tramp-file-name
1863 multi-method method user host
1864 (mapconcat 'identity
b1d06e75
KG
1865 (append '("")
1866 (reverse result)
1867 (list thisstep))
c62c9d08
KG
1868 "/")))))
1869 (cond ((string= "." thisstep)
1870 (tramp-message-for-buffer multi-method method user host
1871 10 "Ignoring step `.'"))
1872 ((string= ".." thisstep)
1873 (tramp-message-for-buffer multi-method method user host
1874 10 "Processing step `..'")
1875 (pop result))
1876 ((stringp symlink-target)
1877 ;; It's a symlink, follow it.
1878 (tramp-message-for-buffer
1879 multi-method method user host
1880 10 "Follow symlink to %s" symlink-target)
1881 (setq numchase (1+ numchase))
1882 (when (file-name-absolute-p symlink-target)
1883 (setq result nil))
1884 (setq steps
1885 (append (tramp-split-string symlink-target "/") steps)))
1886 (t
1887 ;; It's a file.
1888 (setq result (cons thisstep result)))))
1889 (when (>= numchase numchase-limit)
1890 (error "Maximum number (%d) of symlinks exceeded" numchase-limit))
1891 (setq result (reverse result))
1892 (tramp-message-for-buffer
1893 multi-method method user host
1894 10 "True name of `%s' is `%s'"
1895 filename (mapconcat 'identity (cons "" result) "/"))
1896 (tramp-make-tramp-file-name
1897 multi-method method user host
1898 (concat (mapconcat 'identity (cons "" result) "/")
1899 (if is-dir "/" ""))))))
fb7933a3
KG
1900
1901;; Basic functions.
1902
1903(defun tramp-handle-file-exists-p (filename)
1904 "Like `file-exists-p' for tramp files."
c62c9d08 1905 (with-parsed-tramp-file-name filename nil
3b89d388 1906 (when (tramp-ange-ftp-file-name-p multi-method method user host)
c62c9d08 1907 (tramp-invoke-ange-ftp 'file-exists-p filename))
fb7933a3
KG
1908 (save-excursion
1909 (zerop (tramp-send-command-and-check
1910 multi-method method user host
1911 (format
c62c9d08
KG
1912 (tramp-get-file-exists-command multi-method method user host)
1913 (tramp-shell-quote-argument path)))))))
fb7933a3
KG
1914
1915;; CCC: This should check for an error condition and signal failure
1916;; when something goes wrong.
1917;; Daniel Pittman <daniel@danann.net>
1918(defun tramp-handle-file-attributes (filename &optional nonnumeric)
1919 "Like `file-attributes' for tramp files.
1920Optional argument NONNUMERIC means return user and group name
1921rather than as numbers."
ac474af1
KG
1922 (let (result)
1923 (with-parsed-tramp-file-name filename nil
3b89d388 1924 (when (tramp-ange-ftp-file-name-p multi-method method user host)
ac474af1
KG
1925 (tramp-invoke-ange-ftp 'file-attributes filename))
1926 (when (tramp-handle-file-exists-p filename)
1927 ;; file exists, find out stuff
1928 (save-excursion
fb7933a3 1929 (if (tramp-get-remote-perl multi-method method user host)
ac474af1
KG
1930 (setq result
1931 (tramp-handle-file-attributes-with-perl
1932 multi-method method user host path nonnumeric))
1933 (setq result
1934 (tramp-handle-file-attributes-with-ls
1935 multi-method method user host path nonnumeric))))))
1936 result))
fb7933a3
KG
1937
1938
1939(defun tramp-handle-file-attributes-with-ls
1940 (multi-method method user host path &optional nonnumeric)
1941 "Implement `file-attributes' for tramp files using the ls(1) command."
1942 (let (symlinkp dirp
1943 res-inode res-filemodes res-numlinks
1944 res-uid res-gid res-size res-symlink-target)
ac474af1
KG
1945 (tramp-message-for-buffer multi-method method user host 10
1946 "file attributes with ls: %s"
1947 (tramp-make-tramp-file-name
1948 multi-method method user host path))
fb7933a3
KG
1949 (tramp-send-command
1950 multi-method method user host
1951 (format "%s %s %s"
1952 (tramp-get-ls-command multi-method method user host)
1953 (if nonnumeric "-ild" "-ildn")
1954 (tramp-shell-quote-argument path)))
1955 (tramp-wait-for-output)
1956 ;; parse `ls -l' output ...
1957 ;; ... inode
1958 (setq res-inode
1959 (condition-case err
1960 (read (current-buffer))
1961 (invalid-read-syntax
1962 (when (and (equal (cadr err)
1963 "Integer constant overflow in reader")
1964 (string-match
1965 "^[0-9]+\\([0-9][0-9][0-9][0-9][0-9]\\)\\'"
1966 (caddr err)))
1967 (let* ((big (read (substring (caddr err) 0
1968 (match-beginning 1))))
1969 (small (read (match-string 1 (caddr err))))
1970 (twiddle (/ small 65536)))
1971 (cons (+ big twiddle)
1972 (- small (* twiddle 65536))))))))
1973 ;; ... file mode flags
1974 (setq res-filemodes (symbol-name (read (current-buffer))))
1975 ;; ... number links
1976 (setq res-numlinks (read (current-buffer)))
1977 ;; ... uid and gid
1978 (setq res-uid (read (current-buffer)))
1979 (setq res-gid (read (current-buffer)))
1980 (unless nonnumeric
1981 (unless (numberp res-uid) (setq res-uid -1))
1982 (unless (numberp res-gid) (setq res-gid -1)))
1983 ;; ... size
1984 (setq res-size (read (current-buffer)))
1985 ;; From the file modes, figure out other stuff.
1986 (setq symlinkp (eq ?l (aref res-filemodes 0)))
1987 (setq dirp (eq ?d (aref res-filemodes 0)))
1988 ;; if symlink, find out file name pointed to
1989 (when symlinkp
1990 (search-forward "-> ")
1991 (setq res-symlink-target
1992 (buffer-substring (point)
1993 (tramp-line-end-position))))
1994 ;; return data gathered
1995 (list
1996 ;; 0. t for directory, string (name linked to) for symbolic
1997 ;; link, or nil.
1998 (or dirp res-symlink-target nil)
1999 ;; 1. Number of links to file.
2000 res-numlinks
2001 ;; 2. File uid.
2002 res-uid
2003 ;; 3. File gid.
2004 res-gid
2005 ;; 4. Last access time, as a list of two integers. First
2006 ;; integer has high-order 16 bits of time, second has low 16
2007 ;; bits.
2008 ;; 5. Last modification time, likewise.
2009 ;; 6. Last status change time, likewise.
2010 '(0 0) '(0 0) '(0 0) ;CCC how to find out?
2011 ;; 7. Size in bytes (-1, if number is out of range).
2012 res-size
2013 ;; 8. File modes, as a string of ten letters or dashes as in ls -l.
2014 res-filemodes
2015 ;; 9. t iff file's gid would change if file were deleted and
2016 ;; recreated.
2017 nil ;hm?
2018 ;; 10. inode number.
2019 res-inode
2020 ;; 11. Device number.
2021 -1 ;hm?
2022 )))
2023
2024(defun tramp-handle-file-attributes-with-perl
2025 (multi-method method user host path &optional nonnumeric)
2026 "Implement `file-attributes' for tramp files using a Perl script.
2027
2028The Perl command is sent to the remote machine when the connection
2029is initially created and is kept cached by the remote shell."
ac474af1
KG
2030 (tramp-message-for-buffer multi-method method user host 10
2031 "file attributes with perl: %s"
2032 (tramp-make-tramp-file-name
2033 multi-method method user host path))
fb7933a3
KG
2034 (tramp-send-command
2035 multi-method method user host
2036 (format "tramp_file_attributes %s"
2037 (tramp-shell-quote-argument path)))
2038 (tramp-wait-for-output)
2039 (let ((result (read (current-buffer))))
2040 (setcar (nthcdr 8 result)
2041 (tramp-file-mode-from-int (nth 8 result)))
2042 result))
2043
2044(defun tramp-handle-set-visited-file-modtime (&optional time-list)
2045 "Like `set-visited-file-modtime' for tramp files."
2046 (unless (buffer-file-name)
2047 (error "Can't set-visited-file-modtime: buffer `%s' not visiting a file"
2048 (buffer-name)))
2049 (when time-list
2050 (tramp-run-real-handler 'set-visited-file-modtime (list time-list)))
c62c9d08
KG
2051 (let ((f (buffer-file-name))
2052 (coding-system-used nil))
2053 (with-parsed-tramp-file-name f nil
b1d06e75
KG
2054 ;; This operation is not handled by Ange-FTP! Compare this
2055 ;; behavior with `file-truename' which Ange-FTP does not really
2056 ;; handle, either, but at least it pretends to. I wonder if
2057 ;; Ange-FTP should also pretend to grok
2058 ;; `set-visited-file-modtime', for consistency?
3b89d388 2059 (when (tramp-ange-ftp-file-name-p multi-method method user host)
c62c9d08
KG
2060 (throw 'tramp-forward-to-ange-ftp
2061 (tramp-run-real-handler 'set-visited-file-modtime
2062 (list time-list))))
2063 (let* ((attr (file-attributes f))
2064 (modtime (nth 5 attr)))
2065 ;; We use '(0 0) as a don't-know value. See also
2066 ;; `tramp-handle-file-attributes-with-ls'.
2067 (when (boundp 'last-coding-system-used)
2068 (setq coding-system-used last-coding-system-used))
fb7933a3 2069 (if (not (equal modtime '(0 0)))
c62c9d08 2070 (tramp-run-real-handler 'set-visited-file-modtime (list modtime))
fb7933a3
KG
2071 (save-excursion
2072 (tramp-send-command
2073 multi-method method user host
2074 (format "%s -ild %s"
2075 (tramp-get-ls-command multi-method method user host)
2076 (tramp-shell-quote-argument path)))
2077 (tramp-wait-for-output)
2078 (setq attr (buffer-substring (point)
2079 (progn (end-of-line) (point)))))
c62c9d08
KG
2080 (setq tramp-buffer-file-attributes attr))
2081 (when (boundp 'last-coding-system-used)
2082 (setq last-coding-system-used coding-system-used))
fb7933a3
KG
2083 nil))))
2084
c62c9d08
KG
2085;; CCC continue here
2086
2087;; This function makes the same assumption as
2088;; `tramp-handle-set-visited-file-modtime'.
2089(defun tramp-handle-verify-visited-file-modtime (buf)
2090 "Like `verify-visited-file-modtime' for tramp files."
2091 (with-current-buffer buf
2092 (let ((f (buffer-file-name)))
2093 (with-parsed-tramp-file-name f nil
3b89d388 2094 (when (tramp-ange-ftp-file-name-p multi-method method user host)
c62c9d08
KG
2095 ;; This one requires a hack since the file name is not passed
2096 ;; on the arg list.
2097 (let ((buffer-file-name (tramp-make-ange-ftp-file-name
2098 user host path)))
2099 (tramp-invoke-ange-ftp 'verify-visited-file-modtime buf)))
2100 (let* ((attr (file-attributes f))
2101 (modtime (nth 5 attr)))
2102 (cond ((and attr (not (equal modtime '(0 0))))
2103 ;; Why does `file-attributes' return a list (HIGH
2104 ;; LOW), but `visited-file-modtime' returns a cons
2105 ;; (HIGH . LOW)?
2106 (let ((mt (visited-file-modtime)))
2107 (< (abs (tramp-time-diff
2108 modtime (list (car mt) (cdr mt)))) 2)))
2109 (attr
2110 (save-excursion
2111 (tramp-send-command
2112 multi-method method user host
2113 (format "%s -ild %s"
2114 (tramp-get-ls-command multi-method method
2115 user host)
2116 (tramp-shell-quote-argument path)))
2117 (tramp-wait-for-output)
2118 (setq attr (buffer-substring
2119 (point) (progn (end-of-line) (point)))))
2120 (equal tramp-buffer-file-attributes attr))
2121 ;; If file does not exist, say it is not modified.
487fa986 2122 (t nil)))))))
c62c9d08 2123
fb7933a3
KG
2124(defadvice clear-visited-file-modtime (after tramp activate)
2125 "Set `tramp-buffer-file-attributes' back to nil.
2126Tramp uses this variable as an emulation for the actual modtime of the file,
2127if the remote host can't provide the modtime."
2128 (setq tramp-buffer-file-attributes nil))
2129
2130(defun tramp-handle-set-file-modes (filename mode)
2131 "Like `set-file-modes' for tramp files."
c62c9d08 2132 (with-parsed-tramp-file-name filename nil
3b89d388 2133 (when (tramp-ange-ftp-file-name-p multi-method method user host)
dba28077 2134 (tramp-invoke-ange-ftp 'set-file-modes mode filename))
fb7933a3
KG
2135 (save-excursion
2136 (unless (zerop (tramp-send-command-and-check
c62c9d08
KG
2137 multi-method method user host
2138 (format "chmod %s %s"
2139 (tramp-decimal-to-octal mode)
2140 (tramp-shell-quote-argument path))))
fb7933a3
KG
2141 (signal 'file-error
2142 (list "Doing chmod"
2143 ;; FIXME: extract the proper text from chmod's stderr.
2144 "error while changing file's mode"
2145 filename))))))
2146
2147;; Simple functions using the `test' command.
2148
2149(defun tramp-handle-file-executable-p (filename)
2150 "Like `file-executable-p' for tramp files."
c62c9d08 2151 (with-parsed-tramp-file-name filename nil
3b89d388 2152 (when (tramp-ange-ftp-file-name-p multi-method method user host)
c62c9d08
KG
2153 (tramp-invoke-ange-ftp 'file-executable-p filename))
2154 (zerop (tramp-run-test "-x" filename))))
fb7933a3
KG
2155
2156(defun tramp-handle-file-readable-p (filename)
2157 "Like `file-readable-p' for tramp files."
c62c9d08 2158 (with-parsed-tramp-file-name filename nil
3b89d388 2159 (when (tramp-ange-ftp-file-name-p multi-method method user host)
c62c9d08
KG
2160 (tramp-invoke-ange-ftp 'file-readable-p filename))
2161 (zerop (tramp-run-test "-r" filename))))
fb7933a3
KG
2162
2163(defun tramp-handle-file-accessible-directory-p (filename)
2164 "Like `file-accessible-directory-p' for tramp files."
c62c9d08 2165 (with-parsed-tramp-file-name filename nil
3b89d388 2166 (when (tramp-ange-ftp-file-name-p multi-method method user host)
c62c9d08
KG
2167 (tramp-invoke-ange-ftp 'file-accessible-directory-p filename))
2168 (and (zerop (tramp-run-test "-d" filename))
2169 (zerop (tramp-run-test "-r" filename))
2170 (zerop (tramp-run-test "-x" filename)))))
fb7933a3
KG
2171
2172;; When the remote shell is started, it looks for a shell which groks
2173;; tilde expansion. Here, we assume that all shells which grok tilde
2174;; expansion will also provide a `test' command which groks `-nt' (for
2175;; newer than). If this breaks, tell me about it and I'll try to do
2176;; something smarter about it.
2177(defun tramp-handle-file-newer-than-file-p (file1 file2)
2178 "Like `file-newer-than-file-p' for tramp files."
2179 (cond ((not (file-exists-p file1))
2180 nil)
2181 ((not (file-exists-p file2))
2182 t)
91879624 2183 ;; We are sure both files exist at this point.
fb7933a3
KG
2184 (t
2185 (save-excursion
91879624
KG
2186 ;; We try to get the mtime of both files. If they are not
2187 ;; equal to the "dont-know" value, then we subtract the times
2188 ;; and obtain the result.
2189 (let ((fa1 (file-attributes file1))
2190 (fa2 (file-attributes file2)))
2191 (if (and (not (equal (nth 5 fa1) '(0 0)))
2192 (not (equal (nth 5 fa2) '(0 0))))
2193 (> 0 (car (subtract-time (nth 5 fa1) (nth 5 fa2))))
2194 ;; If one of them is the dont-know value, then we can
2195 ;; still try to run a shell command on the remote host.
2196 ;; However, this only works if both files are Tramp
2197 ;; files and both have the same method, same user, same
2198 ;; host.
c62c9d08
KG
2199 (unless (and (tramp-tramp-file-p file1)
2200 (tramp-tramp-file-p file2))
91879624
KG
2201 (signal
2202 'file-error
2203 (list
2204 "Cannot check if Tramp file is newer than non-Tramp file"
2205 file1 file2)))
2206 (with-parsed-tramp-file-name file1 v1
2207 (with-parsed-tramp-file-name file2 v2
2208 (when (and (tramp-ange-ftp-file-name-p
3b89d388 2209 v1-multi-method v1-method v1-user v1-host)
91879624 2210 (tramp-ange-ftp-file-name-p
3b89d388 2211 v2-multi-method v2-method v2-user v2-host))
91879624
KG
2212 (tramp-invoke-ange-ftp 'file-newer-than-file-p
2213 file1 file2))
2214 (unless (and (equal v1-multi-method v2-multi-method)
2215 (equal v1-method v2-method)
2216 (equal v1-user v2-user)
2217 (equal v1-host v2-host))
2218 (signal 'file-error
2219 (list "Files must have same method, user, host"
2220 file1 file2)))
2221 (unless (and (tramp-tramp-file-p file1)
2222 (tramp-tramp-file-p file2))
2223 (signal 'file-error
2224 (list "Files must be tramp files on same host"
2225 file1 file2)))
2226 (if (tramp-get-test-groks-nt
2227 v1-multi-method v1-method v1-user v1-host)
2228 (zerop (tramp-run-test2 "test" file1 file2 "-nt"))
2229 (zerop (tramp-run-test2
2230 "tramp_test_nt" file1 file2)))))))))))
fb7933a3
KG
2231
2232;; Functions implemented using the basic functions above.
2233
2234(defun tramp-handle-file-modes (filename)
2235 "Like `file-modes' for tramp files."
c62c9d08 2236 (with-parsed-tramp-file-name filename nil
3b89d388 2237 (when (tramp-ange-ftp-file-name-p multi-method method user host)
c62c9d08
KG
2238 (tramp-invoke-ange-ftp 'file-modes filename))
2239 (when (file-exists-p filename)
2240 (tramp-mode-string-to-int
2241 (nth 8 (tramp-handle-file-attributes filename))))))
fb7933a3
KG
2242
2243(defun tramp-handle-file-directory-p (filename)
2244 "Like `file-directory-p' for tramp files."
2245 ;; Care must be taken that this function returns `t' for symlinks
2246 ;; pointing to directories. Surely the most obvious implementation
2247 ;; would be `test -d', but that returns false for such symlinks.
2248 ;; CCC: Stefan Monnier says that `test -d' follows symlinks. And
2249 ;; I now think he's right. So we could be using `test -d', couldn't
2250 ;; we?
2251 ;;
2252 ;; Alternatives: `cd %s', `test -d %s'
c62c9d08 2253 (with-parsed-tramp-file-name filename nil
3b89d388 2254 (when (tramp-ange-ftp-file-name-p multi-method method user host)
c62c9d08
KG
2255 (tramp-invoke-ange-ftp 'file-directory-p filename))
2256 (save-excursion
fb7933a3
KG
2257 (zerop
2258 (tramp-send-command-and-check
c62c9d08
KG
2259 multi-method method user host
2260 (format "test -d %s"
2261 (tramp-shell-quote-argument path))
2262 t))))) ;run command in subshell
fb7933a3
KG
2263
2264(defun tramp-handle-file-regular-p (filename)
2265 "Like `file-regular-p' for tramp files."
c62c9d08 2266 (with-parsed-tramp-file-name filename nil
3b89d388 2267 (when (tramp-ange-ftp-file-name-p multi-method method user host)
c62c9d08
KG
2268 (tramp-invoke-ange-ftp 'file-regular-p filename))
2269 (and (tramp-handle-file-exists-p filename)
2270 (eq ?- (aref (nth 8 (tramp-handle-file-attributes filename)) 0)))))
fb7933a3
KG
2271
2272(defun tramp-handle-file-symlink-p (filename)
2273 "Like `file-symlink-p' for tramp files."
c62c9d08 2274 (with-parsed-tramp-file-name filename nil
3b89d388 2275 (when (tramp-ange-ftp-file-name-p multi-method method user host)
c62c9d08
KG
2276 (tramp-invoke-ange-ftp 'file-symlink-p filename))
2277 (let ((x (car (tramp-handle-file-attributes filename))))
2278 (when (stringp x) x))))
fb7933a3
KG
2279
2280(defun tramp-handle-file-writable-p (filename)
2281 "Like `file-writable-p' for tramp files."
c62c9d08 2282 (with-parsed-tramp-file-name filename nil
3b89d388 2283 (when (tramp-ange-ftp-file-name-p multi-method method user host)
c62c9d08
KG
2284 (tramp-invoke-ange-ftp 'file-writable-p filename))
2285 (if (tramp-handle-file-exists-p filename)
2286 ;; Existing files must be writable.
2287 (zerop (tramp-run-test "-w" filename))
2288 ;; If file doesn't exist, check if directory is writable.
2289 (and (zerop (tramp-run-test
2290 "-d" (tramp-handle-file-name-directory filename)))
2291 (zerop (tramp-run-test
2292 "-w" (tramp-handle-file-name-directory filename)))))))
fb7933a3
KG
2293
2294(defun tramp-handle-file-ownership-preserved-p (filename)
2295 "Like `file-ownership-preserved-p' for tramp files."
c62c9d08 2296 (with-parsed-tramp-file-name filename nil
3b89d388 2297 (when (tramp-ange-ftp-file-name-p multi-method method user host)
c62c9d08
KG
2298 (tramp-invoke-ange-ftp 'file-ownership-preserved-p filename))
2299 (or (not (tramp-handle-file-exists-p filename))
2300 ;; Existing files must be writable.
2301 (zerop (tramp-run-test "-O" filename)))))
fb7933a3
KG
2302
2303;; Other file name ops.
2304
2305