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