/[emacs]/emacs/lisp/net/tramp.el
ViewVC logotype

Diff of /emacs/lisp/net/tramp.el

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.23 by kai, Mon Sep 2 12:53:12 2002 UTC revision 1.24 by kai, Sun Sep 22 13:23:36 2002 UTC
# Line 72  Line 72 
72  ;; In the Tramp CVS repository, the version numer is auto-frobbed from  ;; 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  ;; the Makefile, so you should edit the top-level Makefile to change
74  ;; the version number.  ;; the version number.
75  (defconst tramp-version "2.0.15"  (defconst tramp-version "2.0.20"
76    "This version of tramp.")    "This version of tramp.")
77    
78  (defconst tramp-bug-report-address "tramp-devel@mail.freesoftware.fsf.org"  (defconst tramp-bug-report-address "tramp-devel@mail.freesoftware.fsf.org"
# Line 89  Line 89 
89  (require 'shell)  (require 'shell)
90  (require 'advice)  (require 'advice)
91    
92    (autoload 'tramp-uuencode-region "tramp-uu"
93      "Implementation of `uuencode' in Lisp.")
94    
95    (unless (fboundp 'uudecode-decode-region)
96      (autoload 'uudecode-decode-region "uudecode"))
97    
98  ;; ;; It does not work to load EFS after loading TRAMP.    ;; ;; It does not work to load EFS after loading TRAMP.  
99  ;; (when (fboundp 'efs-file-handler-function)  ;; (when (fboundp 'efs-file-handler-function)
100  ;;   (require 'efs))  ;;   (require 'efs))
# Line 103  Line 109 
109  (unless (boundp 'custom-print-functions)  (unless (boundp 'custom-print-functions)
110    (defvar custom-print-functions nil))  ; not autoloaded before Emacs 20.4    (defvar custom-print-functions nil))  ; not autoloaded before Emacs 20.4
111    
112    ;; XEmacs is distributed with few Lisp packages.  Further packages are
113    ;; installed using EFS.  If we use a unified filename format, then
114    ;; Tramp is required in addition to EFS.  (But why can't Tramp just
115    ;; disable EFS when Tramp is loaded?  Then XEmacs can ship with EFS
116    ;; just like before.)  Another reason for using a separate filename
117    ;; syntax on XEmacs is that EFS hooks into XEmacs in many places, but
118    ;; Tramp only knows how to deal with `file-name-handler-alist', not
119    ;; the other places.
120    (defvar tramp-unified-filenames (not (featurep 'xemacs))
121      "Non-nil means to use unified Ange-FTP/Tramp filename syntax.
122    Nil means to use a separate filename syntax for Tramp.")
123    
124  ;;; User Customizable Internal Variables:  ;;; User Customizable Internal Variables:
125    
126  (defgroup tramp nil  (defgroup tramp nil
# Line 126  The idea is to use a local directory so Line 144  The idea is to use a local directory so
144    :type '(choice (const nil)    :type '(choice (const nil)
145                   string))                   string))
146    
147  (defcustom tramp-sh-program "/bin/sh"  (defcustom tramp-encoding-shell
148    "*Use this program for shell commands on the local host.    (if (memq system-type '(windows-nt))
149  This MUST be a Bourne-like shell.  This shell is used to execute        (getenv "COMSPEC")
150  the encoding and decoding command on the local host, so if you      "/bin/sh")
151  want to use `~' in those commands, you should choose a shell here    "*Use this program for encoding and decoding commands on the local host.
152  which groks tilde expansion.  `/bin/sh' normally does not  This shell is used to execute the encoding and decoding command on the
153  understand tilde expansion.  local host, so if you want to use `~' in those commands, you should
154    choose a shell here which groks tilde expansion.  `/bin/sh' normally
155    does not understand tilde expansion.
156    
157    For encoding and deocding, commands like the following are executed:
158    
159        /bin/sh -c COMMAND < INPUT > OUTPUT
160    
161    This variable can be used to change the \"/bin/sh\" part.  See the
162    variable `tramp-encoding-command-switch' for the \"-c\" part.  Also, see the
163    variable `tramp-encoding-reads-stdin' to specify whether the commands read
164    standard input or a file.
165    
166  Note that this variable is not used for remote commands.  There are  Note that this variable is not used for remote commands.  There are
167  mechanisms in tramp.el which automatically determine the right shell to  mechanisms in tramp.el which automatically determine the right shell to
# Line 140  use for the remote host." Line 169  use for the remote host."
169    :group 'tramp    :group 'tramp
170    :type '(file :must-match t))    :type '(file :must-match t))
171    
172    (defcustom tramp-encoding-command-switch
173      (if (string-match "cmd\\.exe" tramp-encoding-shell)
174          "/c"
175        "-c")
176      "*Use this switch together with `tramp-encoding-shell' for local commands.
177    See the variable `tramp-encoding-shell' for more information."
178      :group 'tramp
179      :type 'string)
180    
181    (defcustom tramp-encoding-reads-stdin t
182      "*If non-nil, encoding commands read from standard input.
183    If nil, the filename is the last argument.
184    
185    Note that the commands always must write to standard output."
186      :group 'tramp
187      :type 'boolean)
188    
189  (defcustom tramp-multi-sh-program  (defcustom tramp-multi-sh-program
190    (if (memq system-type '(windows-nt))    tramp-encoding-shell
       "cmd.exe"  
     tramp-sh-program)  
191    "*Use this program for bootstrapping multi-hop connections.    "*Use this program for bootstrapping multi-hop connections.
192  This variable is similar to `tramp-sh-program', but it is only used  This variable is similar to `tramp-encoding-shell', but it is only used
193  when initializing a multi-hop connection.  Therefore, the set of  when initializing a multi-hop connection.  Therefore, the set of
194  commands sent to this shell is quite restricted, and if you are  commands sent to this shell is quite restricted, and if you are
195  careful it works to use CMD.EXE under Windows (instead of a Bourne-ish  careful it works to use CMD.EXE under Windows (instead of a Bourne-ish
# Line 154  shell which does not normally exist on W Line 198  shell which does not normally exist on W
198  To use multi-hop methods from Windows, you also need suitable entries  To use multi-hop methods from Windows, you also need suitable entries
199  in `tramp-multi-connection-function-alist' for the first hop.  in `tramp-multi-connection-function-alist' for the first hop.
200    
201  This variable defaults to CMD.EXE on Windows NT, and to the value of  This variable defaults to the value of `tramp-encoding-shell'."
 `tramp-sh-program' on other systems."  
202    :group 'tramp    :group 'tramp
203    :type '(file :must-match t))    :type '(file :must-match t))
204    
# Line 440  This variable defaults to CMD.EXE on Win Line 483  This variable defaults to CMD.EXE on Win
483  This is a list of entries of the form (NAME PARAM1 PARAM2 ...).  This is a list of entries of the form (NAME PARAM1 PARAM2 ...).
484  Each NAME stands for a remote access method.  Each PARAM is a  Each NAME stands for a remote access method.  Each PARAM is a
485  pair of the form (KEY VALUE).  The following KEYs are defined:  pair of the form (KEY VALUE).  The following KEYs are defined:
486    * `tramp-connection-function'   * `tramp-connection-function'
487      This specifies the function to use to connect to the remote host.      This specifies the function to use to connect to the remote host.
488      Currently, `tramp-open-connection-rsh', `tramp-open-connection-telnet'      Currently, `tramp-open-connection-rsh', `tramp-open-connection-telnet'
489      and `tramp-open-connection-su' are defined.  See the documentation      and `tramp-open-connection-su' are defined.  See the documentation
# Line 477  pair of the form (KEY VALUE).  The follo Line 520  pair of the form (KEY VALUE).  The follo
520      This specifies the list of arguments to pass to `su'.      This specifies the list of arguments to pass to `su'.
521      \"%u\" is replaced by the user name, use \"%%\" for a literal      \"%u\" is replaced by the user name, use \"%%\" for a literal
522      percent character.      percent character.
   * `tramp-encoding-command'  
     This specifies a command to use to encode the file contents for  
     transfer.  The command should read the raw file contents from  
     standard input and write the encoded file contents to standard  
     output.  In this string, the percent escape \"%f\" should be used  
     to indicate the file to convert.  Use \"%%\" if you need a literal  
     percent character in your command.  
   * `tramp-decoding-command'  
     This specifies a command to use to decode file contents encoded  
     with `tramp-encoding-command'.  The command should read from standard  
     input and write to standard output.  
   * `tramp-encoding-function'  
     This specifies a function to be called to encode the file contents  
     on the local side.  This function should accept two arguments  
     START and END, the beginning and end of the region to encode.  The  
     region should be replaced with the encoded contents.  
   * `tramp-decoding-function'  
     Same for decoding on the local side.  
523    * `tramp-telnet-program'    * `tramp-telnet-program'
524      Specifies the telnet program to use when using      Specifies the telnet program to use when using
525      `tramp-open-connection-telnet' to log in.      `tramp-open-connection-telnet' to log in.
# Line 514  file is passed through the same buffer u Line 539  file is passed through the same buffer u
539  this case, the file contents need to be protected since the  this case, the file contents need to be protected since the
540  `tramp-rsh-program' might use escape codes or the connection might not  `tramp-rsh-program' might use escape codes or the connection might not
541  be eight-bit clean.  Therefore, file contents are encoded for transit.  be eight-bit clean.  Therefore, file contents are encoded for transit.
542    See the variable `tramp-coding-commands' for details.
543    
544  Two possibilities for encoding are uuencode/uudecode and mimencode.  So, to summarize: if the method is an out-of-band method, then you
545  For uuencode/uudecode you want to set `tramp-encoding-command' to  must specify `tramp-rcp-program' and `tramp-rcp-args'.  If it is an
546  something like \"uuencode\" and `tramp-decoding-command' to \"uudecode  inline method, then these two parameters should be nil.  Every method,
547  -p\".  For mimencode you want to set `tramp-encoding-command' to  inline or out of band, must specify `tramp-connection-function' plus
548  something like \"mimencode -b\" and `tramp-decoding-command' to  the associated arguments (for example, the telnet program if you chose
 \"mimencode -b -u\".  
   
 When using inline transfer, you can use a program or a Lisp function  
 on the local side to encode or decode the file contents.  Set the  
 `tramp-encoding-function' and `tramp-decoding-function' parameters to nil  
 in order to use the commands or to the function to use.  It is  
 possible to specify one function and the other parameter as nil.  
   
 So, to summarize: if the method is an inline method, you must specify  
 `tramp-encoding-command' and `tramp-decoding-command', and  
 `tramp-rcp-program' must be nil.  If the method is out of band, then  
 you must specify `tramp-rcp-program' and `tramp-rcp-args' and  
 `tramp-encoding-command' and `tramp-decoding-command' must be nil.  
 Every method, inline or out of band, must specify  
 `tramp-connection-function' plus the associated arguments (for  
 example, the telnet program if you chose  
549  `tramp-open-connection-telnet').  `tramp-open-connection-telnet').
550    
551  Notes:  Notes:
# Line 544  When using `tramp-open-connection-su' th Line 554  When using `tramp-open-connection-su' th
554  remote host' sounds strange, but it is used nevertheless, for  remote host' sounds strange, but it is used nevertheless, for
555  consistency.  No connection is opened to a remote host, but `su' is  consistency.  No connection is opened to a remote host, but `su' is
556  started on the local host.  You are not allowed to specify a remote  started on the local host.  You are not allowed to specify a remote
557  host other than `localhost' or the name of the local host.  host other than `localhost' or the name of the local host."
   
 Using a uuencode/uudecode inline method is discouraged, please use one  
 of the base64 methods instead since base64 encoding is much more  
 reliable and the commands are more standardized between the different  
 Unix versions.  But if you can't use base64 for some reason, please  
 note that the default uudecode command does not work well for some  
 Unices, in particular AIX and Irix.  For AIX, you might want to use  
 the following command for uudecode:  
   
     sed '/^begin/d;/^[` ]$/d;/^end/d' | iconv -f uucode -t ISO8859-1  
   
 For Irix, no solution is known yet."  
558    :group 'tramp    :group 'tramp
559    :type '(repeat    :type '(repeat
560            (cons string            (cons string
# Line 629  for Tramp and EFS, so there the default Line 627  for Tramp and EFS, so there the default
627    :type 'string)    :type 'string)
628    
629  (defcustom tramp-default-method-alist  (defcustom tramp-default-method-alist
630    (if (featurep 'xemacs)    (when tramp-unified-filenames
       nil  
631      '(("\\`ftp\\." "" "ftp")      '(("\\`ftp\\." "" "ftp")
632        ("" "\\`\\(anonymous\\|ftp\\)\\'" "ftp")))        ("" "\\`\\(anonymous\\|ftp\\)\\'" "ftp")))
633    "*Default method to use for specific user/host pairs.    "*Default method to use for specific user/host pairs.
# Line 654  See `tramp-methods' for a list of possib Line 651  See `tramp-methods' for a list of possib
651    :group 'tramp    :group 'tramp
652    :type 'string)    :type 'string)
653    
654    ;; Default values for non-Unices seeked
655    (defconst tramp-completion-function-alist-rsh
656      (unless (memq system-type '(windows-nt))
657        '((tramp-parse-rhosts "/etc/hosts.equiv")
658          (tramp-parse-rhosts "~/.rhosts")))
659      "Default list of (FUNNCTION FILE) pairs to be examined for rsh methods."
660    )
661    
662    ;; Default values for non-Unices seeked
663    (defconst tramp-completion-function-alist-ssh
664      (unless (memq system-type '(windows-nt))
665        '((tramp-parse-rhosts "/etc/hosts.equiv")
666          (tramp-parse-rhosts "/etc/shosts.equiv")
667          (tramp-parse-shosts "/etc/ssh_known_hosts")
668          (tramp-parse-rhosts "~/.rhosts")
669          (tramp-parse-rhosts "~/.shosts")
670          (tramp-parse-shosts "~/.ssh/known_hosts")))
671      "Default list of (FUNNCTION FILE) pairs to be examined for ssh methods."
672    )
673    
674    ;; Default values for non-Unices seeked
675    (defconst tramp-completion-function-alist-telnet
676      (unless (memq system-type '(windows-nt))
677        '((tramp-parse-hosts "/etc/hosts")))
678      "Default list of (FUNNCTION FILE) pairs to be examined for telnet methods."
679    )
680    
681    ;; Default values for non-Unices seeked
682    (defconst tramp-completion-function-alist-su
683      (unless (memq system-type '(windows-nt))
684        '((tramp-parse-passwd "/etc/passwd")))
685      "Default list of (FUNNCTION FILE) pairs to be examined for su methods."
686    )
687    
688    (defcustom tramp-completion-function-alist
689      (list (cons "rcp"      tramp-completion-function-alist-rsh)
690            (cons "scp"      tramp-completion-function-alist-ssh)
691            (cons "scp1"     tramp-completion-function-alist-ssh)
692            (cons "scp2"     tramp-completion-function-alist-ssh)
693            (cons "scp1-old" tramp-completion-function-alist-ssh)
694            (cons "scp2-old" tramp-completion-function-alist-ssh)
695            (cons "rsync"    tramp-completion-function-alist-rsh)
696            (cons "rsh"      tramp-completion-function-alist-rsh)
697            (cons "ssh"      tramp-completion-function-alist-ssh)
698            (cons "ssh1"     tramp-completion-function-alist-ssh)
699            (cons "ssh2"     tramp-completion-function-alist-ssh)
700            (cons "ssh1-old" tramp-completion-function-alist-ssh)
701            (cons "ssh2-old" tramp-completion-function-alist-ssh)
702            (cons "telnet"   tramp-completion-function-alist-telnet)
703            (cons "su"       tramp-completion-function-alist-su)
704            (cons "sudo"     tramp-completion-function-alist-su)
705            (cons "multi"    nil)
706            (cons "scpx"     tramp-completion-function-alist-ssh)
707            (cons "sshx"     tramp-completion-function-alist-ssh)
708            (cons "krlogin"  tramp-completion-function-alist-rsh)
709            (cons "plink"    tramp-completion-function-alist-ssh)
710            (cons "pscp"     tramp-completion-function-alist-ssh)
711            (cons "fcp"      nil)
712         )
713      "*Alist of methods for remote files.
714    This is a list of entries of the form (NAME PAIR1 PAIR2 ...).
715    Each NAME stands for a remote access method.  Each PAIR is of the form
716    \(FUNCTION FILE).  FUNCTION is responsible to extract user names and host
717    names from FILE for completion.  The following predefined FUNCTIONs exists:
718    
719     * `tramp-parse-rhosts' for \".rhosts\" like files,
720     * `tramp-parse-shosts' for \"ssh_known_hosts\" like files,
721     * `tramp-parse-hosts'  for \"/etc/hosts\" like files, and
722     * `tramp-parse-passwd' for \"/etc/passwd\" like files.
723    
724    A FUNCTION parsing \".netrc\" file syntax doesn't exist in TRAMP. This
725    task is delegated to ange-ftp; its customization should be used instead.
726    
727    FUNCTION can also see a customer defined function.  For more details see
728    the info pages."
729      :group 'tramp
730      :type '(repeat
731              (cons string
732                    (choice (const nil) (repeat (list function file))))))
733    
734  (defcustom tramp-rsh-end-of-line "\n"  (defcustom tramp-rsh-end-of-line "\n"
735    "*String used for end of line in rsh connections.    "*String used for end of line in rsh connections.
736  I don't think this ever needs to be changed, so please tell me about it  I don't think this ever needs to be changed, so please tell me about it
737  if you need to change this."  if you need to change this.
738    Also see `tramp-password-end-of-line'."
739      :group 'tramp
740      :type 'string)
741    
742    (defcustom tramp-password-end-of-line tramp-rsh-end-of-line
743      "*String used for end of line after sending a password.
744    It seems that people using plink under Windows need to send
745    \"\\r\\n\" (carriage-return, then newline) after a password, but just
746    \"\\n\" after all other lines.  This variable can be used for the
747    password, see `tramp-rsh-end-of-line' for the other cases.
748    
749    The default value is to use the same value as `tramp-rsh-end-of-line'."
750    :group 'tramp    :group 'tramp
751    :type 'string)    :type 'string)
752    
# Line 774  shell from reading its init file." Line 863  shell from reading its init file."
863    :group 'tramp    :group 'tramp
864    :type '(alist :key-type string :value-type string))    :type '(alist :key-type string :value-type string))
865    
866  ;; File name format.  (defcustom tramp-prefix-format
867      (if tramp-unified-filenames "/" "/[")
868      "*String matching the very beginning of tramp file names.
869    Used in `tramp-make-tramp-file-name' and `tramp-make-tramp-multi-file-name'."
870      :group 'tramp
871      :type 'string)
872    
873    (defcustom tramp-prefix-regexp
874      (concat "^" (regexp-quote tramp-prefix-format))
875      "*Regexp matching the very beginning of tramp file names.
876    Should always start with \"^\". Derived from `tramp-prefix-format'."
877      :group 'tramp
878      :type 'regexp)
879    
880    (defcustom tramp-method-regexp
881      "[a-zA-Z_0-9-]+"
882      "*Regexp matching methods identifiers."
883      :group 'tramp
884      :type 'regexp)
885    
886    ;; It is a little bit annoying that in XEmacs case this delimeter is different
887    ;; for single-hop and multi-hop cases.
888    (defcustom tramp-postfix-single-method-format
889      (if tramp-unified-filenames ":" "/")
890      "*String matching delimeter between method and user or host names.
891    Applicable for single-hop methods.
892    Used in `tramp-make-tramp-file-name'."
893      :group 'tramp
894      :type 'string)
895    
896    (defcustom tramp-postfix-single-method-regexp
897      (regexp-quote tramp-postfix-single-method-format)
898      "*Regexp matching delimeter between method and user or host names.
899    Applicable for single-hop methods.
900    Derived from `tramp-postfix-single-method-format'."
901      :group 'tramp
902      :type 'regexp)
903    
904    (defcustom tramp-postfix-multi-method-format
905      ":"
906      "*String matching delimeter between method and user or host names.
907    Applicable for multi-hop methods.
908    Used in `tramp-make-tramp-multi-file-name'."
909      :group 'tramp
910      :type 'string)
911    
912    (defcustom tramp-postfix-multi-method-regexp
913      (regexp-quote tramp-postfix-multi-method-format)
914      "*Regexp matching delimeter between method and user or host names.
915    Applicable for multi-hop methods.
916    Derived from `tramp-postfix-multi-method-format'."
917      :group 'tramp
918      :type 'regexp)
919    
920    (defcustom tramp-postfix-multi-hop-format
921      (if tramp-unified-filenames ":" "/")
922      "*String matching delimeter between path and next method.
923    Applicable for multi-hop methods.
924    Used in `tramp-make-tramp-multi-file-name'."
925      :group 'tramp
926      :type 'string)
927    
928    (defcustom tramp-postfix-multi-hop-regexp
929      (regexp-quote tramp-postfix-multi-hop-format)
930      "*Regexp matching delimeter between path and next method.
931    Applicable for multi-hop methods.
932    Derived from `tramp-postfix-multi-hop-format'."
933      :group 'tramp
934      :type 'regexp)
935    
936    (defcustom tramp-user-regexp
937      "[^:@/]*"
938      "*Regexp matching user names."
939      :group 'tramp
940      :type 'regexp)
941    
942    (defcustom tramp-postfix-user-format
943      "@"
944      "*String matching delimeter between user and host names.
945    Used in `tramp-make-tramp-file-name' and `tramp-make-tramp-multi-file-name'."
946      :group 'tramp
947      :type 'string)
948    
949    (defcustom tramp-postfix-user-regexp
950      (regexp-quote tramp-postfix-user-format)
951      "*Regexp matching delimeter between user and host names.
952    Derived from `tramp-postfix-user-format'."
953      :group 'tramp
954      :type 'regexp)
955    
956    (defcustom tramp-host-regexp
957      "[a-zA-Z0-9_.-]*"
958      "*Regexp matching host names."
959      :group 'tramp
960      :type 'regexp)
961    
962    (defcustom tramp-postfix-host-format
963      (if tramp-unified-filenames ":" "]")
964      "*String matching delimeter between host names and paths.
965    Used in `tramp-make-tramp-file-name' and `tramp-make-tramp-multi-file-name'."
966      :group 'tramp
967      :type 'string)
968    
969    (defcustom tramp-postfix-host-regexp
970      (regexp-quote tramp-postfix-host-format)
971      "*Regexp matching delimeter between host names and paths.
972    Derived from `tramp-postfix-host-format'."
973      :group 'tramp
974      :type 'regexp)
975    
976    (defcustom tramp-path-regexp
977      ".*$"
978      "*Regexp matching paths."
979      :group 'tramp
980      :type 'regexp)
981    
982  (defconst tramp-file-name-structure-unified  ;; File name format.
   (list (concat "\\`/\\(\\([a-zA-Z0-9-]+\\):\\)?" ;method  
                       "\\(\\([^:@/]+\\)@\\)?" ;user  
                       "\\([^:/]+\\):"   ;host  
                       "\\(.*\\)\\'")    ;path  
               2 4 5 6)  
   "Default value for `tramp-file-name-structure' for unified remoting.  
 On Emacs (not XEmacs), the Tramp and Ange-FTP packages use a unified  
 filename space.  This value is used for this unified namespace.")  
   
 (defconst tramp-file-name-structure-separate  
   (list (concat "\\`/\\[\\(\\([a-zA-Z0-9-]+\\)/\\)?" ;method  
                 "\\(\\([-a-zA-Z0-9_#/:]+\\)@\\)?" ;user  
                 "\\([-a-zA-Z0-9_#/:@.]+\\)\\]" ;host  
                 "\\(.*\\)\\'")          ;path  
         2 4 5 6)  
   "Default value for `tramp-file-name-structure' for separate remoting.  
 On XEmacs, the Tramp and EFS packages use a separate namespace for  
 remote filenames.  This value is used in that case.  It is designed  
 not to clash with the EFS filename syntax.")  
983    
984  (defcustom tramp-file-name-structure  (defcustom tramp-file-name-structure
985    (if (featurep 'xemacs)    (list
986        tramp-file-name-structure-separate     (concat
987      tramp-file-name-structure-unified)      tramp-prefix-regexp
988        "\\(" "\\(" tramp-method-regexp "\\)" tramp-postfix-single-method-regexp "\\)?"
989        "\\(" "\\(" tramp-user-regexp   "\\)" tramp-postfix-user-regexp   "\\)?"
990              "\\(" tramp-host-regexp   "\\)" tramp-postfix-host-regexp
991              "\\(" tramp-path-regexp   "\\)")
992       2 4 5 6)
993    
994    "*List of five elements (REGEXP METHOD USER HOST FILE), detailing \    "*List of five elements (REGEXP METHOD USER HOST FILE), detailing \
995  the tramp file name structure.  the tramp file name structure.
996    
# Line 815  but for the host name.  The fifth elemen Line 1005  but for the host name.  The fifth elemen
1005  These numbers are passed directly to `match-string', which see.  That  These numbers are passed directly to `match-string', which see.  That
1006  means the opening parentheses are counted to identify the pair.  means the opening parentheses are counted to identify the pair.
1007    
1008  See also `tramp-file-name-regexp' and `tramp-make-tramp-file-format'."  See also `tramp-file-name-regexp'."
1009    :group 'tramp    :group 'tramp
1010    :type '(list (regexp :tag "File name regexp")    :type '(list (regexp :tag "File name regexp")
1011                 (integer :tag "Paren pair for method name")                 (integer :tag "Paren pair for method name")
# Line 839  See `tramp-file-name-structure-separate' Line 1029  See `tramp-file-name-structure-separate'
1029    
1030  ;;;###autoload  ;;;###autoload
1031  (defcustom tramp-file-name-regexp  (defcustom tramp-file-name-regexp
1032    (if (featurep 'xemacs)    (if tramp-unified-filenames
1033        tramp-file-name-regexp-separate        tramp-file-name-regexp-unified
1034      tramp-file-name-regexp-unified)      tramp-file-name-regexp-separate)
1035    "*Regular expression matching file names handled by tramp.    "*Regular expression matching file names handled by tramp.
1036  This regexp should match tramp file names but no other file names.  This regexp should match tramp file names but no other file names.
1037  \(When tramp.el is loaded, this regular expression is prepended to  \(When tramp.el is loaded, this regular expression is prepended to
# Line 855  this file (tramp.el) is loaded.  This me Line 1045  this file (tramp.el) is loaded.  This me
1045  before loading tramp.el.  Alternatively, `file-name-handler-alist' can be  before loading tramp.el.  Alternatively, `file-name-handler-alist' can be
1046  updated after changing this variable.  updated after changing this variable.
1047    
1048  Also see `tramp-file-name-structure' and `tramp-make-tramp-file-format'."  Also see `tramp-file-name-structure'."
1049    :group 'tramp    :group 'tramp
1050    :type 'regexp)    :type 'regexp)
1051    
1052  (defconst tramp-make-tramp-file-format-unified  ;;;###autoload
1053     "/%m:%u@%h:%p"  (defconst tramp-completion-file-name-regexp-unified
1054     "Value for `tramp-make-tramp-file-format' for unified remoting.    "^/[^/]*$"
1055  Emacs (not XEmacs) uses a unified filename syntax for Ange-FTP and Tramp.    "Value for `tramp-completion-file-name-regexp' for unified remoting.
1056  See `tramp-file-name-structure-unified' for more details.")  Emacs (not XEmacs) uses a unified filename syntax for Ange-FTP and
1057    Tramp.  See `tramp-file-name-structure-unified' for more explanations.")
 (defconst tramp-make-tramp-file-format-separate  
   "/[%m/%u@%h]%p"  
   "Value for `tramp-make-tramp-file-format' for separate remoting.  
 XEmacs uses a separate filename syntax for EFS and Tramp.  
 See `tramp-file-name-structure-separate' for more details.")  
   
 (defcustom tramp-make-tramp-file-format  
   (if (featurep 'xemacs)  
       tramp-make-tramp-file-format-separate  
     tramp-make-tramp-file-format-unified)  
   "*Format string saying how to construct tramp file name.  
 `%m' is replaced by the method name.  
 `%u' is replaced by the user name.  
 `%h' is replaced by the host name.  
 `%p' is replaced by the file name.  
 `%%' is replaced by %.  
1058    
1059  Also see `tramp-file-name-structure' and `tramp-file-name-regexp'."  ;;;###autoload
1060    :group 'tramp  (defconst tramp-completion-file-name-regexp-separate
1061    :type 'string)    "^/\\([[][^]]*\\)?$"
1062      "Value for `tramp-completion-file-name-regexp' for separate remoting.
1063    XEmacs uses a separate filename syntax for Tramp and EFS.
1064    See `tramp-file-name-structure-separate' for more explanations.")
1065    
1066  (defconst tramp-make-tramp-file-user-nil-format-unified  ;;;###autoload
1067    "/%m:%h:%p"  (defcustom tramp-completion-file-name-regexp
1068    "Value of `tramp-make-tramp-file-user-nil-format' for unified remoting.    (if tramp-unified-filenames
1069  Emacs (not XEmacs) uses a unified filename syntax for Ange-FTP and Tramp.        tramp-completion-file-name-regexp-unified
1070  See `tramp-file-name-structure-unified' for details.")      tramp-completion-file-name-regexp-separate)
1071      "*Regular expression matching file names handled by tramp completion.
1072  (defconst tramp-make-tramp-file-user-nil-format-separate  This regexp should match partial tramp file names only.
   "/[%m/%h]%p"  
   "Value of `tramp-make-tramp-file-user-nil-format' for separate remoting.  
 XEmacs uses a separate filename syntax for EFS and Tramp.  
 See `tramp-file-name-structure-separate' for details.")  
   
 (defcustom tramp-make-tramp-file-user-nil-format  
   (if (featurep 'xemacs)  
       tramp-make-tramp-file-user-nil-format-separate  
     tramp-make-tramp-file-user-nil-format-unified)  
   "*Format string saying how to construct tramp file name when the user name is not known.  
 `%m' is replaced by the method name.  
 `%h' is replaced by the host name.  
 `%p' is replaced by the file name.  
 `%%' is replaced by %.  
1073    
1074  Also see `tramp-make-tramp-file-format', `tramp-file-name-structure', and `tramp-file-name-regexp'."  Please note that the entry in `file-name-handler-alist' is made when
1075    :group 'tramp  this file (tramp.el) is loaded.  This means that this variable must be set
1076    :type 'string)  before loading tramp.el.  Alternatively, `file-name-handler-alist' can be
1077    updated after changing this variable.
1078    
1079  (defconst tramp-multi-file-name-structure-unified  Also see `tramp-file-name-structure'."
1080    (list (concat "\\`/\\(\\([a-zA-Z0-9]+\\)?:\\)" ;method    :group 'tramp
1081                  "\\(\\(%s\\)+\\)"       ;hops    :type 'regexp)
                 "\\(.*\\)\\'")          ;path  
         2 3 -1)  
   "Value for `tramp-multi-file-name-structure' for unified remoting.  
 Emacs (not XEmacs) uses a unified filename syntax for Ange-FTP and Tramp.  
 See `tramp-file-name-structure-unified' for details.")  
   
 (defconst tramp-multi-file-name-structure-separate  
   (list (concat  
          ;; prefix  
          "\\`/\\[\\(\\([a-z0-9]+\\)?\\)"  
          ;; regexp specifying the hops  
          "\\(\\(%s\\)+\\)"  
          ;; path name  
          "\\]\\(.*\\)\\'")  
         2                               ;number of pair to match method  
         3                               ;number of pair to match hops  
         -1)                             ;number of pair to match path  
   "Value of `tramp-multi-file-name-structure' for separate remoting.  
 XEmacs uses a separate filename syntax for EFS and Tramp.  
 See `tramp-file-name-structure-separate' for details.")  
1082    
1083  (defcustom tramp-multi-file-name-structure  (defcustom tramp-multi-file-name-structure
1084    (if (featurep 'xemacs)    (list
1085        tramp-multi-file-name-structure-separate     (concat
1086      tramp-multi-file-name-structure-unified)      tramp-prefix-regexp
1087        "\\(" "\\(" tramp-method-regexp "\\)" "\\)?"
1088        "\\(" "\\(" tramp-postfix-multi-hop-regexp "%s" "\\)+" "\\)?"
1089        tramp-postfix-host-regexp "\\(" tramp-path-regexp "\\)")
1090       2 3 -1)
1091    "*Describes the file name structure of `multi' files.    "*Describes the file name structure of `multi' files.
1092  Multi files allow you to contact a remote host in several hops.  Multi files allow you to contact a remote host in several hops.
1093  This is a list of four elements (REGEXP METHOD HOP PATH).  This is a list of four elements (REGEXP METHOD HOP PATH).
# Line 967  string, but I haven't actually tried wha Line 1115  string, but I haven't actually tried wha
1115                 (integer :tag "Paren pair for hops")                 (integer :tag "Paren pair for hops")
1116                 (integer :tag "Paren pair to match path")))                 (integer :tag "Paren pair to match path")))
1117    
 (defconst tramp-multi-file-name-hop-structure-unified  
   (list (concat "\\([a-zA-z0-9_]+\\):" ;hop method  
                 "\\([^@:/]+\\)@"        ;user  
                 "\\([^:/]+\\):")        ;host  
         1 2 3)  
   "Value of `tramp-multi-file-name-hop-structure' for unified remoting.  
 Emacs (not XEmacs) uses a unified filename syntax for Ange-FTP and Tramp.  
 See `tramp-file-name-structure-unified' for details.")  
   
 (defconst tramp-multi-file-name-hop-structure-separate  
   (list (concat "/\\([a-z0-9_]+\\):"    ;hop method  
                 "\\([a-z0-9_]+\\)@"     ;user  
                 "\\([a-z0-9.-]+\\)")    ;host  
         1 2 3)  
   "Value of `tramp-multi-file-name-hop-structure' for separate remoting.  
 XEmacs uses a separate filename syntax for EFS and Tramp.  
 See `tramp-file-name-structure-separate' for details.")  
   
1118  (defcustom tramp-multi-file-name-hop-structure  (defcustom tramp-multi-file-name-hop-structure
1119    (if (featurep 'xemacs)    (list
1120        tramp-multi-file-name-hop-structure-separate     (concat
1121      tramp-multi-file-name-hop-structure-unified)      "\\(" tramp-method-regexp "\\)" tramp-postfix-multi-method-regexp
1122        "\\(" tramp-user-regexp   "\\)" tramp-postfix-user-regexp
1123        "\\(" tramp-host-regexp   "\\)")
1124       1 2 3)
1125    "*Describes the structure of a hop in multi files.    "*Describes the structure of a hop in multi files.
1126  This is a list of four elements (REGEXP METHOD USER HOST).  First  This is a list of four elements (REGEXP METHOD USER HOST).  First
1127  element REGEXP is used to match against the hop.  Pair number METHOD  element REGEXP is used to match against the hop.  Pair number METHOD
# Line 1002  This regular expression should match exa Line 1135  This regular expression should match exa
1135                 (integer :tag "Paren pair for user name")                 (integer :tag "Paren pair for user name")
1136                 (integer :tag "Paren pair for host name")))                 (integer :tag "Paren pair for host name")))
1137    
 (defconst tramp-make-multi-tramp-file-format-unified  
   (list "/%m" ":%m:%u@%h" ":%p")  
   "Value of `tramp-make-multi-tramp-file-format' for unified remoting.  
 Emacs (not XEmacs) uses a unified filename syntax for Ange-FTP and Tramp.  
 See `tramp-file-name-structure-unified' for details.")  
   
 (defconst tramp-make-multi-tramp-file-format-separate  
   (list "/[%m" "/%m:%u@%h" "]%p")  
   "Value of `tramp-make-multi-tramp-file-format' for separate remoting.  
 XEmacs uses a separate filename syntax for EFS and Tramp.  
 See `tramp-file-name-structure-separate' for details.")  
   
1138  (defcustom tramp-make-multi-tramp-file-format  (defcustom tramp-make-multi-tramp-file-format
1139    (if (featurep 'xemacs)    (list
1140        tramp-make-multi-tramp-file-format-separate     (concat tramp-prefix-format "%m")
1141      tramp-make-multi-tramp-file-format-unified)     (concat tramp-postfix-multi-hop-format
1142        "%m" tramp-postfix-multi-method-format
1143        "%u" tramp-postfix-user-format
1144        "%h")
1145       (concat tramp-postfix-host-format "%p"))
1146    "*Describes how to construct a `multi' file name.    "*Describes how to construct a `multi' file name.
1147  This is a list of three elements PREFIX, HOP and PATH.  This is a list of three elements PREFIX, HOP and PATH.
1148    
# Line 1327  use strict; Line 1452  use strict;
1452    
1453  my %%trans = do {  my %%trans = do {
1454      my $i = 0;      my $i = 0;
1455      map {($_, sprintf(q(%%06b), $i++))}      map {($_, substr(unpack(q(B8), chr $i++), 2, 6))}
1456        split //, q(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/)        split //, q(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/)
1457  };  };
1458    
# Line 1348  while (my $data = <STDIN>) { Line 1473  while (my $data = <STDIN>) {
1473      $pending .= $data;      $pending .= $data;
1474    
1475      my $len = length($pending);      my $len = length($pending);
1476      my $chunk = substr($pending, 0, $len & ~3, q());      my $chunk = substr($pending, 0, $len & ~3);
1477    
1478      # Easy method: translate from chars to (pregenerated) six-bit packets, join,      # Easy method: translate from chars to (pregenerated) six-bit packets, join,
1479      # split in 8-bit chunks and convert back to char.      # split in 8-bit chunks and convert back to char.
# Line 1398  This variable is buffer-local in every b Line 1523  This variable is buffer-local in every b
1523  ;; This variable does not have the right value in XEmacs.  What should  ;; This variable does not have the right value in XEmacs.  What should
1524  ;; I use instead of find-operation-coding-system in XEmacs?  ;; I use instead of find-operation-coding-system in XEmacs?
1525  (defvar tramp-feature-write-region-fix  (defvar tramp-feature-write-region-fix
1526    (unless (featurep 'xemacs)    (when (fboundp 'find-operation-coding-system)
1527      (let ((file-coding-system-alist '(("test" emacs-mule))))      (let ((file-coding-system-alist '(("test" emacs-mule))))
1528        (find-operation-coding-system 'write-region 0 0 "" nil "test")))        (find-operation-coding-system 'write-region 0 0 "" nil "test")))
1529      "Internal variable to say if `write-region' chooses the right coding.      "Internal variable to say if `write-region' chooses the right coding.
# Line 1455  on the FILENAME argument, even if VISIT Line 1580  on the FILENAME argument, even if VISIT
1580          "Alist of handler functions.          "Alist of handler functions.
1581  Operations not mentioned here will be handled by the normal Emacs functions.")  Operations not mentioned here will be handled by the normal Emacs functions.")
1582    
1583    ;; Handlers for partial tramp file names. For GNU Emacs just
1584    ;; `file-name-all-completions' is needed. The other ones are necessary
1585    ;; for XEmacs.
1586    (defconst tramp-completion-file-name-handler-alist
1587      '(
1588        (file-name-directory . tramp-completion-handle-file-name-directory)
1589        (file-name-nondirectory . tramp-completion-handle-file-name-nondirectory)
1590        (file-exists-p . tramp-completion-handle-file-exists-p)
1591        (file-name-all-completions . tramp-completion-handle-file-name-all-completions)
1592        (file-name-completion . tramp-completion-handle-file-name-completion)
1593        (expand-file-name . tramp-completion-handle-expand-file-name))
1594      "Alist of completion handler functions.
1595    Used for file names matching `tramp-file-name-regexp'. Operations not
1596    mentioned here will be handled by `tramp-file-name-handler-alist' or the
1597    normal Emacs functions.")
1598    
1599  ;;; Internal functions which must come first.  ;;; Internal functions which must come first.
1600    
1601  (defsubst tramp-message (level fmt-string &rest args)  (defsubst tramp-message (level fmt-string &rest args)
# Line 1527  If VAR is nil, then we bind `v' to the s Line 1668  If VAR is nil, then we bind `v' to the s
1668    
1669  (put 'with-parsed-tramp-file-name 'lisp-indent-function 2)  (put 'with-parsed-tramp-file-name 'lisp-indent-function 2)
1670    
1671    ;;; Config Manipulation Functions:
1672    
1673    (defun tramp-set-completion-function (method function-list)
1674      "Sets the list of completion functions for METHOD.
1675    FUNCTION-LIST is a list of entries of the form (FUNCTION FILE).
1676    The FUNCTION is intended to parse FILE according its syntax.
1677    It might be a predefined FUNCTION, or a user defined FUNCTION.
1678    Predefined FUNCTIONs are `tramp-parse-rhosts', `tramp-parse-shosts',
1679    `tramp-parse-hosts', and `tramp-parse-passwd'.
1680    Example:
1681    
1682        (tramp-set-completion-function
1683         \"ssh\"
1684         '((tramp-parse-shosts \"/etc/ssh_known_hosts\")
1685           (tramp-parse-shosts \"~/.ssh/known_hosts\")))"
1686    
1687      (let ((v (cdr (assoc method tramp-completion-function-alist))))
1688        (when v (setcdr v function-list))))
1689    
1690    (defun tramp-get-completion-function (method)
1691      "Returns list of completion functions for METHOD.
1692    For definition of that list see `tramp-set-completion-function'."
1693     (cdr (assoc method tramp-completion-function-alist)))
1694    
1695  ;;; File Name Handler Functions:  ;;; File Name Handler Functions:
1696    
1697  (defun tramp-handle-make-symbolic-link  (defun tramp-handle-make-symbolic-link
# Line 2556  This is like `dired-recursive-delete-dir Line 2721  This is like `dired-recursive-delete-dir
2721  (defun tramp-handle-insert-directory  (defun tramp-handle-insert-directory
2722    (filename switches &optional wildcard full-directory-p)    (filename switches &optional wildcard full-directory-p)
2723    "Like `insert-directory' for tramp files."    "Like `insert-directory' for tramp files."
2724      ;; For the moment, we assume that the remote "ls" program does not
2725      ;; grok "--dired".  In the future, we should detect this on
2726      ;; connection setup.
2727      (when (string-match "^--dired\\s-+" switches)
2728        (setq switches (replace-match "" nil t switches)))
2729    (setq filename (expand-file-name filename))    (setq filename (expand-file-name filename))
2730    (with-parsed-tramp-file-name filename nil    (with-parsed-tramp-file-name filename nil
2731      (when (tramp-ange-ftp-file-name-p multi-method method)      (when (tramp-ange-ftp-file-name-p multi-method method)
# Line 2607  This is like `dired-recursive-delete-dir Line 2777  This is like `dired-recursive-delete-dir
2777                     (file-name-nondirectory path)))))                     (file-name-nondirectory path)))))
2778        (sit-for 1)                       ;needed for rsh but not ssh?        (sit-for 1)                       ;needed for rsh but not ssh?
2779        (tramp-wait-for-output))        (tramp-wait-for-output))
2780      (insert-buffer (tramp-get-buffer multi-method method user host))      (let ((old-pos (point)))
2781      ;; On XEmacs, we want to call (exchange-point-and-mark t), but        (insert-buffer-substring
2782      ;; that doesn't exist on Emacs, so we use this workaround instead.         (tramp-get-buffer multi-method method user host))
2783      ;; Since zmacs-region-stays doesn't exist in Emacs, this ought to        ;; On XEmacs, we want to call (exchange-point-and-mark t), but
2784      ;; be safe.  Thanks to Daniel Pittman <daniel@danann.net>.        ;; that doesn't exist on Emacs, so we use this workaround instead.
2785      (let ((zmacs-region-stays t))        ;; Since zmacs-region-stays doesn't exist in Emacs, this ought to
2786        (exchange-point-and-mark))        ;; be safe.  Thanks to Daniel Pittman <daniel@danann.net>.
2787      (save-excursion        ;;     (let ((zmacs-region-stays t))
2788        (tramp-send-command multi-method method user host "cd")        ;;       (exchange-point-and-mark))
       (tramp-wait-for-output))  
     ;; Another XEmacs specialty follows.  What's the right way to do  
     ;; it?  
     (when (and (featurep 'xemacs)  
                (eq major-mode 'dired-mode))  
2789        (save-excursion        (save-excursion
2790          (require 'dired)          (tramp-send-command multi-method method user host "cd")
2791          (dired-insert-set-properties (point) (mark t))))))          (tramp-wait-for-output))
2792          ;; Another XEmacs specialty follows.  What's the right way to do
2793          ;; it?
2794          (when (and (featurep 'xemacs)
2795                     (eq major-mode 'dired-mode))
2796            (save-excursion
2797              (require 'dired)
2798              (dired-insert-set-properties old-pos (point)))))))
2799    
2800  ;; Continuation of kluge to pacify byte-compiler.  ;; Continuation of kluge to pacify byte-compiler.
2801  ;;(eval-when-compile  ;;(eval-when-compile
# Line 2778  This will break if COMMAND prints a newl Line 2950  This will break if COMMAND prints a newl
2950      (when (tramp-ange-ftp-file-name-p multi-method method)      (when (tramp-ange-ftp-file-name-p multi-method method)
2951        (tramp-invoke-ange-ftp 'file-local-copy filename))        (tramp-invoke-ange-ftp 'file-local-copy filename))
2952      (let ((trampbuf (get-buffer-create "*tramp output*"))      (let ((trampbuf (get-buffer-create "*tramp output*"))
2953              (rcp-program (tramp-get-rcp-program
2954                            multi-method
2955                            (tramp-find-method multi-method method user host)))
2956              (rcp-args (tramp-get-rcp-args
2957                         multi-method
2958                         (tramp-find-method multi-method method user host)))
2959            tmpfil)            tmpfil)
2960        (unless (file-exists-p filename)        (unless (file-exists-p filename)
2961          (error "Cannot make local copy of non-existing file `%s'"          (error "Cannot make local copy of non-existing file `%s'"
2962                 filename))                 filename))
2963        (setq tmpfil (tramp-make-temp-file))        (setq tmpfil (tramp-make-temp-file))
2964        (cond ((tramp-get-rcp-program multi-method method)        (cond (rcp-program
2965               ;; Use rcp-like program for file transfer.               ;; Use rcp-like program for file transfer.
2966               (tramp-message-for-buffer               (tramp-message-for-buffer
2967                multi-method method user host                multi-method method user host
# Line 2792  This will break if COMMAND prints a newl Line 2970  This will break if COMMAND prints a newl
2970               (unless (equal               (unless (equal
2971                        0                        0
2972                        (apply #'call-process                        (apply #'call-process
2973                               (tramp-get-rcp-program multi-method method)                               rcp-program
2974                               nil trampbuf nil                               nil trampbuf nil
2975                               (append (tramp-get-rcp-args multi-method method)                               (append rcp-args
2976                                       (list                                       (list
2977                                        (tramp-make-rcp-program-file-name                                        (tramp-make-rcp-program-file-name
2978                                         user host                                         user host
# Line 2804  This will break if COMMAND prints a newl Line 2982  This will break if COMMAND prints a newl
2982                 (error                 (error
2983                  (concat "tramp-handle-file-local-copy: `%s' didn't work, "                  (concat "tramp-handle-file-local-copy: `%s' didn't work, "
2984                          "see buffer `%s' for details")                          "see buffer `%s' for details")
2985                  (tramp-get-rcp-program multi-method method) trampbuf))                  rcp-program trampbuf))
2986               (tramp-message-for-buffer               (tramp-message-for-buffer
2987                multi-method method user host                multi-method method user host
2988                5 "Fetching %s to tmp file %s...done" filename tmpfil))                5 "Fetching %s to tmp file %s...done" filename tmpfil))
2989              ((and (tramp-get-encoding-command multi-method method user host)              ((and (tramp-get-remote-encoding multi-method method user host)
2990                    (tramp-get-decoding-command multi-method method user host))                    (tramp-get-remote-decoding multi-method method user host))
2991               ;; Use inline encoding for file transfer.               ;; Use inline encoding for file transfer.
2992               (save-excursion               (save-excursion
2993                 ;; Following line for setting tramp-current-method,                 ;; Following line for setting tramp-current-method,
# Line 2818  This will break if COMMAND prints a newl Line 2996  This will break if COMMAND prints a newl
2996                 (tramp-message 5 "Encoding remote file %s..." filename)                 (tramp-message 5 "Encoding remote file %s..." filename)
2997                 (tramp-barf-unless-okay                 (tramp-barf-unless-okay
2998                  multi-method method user host                  multi-method method user host
2999                  (concat (tramp-get-encoding-command multi-method method user host)                  (concat (tramp-get-remote-encoding
3000                             multi-method method user host)
3001                          " < " (tramp-shell-quote-argument path))                          " < " (tramp-shell-quote-argument path))
3002                  nil 'file-error                  nil 'file-error
3003                  "Encoding remote file failed, see buffer `%s' for details"                  "Encoding remote file failed, see buffer `%s' for details"
# Line 2828  This will break if COMMAND prints a newl Line 3007  This will break if COMMAND prints a newl
3007                 (delete-region (point) (progn (forward-line -1) (point)))                 (delete-region (point) (progn (forward-line -1) (point)))
3008    
3009                 (tramp-message 5 "Decoding remote file %s..." filename)                 (tramp-message 5 "Decoding remote file %s..." filename)
3010                 (if (and (tramp-get-decoding-function multi-method method user host)  
3011                          (fboundp (tramp-get-decoding-function                 (let ((loc-enc (tramp-get-local-encoding
3012                                    multi-method method user host)))                                 multi-method method user host))
3013                     ;; If tramp-decoding-function is defined for this                       (loc-dec (tramp-get-local-decoding
3014                     ;; method, we call it.                                 multi-method method user host)))
3015                   (if (and (symbolp loc-dec) (fboundp loc-dec))
3016                       ;; If local decoding is a function, we call it.
3017                     (let ((tmpbuf (get-buffer-create " *tramp tmp*")))                     (let ((tmpbuf (get-buffer-create " *tramp tmp*")))
3018                       (set-buffer tmpbuf)                       (set-buffer tmpbuf)
3019                       (erase-buffer)                       (erase-buffer)
# Line 2841  This will break if COMMAND prints a newl Line 3022  This will break if COMMAND prints a newl
3022                       (tramp-message-for-buffer                       (tramp-message-for-buffer
3023                        multi-method method user host                        multi-method method user host
3024                        6 "Decoding remote file %s with function %s..."                        6 "Decoding remote file %s with function %s..."
3025                        filename                        filename loc-dec)
                       (tramp-get-decoding-function multi-method method user host))  
3026                       (set-buffer tmpbuf)                       (set-buffer tmpbuf)
3027                         ;; Douglas Gray Stephens <DGrayStephens@slb.com>
3028                         ;; says that we need to strip tramp_exit_status
3029                         ;; line from the output here.  Go to point-max,
3030                         ;; search backward for tramp_exit_status, delete
3031                         ;; between point and point-max if found.
3032                       (let ((coding-system-for-write 'no-conversion))                       (let ((coding-system-for-write 'no-conversion))
3033                         (funcall (tramp-get-decoding-function                         (funcall loc-dec (point-min) (point-max))
                                  multi-method method user host)  
                                 (point-min)  
                                 (point-max))  
3034                         (write-region (point-min) (point-max) tmpfil))                         (write-region (point-min) (point-max) tmpfil))
3035                       (kill-buffer tmpbuf))                       (kill-buffer tmpbuf))
3036                   ;; If tramp-decoding-function is not defined for this                   ;; If tramp-decoding-function is not defined for this
# Line 2857  This will break if COMMAND prints a newl Line 3039  This will break if COMMAND prints a newl
3039                     (write-region (point-min) (point-max) tmpfil2)                     (write-region (point-min) (point-max) tmpfil2)
3040                     (tramp-message                     (tramp-message
3041                      6 "Decoding remote file %s with command %s..."                      6 "Decoding remote file %s with command %s..."
3042                      filename                      filename loc-dec)
3043                      (tramp-get-decoding-command multi-method method user host))                     (tramp-call-local-coding-command
3044                     (call-process                      loc-dec tmpfil2 tmpfil)
                     tramp-sh-program  
                     tmpfil2             ;input  
                     nil                 ;output  
                     nil                 ;display  
                     "-c" (concat (tramp-get-decoding-command  
                                   multi-method method user host)  
                                  " > " tmpfil))  
3045                     (delete-file tmpfil2)))                     (delete-file tmpfil2)))
3046                 (tramp-message-for-buffer                 (tramp-message-for-buffer
3047                  multi-method method user host                  multi-method method user host
3048                  5 "Decoding remote file %s...done" filename)))                  5 "Decoding remote file %s...done" filename))))
3049    
3050              (t (error "Wrong method specification for `%s'" method)))              (t (error "Wrong method specification for `%s'" method)))
3051        tmpfil)))        tmpfil)))
# Line 2910  This will break if COMMAND prints a newl Line 3085  This will break if COMMAND prints a newl
3085          ;; Now `last-coding-system-used' has right value.  Remember it.          ;; Now `last-coding-system-used' has right value.  Remember it.
3086          (when (boundp 'last-coding-system-used)          (when (boundp 'last-coding-system-used)
3087            (setq coding-system-used last-coding-system-used))            (setq coding-system-used last-coding-system-used))
3088          (tramp-message 9 "Inserting local temp file `%s'...done" local-copy)          (tramp-message-for-buffer
3089             multi-method method user host
3090             9 "Inserting local temp file `%s'...done" local-copy)
3091          (delete-file local-copy)          (delete-file local-copy)
3092          (when (boundp 'last-coding-system-used)          (when (boundp 'last-coding-system-used)
3093            (setq last-coding-system-used coding-system-used))            (setq last-coding-system-used coding-system-used))
# Line 2944  This will break if COMMAND prints a newl Line 3121  This will break if COMMAND prints a newl
3121        (tramp-invoke-ange-ftp 'write-region        (tramp-invoke-ange-ftp 'write-region
3122                               start end filename append visit))                               start end filename append visit))
3123      (let ((curbuf (current-buffer))      (let ((curbuf (current-buffer))
3124            (rcp-program (tramp-get-rcp-program multi-method method))            (rcp-program (tramp-get-rcp-program
3125            (rcp-args (tramp-get-rcp-args multi-method method))                          multi-method (tramp-find-method multi-method method user host)))
3126            (encoding-command            (rcp-args (tramp-get-rcp-args
3127             (tramp-get-encoding-command multi-method method user host))                       multi-method
3128            (encoding-function                       (tramp-find-method multi-method method user host)))
3129             (tramp-get-encoding-function multi-method method user host))            (rem-enc (tramp-get-remote-encoding multi-method method user host))
3130            (decoding-command            (rem-dec (tramp-get-remote-decoding multi-method method user host))
3131             (tramp-get-decoding-command multi-method method user host))            (loc-enc (tramp-get-local-encoding multi-method method user host))
3132              (loc-dec (tramp-get-local-decoding multi-method method user host))
3133            (trampbuf (get-buffer-create "*tramp output*"))            (trampbuf (get-buffer-create "*tramp output*"))
3134            ;; We use this to save the value of `last-coding-system-used'            ;; We use this to save the value of `last-coding-system-used'
3135            ;; after writing the tmp file.  At the end of the function,            ;; after writing the tmp file.  At the end of the function,
# Line 3013  This will break if COMMAND prints a newl Line 3191  This will break if COMMAND prints a newl
3191                  multi-method method user host                  multi-method method user host
3192                  6 "Transferring file using `%s'...done"                  6 "Transferring file using `%s'...done"
3193                  rcp-program)))                  rcp-program)))
3194              ((and encoding-command decoding-command)              ((and rem-enc rem-dec)
3195               ;; Use inline file transfer               ;; Use inline file transfer
3196               (let ((tmpbuf (get-buffer-create " *tramp file transfer*")))               (let ((tmpbuf (get-buffer-create " *tramp file transfer*")))
3197                 (save-excursion                 (save-excursion
# Line 3023  This will break if COMMAND prints a newl Line 3201  This will break if COMMAND prints a newl
3201                   (set-buffer tmpbuf)                   (set-buffer tmpbuf)
3202                   (erase-buffer)                   (erase-buffer)
3203                   ;; Use encoding function or command.                   ;; Use encoding function or command.
3204                   (if (and encoding-function                   (if (and (symbolp loc-enc) (fboundp loc-enc))
                           (fboundp encoding-function))  
3205                       (progn                       (progn
3206                         (tramp-message-for-buffer                         (tramp-message-for-buffer
3207                          multi-method method user host                          multi-method method user host
# Line 3041  This will break if COMMAND prints a newl Line 3218  This will break if COMMAND prints a newl
3218                         ;; tmp file anyway.                         ;; tmp file anyway.
3219                         (let ((default-directory                         (let ((default-directory
3220                                 (tramp-temporary-file-directory)))                                 (tramp-temporary-file-directory)))
3221                           (funcall encoding-function (point-min) (point-max)))                           (funcall loc-enc (point-min) (point-max)))
3222                         (goto-char (point-max))                         (goto-char (point-max))
3223                         (unless (bolp)                         (unless (bolp)
3224                           (newline)))                           (newline)))
3225                     (tramp-message-for-buffer                     (tramp-message-for-buffer
3226                      multi-method method user host                      multi-method method user host
3227                      6 "Encoding region using command...")                      6 "Encoding region using command `%s'..." loc-enc)
3228                     (unless (equal 0                     (unless (equal 0 (tramp-call-local-coding-command
3229                                    (call-process                                       loc-enc tmpfil t))
                                    tramp-sh-program  
                                    tmpfil ;input = local tmp file  
                                    t    ;output is current buffer  
                                    nil  ;don't redisplay  
                                    "-c"  
                                    encoding-command))  
3230                       (pop-to-buffer trampbuf)                       (pop-to-buffer trampbuf)
3231                       (error (concat "Cannot write to `%s', local encoding"                       (error (concat "Cannot write to `%s', local encoding"
3232                                      " command `%s' failed")                                      " command `%s' failed")
3233                              filename encoding-command)))                              filename loc-enc)))
3234                   ;; Send tmpbuf into remote decoding command which                   ;; Send tmpbuf into remote decoding command which
3235                   ;; writes to remote file.  Because this happens on the                   ;; writes to remote file.  Because this happens on the
3236                   ;; remote host, we cannot use the function.                   ;; remote host, we cannot use the function.
# Line 3069  This will break if COMMAND prints a newl Line 3240  This will break if COMMAND prints a newl
3240                   (tramp-send-command                   (tramp-send-command
3241                    multi-method method user host                    multi-method method user host
3242                    (format "%s >%s <<'EOF'"                    (format "%s >%s <<'EOF'"
3243                            decoding-command                            rem-dec
3244                            (tramp-shell-quote-argument path)))                            (tramp-shell-quote-argument path)))
3245                   (set-buffer tmpbuf)                   (set-buffer tmpbuf)
3246                   (tramp-message-for-buffer                   (tramp-message-for-buffer
# Line 3092  This will break if COMMAND prints a newl Line 3263  This will break if COMMAND prints a newl
3263                    multi-method method user host nil nil 'file-error                    multi-method method user host nil nil 'file-error
3264                    (concat "Couldn't write region to `%s',"                    (concat "Couldn't write region to `%s',"
3265                            " decode using `%s' failed")                            " decode using `%s' failed")
3266                    filename decoding-command)                    filename rem-dec)
3267                   (tramp-message 5 "Decoding region into remote file %s...done"                   (tramp-message 5 "Decoding region into remote file %s...done"
3268                                  filename)                                  filename)
3269                   (kill-buffer tmpbuf))))                   (kill-buffer tmpbuf))))
# Line 3155  pass to the OPERATION." Line 3326  pass to the OPERATION."
3326                 operation))                 operation))
3327           (inhibit-file-name-handlers           (inhibit-file-name-handlers
3328            (list 'tramp-file-name-handler            (list 'tramp-file-name-handler
3329                    'tramp-completion-file-name-handler
3330                    (and (eq inhibit-file-name-operation op)
3331                         inhibit-file-name-handlers)))
3332             (inhibit-file-name-operation op))
3333        (apply operation args)))
3334    
3335    ;; This function is used from `tramp-completion-file-name-handler' functions
3336    ;; only, if `tramp-completion-mode' is true. But this cannot be checked here
3337    ;; because the check is based on a full filename, not available for all
3338    ;; basic I/O operations.
3339    (defun tramp-completion-run-real-handler (operation args)
3340      "Invoke `tramp-file-name-handler' for OPERATION.
3341    First arg specifies the OPERATION, second arg is a list of arguments to
3342    pass to the OPERATION."
3343      (let* ((op (if (eq operation 'ange-ftp-hook-function)
3344                     (car args)
3345                   operation))
3346             (inhibit-file-name-handlers
3347              (list 'tramp-completion-file-name-handler
3348                  (and (eq inhibit-file-name-operation op)                  (and (eq inhibit-file-name-operation op)
3349                       inhibit-file-name-handlers)))                       inhibit-file-name-handlers)))
3350           (inhibit-file-name-operation op))           (inhibit-file-name-operation op))
# Line 3171  Falls back to normal file name handler i Line 3361  Falls back to normal file name handler i
3361            (save-match-data (apply (cdr fn) args)))            (save-match-data (apply (cdr fn) args)))
3362        (tramp-run-real-handler operation args))))        (tramp-run-real-handler operation args))))
3363    
3364    (put 'tramp-file-name-handler 'file-remote-p t) ;for file-remote-p
3365    
3366    ;;;###autoload
3367    (defun tramp-completion-file-name-handler (operation &rest args)
3368      "Invoke tramp file name completion handler.
3369    Falls back to normal file name handler if no tramp file name handler exists."
3370    ;;   (setq tramp-debug-buffer t)
3371    ;;   (tramp-message 1 "%s %s" operation args)
3372    ;;   (tramp-message 1 "%s %s\n%s"
3373    ;;               operation args (with-output-to-string (backtrace)))
3374      (let ((fn (assoc operation tramp-completion-file-name-handler-alist)))
3375        (if fn
3376            (catch 'tramp-forward-to-ange-ftp
3377              (save-match-data (apply (cdr fn) args)))
3378          (tramp-completion-run-real-handler operation args))))
3379    
3380  ;; Register in file name handler alist  ;; Register in file name handler alist
3381  ;;;###autoload  ;;;###autoload
3382  (add-to-list 'file-name-handler-alist  (add-to-list 'file-name-handler-alist
3383               (cons tramp-file-name-regexp 'tramp-file-name-handler))               (cons tramp-file-name-regexp 'tramp-file-name-handler))
3384    (add-to-list 'file-name-handler-alist
3385                 (cons tramp-completion-file-name-regexp
3386                       'tramp-completion-file-name-handler))
3387    
3388  ;; To handle EFS, the following functions need to be dealt with:  ;; To handle EFS, the following functions need to be dealt with:
3389  ;;  ;;
# Line 3212  necessary anymore." Line 3421  necessary anymore."
3421              (cons jka (delete jka file-name-handler-alist))))))              (cons jka (delete jka file-name-handler-alist))))))
3422  (tramp-repair-jka-compr)  (tramp-repair-jka-compr)
3423    
3424    (defun tramp-flatten-list (arg)
3425      "Expands all lists inside ARG to a sequential list.
3426    Return (nil) if arg is nil."
3427      (let ((car (car arg))
3428            (cdr (cdr arg)))
3429        (cond
3430         ((eq arg nil) '(nil))
3431         ((listp car)
3432          (if (null cdr)
3433              (tramp-flatten-list car)
3434            (append (tramp-flatten-list car) (tramp-flatten-list cdr))))
3435         ((null cdr) (list car))
3436         (t (cons car (tramp-flatten-list cdr))))))
3437    
3438  (defun tramp-invoke-ange-ftp (operation &rest args)  (defun tramp-invoke-ange-ftp (operation &rest args)
3439    "Invoke the Ange-FTP handler function and throw."    "Invoke the Ange-FTP handler function and throw."
3440    (or (boundp 'ange-ftp-name-format)    (or (boundp 'ange-ftp-name-format)
# Line 3228  necessary anymore." Line 3451  necessary anymore."
3451    
3452  (defun tramp-ange-ftp-file-name-p (multi-method method)  (defun tramp-ange-ftp-file-name-p (multi-method method)
3453    "Check if it's a filename that should be forwarded to Ange-FTP."    "Check if it's a filename that should be forwarded to Ange-FTP."
3454    (and (not (featurep 'xemacs))    (and tramp-unified-filenames
3455         (null multi-method)         (null multi-method)
3456         (string= method tramp-ftp-method)))         (string= method tramp-ftp-method)))
3457    
# Line 3300  necessary anymore." Line 3523  necessary anymore."
3523      (tramp-setup-complete)      (tramp-setup-complete)
3524    (eval-after-load "complete" '(tramp-setup-complete)))    (eval-after-load "complete" '(tramp-setup-complete)))
3525    
3526    ;;; File name handler functions for completion mode
3527    
3528    ;; Necessary because `tramp-file-name-regexp-unified' and
3529    ;; `tramp-completion-file-name-regexp-unified' aren't different.
3530    ;; If nil, `tramp-completion-run-real-handler' is called (i.e. forwarding to
3531    ;; `tramp-file-name-handler'). Otherwise, it takes `tramp-run-real-handler'.
3532    ;; Using `last-input-event' is a little bit risky, because completing a file
3533    ;; might require loading other files, like "~/.netrc", and for them it
3534    ;; shouldn't be decided based on that variable. On the other hand, those files
3535    ;; shouldn't have partial tramp file name syntax. Maybe another variable should
3536    ;; be introduced overwriting this check in such cases. Or we change tramp
3537    ;; file name syntax in order to avoid ambiguities, like in XEmacs ...
3538    ;; In case of XEmacs it can be always true (and wouldn't be necessary).
3539    (defun tramp-completion-mode (file)
3540      "Checks whether method / user name / host name completion is active."
3541      (cond
3542       ((featurep 'xemacs) t)
3543       ((string-match "^/.*:.*:$" file) nil)
3544       ((string-match
3545         (concat
3546          tramp-prefix-regexp
3547          tramp-method-regexp tramp-postfix-single-method-regexp "$")
3548         file)
3549        (member (match-string 1 file)
3550                (cons tramp-ftp-method (mapcar 'car tramp-methods))))
3551       ((or (equal last-input-event 'tab)
3552            (and (not (event-modifiers last-input-event))
3553                 (integerp last-input-event)
3554                 (or (char-equal last-input-event ?\?)
3555                     (char-equal last-input-event ?\t) ; handled by 'tab already?
3556                     (char-equal last-input-event ?\ ))))
3557        t)))
3558    
3559    (defun tramp-completion-handle-file-exists-p (filename)
3560      "Like `file-exists-p' for tramp files."
3561      (if (tramp-completion-mode filename)
3562          (tramp-run-real-handler
3563           'file-exists-p (list filename))
3564        (tramp-completion-run-real-handler
3565         'file-exists-p (list filename))))
3566    
3567    ;; Path manipulation in case of partial TRAMP file names.
3568    (defun tramp-completion-handle-file-name-directory (file)
3569      "Like `file-name-directory' but aware of TRAMP files."
3570      (if (tramp-completion-mode file)
3571          "/"
3572        (tramp-completion-run-real-handler
3573         'file-name-directory (list file))))
3574    
3575    ;; Path manipulation in case of partial TRAMP file names.
3576    (defun tramp-completion-handle-file-name-nondirectory (file)
3577      "Like `file-name-nondirectory' but aware of TRAMP files."
3578      (substring
3579       file (length (tramp-completion-handle-file-name-directory file))))
3580    
3581    ;; Method, host name and user name completion.
3582    ;; `tramp-completion-dissect-file-name' returns a list of
3583    ;; tramp-file-name structures. For all of them we return possible completions.
3584    (defun tramp-completion-handle-file-name-all-completions (filename directory)
3585      "Like `file-name-all-completions' for partial tramp files."
3586    
3587      (let*
3588          ((fullname (concat directory filename))
3589           ;; prepare ange-ftp fix
3590           (fix-ange-ftp-string
3591            (concat tramp-ftp-method tramp-postfix-single-method-format))
3592           (fix-ange-ftp (string-match (concat "^" fix-ange-ftp-string) filename))
3593           ;; local files
3594           (result
3595            (if (tramp-completion-mode fullname)
3596                (tramp-run-real-handler
3597                 'file-name-all-completions (list filename directory))
3598              (tramp-completion-run-real-handler
3599               'file-name-all-completions (list filename directory))))
3600           ;; possible completion structures
3601           (v (tramp-completion-dissect-file-name fullname)))
3602    
3603        (while v
3604          (let* ((car (car v))
3605                 (multi-method (tramp-file-name-multi-method car))
3606                 (method (tramp-file-name-method car))
3607                 (user (tramp-file-name-user car))
3608                 (host (tramp-file-name-host car))
3609                 (path (tramp-file-name-path car))
3610                 (m (tramp-find-method multi-method method user host))
3611                 all-user-hosts)
3612    
3613            (unless (or multi-method ;; Not handled (yet).
3614                        path)        ;; Nothing to complete
3615    
3616              (if (or user host)
3617    
3618                ;; Method dependent user / host combinations
3619                (progn
3620                  (mapcar
3621                   '(lambda (x)
3622                      (setq all-user-hosts
3623                            (append all-user-hosts
3624                                    (funcall (nth 0 x) (nth 1 x)))))
3625                   (tramp-get-completion-function m))
3626    
3627                  (setq result (append result
3628                    (mapcar
3629                     '(lambda (x)
3630                        (tramp-get-completion-user-host
3631                         method user host (nth 0 x) (nth 1 x)))
3632                     (delq nil all-user-hosts)))))
3633    
3634                ;; Possible methods
3635                (setq result
3636                      (append result (tramp-get-completion-methods m))))
3637    
3638              ;; Ange-ftp completions.
3639              ;; Filename might have the form "ftp:xxx". Ange-ftp isn't able to
3640              ;; handle the prefix "ftp:" correctly in
3641              ;; `ange-ftp-file-name-all-completions'; it simply calls
3642              ;;`(all-completions file (ange-ftp-generate-root-prefixes))'.
3643              ;; So we must wrap around.
3644              (when (tramp-ange-ftp-file-name-p nil m)
3645                (setq result (append result
3646                  (mapcar
3647                   '(lambda (x) (if fix-ange-ftp (concat fix-ange-ftp-string x) x))
3648                   (catch 'tramp-forward-to-ange-ftp
3649                     (tramp-invoke-ange-ftp
3650                      'file-name-all-completions
3651                      (if fix-ange-ftp
3652                          (substring filename (length fix-ange-ftp-string))
3653                        filename)
3654                      directory)))))))
3655    
3656          (setq v (delq car v))))
3657    
3658        ;;; unify list, remove nil elements
3659        (let (result1)
3660          (while result
3661            (let ((car (car result)))
3662              (when car (add-to-list 'result1 car))
3663              (setq result (delq car result))))
3664    
3665          result1)))
3666    
3667    ;; Method, host name and user name completion for a file.
3668    (defun tramp-completion-handle-file-name-completion (filename directory)
3669      "Like `file-name-completion' for tramp files."
3670      (try-completion filename
3671       (mapcar 'list (file-name-all-completions filename directory))))
3672    
3673    ;; I misuse a little bit the tramp-file-name structure in order to handle
3674    ;; completion possibilities for partial methods / user names / host names.
3675    ;; Return value is a list of tramp-file-name structures according to possible
3676    ;; completions. If "multi-method" or "path" is non-nil it means there
3677    ;; shouldn't be a completion anymore.
3678    
3679    ;; Expected results:
3680    
3681    ;; "/x" "/[x"               "/x@" "/[x@"             "/x@y" "/[x@y"
3682    ;; [nil nil nil "x" nil]    [nil nil "x" nil nil]    [nil nil "x" "y" nil]
3683    ;; [nil nil "x" nil nil]
3684    ;; [nil "x" nil nil nil]
3685    
3686    ;; "/x:"                    "/x:y"                   "/x:y:"                  
3687    ;; [nil nil nil "x" ""]     [nil nil nil "x" "y"]    [nil "x" nil "y" ""]
3688    ;;       "/[x/"                   "/[x/y"
3689    ;; [nil "x" nil "" nil]     [nil "x" nil "y" nil]
3690    ;; [nil "x" "" nil nil]     [nil "x" "y" nil nil]
3691    
3692    ;; "/x:y@"                  "/x:y@z"                 "/x:y@z:"
3693    ;; [nil nil nil "x" "y@"]   [nil nil nil "x" "y@z"]  [nil "x" "y" "z" ""]
3694    ;;       "/[x/y@"                 "/[x/y@z"
3695    ;; [nil "x" nil "y" nil]    [nil "x" "y" "z" nil]
3696    (defun tramp-completion-dissect-file-name (name)
3697      "Returns a list of `tramp-file-name' structures.
3698    They are collected by `tramp-completion-dissect-file-name1'."
3699    
3700      (let* ((result)
3701             (x-nil "\\|\\(\\)"))
3702    
3703        ;; "/method" "/[method"
3704        (defconst tramp-completion-file-name-structure1
3705          (list (concat tramp-prefix-regexp "\\(" tramp-method-regexp x-nil "\\)$")
3706                1 9 9 9))
3707        ;; "/user" "/[user"
3708        (defconst tramp-completion-file-name-structure2
3709          (list (concat tramp-prefix-regexp "\\(" tramp-user-regexp x-nil   "\\)$")
3710                9 1 9 9))
3711        ;; "/host" "/[host"
3712        (defconst tramp-completion-file-name-structure3
3713          (list (concat tramp-prefix-regexp "\\(" tramp-host-regexp x-nil   "\\)$")
3714                9 9 1 9))
3715        ;; "/user@host" "/[user@host"
3716        (defconst tramp-completion-file-name-structure4
3717          (list (concat tramp-prefix-regexp
3718                        "\\(" tramp-user-regexp "\\)"   tramp-postfix-user-regexp
3719                        "\\(" tramp-host-regexp x-nil   "\\)$")
3720                9 1 2 9))
3721        ;; "/method:user" "/[method/user"
3722        (defconst tramp-completion-file-name-structure5
3723          (list (concat tramp-prefix-regexp
3724                        "\\(" tramp-method-regexp "\\)" tramp-postfix-single-method-regexp
3725                        "\\(" tramp-user-regexp x-nil   "\\)$")
3726                1 2 9 9))
3727        ;; "/method:host" "/[method/host"
3728        (defconst tramp-completion-file-name-structure6
3729          (list (concat tramp-prefix-regexp
3730                        "\\(" tramp-method-regexp "\\)" tramp-postfix-single-method-regexp
3731                        "\\(" tramp-host-regexp x-nil   "\\)$")
3732                1 9 2 9))
3733        ;; "/method:user@host" "/[method/user@host"
3734        (defconst tramp-completion-file-name-structure7
3735          (list (concat tramp-prefix-regexp
3736                        "\\(" tramp-method-regexp "\\)" tramp-postfix-single-method-regexp
3737                        "\\(" tramp-user-regexp "\\)"   tramp-postfix-user-regexp
3738                        "\\(" tramp-host-regexp x-nil   "\\)$")
3739                1 2 3 9))
3740      
3741        (mapcar '(lambda (regexp)
3742          (add-to-list 'result
3743            (tramp-completion-dissect-file-name1 regexp name)))
3744          (list
3745           tramp-completion-file-name-structure1
3746           tramp-completion-file-name-structure2
3747           tramp-completion-file-name-structure3
3748           tramp-completion-file-name-structure4
3749           tramp-completion-file-name-structure5
3750           tramp-completion-file-name-structure6
3751           tramp-completion-file-name-structure7
3752           tramp-file-name-structure))
3753    
3754        (delq nil result)))
3755    
3756    (defun tramp-completion-dissect-file-name1 (structure name)
3757      "Returns a `tramp-file-name' structure matching STRUCTURE.
3758    The structure consists of multi-method, remote method, remote user,
3759    remote host and remote path name."
3760    
3761      (let (method)
3762        (save-match-data
3763          (when (string-match (nth 0 structure) name)
3764            (setq method (match-string (nth 1 structure) name))
3765            (if (and method (member method tramp-multi-methods))
3766                ;; Not handled (yet).
3767                (make-tramp-file-name
3768                 :multi-method method
3769                 :method nil
3770                 :user nil
3771                 :host nil
3772                 :path nil)
3773              (let ((user   (match-string (nth 2 structure) name))
3774                    (host   (match-string (nth 3 structure) name))
3775                    (path   (match-string (nth 4 structure) name)))
3776                (make-tramp-file-name
3777                 :multi-method nil
3778                 :method method
3779                 :user user
3780                 :host host
3781                 :path path)))))))
3782    
3783    ;; This function returns all possible method completions, adding the
3784    ;; trailing method delimeter.
3785    ;; In case of Emacs, `tramp-ftp-method' is handled as well because it doesn't
3786    ;; belong to `tramp-methods'.
3787    (defun tramp-get-completion-methods (partial-method)
3788      "Returns all method completions for PARTIAL-METHOD."
3789      (let ((all-methods (delete "multi" (mapcar 'car tramp-methods))))
3790    
3791        (mapcar
3792         '(lambda (method)
3793            (and method
3794             (string-match (concat "^" (regexp-quote partial-method)) method)
3795             ;; we must remove leading "/".
3796             (substring (tramp-make-tramp-file-name nil method nil nil nil) 1)))
3797    
3798         (add-to-list 'all-methods
3799                      (when tramp-unified-filenames tramp-ftp-method)))))
3800    
3801    ;; Compares partial user and host names with possible completions.
3802    (defun tramp-get-completion-user-host (method partial-user partial-host user host)
3803      "Returns the most expanded string for user and host name completion.
3804    PARTIAL-USER must match USER, PARTIAL-HOST must match HOST."
3805      (cond
3806    
3807       ((and partial-user partial-host)
3808        (if (and host
3809                 (string-match (concat "^" (regexp-quote partial-host)) host)
3810                 (string-equal partial-user (or user partial-user)))
3811            (setq user partial-user)
3812          (setq user nil
3813                host nil)))
3814    
3815       (partial-user
3816        (setq host nil)
3817        (unless
3818            (and user (string-match (concat "^" (regexp-quote partial-user)) user))
3819          (setq user nil)))
3820    
3821       (partial-host
3822        (setq user nil)
3823        (unless
3824            (and host (string-match (concat "^" (regexp-quote partial-host)) host))
3825          (setq host nil)))
3826    
3827       (t (setq user nil
3828                host nil)))
3829    
3830      (when (or user host)
3831        ;; we must remove leading "/".
3832        (substring (tramp-make-tramp-file-name nil method user host nil) 1)))
3833    
3834    (defun tramp-parse-rhosts (filename)
3835      "Return a list of (user host) tuples allowed to access.
3836    Either user or host may be nil"
3837    
3838      (let (res)
3839        (when (file-exists-p filename)
3840          (with-temp-buffer
3841            (insert-file-contents filename)
3842            (goto-char (point-min))
3843            (while (not (eobp))
3844              (add-to-list 'res (tramp-parse-rhosts-group)))))
3845        res))
3846    
3847    ;; Taken from gnus/netrc.el
3848    (eval-and-compile
3849      (defalias 'tramp-point-at-eol
3850        (if (fboundp 'point-at-eol)
3851            'point-at-eol
3852          'line-end-position)))
3853    
3854    (defun tramp-parse-rhosts-group ()
3855       "Return a (user host) tuple allowed to access.
3856    Either user or host may be nil"
3857    
3858       (let ((result)
3859             (regexp
3860              (concat
3861               "^\\(" tramp-host-regexp "\\)"
3862               "\\([ \t]+" "\\(" tramp-user-regexp "\\)" "\\)?")))
3863    
3864         (narrow-to-region (point) (tramp-point-at-eol))
3865         (when (re-search-forward regexp nil t)
3866           (setq result (append (list (match-string 3) (match-string 1)))))
3867         (widen)
3868         (forward-line 1)
3869         result))
3870    
3871    (defun tramp-parse-shosts (filename)
3872      "Return a list of (user host) tuples allowed to access.
3873    User is always nil."
3874    
3875      (let (res)
3876        (when (file-exists-p filename)
3877          (with-temp-buffer
3878            (insert-file-contents filename)
3879            (goto-char (point-min))
3880            (while (not (eobp))
3881              (add-to-list 'res (tramp-parse-shosts-group)))))
3882        res))
3883    
3884    (defun tramp-parse-shosts-group ()
3885       "Return a (user host) tuple allowed to access.
3886    User is always nil."
3887    
3888       (let ((result)
3889             (regexp (concat "^\\(" tramp-host-regexp "\\)")))
3890    
3891         (narrow-to-region (point) (tramp-point-at-eol))
3892         (when (re-search-forward regexp nil t)
3893           (setq result (list nil (match-string 1))))
3894         (widen)
3895         (or
3896          (> (skip-chars-forward ",") 0)
3897          (forward-line 1))
3898         result))
3899    
3900    (defun tramp-parse-hosts (filename)
3901      "Return a list of (user host) tuples allowed to access.
3902    User is always nil."
3903    
3904      (let (res)
3905        (when (file-exists-p filename)
3906          (with-temp-buffer
3907            (insert-file-contents filename)
3908            (goto-char (point-min))
3909            (while (not (eobp))
3910              (add-to-list 'res (tramp-parse-hosts-group)))))
3911        res))
3912    
3913    (defun tramp-parse-hosts-group ()
3914       "Return a (user host) tuple allowed to access.
3915    User is always nil."
3916    
3917       (let ((result)
3918             (regexp (concat "^\\(" tramp-host-regexp "\\)")))
3919    
3920         (narrow-to-region (point) (tramp-point-at-eol))
3921         (when (re-search-forward regexp nil t)
3922           (unless (char-equal (or (char-after) ?\n) ?:) ; no IPv6
3923             (setq result (list nil (match-string 1)))))
3924         (widen)
3925         (or
3926          (> (skip-chars-forward " \t") 0)
3927          (forward-line 1))
3928         result))
3929    
3930    (defun tramp-parse-passwd (filename)
3931      "Return a list of (user host) tuples allowed to access.
3932    Host is always \"localhost\"."
3933    
3934      (let (res)
3935        (if (and (symbolp 'user) (zerop (length user)))
3936            '(("root" nil))
3937          (when (file-exists-p filename)
3938            (with-temp-buffer
3939              (insert-file-contents filename)
3940              (goto-char (point-min))
3941              (while (not (eobp))
3942                (add-to-list 'res (tramp-parse-passwd-group)))))
3943          res)))
3944    
3945    (defun tramp-parse-passwd-group ()
3946       "Return a (user host) tuple allowed to access.
3947    User is always nil."
3948    
3949       (let ((result)
3950             (regexp (concat "^\\(" tramp-user-regexp "\\):")))
3951    
3952         (narrow-to-region (point) (tramp-point-at-eol))
3953         (when (re-search-forward regexp nil t)
3954           (setq result (list (match-string 1) "localhost")))
3955         (widen)
3956         (forward-line 1)
3957         result))
3958    
3959    (defun tramp-completion-handle-expand-file-name (name &optional dir)
3960      "Like `expand-file-name' for tramp files."
3961      (let ((fullname (concat (or dir default-directory) name)))
3962        (if (tramp-completion-mode fullname)
3963            (tramp-run-real-handler
3964             'expand-file-name (list name dir))
3965          (tramp-completion-run-real-handler
3966           'expand-file-name (list name dir)))))
3967    
3968  ;;; Internal Functions:  ;;; Internal Functions:
3969    
# Line 3551  file exists and nonzero exit status othe Line 4213  file exists and nonzero exit status othe
4213          (error "Couldn't find remote `%s' prompt." shell))          (error "Couldn't find remote `%s' prompt." shell))
4214        (tramp-message        (tramp-message
4215         9 "Setting remote shell prompt...")         9 "Setting remote shell prompt...")
4216          ;; Douglas Gray Stephens <DGrayStephens@slb.com> says that we
4217          ;; must use "\n" here, not tramp-rsh-end-of-line.  Kai left the
4218          ;; last tramp-rsh-end-of-line, Douglas wanted to replace that,
4219          ;; as well.
4220        (process-send-string nil (format "PS1='%s%s%s'; PS2=''; PS3=''%s"        (process-send-string nil (format "PS1='%s%s%s'; PS2=''; PS3=''%s"
4221                                         tramp-rsh-end-of-line                                         tramp-rsh-end-of-line
4222                                         tramp-end-of-output                                         tramp-end-of-output
4223                                         tramp-rsh-end-of-line                                         tramp-rsh-end-of-line
4224                                         tramp-rsh-end-of-line))                                         tramp-rsh-end-of-line))
4225        (tramp-wait-for-output)        (tramp-wait-for-output)
4226        (tramp-message        (tramp-message
4227         9 "Setting remote shell prompt...done")         9 "Setting remote shell prompt...done")
 ;;       (tramp-send-command multi-method method user host "echo hello")  
 ;;       (tramp-message 5 "Waiting for remote `%s' to start up..." shell)  
 ;;       (unless (tramp-wait-for-output 5)  
 ;;         (unless (tramp-wait-for-output 5)  
 ;;           (pop-to-buffer (buffer-name))  
 ;;           (error "Couldn't start remote `%s', see buffer `%s' for details"  
 ;;                  shell (buffer-name))))  
 ;;       (tramp-message 5 "Waiting for remote `%s' to start up...done" shell)  
4228        )        )
4229       (t (tramp-message 5 "Remote `%s' groks tilde expansion, good"       (t (tramp-message 5 "Remote `%s' groks tilde expansion, good"
4230                         (tramp-get-remote-sh multi-method method))))))                         (tramp-get-remote-sh multi-method method))))))
# Line 3634  Returns nil if none was found, else the Line 4292  Returns nil if none was found, else the
4292    
4293  (defun tramp-action-password (p multi-method method user host)  (defun tramp-action-password (p multi-method method user host)
4294    "Query the user for a password."    "Query the user for a password."
4295    (when (tramp-method-out-of-band-p multi-method method)    (when (tramp-method-out-of-band-p multi-method method user host)
4296      (kill-process (get-buffer-process (current-buffer)))      (kill-process (get-buffer-process (current-buffer)))
4297      (error (concat "Out of band method `%s' not applicable "      (error (concat "Out of band method `%s' not applicable "
4298                     "for remote shell asking for a password")                     "for remote shell asking for a password")
4299             method))             method))
4300      (tramp-message 9 "Sending password")
4301    (tramp-enter-password p (match-string 0)))    (tramp-enter-password p (match-string 0)))
4302    
4303  (defun tramp-action-succeed (p multi-method method user host)  (defun tramp-action-succeed (p multi-method method user host)
# Line 3689  See also `tramp-action-yesno'." Line 4348  See also `tramp-action-yesno'."
4348    
4349  (defun tramp-multi-action-password (p method user host)  (defun tramp-multi-action-password (p method user host)
4350    "Query the user for a password."    "Query the user for a password."
4351      (tramp-message 9 "Sending password")
4352    (tramp-enter-password p (match-string 0)))    (tramp-enter-password p (match-string 0)))
4353    
4354  (defun tramp-multi-action-succeed (p method user host)  (defun tramp-multi-action-succeed (p method user host)
# Line 3799  Maybe the different regular expressions Line 4459  Maybe the different regular expressions
4459  * Actually, the telnet program as well as the args to be used can be  * Actually, the telnet program as well as the args to be used can be
4460    specified in the method parameters, see the variable `tramp-methods'."    specified in the method parameters, see the variable `tramp-methods'."
4461    (save-match-data    (save-match-data
4462      (when (tramp-method-out-of-band-p multi-method method)      (when (tramp-method-out-of-band-p multi-method method user host)
4463        (error "Cannot use out-of-band method `%s' with telnet connection method"        (error "Cannot use out-of-band method `%s' with telnet connection method"
4464               method))               method))
4465      (when multi-method      (when multi-method
# Line 3810  Maybe the different regular expressions Line 4470  Maybe the different regular expressions
4470      (let ((process-environment (copy-sequence process-environment)))      (let ((process-environment (copy-sequence process-environment)))
4471        (setenv "TERM" tramp-terminal-type)        (setenv "TERM" tramp-terminal-type)
4472        (let* ((default-directory (tramp-temporary-file-directory))        (let* ((default-directory (tramp-temporary-file-directory))
4473                 ;; If we omit the conditional here, then we would use
4474                 ;; `undecided-dos' in some cases.  With the conditional,
4475                 ;; we use nil in these cases.  Which one is right?
4476               (coding-system-for-read (unless (and (not (featurep 'xemacs))               (coding-system-for-read (unless (and (not (featurep 'xemacs))
4477                                                    (> emacs-major-version 20))                                                    (> emacs-major-version 20))
4478                                         tramp-dos-coding-system))                                         tramp-dos-coding-system))
4479               (p (apply 'start-process               (p (apply 'start-process
4480                         (tramp-buffer-name multi-method method user host)                         (tramp-buffer-name multi-method method user host)
4481                         (tramp-get-buffer multi-method method user host)                         (tramp-get-buffer multi-method method user host)
4482                         (tramp-get-telnet-program multi-method method)                         (tramp-get-telnet-program
4483                            multi-method
4484                            (tramp-find-method multi-method method user host))
4485                         host                         host
4486                         (tramp-get-telnet-args multi-method method)))                         (tramp-get-telnet-args
4487                            multi-method
4488                            (tramp-find-method multi-method method user host))))
4489               (found nil)               (found nil)
4490               (pw nil))               (pw nil))
4491          (process-kill-without-query p)          (process-kill-without-query p)
# Line 3860  arguments, and xx will be used as the ho Line 4527  arguments, and xx will be used as the ho
4527      (when multi-method      (when multi-method
4528        (error "Cannot multi-connect using rsh connection method"))        (error "Cannot multi-connect using rsh connection method"))
4529      (tramp-pre-connection multi-method method user host)      (tramp-pre-connection multi-method method user host)
4530      (if user      (if (and user (not (string= user "")))
4531          (tramp-message 7 "Opening connection for %s@%s using %s..."          (tramp-message 7 "Opening connection for %s@%s using %s..."
4532                         user host method)                         user host method)
4533        (tramp-message 7 "Opening connection at %s using %s..." host method))        (tramp-message 7 "Opening connection at %s using %s..." host method))
4534      (let ((process-environment (copy-sequence process-environment))      (let ((process-environment (copy-sequence process-environment))
4535            (bufnam (tramp-buffer-name multi-method method user host))            (bufnam (tramp-buffer-name multi-method method user host))
4536            (buf (tramp-get-buffer multi-method method user host))            (buf (tramp-get-buffer multi-method method user host))
4537            (rsh-program (tramp-get-rsh-program multi-method method))            (rsh-program (tramp-get-rsh-program
4538            (rsh-args (tramp-get-rsh-args multi-method method)))                          multi-method
4539                            (tramp-find-method multi-method method user host)))
4540              (rsh-args (tramp-get-rsh-args
4541                         multi-method
4542                         (tramp-find-method multi-method method user host))))
4543        ;; The following should be changed.  We need a more general        ;; The following should be changed.  We need a more general
4544        ;; mechanism to parse extra host args.        ;; mechanism to parse extra host args.
4545        (when (string-match "\\([^#]*\\)#\\(.*\\)" host)        (when (string-match "\\([^#]*\\)#\\(.*\\)" host)
# Line 3876  arguments, and xx will be used as the ho Line 4547  arguments, and xx will be used as the ho
4547          (setq host (match-string 1 host)))          (setq host (match-string 1 host)))
4548        (setenv "TERM" tramp-terminal-type)        (setenv "TERM" tramp-terminal-type)
4549        (let* ((default-directory (tramp-temporary-file-directory))        (let* ((default-directory (tramp-temporary-file-directory))
4550                 ;; If we omit the conditional, we would use
4551                 ;; `undecided-dos' in some cases.  With the conditional,
4552                 ;; we use nil in these cases.  Which one is right?
4553               (coding-system-for-read (unless (and (not (featurep 'xemacs))               (coding-system-for-read (unless (and (not (featurep 'xemacs))
4554                                                    (> emacs-major-version 20))                                                    (> emacs-major-version 20))
4555                                         tramp-dos-coding-system))                                         tramp-dos-coding-system))
4556               (p (if user               (p (if (and user (not (string= user "")))
4557                      (apply #'start-process bufnam buf rsh-program                        (apply #'start-process bufnam buf rsh-program  
4558                             host "-l" user rsh-args)                             host "-l" user rsh-args)
4559                    (apply #'start-process bufnam buf rsh-program                    (apply #'start-process bufnam buf rsh-program
# Line 3908  set up correctly.  Note that the other u Line 4582  set up correctly.  Note that the other u
4582  prompt than you do, so it is not at all unlikely that the variable  prompt than you do, so it is not at all unlikely that the variable
4583  `shell-prompt-pattern' is set up wrongly!"  `shell-prompt-pattern' is set up wrongly!"
4584    (save-match-data    (save-match-data
4585      (when (tramp-method-out-of-band-p multi-method method)      (when (tramp-method-out-of-band-p multi-method method user host)
4586        (error "Cannot use out-of-band method `%s' with `su' connection method"        (error "Cannot use out-of-band method `%s' with `su' connection method"
4587               method))               method))
4588      (unless (or (string-match (concat "^" (regexp-quote host))      (unless (or (string-match (concat "^" (regexp-quote host))
4589                                (system-name))                                (system-name))
4590                  (string= "localhost" host))                  (string= "localhost" host)
4591                    (string= "" host))
4592        (error        (error
4593         "Cannot connect to different host `%s' with `su' connection method"         "Cannot connect to different host `%s' with `su' connection method"
4594         host))         host))
     (when (not user)  
       (setq user "root"))  
4595      (tramp-pre-connection multi-method method user host)      (tramp-pre-connection multi-method method user host)
4596      (tramp-message 7 "Opening connection for `%s' using `%s'..." user method)      (tramp-message 7 "Opening connection for `%s' using `%s'..."
4597                       (or user "<root>") method)
4598      (let ((process-environment (copy-sequence process-environment)))      (let ((process-environment (copy-sequence process-environment)))
4599        (setenv "TERM" tramp-terminal-type)        (setenv "TERM" tramp-terminal-type)
4600        (let* ((default-directory (tramp-temporary-file-directory))        (let* ((default-directory (tramp-temporary-file-directory))
4601                 ;; If we omit the conditional, we use `undecided-dos' in
4602                 ;; some cases.  With the conditional, we use nil in these
4603                 ;; cases.  What's the difference?  Which one is right?
4604               (coding-system-for-read (unless (and (not (featurep 'xemacs))               (coding-system-for-read (unless (and (not (featurep 'xemacs))
4605                                                    (> emacs-major-version 20))                                                    (> emacs-major-version 20))
4606                                         tramp-dos-coding-system))                                         tramp-dos-coding-system))
4607               (p (apply 'start-process               (p (apply 'start-process
4608                         (tramp-buffer-name multi-method method user host)                         (tramp-buffer-name multi-method method user host)
4609                         (tramp-get-buffer multi-method method user host)                         (tramp-get-buffer multi-method method user host)
4610                         (tramp-get-su-program multi-method method)                         (tramp-get-su-program
4611                            multi-method
4612                            (tramp-find-method multi-method method user host))
4613                         (mapcar                         (mapcar
4614                          '(lambda (x)                          '(lambda (x)
4615                             (format-spec x `((?u . ,user))))                             (format-spec x `((?u . ,(or user "root")))))
4616                          (tramp-get-su-args multi-method method))))                          (tramp-get-su-args
4617                             multi-method
4618                             (tramp-find-method multi-method method user host)))))
4619               (found nil)               (found nil)
4620               (pw nil))               (pw nil))
4621          (process-kill-without-query p)          (process-kill-without-query p)
# Line 3963  log in as u2 to h2." Line 4644  log in as u2 to h2."
4644    (save-match-data    (save-match-data
4645      (unless multi-method      (unless multi-method
4646        (error "Multi-hop open connection function called on non-multi method"))        (error "Multi-hop open connection function called on non-multi method"))
4647      (when (tramp-method-out-of-band-p multi-method method)      (when (tramp-method-out-of-band-p multi-method method user host)
4648        (error "No out of band multi-hop connections"))        (error "No out of band multi-hop connections"))
4649      (unless (and (arrayp method) (not (stringp method)))      (unless (and (arrayp method) (not (stringp method)))
4650        (error "METHOD must be an array of strings for multi methods"))        (error "METHOD must be an array of strings for multi methods"))
# Line 3979  log in as u2 to h2." Line 4660  log in as u2 to h2."
4660      (let ((process-environment (copy-sequence process-environment)))      (let ((process-environment (copy-sequence process-environment)))
4661        (setenv "TERM" tramp-terminal-type)        (setenv "TERM" tramp-terminal-type)
4662        (let* ((default-directory (tramp-temporary-file-directory))        (let* ((default-directory (tramp-temporary-file-directory))
4663                 ;; If we omit the conditional, we use `undecided-dos' in
4664                 ;; some cases.  With the conditional, we use nil in these
4665                 ;; cases.  What's the difference?  Which one is right?
4666               (coding-system-for-read (unless (and (not (featurep 'xemacs))               (coding-system-for-read (unless (and (not (featurep 'xemacs))
4667                                                    (> emacs-major-version 20))                                                    (> emacs-major-version 20))
4668                                         tramp-dos-coding-system))                                         tramp-dos-coding-system))
# Line 4137  nil." Line 4821  nil."
4821  Uses PROMPT as a prompt and sends the password to process P."  Uses PROMPT as a prompt and sends the password to process P."
4822    (let ((pw (tramp-read-passwd prompt)))    (let ((pw (tramp-read-passwd prompt)))
4823      (erase-buffer)      (erase-buffer)
4824      (process-send-string p (concat pw tramp-rsh-end-of-line))))      (process-send-string p (concat pw tramp-password-end-of-line))))
4825    
4826  ;; HHH: Not Changed.  This might handle the case where USER is not  ;; HHH: Not Changed.  This might handle the case where USER is not
4827  ;;      given in the "File name" very poorly.  Then, the local  ;;      given in the "File name" very poorly.  Then, the local
# Line 4163  to set up.  METHOD, USER and HOST specif Line 4847  to set up.  METHOD, USER and HOST specif
4847    ;; a Kerberos login.    ;; a Kerberos login.
4848    (sit-for 1)    (sit-for 1)
4849    (tramp-discard-garbage-erase-buffer p multi-method method user host)    (tramp-discard-garbage-erase-buffer p multi-method method user host)
4850    (process-send-string nil (format "exec %s%s"    ;; It is useful to set the prompt in the following command because
4851      ;; some people have a setting for $PS1 which /bin/sh doesn't know
4852      ;; about and thus /bin/sh will display a strange prompt.  For
4853      ;; example, if $PS1 has "${CWD}" in the value, then ksh will display
4854      ;; the current working directory but /bin/sh will display a dollar
4855      ;; sign.  The following command line sets $PS1 to a sane value, and
4856      ;; works under Bourne-ish shells as well as csh-like shells.  Daniel
4857      ;; Pittman reports that the unusual positioning of the single quotes
4858      ;; makes it work under `rc', too.
4859      (process-send-string nil (format "exec env 'PS1=$ ' %s%s"
4860                                     (tramp-get-remote-sh multi-method method)                                     (tramp-get-remote-sh multi-method method)
4861                                     tramp-rsh-end-of-line))                                     tramp-rsh-end-of-line))
4862    (when tramp-debug-buffer    (when tramp-debug-buffer
# Line 4171  to set up.  METHOD, USER and HOST specif Line 4864  to set up.  METHOD, USER and HOST specif
4864        (set-buffer (tramp-get-debug-buffer multi-method method user host))        (set-buffer (tramp-get-debug-buffer multi-method method user host))
4865        (goto-char (point-max))        (goto-char (point-max))
4866        (tramp-insert-with-face        (tramp-insert-with-face
4867         'bold (format "$ exec %s\n" (tramp-get-remote-sh multi-method method)))))         'bold (format "$ exec env PS1='$ ' %s\n"
4868                         (tramp-get-remote-sh multi-method method)))))
4869    (tramp-message 9 "Waiting 30s for remote `%s' to come up..."    (tramp-message 9 "Waiting 30s for remote `%s' to come up..."
4870                 (tramp-get-remote-sh multi-method method))                 (tramp-get-remote-sh multi-method method))
4871    (unless (tramp-wait-for-regexp    (unless (tramp-wait-for-regexp
# Line 4285  to set up.  METHOD, USER and HOST specif Line 4979  to set up.  METHOD, USER and HOST specif
4979             (buffer-name)))             (buffer-name)))
4980    (erase-buffer)    (erase-buffer)
4981    (tramp-message 9 "Setting shell prompt")    (tramp-message 9 "Setting shell prompt")
4982      ;; Douglas Gray Stephens <DGrayStephens@slb.com> says that we must
4983      ;; use "\n" here, not tramp-rsh-end-of-line.
4984    (tramp-send-command    (tramp-send-command
4985     multi-method method user host     multi-method method user host
4986     (format "PS1='%s%s%s'; PS2=''; PS3=''"     (format "PS1='%s%s%s'; PS2=''; PS3=''"
4987             tramp-rsh-end-of-line             tramp-rsh-end-of-line
4988             tramp-end-of-output             tramp-end-of-output
4989             tramp-rsh-end-of-line))             tramp-rsh-end-of-line))
4990    (tramp-wait-for-output)    (tramp-wait-for-output))
 ;;   (tramp-send-command multi-method method user host "echo hello")  
 ;;   (tramp-message 9 "Waiting for remote `%s' to come up..."  
 ;;                (tramp-get-remote-sh multi-method method))  
 ;;   (unless (tramp-wait-for-output 5)  
 ;;     (unless (tramp-wait-for-output 5)  
 ;;       (pop-to-buffer (buffer-name))  
 ;;       (error "Couldn't set remote shell prompt.  See buffer `%s' for details"  
 ;;              (buffer-name))))  
 ;;   (tramp-message 7 "Waiting for remote `%s' to come up...done"  
 ;;                (tramp-get-remote-sh multi-method method))  
   )  
4991    
4992  (defun tramp-post-connection (multi-method method user host)  (defun tramp-post-connection (multi-method method user host)
4993    "Prepare a remote shell before being able to work on it.    "Prepare a remote shell before being able to work on it.
# Line 4380  locale to C and sets up the remote shell Line 5065  locale to C and sets up the remote shell
5065    (tramp-wait-for-output)    (tramp-wait-for-output)
5066    (goto-char (point-min))    (goto-char (point-min))
5067    (setq tramp-test-groks-nt    (setq tramp-test-groks-nt
5068          (looking-at (format "\n%s\n" (regexp-quote tramp-end-of-output))))          (looking-at (format "\n%s\r?\n" (regexp-quote tramp-end-of-output))))
5069    (unless tramp-test-groks-nt    (unless tramp-test-groks-nt
5070      (tramp-send-command      (tramp-send-command
5071       multi-method method user host       multi-method method user host
# Line 4412  locale to C and sets up the remote shell Line 5097  locale to C and sets up the remote shell
5097                   " -e '" tramp-perl-file-attributes "' $1 2>/dev/null\n"                   " -e '" tramp-perl-file-attributes "' $1 2>/dev/null\n"
5098                   "}"))                   "}"))
5099          (tramp-wait-for-output)          (tramp-wait-for-output)
5100          (tramp-message 5 "Sending the Perl `mime-encode' implementations.")          (unless (tramp-get-rcp-program
5101          (tramp-send-linewise                   multi-method
5102           multi-method method user host                   (tramp-find-method multi-method method user host))
5103           (concat "tramp_encode () {\n"            (tramp-message 5 "Sending the Perl `mime-encode' implementations.")
5104                   (format tramp-perl-encode tramp-remote-perl)            (tramp-send-linewise
5105                   " 2>/dev/null"             multi-method method user host
5106                   "\n}"))             (concat "tramp_encode () {\n"
5107          (tramp-wait-for-output)                     (format tramp-perl-encode tramp-remote-perl)
5108          (tramp-send-linewise                     " 2>/dev/null"
5109           multi-method method user host                     "\n}"))
5110           (concat "tramp_encode_with_module () {\n"            (tramp-wait-for-output)
5111                   (format tramp-perl-encode-with-module tramp-remote-perl)            (tramp-send-linewise
5112                   " 2>/dev/null"             multi-method method user host
5113                   "\n}"))             (concat "tramp_encode_with_module () {\n"
5114          (tramp-wait-for-output)                     (format tramp-perl-encode-with-module tramp-remote-perl)
5115          (tramp-message 5 "Sending the Perl `mime-decode' implementations.")                     " 2>/dev/null"
5116          (tramp-send-linewise                     "\n}"))
5117           multi-method method user host            (tramp-wait-for-output)
5118           (concat "tramp_decode () {\n"            (tramp-message 5 "Sending the Perl `mime-decode' implementations.")
5119                   (format tramp-perl-decode tramp-remote-perl)            (tramp-send-linewise
5120                   " 2>/dev/null"             multi-method method user host
5121                   "\n}"))             (concat "tramp_decode () {\n"
5122          (tramp-wait-for-output)                     (format tramp-perl-decode tramp-remote-perl)
5123          (tramp-send-linewise                     " 2>/dev/null"
5124           multi-method method user host                     "\n}"))
5125           (concat "tramp_decode_with_module () {\n"            (tramp-wait-for-output)
5126                   (format tramp-perl-decode-with-module tramp-remote-perl)            (tramp-send-linewise
5127                   " 2>/dev/null"             multi-method method user host
5128                   "\n}"))             (concat "tramp_decode_with_module () {\n"
5129          (tramp-wait-for-output))))                     (format tramp-perl-decode-with-module tramp-remote-perl)
5130                       " 2>/dev/null"
5131                       "\n}"))
5132              (tramp-wait-for-output)))))
5133    ;; Find ln(1)    ;; Find ln(1)
5134    (erase-buffer)    (erase-buffer)
5135    (let ((ln (tramp-find-executable multi-method method user host    (let ((ln (tramp-find-executable multi-method method user host
# Line 4450  locale to C and sets up the remote shell Line 5138  locale to C and sets up the remote shell
5138        (tramp-set-connection-property "ln" ln multi-method method user host)))        (tramp-set-connection-property "ln" ln multi-method method user host)))
5139    (erase-buffer)    (erase-buffer)
5140    ;; Find the right encoding/decoding commands to use.    ;; Find the right encoding/decoding commands to use.
5141    (unless (tramp-get-rcp-program multi-method method)    (unless (tramp-get-rcp-program
5142               multi-method
5143               (tramp-find-method multi-method method user host))
5144      (tramp-find-inline-encoding multi-method method user host))      (tramp-find-inline-encoding multi-method method user host))
5145    ;; If encoding/decoding command are given, test to see if they work.    ;; If encoding/decoding command are given, test to see if they work.
5146    ;; CCC: Maybe it would be useful to run the encoder both locally and    ;; CCC: Maybe it would be useful to run the encoder both locally and
5147    ;; remotely to see if they produce the same result.    ;; remotely to see if they produce the same result.
5148    (let ((decoding (tramp-get-decoding-command multi-method method user host))    (let ((rem-enc (tramp-get-remote-encoding multi-method method user host))
5149          (encoding (tramp-get-encoding-command multi-method method user host))          (rem-dec (tramp-get-remote-decoding multi-method method user host))
5150          (magic-string "xyzzy"))          (magic-string "xyzzy"))
5151      (when (and (or decoding encoding) (not (and decoding encoding)))      (when (and (or rem-dec rem-enc) (not (and rem-dec rem-enc)))
5152        (tramp-kill-process multi-method method user host)        (tramp-kill-process multi-method method user host)
5153          ;; Improve error message and/or error check.
5154        (error        (error
5155         "Must give both decoding and encoding command in method definition"))         "Must give both decoding and encoding command in method definition"))
5156      (when (and decoding encoding)      (when (and rem-enc rem-dec)
5157        (tramp-message        (tramp-message
5158         5         5
5159         "Checking to see if encoding/decoding commands work on remote host...")         "Checking to see if encoding/decoding commands work on remote host...")
5160        (tramp-send-command        (tramp-send-command
5161         multi-method method user host         multi-method method user host
5162         (format "echo %s | %s | %s"         (format "echo %s | %s | %s"
5163                 (tramp-shell-quote-argument magic-string) encoding decoding))                 (tramp-shell-quote-argument magic-string) rem-enc rem-dec))
5164        (tramp-wait-for-output)        (tramp-wait-for-output)
5165        (unless (looking-at (regexp-quote magic-string))        (unless (looking-at (regexp-quote magic-string))
5166          (tramp-kill-process multi-method method user host)          (tramp-kill-process multi-method method user host)
# Line 4483  locale to C and sets up the remote shell Line 5174  locale to C and sets up the remote shell
5174  ;; and decoding.  Then we just use that in the last item.  The other  ;; and decoding.  Then we just use that in the last item.  The other
5175  ;; alternative is to use the Perl version of UU encoding.  But then  ;; alternative is to use the Perl version of UU encoding.  But then
5176  ;; we need a Lisp version of uuencode.  ;; we need a Lisp version of uuencode.
5177    ;;
5178    ;; Old text from documentation of tramp-methods:
5179    ;; Using a uuencode/uudecode inline method is discouraged, please use one
5180    ;; of the base64 methods instead since base64 encoding is much more
5181    ;; reliable and the commands are more standardized between the different
5182    ;; Unix versions.  But if you can't use base64 for some reason, please
5183    ;; note that the default uudecode command does not work well for some
5184    ;; Unices, in particular AIX and Irix.  For AIX, you might want to use
5185    ;; the following command for uudecode:
5186    ;;
5187    ;;     sed '/^begin/d;/^[` ]$/d;/^end/d' | iconv -f uucode -t ISO8859-1
5188    ;;
5189    ;; For Irix, no solution is known yet.
5190    
5191  (defvar tramp-coding-commands  (defvar tramp-coding-commands
5192    '(("mimencode -b" "mimencode -u -b"    '(("mimencode -b" "mimencode -u -b"
5193       base64-encode-region base64-decode-region)       base64-encode-region base64-decode-region)
# Line 4491  locale to C and sets up the remote shell Line 5196  locale to C and sets up the remote shell
5196      ("recode data..base64" "recode base64..data"      ("recode data..base64" "recode base64..data"
5197       base64-encode-region base64-decode-region)       base64-encode-region base64-decode-region)
5198      ("uuencode xxx" "uudecode -o -"      ("uuencode xxx" "uudecode -o -"
5199       nil uudecode-decode-region)       tramp-uuencode-region uudecode-decode-region)
5200      ("uuencode xxx" "uudecode -p"      ("uuencode xxx" "uudecode -p"
5201       nil uudecode-decode-region)       tramp-uuencode-region uudecode-decode-region)
5202      ("uuencode xxx" "tramp_uudecode"      ("uuencode xxx" "tramp_uudecode"
5203       nil uudecode-decode-region)       tramp-uuencode-region uudecode-decode-region)
5204      ("tramp_encode_with_module" "tramp_decode_with_module"      ("tramp_encode_with_module" "tramp_decode_with_module"
5205       base64-encode-region base64-decode-region)       base64-encode-region base64-decode-region)
5206      ("tramp_encode" "tramp_decode"      ("tramp_encode" "tramp_decode"
5207       base64-encode-region base64-decode-region))       base64-encode-region base64-decode-region))
5208    "List of coding commands for inline transfer.    "List of coding commands for inline transfer.
5209  Each item is a list (ENCODING-COMMAND DECODING-COMMAND  Each item is a list that looks like this:
 ENCODING-FUNCTION DECODING-FUNCTION).  
5210    
5211  Each item can be a string, giving a command, or a symbol, giving  \(REMOTE-ENCODING REMOTE-DECODING LOCAL-ENCODING LOCAL-DECODING)
 a function.  
5212    
5213  The ENCODING-COMMAND should be a command accepting a plain file on  The REMOTE-ENCODING should be a string, giving a command accepting a
5214  standard input and writing the encoded file to standard output.  The  plain file on standard input and writing the encoded file to standard
5215  DECODING-COMMAND should be a command accepting an encoded file on  output.  The REMOTE-DECODING should also be a string, giving a command
5216  standard input and writing the decoded file to standard output.  accepting an encoded file on standard input and writing the decoded
5217    file to standard output.
5218  The ENCODING-FUNCTION and DECODING-FUNCTION functions will be called  
5219  with two arguments, start and end of region, and are expected to  LOCAL-ENCODING and LOCAL-DECODING can be strings, giving commands, or
5220  replace the region contents with the encoded or decoded results,  symbols, giving functions.  If they are strings, then they can contain
5221  respectively.")  the \"%s\" format specifier.  If that specifier is present, the input
5222    filename will be put into the command line at that spot.  If the
5223    specifier is not present, the input should be read from standard
5224    input.
5225    
5226    If they are functions, they will be called with two arguments, start
5227    and end of region, and are expected to replace the region contents
5228    with the encoded or decoded results, respectively.")
5229    
5230  (defun tramp-find-inline-encoding (multi-method method user host)  (defun tramp-find-inline-encoding (multi-method method user host)
5231    "Find an inline transfer encoding that works.    "Find an inline transfer encoding that works.
# Line 4525  Goes through the list `tramp-coding-comm Line 5235  Goes through the list `tramp-coding-comm
5235      (while (and commands (null found))      (while (and commands (null found))
5236        (setq item (pop commands))        (setq item (pop commands))
5237        (catch 'wont-work        (catch 'wont-work
5238          (let ((ec (nth 0 item))          (let ((rem-enc (nth 0 item))
5239                (dc (nth 1 item))                (rem-dec (nth 1 item))
5240                (ef (nth 2 item))                (loc-enc (nth 2 item))
5241                (df (nth 3 item)))                (loc-dec (nth 3 item)))
5242            ;; Check if encoding and decoding commands can be called            ;; Check if remote encoding and decoding commands can be
5243            ;; remotely with null input and output.  This makes sure there            ;; called remotely with null input and output.  This makes
5244            ;; are no syntax errors and the command is really found.            ;; sure there are no syntax errors and the command is really
5245              ;; found.
5246            (tramp-message-for-buffer            (tramp-message-for-buffer
5247             multi-method method user host 9             multi-method method user host 9
5248             "Checking remote encoding command `%s' for sanity" ec)             "Checking remote encoding command `%s' for sanity" rem-enc)
5249            (unless (zerop (tramp-send-command-and-check            (unless (zerop (tramp-send-command-and-check
5250                            multi-method method user host                            multi-method method user host
5251                            (format "%s </dev/null >/dev/null" ec) t))                            (format "%s </dev/null >/dev/null" rem-enc) t))
5252              (throw 'wont-work nil))              (throw 'wont-work nil))
5253            (tramp-message-for-buffer            (tramp-message-for-buffer
5254             multi-method method user host 9             multi-method method user host 9
5255             "Checking remote decoding command `%s' for sanity" dc)             "Checking remote decoding command `%s' for sanity" rem-dec)
5256            (unless (zerop (tramp-send-command-and-check            (unless (zerop (tramp-send-command-and-check
5257                            multi-method method user host                            multi-method method user host
5258                            (format "echo xyzzy | %s | %s >/dev/null" ec dc) t))                            (format "echo xyzzy | %s | %s >/dev/null"
5259                                      rem-enc rem-dec) t))
5260              (throw 'wont-work nil))              (throw 'wont-work nil))
5261            ;; If no encoding/decoding function is given, the            ;; If the local encoder or decoder is a string, the
5262            ;; corresponding encoding/decoding command also has to work            ;; corresponding command has to work locally.
5263            ;; locally.            (when (stringp loc-enc)
           (when (not (fboundp ef))  
5264              (tramp-message-for-buffer              (tramp-message-for-buffer
5265               multi-method method user host 9               multi-method method user host 9
5266               "Checking local encoding command `%s' for sanity" ec)               "Checking local encoding command `%s' for sanity" loc-enc)
5267              (unless (zerop (call-process              (unless (zerop (tramp-call-local-coding-command
5268                              tramp-sh-program ;program                              loc-enc nil nil))
                             nil         ;input  
                             nil         ;output buffer  
                             nil         ;redisplay  
                             "-c"  
                             (format "%s </dev/null >/dev/null" ec)))  
5269                (throw 'wont-work nil)))                (throw 'wont-work nil)))
5270            (when (not (fboundp df))            (when (stringp loc-dec)
5271              (tramp-message-for-buffer              (tramp-message-for-buffer
5272               multi-method method user host 9               multi-method method user host 9
5273               "Checking local decoding command `%s' for sanity" dc)               "Checking local decoding command `%s' for sanity" loc-dec)
5274              (unless (zerop (call-process              (unless (zerop (tramp-call-local-coding-command
5275                              tramp-sh-program ;program                              loc-dec nil nil))
                             nil         ;input file  
                             nil         ;output buffer  
                             nil         ;redisplay  
                             "-c"  
                             (format "%s </dev/null >/dev/null" dc)))  
5276                (throw 'wont-work nil)))                (throw 'wont-work nil)))
5277            ;; CCC: At this point, maybe we should check that the output            ;; CCC: At this point, maybe we should check that the output
5278            ;; of the commands is correct.  But for the moment we will            ;; of the commands is correct.  But for the moment we will
# Line 4582  Goes through the list `tramp-coding-comm Line 5283  Goes through the list `tramp-coding-comm
5283      ;; set connection properties.      ;; set connection properties.
5284      (unless found      (unless found
5285        (error "Couldn't find an inline transfer encoding"))        (error "Couldn't find an inline transfer encoding"))
5286      (let ((ec (nth 0 found))      (let ((rem-enc (nth 0 found))
5287            (dc (nth 1 found))            (rem-dec (nth 1 found))
5288            (ef (nth 2 found))            (loc-enc (nth 2 found))
5289            (df (nth 3 found)))            (loc-dec (nth 3 found)))
5290        (tramp-set-encoding-command multi-method method user host ec)        (tramp-message 10 "Using remote encoding %s" rem-enc)
5291        (tramp-set-decoding-command multi-method method user host dc)        (tramp-set-remote-encoding multi-method method user host rem-enc)
5292        (tramp-set-encoding-function multi-method method user host ef)        (tramp-message 10 "Using remote decoding %s" rem-dec)
5293        (tramp-set-decoding-function multi-method method user host df))))        (tramp-set-remote-decoding multi-method method user host rem-dec)
5294                    (tramp-message 10 "Using local encoding %s" loc-enc)
5295          (tramp-set-local-encoding multi-method method user host loc-enc)
5296          (tramp-message 10 "Using local decoding %s" loc-dec)
5297          (tramp-set-local-decoding multi-method method user host loc-dec))))
5298    
5299    (defun tramp-call-local-coding-command (cmd input output)
5300      "Call the local encoding or decoding command.
5301    If CMD contains \"%s\", provide input file INPUT there in command.
5302    Otherwise, INPUT is passed via standard input.
5303    INPUT can also be nil which means `/dev/null'.
5304    OUTPUT can be a string (which specifies a filename), or t (which
5305    means standard output and thus the current buffer), or nil (which
5306    means discard it)."
5307      (call-process
5308       tramp-encoding-shell                 ;program
5309       (when (and input (not (string-match "%s" cmd)))
5310         input)                             ;input
5311       (if (eq output t) t nil)             ;output
5312       nil                                  ;redisplay
5313       tramp-encoding-command-switch
5314       ;; actual shell command
5315       (concat
5316        (if (string-match "%s" cmd) (format cmd input) cmd)
5317        (if (stringp output) (concat "> " output) ""))))
5318    
5319  (defun tramp-maybe-open-connection (multi-method method user host)  (defun tramp-maybe-open-connection (multi-method method user host)
5320    "Maybe open a connection to HOST, logging in as USER, using METHOD.    "Maybe open a connection to HOST, logging in as USER, using METHOD.
5321  Does not do anything if a connection is already open, but re-opens the  Does not do anything if a connection is already open, but re-opens the
5322  connection if a previous connection has died for some reason."  connection if a previous connection has died for some reason."
5323    (let ((p (get-buffer-process (tramp-get-buffer multi-method method user host)))    (let ((p (get-buffer-process
5324                (tramp-get-buffer multi-method method user host)))
5325          last-cmd-time)          last-cmd-time)
5326      ;; If too much time has passed since last command was sent, look      ;; If too much time has passed since last command was sent, look
5327      ;; whether process is still alive.  If it isn't, kill it.  When      ;; whether process is still alive.  If it isn't, kill it.  When
# Line 4618  connection if a previous connection has Line 5343  connection if a previous connection has
5343      (unless (and p (processp p) (memq (process-status p) '(run open)))      (unless (and p (processp p) (memq (process-status p) '(run open)))
5344        (when (and p (processp p))        (when (and p (processp p))
5345          (delete-process p))          (delete-process p))
5346        (funcall (tramp-get-connection-function multi-method method)        (funcall (tramp-get-connection-function
5347                    multi-method
5348                    (tramp-find-method multi-method method user host))
5349                 multi-method method user host))))                 multi-method method user host))))
5350    
5351  (defun tramp-send-command  (defun tramp-send-command
# Line 4681  the remote host use line-endings as defi Line 5408  the remote host use line-endings as defi
5408          (start-time (current-time))          (start-time (current-time))
5409          (end-of-output (concat "^"          (end-of-output (concat "^"
5410                                 (regexp-quote tramp-end-of-output)                                 (regexp-quote tramp-end-of-output)
5411                                 "$")))                                 "\r?$")))
5412      ;; Algorithm: get waiting output.  See if last line contains      ;; Algorithm: get waiting output.  See if last line contains
5413      ;; end-of-output sentinel.  If not, wait a bit and again get      ;; end-of-output sentinel.  If not, wait a bit and again get
5414      ;; waiting output.  Repeat until timeout expires or end-of-output      ;; waiting output.  Repeat until timeout expires or end-of-output
# Line 4778  FMT and ARGS which are passed to `error' Line 5505  FMT and ARGS which are passed to `error'
5505      (pop-to-buffer (current-buffer))      (pop-to-buffer (current-buffer))
5506      (funcall 'signal signal (apply 'format fmt args))))      (funcall 'signal signal (apply 'format fmt args))))
5507    
5508    ;; Chunked sending kluge.
5509    (defvar tramp-chunksize nil
5510      "If non-nil, chunksize for sending things to remote host.")
5511    
5512  (defun tramp-send-region (multi-method method user host start end)  (defun tramp-send-region (multi-method method user host start end)
5513    "Send the region from START to END to remote command    "Send the region from START to END to remote command
5514  running as USER on HOST using METHOD."  running as USER on HOST using METHOD."
# Line 4785  running as USER on HOST using METHOD." Line 5516  running as USER on HOST using METHOD."
5516                 (tramp-get-buffer multi-method method user host))))                 (tramp-get-buffer multi-method method user host))))
5517      (unless proc      (unless proc
5518        (error "Can't send region to remote host -- not logged in"))        (error "Can't send region to remote host -- not logged in"))
5519      (process-send-region proc start end)      (if tramp-chunksize
5520            (let ((pos start))
5521              (while (< pos end)
5522                (tramp-message-for-buffer
5523                 multi-method method user host 10
5524                 "Sending chunk from %s to %s" pos end)
5525                (process-send-region proc
5526                                     pos
5527                                     (min (+ pos tramp-chunksize)
5528                                          end))
5529                (setq pos (+ pos tramp-chunksize))
5530                (sleep-for 0.1)))
5531          (process-send-region proc start end))
5532      (when tramp-debug-buffer      (when tramp-debug-buffer
5533        (append-to-buffer        (append-to-buffer
5534         (tramp-get-debug-buffer multi-method method user host)         (tramp-get-debug-buffer multi-method method user host)
# Line 4978  remote path name." Line 5721  remote path name."
5721          (let ((user (match-string (nth 2 tramp-file-name-structure) name))          (let ((user (match-string (nth 2 tramp-file-name-structure) name))
5722                (host (match-string (nth 3 tramp-file-name-structure) name))                (host (match-string (nth 3 tramp-file-name-structure) name))
5723                (path (match-string (nth 4 tramp-file-name-structure) name)))                (path (match-string (nth 4 tramp-file-name-structure) name)))
           (when (not method)  
             (setq method (tramp-find-default-method user host)))  
5724            (make-tramp-file-name            (make-tramp-file-name
5725             :multi-method nil             :multi-method nil
5726             :method method             :method method
# Line 4994  remote path name." Line 5735  remote path name."
5735          item)          item)
5736      (while choices      (while choices
5737        (setq item (pop choices))        (setq item (pop choices))
5738        (when (and (string-match (nth 0 item) host)        (when (and (string-match (nth 0 item) (or host ""))
5739                   (string-match (nth 1 item) (or user "")))                   (string-match (nth 1 item) (or user "")))
5740          (setq method (nth 2 item))          (setq method (nth 2 item))
5741          (setq choices nil)))          (setq choices nil)))
5742      method))      method))
5743    
5744    (defun tramp-find-method (multi-method method user host)
5745      "Return the right method string to use.
5746    This is MULTI-METHOD, if non-nil.  Otherwise, it is METHOD, if non-nil.
5747    If both MULTI-METHOD and METHOD are nil, do a lookup in
5748    `tramp-default-method-alist'."
5749      (or multi-method method (tramp-find-default-method user host)))
5750            
5751  ;; HHH: Not Changed.  Multi method.  Will probably not handle the case where  ;; HHH: Not Changed.  Multi method.  Will probably not handle the case where
5752  ;;      a user name is not provided in the "file name" very well.  ;;      a user name is not provided in the "file name" very well.
# Line 5038  remote path name." Line 5786  remote path name."
5786    
5787  (defun tramp-make-tramp-file-name (multi-method method user host path)  (defun tramp-make-tramp-file-name (multi-method method user host path)
5788    "Constructs a tramp file name from METHOD, USER, HOST and PATH."    "Constructs a tramp file name from METHOD, USER, HOST and PATH."
   (unless tramp-make-tramp-file-format  
     (error "`tramp-make-tramp-file-format' is nil"))  
5789    (if multi-method    (if multi-method
5790        (tramp-make-tramp-multi-file-name multi-method method user host path)        (tramp-make-tramp-multi-file-name multi-method method user host path)
5791      (if user      (format-spec
5792          (format-spec tramp-make-tramp-file-format       (concat tramp-prefix-format
5793                       `((?m . ,method) (?u . ,user) (?h . ,host) (?p . ,path)))        (when method (concat "%m" tramp-postfix-single-method-format))
5794        (format-spec tramp-make-tramp-file-user-nil-format        (when user   (concat "%u" tramp-postfix-user-format))
5795                     `((?m . ,method) (?h . ,host) (?p . ,path))))))        (when host   (concat "%h" tramp-postfix-host-format))
5796          (when path   (concat "%p")))
5797        `((?m . ,method) (?u . ,user) (?h . ,host) (?p . ,path)))))
5798    
5799  ;; CCC: Henrik Holm: Not Changed.  Multi Method.  What should be done  ;; CCC: Henrik Holm: Not Changed.  Multi Method.  What should be done
5800  ;; with this when USER is nil?  ;; with this when USER is nil?
# Line 5081  remote path name." Line 5829  remote path name."
5829        (format "/%s@%s:%s" user host path)        (format "/%s@%s:%s" user host path)
5830      (format "/%s:%s" host path)))      (format "/%s:%s" host path)))
5831    
5832  (defun tramp-method-out-of-band-p (multi-method method)  (defun tramp-method-out-of-band-p (multi-method method user host)
5833    "Return t if this is an out-of-band method, nil otherwise.    "Return t if this is an out-of-band method, nil otherwise.
5834  It is important to check for this condition, since it is not possible  It is important to check for this condition, since it is not possible
5835  to enter a password for the `tramp-rcp-program'."  to enter a password for the `tramp-rcp-program'."
5836    (tramp-get-rcp-program multi-method method))    (tramp-get-rcp-program
5837       multi-method
5838       (tramp-find-method multi-method method user host)))
5839    
5840  ;; Variables local to connection.  ;; Variables local to connection.
5841    
# Line 5136  If the value is not set for the connecti Line 5886  If the value is not set for the connecti
5886            value)))            value)))
5887    
5888  ;; Some predefined connection properties.  ;; Some predefined connection properties.
5889  (defun tramp-get-encoding-command (multi-method method user host)  (defun tramp-set-remote-encoding (multi-method method user host rem-enc)
5890    (tramp-get-connection-property "encoding-command" nil    (tramp-set-connection-property "remote-encoding" rem-enc
5891                                   multi-method method user host))                                   multi-method method user host))
5892  (defun tramp-set-encoding-command (multi-method method user host command)  (defun tramp-get-remote-encoding (multi-method method user host)
5893    (tramp-set-connection-property "encoding-command" command    (tramp-get-connection-property "remote-encoding" nil
5894                                   multi-method method user host))                                   multi-method method user host))
5895  (defun tramp-get-decoding-command (multi-method method user host)  
5896    (tramp-get-connection-property "decoding-command" nil  (defun tramp-set-remote-decoding (multi-method method user host rem-dec)
5897      (tramp-set-connection-property "remote-decoding" rem-dec
5898                                   multi-method method user host))                                   multi-method method user host))
5899  (defun tramp-set-decoding-command (multi-method method user host command)  (defun tramp-get-remote-decoding (multi-method method user host)
5900    (tramp-set-connection-property "decoding-command" command    (tramp-get-connection-property "remote-decoding" nil
5901                                   multi-method method user host))                                   multi-method method user host))
5902  (defun tramp-get-encoding-function (multi-method method user host)  
5903    (tramp-get-connection-property "encoding-function" nil  (defun tramp-set-local-encoding (multi-method method user host loc-enc)
5904      (tramp-set-connection-property "local-encoding" loc-enc
5905                                   multi-method method user host))                                   multi-method method user host))
5906  (defun tramp-set-encoding-function (multi-method method user host func)  (defun tramp-get-local-encoding (multi-method method user host)
5907    (tramp-set-connection-property "encoding-function" func    (tramp-get-connection-property "local-encoding" nil
5908                                   multi-method method user host))                                   multi-method method user host))
5909  (defun tramp-get-decoding-function (multi-method method user host)  
5910    (tramp-get-connection-property "decoding-function" nil  (defun tramp-set-local-decoding (multi-method method user host loc-dec)
5911      (tramp-set-connection-property "local-decoding" loc-dec
5912                                   multi-method method user host))                                   multi-method method user host))
5913  (defun tramp-set-decoding-function (multi-method method user host func)  (defun tramp-get-local-decoding (multi-method method user host)
5914    (tramp-set-connection-property "decoding-function" func    (tramp-get-connection-property "local-decoding" nil
5915                                   multi-method method user host))                                   multi-method method user host))
5916    
5917    
5918  (defun tramp-get-connection-function (multi-method method)  
5919    (defun tramp-get-connection-function (multi-method method user host)
5920    (second (or (assoc 'tramp-connection-function    (second (or (assoc 'tramp-connection-function
5921                       (assoc (or multi-method method tramp-default-method)                       (assoc (tramp-find-method multi-method method user host)
5922                              tramp-methods))                              tramp-methods))
5923                (error "Method `%s' didn't specify a connection function"                (error "Method `%s' didn't specify a connection function"
5924                       (or multi-method method)))))                       (or multi-method method)))))
5925    
5926  (defun tramp-get-remote-sh (multi-method method)  (defun tramp-get-remote-sh (multi-method method user host)
5927    (second (or (assoc 'tramp-remote-sh    (second (or (assoc 'tramp-remote-sh
5928                       (assoc (or multi-method method tramp-default-method)                       (assoc (tramp-find-method multi-method method user host)
5929                              tramp-methods))                              tramp-methods))
5930                (error "Method `%s' didn't specify a remote shell"                (error "Method `%s' didn't specify a remote shell"
5931                       (or multi-method method)))))                       (or multi-method method)))))
5932    
5933  (defun tramp-get-rsh-program (multi-method method)  (defun tramp-get-rsh-program (multi-method method user host)
5934    (second (or (assoc 'tramp-rsh-program    (second (or (assoc 'tramp-rsh-program
5935                       (assoc (or multi-method method tramp-default-method)                       (assoc (tramp-find-method multi-method method user host)
5936                              tramp-methods))                              tramp-methods))
5937                (error "Method `%s' didn't specify an rsh program"                (error "Method `%s' didn't specify an rsh program"
5938                       (or multi-method method)))))                       (or multi-method method)))))
5939    
5940  (defun tramp-get-rsh-args (multi-method method)  (defun tramp-get-rsh-args (multi-method method user host)
5941    (second (or (assoc 'tramp-rsh-args    (second (or (assoc 'tramp-rsh-args
5942                       (assoc (or multi-method method tramp-default-method)                       (assoc (tramp-find-method multi-method method user host)
5943                              tramp-methods))                              tramp-methods))
5944                (error "Method `%s' didn't specify rsh args"                (error "Method `%s' didn't specify rsh args"
5945                       (or multi-method method)))))                       (or multi-method method)))))
5946    
5947  (defun tramp-get-rcp-program (multi-method method)  (defun tramp-get-rcp-program (multi-method method user host)
5948    (second (or (assoc 'tramp-rcp-program    (second (or (assoc 'tramp-rcp-program
5949                       (assoc (or multi-method method tramp-default-method)                       (assoc (tramp-find-method multi-method method user host)
5950                              tramp-methods))                              tramp-methods))
5951                (error "Method `%s' didn't specify an rcp program"                (error "Method `%s' didn't specify an rcp program"
5952                       (or multi-method method)))))                       (or multi-method method)))))
5953    
5954  (defun tramp-get-rcp-args (multi-method method)  (defun tramp-get-rcp-args (multi-method method user host)
5955    (second (or (assoc 'tramp-rcp-args    (second (or (assoc 'tramp-rcp-args
5956                       (assoc (or multi-method method tramp-default-method)                       (assoc (tramp-find-method multi-method method user host)
5957                              tramp-methods))                              tramp-methods))
5958                (error "Method `%s' didn't specify rcp args"                (error "Method `%s' didn't specify rcp args"
5959                       (or multi-method method)))))                       (or multi-method method)))))
5960    
5961  (defun tramp-get-rcp-keep-date-arg (multi-method method)  (defun tramp-get-rcp-keep-date-arg (multi-method method user host)
5962    (second (or (assoc 'tramp-rcp-keep-date-arg    (second (or (assoc 'tramp-rcp-keep-date-arg
5963                       (assoc (or multi-method method tramp-default-method)                       (assoc (tramp-find-method multi-method method user host)
5964                              tramp-methods))                              tramp-methods))
5965                (error "Method `%s' didn't specify `keep-date' arg for tramp"                (error "Method `%s' didn't specify `keep-date' arg for tramp"
5966                       (or multi-method method)))))                       (or multi-method method)))))
5967    
5968  (defun tramp-get-su-program (multi-method method)  (defun tramp-get-su-program (multi-method method user host)
5969    (second (or (assoc 'tramp-su-program    (second (or (assoc 'tramp-su-program
5970                       (assoc (or multi-method method tramp-default-method)                       (assoc (tramp-find-method multi-method method user host)
5971                              tramp-methods))                              tramp-methods))
5972                (error "Method `%s' didn't specify a su program"                (error "Method `%s' didn't specify a su program"
5973                       (or multi-method method)))))                       (or multi-method method)))))
5974    
5975  (defun tramp-get-su-args (multi-method method)  (defun tramp-get-su-args (multi-method method user host)
5976    (second (or (assoc 'tramp-su-args    (second (or (assoc 'tramp-su-args
5977                       (assoc (or multi-method method tramp-default-method)                       (assoc (tramp-find-method multi-method method user host)
5978                              tramp-methods))                              tramp-methods))
5979                (error "Method `%s' didn't specify su args"                (error "Method `%s' didn't specify su args"
5980                       (or multi-method method)))))                       (or multi-method method)))))
5981    
5982  (defun tramp-get-telnet-program (multi-method method)  (defun tramp-get-telnet-program (multi-method method user host)
5983    (second (or (assoc 'tramp-telnet-program    (second (or (assoc 'tramp-telnet-program
5984                       (assoc (or multi-method method tramp-default-method)                       (assoc (tramp-find-method multi-method method user host)
5985                              tramp-methods))                              tramp-methods))
5986                (error "Method `%s' didn't specify a telnet program"                (error "Method `%s' didn't specify a telnet program"
5987                       (or multi-method method)))))                       (or multi-method method)))))
5988    
5989  (defun tramp-get-telnet-args (multi-method method)  (defun tramp-get-telnet-args (multi-method method user host)
5990    (second (or (assoc 'tramp-telnet-args    (second (or (assoc 'tramp-telnet-args
5991                       (assoc (or multi-method method tramp-default-method)                       (assoc (tramp-find-method multi-method method user host)
5992                              tramp-methods))                              tramp-methods))
5993                (error "Method `%s' didn't specify telnet args"                (error "Method `%s' didn't specify telnet args"
5994                       (or multi-method method)))))                       (or multi-method method)))))
5995    
 ;; (defun tramp-get-encoding-command (multi-method method)  
 ;;   (second (or (assoc 'tramp-encoding-command  
 ;;                      (assoc (or multi-method method tramp-default-method)  
 ;;                             tramp-methods))  
 ;;               (error "Method `%s' didn't specify an encoding command"  
 ;;                      (or multi-method method)))))  
   
 ;; (defun tramp-get-decoding-command (multi-method method)  
 ;;   (second (or (assoc 'tramp-decoding-command  
 ;;                      (assoc (or multi-method method tramp-default-method)  
 ;;                             tramp-methods))  
 ;;               (error "Method `%s' didn't specify a decoding command"  
 ;;                      (or multi-method method)))))  
   
 ;; (defun tramp-get-encoding-function (multi-method method)  
 ;;   (second (or (assoc 'tramp-encoding-function  
 ;;                      (assoc (or multi-method method tramp-default-method)  
 ;;                             tramp-methods))  
 ;;               (error "Method `%s' didn't specify an encoding function"  
 ;;                      (or multi-method method)))))  
   
 ;; (defun tramp-get-decoding-function (multi-method method)  
 ;;   (second (or (assoc 'tramp-decoding-function  
 ;;                      (assoc (or multi-method method tramp-default-method)  
 ;;                             tramp-methods))  
 ;;               (error "Method `%s' didn't specify a decoding function"  
 ;;                      (or multi-method method)))))  
5996    
5997  ;; Auto saving to a special directory.  ;; Auto saving to a special directory.
5998    
# Line 5463  Only works for Bourne-like shells." Line 6190  Only works for Bourne-like shells."
6190  ;;       nil  ;;       nil
6191  ;;     ad-do-it))  ;;     ad-do-it))
6192    
6193  ;; We currently use "[" and "]" in the filename format.  In Emacs  ;; We currently (sometimes) use "[" and "]" in the filename format.
6194  ;; 20.x, this means that Emacs wants to expand wildcards if  ;; This means that Emacs wants to expand wildcards if
6195  ;; `find-file-wildcards' is non-nil, and then barfs because no  ;; `find-file-wildcards' is non-nil, and then barfs because no
6196  ;; expansion could be found.  We detect this situation and do  ;; expansion could be found.  We detect this situation and do
6197  ;; something really awful: we have `file-expand-wildcards' return the  ;; something really awful: we have `file-expand-wildcards' return the
6198  ;; original filename if it can't expand anything.  Let's just hope  ;; original filename if it can't expand anything.  Let's just hope
6199  ;; that this doesn't break anything else.  ;; that this doesn't break anything else.
6200  ;;  ;; CCC: This check is now also really awful; we should search all
6201  ;; Another problem is that the check is done by Emacs version, which  ;; of the filename format, not just the prefix.
6202  ;; is really not what we want to do.  Oh, well.  (when (string-match "\\[" tramp-prefix-format)
   
 ;;(when (and (not (featurep 'xemacs))  
 ;;         (= emacs-major-version 20))  
 ;; It seems that this advice is needed in Emacs 21, too.  
6203  (defadvice file-expand-wildcards (around tramp-fix activate)  (defadvice file-expand-wildcards (around tramp-fix activate)
6204    (let ((name (ad-get-arg 0)))    (let ((name (ad-get-arg 0)))
6205      (if (tramp-tramp-file-p name)      (if (tramp-tramp-file-p name)
# Line 5490  Only works for Bourne-like shells." Line 6213  Only works for Bourne-like shells."
6213        ;; If it is not a Tramp file, just run the original function.        ;; If it is not a Tramp file, just run the original function.
6214        (let ((res ad-do-it))        (let ((res ad-do-it))
6215          (setq ad-return-value (or res (list name)))))))          (setq ad-return-value (or res (list name)))))))
6216  ;;  )  )
6217    
6218  ;; Tramp version is useful in a number of situations.  ;; Tramp version is useful in a number of situations.
6219    
# Line 5526  Only works for Bourne-like shells." Line 6249  Only works for Bourne-like shells."
6249         tramp-auto-save-directory        ; vars to dump         tramp-auto-save-directory        ; vars to dump
6250         tramp-default-method         tramp-default-method
6251         tramp-rsh-end-of-line         tramp-rsh-end-of-line
6252           tramp-password-end-of-line
6253         tramp-remote-path         tramp-remote-path
6254         tramp-login-prompt-regexp         tramp-login-prompt-regexp
6255         tramp-password-prompt-regexp         tramp-password-prompt-regexp
# Line 5539  Only works for Bourne-like shells." Line 6263  Only works for Bourne-like shells."
6263         tramp-multi-file-name-hop-structure         tramp-multi-file-name-hop-structure
6264         tramp-multi-methods         tramp-multi-methods
6265         tramp-multi-connection-function-alist         tramp-multi-connection-function-alist
6266         tramp-make-tramp-file-format         tramp-methods
6267         tramp-end-of-output         tramp-end-of-output
6268         tramp-coding-commands         tramp-coding-commands
6269         tramp-actions-before-shell         tramp-actions-before-shell
# Line 5587  report. Line 6311  report.
6311    
6312  ;;; TODO:  ;;; TODO:
6313    
6314    ;; * Autodetect if remote `ls' groks the "--dired" switch.
6315  ;; * Add fallback for inline encodings.  This should be used  ;; * Add fallback for inline encodings.  This should be used
6316  ;;   if the remote end doesn't support mimencode or a similar program.  ;;   if the remote end doesn't support mimencode or a similar program.
6317  ;;   For reading files from the remote host, we can just parse the output  ;;   For reading files from the remote host, we can just parse the output
# Line 5599  report. Line 6324  report.
6324  ;;   two commands to write a null byte:  ;;   two commands to write a null byte:
6325  ;;   dd if=/dev/zero bs=1 count=1  ;;   dd if=/dev/zero bs=1 count=1
6326  ;;   echo | tr '\n' '\000'  ;;   echo | tr '\n' '\000'
6327    ;; * Separate local `tramp-coding-commands' from remote ones.  Connect
6328    ;;   the two via a format which can be `uu' or `b64'.  Then we can search
6329    ;;   for the right local commands and the right remote commands separately.
6330  ;; * Cooperate with PCL-CVS.  It uses start-process, which doesn't  ;; * Cooperate with PCL-CVS.  It uses start-process, which doesn't
6331  ;;   work for remote files.  ;;   work for remote files.
6332  ;; * Rewrite `tramp-shell-quote-argument' to abstain from using  ;; * Rewrite `tramp-shell-quote-argument' to abstain from using
# Line 5684  report. Line 6412  report.
6412  ;;   about Tramp, it does not do the right thing if the target file  ;;   about Tramp, it does not do the right thing if the target file
6413  ;;   name is a Tramp name.  ;;   name is a Tramp name.
6414  ;; * Username and hostname completion.  ;; * Username and hostname completion.
6415    ;; ** If `partial-completion-mode' isn't loaded, "/foo:bla" tries to
6416    ;;    connect to host "blabla" already if that host is unique. No idea
6417    ;;    how to suppress. Maybe not an essential problem.
6418    ;; ** For "/ssh1-old:", `(file-name-all-completions "ssh1" "/")' is called
6419    ;;    only. Likely due to word delimeter property of "-". Maybe we can remove
6420    ;;    all the "*-old" methods? Or rename them to "*_old"?
6421    ;; ** Try to avoid usage of `last-input-event' in `tramp-completion-mode'.
6422    ;; ** Handle quoted file names, starting with "/:". Problem is that
6423    ;;    `file-name-non-special' calls later on `file-name-all-completions'
6424    ;;    without ":". Hmm. Worth a bug report?
6425    ;; ** Acknowledge port numbers.
6426    ;; ** Extend `tramp-get-completion-su' for NIS and shadow passwords.
6427    ;; ** Unify `tramp-parse-{rhosts,shosts,hosts,passwd}'.
6428    ;;    Code is nearly identical.
6429    ;; ** Decide whiche files to take for searching user/host names depending on
6430    ;;    operating system (windows-nt) in `tramp-completion-function-alist'.
6431    ;; ** Enhance variables for debug.
6432    ;; ** Implement "/multi:" completion.
6433    ;; ** Add a learning mode for completion. Make results persistent.
6434    
6435  ;; Functions for file-name-handler-alist:  ;; Functions for file-name-handler-alist:
6436  ;; diff-latest-backup-file -- in diff.el  ;; diff-latest-backup-file -- in diff.el

Legend:
Removed from v.1.23  
changed lines
  Added in v.1.24

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26