comparison lisp/net/tramp.el @ 49995:a0e8a85259ed

Version 2.0.30 released. Replace term "path" with "localname" unless it is used for a search path. (tramp-handle-expand-file-name): Allow ".." to cross host boundaries. (tramp-open-connection-setup-interactive-shell): Unset $ENV in addition to setting $PS1 when starting the Bourne-ish shell. Some sh implementations (eg, bash when called as sh) read the file named there on startup, which could clobber $PS1. (tramp-do-copy-or-rename-file-one-local): New function. Not implemented. Not used. Should invoke rcp or scp directly to keep the time.
author Kai Großjohann <kgrossjo@eu.uu.net>
date Fri, 28 Feb 2003 18:28:47 +0000
parents 407d6516031a
children 155b4b78aa3b
comparison
equal deleted inserted replaced
49994:dcf78d005b68 49995:a0e8a85259ed
1 ;;; tramp.el --- Transparent Remote Access, Multiple Protocol -*- coding: iso-8859-1; -*- 1 ;;; tramp.el --- Transparent Remote Access, Multiple Protocol -*- coding: iso-8859-1; -*-
2 2
3 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. 3 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
4 4
5 ;; Author: Kai.Grossjohann@CS.Uni-Dortmund.DE 5 ;; Author: Kai.Grossjohann@CS.Uni-Dortmund.DE
6 ;; Keywords: comm, processes 6 ;; Keywords: comm, processes
7 7
8 ;; This file is part of GNU Emacs. 8 ;; This file is part of GNU Emacs.
9 9
10 ;; GNU Emacs is free software; you can redistribute it and/or modify 10 ;; GNU Emacs is free software; you can redistribute it and/or modify
32 ;; For more detailed instructions, please see the info file, which is 32 ;; For more detailed instructions, please see the info file, which is
33 ;; included in the file `tramp.tar.gz' mentioned below. 33 ;; included in the file `tramp.tar.gz' mentioned below.
34 ;; 34 ;;
35 ;; Notes: 35 ;; Notes:
36 ;; ----- 36 ;; -----
37 ;; 37 ;;
38 ;; This package only works for Emacs 20 and higher, and for XEmacs 21 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 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 40 ;; 19 is reported to have other problems. For XEmacs 21, you need the
41 ;; package `fsf-compat' for the `with-timeout' macro.) 41 ;; package `fsf-compat' for the `with-timeout' macro.)
42 ;; 42 ;;
70 ;;; Code: 70 ;;; Code:
71 71
72 ;; In the Tramp CVS repository, the version numer is auto-frobbed from 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 73 ;; the Makefile, so you should edit the top-level Makefile to change
74 ;; the version number. 74 ;; the version number.
75 (defconst tramp-version "2.0.29" 75 (defconst tramp-version "2.0.30"
76 "This version of tramp.") 76 "This version of tramp.")
77 77
78 (defconst tramp-bug-report-address "tramp-devel@mail.freesoftware.fsf.org" 78 (defconst tramp-bug-report-address "tramp-devel@mail.freesoftware.fsf.org"
79 "Email address to send bug reports to.") 79 "Email address to send bug reports to.")
80 80
93 "Implementation of `uuencode' in Lisp.") 93 "Implementation of `uuencode' in Lisp.")
94 94
95 (unless (fboundp 'uudecode-decode-region) 95 (unless (fboundp 'uudecode-decode-region)
96 (autoload 'uudecode-decode-region "uudecode")) 96 (autoload 'uudecode-decode-region "uudecode"))
97 97
98 ;; ;; It does not work to load EFS after loading TRAMP. 98 ;; ;; It does not work to load EFS after loading TRAMP.
99 ;; (when (fboundp 'efs-file-handler-function) 99 ;; (when (fboundp 'efs-file-handler-function)
100 ;; (require 'efs)) 100 ;; (require 'efs))
101 101
102 ;; Load foreign methods. Because they do require Tramp internally, this 102 ;; Load foreign methods. Because they do require Tramp internally, this
103 ;; must be done with the `eval-after-load' trick. 103 ;; must be done with the `eval-after-load' trick.
108 '(require 'tramp-ftp))) 108 '(require 'tramp-ftp)))
109 109
110 ;; tramp-smb uses "smbclient" from Samba. 110 ;; tramp-smb uses "smbclient" from Samba.
111 ;; Not available under Cygwin and Windows, because they don't offer 111 ;; Not available under Cygwin and Windows, because they don't offer
112 ;; "smbclient". And even not necessary there, because Emacs supports 112 ;; "smbclient". And even not necessary there, because Emacs supports
113 ;; UNC file names like "//host/share/path". 113 ;; UNC file names like "//host/share/localname".
114 (unless (memq system-type '(cygwin windows-nt)) 114 (unless (memq system-type '(cygwin windows-nt))
115 (eval-after-load "tramp" 115 (eval-after-load "tramp"
116 '(require 'tramp-smb))) 116 '(require 'tramp-smb)))
117 117
118 (eval-when-compile 118 (eval-when-compile
487 (tramp-rcp-keep-date-arg "-p") 487 (tramp-rcp-keep-date-arg "-p")
488 (tramp-su-program nil) 488 (tramp-su-program nil)
489 (tramp-su-args nil) 489 (tramp-su-args nil)
490 (tramp-telnet-program nil) 490 (tramp-telnet-program nil)
491 (tramp-telnet-args nil)) 491 (tramp-telnet-args nil))
492 ("fcp" 492 ("fcp"
493 (tramp-connection-function tramp-open-connection-rsh) 493 (tramp-connection-function tramp-open-connection-rsh)
494 (tramp-rsh-program "fsh") 494 (tramp-rsh-program "fsh")
495 (tramp-rcp-program "fcp") 495 (tramp-rcp-program "fcp")
496 (tramp-remote-sh "/bin/sh -i") 496 (tramp-remote-sh "/bin/sh -i")
497 (tramp-rsh-args ("sh" "-i")) 497 (tramp-rsh-args ("sh" "-i"))
518 which groks tilde expansion, but it can search for it. Also note 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 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. 520 the value that you decide to use. You Have Been Warned.
521 * `tramp-rsh-program' 521 * `tramp-rsh-program'
522 This specifies the name of the program to use for rsh; this might be 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. 523 the absolute filename of rsh or the name of a workalike program.
524 * `tramp-rsh-args' 524 * `tramp-rsh-args'
525 This specifies the list of arguments to pass to the above 525 This specifies the list of arguments to pass to the above
526 mentioned program. Please note that this is a list of arguments, 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\" 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 528 here. Instead, you want two list elements, one for \"-a\" and one
529 for \"-b\", or one for \"-f\" and one for \"foo\". 529 for \"-b\", or one for \"-f\" and one for \"foo\".
530 * `tramp-rcp-program' 530 * `tramp-rcp-program'
531 This specifies the name of the program to use for rcp; this might be 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. 532 the absolute filename of rcp or the name of a workalike program.
533 * `tramp-rcp-args' 533 * `tramp-rcp-args'
534 This specifies the list of parameters to pass to the above mentioned 534 This specifies the list of parameters to pass to the above mentioned
535 program, the hints for `tramp-rsh-args' also apply here. 535 program, the hints for `tramp-rsh-args' also apply here.
536 * `tramp-rcp-keep-date-arg' 536 * `tramp-rcp-keep-date-arg'
537 This specifies the parameter to use for `rcp' when the timestamp 537 This specifies the parameter to use for `rcp' when the timestamp
940 :group 'tramp 940 :group 'tramp
941 :type 'regexp) 941 :type 'regexp)
942 942
943 (defcustom tramp-postfix-multi-hop-format 943 (defcustom tramp-postfix-multi-hop-format
944 (if tramp-unified-filenames ":" "/") 944 (if tramp-unified-filenames ":" "/")
945 "*String matching delimeter between path and next method. 945 "*String matching delimeter between host and next method.
946 Applicable for multi-hop methods. 946 Applicable for multi-hop methods.
947 Used in `tramp-make-tramp-multi-file-name'." 947 Used in `tramp-make-tramp-multi-file-name'."
948 :group 'tramp 948 :group 'tramp
949 :type 'string) 949 :type 'string)
950 950
951 (defcustom tramp-postfix-multi-hop-regexp 951 (defcustom tramp-postfix-multi-hop-regexp
952 (regexp-quote tramp-postfix-multi-hop-format) 952 (regexp-quote tramp-postfix-multi-hop-format)
953 "*Regexp matching delimeter between path and next method. 953 "*Regexp matching delimeter between host and next method.
954 Applicable for multi-hop methods. 954 Applicable for multi-hop methods.
955 Derived from `tramp-postfix-multi-hop-format'." 955 Derived from `tramp-postfix-multi-hop-format'."
956 :group 'tramp 956 :group 'tramp
957 :type 'regexp) 957 :type 'regexp)
958 958
988 :group 'tramp 988 :group 'tramp
989 :type 'regexp) 989 :type 'regexp)
990 990
991 (defcustom tramp-postfix-host-format 991 (defcustom tramp-postfix-host-format
992 (if tramp-unified-filenames ":" "]") 992 (if tramp-unified-filenames ":" "]")
993 "*String matching delimeter between host names and paths. 993 "*String matching delimeter between host names and localnames.
994 Used in `tramp-make-tramp-file-name' and `tramp-make-tramp-multi-file-name'." 994 Used in `tramp-make-tramp-file-name' and `tramp-make-tramp-multi-file-name'."
995 :group 'tramp 995 :group 'tramp
996 :type 'string) 996 :type 'string)
997 997
998 (defcustom tramp-postfix-host-regexp 998 (defcustom tramp-postfix-host-regexp
999 (regexp-quote tramp-postfix-host-format) 999 (regexp-quote tramp-postfix-host-format)
1000 "*Regexp matching delimeter between host names and paths. 1000 "*Regexp matching delimeter between host names and localnames.
1001 Derived from `tramp-postfix-host-format'." 1001 Derived from `tramp-postfix-host-format'."
1002 :group 'tramp 1002 :group 'tramp
1003 :type 'regexp) 1003 :type 'regexp)
1004 1004
1005 (defcustom tramp-path-regexp 1005 (defcustom tramp-localname-regexp
1006 ".*$" 1006 ".*$"
1007 "*Regexp matching paths." 1007 "*Regexp matching localnames."
1008 :group 'tramp 1008 :group 'tramp
1009 :type 'regexp) 1009 :type 'regexp)
1010 1010
1011 ;; File name format. 1011 ;; File name format.
1012 1012
1015 (concat 1015 (concat
1016 tramp-prefix-regexp 1016 tramp-prefix-regexp
1017 "\\(" "\\(" tramp-method-regexp "\\)" tramp-postfix-single-method-regexp "\\)?" 1017 "\\(" "\\(" tramp-method-regexp "\\)" tramp-postfix-single-method-regexp "\\)?"
1018 "\\(" "\\(" tramp-user-regexp "\\)" tramp-postfix-user-regexp "\\)?" 1018 "\\(" "\\(" tramp-user-regexp "\\)" tramp-postfix-user-regexp "\\)?"
1019 "\\(" tramp-host-with-port-regexp "\\)" tramp-postfix-host-regexp 1019 "\\(" tramp-host-with-port-regexp "\\)" tramp-postfix-host-regexp
1020 "\\(" tramp-path-regexp "\\)") 1020 "\\(" tramp-localname-regexp "\\)")
1021 2 4 5 6) 1021 2 4 5 6)
1022 1022
1023 "*List of five elements (REGEXP METHOD USER HOST FILE), detailing \ 1023 "*List of five elements (REGEXP METHOD USER HOST FILE), detailing \
1024 the tramp file name structure. 1024 the tramp file name structure.
1025 1025
1113 (list 1113 (list
1114 (concat 1114 (concat
1115 tramp-prefix-regexp 1115 tramp-prefix-regexp
1116 "\\(" "\\(" tramp-method-regexp "\\)" "\\)?" 1116 "\\(" "\\(" tramp-method-regexp "\\)" "\\)?"
1117 "\\(" "\\(" tramp-postfix-multi-hop-regexp "%s" "\\)+" "\\)?" 1117 "\\(" "\\(" tramp-postfix-multi-hop-regexp "%s" "\\)+" "\\)?"
1118 tramp-postfix-host-regexp "\\(" tramp-path-regexp "\\)") 1118 tramp-postfix-host-regexp "\\(" tramp-localname-regexp "\\)")
1119 2 3 -1) 1119 2 3 -1)
1120 "*Describes the file name structure of `multi' files. 1120 "*Describes the file name structure of `multi' files.
1121 Multi files allow you to contact a remote host in several hops. 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). 1122 This is a list of four elements (REGEXP METHOD HOP LOCALNAME).
1123 1123
1124 The first element, REGEXP, gives a regular expression to match against 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 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 1126 value of `tramp-multi-file-name-hop-structure'. (Note: in order to
1127 allow multiple hops, you normally want to use something like 1127 allow multiple hops, you normally want to use something like
1128 \"\\\\(\\\\(%s\\\\)+\\\\)\" in the regular expression. The outer pair 1128 \"\\\\(\\\\(%s\\\\)+\\\\)\" in the regular expression. The outer pair
1129 of parentheses is used for the HOP element, see below.) 1129 of parentheses is used for the HOP element, see below.)
1130 1130
1131 All remaining elements are numbers. METHOD gives the number of the 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 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 1133 paren pair which matches the hop sequence. LOCALNAME gives the number of
1134 the paren pair which matches the path name on the remote host. 1134 the paren pair which matches the localname (pathname) on the remote host.
1135 1135
1136 PATH can also be negative, which means to count from the end. Ie, a 1136 LOCALNAME can also be negative, which means to count from the end. Ie, a
1137 value of -1 means the last paren pair. 1137 value of -1 means the last paren pair.
1138 1138
1139 I think it would be good if the regexp matches the whole of the 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..." 1140 string, but I haven't actually tried what happens if it doesn't..."
1141 :group 'tramp 1141 :group 'tramp
1142 :type '(list (regexp :tag "File name regexp") 1142 :type '(list (regexp :tag "File name regexp")
1143 (integer :tag "Paren pair for method name") 1143 (integer :tag "Paren pair for method name")
1144 (integer :tag "Paren pair for hops") 1144 (integer :tag "Paren pair for hops")
1145 (integer :tag "Paren pair to match path"))) 1145 (integer :tag "Paren pair to match localname")))
1146 1146
1147 (defcustom tramp-multi-file-name-hop-structure 1147 (defcustom tramp-multi-file-name-hop-structure
1148 (list 1148 (list
1149 (concat 1149 (concat
1150 "\\(" tramp-method-regexp "\\)" tramp-postfix-multi-method-regexp 1150 "\\(" tramp-method-regexp "\\)" tramp-postfix-multi-method-regexp
1171 "%m" tramp-postfix-multi-method-format 1171 "%m" tramp-postfix-multi-method-format
1172 "%u" tramp-postfix-user-format 1172 "%u" tramp-postfix-user-format
1173 "%h") 1173 "%h")
1174 (concat tramp-postfix-host-format "%p")) 1174 (concat tramp-postfix-host-format "%p"))
1175 "*Describes how to construct a `multi' file name. 1175 "*Describes how to construct a `multi' file name.
1176 This is a list of three elements PREFIX, HOP and PATH. 1176 This is a list of three elements PREFIX, HOP and LOCALNAME.
1177 1177
1178 The first element PREFIX says how to construct the prefix, the second 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 1179 element HOP specifies what each hop looks like, and the final element
1180 PATH says how to construct the path name. 1180 LOCALNAME says how to construct the localname (pathname).
1181 1181
1182 In PREFIX, `%%' means `%' and `%m' means the method name. 1182 In PREFIX, `%%' means `%' and `%m' means the method name.
1183 1183
1184 In HOP, `%%' means `%' and `%m', `%u', `%h' mean the hop method, hop 1184 In HOP, `%%' means `%' and `%m', `%u', `%h' mean the hop method, hop
1185 user and hop host, respectively. 1185 user and hop host, respectively.
1186 1186
1187 In PATH, `%%' means `%' and `%p' means the path name. 1187 In LOCALNAME, `%%' means `%' and `%p' means the localname.
1188 1188
1189 The resulting file name always contains one copy of PREFIX and one 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 1190 copy of LOCALNAME, but there is one copy of HOP for each hop in the file
1191 name. 1191 name.
1192 1192
1193 Note: the current implementation requires the prefix to contain the 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 1194 method name, followed by all the hops, and the localname must come
1195 last." 1195 last."
1196 :group 'tramp 1196 :group 'tramp
1197 :type '(list string string string)) 1197 :type '(list string string string))
1198 1198
1199 (defcustom tramp-terminal-type "dumb" 1199 (defcustom tramp-terminal-type "dumb"
1246 "List of pattern/action pairs. 1246 "List of pattern/action pairs.
1247 This list is used for each hop in multi-hop connections. 1247 This list is used for each hop in multi-hop connections.
1248 See `tramp-actions-before-shell' for more info." 1248 See `tramp-actions-before-shell' for more info."
1249 :group 'tramp 1249 :group 'tramp
1250 :type '(repeat (list variable function))) 1250 :type '(repeat (list variable function)))
1251
1252 ;; Chunked sending kluge. We set this to 500 for black-listed constellations
1253 ;; known to have a bug in `process-send-string'; some ssh connections appear
1254 ;; to drop bytes when data is sent too quickly.
1255 (defcustom tramp-chunksize
1256 (when (and (not (featurep 'xemacs))
1257 (memq system-type '(hpux)))
1258 500)
1259 "*If non-nil, chunksize for sending input to local process.
1260 It is necessary only on systems which have a buggy `process-send-string'
1261 implementation. The necessity, whether this variable must be set, can be
1262 checked via the following code:
1263
1264 (with-temp-buffer
1265 (let ((bytes 1000)
1266 (proc (start-process (buffer-name) (current-buffer) \"wc\" \"-c\")))
1267 (process-send-string proc (make-string bytes ?x))
1268 (process-send-eof proc)
1269 (process-send-eof proc)
1270 (accept-process-output proc 1)
1271 (goto-char (point-min))
1272 (re-search-forward \"\\\\w+\")
1273 (message \"Bytes sent: %s\\tBytes received: %s\" bytes (match-string 0))))
1274
1275 Please raise a bug report via \"M-x tramp-bug\" if your system needs
1276 this variable to be set as well."
1277 :group 'tramp
1278 :type 'integer)
1251 1279
1252 ;;; Internal Variables: 1280 ;;; Internal Variables:
1253 1281
1254 (defvar tramp-buffer-file-attributes nil 1282 (defvar tramp-buffer-file-attributes nil
1255 "Holds the `ls -ild' output for the current buffer. 1283 "Holds the `ls -ild' output for the current buffer.
1706 Second arg VAR is a symbol. It is used as a variable name to hold 1734 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 1735 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 1736 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 1737 `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', 1738 be bound to the multi-method component, and so on for `foo-method',
1711 `foo-user', `foo-host', `foo-path'. 1739 `foo-user', `foo-host', `foo-localname'.
1712 1740
1713 Remaining args are Lisp expressions to be evaluated (inside an implicit 1741 Remaining args are Lisp expressions to be evaluated (inside an implicit
1714 `progn'). 1742 `progn').
1715 1743
1716 If VAR is nil, then we bind `v' to the structure and `multi-method', 1744 If VAR is nil, then we bind `v' to the structure and `multi-method',
1717 `method', `user', `host', `path' to the components." 1745 `method', `user', `host', `localname' to the components."
1718 `(let* ((,(or var 'v) (tramp-dissect-file-name ,filename)) 1746 `(let* ((,(or var 'v) (tramp-dissect-file-name ,filename))
1719 (,(if var (intern (concat (symbol-name var) "-multi-method")) 'multi-method) 1747 (,(if var (intern (concat (symbol-name var) "-multi-method")) 'multi-method)
1720 (tramp-file-name-multi-method ,(or var 'v))) 1748 (tramp-file-name-multi-method ,(or var 'v)))
1721 (,(if var (intern (concat (symbol-name var) "-method")) 'method) 1749 (,(if var (intern (concat (symbol-name var) "-method")) 'method)
1722 (tramp-file-name-method ,(or var 'v))) 1750 (tramp-file-name-method ,(or var 'v)))
1723 (,(if var (intern (concat (symbol-name var) "-user")) 'user) 1751 (,(if var (intern (concat (symbol-name var) "-user")) 'user)
1724 (tramp-file-name-user ,(or var 'v))) 1752 (tramp-file-name-user ,(or var 'v)))
1725 (,(if var (intern (concat (symbol-name var) "-host")) 'host) 1753 (,(if var (intern (concat (symbol-name var) "-host")) 'host)
1726 (tramp-file-name-host ,(or var 'v))) 1754 (tramp-file-name-host ,(or var 'v)))
1727 (,(if var (intern (concat (symbol-name var) "-path")) 'path) 1755 (,(if var (intern (concat (symbol-name var) "-localname")) 'localname)
1728 (tramp-file-name-path ,(or var 'v)))) 1756 (tramp-file-name-localname ,(or var 'v))))
1729 ,@body)) 1757 ,@body))
1730 1758
1731 (put 'with-parsed-tramp-file-name 'lisp-indent-function 2) 1759 (put 'with-parsed-tramp-file-name 'lisp-indent-function 2)
1732 1760
1733 ;;; Config Manipulation Functions: 1761 ;;; Config Manipulation Functions:
1762 1790
1763 (defun tramp-handle-make-symbolic-link 1791 (defun tramp-handle-make-symbolic-link
1764 (filename linkname &optional ok-if-already-exists) 1792 (filename linkname &optional ok-if-already-exists)
1765 "Like `make-symbolic-link' for tramp files. 1793 "Like `make-symbolic-link' for tramp files.
1766 If LINKNAME is a non-Tramp file, it is used verbatim as the target of 1794 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 1795 the symlink. If LINKNAME is a Tramp file, only the localname component is
1768 used as the target of the symlink. 1796 used as the target of the symlink.
1769 1797
1770 If LINKNAME is a Tramp file and the path component is relative, then 1798 If LINKNAME is a Tramp file and the localname component is relative, then
1771 it is expanded first, before the path component is taken. Note that 1799 it is expanded first, before the localname component is taken. Note that
1772 this can give surprising results if the user/host for the source and 1800 this can give surprising results if the user/host for the source and
1773 target of the symlink differ." 1801 target of the symlink differ."
1774 (with-parsed-tramp-file-name linkname l 1802 (with-parsed-tramp-file-name linkname l
1775 (let ((ln (tramp-get-remote-ln l-multi-method l-method l-user l-host)) 1803 (let ((ln (tramp-get-remote-ln l-multi-method l-method l-user l-host))
1776 (cwd (file-name-directory l-path))) 1804 (cwd (file-name-directory l-localname)))
1777 (unless ln 1805 (unless ln
1778 (signal 'file-error 1806 (signal 'file-error
1779 (list "Making a symbolic link." 1807 (list "Making a symbolic link."
1780 "ln(1) does not exist on the remote host."))) 1808 "ln(1) does not exist on the remote host.")))
1781 1809
1785 (if (or (null ok-if-already-exists) ; not allowed to exist 1813 (if (or (null ok-if-already-exists) ; not allowed to exist
1786 (and (numberp ok-if-already-exists) 1814 (and (numberp ok-if-already-exists)
1787 (not (yes-or-no-p 1815 (not (yes-or-no-p
1788 (format 1816 (format
1789 "File %s already exists; make it a link anyway? " 1817 "File %s already exists; make it a link anyway? "
1790 l-path))))) 1818 l-localname)))))
1791 (signal 'file-already-exists (list "File already exists" l-path)) 1819 (signal 'file-already-exists (list "File already exists" l-localname))
1792 (delete-file linkname))) 1820 (delete-file linkname)))
1793 1821
1794 ;; If FILENAME is a Tramp name, use just the path component. 1822 ;; If FILENAME is a Tramp name, use just the localname component.
1795 (when (tramp-tramp-file-p filename) 1823 (when (tramp-tramp-file-p filename)
1796 (setq filename (tramp-file-name-path 1824 (setq filename (tramp-file-name-localname
1797 (tramp-dissect-file-name 1825 (tramp-dissect-file-name
1798 (expand-file-name filename))))) 1826 (expand-file-name filename)))))
1799 1827
1800 ;; Right, they are on the same host, regardless of user, method, etc. 1828 ;; 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 1829 ;; We now make the link on the remote machine. This will occur as the user
1802 ;; that FILENAME belongs to. 1830 ;; that FILENAME belongs to.
1803 (zerop 1831 (zerop
1804 (tramp-send-command-and-check 1832 (tramp-send-command-and-check
1805 l-multi-method l-method l-user l-host 1833 l-multi-method l-method l-user l-host
1806 (format "cd %s && %s -sf %s %s" 1834 (format "cd %s && %s -sf %s %s"
1807 cwd ln 1835 cwd ln
1808 filename 1836 filename
1809 l-path) 1837 l-localname)
1810 t))))) 1838 t)))))
1811 1839
1812 1840
1813 (defun tramp-handle-load (file &optional noerror nomessage nosuffix must-suffix) 1841 (defun tramp-handle-load (file &optional noerror nomessage nosuffix must-suffix)
1814 "Like `load' for tramp files. Not implemented!" 1842 "Like `load' for tramp files. Not implemented!"
1815 (unless (file-name-absolute-p file) 1843 (unless (file-name-absolute-p file)
1816 (error "Tramp cannot `load' files without absolute path name")) 1844 (error "Tramp cannot `load' files without absolute file name"))
1817 (with-parsed-tramp-file-name file nil 1845 (with-parsed-tramp-file-name file nil
1818 (unless nosuffix 1846 (unless nosuffix
1819 (cond ((file-exists-p (concat file ".elc")) 1847 (cond ((file-exists-p (concat file ".elc"))
1820 (setq file (concat file ".elc"))) 1848 (setq file (concat file ".elc")))
1821 ((file-exists-p (concat file ".el")) 1849 ((file-exists-p (concat file ".el"))
1840 (delete-file local-copy)) 1868 (delete-file local-copy))
1841 (unless nomessage 1869 (unless nomessage
1842 (message "Loading %s...done" file)) 1870 (message "Loading %s...done" file))
1843 t))) 1871 t)))
1844 1872
1845 ;; Path manipulation functions that grok TRAMP paths... 1873 ;; Localname manipulation functions that grok TRAMP localnames...
1846 (defun tramp-handle-file-name-directory (file) 1874 (defun tramp-handle-file-name-directory (file)
1847 "Like `file-name-directory' but aware of TRAMP files." 1875 "Like `file-name-directory' but aware of TRAMP files."
1848 ;; everything except the last filename thing is the directory 1876 ;; everything except the last filename thing is the directory
1849 (with-parsed-tramp-file-name file nil 1877 (with-parsed-tramp-file-name file nil
1850 ;; For the following condition, two possibilities should be tried: 1878 ;; For the following condition, two possibilities should be tried:
1851 ;; (1) (string= path "") 1879 ;; (1) (string= localname "")
1852 ;; (2) (or (string= path "") (string= path "/")) 1880 ;; (2) (or (string= localname "") (string= localname "/"))
1853 ;; The second variant fails when completing a "/" directory on 1881 ;; The second variant fails when completing a "/" directory on
1854 ;; the remote host, that is a filename which looks like 1882 ;; the remote host, that is a filename which looks like
1855 ;; "/user@host:/". But maybe wildcards fail with the first variant. 1883 ;; "/user@host:/". But maybe wildcards fail with the first variant.
1856 ;; We should do some investigation. 1884 ;; We should do some investigation.
1857 (if (string= path "") 1885 (if (string= localname "")
1858 ;; For a filename like "/[foo]", we return "/". The `else' 1886 ;; For a filename like "/[foo]", we return "/". The `else'
1859 ;; case would return "/[foo]" unchanged. But if we do that, 1887 ;; case would return "/[foo]" unchanged. But if we do that,
1860 ;; then `file-expand-wildcards' ceases to work. It's not 1888 ;; then `file-expand-wildcards' ceases to work. It's not
1861 ;; quite clear to me what's the intuition that tells that this 1889 ;; quite clear to me what's the intuition that tells that this
1862 ;; behavior is the right behavior, but oh, well. 1890 ;; behavior is the right behavior, but oh, well.
1863 "/" 1891 "/"
1864 ;; run the command on the path portion only 1892 ;; run the command on the localname portion only
1865 ;; CCC: This should take into account the remote machine type, no? 1893 ;; CCC: This should take into account the remote machine type, no?
1866 ;; --daniel <daniel@danann.net> 1894 ;; --daniel <daniel@danann.net>
1867 (tramp-make-tramp-file-name multi-method method user host 1895 (tramp-make-tramp-file-name multi-method method user host
1868 ;; This will not recurse... 1896 ;; This will not recurse...
1869 (or (file-name-directory path) ""))))) 1897 (or (file-name-directory localname) "")))))
1870 1898
1871 (defun tramp-handle-file-name-nondirectory (file) 1899 (defun tramp-handle-file-name-nondirectory (file)
1872 "Like `file-name-nondirectory' but aware of TRAMP files." 1900 "Like `file-name-nondirectory' but aware of TRAMP files."
1873 (with-parsed-tramp-file-name file nil 1901 (with-parsed-tramp-file-name file nil
1874 (file-name-nondirectory path))) 1902 (file-name-nondirectory localname)))
1875 1903
1876 (defun tramp-handle-file-truename (filename &optional counter prev-dirs) 1904 (defun tramp-handle-file-truename (filename &optional counter prev-dirs)
1877 "Like `file-truename' for tramp files." 1905 "Like `file-truename' for tramp files."
1878 (with-parsed-tramp-file-name filename nil 1906 (with-parsed-tramp-file-name filename nil
1879 (let* ((steps (tramp-split-string path "/")) 1907 (let* ((steps (tramp-split-string localname "/"))
1880 (pathdir (let ((directory-sep-char ?/)) 1908 (localnamedir (let ((directory-sep-char ?/))
1881 (file-name-as-directory path))) 1909 (file-name-as-directory localname)))
1882 (is-dir (string= path pathdir)) 1910 (is-dir (string= localname localnamedir))
1883 (thisstep nil) 1911 (thisstep nil)
1884 (numchase 0) 1912 (numchase 0)
1885 ;; Don't make the following value larger than necessary. 1913 ;; Don't make the following value larger than necessary.
1886 ;; People expect an error message in a timely fashion when 1914 ;; People expect an error message in a timely fashion when
1887 ;; something is wrong; otherwise they might think that Emacs 1915 ;; something is wrong; otherwise they might think that Emacs
1954 (save-excursion 1982 (save-excursion
1955 (zerop (tramp-send-command-and-check 1983 (zerop (tramp-send-command-and-check
1956 multi-method method user host 1984 multi-method method user host
1957 (format 1985 (format
1958 (tramp-get-file-exists-command multi-method method user host) 1986 (tramp-get-file-exists-command multi-method method user host)
1959 (tramp-shell-quote-argument path))))))) 1987 (tramp-shell-quote-argument localname)))))))
1960 1988
1961 ;; Devices must distinguish physical file systems. The device numbers 1989 ;; Devices must distinguish physical file systems. The device numbers
1962 ;; provided by "lstat" aren't unique, because we operate on different hosts. 1990 ;; 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 1991 ;; 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 1992 ;; EFS use device number "-1". In order to be different, we use device number
1979 ;; file exists, find out stuff 2007 ;; file exists, find out stuff
1980 (save-excursion 2008 (save-excursion
1981 (if (tramp-get-remote-perl multi-method method user host) 2009 (if (tramp-get-remote-perl multi-method method user host)
1982 (setq result 2010 (setq result
1983 (tramp-handle-file-attributes-with-perl 2011 (tramp-handle-file-attributes-with-perl
1984 multi-method method user host path nonnumeric)) 2012 multi-method method user host localname nonnumeric))
1985 (setq result 2013 (setq result
1986 (tramp-handle-file-attributes-with-ls 2014 (tramp-handle-file-attributes-with-ls
1987 multi-method method user host path nonnumeric))) 2015 multi-method method user host localname nonnumeric)))
1988 ;; set virtual device number 2016 ;; set virtual device number
1989 (setcar (nthcdr 11 result) 2017 (setcar (nthcdr 11 result)
1990 (tramp-get-device multi-method method user host))))) 2018 (tramp-get-device multi-method method user host)))))
1991 result)) 2019 result))
1992 2020
1993 (defun tramp-handle-file-attributes-with-ls 2021 (defun tramp-handle-file-attributes-with-ls
1994 (multi-method method user host path &optional nonnumeric) 2022 (multi-method method user host localname &optional nonnumeric)
1995 "Implement `file-attributes' for tramp files using the ls(1) command." 2023 "Implement `file-attributes' for tramp files using the ls(1) command."
1996 (let (symlinkp dirp 2024 (let (symlinkp dirp
1997 res-inode res-filemodes res-numlinks 2025 res-inode res-filemodes res-numlinks
1998 res-uid res-gid res-size res-symlink-target) 2026 res-uid res-gid res-size res-symlink-target)
1999 (tramp-message-for-buffer multi-method method user host 10 2027 (tramp-message-for-buffer multi-method method user host 10
2000 "file attributes with ls: %s" 2028 "file attributes with ls: %s"
2001 (tramp-make-tramp-file-name 2029 (tramp-make-tramp-file-name
2002 multi-method method user host path)) 2030 multi-method method user host localname))
2003 (tramp-send-command 2031 (tramp-send-command
2004 multi-method method user host 2032 multi-method method user host
2005 (format "%s %s %s" 2033 (format "%s %s %s"
2006 (tramp-get-ls-command multi-method method user host) 2034 (tramp-get-ls-command multi-method method user host)
2007 (if nonnumeric "-ild" "-ildn") 2035 (if nonnumeric "-ild" "-ildn")
2008 (tramp-shell-quote-argument path))) 2036 (tramp-shell-quote-argument localname)))
2009 (tramp-wait-for-output) 2037 (tramp-wait-for-output)
2010 ;; parse `ls -l' output ... 2038 ;; parse `ls -l' output ...
2011 ;; ... inode 2039 ;; ... inode
2012 (setq res-inode 2040 (setq res-inode
2013 (condition-case err 2041 (condition-case err
2074 ;; 11. Device number. Will be replaced by a virtual device number. 2102 ;; 11. Device number. Will be replaced by a virtual device number.
2075 -1 2103 -1
2076 ))) 2104 )))
2077 2105
2078 (defun tramp-handle-file-attributes-with-perl 2106 (defun tramp-handle-file-attributes-with-perl
2079 (multi-method method user host path &optional nonnumeric) 2107 (multi-method method user host localname &optional nonnumeric)
2080 "Implement `file-attributes' for tramp files using a Perl script. 2108 "Implement `file-attributes' for tramp files using a Perl script.
2081 2109
2082 The Perl command is sent to the remote machine when the connection 2110 The Perl command is sent to the remote machine when the connection
2083 is initially created and is kept cached by the remote shell." 2111 is initially created and is kept cached by the remote shell."
2084 (tramp-message-for-buffer multi-method method user host 10 2112 (tramp-message-for-buffer multi-method method user host 10
2085 "file attributes with perl: %s" 2113 "file attributes with perl: %s"
2086 (tramp-make-tramp-file-name 2114 (tramp-make-tramp-file-name
2087 multi-method method user host path)) 2115 multi-method method user host localname))
2088 (tramp-send-command 2116 (tramp-send-command
2089 multi-method method user host 2117 multi-method method user host
2090 (format "tramp_file_attributes %s" 2118 (format "tramp_file_attributes %s"
2091 (tramp-shell-quote-argument path))) 2119 (tramp-shell-quote-argument localname)))
2092 (tramp-wait-for-output) 2120 (tramp-wait-for-output)
2093 (let ((result (read (current-buffer)))) 2121 (let ((result (read (current-buffer))))
2094 (setcar (nthcdr 8 result) 2122 (setcar (nthcdr 8 result)
2095 (tramp-file-mode-from-int (nth 8 result))) 2123 (tramp-file-mode-from-int (nth 8 result)))
2096 result)) 2124 result))
2125 (save-excursion 2153 (save-excursion
2126 (tramp-send-command 2154 (tramp-send-command
2127 multi-method method user host 2155 multi-method method user host
2128 (format "%s -ild %s" 2156 (format "%s -ild %s"
2129 (tramp-get-ls-command multi-method method user host) 2157 (tramp-get-ls-command multi-method method user host)
2130 (tramp-shell-quote-argument path))) 2158 (tramp-shell-quote-argument localname)))
2131 (tramp-wait-for-output) 2159 (tramp-wait-for-output)
2132 (setq attr (buffer-substring (point) 2160 (setq attr (buffer-substring (point)
2133 (progn (end-of-line) (point))))) 2161 (progn (end-of-line) (point)))))
2134 (setq tramp-buffer-file-attributes attr)) 2162 (setq tramp-buffer-file-attributes attr))
2135 (when (boundp 'last-coding-system-used) 2163 (when (boundp 'last-coding-system-used)
2159 (tramp-send-command 2187 (tramp-send-command
2160 multi-method method user host 2188 multi-method method user host
2161 (format "%s -ild %s" 2189 (format "%s -ild %s"
2162 (tramp-get-ls-command multi-method method 2190 (tramp-get-ls-command multi-method method
2163 user host) 2191 user host)
2164 (tramp-shell-quote-argument path))) 2192 (tramp-shell-quote-argument localname)))
2165 (tramp-wait-for-output) 2193 (tramp-wait-for-output)
2166 (setq attr (buffer-substring 2194 (setq attr (buffer-substring
2167 (point) (progn (end-of-line) (point))))) 2195 (point) (progn (end-of-line) (point)))))
2168 (equal tramp-buffer-file-attributes attr)) 2196 (equal tramp-buffer-file-attributes attr))
2169 ;; If file does not exist, say it is not modified. 2197 ;; If file does not exist, say it is not modified.
2181 (save-excursion 2209 (save-excursion
2182 (unless (zerop (tramp-send-command-and-check 2210 (unless (zerop (tramp-send-command-and-check
2183 multi-method method user host 2211 multi-method method user host
2184 (format "chmod %s %s" 2212 (format "chmod %s %s"
2185 (tramp-decimal-to-octal mode) 2213 (tramp-decimal-to-octal mode)
2186 (tramp-shell-quote-argument path)))) 2214 (tramp-shell-quote-argument localname))))
2187 (signal 'file-error 2215 (signal 'file-error
2188 (list "Doing chmod" 2216 (list "Doing chmod"
2189 ;; FIXME: extract the proper text from chmod's stderr. 2217 ;; FIXME: extract the proper text from chmod's stderr.
2190 "error while changing file's mode" 2218 "error while changing file's mode"
2191 filename)))))) 2219 filename))))))
2286 (save-excursion 2314 (save-excursion
2287 (zerop 2315 (zerop
2288 (tramp-send-command-and-check 2316 (tramp-send-command-and-check
2289 multi-method method user host 2317 multi-method method user host
2290 (format "test -d %s" 2318 (format "test -d %s"
2291 (tramp-shell-quote-argument path)) 2319 (tramp-shell-quote-argument localname))
2292 t))))) ;run command in subshell 2320 t))))) ;run command in subshell
2293 2321
2294 (defun tramp-handle-file-regular-p (filename) 2322 (defun tramp-handle-file-regular-p (filename)
2295 "Like `file-regular-p' for tramp files." 2323 "Like `file-regular-p' for tramp files."
2296 (with-parsed-tramp-file-name filename nil 2324 (with-parsed-tramp-file-name filename nil
2344 ;; (substring directory 0 directory-length-1) 2372 ;; (substring directory 0 directory-length-1)
2345 ;; directory))))) 2373 ;; directory)))))
2346 2374
2347 (defun tramp-handle-directory-file-name (directory) 2375 (defun tramp-handle-directory-file-name (directory)
2348 "Like `directory-file-name' for tramp files." 2376 "Like `directory-file-name' for tramp files."
2349 ;; If path component of filename is "/", leave it unchanged. 2377 ;; If localname component of filename is "/", leave it unchanged.
2350 ;; Otherwise, remove any trailing slash from path component. 2378 ;; Otherwise, remove any trailing slash from localname component.
2351 ;; Method, host, etc, are unchanged. Does it make sense to try 2379 ;; Method, host, etc, are unchanged. Does it make sense to try
2352 ;; to avoid parsing the filename? 2380 ;; to avoid parsing the filename?
2353 (with-parsed-tramp-file-name directory nil 2381 (with-parsed-tramp-file-name directory nil
2354 (if (and (not (zerop (length path))) 2382 (if (and (not (zerop (length localname)))
2355 (eq (aref path (1- (length path))) ?/) 2383 (eq (aref localname (1- (length localname))) ?/)
2356 (not (string= path "/"))) 2384 (not (string= localname "/")))
2357 (substring directory 0 -1) 2385 (substring directory 0 -1)
2358 directory))) 2386 directory)))
2359 2387
2360 ;; Directory listings. 2388 ;; Directory listings.
2361 2389
2365 (with-parsed-tramp-file-name directory nil 2393 (with-parsed-tramp-file-name directory nil
2366 (let (result x) 2394 (let (result x)
2367 (save-excursion 2395 (save-excursion
2368 (tramp-barf-unless-okay 2396 (tramp-barf-unless-okay
2369 multi-method method user host 2397 multi-method method user host
2370 (concat "cd " (tramp-shell-quote-argument path)) 2398 (concat "cd " (tramp-shell-quote-argument localname))
2371 nil 2399 nil
2372 'file-error 2400 'file-error
2373 "tramp-handle-directory-files: couldn't `cd %s'" 2401 "tramp-handle-directory-files: couldn't `cd %s'"
2374 (tramp-shell-quote-argument path)) 2402 (tramp-shell-quote-argument localname))
2375 (tramp-send-command 2403 (tramp-send-command
2376 multi-method method user host 2404 multi-method method user host
2377 (concat (tramp-get-ls-command multi-method method user host) 2405 (concat (tramp-get-ls-command multi-method method user host)
2378 " -a | cat")) 2406 " -a | cat"))
2379 (tramp-wait-for-output) 2407 (tramp-wait-for-output)
2421 (let* ((nowild tramp-completion-without-shell-p) 2449 (let* ((nowild tramp-completion-without-shell-p)
2422 result) 2450 result)
2423 (save-excursion 2451 (save-excursion
2424 (tramp-barf-unless-okay 2452 (tramp-barf-unless-okay
2425 multi-method method user host 2453 multi-method method user host
2426 (format "cd %s" (tramp-shell-quote-argument path)) 2454 (format "cd %s" (tramp-shell-quote-argument localname))
2427 nil 'file-error 2455 nil 'file-error
2428 "tramp-handle-file-name-all-completions: Couldn't `cd %s'" 2456 "tramp-handle-file-name-all-completions: Couldn't `cd %s'"
2429 (tramp-shell-quote-argument path)) 2457 (tramp-shell-quote-argument localname))
2430 2458
2431 ;; Get a list of directories and files, including reliably 2459 ;; Get a list of directories and files, including reliably
2432 ;; tagging the directories with a trailing '/'. Because I 2460 ;; tagging the directories with a trailing '/'. Because I
2433 ;; rock. --daniel@danann.net 2461 ;; rock. --daniel@danann.net
2434 (tramp-send-command 2462 (tramp-send-command
2447 (goto-char (point-max)) 2475 (goto-char (point-max))
2448 (while (zerop (forward-line -1)) 2476 (while (zerop (forward-line -1))
2449 (push (buffer-substring (point) 2477 (push (buffer-substring (point)
2450 (tramp-line-end-position)) 2478 (tramp-line-end-position))
2451 result)) 2479 result))
2452 2480
2453 (tramp-send-command multi-method method user host "cd") 2481 (tramp-send-command multi-method method user host "cd")
2454 (tramp-wait-for-output) 2482 (tramp-wait-for-output)
2455 2483
2456 ;; Return the list. 2484 ;; Return the list.
2457 (if nowild 2485 (if nowild
2496 "File %s already exists; make it a new name anyway? " 2524 "File %s already exists; make it a new name anyway? "
2497 newname))) 2525 newname)))
2498 (error "add-name-to-file: file %s already exists" newname)) 2526 (error "add-name-to-file: file %s already exists" newname))
2499 (tramp-barf-unless-okay 2527 (tramp-barf-unless-okay
2500 v1-multi-method v1-method v1-user v1-host 2528 v1-multi-method v1-method v1-user v1-host
2501 (format "%s %s %s" ln (tramp-shell-quote-argument v1-path) 2529 (format "%s %s %s" ln (tramp-shell-quote-argument v1-localname)
2502 (tramp-shell-quote-argument v2-path)) 2530 (tramp-shell-quote-argument v2-localname))
2503 nil 'file-error 2531 nil 'file-error
2504 "error with add-name-to-file, see buffer `%s' for details" 2532 "error with add-name-to-file, see buffer `%s' for details"
2505 (buffer-name)))))) 2533 (buffer-name))))))
2506 2534
2507 (defun tramp-handle-copy-file 2535 (defun tramp-handle-copy-file
2570 ;; Shortcut: if method, host, user are the same for both 2598 ;; Shortcut: if method, host, user are the same for both
2571 ;; files, we invoke `cp' or `mv' on the remote host 2599 ;; files, we invoke `cp' or `mv' on the remote host
2572 ;; directly. 2600 ;; directly.
2573 (tramp-do-copy-or-rename-file-directly 2601 (tramp-do-copy-or-rename-file-directly
2574 op v1-multi-method v1-method v1-user v1-host 2602 op v1-multi-method v1-method v1-user v1-host
2575 v1-path v2-path keep-date) 2603 v1-localname v2-localname keep-date)
2576 ;; The shortcut was not possible. So we copy the 2604 ;; The shortcut was not possible. So we copy the
2577 ;; file first. If the operation was `rename', we go 2605 ;; file first. If the operation was `rename', we go
2578 ;; back and delete the original file (if the copy was 2606 ;; back and delete the original file (if the copy was
2579 ;; successful). The approach is simple-minded: we 2607 ;; successful). The approach is simple-minded: we
2580 ;; create a new buffer, insert the contents of the 2608 ;; create a new buffer, insert the contents of the
2588 ;; can invoke rcp directly. Note that 2616 ;; can invoke rcp directly. Note that
2589 ;; default-directory should point to a local 2617 ;; default-directory should point to a local
2590 ;; directory if we want to invoke rcp. 2618 ;; directory if we want to invoke rcp.
2591 (tramp-do-copy-or-rename-via-buffer 2619 (tramp-do-copy-or-rename-via-buffer
2592 op filename newname keep-date))))) 2620 op filename newname keep-date)))))
2593 ((or t1 t2) 2621 ((or t1 t2)
2594 ;; Use the generic method via a Tramp buffer. 2622 ;; Use the generic method via a Tramp buffer.
2595 (tramp-do-copy-or-rename-via-buffer op filename newname keep-date)) 2623 (tramp-do-copy-or-rename-via-buffer op filename newname keep-date))
2596 (t 2624 (t
2597 ;; One of them must be a Tramp file. 2625 ;; One of them must be a Tramp file.
2598 (error "Tramp implementation says this cannot happen"))))) 2626 (error "Tramp implementation says this cannot happen")))))
2599 2627
2628 ;; CCC: implement keep-date if possible -- via touch?
2600 (defun tramp-do-copy-or-rename-via-buffer (op filename newname keep-date) 2629 (defun tramp-do-copy-or-rename-via-buffer (op filename newname keep-date)
2601 "Use an Emacs buffer to copy or rename a file. 2630 "Use an Emacs buffer to copy or rename a file.
2602 First arg OP is either `copy' or `rename' and indicates the operation. 2631 First arg OP is either `copy' or `rename' and indicates the operation.
2603 FILENAME is the source file, NEWNAME the target file. 2632 FILENAME is the source file, NEWNAME the target file.
2604 KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME." 2633 KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME."
2615 ;; If the operation was `rename', delete the original file. 2644 ;; If the operation was `rename', delete the original file.
2616 (unless (eq op 'copy) 2645 (unless (eq op 'copy)
2617 (delete-file filename)))) 2646 (delete-file filename))))
2618 2647
2619 (defun tramp-do-copy-or-rename-file-directly 2648 (defun tramp-do-copy-or-rename-file-directly
2620 (op multi-method method user host path1 path2 keep-date) 2649 (op multi-method method user host localname1 localname2 keep-date)
2621 "Invokes `cp' or `mv' on the remote system. 2650 "Invokes `cp' or `mv' on the remote system.
2622 OP must be one of `copy' or `rename', indicating `cp' or `mv', 2651 OP must be one of `copy' or `rename', indicating `cp' or `mv',
2623 respectively. METHOD, USER, and HOST specify the connection. 2652 respectively. METHOD, USER, and HOST specify the connection.
2624 PATH1 and PATH2 specify the two arguments of `cp' or `mv'. 2653 LOCALNAME1 and LOCALNAME2 specify the two arguments of `cp' or `mv'.
2625 If KEEP-DATE is non-nil, preserve the time stamp when copying." 2654 If KEEP-DATE is non-nil, preserve the time stamp when copying."
2626 ;; CCC: What happens to the timestamp when renaming? 2655 ;; CCC: What happens to the timestamp when renaming?
2627 (let ((cmd (cond ((and (eq op 'copy) keep-date) "cp -f -p") 2656 (let ((cmd (cond ((and (eq op 'copy) keep-date) "cp -f -p")
2628 ((eq op 'copy) "cp -f") 2657 ((eq op 'copy) "cp -f")
2629 ((eq op 'rename) "mv -f") 2658 ((eq op 'rename) "mv -f")
2633 (save-excursion 2662 (save-excursion
2634 (tramp-barf-unless-okay 2663 (tramp-barf-unless-okay
2635 multi-method method user host 2664 multi-method method user host
2636 (format "%s %s %s" 2665 (format "%s %s %s"
2637 cmd 2666 cmd
2638 (tramp-shell-quote-argument path1) 2667 (tramp-shell-quote-argument localname1)
2639 (tramp-shell-quote-argument path2)) 2668 (tramp-shell-quote-argument localname2))
2640 nil 'file-error 2669 nil 'file-error
2641 "Copying directly failed, see buffer `%s' for details." 2670 "Copying directly failed, see buffer `%s' for details."
2642 (buffer-name))))) 2671 (buffer-name)))))
2672
2673 (defun tramp-do-copy-or-rename-file-one-local
2674 (op filename newname keep-date)
2675 "Invoke rcp program to copy.
2676 One of FILENAME and NEWNAME must be a Tramp name, the other must
2677 be a local filename. The method used must be an out-of-band method."
2678 ;; CCC
2679 )
2643 2680
2644 ;; mkdir 2681 ;; mkdir
2645 (defun tramp-handle-make-directory (dir &optional parents) 2682 (defun tramp-handle-make-directory (dir &optional parents)
2646 "Like `make-directory' for tramp files." 2683 "Like `make-directory' for tramp files."
2647 (setq dir (expand-file-name dir)) 2684 (setq dir (expand-file-name dir))
2649 (save-excursion 2686 (save-excursion
2650 (tramp-barf-unless-okay 2687 (tramp-barf-unless-okay
2651 multi-method method user host 2688 multi-method method user host
2652 (format " %s %s" 2689 (format " %s %s"
2653 (if parents "mkdir -p" "mkdir") 2690 (if parents "mkdir -p" "mkdir")
2654 (tramp-shell-quote-argument path)) 2691 (tramp-shell-quote-argument localname))
2655 nil 'file-error 2692 nil 'file-error
2656 "Couldn't make directory %s" dir)))) 2693 "Couldn't make directory %s" dir))))
2657 2694
2658 ;; CCC error checking? 2695 ;; CCC error checking?
2659 (defun tramp-handle-delete-directory (directory) 2696 (defun tramp-handle-delete-directory (directory)
2662 (with-parsed-tramp-file-name directory nil 2699 (with-parsed-tramp-file-name directory nil
2663 (save-excursion 2700 (save-excursion
2664 (tramp-send-command 2701 (tramp-send-command
2665 multi-method method user host 2702 multi-method method user host
2666 (format "rmdir %s ; echo ok" 2703 (format "rmdir %s ; echo ok"
2667 (tramp-shell-quote-argument path))) 2704 (tramp-shell-quote-argument localname)))
2668 (tramp-wait-for-output)))) 2705 (tramp-wait-for-output))))
2669 2706
2670 (defun tramp-handle-delete-file (filename) 2707 (defun tramp-handle-delete-file (filename)
2671 "Like `delete-file' for tramp files." 2708 "Like `delete-file' for tramp files."
2672 (setq filename (expand-file-name filename)) 2709 (setq filename (expand-file-name filename))
2673 (with-parsed-tramp-file-name filename nil 2710 (with-parsed-tramp-file-name filename nil
2674 (save-excursion 2711 (save-excursion
2675 (unless (zerop (tramp-send-command-and-check 2712 (unless (zerop (tramp-send-command-and-check
2676 multi-method method user host 2713 multi-method method user host
2677 (format "rm -f %s" 2714 (format "rm -f %s"
2678 (tramp-shell-quote-argument path)))) 2715 (tramp-shell-quote-argument localname))))
2679 (signal 'file-error "Couldn't delete Tramp file"))))) 2716 (signal 'file-error "Couldn't delete Tramp file")))))
2680 2717
2681 ;; Dired. 2718 ;; Dired.
2682 2719
2683 ;; CCC: This does not seem to be enough. Something dies when 2720 ;; CCC: This does not seem to be enough. Something dies when
2684 ;; we try and delete two directories under TRAMP :/ 2721 ;; we try and delete two directories under TRAMP :/
2685 (defun tramp-handle-dired-recursive-delete-directory (filename) 2722 (defun tramp-handle-dired-recursive-delete-directory (filename)
2686 "Recursively delete the directory given. 2723 "Recursively delete the directory given.
2687 This is like `dired-recursive-delete-directory' for tramp files." 2724 This is like `dired-recursive-delete-directory' for tramp files."
2688 (with-parsed-tramp-file-name filename nil 2725 (with-parsed-tramp-file-name filename nil
2689 ;; run a shell command 'rm -r <path>' 2726 ;; run a shell command 'rm -r <localname>'
2690 ;; Code shamelessly stolen for the dired implementation and, um, hacked :) 2727 ;; Code shamelessly stolen for the dired implementation and, um, hacked :)
2691 (or (tramp-handle-file-exists-p filename) 2728 (or (tramp-handle-file-exists-p filename)
2692 (signal 2729 (signal
2693 'file-error 2730 'file-error
2694 (list "Removing old file name" "no such directory" filename))) 2731 (list "Removing old file name" "no such directory" filename)))
2695 ;; Which is better, -r or -R? (-r works for me <daniel@danann.net>) 2732 ;; Which is better, -r or -R? (-r works for me <daniel@danann.net>)
2696 (tramp-send-command multi-method method user host 2733 (tramp-send-command multi-method method user host
2697 (format "rm -r %s" (tramp-shell-quote-argument path))) 2734 (format "rm -r %s" (tramp-shell-quote-argument localname)))
2698 ;; Wait for the remote system to return to us... 2735 ;; Wait for the remote system to return to us...
2699 ;; This might take a while, allow it plenty of time. 2736 ;; This might take a while, allow it plenty of time.
2700 (tramp-wait-for-output 120) 2737 (tramp-wait-for-output 120)
2701 ;; Make sure that it worked... 2738 ;; Make sure that it worked...
2702 (and (tramp-handle-file-exists-p filename) 2739 (and (tramp-handle-file-exists-p filename)
2703 (error "Failed to recusively delete %s" filename)))) 2740 (error "Failed to recusively delete %s" filename))))
2704 2741
2705 2742
2706 (defun tramp-handle-dired-call-process (program discard &rest arguments) 2743 (defun tramp-handle-dired-call-process (program discard &rest arguments)
2707 "Like `dired-call-process' for tramp files." 2744 "Like `dired-call-process' for tramp files."
2708 (with-parsed-tramp-file-name default-directory nil 2745 (with-parsed-tramp-file-name default-directory nil
2709 (save-excursion 2746 (save-excursion
2710 (tramp-barf-unless-okay 2747 (tramp-barf-unless-okay
2711 multi-method method user host 2748 multi-method method user host
2712 (format "cd %s" (tramp-shell-quote-argument path)) 2749 (format "cd %s" (tramp-shell-quote-argument localname))
2713 nil 'file-error 2750 nil 'file-error
2714 "tramp-handle-dired-call-process: Couldn't `cd %s'" 2751 "tramp-handle-dired-call-process: Couldn't `cd %s'"
2715 (tramp-shell-quote-argument path)) 2752 (tramp-shell-quote-argument localname))
2716 (tramp-send-command 2753 (tramp-send-command
2717 multi-method method user host 2754 multi-method method user host
2718 (mapconcat #'tramp-shell-quote-argument (cons program arguments) " ")) 2755 (mapconcat #'tramp-shell-quote-argument (cons program arguments) " "))
2719 (tramp-wait-for-output)) 2756 (tramp-wait-for-output))
2720 (unless discard 2757 (unless discard
2752 multi-method method user host 10 2789 multi-method method user host 10
2753 "Inserting directory `ls %s %s', wildcard %s, fulldir %s" 2790 "Inserting directory `ls %s %s', wildcard %s, fulldir %s"
2754 switches filename (if wildcard "yes" "no") 2791 switches filename (if wildcard "yes" "no")
2755 (if full-directory-p "yes" "no")) 2792 (if full-directory-p "yes" "no"))
2756 (when wildcard 2793 (when wildcard
2757 (setq wildcard (file-name-nondirectory path)) 2794 (setq wildcard (file-name-nondirectory localname))
2758 (setq path (file-name-directory path))) 2795 (setq localname (file-name-directory localname)))
2759 (when (listp switches) 2796 (when (listp switches)
2760 (setq switches (mapconcat 'identity switches " "))) 2797 (setq switches (mapconcat 'identity switches " ")))
2761 (unless full-directory-p 2798 (unless full-directory-p
2762 (setq switches (concat "-d " switches))) 2799 (setq switches (concat "-d " switches)))
2763 (when wildcard 2800 (when wildcard
2770 multi-method method user host 2807 multi-method method user host
2771 (format "%s %s %s" 2808 (format "%s %s %s"
2772 (tramp-get-ls-command multi-method method user host) 2809 (tramp-get-ls-command multi-method method user host)
2773 switches 2810 switches
2774 (if wildcard 2811 (if wildcard
2775 path 2812 localname
2776 (tramp-shell-quote-argument (concat path "."))))) 2813 (tramp-shell-quote-argument (concat localname ".")))))
2777 (tramp-barf-unless-okay 2814 (tramp-barf-unless-okay
2778 multi-method method user host 2815 multi-method method user host
2779 (format "cd %s" (tramp-shell-quote-argument 2816 (format "cd %s" (tramp-shell-quote-argument
2780 (file-name-directory path))) 2817 (file-name-directory localname)))
2781 nil 'file-error 2818 nil 'file-error
2782 "Couldn't `cd %s'" 2819 "Couldn't `cd %s'"
2783 (tramp-shell-quote-argument (file-name-directory path))) 2820 (tramp-shell-quote-argument (file-name-directory localname)))
2784 (tramp-send-command 2821 (tramp-send-command
2785 multi-method method user host 2822 multi-method method user host
2786 (format "%s %s %s" 2823 (format "%s %s %s"
2787 (tramp-get-ls-command multi-method method user host) 2824 (tramp-get-ls-command multi-method method user host)
2788 switches 2825 switches
2789 (if full-directory-p 2826 (if full-directory-p
2790 ;; Add "/." to make sure we got complete dir 2827 ;; Add "/." to make sure we got complete dir
2791 ;; listing for symlinks, too. 2828 ;; listing for symlinks, too.
2792 (concat (file-name-as-directory 2829 (concat (file-name-as-directory
2793 (file-name-nondirectory path)) ".") 2830 (file-name-nondirectory localname)) ".")
2794 (file-name-nondirectory path))))) 2831 (file-name-nondirectory localname)))))
2795 (sit-for 1) ;needed for rsh but not ssh? 2832 (sit-for 1) ;needed for rsh but not ssh?
2796 (tramp-wait-for-output)) 2833 (tramp-wait-for-output))
2797 (let ((old-pos (point))) 2834 (let ((old-pos (point)))
2798 (insert-buffer-substring 2835 (insert-buffer-substring
2799 (tramp-get-buffer multi-method method user host)) 2836 (tramp-get-buffer multi-method method user host))
2842 (and (>= c1 ?a) (<= c1 ?z))))) 2879 (and (>= c1 ?a) (<= c1 ?z)))))
2843 (substring name 2) 2880 (substring name 2)
2844 name)) 2881 name))
2845 2882
2846 (defun tramp-handle-expand-file-name (name &optional dir) 2883 (defun tramp-handle-expand-file-name (name &optional dir)
2847 "Like `expand-file-name' for tramp files." 2884 "Like `expand-file-name' for tramp files.
2885 If the localname part of the given filename starts with \"/../\" then
2886 the result will be a local, non-Tramp, filename."
2848 ;; If DIR is not given, use DEFAULT-DIRECTORY or "/". 2887 ;; If DIR is not given, use DEFAULT-DIRECTORY or "/".
2849 (setq dir (or dir default-directory "/")) 2888 (setq dir (or dir default-directory "/"))
2850 ;; Unless NAME is absolute, concat DIR and NAME. 2889 ;; Unless NAME is absolute, concat DIR and NAME.
2851 (unless (file-name-absolute-p name) 2890 (unless (file-name-absolute-p name)
2852 (setq name (concat (file-name-as-directory dir) name))) 2891 (setq name (concat (file-name-as-directory dir) name)))
2854 (if (not (tramp-tramp-file-p name)) 2893 (if (not (tramp-tramp-file-p name))
2855 (tramp-run-real-handler 'expand-file-name 2894 (tramp-run-real-handler 'expand-file-name
2856 (list name nil)) 2895 (list name nil))
2857 ;; Dissect NAME. 2896 ;; Dissect NAME.
2858 (with-parsed-tramp-file-name name nil 2897 (with-parsed-tramp-file-name name nil
2859 (unless (file-name-absolute-p path) 2898 (unless (file-name-absolute-p localname)
2860 (setq path (concat "~/" path))) 2899 (setq localname (concat "~/" localname)))
2861 (save-excursion 2900 (save-excursion
2862 ;; Tilde expansion if necessary. This needs a shell which 2901 ;; Tilde expansion if necessary. This needs a shell which
2863 ;; groks tilde expansion! The function `tramp-find-shell' is 2902 ;; groks tilde expansion! The function `tramp-find-shell' is
2864 ;; supposed to find such a shell on the remote host. Please 2903 ;; supposed to find such a shell on the remote host. Please
2865 ;; tell me about it when this doesn't work on your system. 2904 ;; tell me about it when this doesn't work on your system.
2866 (when (string-match "\\`\\(~[^/]*\\)\\(.*\\)\\'" path) 2905 (when (string-match "\\`\\(~[^/]*\\)\\(.*\\)\\'" localname)
2867 (let ((uname (match-string 1 path)) 2906 (let ((uname (match-string 1 localname))
2868 (fname (match-string 2 path))) 2907 (fname (match-string 2 localname)))
2869 ;; CCC fanatic error checking? 2908 ;; CCC fanatic error checking?
2870 (set-buffer (tramp-get-buffer multi-method method user host)) 2909 (set-buffer (tramp-get-buffer multi-method method user host))
2871 (erase-buffer) 2910 (erase-buffer)
2872 (tramp-send-command 2911 (tramp-send-command
2873 multi-method method user host 2912 multi-method method user host
2874 (format "cd %s; pwd" uname) 2913 (format "cd %s; pwd" uname)
2875 t) 2914 t)
2876 (tramp-wait-for-output) 2915 (tramp-wait-for-output)
2877 (goto-char (point-min)) 2916 (goto-char (point-min))
2878 (setq uname (buffer-substring (point) (tramp-line-end-position))) 2917 (setq uname (buffer-substring (point) (tramp-line-end-position)))
2879 (setq path (concat uname fname)) 2918 (setq localname (concat uname fname))
2880 (erase-buffer))) 2919 (erase-buffer)))
2881 ;; No tilde characters in file name, do normal 2920 ;; Look if localname starts with "/../" construct. If this is
2882 ;; expand-file-name (this does "/./" and "/../"). We bind 2921 ;; the case, then we return a local name instead of a remote name.
2883 ;; directory-sep-char here for XEmacs on Windows, which would 2922 (if (string-match "^/\\.\\./" localname)
2884 ;; otherwise use backslash. 2923 (expand-file-name (substring localname 3))
2885 (let ((directory-sep-char ?/)) 2924 ;; No tilde characters in file name, do normal
2886 (tramp-make-tramp-file-name 2925 ;; expand-file-name (this does "/./" and "/../"). We bind
2887 multi-method method user host 2926 ;; directory-sep-char here for XEmacs on Windows, which
2888 (tramp-drop-volume-letter 2927 ;; would otherwise use backslash.
2889 (tramp-run-real-handler 'expand-file-name (list path))))))))) 2928 (let ((directory-sep-char ?/))
2929 (tramp-make-tramp-file-name
2930 multi-method method user host
2931 (tramp-drop-volume-letter
2932 (tramp-run-real-handler 'expand-file-name
2933 (list localname))))))))))
2890 2934
2891 ;; Remote commands. 2935 ;; Remote commands.
2892 2936
2893 (defun tramp-handle-shell-command (command &optional output-buffer error-buffer) 2937 (defun tramp-handle-shell-command (command &optional output-buffer error-buffer)
2894 "Like `shell-command' for tramp files. 2938 "Like `shell-command' for tramp files.
2902 (when error-buffer 2946 (when error-buffer
2903 (error "Tramp doesn't grok optional third arg ERROR-BUFFER, yet")) 2947 (error "Tramp doesn't grok optional third arg ERROR-BUFFER, yet"))
2904 (save-excursion 2948 (save-excursion
2905 (tramp-barf-unless-okay 2949 (tramp-barf-unless-okay
2906 multi-method method user host 2950 multi-method method user host
2907 (format "cd %s" (tramp-shell-quote-argument path)) 2951 (format "cd %s" (tramp-shell-quote-argument localname))
2908 nil 'file-error 2952 nil 'file-error
2909 "tramp-handle-shell-command: Couldn't `cd %s'" 2953 "tramp-handle-shell-command: Couldn't `cd %s'"
2910 (tramp-shell-quote-argument path)) 2954 (tramp-shell-quote-argument localname))
2911 (tramp-send-command multi-method method user host 2955 (tramp-send-command multi-method method user host
2912 (concat command "; tramp_old_status=$?")) 2956 (concat command "; tramp_old_status=$?"))
2913 ;; This will break if the shell command prints "/////" 2957 ;; This will break if the shell command prints "/////"
2914 ;; somewhere. Let's just hope for the best... 2958 ;; somewhere. Let's just hope for the best...
2915 (tramp-wait-for-output)) 2959 (tramp-wait-for-output))
2992 nil output-buf nil 3036 nil output-buf nil
2993 (append rcp-args 3037 (append rcp-args
2994 (list 3038 (list
2995 (tramp-make-rcp-program-file-name 3039 (tramp-make-rcp-program-file-name
2996 user host 3040 user host
2997 (tramp-shell-quote-argument path)) 3041 (tramp-shell-quote-argument localname))
2998 tmpfil)))) 3042 tmpfil))))
2999 (pop-to-buffer output-buf) 3043 (pop-to-buffer output-buf)
3000 (error 3044 (error
3001 (concat "tramp-handle-file-local-copy: `%s' didn't work, " 3045 (concat "tramp-handle-file-local-copy: `%s' didn't work, "
3002 "see buffer `%s' for details") 3046 "see buffer `%s' for details")
3011 ;; tramp-current-user, tramp-current-host. 3055 ;; tramp-current-user, tramp-current-host.
3012 (set-buffer tramp-buf) 3056 (set-buffer tramp-buf)
3013 (tramp-message 5 "Encoding remote file %s..." filename) 3057 (tramp-message 5 "Encoding remote file %s..." filename)
3014 (tramp-barf-unless-okay 3058 (tramp-barf-unless-okay
3015 multi-method method user host 3059 multi-method method user host
3016 (concat rem-enc " < " (tramp-shell-quote-argument path)) 3060 (concat rem-enc " < " (tramp-shell-quote-argument localname))
3017 nil 'file-error 3061 nil 'file-error
3018 "Encoding remote file failed, see buffer `%s' for details" 3062 "Encoding remote file failed, see buffer `%s' for details"
3019 tramp-buf) 3063 tramp-buf)
3020 ;; Remove trailing status code 3064 ;; Remove trailing status code
3021 (goto-char (point-max)) 3065 (goto-char (point-max))
3170 (let ((argl (append rcp-args 3214 (let ((argl (append rcp-args
3171 (list 3215 (list
3172 tmpfil 3216 tmpfil
3173 (tramp-make-rcp-program-file-name 3217 (tramp-make-rcp-program-file-name
3174 user host 3218 user host
3175 (tramp-shell-quote-argument path)))))) 3219 (tramp-shell-quote-argument localname))))))
3176 (tramp-message-for-buffer 3220 (tramp-message-for-buffer
3177 multi-method method user host 3221 multi-method method user host
3178 6 "Writing tmp file using `%s'..." rcp-program) 3222 6 "Writing tmp file using `%s'..." rcp-program)
3179 (save-excursion (set-buffer trampbuf) (erase-buffer)) 3223 (save-excursion (set-buffer trampbuf) (erase-buffer))
3180 (when tramp-debug-buffer 3224 (when tramp-debug-buffer
3244 5 "Decoding region into remote file %s..." filename) 3288 5 "Decoding region into remote file %s..." filename)
3245 (tramp-send-command 3289 (tramp-send-command
3246 multi-method method user host 3290 multi-method method user host
3247 (format "%s >%s <<'EOF'" 3291 (format "%s >%s <<'EOF'"
3248 rem-dec 3292 rem-dec
3249 (tramp-shell-quote-argument path))) 3293 (tramp-shell-quote-argument localname)))
3250 (set-buffer tmpbuf) 3294 (set-buffer tmpbuf)
3251 (tramp-message-for-buffer 3295 (tramp-message-for-buffer
3252 multi-method method user host 3296 multi-method method user host
3253 6 "Sending data to remote host...") 3297 6 "Sending data to remote host...")
3254 (tramp-send-region multi-method method user host 3298 (tramp-send-string multi-method method user host
3255 (point-min) (point-max)) 3299 (buffer-string))
3256 ;; wait for remote decoding to complete 3300 ;; wait for remote decoding to complete
3257 (tramp-message-for-buffer 3301 (tramp-message-for-buffer
3258 multi-method method user host 3302 multi-method method user host
3259 6 "Sending end of data token...") 3303 6 "Sending end of data token...")
3260 (tramp-send-command 3304 (tramp-send-command
3290 (eq visit nil) 3334 (eq visit nil)
3291 (stringp visit)) 3335 (stringp visit))
3292 (message "Wrote %s" filename))))) 3336 (message "Wrote %s" filename)))))
3293 3337
3294 ;; Call down to the real handler. 3338 ;; Call down to the real handler.
3295 ;; Because EFS does not play nicely with TRAMP (both systems match an 3339 ;; Because EFS does not play nicely with TRAMP (both systems match a
3296 ;; TRAMP path) it is needed to disable efs as well as tramp for the 3340 ;; TRAMP file name) it is needed to disable efs as well as tramp for the
3297 ;; operation. 3341 ;; operation.
3298 ;; 3342 ;;
3299 ;; Other than that, this is the canon file-handler code that the doco 3343 ;; Other than that, this is the canon file-handler code that the doco
3300 ;; says should be used here. Which is nice. 3344 ;; says should be used here. Which is nice.
3301 ;; 3345 ;;
3302 ;; Under XEmacs current, EFS also hooks in as 3346 ;; Under XEmacs current, EFS also hooks in as
3303 ;; efs-sifn-handler-function to handle any path with environment 3347 ;; efs-sifn-handler-function to handle any filename with environment
3304 ;; variables. This has two implications: 3348 ;; variables. This has two implications:
3305 ;; 1) That EFS may not be completely dead (yet) for TRAMP paths 3349 ;; 1) That EFS may not be completely dead (yet) for TRAMP filenames
3306 ;; 2) That TRAMP might want to do the same thing. 3350 ;; 2) That TRAMP might want to do the same thing.
3307 ;; Details as they come in. 3351 ;; Details as they come in.
3308 ;; 3352 ;;
3309 ;; Daniel Pittman <daniel@danann.net> 3353 ;; Daniel Pittman <daniel@danann.net>
3310 3354
3504 ;;-(let ((comint-file-name-quote-list 3548 ;;-(let ((comint-file-name-quote-list
3505 ;;- (set-difference tramp-file-name-quote-list 3549 ;;- (set-difference tramp-file-name-quote-list
3506 ;;- '(?\* ?\? ?[ ?])))) 3550 ;;- '(?\* ?\? ?[ ?]))))
3507 ;;- (tramp-send-command 3551 ;;- (tramp-send-command
3508 ;;- multi-method method user host 3552 ;;- multi-method method user host
3509 ;;- (format "echo %s" (comint-quote-filename path))) 3553 ;;- (format "echo %s" (comint-quote-filename localname)))
3510 ;;- (tramp-wait-for-output)) 3554 ;;- (tramp-wait-for-output))
3511 (tramp-send-command multi-method method user host 3555 (tramp-send-command multi-method method user host
3512 (format "echo %s" path)) 3556 (format "echo %s" localname))
3513 (tramp-wait-for-output) 3557 (tramp-wait-for-output)
3514 (setq bufstr (buffer-substring (point-min) 3558 (setq bufstr (buffer-substring (point-min)
3515 (tramp-line-end-position))) 3559 (tramp-line-end-position)))
3516 (goto-char (point-min)) 3560 (goto-char (point-min))
3517 (if (string-equal path bufstr) 3561 (if (string-equal localname bufstr)
3518 nil 3562 nil
3519 (insert "(\"") 3563 (insert "(\"")
3520 (while (search-forward " " nil t) 3564 (while (search-forward " " nil t)
3521 (delete-backward-char 1) 3565 (delete-backward-char 1)
3522 (insert "\" \"")) 3566 (insert "\" \""))
3552 3596
3553 ;; Necessary because `tramp-file-name-regexp-unified' and 3597 ;; Necessary because `tramp-file-name-regexp-unified' and
3554 ;; `tramp-completion-file-name-regexp-unified' aren't different. 3598 ;; `tramp-completion-file-name-regexp-unified' aren't different.
3555 ;; If nil, `tramp-completion-run-real-handler' is called (i.e. forwarding to 3599 ;; If nil, `tramp-completion-run-real-handler' is called (i.e. forwarding to
3556 ;; `tramp-file-name-handler'). Otherwise, it takes `tramp-run-real-handler'. 3600 ;; `tramp-file-name-handler'). Otherwise, it takes `tramp-run-real-handler'.
3557 ;; Using `last-input-event' is a little bit risky, because completing a file 3601 ;; Using `last-input-event' is a little bit risky, because completing a file
3558 ;; might require loading other files, like "~/.netrc", and for them it 3602 ;; might require loading other files, like "~/.netrc", and for them it
3559 ;; shouldn't be decided based on that variable. On the other hand, those files 3603 ;; shouldn't be decided based on that variable. On the other hand, those files
3560 ;; shouldn't have partial tramp file name syntax. Maybe another variable should 3604 ;; shouldn't have partial tramp file name syntax. Maybe another variable should
3561 ;; be introduced overwriting this check in such cases. Or we change tramp 3605 ;; be introduced overwriting this check in such cases. Or we change tramp
3562 ;; file name syntax in order to avoid ambiguities, like in XEmacs ... 3606 ;; file name syntax in order to avoid ambiguities, like in XEmacs ...
3585 (tramp-run-real-handler 3629 (tramp-run-real-handler
3586 'file-exists-p (list filename)) 3630 'file-exists-p (list filename))
3587 (tramp-completion-run-real-handler 3631 (tramp-completion-run-real-handler
3588 'file-exists-p (list filename)))) 3632 'file-exists-p (list filename))))
3589 3633
3590 ;; Path manipulation in case of partial TRAMP file names. 3634 ;; Localname manipulation in case of partial TRAMP file names.
3591 (defun tramp-completion-handle-file-name-directory (file) 3635 (defun tramp-completion-handle-file-name-directory (file)
3592 "Like `file-name-directory' but aware of TRAMP files." 3636 "Like `file-name-directory' but aware of TRAMP files."
3593 (if (tramp-completion-mode file) 3637 (if (tramp-completion-mode file)
3594 "/" 3638 "/"
3595 (tramp-completion-run-real-handler 3639 (tramp-completion-run-real-handler
3596 'file-name-directory (list file)))) 3640 'file-name-directory (list file))))
3597 3641
3598 ;; Path manipulation in case of partial TRAMP file names. 3642 ;; Localname manipulation in case of partial TRAMP file names.
3599 (defun tramp-completion-handle-file-name-nondirectory (file) 3643 (defun tramp-completion-handle-file-name-nondirectory (file)
3600 "Like `file-name-nondirectory' but aware of TRAMP files." 3644 "Like `file-name-nondirectory' but aware of TRAMP files."
3601 (substring 3645 (substring
3602 file (length (tramp-completion-handle-file-name-directory file)))) 3646 file (length (tramp-completion-handle-file-name-directory file))))
3603 3647
3623 (let* ((car (car v)) 3667 (let* ((car (car v))
3624 (multi-method (tramp-file-name-multi-method car)) 3668 (multi-method (tramp-file-name-multi-method car))
3625 (method (tramp-file-name-method car)) 3669 (method (tramp-file-name-method car))
3626 (user (tramp-file-name-user car)) 3670 (user (tramp-file-name-user car))
3627 (host (tramp-file-name-host car)) 3671 (host (tramp-file-name-host car))
3628 (path (tramp-file-name-path car)) 3672 (localname (tramp-file-name-localname car))
3629 (m (tramp-find-method multi-method method user host)) 3673 (m (tramp-find-method multi-method method user host))
3630 (tramp-current-user user) ; see `tramp-parse-passwd' 3674 (tramp-current-user user) ; see `tramp-parse-passwd'
3631 all-user-hosts) 3675 all-user-hosts)
3632 3676
3633 (unless (or multi-method ;; Not handled (yet). 3677 (unless (or multi-method ;; Not handled (yet).
3634 path) ;; Nothing to complete 3678 localname) ;; Nothing to complete
3635 3679
3636 (if (or user host) 3680 (if (or user host)
3637 3681
3638 ;; Method dependent user / host combinations 3682 ;; Method dependent user / host combinations
3639 (progn 3683 (progn
3642 (setq all-user-hosts 3686 (setq all-user-hosts
3643 (append all-user-hosts 3687 (append all-user-hosts
3644 (funcall (nth 0 x) (nth 1 x))))) 3688 (funcall (nth 0 x) (nth 1 x)))))
3645 (tramp-get-completion-function m)) 3689 (tramp-get-completion-function m))
3646 3690
3647 (setq result (append result 3691 (setq result (append result
3648 (mapcar 3692 (mapcar
3649 (lambda (x) 3693 (lambda (x)
3650 (tramp-get-completion-user-host 3694 (tramp-get-completion-user-host
3651 method user host (nth 0 x) (nth 1 x))) 3695 method user host (nth 0 x) (nth 1 x)))
3652 (delq nil all-user-hosts))))) 3696 (delq nil all-user-hosts)))))
3673 (mapcar 'list (file-name-all-completions filename directory)))) 3717 (mapcar 'list (file-name-all-completions filename directory))))
3674 3718
3675 ;; I misuse a little bit the tramp-file-name structure in order to handle 3719 ;; I misuse a little bit the tramp-file-name structure in order to handle
3676 ;; completion possibilities for partial methods / user names / host names. 3720 ;; completion possibilities for partial methods / user names / host names.
3677 ;; Return value is a list of tramp-file-name structures according to possible 3721 ;; Return value is a list of tramp-file-name structures according to possible
3678 ;; completions. If "multi-method" or "path" is non-nil it means there 3722 ;; completions. If "multi-method" or "localname" is non-nil it means there
3679 ;; shouldn't be a completion anymore. 3723 ;; shouldn't be a completion anymore.
3680 3724
3681 ;; Expected results: 3725 ;; Expected results:
3682 3726
3683 ;; "/x" "/[x" "/x@" "/[x@" "/x@y" "/[x@y" 3727 ;; "/x" "/[x" "/x@" "/[x@" "/x@y" "/[x@y"
3684 ;; [nil nil nil "x" nil] [nil nil "x" nil nil] [nil nil "x" "y" nil] 3728 ;; [nil nil nil "x" nil] [nil nil "x" nil nil] [nil nil "x" "y" nil]
3685 ;; [nil nil "x" nil nil] 3729 ;; [nil nil "x" nil nil]
3686 ;; [nil "x" nil nil nil] 3730 ;; [nil "x" nil nil nil]
3687 3731
3688 ;; "/x:" "/x:y" "/x:y:" 3732 ;; "/x:" "/x:y" "/x:y:"
3689 ;; [nil nil nil "x" ""] [nil nil nil "x" "y"] [nil "x" nil "y" ""] 3733 ;; [nil nil nil "x" ""] [nil nil nil "x" "y"] [nil "x" nil "y" ""]
3690 ;; "/[x/" "/[x/y" 3734 ;; "/[x/" "/[x/y"
3691 ;; [nil "x" nil "" nil] [nil "x" nil "y" nil] 3735 ;; [nil "x" nil "" nil] [nil "x" nil "y" nil]
3692 ;; [nil "x" "" nil nil] [nil "x" "y" nil nil] 3736 ;; [nil "x" "" nil nil] [nil "x" "y" nil nil]
3693 3737
3755 (delq nil result))) 3799 (delq nil result)))
3756 3800
3757 (defun tramp-completion-dissect-file-name1 (structure name) 3801 (defun tramp-completion-dissect-file-name1 (structure name)
3758 "Returns a `tramp-file-name' structure matching STRUCTURE. 3802 "Returns a `tramp-file-name' structure matching STRUCTURE.
3759 The structure consists of multi-method, remote method, remote user, 3803 The structure consists of multi-method, remote method, remote user,
3760 remote host and remote path name." 3804 remote host and localname (filename on remote host)."
3761 3805
3762 (let (method) 3806 (let (method)
3763 (save-match-data 3807 (save-match-data
3764 (when (string-match (nth 0 structure) name) 3808 (when (string-match (nth 0 structure) name)
3765 (setq method (and (nth 1 structure) 3809 (setq method (and (nth 1 structure)
3769 (make-tramp-file-name 3813 (make-tramp-file-name
3770 :multi-method method 3814 :multi-method method
3771 :method nil 3815 :method nil
3772 :user nil 3816 :user nil
3773 :host nil 3817 :host nil
3774 :path nil) 3818 :localname nil)
3775 (let ((user (and (nth 2 structure) 3819 (let ((user (and (nth 2 structure)
3776 (match-string (nth 2 structure) name))) 3820 (match-string (nth 2 structure) name)))
3777 (host (and (nth 3 structure) 3821 (host (and (nth 3 structure)
3778 (match-string (nth 3 structure) name))) 3822 (match-string (nth 3 structure) name)))
3779 (path (and (nth 4 structure) 3823 (localname (and (nth 4 structure)
3780 (match-string (nth 4 structure) name)))) 3824 (match-string (nth 4 structure) name))))
3781 (make-tramp-file-name 3825 (make-tramp-file-name
3782 :multi-method nil 3826 :multi-method nil
3783 :method method 3827 :method method
3784 :user user 3828 :user user
3785 :host host 3829 :host host
3786 :path path))))))) 3830 :localname localname)))))))
3787 3831
3788 ;; This function returns all possible method completions, adding the 3832 ;; This function returns all possible method completions, adding the
3789 ;; trailing method delimeter. 3833 ;; trailing method delimeter.
3790 (defun tramp-get-completion-methods (partial-method) 3834 (defun tramp-get-completion-methods (partial-method)
3791 "Returns all method completions for PARTIAL-METHOD." 3835 "Returns all method completions for PARTIAL-METHOD."
4044 (save-excursion 4088 (save-excursion
4045 (tramp-send-command-and-check 4089 (tramp-send-command-and-check
4046 (tramp-file-name-multi-method v) (tramp-file-name-method v) 4090 (tramp-file-name-multi-method v) (tramp-file-name-method v)
4047 (tramp-file-name-user v) (tramp-file-name-host v) 4091 (tramp-file-name-user v) (tramp-file-name-host v)
4048 (format "test %s %s" switch 4092 (format "test %s %s" switch
4049 (tramp-shell-quote-argument (tramp-file-name-path v))))))) 4093 (tramp-shell-quote-argument (tramp-file-name-localname v)))))))
4050 4094
4051 (defun tramp-run-test2 (program file1 file2 &optional switch) 4095 (defun tramp-run-test2 (program file1 file2 &optional switch)
4052 "Run `test'-like PROGRAM on the remote system, given FILE1, FILE2. 4096 "Run `test'-like PROGRAM on the remote system, given FILE1, FILE2.
4053 The optional SWITCH is inserted between the two files. 4097 The optional SWITCH is inserted between the two files.
4054 Returns the exit code of the `test' PROGRAM. Barfs if the methods, 4098 Returns the exit code of the `test' PROGRAM. Barfs if the methods,
4061 (method2 (tramp-file-name-method v2)) 4105 (method2 (tramp-file-name-method v2))
4062 (user1 (tramp-file-name-user v1)) 4106 (user1 (tramp-file-name-user v1))
4063 (user2 (tramp-file-name-user v2)) 4107 (user2 (tramp-file-name-user v2))
4064 (host1 (tramp-file-name-host v1)) 4108 (host1 (tramp-file-name-host v1))
4065 (host2 (tramp-file-name-host v2)) 4109 (host2 (tramp-file-name-host v2))
4066 (path1 (tramp-file-name-path v1)) 4110 (localname1 (tramp-file-name-localname v1))
4067 (path2 (tramp-file-name-path v2))) 4111 (localname2 (tramp-file-name-localname v2)))
4068 (unless (and method1 method2 host1 host2 4112 (unless (and method1 method2 host1 host2
4069 (equal mmethod1 mmethod2) 4113 (equal mmethod1 mmethod2)
4070 (equal method1 method2) 4114 (equal method1 method2)
4071 (equal user1 user2) 4115 (equal user1 user2)
4072 (equal host1 host2)) 4116 (equal host1 host2))
4075 (save-excursion 4119 (save-excursion
4076 (tramp-send-command-and-check 4120 (tramp-send-command-and-check
4077 mmethod1 method1 user1 host1 4121 mmethod1 method1 user1 host1
4078 (format "%s %s %s %s" 4122 (format "%s %s %s %s"
4079 program 4123 program
4080 (tramp-shell-quote-argument path1) 4124 (tramp-shell-quote-argument localname1)
4081 (or switch "") 4125 (or switch "")
4082 (tramp-shell-quote-argument path2)))))) 4126 (tramp-shell-quote-argument localname2))))))
4083 4127
4084 (defun tramp-buffer-name (multi-method method user host) 4128 (defun tramp-buffer-name (multi-method method user host)
4085 "A name for the connection buffer for USER at HOST using METHOD." 4129 "A name for the connection buffer for USER at HOST using METHOD."
4086 (cond (multi-method 4130 (cond (multi-method
4087 (tramp-buffer-name-multi-method "tramp" multi-method method user host)) 4131 (tramp-buffer-name-multi-method "tramp" multi-method method user host))
4136 First args METHOD, USER and HOST specify the connection, PROGNAME 4180 First args METHOD, USER and HOST specify the connection, PROGNAME
4137 is the program to search for, and DIRLIST gives the list of directories 4181 is the program to search for, and DIRLIST gives the list of directories
4138 to search. If IGNORE-TILDE is non-nil, directory names starting 4182 to search. If IGNORE-TILDE is non-nil, directory names starting
4139 with `~' will be ignored. 4183 with `~' will be ignored.
4140 4184
4141 Returns the full path name of PROGNAME, if found, and nil otherwise. 4185 Returns the absolute file name of PROGNAME, if found, and nil otherwise.
4142 4186
4143 This function expects to be in the right *tramp* buffer." 4187 This function expects to be in the right *tramp* buffer."
4144 (let (result) 4188 (let (result)
4145 (when ignore-tilde 4189 (when ignore-tilde
4146 ;; Remove all ~/foo directories from dirlist. In Emacs 20, 4190 ;; Remove all ~/foo directories from dirlist. In Emacs 20,
4236 (not (tramp-handle-file-exists-p nonexisting))) 4280 (not (tramp-handle-file-exists-p nonexisting)))
4237 (and (setq tramp-file-exists-command "ls -d %s") 4281 (and (setq tramp-file-exists-command "ls -d %s")
4238 (tramp-handle-file-exists-p existing) 4282 (tramp-handle-file-exists-p existing)
4239 (not (tramp-handle-file-exists-p nonexisting)))) 4283 (not (tramp-handle-file-exists-p nonexisting))))
4240 (error "Couldn't find command to check if file exists.")))) 4284 (error "Couldn't find command to check if file exists."))))
4241 4285
4242 4286
4243 ;; CCC test ksh or bash found for tilde expansion? 4287 ;; CCC test ksh or bash found for tilde expansion?
4244 (defun tramp-find-shell (multi-method method user host) 4288 (defun tramp-find-shell (multi-method method user host)
4245 "Find a shell on the remote host which groks tilde expansion." 4289 "Find a shell on the remote host which groks tilde expansion."
4246 (let ((shell nil)) 4290 (let ((shell nil))
4292 (t (tramp-message 5 "Remote `%s' groks tilde expansion, good" 4336 (t (tramp-message 5 "Remote `%s' groks tilde expansion, good"
4293 (tramp-get-remote-sh multi-method method user host)))))) 4337 (tramp-get-remote-sh multi-method method user host))))))
4294 4338
4295 (defun tramp-check-ls-command (multi-method method user host cmd) 4339 (defun tramp-check-ls-command (multi-method method user host cmd)
4296 "Checks whether the given `ls' executable groks `-n'. 4340 "Checks whether the given `ls' executable groks `-n'.
4297 METHOD, USER and HOST specify the connection, CMD (the full path name of) 4341 METHOD, USER and HOST specify the connection, CMD (the absolute file name of)
4298 the `ls' executable. Returns t if CMD supports the `-n' option, nil 4342 the `ls' executable. Returns t if CMD supports the `-n' option, nil
4299 otherwise." 4343 otherwise."
4300 (tramp-message 9 "Checking remote `%s' command for `-n' option" 4344 (tramp-message 9 "Checking remote `%s' command for `-n' option"
4301 cmd) 4345 cmd)
4302 (when (tramp-handle-file-executable-p 4346 (when (tramp-handle-file-executable-p
4335 (or 4379 (or
4336 (tramp-check-ls-commands multi-method method user host "ls" tramp-remote-path) 4380 (tramp-check-ls-commands multi-method method user host "ls" tramp-remote-path)
4337 (tramp-check-ls-commands multi-method method user host "gnuls" tramp-remote-path) 4381 (tramp-check-ls-commands multi-method method user host "gnuls" tramp-remote-path)
4338 (tramp-check-ls-commands multi-method method user host "gls" tramp-remote-path))) 4382 (tramp-check-ls-commands multi-method method user host "gls" tramp-remote-path)))
4339 4383
4340 ;; ------------------------------------------------------------ 4384 ;; ------------------------------------------------------------
4341 ;; -- Functions for establishing connection -- 4385 ;; -- Functions for establishing connection --
4342 ;; ------------------------------------------------------------ 4386 ;; ------------------------------------------------------------
4343 4387
4344 ;; The following functions are actions to be taken when seeing certain 4388 ;; The following functions are actions to be taken when seeing certain
4345 ;; prompts from the remote host. See the variable 4389 ;; prompts from the remote host. See the variable
4346 ;; `tramp-actions-before-shell' for usage of these functions. 4390 ;; `tramp-actions-before-shell' for usage of these functions.
4347 4391
4536 (error "Cannot use out-of-band method `%s' with telnet connection method" 4580 (error "Cannot use out-of-band method `%s' with telnet connection method"
4537 method)) 4581 method))
4538 (when multi-method 4582 (when multi-method
4539 (error "Cannot multi-connect using telnet connection method")) 4583 (error "Cannot multi-connect using telnet connection method"))
4540 (tramp-pre-connection multi-method method user host) 4584 (tramp-pre-connection multi-method method user host)
4541 (tramp-message 7 "Opening connection for %s@%s using %s..." 4585 (tramp-message 7 "Opening connection for %s@%s using %s..."
4542 (or user (user-login-name)) host method) 4586 (or user (user-login-name)) host method)
4543 (let ((process-environment (copy-sequence process-environment))) 4587 (let ((process-environment (copy-sequence process-environment)))
4544 (setenv "TERM" tramp-terminal-type) 4588 (setenv "TERM" tramp-terminal-type)
4545 (let* ((default-directory (tramp-temporary-file-directory)) 4589 (let* ((default-directory (tramp-temporary-file-directory))
4546 ;; If we omit the conditional here, then we would use 4590 ;; If we omit the conditional here, then we would use
4570 tramp-actions-before-shell) 4614 tramp-actions-before-shell)
4571 (tramp-open-connection-setup-interactive-shell 4615 (tramp-open-connection-setup-interactive-shell
4572 p multi-method method user host) 4616 p multi-method method user host)
4573 (tramp-post-connection multi-method method user host))))) 4617 (tramp-post-connection multi-method method user host)))))
4574 4618
4575 4619
4576 (defun tramp-open-connection-rsh (multi-method method user host) 4620 (defun tramp-open-connection-rsh (multi-method method user host)
4577 "Open a connection using an rsh METHOD. 4621 "Open a connection using an rsh METHOD.
4578 This starts the command `rsh HOST -l USER'[*], then waits for a remote 4622 This starts the command `rsh HOST -l USER'[*], then waits for a remote
4579 password or shell prompt. If a password prompt is seen, the user is 4623 password or shell prompt. If a password prompt is seen, the user is
4580 queried for a password, this function sends the password to the remote 4624 queried for a password, this function sends the password to the remote
4601 (save-match-data 4645 (save-match-data
4602 (when multi-method 4646 (when multi-method
4603 (error "Cannot multi-connect using rsh connection method")) 4647 (error "Cannot multi-connect using rsh connection method"))
4604 (tramp-pre-connection multi-method method user host) 4648 (tramp-pre-connection multi-method method user host)
4605 (if (and user (not (string= user ""))) 4649 (if (and user (not (string= user "")))
4606 (tramp-message 7 "Opening connection for %s@%s using %s..." 4650 (tramp-message 7 "Opening connection for %s@%s using %s..."
4607 user host method) 4651 user host method)
4608 (tramp-message 7 "Opening connection at %s using %s..." host method)) 4652 (tramp-message 7 "Opening connection at %s using %s..." host method))
4609 (let ((process-environment (copy-sequence process-environment)) 4653 (let ((process-environment (copy-sequence process-environment))
4610 (bufnam (tramp-buffer-name multi-method method user host)) 4654 (bufnam (tramp-buffer-name multi-method method user host))
4611 (buf (tramp-get-buffer multi-method method user host)) 4655 (buf (tramp-get-buffer multi-method method user host))
4629 ;; we use nil in these cases. Which one is right? 4673 ;; we use nil in these cases. Which one is right?
4630 (coding-system-for-read (unless (and (not (featurep 'xemacs)) 4674 (coding-system-for-read (unless (and (not (featurep 'xemacs))
4631 (> emacs-major-version 20)) 4675 (> emacs-major-version 20))
4632 tramp-dos-coding-system)) 4676 tramp-dos-coding-system))
4633 (p (if (and user (not (string= user ""))) 4677 (p (if (and user (not (string= user "")))
4634 (apply #'start-process bufnam buf rsh-program 4678 (apply #'start-process bufnam buf rsh-program
4635 host "-l" user rsh-args) 4679 host "-l" user rsh-args)
4636 (apply #'start-process bufnam buf rsh-program 4680 (apply #'start-process bufnam buf rsh-program
4637 host rsh-args))) 4681 host rsh-args)))
4638 (found nil)) 4682 (found nil))
4639 (process-kill-without-query p) 4683 (process-kill-without-query p)
4640 4684
4641 (set-buffer buf) 4685 (set-buffer buf)
4701 (set-buffer (tramp-get-buffer multi-method method user host)) 4745 (set-buffer (tramp-get-buffer multi-method method user host))
4702 (tramp-process-actions p multi-method method user host 4746 (tramp-process-actions p multi-method method user host
4703 tramp-actions-before-shell) 4747 tramp-actions-before-shell)
4704 (tramp-open-connection-setup-interactive-shell 4748 (tramp-open-connection-setup-interactive-shell
4705 p multi-method method user host) 4749 p multi-method method user host)
4706 (tramp-post-connection multi-method method 4750 (tramp-post-connection multi-method method
4707 user host))))) 4751 user host)))))
4708 4752
4709 ;; HHH: Not Changed. Multi method. It is not clear to me how this can 4753 ;; HHH: Not Changed. Multi method. It is not clear to me how this can
4710 ;; handle not giving a user name in the "file name". 4754 ;; handle not giving a user name in the "file name".
4711 ;; 4755 ;;
4712 ;; This is more difficult than for the single-hop method. In the 4756 ;; This is more difficult than for the single-hop method. In the
4713 ;; multi-hop-method, the desired behaviour should be that the 4757 ;; multi-hop-method, the desired behaviour should be that the
4714 ;; user must specify names for the telnet hops of which the user 4758 ;; user must specify names for the telnet hops of which the user
4774 (tramp-open-connection-setup-interactive-shell 4818 (tramp-open-connection-setup-interactive-shell
4775 p multi-method method user host) 4819 p multi-method method user host)
4776 (tramp-post-connection multi-method method user host))))) 4820 (tramp-post-connection multi-method method user host)))))
4777 4821
4778 ;; HHH: Changed. Multi method. Don't know how to handle this in the case 4822 ;; HHH: Changed. Multi method. Don't know how to handle this in the case
4779 ;; of no user name provided. Hack to make it work as it did before: 4823 ;; of no user name provided. Hack to make it work as it did before:
4780 ;; changed `user' to `(or user (user-login-name))' in the places where 4824 ;; changed `user' to `(or user (user-login-name))' in the places where
4781 ;; the value is actually used. 4825 ;; the value is actually used.
4782 (defun tramp-multi-connect-telnet (p method user host command) 4826 (defun tramp-multi-connect-telnet (p method user host command)
4783 "Issue `telnet' command. 4827 "Issue `telnet' command.
4784 Uses shell COMMAND to issue a `telnet' command to log in as USER to 4828 Uses shell COMMAND to issue a `telnet' command to log in as USER to
4796 (tramp-message 9 "Sending telnet command `%s'" cmd1) 4840 (tramp-message 9 "Sending telnet command `%s'" cmd1)
4797 (process-send-string p cmd) 4841 (process-send-string p cmd)
4798 (tramp-process-multi-actions p method user host 4842 (tramp-process-multi-actions p method user host
4799 tramp-multi-actions))) 4843 tramp-multi-actions)))
4800 4844
4801 ;; HHH: Changed. Multi method. Don't know how to handle this in the case 4845 ;; HHH: Changed. Multi method. Don't know how to handle this in the case
4802 ;; of no user name provided. Hack to make it work as it did before: 4846 ;; of no user name provided. Hack to make it work as it did before:
4803 ;; changed `user' to `(or user (user-login-name))' in the places where 4847 ;; changed `user' to `(or user (user-login-name))' in the places where
4804 ;; the value is actually used. 4848 ;; the value is actually used.
4805 (defun tramp-multi-connect-rlogin (p method user host command) 4849 (defun tramp-multi-connect-rlogin (p method user host command)
4806 "Issue `rlogin' command. 4850 "Issue `rlogin' command.
4807 Uses shell COMMAND to issue an `rlogin' command to log in as USER to 4851 Uses shell COMMAND to issue an `rlogin' command to log in as USER to
4822 (tramp-message 9 "Sending rlogin command `%s'" cmd1) 4866 (tramp-message 9 "Sending rlogin command `%s'" cmd1)
4823 (process-send-string p cmd) 4867 (process-send-string p cmd)
4824 (tramp-process-multi-actions p method user host 4868 (tramp-process-multi-actions p method user host
4825 tramp-multi-actions))) 4869 tramp-multi-actions)))
4826 4870
4827 ;; HHH: Changed. Multi method. Don't know how to handle this in the case 4871 ;; HHH: Changed. Multi method. Don't know how to handle this in the case
4828 ;; of no user name provided. Hack to make it work as it did before: 4872 ;; of no user name provided. Hack to make it work as it did before:
4829 ;; changed `user' to `(or user (user-login-name))' in the places where 4873 ;; changed `user' to `(or user (user-login-name))' in the places where
4830 ;; the value is actually used. 4874 ;; the value is actually used.
4831 (defun tramp-multi-connect-su (p method user host command) 4875 (defun tramp-multi-connect-su (p method user host command)
4832 "Issue `su' command. 4876 "Issue `su' command.
4833 Uses shell COMMAND to issue a `su' command to log in as USER on 4877 Uses shell COMMAND to issue a `su' command to log in as USER on
4932 ;; example, if $PS1 has "${CWD}" in the value, then ksh will display 4976 ;; example, if $PS1 has "${CWD}" in the value, then ksh will display
4933 ;; the current working directory but /bin/sh will display a dollar 4977 ;; the current working directory but /bin/sh will display a dollar
4934 ;; sign. The following command line sets $PS1 to a sane value, and 4978 ;; sign. The following command line sets $PS1 to a sane value, and
4935 ;; works under Bourne-ish shells as well as csh-like shells. Daniel 4979 ;; works under Bourne-ish shells as well as csh-like shells. Daniel
4936 ;; Pittman reports that the unusual positioning of the single quotes 4980 ;; Pittman reports that the unusual positioning of the single quotes
4937 ;; makes it work under `rc', too. 4981 ;; makes it work under `rc', too. We also unset the variable $ENV
4938 (process-send-string nil (format "exec env 'PS1=$ ' %s%s" 4982 ;; because that is read by some sh implementations (eg, bash when
4983 ;; called as sh) on startup; this way, we avoid the startup file
4984 ;; clobbering $PS1.
4985 (process-send-string nil (format "exec env 'ENV=' 'PS1=$ ' %s%s"
4939 (tramp-get-remote-sh 4986 (tramp-get-remote-sh
4940 multi-method method user host) 4987 multi-method method user host)
4941 tramp-rsh-end-of-line)) 4988 tramp-rsh-end-of-line))
4942 (when tramp-debug-buffer 4989 (when tramp-debug-buffer
4943 (save-excursion 4990 (save-excursion
5157 "test -n \"`find $1 -prune -newer $2 -print`\"" tramp-rsh-end-of-line 5204 "test -n \"`find $1 -prune -newer $2 -print`\"" tramp-rsh-end-of-line
5158 "}"))) 5205 "}")))
5159 (tramp-wait-for-output) 5206 (tramp-wait-for-output)
5160 ;; Send the fallback `uudecode' script. 5207 ;; Send the fallback `uudecode' script.
5161 (erase-buffer) 5208 (erase-buffer)
5162 (tramp-send-linewise multi-method method user host tramp-uudecode) 5209 (tramp-send-string multi-method method user host tramp-uudecode)
5163 (tramp-wait-for-output) 5210 (tramp-wait-for-output)
5164 ;; Find a `perl'. 5211 ;; Find a `perl'.
5165 (erase-buffer) 5212 (erase-buffer)
5166 (let ((tramp-remote-perl 5213 (let ((tramp-remote-perl
5167 (or (tramp-find-executable multi-method method user host 5214 (or (tramp-find-executable multi-method method user host
5172 (tramp-set-connection-property "perl" tramp-remote-perl 5219 (tramp-set-connection-property "perl" tramp-remote-perl
5173 multi-method method user host) 5220 multi-method method user host)
5174 ;; Set up stat in Perl if we can. 5221 ;; Set up stat in Perl if we can.
5175 (when tramp-remote-perl 5222 (when tramp-remote-perl
5176 (tramp-message 5 "Sending the Perl `file-attributes' implementation.") 5223 (tramp-message 5 "Sending the Perl `file-attributes' implementation.")
5177 (tramp-send-linewise 5224 (tramp-send-string
5178 multi-method method user host 5225 multi-method method user host
5179 (concat "tramp_file_attributes () {\n" 5226 (concat "tramp_file_attributes () {\n"
5180 tramp-remote-perl 5227 tramp-remote-perl
5181 " -e '" tramp-perl-file-attributes "' $1 2>/dev/null\n" 5228 " -e '" tramp-perl-file-attributes "' $1 2>/dev/null\n"
5182 "}")) 5229 "}"))
5184 (unless (tramp-get-rcp-program 5231 (unless (tramp-get-rcp-program
5185 multi-method 5232 multi-method
5186 (tramp-find-method multi-method method user host) 5233 (tramp-find-method multi-method method user host)
5187 user host) 5234 user host)
5188 (tramp-message 5 "Sending the Perl `mime-encode' implementations.") 5235 (tramp-message 5 "Sending the Perl `mime-encode' implementations.")
5189 (tramp-send-linewise 5236 (tramp-send-string
5190 multi-method method user host 5237 multi-method method user host
5191 (concat "tramp_encode () {\n" 5238 (concat "tramp_encode () {\n"
5192 (format tramp-perl-encode tramp-remote-perl) 5239 (format tramp-perl-encode tramp-remote-perl)
5193 " 2>/dev/null" 5240 " 2>/dev/null"
5194 "\n}")) 5241 "\n}"))
5195 (tramp-wait-for-output) 5242 (tramp-wait-for-output)
5196 (tramp-send-linewise 5243 (tramp-send-string
5197 multi-method method user host 5244 multi-method method user host
5198 (concat "tramp_encode_with_module () {\n" 5245 (concat "tramp_encode_with_module () {\n"
5199 (format tramp-perl-encode-with-module tramp-remote-perl) 5246 (format tramp-perl-encode-with-module tramp-remote-perl)
5200 " 2>/dev/null" 5247 " 2>/dev/null"
5201 "\n}")) 5248 "\n}"))
5202 (tramp-wait-for-output) 5249 (tramp-wait-for-output)
5203 (tramp-message 5 "Sending the Perl `mime-decode' implementations.") 5250 (tramp-message 5 "Sending the Perl `mime-decode' implementations.")
5204 (tramp-send-linewise 5251 (tramp-send-string
5205 multi-method method user host 5252 multi-method method user host
5206 (concat "tramp_decode () {\n" 5253 (concat "tramp_decode () {\n"
5207 (format tramp-perl-decode tramp-remote-perl) 5254 (format tramp-perl-decode tramp-remote-perl)
5208 " 2>/dev/null" 5255 " 2>/dev/null"
5209 "\n}")) 5256 "\n}"))
5210 (tramp-wait-for-output) 5257 (tramp-wait-for-output)
5211 (tramp-send-linewise 5258 (tramp-send-string
5212 multi-method method user host 5259 multi-method method user host
5213 (concat "tramp_decode_with_module () {\n" 5260 (concat "tramp_decode_with_module () {\n"
5214 (format tramp-perl-decode-with-module tramp-remote-perl) 5261 (format tramp-perl-decode-with-module tramp-remote-perl)
5215 " 2>/dev/null" 5262 " 2>/dev/null"
5216 "\n}")) 5263 "\n}"))
5466 (unless noerase (erase-buffer)) 5513 (unless noerase (erase-buffer))
5467 (setq proc (get-buffer-process (current-buffer))) 5514 (setq proc (get-buffer-process (current-buffer)))
5468 (process-send-string proc 5515 (process-send-string proc
5469 (concat command tramp-rsh-end-of-line)))) 5516 (concat command tramp-rsh-end-of-line))))
5470 5517
5471 ;; It seems that Tru64 Unix does not like it if long strings are sent
5472 ;; to it in one go. (This happens when sending the Perl
5473 ;; `file-attributes' implementation, for instance.) Therefore, we
5474 ;; have this function which waits a bit at each line.
5475 (defun tramp-send-linewise
5476 (multi-method method user host string &optional noerase)
5477 "Send the STRING to USER at HOST linewise.
5478 Erases temporary buffer before sending the STRING (unless NOERASE
5479 is true).
5480
5481 The STRING is expected to use Unix line-endings, but the lines sent to
5482 the remote host use line-endings as defined in the variable
5483 `tramp-rsh-end-of-line'."
5484 (tramp-maybe-open-connection multi-method method user host)
5485 (when tramp-debug-buffer
5486 (save-excursion
5487 (set-buffer (tramp-get-debug-buffer multi-method method user host))
5488 (goto-char (point-max))
5489 (tramp-insert-with-face 'bold (format "$ %s\n" string))))
5490 (let ((proc nil)
5491 (lines (split-string string "\n")))
5492 (set-buffer (tramp-get-buffer multi-method method user host))
5493 (unless noerase (erase-buffer))
5494 (setq proc (get-buffer-process (current-buffer)))
5495 (mapcar (lambda (x)
5496 (sleep-for 0.1)
5497 (process-send-string proc
5498 (concat x tramp-rsh-end-of-line)))
5499 lines)))
5500
5501 (defun tramp-wait-for-output (&optional timeout) 5518 (defun tramp-wait-for-output (&optional timeout)
5502 "Wait for output from remote rsh command." 5519 "Wait for output from remote rsh command."
5503 (let ((proc (get-buffer-process (current-buffer))) 5520 (let ((proc (get-buffer-process (current-buffer)))
5504 (found nil) 5521 (found nil)
5505 (start-time (current-time)) 5522 (start-time (current-time))
5600 ;; CCC: really pop-to-buffer? Maybe it's appropriate to be more 5617 ;; CCC: really pop-to-buffer? Maybe it's appropriate to be more
5601 ;; silent. 5618 ;; silent.
5602 (pop-to-buffer (current-buffer)) 5619 (pop-to-buffer (current-buffer))
5603 (funcall 'signal signal (apply 'format fmt args)))) 5620 (funcall 'signal signal (apply 'format fmt args))))
5604 5621
5605 ;; Chunked sending kluge. We set this to 500 just to be on the 5622 ;; It seems that Tru64 Unix does not like it if long strings are sent
5606 ;; safe side; some ssh connections appear to drop bytes when data 5623 ;; to it in one go. (This happens when sending the Perl
5607 ;; is sent too quickly. 5624 ;; `file-attributes' implementation, for instance.) Therefore, we
5608 ;; This happens when using `ssh' method using GNU Emacs 20.7.1 5625 ;; have this function which waits a bit at each line.
5609 ;; (hppa1.1-hp-hpux10.20, Motif). (The connection is made to 5626 (defun tramp-send-string
5610 ;; localhost.) 5627 (multi-method method user host string)
5611 (defvar tramp-chunksize 500 5628 "Send the STRING to USER at HOST using METHOD.
5612 "If non-nil, chunksize for sending things to remote host.") 5629
5613 5630 The STRING is expected to use Unix line-endings, but the lines sent to
5614 (defun tramp-send-region (multi-method method user host start end) 5631 the remote host use line-endings as defined in the variable
5615 "Send the region from START to END to remote command 5632 `tramp-rsh-end-of-line'."
5616 running as USER on HOST using METHOD."
5617 (let ((proc (get-buffer-process 5633 (let ((proc (get-buffer-process
5618 (tramp-get-buffer multi-method method user host)))) 5634 (tramp-get-buffer multi-method method user host))))
5619 (unless proc 5635 (unless proc
5620 (error "Can't send region to remote host -- not logged in")) 5636 (error "Can't send string to remote host -- not logged in"))
5637 ;; debug message
5638 (when tramp-debug-buffer
5639 (save-excursion
5640 (set-buffer (tramp-get-debug-buffer multi-method method user host))
5641 (goto-char (point-max))
5642 (tramp-insert-with-face 'bold (format "$ %s\n" string))))
5643 ;; replace "\n" by `tramp-rsh-end-of-line'
5644 (setq string
5645 (mapconcat 'identity
5646 (split-string string "\n")
5647 tramp-rsh-end-of-line))
5648 (unless (string-equal (substring string -1) tramp-rsh-end-of-line)
5649 (setq string (concat string tramp-rsh-end-of-line)))
5650 ;; send the string
5621 (if (and tramp-chunksize (not (zerop tramp-chunksize))) 5651 (if (and tramp-chunksize (not (zerop tramp-chunksize)))
5622 (let ((pos start)) 5652 (let ((pos 0)
5653 (end (length string)))
5623 (while (< pos end) 5654 (while (< pos end)
5624 (tramp-message-for-buffer 5655 (tramp-message-for-buffer
5625 multi-method method user host 10 5656 multi-method method user host 10
5626 "Sending chunk from %s to %s" pos end) 5657 "Sending chunk from %s to %s"
5627 (process-send-region proc 5658 pos (min (+ pos tramp-chunksize) end))
5628 pos 5659 (process-send-string
5629 (min (+ pos tramp-chunksize) 5660 proc (substring string pos (min (+ pos tramp-chunksize) end)))
5630 end))
5631 (setq pos (+ pos tramp-chunksize)) 5661 (setq pos (+ pos tramp-chunksize))
5632 (sleep-for 0.1))) 5662 (sleep-for 0.1)))
5633 (process-send-region proc start end)) 5663 (process-send-string proc string))))
5634 (when tramp-debug-buffer
5635 (append-to-buffer
5636 (tramp-get-debug-buffer multi-method method user host)
5637 start end))))
5638 5664
5639 (defun tramp-send-eof (multi-method method user host) 5665 (defun tramp-send-eof (multi-method method user host)
5640 "Send EOF to the remote end. 5666 "Send EOF to the remote end.
5641 METHOD, HOST and USER specify the connection." 5667 METHOD, HOST and USER specify the connection."
5642 (let ((proc (get-buffer-process 5668 (let ((proc (get-buffer-process
5787 (format "[%c%c]" (downcase c) (upcase c)))) 5813 (format "[%c%c]" (downcase c) (upcase c))))
5788 string 5814 string
5789 "")) 5815 ""))
5790 5816
5791 5817
5792 ;; ------------------------------------------------------------ 5818 ;; ------------------------------------------------------------
5793 ;; -- TRAMP file names -- 5819 ;; -- TRAMP file names --
5794 ;; ------------------------------------------------------------ 5820 ;; ------------------------------------------------------------
5795 ;; Conversion functions between external representation and 5821 ;; Conversion functions between external representation and
5796 ;; internal data structure. Convenience functions for internal 5822 ;; internal data structure. Convenience functions for internal
5797 ;; data structure. 5823 ;; data structure.
5798 5824
5799 (defstruct tramp-file-name multi-method method user host path) 5825 (defstruct tramp-file-name multi-method method user host localname)
5800 5826
5801 (defun tramp-tramp-file-p (name) 5827 (defun tramp-tramp-file-p (name)
5802 "Return t iff NAME is a tramp file." 5828 "Return t iff NAME is a tramp file."
5803 (save-match-data 5829 (save-match-data
5804 (string-match tramp-file-name-regexp name))) 5830 (string-match tramp-file-name-regexp name)))
5805 5831
5806 ;; HHH: Changed. Used to assign the return value of (user-login-name) 5832 ;; HHH: Changed. Used to assign the return value of (user-login-name)
5807 ;; to the `user' part of the structure if a user name was not 5833 ;; to the `user' part of the structure if a user name was not
5808 ;; provided, now it assigns nil. 5834 ;; provided, now it assigns nil.
5809 (defun tramp-dissect-file-name (name) 5835 (defun tramp-dissect-file-name (name)
5810 "Return an `tramp-file-name' structure. 5836 "Return an `tramp-file-name' structure.
5811 The structure consists of remote method, remote user, remote host and 5837 The structure consists of remote method, remote user, remote host and
5812 remote path name." 5838 localname (file name on remote host)."
5813 (save-match-data 5839 (save-match-data
5814 (let* ((match (string-match (nth 0 tramp-file-name-structure) name)) 5840 (let* ((match (string-match (nth 0 tramp-file-name-structure) name))
5815 (method 5841 (method
5816 ; single-hop 5842 ; single-hop
5817 (if match (match-string (nth 1 tramp-file-name-structure) name) 5843 (if match (match-string (nth 1 tramp-file-name-structure) name)
5826 (tramp-dissect-multi-file-name name) 5852 (tramp-dissect-multi-file-name name)
5827 ;; Normal method. First, find out default method. 5853 ;; Normal method. First, find out default method.
5828 (unless match (error "Not a tramp file name: %s" name)) 5854 (unless match (error "Not a tramp file name: %s" name))
5829 (let ((user (match-string (nth 2 tramp-file-name-structure) name)) 5855 (let ((user (match-string (nth 2 tramp-file-name-structure) name))
5830 (host (match-string (nth 3 tramp-file-name-structure) name)) 5856 (host (match-string (nth 3 tramp-file-name-structure) name))
5831 (path (match-string (nth 4 tramp-file-name-structure) name))) 5857 (localname (match-string (nth 4 tramp-file-name-structure) name)))
5832 (make-tramp-file-name 5858 (make-tramp-file-name
5833 :multi-method nil 5859 :multi-method nil
5834 :method method 5860 :method method
5835 :user (or user nil) 5861 :user (or user nil)
5836 :host host 5862 :host host
5837 :path path)))))) 5863 :localname localname))))))
5838 5864
5839 (defun tramp-find-default-method (user host) 5865 (defun tramp-find-default-method (user host)
5840 "Look up the right method to use in `tramp-default-method-alist'." 5866 "Look up the right method to use in `tramp-default-method-alist'."
5841 (let ((choices tramp-default-method-alist) 5867 (let ((choices tramp-default-method-alist)
5842 (method tramp-default-method) 5868 (method tramp-default-method)
5853 "Return the right method string to use. 5879 "Return the right method string to use.
5854 This is MULTI-METHOD, if non-nil. Otherwise, it is METHOD, if non-nil. 5880 This is MULTI-METHOD, if non-nil. Otherwise, it is METHOD, if non-nil.
5855 If both MULTI-METHOD and METHOD are nil, do a lookup in 5881 If both MULTI-METHOD and METHOD are nil, do a lookup in
5856 `tramp-default-method-alist'." 5882 `tramp-default-method-alist'."
5857 (or multi-method method (tramp-find-default-method user host))) 5883 (or multi-method method (tramp-find-default-method user host)))
5858 5884
5859 ;; HHH: Not Changed. Multi method. Will probably not handle the case where 5885 ;; HHH: Not Changed. Multi method. Will probably not handle the case where
5860 ;; a user name is not provided in the "file name" very well. 5886 ;; a user name is not provided in the "file name" very well.
5861 (defun tramp-dissect-multi-file-name (name) 5887 (defun tramp-dissect-multi-file-name (name)
5862 "Not implemented yet." 5888 "Not implemented yet."
5863 (let ((regexp (nth 0 tramp-multi-file-name-structure)) 5889 (let ((regexp (nth 0 tramp-multi-file-name-structure))
5864 (method-index (nth 1 tramp-multi-file-name-structure)) 5890 (method-index (nth 1 tramp-multi-file-name-structure))
5865 (hops-index (nth 2 tramp-multi-file-name-structure)) 5891 (hops-index (nth 2 tramp-multi-file-name-structure))
5866 (path-index (nth 3 tramp-multi-file-name-structure)) 5892 (localname-index (nth 3 tramp-multi-file-name-structure))
5867 (hop-regexp (nth 0 tramp-multi-file-name-hop-structure)) 5893 (hop-regexp (nth 0 tramp-multi-file-name-hop-structure))
5868 (hop-method-index (nth 1 tramp-multi-file-name-hop-structure)) 5894 (hop-method-index (nth 1 tramp-multi-file-name-hop-structure))
5869 (hop-user-index (nth 2 tramp-multi-file-name-hop-structure)) 5895 (hop-user-index (nth 2 tramp-multi-file-name-hop-structure))
5870 (hop-host-index (nth 3 tramp-multi-file-name-hop-structure)) 5896 (hop-host-index (nth 3 tramp-multi-file-name-hop-structure))
5871 method hops len hop-methods hop-users hop-hosts path) 5897 method hops len hop-methods hop-users hop-hosts localname)
5872 (unless (string-match (format regexp hop-regexp) name) 5898 (unless (string-match (format regexp hop-regexp) name)
5873 (error "Not a multi tramp file name: %s" name)) 5899 (error "Not a multi tramp file name: %s" name))
5874 (setq method (match-string method-index name)) 5900 (setq method (match-string method-index name))
5875 (setq hops (match-string hops-index name)) 5901 (setq hops (match-string hops-index name))
5876 (setq len (/ (length (match-data t)) 2)) 5902 (setq len (/ (length (match-data t)) 2))
5877 (when (< path-index 0) (incf path-index len)) 5903 (when (< localname-index 0) (incf localname-index len))
5878 (setq path (match-string path-index name)) 5904 (setq localname (match-string localname-index name))
5879 (let ((index 0)) 5905 (let ((index 0))
5880 (while (string-match hop-regexp hops index) 5906 (while (string-match hop-regexp hops index)
5881 (setq index (match-end 0)) 5907 (setq index (match-end 0))
5882 (setq hop-methods 5908 (setq hop-methods
5883 (cons (match-string hop-method-index hops) hop-methods)) 5909 (cons (match-string hop-method-index hops) hop-methods))
5888 (make-tramp-file-name 5914 (make-tramp-file-name
5889 :multi-method method 5915 :multi-method method
5890 :method (apply 'vector (reverse hop-methods)) 5916 :method (apply 'vector (reverse hop-methods))
5891 :user (apply 'vector (reverse hop-users)) 5917 :user (apply 'vector (reverse hop-users))
5892 :host (apply 'vector (reverse hop-hosts)) 5918 :host (apply 'vector (reverse hop-hosts))
5893 :path path))) 5919 :localname localname)))
5894 5920
5895 (defun tramp-make-tramp-file-name (multi-method method user host path) 5921 (defun tramp-make-tramp-file-name (multi-method method user host localname)
5896 "Constructs a tramp file name from METHOD, USER, HOST and PATH." 5922 "Constructs a tramp file name from METHOD, USER, HOST and LOCALNAME."
5897 (if multi-method 5923 (if multi-method
5898 (tramp-make-tramp-multi-file-name multi-method method user host path) 5924 (tramp-make-tramp-multi-file-name multi-method method user host localname)
5899 (format-spec 5925 (format-spec
5900 (concat tramp-prefix-format 5926 (concat tramp-prefix-format
5901 (when method (concat "%m" tramp-postfix-single-method-format)) 5927 (when method (concat "%m" tramp-postfix-single-method-format))
5902 (when user (concat "%u" tramp-postfix-user-format)) 5928 (when user (concat "%u" tramp-postfix-user-format))
5903 (when host (concat "%h" tramp-postfix-host-format)) 5929 (when host (concat "%h" tramp-postfix-host-format))
5904 (when path (concat "%p"))) 5930 (when localname (concat "%p")))
5905 `((?m . ,method) (?u . ,user) (?h . ,host) (?p . ,path))))) 5931 `((?m . ,method) (?u . ,user) (?h . ,host) (?p . ,localname)))))
5906 5932
5907 ;; CCC: Henrik Holm: Not Changed. Multi Method. What should be done 5933 ;; CCC: Henrik Holm: Not Changed. Multi Method. What should be done
5908 ;; with this when USER is nil? 5934 ;; with this when USER is nil?
5909 (defun tramp-make-tramp-multi-file-name (multi-method method user host path) 5935 (defun tramp-make-tramp-multi-file-name (multi-method method user host localname)
5910 "Constructs a tramp file name for a multi-hop method." 5936 "Constructs a tramp file name for a multi-hop method."
5911 (unless tramp-make-multi-tramp-file-format 5937 (unless tramp-make-multi-tramp-file-format
5912 (error "`tramp-make-multi-tramp-file-format' is nil")) 5938 (error "`tramp-make-multi-tramp-file-format' is nil"))
5913 (let* ((prefix-format (nth 0 tramp-make-multi-tramp-file-format)) 5939 (let* ((prefix-format (nth 0 tramp-make-multi-tramp-file-format))
5914 (hop-format (nth 1 tramp-make-multi-tramp-file-format)) 5940 (hop-format (nth 1 tramp-make-multi-tramp-file-format))
5915 (path-format (nth 2 tramp-make-multi-tramp-file-format)) 5941 (localname-format (nth 2 tramp-make-multi-tramp-file-format))
5916 (prefix (format-spec prefix-format `((?m . ,multi-method)))) 5942 (prefix (format-spec prefix-format `((?m . ,multi-method))))
5917 (hops "") 5943 (hops "")
5918 (path (format-spec path-format `((?p . ,path)))) 5944 (localname (format-spec localname-format `((?p . ,localname))))
5919 (i 0) 5945 (i 0)
5920 (len (length method))) 5946 (len (length method)))
5921 (while (< i len) 5947 (while (< i len)
5922 (let ((m (aref method i)) (u (aref user i)) (h (aref host i))) 5948 (let ((m (aref method i)) (u (aref user i)) (h (aref host i)))
5923 (setq hops (concat hops (format-spec hop-format 5949 (setq hops (concat hops (format-spec hop-format
5924 `((?m . ,m) (?u . ,u) (?h . ,h))))) 5950 `((?m . ,m) (?u . ,u) (?h . ,h)))))
5925 (incf i))) 5951 (incf i)))
5926 (concat prefix hops path))) 5952 (concat prefix hops localname)))
5927 5953
5928 (defun tramp-make-rcp-program-file-name (user host path) 5954 (defun tramp-make-rcp-program-file-name (user host localname)
5929 "Create a file name suitable to be passed to `rcp'." 5955 "Create a file name suitable to be passed to `rcp'."
5930 (if user 5956 (if user
5931 (format "%s@%s:%s" user host path) 5957 (format "%s@%s:%s" user host localname)
5932 (format "%s:%s" host path))) 5958 (format "%s:%s" host localname)))
5933 5959
5934 (defun tramp-method-out-of-band-p (multi-method method user host) 5960 (defun tramp-method-out-of-band-p (multi-method method user host)
5935 "Return t if this is an out-of-band method, nil otherwise. 5961 "Return t if this is an out-of-band method, nil otherwise.
5936 It is important to check for this condition, since it is not possible 5962 It is important to check for this condition, since it is not possible
5937 to enter a password for the `tramp-rcp-program'." 5963 to enter a password for the `tramp-rcp-program'."
6224 Note: this function has been written for `tramp-handle-file-truename'. 6250 Note: this function has been written for `tramp-handle-file-truename'.
6225 If you want to use it for something else, you'll have to check whether 6251 If you want to use it for something else, you'll have to check whether
6226 it does the right thing." 6252 it does the right thing."
6227 (delete "" (split-string string pattern))) 6253 (delete "" (split-string string pattern)))
6228 6254
6229 ;; ------------------------------------------------------------ 6255 ;; ------------------------------------------------------------
6230 ;; -- Kludges section -- 6256 ;; -- Kludges section --
6231 ;; ------------------------------------------------------------ 6257 ;; ------------------------------------------------------------
6232 6258
6233 ;; Currently (as of Emacs 20.5), the function `shell-quote-argument' 6259 ;; Currently (as of Emacs 20.5), the function `shell-quote-argument'
6234 ;; does not deal well with newline characters. Newline is replaced by 6260 ;; does not deal well with newline characters. Newline is replaced by
6235 ;; backslash newline. But if, say, the string `a backslash newline b' 6261 ;; backslash newline. But if, say, the string `a backslash newline b'
6236 ;; is passed to a shell, the shell will expand this into "ab", 6262 ;; is passed to a shell, the shell will expand this into "ab",
6270 t t result))) 6296 t t result)))
6271 result)))) 6297 result))))
6272 6298
6273 ;; ;; EFS hooks itself into the file name handling stuff in more places 6299 ;; ;; EFS hooks itself into the file name handling stuff in more places
6274 ;; ;; than just `file-name-handler-alist'. The following tells EFS to stay 6300 ;; ;; than just `file-name-handler-alist'. The following tells EFS to stay
6275 ;; ;; away from tramp.el paths. 6301 ;; ;; away from tramp.el file names.
6276 ;; ;; 6302 ;; ;;
6277 ;; ;; This is needed because EFS installs (efs-dired-before-readin) into 6303 ;; ;; This is needed because EFS installs (efs-dired-before-readin) into
6278 ;; ;; 'dired-before-readin-hook'. This prevents EFS from opening an FTP 6304 ;; ;; 'dired-before-readin-hook'. This prevents EFS from opening an FTP
6279 ;; ;; connection to help it's dired process. Not that I have any real 6305 ;; ;; connection to help it's dired process. Not that I have any real
6280 ;; ;; idea *why* this is helpful to dired. 6306 ;; ;; idea *why* this is helpful to dired.
6285 ;; ;; 6311 ;; ;;
6286 ;; ;; CCC: when the other defadvice calls have disappeared, make sure 6312 ;; ;; CCC: when the other defadvice calls have disappeared, make sure
6287 ;; ;; not to call defadvice unless it's necessary. How do we find out whether 6313 ;; ;; not to call defadvice unless it's necessary. How do we find out whether
6288 ;; ;; it is necessary? (featurep 'efs) is surely the wrong way -- 6314 ;; ;; it is necessary? (featurep 'efs) is surely the wrong way --
6289 ;; ;; EFS might nicht be loaded yet. 6315 ;; ;; EFS might nicht be loaded yet.
6290 ;; (defadvice efs-ftp-path (around dont-match-tramp-path activate protect) 6316 ;; (defadvice efs-ftp-path (around dont-match-tramp-localname activate protect)
6291 ;; "Cause efs-ftp-path to fail when the path is a TRAMP path." 6317 ;; "Cause efs-ftp-path to fail when the path is a TRAMP localname."
6292 ;; (if (tramp-tramp-file-p (ad-get-arg 0)) 6318 ;; (if (tramp-tramp-file-p (ad-get-arg 0))
6293 ;; nil 6319 ;; nil
6294 ;; ad-do-it)) 6320 ;; ad-do-it))
6295 6321
6296 ;; We currently (sometimes) use "[" and "]" in the filename format. 6322 ;; We currently (sometimes) use "[" and "]" in the filename format.
6307 (let ((name (ad-get-arg 0))) 6333 (let ((name (ad-get-arg 0)))
6308 (if (tramp-tramp-file-p name) 6334 (if (tramp-tramp-file-p name)
6309 ;; If it's a Tramp file, dissect it and look if wildcards 6335 ;; If it's a Tramp file, dissect it and look if wildcards
6310 ;; need to be expanded at all. 6336 ;; need to be expanded at all.
6311 (let ((v (tramp-dissect-file-name name))) 6337 (let ((v (tramp-dissect-file-name name)))
6312 (if (string-match "[[*?]" (tramp-file-name-path v)) 6338 (if (string-match "[[*?]" (tramp-file-name-localname v))
6313 (let ((res ad-do-it)) 6339 (let ((res ad-do-it))
6314 (setq ad-return-value (or res (list name)))) 6340 (setq ad-return-value (or res (list name))))
6315 (setq ad-return-value (list name)))) 6341 (setq ad-return-value (list name))))
6316 ;; If it is not a Tramp file, just run the original function. 6342 ;; If it is not a Tramp file, just run the original function.
6317 (let ((res ad-do-it)) 6343 (let ((res ad-do-it))
6371 tramp-coding-commands 6397 tramp-coding-commands
6372 tramp-actions-before-shell 6398 tramp-actions-before-shell
6373 tramp-multi-actions 6399 tramp-multi-actions
6374 tramp-terminal-type 6400 tramp-terminal-type
6375 tramp-shell-prompt-pattern 6401 tramp-shell-prompt-pattern
6402 tramp-chunksize
6376 6403
6377 ;; Non-tramp variables of interest 6404 ;; Non-tramp variables of interest
6378 shell-prompt-pattern 6405 shell-prompt-pattern
6379 backup-by-copying 6406 backup-by-copying
6380 backup-by-copying-when-linked 6407 backup-by-copying-when-linked
6481 ;; what the user names should default to, though. 6508 ;; what the user names should default to, though.
6482 ;; * better error checking. At least whenever we see something 6509 ;; * better error checking. At least whenever we see something
6483 ;; strange when doing zerop, we should kill the process and start 6510 ;; strange when doing zerop, we should kill the process and start
6484 ;; again. (Greg Stark) 6511 ;; again. (Greg Stark)
6485 ;; * Add caching for filename completion. (Greg Stark) 6512 ;; * Add caching for filename completion. (Greg Stark)
6486 ;; Of course, this has issues with usability (stale cache bites) 6513 ;; Of course, this has issues with usability (stale cache bites)
6487 ;; -- <daniel@danann.net> 6514 ;; -- <daniel@danann.net>
6488 ;; * Provide a local cache of old versions of remote files for the rsync 6515 ;; * Provide a local cache of old versions of remote files for the rsync
6489 ;; transfer method to use. (Greg Stark) 6516 ;; transfer method to use. (Greg Stark)
6490 ;; * Remove unneeded parameters from methods. 6517 ;; * Remove unneeded parameters from methods.
6491 ;; * Invoke rsync once for copying a whole directory hierarchy. 6518 ;; * Invoke rsync once for copying a whole directory hierarchy.
6496 ;; * Make it work for XEmacs 20, which is missing `with-timeout'. 6523 ;; * Make it work for XEmacs 20, which is missing `with-timeout'.
6497 ;; * Allow non-Unix remote systems. (More a long-term thing.) 6524 ;; * Allow non-Unix remote systems. (More a long-term thing.)
6498 ;; * Make it work for different encodings, and for different file name 6525 ;; * Make it work for different encodings, and for different file name
6499 ;; encodings, too. (Daniel Pittman) 6526 ;; encodings, too. (Daniel Pittman)
6500 ;; * Change applicable functions to pass a struct tramp-file-name rather 6527 ;; * Change applicable functions to pass a struct tramp-file-name rather
6501 ;; than the individual items MULTI-METHOD, METHOD, USER, HOST, PATH. 6528 ;; than the individual items MULTI-METHOD, METHOD, USER, HOST, LOCALNAME.
6502 ;; * Implement asynchronous shell commands. 6529 ;; * Implement asynchronous shell commands.
6503 ;; * Clean up unused *tramp/foo* buffers after a while. (Pete Forman) 6530 ;; * Clean up unused *tramp/foo* buffers after a while. (Pete Forman)
6504 ;; * Progress reports while copying files. (Michael Kifer) 6531 ;; * Progress reports while copying files. (Michael Kifer)
6505 ;; * `Smart' connection method that uses inline for small and out of 6532 ;; * `Smart' connection method that uses inline for small and out of
6506 ;; band for large files. (Michael Kifer) 6533 ;; band for large files. (Michael Kifer)