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

Diff of /tramp/lisp/tramp.el

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

revision 2.278 by kai, Sat Feb 15 18:12:54 2003 UTC revision 2.279 by kai, Sat Feb 15 18:37:30 2003 UTC
# Line 110  Line 110 
110  ;; tramp-smb uses "smbclient" from Samba.  ;; tramp-smb uses "smbclient" from Samba.
111  ;; Not available under Cygwin and Windows, because they don't offer  ;; Not available under Cygwin and Windows, because they don't offer
112  ;; "smbclient".  And even not necessary there, because Emacs supports  ;; "smbclient".  And even not necessary there, because Emacs supports
113  ;; UNC file names like "//host/share/path".  ;; UNC file names like "//host/share/localname".
114  (unless (memq system-type '(cygwin windows-nt))  (unless (memq system-type '(cygwin windows-nt))
115    (eval-after-load "tramp"    (eval-after-load "tramp"
116      '(require 'tramp-smb)))      '(require 'tramp-smb)))
# Line 520  pair of the form (KEY VALUE).  The follo Line 520  pair of the form (KEY VALUE).  The follo
520      the value that you decide to use.  You Have Been Warned.      the value that you decide to use.  You Have Been Warned.
521    * `tramp-rsh-program'    * `tramp-rsh-program'
522      This specifies the name of the program to use for rsh; this might be      This specifies the name of the program to use for rsh; this might be
523      the full path to rsh or the name of a workalike program.      the absolute filename of rsh or the name of a workalike program.
524    * `tramp-rsh-args'    * `tramp-rsh-args'
525      This specifies the list of arguments to pass to the above      This specifies the list of arguments to pass to the above
526      mentioned program.  Please note that this is a list of arguments,      mentioned program.  Please note that this is a list of arguments,
# Line 529  pair of the form (KEY VALUE).  The follo Line 529  pair of the form (KEY VALUE).  The follo
529      for \"-b\", or one for \"-f\" and one for \"foo\".      for \"-b\", or one for \"-f\" and one for \"foo\".
530    * `tramp-rcp-program'    * `tramp-rcp-program'
531      This specifies the name of the program to use for rcp; this might be      This specifies the name of the program to use for rcp; this might be
532      the full path to rcp or the name of a workalike program.      the absolute filename of rcp or the name of a workalike program.
533    * `tramp-rcp-args'    * `tramp-rcp-args'
534      This specifies the list of parameters to pass to the above mentioned      This specifies the list of parameters to pass to the above mentioned
535      program, the hints for `tramp-rsh-args' also apply here.      program, the hints for `tramp-rsh-args' also apply here.
# Line 942  Derived from `tramp-postfix-multi-method Line 942  Derived from `tramp-postfix-multi-method
942    
943  (defcustom tramp-postfix-multi-hop-format  (defcustom tramp-postfix-multi-hop-format
944    (if tramp-unified-filenames ":" "/")    (if tramp-unified-filenames ":" "/")
945    "*String matching delimeter between path and next method.    "*String matching delimeter between host and next method.
946  Applicable for multi-hop methods.  Applicable for multi-hop methods.
947  Used in `tramp-make-tramp-multi-file-name'."  Used in `tramp-make-tramp-multi-file-name'."
948    :group 'tramp    :group 'tramp
# Line 950  Used in `tramp-make-tramp-multi-file-nam Line 950  Used in `tramp-make-tramp-multi-file-nam
950    
951  (defcustom tramp-postfix-multi-hop-regexp  (defcustom tramp-postfix-multi-hop-regexp
952    (regexp-quote tramp-postfix-multi-hop-format)    (regexp-quote tramp-postfix-multi-hop-format)
953    "*Regexp matching delimeter between path and next method.    "*Regexp matching delimeter between host and next method.
954  Applicable for multi-hop methods.  Applicable for multi-hop methods.
955  Derived from `tramp-postfix-multi-hop-format'."  Derived from `tramp-postfix-multi-hop-format'."
956    :group 'tramp    :group 'tramp
# Line 990  Derived from `tramp-postfix-user-format' Line 990  Derived from `tramp-postfix-user-format'
990    
991  (defcustom tramp-postfix-host-format  (defcustom tramp-postfix-host-format
992    (if tramp-unified-filenames ":" "]")    (if tramp-unified-filenames ":" "]")
993    "*String matching delimeter between host names and paths.    "*String matching delimeter between host names and localnames.
994  Used in `tramp-make-tramp-file-name' and `tramp-make-tramp-multi-file-name'."  Used in `tramp-make-tramp-file-name' and `tramp-make-tramp-multi-file-name'."
995    :group 'tramp    :group 'tramp
996    :type 'string)    :type 'string)
997    
998  (defcustom tramp-postfix-host-regexp  (defcustom tramp-postfix-host-regexp
999    (regexp-quote tramp-postfix-host-format)    (regexp-quote tramp-postfix-host-format)
1000    "*Regexp matching delimeter between host names and paths.    "*Regexp matching delimeter between host names and localnames.
1001  Derived from `tramp-postfix-host-format'."  Derived from `tramp-postfix-host-format'."
1002    :group 'tramp    :group 'tramp
1003    :type 'regexp)    :type 'regexp)
1004    
1005  (defcustom tramp-path-regexp  (defcustom tramp-localname-regexp
1006    ".*$"    ".*$"
1007    "*Regexp matching paths."    "*Regexp matching localnames."
1008    :group 'tramp    :group 'tramp
1009    :type 'regexp)    :type 'regexp)
1010    
# Line 1017  Derived from `tramp-postfix-host-format' Line 1017  Derived from `tramp-postfix-host-format'
1017      "\\(" "\\(" tramp-method-regexp "\\)" tramp-postfix-single-method-regexp "\\)?"      "\\(" "\\(" tramp-method-regexp "\\)" tramp-postfix-single-method-regexp "\\)?"
1018      "\\(" "\\(" tramp-user-regexp "\\)" tramp-postfix-user-regexp   "\\)?"      "\\(" "\\(" tramp-user-regexp "\\)" tramp-postfix-user-regexp   "\\)?"
1019            "\\(" tramp-host-with-port-regexp "\\)" tramp-postfix-host-regexp            "\\(" tramp-host-with-port-regexp "\\)" tramp-postfix-host-regexp
1020            "\\(" tramp-path-regexp "\\)")            "\\(" tramp-localname-regexp "\\)")
1021     2 4 5 6)     2 4 5 6)
1022    
1023    "*List of five elements (REGEXP METHOD USER HOST FILE), detailing \    "*List of five elements (REGEXP METHOD USER HOST FILE), detailing \
# Line 1115  Also see `tramp-file-name-structure'." Line 1115  Also see `tramp-file-name-structure'."
1115      tramp-prefix-regexp      tramp-prefix-regexp
1116      "\\(" "\\(" tramp-method-regexp "\\)" "\\)?"      "\\(" "\\(" tramp-method-regexp "\\)" "\\)?"
1117      "\\(" "\\(" tramp-postfix-multi-hop-regexp "%s" "\\)+" "\\)?"      "\\(" "\\(" tramp-postfix-multi-hop-regexp "%s" "\\)+" "\\)?"
1118      tramp-postfix-host-regexp "\\(" tramp-path-regexp "\\)")      tramp-postfix-host-regexp "\\(" tramp-localname-regexp "\\)")
1119     2 3 -1)     2 3 -1)
1120    "*Describes the file name structure of `multi' files.    "*Describes the file name structure of `multi' files.
1121  Multi files allow you to contact a remote host in several hops.  Multi files allow you to contact a remote host in several hops.
1122  This is a list of four elements (REGEXP METHOD HOP PATH).  This is a list of four elements (REGEXP METHOD HOP LOCALNAME).
1123    
1124  The first element, REGEXP, gives a regular expression to match against  The first element, REGEXP, gives a regular expression to match against
1125  the file name.  In this regular expression, `%s' is replaced with the  the file name.  In this regular expression, `%s' is replaced with the
# Line 1130  of parentheses is used for the HOP eleme Line 1130  of parentheses is used for the HOP eleme
1130    
1131  All remaining elements are numbers.  METHOD gives the number of the  All remaining elements are numbers.  METHOD gives the number of the
1132  paren pair which matches the method name.  HOP gives the number of the  paren pair which matches the method name.  HOP gives the number of the
1133  paren pair which matches the hop sequence.  PATH gives the number of  paren pair which matches the hop sequence.  LOCALNAME gives the number of
1134  the paren pair which matches the path name on the remote host.  the paren pair which matches the localname (pathname) on the remote host.
1135    
1136  PATH can also be negative, which means to count from the end.  Ie, a  LOCALNAME can also be negative, which means to count from the end.  Ie, a
1137  value of -1 means the last paren pair.  value of -1 means the last paren pair.
1138    
1139  I think it would be good if the regexp matches the whole of the  I think it would be good if the regexp matches the whole of the
# Line 1142  string, but I haven't actually tried wha Line 1142  string, but I haven't actually tried wha
1142    :type '(list (regexp :tag "File name regexp")    :type '(list (regexp :tag "File name regexp")
1143                 (integer :tag "Paren pair for method name")                 (integer :tag "Paren pair for method name")
1144                 (integer :tag "Paren pair for hops")                 (integer :tag "Paren pair for hops")
1145                 (integer :tag "Paren pair to match path")))                 (integer :tag "Paren pair to match localname")))
1146    
1147  (defcustom tramp-multi-file-name-hop-structure  (defcustom tramp-multi-file-name-hop-structure
1148    (list    (list
# Line 1173  This regular expression should match exa Line 1173  This regular expression should match exa
1173      "%h")      "%h")
1174     (concat tramp-postfix-host-format "%p"))     (concat tramp-postfix-host-format "%p"))
1175    "*Describes how to construct a `multi' file name.    "*Describes how to construct a `multi' file name.
1176  This is a list of three elements PREFIX, HOP and PATH.  This is a list of three elements PREFIX, HOP and LOCALNAME.
1177    
1178  The first element PREFIX says how to construct the prefix, the second  The first element PREFIX says how to construct the prefix, the second
1179  element HOP specifies what each hop looks like, and the final element  element HOP specifies what each hop looks like, and the final element
1180  PATH says how to construct the path name.  LOCALNAME says how to construct the localname (pathname).
1181    
1182  In PREFIX, `%%' means `%' and `%m' means the method name.  In PREFIX, `%%' means `%' and `%m' means the method name.
1183    
1184  In HOP, `%%' means `%' and `%m', `%u', `%h' mean the hop method, hop  In HOP, `%%' means `%' and `%m', `%u', `%h' mean the hop method, hop
1185  user and hop host, respectively.  user and hop host, respectively.
1186    
1187  In PATH, `%%' means `%' and `%p' means the path name.  In LOCALNAME, `%%' means `%' and `%p' means the localname.
1188    
1189  The resulting file name always contains one copy of PREFIX and one  The resulting file name always contains one copy of PREFIX and one
1190  copy of PATH, but there is one copy of HOP for each hop in the file  copy of LOCALNAME, but there is one copy of HOP for each hop in the file
1191  name.  name.
1192    
1193  Note: the current implementation requires the prefix to contain the  Note: the current implementation requires the prefix to contain the
1194  method name, followed by all the hops, and the path name must come  method name, followed by all the hops, and the localname must come
1195  last."  last."
1196    :group 'tramp    :group 'tramp
1197    :type '(list string string string))    :type '(list string string string))
# Line 1736  the filename structure.  It is also used Line 1736  the filename structure.  It is also used
1736  holding the components.  For example, if VAR is the symbol `foo', then  holding the components.  For example, if VAR is the symbol `foo', then
1737  `foo' will be bound to the whole structure, `foo-multi-method' will  `foo' will be bound to the whole structure, `foo-multi-method' will
1738  be bound to the multi-method component, and so on for `foo-method',  be bound to the multi-method component, and so on for `foo-method',
1739  `foo-user', `foo-host', `foo-path'.  `foo-user', `foo-host', `foo-localname'.
1740    
1741  Remaining args are Lisp expressions to be evaluated (inside an implicit  Remaining args are Lisp expressions to be evaluated (inside an implicit
1742  `progn').  `progn').
1743    
1744  If VAR is nil, then we bind `v' to the structure and `multi-method',  If VAR is nil, then we bind `v' to the structure and `multi-method',
1745  `method', `user', `host', `path' to the components."  `method', `user', `host', `localname' to the components."
1746    `(let* ((,(or var 'v) (tramp-dissect-file-name ,filename))    `(let* ((,(or var 'v) (tramp-dissect-file-name ,filename))
1747            (,(if var (intern (concat (symbol-name var) "-multi-method")) 'multi-method)            (,(if var (intern (concat (symbol-name var) "-multi-method")) 'multi-method)
1748             (tramp-file-name-multi-method ,(or var 'v)))             (tramp-file-name-multi-method ,(or var 'v)))
# Line 1752  If VAR is nil, then we bind `v' to the s Line 1752  If VAR is nil, then we bind `v' to the s
1752             (tramp-file-name-user ,(or var 'v)))             (tramp-file-name-user ,(or var 'v)))
1753            (,(if var (intern (concat (symbol-name var) "-host")) 'host)            (,(if var (intern (concat (symbol-name var) "-host")) 'host)
1754             (tramp-file-name-host ,(or var 'v)))             (tramp-file-name-host ,(or var 'v)))
1755            (,(if var (intern (concat (symbol-name var) "-path")) 'path)            (,(if var (intern (concat (symbol-name var) "-localname")) 'localname)
1756             (tramp-file-name-path ,(or var 'v))))             (tramp-file-name-localname ,(or var 'v))))
1757       ,@body))       ,@body))
1758    
1759  (put 'with-parsed-tramp-file-name 'lisp-indent-function 2)  (put 'with-parsed-tramp-file-name 'lisp-indent-function 2)
# Line 1792  For definition of that list see `tramp-s Line 1792  For definition of that list see `tramp-s
1792    (filename linkname &optional ok-if-already-exists)    (filename linkname &optional ok-if-already-exists)
1793    "Like `make-symbolic-link' for tramp files.    "Like `make-symbolic-link' for tramp files.
1794  If LINKNAME is a non-Tramp file, it is used verbatim as the target of  If LINKNAME is a non-Tramp file, it is used verbatim as the target of
1795  the symlink.  If LINKNAME is a Tramp file, only the path component is  the symlink.  If LINKNAME is a Tramp file, only the localname component is
1796  used as the target of the symlink.  used as the target of the symlink.
1797    
1798  If LINKNAME is a Tramp file and the path component is relative, then  If LINKNAME is a Tramp file and the localname component is relative, then
1799  it is expanded first, before the path component is taken.  Note that  it is expanded first, before the localname component is taken.  Note that
1800  this can give surprising results if the user/host for the source and  this can give surprising results if the user/host for the source and
1801  target of the symlink differ."  target of the symlink differ."
1802    (with-parsed-tramp-file-name linkname l    (with-parsed-tramp-file-name linkname l
1803      (let ((ln (tramp-get-remote-ln l-multi-method l-method l-user l-host))      (let ((ln (tramp-get-remote-ln l-multi-method l-method l-user l-host))
1804            (cwd (file-name-directory l-path)))            (cwd (file-name-directory l-localname)))
1805        (unless ln        (unless ln
1806          (signal 'file-error          (signal 'file-error
1807                  (list "Making a symbolic link."                  (list "Making a symbolic link."
# Line 1815  target of the symlink differ." Line 1815  target of the symlink differ."
1815                       (not (yes-or-no-p                       (not (yes-or-no-p
1816                             (format                             (format
1817                              "File %s already exists; make it a link anyway? "                              "File %s already exists; make it a link anyway? "
1818                              l-path)))))                              l-localname)))))
1819              (signal 'file-already-exists (list "File already exists" l-path))              (signal 'file-already-exists (list "File already exists" l-localname))
1820            (delete-file linkname)))            (delete-file linkname)))
1821    
1822        ;; If FILENAME is a Tramp name, use just the path component.        ;; If FILENAME is a Tramp name, use just the localname component.
1823        (when (tramp-tramp-file-p filename)        (when (tramp-tramp-file-p filename)
1824          (setq filename (tramp-file-name-path          (setq filename (tramp-file-name-localname
1825                          (tramp-dissect-file-name                          (tramp-dissect-file-name
1826                           (expand-file-name filename)))))                           (expand-file-name filename)))))
1827            
# Line 1834  target of the symlink differ." Line 1834  target of the symlink differ."
1834          (format "cd %s && %s -sf %s %s"          (format "cd %s && %s -sf %s %s"
1835                  cwd ln                  cwd ln
1836                  filename                  filename
1837                  l-path)                  l-localname)
1838          t)))))          t)))))
1839    
1840    
1841  (defun tramp-handle-load (file &optional noerror nomessage nosuffix must-suffix)  (defun tramp-handle-load (file &optional noerror nomessage nosuffix must-suffix)
1842    "Like `load' for tramp files.  Not implemented!"    "Like `load' for tramp files.  Not implemented!"
1843    (unless (file-name-absolute-p file)    (unless (file-name-absolute-p file)
1844      (error "Tramp cannot `load' files without absolute path name"))      (error "Tramp cannot `load' files without absolute file name"))
1845    (with-parsed-tramp-file-name file nil    (with-parsed-tramp-file-name file nil
1846      (unless nosuffix      (unless nosuffix
1847        (cond ((file-exists-p (concat file ".elc"))        (cond ((file-exists-p (concat file ".elc"))
# Line 1870  target of the symlink differ." Line 1870  target of the symlink differ."
1870          (message "Loading %s...done" file))          (message "Loading %s...done" file))
1871        t)))        t)))
1872    
1873  ;; Path manipulation functions that grok TRAMP paths...  ;; Localname manipulation functions that grok TRAMP localnames...
1874  (defun tramp-handle-file-name-directory (file)  (defun tramp-handle-file-name-directory (file)
1875    "Like `file-name-directory' but aware of TRAMP files."    "Like `file-name-directory' but aware of TRAMP files."
1876    ;; everything except the last filename thing is the directory    ;; everything except the last filename thing is the directory
1877    (with-parsed-tramp-file-name file nil    (with-parsed-tramp-file-name file nil
1878      ;; For the following condition, two possibilities should be tried:      ;; For the following condition, two possibilities should be tried:
1879      ;; (1) (string= path "")      ;; (1) (string= localname "")
1880      ;; (2) (or (string= path "") (string= path "/"))      ;; (2) (or (string= localname "") (string= localname "/"))
1881      ;; The second variant fails when completing a "/" directory on      ;; The second variant fails when completing a "/" directory on
1882      ;; the remote host, that is a filename which looks like      ;; the remote host, that is a filename which looks like
1883      ;; "/user@host:/".  But maybe wildcards fail with the first variant.      ;; "/user@host:/".  But maybe wildcards fail with the first variant.
1884      ;; We should do some investigation.      ;; We should do some investigation.
1885      (if (string= path "")      (if (string= localname "")
1886          ;; For a filename like "/[foo]", we return "/".  The `else'          ;; For a filename like "/[foo]", we return "/".  The `else'
1887          ;; case would return "/[foo]" unchanged.  But if we do that,          ;; case would return "/[foo]" unchanged.  But if we do that,
1888          ;; then `file-expand-wildcards' ceases to work.  It's not          ;; then `file-expand-wildcards' ceases to work.  It's not
1889          ;; quite clear to me what's the intuition that tells that this          ;; quite clear to me what's the intuition that tells that this
1890          ;; behavior is the right behavior, but oh, well.          ;; behavior is the right behavior, but oh, well.
1891          "/"          "/"
1892        ;; run the command on the path portion only        ;; run the command on the localname portion only
1893        ;; CCC: This should take into account the remote machine type, no?        ;; CCC: This should take into account the remote machine type, no?
1894        ;;  --daniel <daniel@danann.net>        ;;  --daniel <daniel@danann.net>
1895        (tramp-make-tramp-file-name multi-method method user host        (tramp-make-tramp-file-name multi-method method user host
1896                                    ;; This will not recurse...                                    ;; This will not recurse...
1897                                    (or (file-name-directory path) "")))))                                    (or (file-name-directory localname) "")))))
1898    
1899  (defun tramp-handle-file-name-nondirectory (file)  (defun tramp-handle-file-name-nondirectory (file)
1900    "Like `file-name-nondirectory' but aware of TRAMP files."    "Like `file-name-nondirectory' but aware of TRAMP files."
1901    (with-parsed-tramp-file-name file nil    (with-parsed-tramp-file-name file nil
1902      (file-name-nondirectory path)))      (file-name-nondirectory localname)))
1903    
1904  (defun tramp-handle-file-truename (filename &optional counter prev-dirs)  (defun tramp-handle-file-truename (filename &optional counter prev-dirs)
1905    "Like `file-truename' for tramp files."    "Like `file-truename' for tramp files."
1906    (with-parsed-tramp-file-name filename nil    (with-parsed-tramp-file-name filename nil
1907      (let* ((steps        (tramp-split-string path "/"))      (let* ((steps        (tramp-split-string localname "/"))
1908             (pathdir (let ((directory-sep-char ?/))             (localnamedir (let ((directory-sep-char ?/))
1909                        (file-name-as-directory path)))                        (file-name-as-directory localname)))
1910             (is-dir (string= path pathdir))             (is-dir (string= localname localnamedir))
1911             (thisstep nil)             (thisstep nil)
1912             (numchase 0)             (numchase 0)
1913             ;; Don't make the following value larger than necessary.             ;; Don't make the following value larger than necessary.
# Line 1984  target of the symlink differ." Line 1984  target of the symlink differ."
1984                multi-method method user host                multi-method method user host
1985                (format                (format
1986                 (tramp-get-file-exists-command multi-method method user host)                 (tramp-get-file-exists-command multi-method method user host)
1987                 (tramp-shell-quote-argument path)))))))                 (tramp-shell-quote-argument localname)))))))
1988    
1989  ;; Devices must distinguish physical file systems.  The device numbers  ;; Devices must distinguish physical file systems.  The device numbers
1990  ;; provided by "lstat" aren't unique, because we operate on different hosts.  ;; provided by "lstat" aren't unique, because we operate on different hosts.
# Line 2009  rather than as numbers." Line 2009  rather than as numbers."
2009            (if (tramp-get-remote-perl multi-method method user host)            (if (tramp-get-remote-perl multi-method method user host)
2010                (setq result                (setq result
2011                      (tramp-handle-file-attributes-with-perl                      (tramp-handle-file-attributes-with-perl
2012                       multi-method method user host path nonnumeric))                       multi-method method user host localname nonnumeric))
2013              (setq result              (setq result
2014                    (tramp-handle-file-attributes-with-ls                    (tramp-handle-file-attributes-with-ls
2015                     multi-method method user host path nonnumeric)))                     multi-method method user host localname nonnumeric)))
2016            ;; set virtual device number            ;; set virtual device number
2017            (setcar (nthcdr 11 result)            (setcar (nthcdr 11 result)
2018                    (tramp-get-device multi-method method user host)))))                    (tramp-get-device multi-method method user host)))))
2019      result))      result))
2020    
2021  (defun tramp-handle-file-attributes-with-ls  (defun tramp-handle-file-attributes-with-ls
2022    (multi-method method user host path &optional nonnumeric)    (multi-method method user host localname &optional nonnumeric)
2023    "Implement `file-attributes' for tramp files using the ls(1) command."    "Implement `file-attributes' for tramp files using the ls(1) command."
2024    (let (symlinkp dirp    (let (symlinkp dirp
2025                   res-inode res-filemodes res-numlinks                   res-inode res-filemodes res-numlinks
# Line 2027  rather than as numbers." Line 2027  rather than as numbers."
2027      (tramp-message-for-buffer multi-method method user host 10      (tramp-message-for-buffer multi-method method user host 10
2028                                "file attributes with ls: %s"                                "file attributes with ls: %s"
2029                                (tramp-make-tramp-file-name                                (tramp-make-tramp-file-name
2030                                 multi-method method user host path))                                 multi-method method user host localname))
2031      (tramp-send-command      (tramp-send-command
2032       multi-method method user host       multi-method method user host
2033       (format "%s %s %s"       (format "%s %s %s"
2034               (tramp-get-ls-command multi-method method user host)               (tramp-get-ls-command multi-method method user host)
2035               (if nonnumeric "-ild" "-ildn")               (if nonnumeric "-ild" "-ildn")
2036               (tramp-shell-quote-argument path)))               (tramp-shell-quote-argument localname)))
2037      (tramp-wait-for-output)      (tramp-wait-for-output)
2038      ;; parse `ls -l' output ...      ;; parse `ls -l' output ...
2039      ;; ... inode      ;; ... inode
# Line 2104  rather than as numbers." Line 2104  rather than as numbers."
2104       )))       )))
2105    
2106  (defun tramp-handle-file-attributes-with-perl  (defun tramp-handle-file-attributes-with-perl
2107    (multi-method method user host path &optional nonnumeric)    (multi-method method user host localname &optional nonnumeric)
2108    "Implement `file-attributes' for tramp files using a Perl script.    "Implement `file-attributes' for tramp files using a Perl script.
2109    
2110  The Perl command is sent to the remote machine when the connection  The Perl command is sent to the remote machine when the connection
# Line 2112  is initially created and is kept cached Line 2112  is initially created and is kept cached
2112    (tramp-message-for-buffer multi-method method user host 10    (tramp-message-for-buffer multi-method method user host 10
2113                              "file attributes with perl: %s"                              "file attributes with perl: %s"
2114                              (tramp-make-tramp-file-name                              (tramp-make-tramp-file-name
2115                               multi-method method user host path))                               multi-method method user host localname))
2116    (tramp-send-command    (tramp-send-command
2117     multi-method method user host     multi-method method user host
2118     (format "tramp_file_attributes %s"     (format "tramp_file_attributes %s"
2119             (tramp-shell-quote-argument path)))             (tramp-shell-quote-argument localname)))
2120    (tramp-wait-for-output)    (tramp-wait-for-output)
2121    (let ((result (read (current-buffer))))    (let ((result (read (current-buffer))))
2122      (setcar (nthcdr 8 result)      (setcar (nthcdr 8 result)
# Line 2155  If it doesn't exist, generate a new one. Line 2155  If it doesn't exist, generate a new one.
2155               multi-method method user host               multi-method method user host
2156               (format "%s -ild %s"               (format "%s -ild %s"
2157                       (tramp-get-ls-command multi-method method user host)                       (tramp-get-ls-command multi-method method user host)
2158                       (tramp-shell-quote-argument path)))                       (tramp-shell-quote-argument localname)))
2159              (tramp-wait-for-output)              (tramp-wait-for-output)
2160              (setq attr (buffer-substring (point)              (setq attr (buffer-substring (point)
2161                                           (progn (end-of-line) (point)))))                                           (progn (end-of-line) (point)))))
# Line 2189  If it doesn't exist, generate a new one. Line 2189  If it doesn't exist, generate a new one.
2189                      (format "%s -ild %s"                      (format "%s -ild %s"
2190                              (tramp-get-ls-command multi-method method                              (tramp-get-ls-command multi-method method
2191                                                    user host)                                                    user host)
2192                              (tramp-shell-quote-argument path)))                              (tramp-shell-quote-argument localname)))
2193                     (tramp-wait-for-output)                     (tramp-wait-for-output)
2194                     (setq attr (buffer-substring                     (setq attr (buffer-substring
2195                                 (point) (progn (end-of-line) (point)))))                                 (point) (progn (end-of-line) (point)))))
# Line 2211  if the remote host can't provide the mod Line 2211  if the remote host can't provide the mod
2211                        multi-method method user host                        multi-method method user host
2212                        (format "chmod %s %s"                        (format "chmod %s %s"
2213                                (tramp-decimal-to-octal mode)                                (tramp-decimal-to-octal mode)
2214                                (tramp-shell-quote-argument path))))                                (tramp-shell-quote-argument localname))))
2215          (signal 'file-error          (signal 'file-error
2216                  (list "Doing chmod"                  (list "Doing chmod"
2217                        ;; FIXME: extract the proper text from chmod's stderr.                        ;; FIXME: extract the proper text from chmod's stderr.
# Line 2316  if the remote host can't provide the mod Line 2316  if the remote host can't provide the mod
2316         (tramp-send-command-and-check         (tramp-send-command-and-check
2317          multi-method method user host          multi-method method user host
2318          (format "test -d %s"          (format "test -d %s"
2319                  (tramp-shell-quote-argument path))                  (tramp-shell-quote-argument localname))
2320          t)))))                          ;run command in subshell          t)))))                          ;run command in subshell
2321    
2322  (defun tramp-handle-file-regular-p (filename)  (defun tramp-handle-file-regular-p (filename)
# Line 2374  if the remote host can't provide the mod Line 2374  if the remote host can't provide the mod
2374    
2375  (defun tramp-handle-directory-file-name (directory)  (defun tramp-handle-directory-file-name (directory)
2376    "Like `directory-file-name' for tramp files."    "Like `directory-file-name' for tramp files."
2377    ;; If path component of filename is "/", leave it unchanged.    ;; If localname component of filename is "/", leave it unchanged.
2378    ;; Otherwise, remove any trailing slash from path component.    ;; Otherwise, remove any trailing slash from localname component.
2379    ;; Method, host, etc, are unchanged.  Does it make sense to try    ;; Method, host, etc, are unchanged.  Does it make sense to try
2380    ;; to avoid parsing the filename?    ;; to avoid parsing the filename?
2381    (with-parsed-tramp-file-name directory nil    (with-parsed-tramp-file-name directory nil
2382      (if (and (not (zerop (length path)))      (if (and (not (zerop (length localname)))
2383               (eq (aref path (1- (length path))) ?/)               (eq (aref localname (1- (length localname))) ?/)
2384               (not (string= path "/")))               (not (string= localname "/")))
2385          (substring directory 0 -1)          (substring directory 0 -1)
2386        directory)))        directory)))
2387    
# Line 2395  if the remote host can't provide the mod Line 2395  if the remote host can't provide the mod
2395        (save-excursion        (save-excursion
2396          (tramp-barf-unless-okay          (tramp-barf-unless-okay
2397           multi-method method user host           multi-method method user host
2398           (concat "cd " (tramp-shell-quote-argument path))           (concat "cd " (tramp-shell-quote-argument localname))
2399           nil           nil
2400           'file-error           'file-error
2401           "tramp-handle-directory-files: couldn't `cd %s'"           "tramp-handle-directory-files: couldn't `cd %s'"
2402           (tramp-shell-quote-argument path))           (tramp-shell-quote-argument localname))
2403          (tramp-send-command          (tramp-send-command
2404           multi-method method user host           multi-method method user host
2405           (concat (tramp-get-ls-command multi-method method user host)           (concat (tramp-get-ls-command multi-method method user host)
# Line 2451  if the remote host can't provide the mod Line 2451  if the remote host can't provide the mod
2451          (save-excursion          (save-excursion
2452            (tramp-barf-unless-okay            (tramp-barf-unless-okay
2453             multi-method method user host             multi-method method user host
2454             (format "cd %s" (tramp-shell-quote-argument path))             (format "cd %s" (tramp-shell-quote-argument localname))
2455             nil 'file-error             nil 'file-error
2456             "tramp-handle-file-name-all-completions: Couldn't `cd %s'"             "tramp-handle-file-name-all-completions: Couldn't `cd %s'"
2457             (tramp-shell-quote-argument path))             (tramp-shell-quote-argument localname))
2458    
2459            ;; Get a list of directories and files, including reliably            ;; Get a list of directories and files, including reliably
2460            ;; tagging the directories with a trailing '/'.  Because I            ;; tagging the directories with a trailing '/'.  Because I
# Line 2526  if the remote host can't provide the mod Line 2526  if the remote host can't provide the mod
2526            (error "add-name-to-file: file %s already exists" newname))            (error "add-name-to-file: file %s already exists" newname))
2527          (tramp-barf-unless-okay          (tramp-barf-unless-okay
2528           v1-multi-method v1-method v1-user v1-host           v1-multi-method v1-method v1-user v1-host
2529           (format "%s %s %s" ln (tramp-shell-quote-argument v1-path)           (format "%s %s %s" ln (tramp-shell-quote-argument v1-localname)
2530                   (tramp-shell-quote-argument v2-path))                   (tramp-shell-quote-argument v2-localname))
2531           nil 'file-error           nil 'file-error
2532           "error with add-name-to-file, see buffer `%s' for details"           "error with add-name-to-file, see buffer `%s' for details"
2533           (buffer-name))))))           (buffer-name))))))
# Line 2600  and `rename'.  FILENAME and NEWNAME must Line 2600  and `rename'.  FILENAME and NEWNAME must
2600                ;; directly.                ;; directly.
2601                (tramp-do-copy-or-rename-file-directly                (tramp-do-copy-or-rename-file-directly
2602                 op v1-multi-method v1-method v1-user v1-host                 op v1-multi-method v1-method v1-user v1-host
2603                 v1-path v2-path keep-date)                 v1-localname v2-localname keep-date)
2604              ;; The shortcut was not possible.  So we copy the              ;; The shortcut was not possible.  So we copy the
2605              ;; file first.  If the operation was `rename', we go              ;; file first.  If the operation was `rename', we go
2606              ;; back and delete the original file (if the copy was              ;; back and delete the original file (if the copy was
# Line 2646  KEEP-DATE is non-nil if NEWNAME should h Line 2646  KEEP-DATE is non-nil if NEWNAME should h
2646        (delete-file filename))))        (delete-file filename))))
2647    
2648  (defun tramp-do-copy-or-rename-file-directly  (defun tramp-do-copy-or-rename-file-directly
2649    (op multi-method method user host path1 path2 keep-date)    (op multi-method method user host localname1 localname2 keep-date)
2650    "Invokes `cp' or `mv' on the remote system.    "Invokes `cp' or `mv' on the remote system.
2651  OP must be one of `copy' or `rename', indicating `cp' or `mv',  OP must be one of `copy' or `rename', indicating `cp' or `mv',
2652  respectively.  METHOD, USER, and HOST specify the connection.  respectively.  METHOD, USER, and HOST specify the connection.
2653  PATH1 and PATH2 specify the two arguments of `cp' or `mv'.  LOCALNAME1 and LOCALNAME2 specify the two arguments of `cp' or `mv'.
2654  If KEEP-DATE is non-nil, preserve the time stamp when copying."  If KEEP-DATE is non-nil, preserve the time stamp when copying."
2655    ;; CCC: What happens to the timestamp when renaming?    ;; CCC: What happens to the timestamp when renaming?
2656    (let ((cmd (cond ((and (eq op 'copy) keep-date) "cp -f -p")    (let ((cmd (cond ((and (eq op 'copy) keep-date) "cp -f -p")
# Line 2664  If KEEP-DATE is non-nil, preserve the ti Line 2664  If KEEP-DATE is non-nil, preserve the ti
2664         multi-method method user host         multi-method method user host
2665         (format "%s %s %s"         (format "%s %s %s"
2666                 cmd                 cmd
2667                 (tramp-shell-quote-argument path1)                 (tramp-shell-quote-argument localname1)
2668                 (tramp-shell-quote-argument path2))                 (tramp-shell-quote-argument localname2))
2669         nil 'file-error         nil 'file-error
2670         "Copying directly failed, see buffer `%s' for details."         "Copying directly failed, see buffer `%s' for details."
2671         (buffer-name)))))         (buffer-name)))))
# Line 2688  be a local filename.  The method used mu Line 2688  be a local filename.  The method used mu
2688         multi-method method user host         multi-method method user host
2689         (format " %s %s"         (format " %s %s"
2690                 (if parents "mkdir -p" "mkdir")                 (if parents "mkdir -p" "mkdir")
2691                 (tramp-shell-quote-argument path))                 (tramp-shell-quote-argument localname))
2692         nil 'file-error         nil 'file-error
2693         "Couldn't make directory %s" dir))))         "Couldn't make directory %s" dir))))
2694    
# Line 2701  be a local filename.  The method used mu Line 2701  be a local filename.  The method used mu
2701        (tramp-send-command        (tramp-send-command
2702         multi-method method user host         multi-method method user host
2703         (format "rmdir %s ; echo ok"         (format "rmdir %s ; echo ok"
2704                 (tramp-shell-quote-argument path)))                 (tramp-shell-quote-argument localname)))
2705        (tramp-wait-for-output))))        (tramp-wait-for-output))))
2706    
2707  (defun tramp-handle-delete-file (filename)  (defun tramp-handle-delete-file (filename)
# Line 2712  be a local filename.  The method used mu Line 2712  be a local filename.  The method used mu
2712        (unless (zerop (tramp-send-command-and-check        (unless (zerop (tramp-send-command-and-check
2713                        multi-method method user host                        multi-method method user host
2714                        (format "rm -f %s"                        (format "rm -f %s"
2715                                (tramp-shell-quote-argument path))))                                (tramp-shell-quote-argument localname))))
2716          (signal 'file-error "Couldn't delete Tramp file")))))          (signal 'file-error "Couldn't delete Tramp file")))))
2717    
2718  ;; Dired.  ;; Dired.
# Line 2723  be a local filename.  The method used mu Line 2723  be a local filename.  The method used mu
2723    "Recursively delete the directory given.    "Recursively delete the directory given.
2724  This is like `dired-recursive-delete-directory' for tramp files."  This is like `dired-recursive-delete-directory' for tramp files."
2725    (with-parsed-tramp-file-name filename nil    (with-parsed-tramp-file-name filename nil
2726      ;; run a shell command 'rm -r <path>'      ;; run a shell command 'rm -r <localname>'
2727      ;; Code shamelessly stolen for the dired implementation and, um, hacked :)      ;; Code shamelessly stolen for the dired implementation and, um, hacked :)
2728      (or (tramp-handle-file-exists-p filename)      (or (tramp-handle-file-exists-p filename)
2729          (signal          (signal
# Line 2731  This is like `dired-recursive-delete-dir Line 2731  This is like `dired-recursive-delete-dir
2731           (list "Removing old file name" "no such directory" filename)))           (list "Removing old file name" "no such directory" filename)))
2732      ;; Which is better, -r or -R? (-r works for me <daniel@danann.net>)      ;; Which is better, -r or -R? (-r works for me <daniel@danann.net>)
2733      (tramp-send-command multi-method method user host      (tramp-send-command multi-method method user host
2734                          (format "rm -r %s" (tramp-shell-quote-argument path)))                          (format "rm -r %s" (tramp-shell-quote-argument localname)))
2735      ;; Wait for the remote system to return to us...      ;; Wait for the remote system to return to us...
2736      ;; This might take a while, allow it plenty of time.      ;; This might take a while, allow it plenty of time.
2737      (tramp-wait-for-output 120)      (tramp-wait-for-output 120)
# Line 2746  This is like `dired-recursive-delete-dir Line 2746  This is like `dired-recursive-delete-dir
2746      (save-excursion      (save-excursion
2747        (tramp-barf-unless-okay        (tramp-barf-unless-okay
2748         multi-method method user host         multi-method method user host
2749         (format "cd %s" (tramp-shell-quote-argument path))         (format "cd %s" (tramp-shell-quote-argument localname))
2750         nil 'file-error         nil 'file-error
2751         "tramp-handle-dired-call-process: Couldn't `cd %s'"         "tramp-handle-dired-call-process: Couldn't `cd %s'"
2752         (tramp-shell-quote-argument path))         (tramp-shell-quote-argument localname))
2753        (tramp-send-command        (tramp-send-command
2754         multi-method method user host         multi-method method user host
2755         (mapconcat #'tramp-shell-quote-argument (cons program arguments) " "))         (mapconcat #'tramp-shell-quote-argument (cons program arguments) " "))
# Line 2791  This is like `dired-recursive-delete-dir Line 2791  This is like `dired-recursive-delete-dir
2791       switches filename (if wildcard "yes" "no")       switches filename (if wildcard "yes" "no")
2792       (if full-directory-p "yes" "no"))       (if full-directory-p "yes" "no"))
2793      (when wildcard      (when wildcard
2794        (setq wildcard (file-name-nondirectory path))        (setq wildcard (file-name-nondirectory localname))
2795        (setq path (file-name-directory path)))        (setq localname (file-name-directory localname)))
2796      (when (listp switches)      (when (listp switches)
2797        (setq switches (mapconcat 'identity switches " ")))        (setq switches (mapconcat 'identity switches " ")))
2798      (unless full-directory-p      (unless full-directory-p
# Line 2809  This is like `dired-recursive-delete-dir Line 2809  This is like `dired-recursive-delete-dir
2809                     (tramp-get-ls-command multi-method method user host)                     (tramp-get-ls-command multi-method method user host)
2810                     switches                     switches
2811                     (if wildcard                     (if wildcard
2812                         path                         localname
2813                       (tramp-shell-quote-argument (concat path ".")))))                       (tramp-shell-quote-argument (concat localname ".")))))
2814          (tramp-barf-unless-okay          (tramp-barf-unless-okay
2815           multi-method method user host           multi-method method user host
2816           (format "cd %s" (tramp-shell-quote-argument           (format "cd %s" (tramp-shell-quote-argument
2817                            (file-name-directory path)))                            (file-name-directory localname)))
2818           nil 'file-error           nil 'file-error
2819           "Couldn't `cd %s'"           "Couldn't `cd %s'"
2820           (tramp-shell-quote-argument (file-name-directory path)))           (tramp-shell-quote-argument (file-name-directory localname)))
2821          (tramp-send-command          (tramp-send-command
2822           multi-method method user host           multi-method method user host
2823           (format "%s %s %s"           (format "%s %s %s"
# Line 2827  This is like `dired-recursive-delete-dir Line 2827  This is like `dired-recursive-delete-dir
2827                       ;; Add "/." to make sure we got complete dir                       ;; Add "/." to make sure we got complete dir
2828                       ;; listing for symlinks, too.                       ;; listing for symlinks, too.
2829                       (concat (file-name-as-directory                       (concat (file-name-as-directory
2830                                (file-name-nondirectory path)) ".")                                (file-name-nondirectory localname)) ".")
2831                     (file-name-nondirectory path)))))                     (file-name-nondirectory localname)))))
2832        (sit-for 1)                       ;needed for rsh but not ssh?        (sit-for 1)                       ;needed for rsh but not ssh?
2833        (tramp-wait-for-output))        (tramp-wait-for-output))
2834      (let ((old-pos (point)))      (let ((old-pos (point)))
# Line 2893  Doesn't do anything if the NAME does not Line 2893  Doesn't do anything if the NAME does not
2893                                (list name nil))                                (list name nil))
2894      ;; Dissect NAME.      ;; Dissect NAME.
2895      (with-parsed-tramp-file-name name nil      (with-parsed-tramp-file-name name nil
2896        (unless (file-name-absolute-p path)        (unless (file-name-absolute-p localname)
2897          (setq path (concat "~/" path)))          (setq localname (concat "~/" localname)))
2898        (save-excursion        (save-excursion
2899          ;; Tilde expansion if necessary.  This needs a shell which          ;; Tilde expansion if necessary.  This needs a shell which
2900          ;; groks tilde expansion!  The function `tramp-find-shell' is          ;; groks tilde expansion!  The function `tramp-find-shell' is
2901          ;; supposed to find such a shell on the remote host.  Please          ;; supposed to find such a shell on the remote host.  Please
2902          ;; tell me about it when this doesn't work on your system.          ;; tell me about it when this doesn't work on your system.
2903          (when (string-match "\\`\\(~[^/]*\\)\\(.*\\)\\'" path)          (when (string-match "\\`\\(~[^/]*\\)\\(.*\\)\\'" localname)
2904            (let ((uname (match-string 1 path))            (let ((uname (match-string 1 localname))
2905                  (fname (match-string 2 path)))                  (fname (match-string 2 localname)))
2906              ;; CCC fanatic error checking?              ;; CCC fanatic error checking?
2907              (set-buffer (tramp-get-buffer multi-method method user host))              (set-buffer (tramp-get-buffer multi-method method user host))
2908              (erase-buffer)              (erase-buffer)
# Line 2913  Doesn't do anything if the NAME does not Line 2913  Doesn't do anything if the NAME does not
2913              (tramp-wait-for-output)              (tramp-wait-for-output)
2914              (goto-char (point-min))              (goto-char (point-min))
2915              (setq uname (buffer-substring (point) (tramp-line-end-position)))              (setq uname (buffer-substring (point) (tramp-line-end-position)))
2916              (setq path (concat uname fname))              (setq localname (concat uname fname))
2917              (erase-buffer)))              (erase-buffer)))
2918          ;; No tilde characters in file name, do normal          ;; No tilde characters in file name, do normal
2919          ;; expand-file-name (this does "/./" and "/../").  We bind          ;; expand-file-name (this does "/./" and "/../").  We bind
# Line 2923  Doesn't do anything if the NAME does not Line 2923  Doesn't do anything if the NAME does not
2923            (tramp-make-tramp-file-name            (tramp-make-tramp-file-name
2924             multi-method method user host             multi-method method user host
2925             (tramp-drop-volume-letter             (tramp-drop-volume-letter
2926              (tramp-run-real-handler 'expand-file-name (list path)))))))))              (tramp-run-real-handler 'expand-file-name (list localname)))))))))
2927    
2928  ;; Remote commands.  ;; Remote commands.
2929    
# Line 2941  This will break if COMMAND prints a newl Line 2941  This will break if COMMAND prints a newl
2941            (save-excursion            (save-excursion
2942              (tramp-barf-unless-okay              (tramp-barf-unless-okay
2943               multi-method method user host               multi-method method user host
2944               (format "cd %s" (tramp-shell-quote-argument path))               (format "cd %s" (tramp-shell-quote-argument localname))
2945               nil 'file-error               nil 'file-error
2946               "tramp-handle-shell-command: Couldn't `cd %s'"               "tramp-handle-shell-command: Couldn't `cd %s'"
2947               (tramp-shell-quote-argument path))               (tramp-shell-quote-argument localname))
2948              (tramp-send-command multi-method method user host              (tramp-send-command multi-method method user host
2949                                  (concat command "; tramp_old_status=$?"))                                  (concat command "; tramp_old_status=$?"))
2950              ;; This will break if the shell command prints "/////"              ;; This will break if the shell command prints "/////"
# Line 3031  This will break if COMMAND prints a newl Line 3031  This will break if COMMAND prints a newl
3031                                       (list                                       (list
3032                                        (tramp-make-rcp-program-file-name                                        (tramp-make-rcp-program-file-name
3033                                         user host                                         user host
3034                                         (tramp-shell-quote-argument path))                                         (tramp-shell-quote-argument localname))
3035                                        tmpfil))))                                        tmpfil))))
3036                 (pop-to-buffer output-buf)                 (pop-to-buffer output-buf)
3037                 (error                 (error
# Line 3050  This will break if COMMAND prints a newl Line 3050  This will break if COMMAND prints a newl
3050                 (tramp-message 5 "Encoding remote file %s..." filename)                 (tramp-message 5 "Encoding remote file %s..." filename)
3051                 (tramp-barf-unless-okay                 (tramp-barf-unless-okay
3052                  multi-method method user host                  multi-method method user host
3053                  (concat rem-enc " < " (tramp-shell-quote-argument path))                  (concat rem-enc " < " (tramp-shell-quote-argument localname))
3054                  nil 'file-error                  nil 'file-error
3055                  "Encoding remote file failed, see buffer `%s' for details"                  "Encoding remote file failed, see buffer `%s' for details"
3056                  tramp-buf)                  tramp-buf)
# Line 3209  This will break if COMMAND prints a newl Line 3209  This will break if COMMAND prints a newl
3209                                    tmpfil                                    tmpfil
3210                                    (tramp-make-rcp-program-file-name                                    (tramp-make-rcp-program-file-name
3211                                     user host                                     user host
3212                                     (tramp-shell-quote-argument path))))))                                     (tramp-shell-quote-argument localname))))))
3213                 (tramp-message-for-buffer                 (tramp-message-for-buffer
3214                  multi-method method user host                  multi-method method user host
3215                  6 "Writing tmp file using `%s'..." rcp-program)                  6 "Writing tmp file using `%s'..." rcp-program)
# Line 3283  This will break if COMMAND prints a newl Line 3283  This will break if COMMAND prints a newl
3283                    multi-method method user host                    multi-method method user host
3284                    (format "%s >%s <<'EOF'"                    (format "%s >%s <<'EOF'"
3285                            rem-dec                            rem-dec
3286                            (tramp-shell-quote-argument path)))                            (tramp-shell-quote-argument localname)))
3287                   (set-buffer tmpbuf)                   (set-buffer tmpbuf)
3288                   (tramp-message-for-buffer                   (tramp-message-for-buffer
3289                    multi-method method user host                    multi-method method user host
# Line 3329  This will break if COMMAND prints a newl Line 3329  This will break if COMMAND prints a newl
3329          (message "Wrote %s" filename)))))          (message "Wrote %s" filename)))))
3330    
3331  ;; Call down to the real handler.  ;; Call down to the real handler.
3332  ;; Because EFS does not play nicely with TRAMP (both systems match an  ;; Because EFS does not play nicely with TRAMP (both systems match a
3333  ;; TRAMP path) it is needed to disable efs as well as tramp for the  ;; TRAMP file name) it is needed to disable efs as well as tramp for the
3334  ;; operation.  ;; operation.
3335  ;;  ;;
3336  ;; Other than that, this is the canon file-handler code that the doco  ;; Other than that, this is the canon file-handler code that the doco
3337  ;; says should be used here. Which is nice.  ;; says should be used here. Which is nice.
3338  ;;  ;;
3339  ;; Under XEmacs current, EFS also hooks in as  ;; Under XEmacs current, EFS also hooks in as
3340  ;; efs-sifn-handler-function to handle any path with environment  ;; efs-sifn-handler-function to handle any filename with environment
3341  ;; variables. This has two implications:  ;; variables. This has two implications:
3342  ;; 1) That EFS may not be completely dead (yet) for TRAMP paths  ;; 1) That EFS may not be completely dead (yet) for TRAMP filenames
3343  ;; 2) That TRAMP might want to do the same thing.  ;; 2) That TRAMP might want to do the same thing.
3344  ;; Details as they come in.  ;; Details as they come in.
3345  ;;  ;;
# Line 3543  necessary anymore." Line 3543  necessary anymore."
3543                ;;-                       '(?\* ?\? ?[ ?]))))                ;;-                       '(?\* ?\? ?[ ?]))))
3544                ;;-  (tramp-send-command                ;;-  (tramp-send-command
3545                ;;-   multi-method method user host                ;;-   multi-method method user host
3546                ;;-   (format "echo %s" (comint-quote-filename path)))                ;;-   (format "echo %s" (comint-quote-filename localname)))
3547                ;;-  (tramp-wait-for-output))                ;;-  (tramp-wait-for-output))
3548                (tramp-send-command multi-method method user host                (tramp-send-command multi-method method user host
3549                                    (format "echo %s" path))                                    (format "echo %s" localname))
3550                (tramp-wait-for-output)                (tramp-wait-for-output)
3551                (setq bufstr (buffer-substring (point-min)                (setq bufstr (buffer-substring (point-min)
3552                                               (tramp-line-end-position)))                                               (tramp-line-end-position)))
3553                (goto-char (point-min))                (goto-char (point-min))
3554                (if (string-equal path bufstr)                (if (string-equal localname bufstr)
3555                    nil                    nil
3556                  (insert "(\"")                  (insert "(\"")
3557                  (while (search-forward " " nil t)                  (while (search-forward " " nil t)
# Line 3624  necessary anymore." Line 3624  necessary anymore."
3624      (tramp-completion-run-real-handler      (tramp-completion-run-real-handler
3625       'file-exists-p (list filename))))       'file-exists-p (list filename))))
3626    
3627  ;; Path manipulation in case of partial TRAMP file names.  ;; Localname manipulation in case of partial TRAMP file names.
3628  (defun tramp-completion-handle-file-name-directory (file)  (defun tramp-completion-handle-file-name-directory (file)
3629    "Like `file-name-directory' but aware of TRAMP files."    "Like `file-name-directory' but aware of TRAMP files."
3630    (if (tramp-completion-mode file)    (if (tramp-completion-mode file)
# Line 3632  necessary anymore." Line 3632  necessary anymore."
3632      (tramp-completion-run-real-handler      (tramp-completion-run-real-handler
3633       'file-name-directory (list file))))       'file-name-directory (list file))))
3634    
3635  ;; Path manipulation in case of partial TRAMP file names.  ;; Localname manipulation in case of partial TRAMP file names.
3636  (defun tramp-completion-handle-file-name-nondirectory (file)  (defun tramp-completion-handle-file-name-nondirectory (file)
3637    "Like `file-name-nondirectory' but aware of TRAMP files."    "Like `file-name-nondirectory' but aware of TRAMP files."
3638    (substring    (substring
# Line 3662  necessary anymore." Line 3662  necessary anymore."
3662               (method (tramp-file-name-method car))               (method (tramp-file-name-method car))
3663               (user (tramp-file-name-user car))               (user (tramp-file-name-user car))
3664               (host (tramp-file-name-host car))               (host (tramp-file-name-host car))
3665               (path (tramp-file-name-path car))               (localname (tramp-file-name-localname car))
3666               (m (tramp-find-method multi-method method user host))               (m (tramp-find-method multi-method method user host))
3667               (tramp-current-user user) ; see `tramp-parse-passwd'               (tramp-current-user user) ; see `tramp-parse-passwd'
3668               all-user-hosts)               all-user-hosts)
3669    
3670          (unless (or multi-method ;; Not handled (yet).          (unless (or multi-method ;; Not handled (yet).
3671                      path)        ;; Nothing to complete                      localname)        ;; Nothing to complete
3672    
3673            (if (or user host)            (if (or user host)
3674    
# Line 3712  necessary anymore." Line 3712  necessary anymore."
3712  ;; I misuse a little bit the tramp-file-name structure in order to handle  ;; I misuse a little bit the tramp-file-name structure in order to handle
3713  ;; completion possibilities for partial methods / user names / host names.  ;; completion possibilities for partial methods / user names / host names.
3714  ;; Return value is a list of tramp-file-name structures according to possible  ;; Return value is a list of tramp-file-name structures according to possible
3715  ;; completions. If "multi-method" or "path" is non-nil it means there  ;; completions. If "multi-method" or "localname" is non-nil it means there
3716  ;; shouldn't be a completion anymore.  ;; shouldn't be a completion anymore.
3717    
3718  ;; Expected results:  ;; Expected results:
# Line 3794  They are collected by `tramp-completion- Line 3794  They are collected by `tramp-completion-
3794  (defun tramp-completion-dissect-file-name1 (structure name)  (defun tramp-completion-dissect-file-name1 (structure name)
3795    "Returns a `tramp-file-name' structure matching STRUCTURE.    "Returns a `tramp-file-name' structure matching STRUCTURE.
3796  The structure consists of multi-method, remote method, remote user,  The structure consists of multi-method, remote method, remote user,
3797  remote host and remote path name."  remote host and localname (filename on remote host)."
3798    
3799    (let (method)    (let (method)
3800      (save-match-data      (save-match-data
# Line 3808  remote host and remote path name." Line 3808  remote host and remote path name."
3808               :method nil               :method nil
3809               :user nil               :user nil
3810               :host nil               :host nil
3811               :path nil)               :localname nil)
3812            (let ((user   (and (nth 2 structure)            (let ((user   (and (nth 2 structure)
3813                               (match-string (nth 2 structure) name)))                               (match-string (nth 2 structure) name)))
3814                  (host   (and (nth 3 structure)                  (host   (and (nth 3 structure)
3815                               (match-string (nth 3 structure) name)))                               (match-string (nth 3 structure) name)))
3816                  (path   (and (nth 4 structure)                  (localname   (and (nth 4 structure)
3817                               (match-string (nth 4 structure) name))))                               (match-string (nth 4 structure) name))))
3818              (make-tramp-file-name              (make-tramp-file-name
3819               :multi-method nil               :multi-method nil
3820               :method method               :method method
3821               :user user               :user user
3822               :host host               :host host
3823               :path path)))))))               :localname localname)))))))
3824    
3825  ;; This function returns all possible method completions, adding the  ;; This function returns all possible method completions, adding the
3826  ;; trailing method delimeter.  ;; trailing method delimeter.
# Line 4083  Returns the exit code of the `test' prog Line 4083  Returns the exit code of the `test' prog
4083         (tramp-file-name-multi-method v) (tramp-file-name-method v)         (tramp-file-name-multi-method v) (tramp-file-name-method v)
4084         (tramp-file-name-user v) (tramp-file-name-host v)         (tramp-file-name-user v) (tramp-file-name-host v)
4085         (format "test %s %s" switch         (format "test %s %s" switch
4086                 (tramp-shell-quote-argument (tramp-file-name-path v)))))))                 (tramp-shell-quote-argument (tramp-file-name-localname v)))))))
4087    
4088  (defun tramp-run-test2 (program file1 file2 &optional switch)  (defun tramp-run-test2 (program file1 file2 &optional switch)
4089    "Run `test'-like PROGRAM on the remote system, given FILE1, FILE2.    "Run `test'-like PROGRAM on the remote system, given FILE1, FILE2.
# Line 4100  hosts, or files, disagree." Line 4100  hosts, or files, disagree."
4100           (user2 (tramp-file-name-user v2))           (user2 (tramp-file-name-user v2))
4101           (host1 (tramp-file-name-host v1))           (host1 (tramp-file-name-host v1))
4102           (host2 (tramp-file-name-host v2))           (host2 (tramp-file-name-host v2))
4103           (path1 (tramp-file-name-path v1))           (localname1 (tramp-file-name-localname v1))
4104           (path2 (tramp-file-name-path v2)))           (localname2 (tramp-file-name-localname v2)))
4105      (unless (and method1 method2 host1 host2      (unless (and method1 method2 host1 host2
4106                   (equal mmethod1 mmethod2)                   (equal mmethod1 mmethod2)
4107                   (equal method1 method2)                   (equal method1 method2)
# Line 4114  hosts, or files, disagree." Line 4114  hosts, or files, disagree."
4114         mmethod1 method1 user1 host1         mmethod1 method1 user1 host1
4115         (format "%s %s %s %s"         (format "%s %s %s %s"
4116                 program                 program
4117                 (tramp-shell-quote-argument path1)                 (tramp-shell-quote-argument localname1)
4118                 (or switch "")                 (or switch "")
4119                 (tramp-shell-quote-argument path2))))))                 (tramp-shell-quote-argument localname2))))))
4120    
4121  (defun tramp-buffer-name (multi-method method user host)  (defun tramp-buffer-name (multi-method method user host)
4122    "A name for the connection buffer for USER at HOST using METHOD."    "A name for the connection buffer for USER at HOST using METHOD."
# Line 4175  is the program to search for, and DIRLIS Line 4175  is the program to search for, and DIRLIS
4175  to search.  If IGNORE-TILDE is non-nil, directory names starting  to search.  If IGNORE-TILDE is non-nil, directory names starting
4176  with `~' will be ignored.  with `~' will be ignored.
4177    
4178  Returns the full path name of PROGNAME, if found, and nil otherwise.  Returns the absolute file name of PROGNAME, if found, and nil otherwise.
4179    
4180  This function expects to be in the right *tramp* buffer."  This function expects to be in the right *tramp* buffer."
4181    (let (result)    (let (result)
# Line 4331  file exists and nonzero exit status othe Line 4331  file exists and nonzero exit status othe
4331    
4332  (defun tramp-check-ls-command (multi-method method user host cmd)  (defun tramp-check-ls-command (multi-method method user host cmd)
4333    "Checks whether the given `ls' executable groks `-n'.    "Checks whether the given `ls' executable groks `-n'.
4334  METHOD, USER and HOST specify the connection, CMD (the full path name of)  METHOD, USER and HOST specify the connection, CMD (the absolute file name of)
4335  the `ls' executable.  Returns t if CMD supports the `-n' option, nil  the `ls' executable.  Returns t if CMD supports the `-n' option, nil
4336  otherwise."  otherwise."
4337    (tramp-message 9 "Checking remote `%s' command for `-n' option"    (tramp-message 9 "Checking remote `%s' command for `-n' option"
# Line 5827  Not actually used.  Use `(format \"%o\" Line 5827  Not actually used.  Use `(format \"%o\"
5827  ;; internal data structure.  Convenience functions for internal  ;; internal data structure.  Convenience functions for internal
5828  ;; data structure.  ;; data structure.
5829    
5830  (defstruct tramp-file-name multi-method method user host path)  (defstruct tramp-file-name multi-method method user host localname)
5831    
5832  (defun tramp-tramp-file-p (name)  (defun tramp-tramp-file-p (name)
5833    "Return t iff NAME is a tramp file."    "Return t iff NAME is a tramp file."
# Line 5840  Not actually used.  Use `(format \"%o\" Line 5840  Not actually used.  Use `(format \"%o\"
5840  (defun tramp-dissect-file-name (name)  (defun tramp-dissect-file-name (name)
5841    "Return an `tramp-file-name' structure.    "Return an `tramp-file-name' structure.
5842  The structure consists of remote method, remote user, remote host and  The structure consists of remote method, remote user, remote host and
5843  remote path name."  localname (file name on remote host)."
5844    (save-match-data    (save-match-data
5845      (let* ((match (string-match (nth 0 tramp-file-name-structure) name))      (let* ((match (string-match (nth 0 tramp-file-name-structure) name))
5846             (method             (method
# Line 5859  remote path name." Line 5859  remote path name."
5859          (unless match (error "Not a tramp file name: %s" name))          (unless match (error "Not a tramp file name: %s" name))
5860          (let ((user (match-string (nth 2 tramp-file-name-structure) name))          (let ((user (match-string (nth 2 tramp-file-name-structure) name))
5861                (host (match-string (nth 3 tramp-file-name-structure) name))                (host (match-string (nth 3 tramp-file-name-structure) name))
5862                (path (match-string (nth 4 tramp-file-name-structure) name)))                (localname (match-string (nth 4 tramp-file-name-structure) name)))
5863            (make-tramp-file-name            (make-tramp-file-name
5864             :multi-method nil             :multi-method nil
5865             :method method             :method method
5866             :user (or user nil)             :user (or user nil)
5867             :host host             :host host
5868             :path path))))))             :localname localname))))))
5869    
5870  (defun tramp-find-default-method (user host)  (defun tramp-find-default-method (user host)
5871    "Look up the right method to use in `tramp-default-method-alist'."    "Look up the right method to use in `tramp-default-method-alist'."
# Line 5894  If both MULTI-METHOD and METHOD are nil, Line 5894  If both MULTI-METHOD and METHOD are nil,
5894    (let ((regexp           (nth 0 tramp-multi-file-name-structure))    (let ((regexp           (nth 0 tramp-multi-file-name-structure))
5895          (method-index     (nth 1 tramp-multi-file-name-structure))          (method-index     (nth 1 tramp-multi-file-name-structure))
5896          (hops-index       (nth 2 tramp-multi-file-name-structure))          (hops-index       (nth 2 tramp-multi-file-name-structure))
5897          (path-index       (nth 3 tramp-multi-file-name-structure))          (localname-index       (nth 3 tramp-multi-file-name-structure))
5898          (hop-regexp       (nth 0 tramp-multi-file-name-hop-structure))          (hop-regexp       (nth 0 tramp-multi-file-name-hop-structure))
5899          (hop-method-index (nth 1 tramp-multi-file-name-hop-structure))          (hop-method-index (nth 1 tramp-multi-file-name-hop-structure))
5900          (hop-user-index   (nth 2 tramp-multi-file-name-hop-structure))          (hop-user-index   (nth 2 tramp-multi-file-name-hop-structure))
5901          (hop-host-index   (nth 3 tramp-multi-file-name-hop-structure))          (hop-host-index   (nth 3 tramp-multi-file-name-hop-structure))
5902          method hops len hop-methods hop-users hop-hosts path)          method hops len hop-methods hop-users hop-hosts localname)
5903      (unless (string-match (format regexp hop-regexp) name)      (unless (string-match (format regexp hop-regexp) name)
5904        (error "Not a multi tramp file name: %s" name))        (error "Not a multi tramp file name: %s" name))
5905      (setq method (match-string method-index name))      (setq method (match-string method-index name))
5906      (setq hops (match-string hops-index name))      (setq hops (match-string hops-index name))
5907      (setq len (/ (length (match-data t)) 2))      (setq len (/ (length (match-data t)) 2))
5908      (when (< path-index 0) (incf path-index len))      (when (< localname-index 0) (incf localname-index len))
5909      (setq path (match-string path-index name))      (setq localname (match-string localname-index name))
5910      (let ((index 0))      (let ((index 0))
5911        (while (string-match hop-regexp hops index)        (while (string-match hop-regexp hops index)
5912          (setq index (match-end 0))          (setq index (match-end 0))
# Line 5921  If both MULTI-METHOD and METHOD are nil, Line 5921  If both MULTI-METHOD and METHOD are nil,
5921       :method       (apply 'vector (reverse hop-methods))       :method       (apply 'vector (reverse hop-methods))
5922       :user         (apply 'vector (reverse hop-users))       :user         (apply 'vector (reverse hop-users))
5923       :host         (apply 'vector (reverse hop-hosts))       :host         (apply 'vector (reverse hop-hosts))
5924       :path         path)))       :localname         localname)))
5925    
5926  (defun tramp-make-tramp-file-name (multi-method method user host path)  (defun tramp-make-tramp-file-name (multi-method method user host localname)
5927    "Constructs a tramp file name from METHOD, USER, HOST and PATH."    "Constructs a tramp file name from METHOD, USER, HOST and LOCALNAME."
5928    (if multi-method    (if multi-method
5929        (tramp-make-tramp-multi-file-name multi-method method user host path)        (tramp-make-tramp-multi-file-name multi-method method user host localname)
5930      (format-spec      (format-spec
5931       (concat tramp-prefix-format       (concat tramp-prefix-format
5932        (when method (concat "%m" tramp-postfix-single-method-format))        (when method (concat "%m" tramp-postfix-single-method-format))
5933        (when user   (concat "%u" tramp-postfix-user-format))        (when user   (concat "%u" tramp-postfix-user-format))
5934        (when host   (concat "%h" tramp-postfix-host-format))        (when host   (concat "%h" tramp-postfix-host-format))
5935        (when path   (concat "%p")))        (when localname   (concat "%p")))
5936      `((?m . ,method) (?u . ,user) (?h . ,host) (?p . ,path)))))      `((?m . ,method) (?u . ,user) (?h . ,host) (?p . ,localname)))))
5937    
5938  ;; CCC: Henrik Holm: Not Changed.  Multi Method.  What should be done  ;; CCC: Henrik Holm: Not Changed.  Multi Method.  What should be done
5939  ;; with this when USER is nil?  ;; with this when USER is nil?
5940  (defun tramp-make-tramp-multi-file-name (multi-method method user host path)  (defun tramp-make-tramp-multi-file-name (multi-method method user host localname)
5941    "Constructs a tramp file name for a multi-hop method."    "Constructs a tramp file name for a multi-hop method."
5942    (unless tramp-make-multi-tramp-file-format    (unless tramp-make-multi-tramp-file-format
5943      (error "`tramp-make-multi-tramp-file-format' is nil"))      (error "`tramp-make-multi-tramp-file-format' is nil"))
5944    (let* ((prefix-format (nth 0 tramp-make-multi-tramp-file-format))    (let* ((prefix-format (nth 0 tramp-make-multi-tramp-file-format))
5945           (hop-format    (nth 1 tramp-make-multi-tramp-file-format))           (hop-format    (nth 1 tramp-make-multi-tramp-file-format))
5946           (path-format   (nth 2 tramp-make-multi-tramp-file-format))           (localname-format   (nth 2 tramp-make-multi-tramp-file-format))
5947           (prefix (format-spec prefix-format `((?m . ,multi-method))))           (prefix (format-spec prefix-format `((?m . ,multi-method))))
5948           (hops "")           (hops "")
5949           (path (format-spec path-format `((?p . ,path))))           (localname (format-spec localname-format `((?p . ,localname))))
5950           (i 0)           (i 0)
5951           (len (length method)))           (len (length method)))
5952      (while (< i len)      (while (< i len)
# Line 5954  If both MULTI-METHOD and METHOD are nil, Line 5954  If both MULTI-METHOD and METHOD are nil,
5954          (setq hops (concat hops (format-spec hop-format          (setq hops (concat hops (format-spec hop-format
5955                                               `((?m . ,m) (?u . ,u) (?h . ,h)))))                                               `((?m . ,m) (?u . ,u) (?h . ,h)))))
5956          (incf i)))          (incf i)))
5957      (concat prefix hops path)))      (concat prefix hops localname)))
5958    
5959  (defun tramp-make-rcp-program-file-name (user host path)  (defun tramp-make-rcp-program-file-name (user host localname)
5960    "Create a file name suitable to be passed to `rcp'."    "Create a file name suitable to be passed to `rcp'."
5961    (if user    (if user
5962        (format "%s@%s:%s" user host path)        (format "%s@%s:%s" user host localname)
5963      (format "%s:%s" host path)))      (format "%s:%s" host localname)))
5964    
5965  (defun tramp-method-out-of-band-p (multi-method method user host)  (defun tramp-method-out-of-band-p (multi-method method user host)
5966    "Return t if this is an out-of-band method, nil otherwise.    "Return t if this is an out-of-band method, nil otherwise.
# Line 6303  Only works for Bourne-like shells." Line 6303  Only works for Bourne-like shells."
6303    
6304  ;; ;; EFS hooks itself into the file name handling stuff in more places  ;; ;; EFS hooks itself into the file name handling stuff in more places
6305  ;; ;; than just `file-name-handler-alist'. The following tells EFS to stay  ;; ;; than just `file-name-handler-alist'. The following tells EFS to stay
6306  ;; ;; away from tramp.el paths.  ;; ;; away from tramp.el file names.
6307  ;; ;;  ;; ;;
6308  ;; ;; This is needed because EFS installs (efs-dired-before-readin) into  ;; ;; This is needed because EFS installs (efs-dired-before-readin) into
6309  ;; ;; 'dired-before-readin-hook'. This prevents EFS from opening an FTP  ;; ;; 'dired-before-readin-hook'. This prevents EFS from opening an FTP
# Line 6318  Only works for Bourne-like shells." Line 6318  Only works for Bourne-like shells."
6318  ;; ;; not to call defadvice unless it's necessary.  How do we find out whether  ;; ;; not to call defadvice unless it's necessary.  How do we find out whether
6319  ;; ;; it is necessary?  (featurep 'efs) is surely the wrong way --  ;; ;; it is necessary?  (featurep 'efs) is surely the wrong way --
6320  ;; ;; EFS might nicht be loaded yet.  ;; ;; EFS might nicht be loaded yet.
6321  ;; (defadvice efs-ftp-path (around dont-match-tramp-path activate protect)  ;; (defadvice efs-ftp-path (around dont-match-tramp-localname activate protect)
6322  ;;   "Cause efs-ftp-path to fail when the path is a TRAMP path."  ;;   "Cause efs-ftp-path to fail when the path is a TRAMP localname."
6323  ;;   (if (tramp-tramp-file-p (ad-get-arg 0))  ;;   (if (tramp-tramp-file-p (ad-get-arg 0))
6324  ;;       nil  ;;       nil
6325  ;;     ad-do-it))  ;;     ad-do-it))
# Line 6340  Only works for Bourne-like shells." Line 6340  Only works for Bourne-like shells."
6340          ;; If it's a Tramp file, dissect it and look if wildcards          ;; If it's a Tramp file, dissect it and look if wildcards
6341          ;; need to be expanded at all.          ;; need to be expanded at all.
6342          (let ((v (tramp-dissect-file-name name)))          (let ((v (tramp-dissect-file-name name)))
6343            (if (string-match "[[*?]" (tramp-file-name-path v))            (if (string-match "[[*?]" (tramp-file-name-localname v))
6344                (let ((res ad-do-it))                (let ((res ad-do-it))
6345                  (setq ad-return-value (or res (list name))))                  (setq ad-return-value (or res (list name))))
6346              (setq ad-return-value (list name))))              (setq ad-return-value (list name))))
# Line 6530  report. Line 6530  report.
6530  ;; * Make it work for different encodings, and for different file name  ;; * Make it work for different encodings, and for different file name
6531  ;;   encodings, too.  (Daniel Pittman)  ;;   encodings, too.  (Daniel Pittman)
6532  ;; * Change applicable functions to pass a struct tramp-file-name rather  ;; * Change applicable functions to pass a struct tramp-file-name rather
6533  ;;   than the individual items MULTI-METHOD, METHOD, USER, HOST, PATH.  ;;   than the individual items MULTI-METHOD, METHOD, USER, HOST, LOCALNAME.
6534  ;; * Implement asynchronous shell commands.  ;; * Implement asynchronous shell commands.
6535  ;; * Clean up unused *tramp/foo* buffers after a while.  (Pete Forman)  ;; * Clean up unused *tramp/foo* buffers after a while.  (Pete Forman)
6536  ;; * Progress reports while copying files.  (Michael Kifer)  ;; * Progress reports while copying files.  (Michael Kifer)

Legend:
Removed from v.2.278  
changed lines
  Added in v.2.279

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