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