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))) |
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, |
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. |
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 |
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 |
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 |
|
|
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 \ |
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 |
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 |
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 |
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)) |
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))) |
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) |
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." |
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 |
|
|
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")) |
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. |
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. |
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 |
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 |
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 |
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) |
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))))) |
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))))) |
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. |
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) |
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 |
|
|
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) |
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 |
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)))))) |
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 |
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") |
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))))) |
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 |
|
|
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) |
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. |
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 |
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) |
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) " ")) |
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 |
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" |
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))) |
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) |
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 |
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 |
|
|
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 "/////" |
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 |
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) |
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) |
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 |
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 |
;; |
;; |
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) |
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) |
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 |
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 |
|
|
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: |
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 |
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. |
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. |
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) |
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." |
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) |
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" |
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." |
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 |
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'." |
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)) |
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) |
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. |
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 |
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)) |
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)))) |
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) |