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