comparison lisp/net/tramp-sh.el @ 110762:d6e88106c5b8

Continue reorganization of load dependencies. (Bug#7156) * net/tramp.el (tramp-handle-file-local-copy-hook) (tramp-delete-temp-file-function): Move down. (tramp-exists-file-name-handler): Move up. (tramp-register-file-name-handlers): Simplify autoload. (tramp-handle-write-region-hook, tramp-handle-directory-file-name) (tramp-handle-directory-files, tramp-handle-dired-uncache) (tramp-handle-file-modes, tramp-handle-file-name-as-directory) (tramp-handle-file-name-completion) (tramp-handle-file-name-directory) (tramp-handle-file-name-nondirectory, tramp-handle-file-regular-p) (tramp-handle-file-remote-p, tramp-handle-file-symlink-p) (tramp-handle-find-backup-file-name) (tramp-handle-insert-file-contents, tramp-handle-load) (tramp-handle-substitute-in-file-name) (tramp-handle-unhandled-file-name-directory) (tramp-mode-string-to-int, tramp-local-host-p) (tramp-make-tramp-temp-file): Moved from tramp-sh.el. * net/tramp-gvfs.el (top): * net/tramp-smb.el (top): Do not require 'tramp-sh. * net/tramp-sh.el (all): Move several objects to tramp.el, see there. Rename `tramp-handle-*' to `tramp-sh-handle-*'.
author Michael Albinus <michael.albinus@gmx.de>
date Mon, 04 Oct 2010 21:44:08 +0200
parents 4e901a2d3669
children 073caec7510f
comparison
equal deleted inserted replaced
110761:d131be972bc8 110762:d6e88106c5b8
618 ;; Perl script to implement `file-attributes' in a Lisp `read'able 618 ;; Perl script to implement `file-attributes' in a Lisp `read'able
619 ;; output. If you are hacking on this, note that you get *no* output 619 ;; output. If you are hacking on this, note that you get *no* output
620 ;; unless this spits out a complete line, including the '\n' at the 620 ;; unless this spits out a complete line, including the '\n' at the
621 ;; end. 621 ;; end.
622 ;; The device number is returned as "-1", because there will be a virtual 622 ;; The device number is returned as "-1", because there will be a virtual
623 ;; device number set in `tramp-handle-file-attributes'. 623 ;; device number set in `tramp-sh-handle-file-attributes'.
624 (defconst tramp-perl-file-attributes 624 (defconst tramp-perl-file-attributes
625 "%s -e ' 625 "%s -e '
626 @stat = lstat($ARGV[0]); 626 @stat = lstat($ARGV[0]);
627 if (!@stat) { 627 if (!@stat) {
628 print \"nil\\n\"; 628 print \"nil\\n\";
865 ;; New handlers should be added here. The following operations can be 865 ;; New handlers should be added here. The following operations can be
866 ;; handled using the normal primitives: file-name-sans-versions, 866 ;; handled using the normal primitives: file-name-sans-versions,
867 ;; get-file-buffer. 867 ;; get-file-buffer.
868 (defconst tramp-sh-file-name-handler-alist 868 (defconst tramp-sh-file-name-handler-alist
869 '((load . tramp-handle-load) 869 '((load . tramp-handle-load)
870 (make-symbolic-link . tramp-handle-make-symbolic-link) 870 (make-symbolic-link . tramp-sh-handle-make-symbolic-link)
871 (file-name-as-directory . tramp-handle-file-name-as-directory) 871 (file-name-as-directory . tramp-handle-file-name-as-directory)
872 (file-name-directory . tramp-handle-file-name-directory) 872 (file-name-directory . tramp-handle-file-name-directory)
873 (file-name-nondirectory . tramp-handle-file-name-nondirectory) 873 (file-name-nondirectory . tramp-handle-file-name-nondirectory)
874 (file-truename . tramp-handle-file-truename) 874 (file-truename . tramp-sh-handle-file-truename)
875 (file-exists-p . tramp-handle-file-exists-p) 875 (file-exists-p . tramp-sh-handle-file-exists-p)
876 (file-directory-p . tramp-handle-file-directory-p) 876 (file-directory-p . tramp-sh-handle-file-directory-p)
877 (file-executable-p . tramp-handle-file-executable-p) 877 (file-executable-p . tramp-sh-handle-file-executable-p)
878 (file-readable-p . tramp-handle-file-readable-p) 878 (file-readable-p . tramp-sh-handle-file-readable-p)
879 (file-regular-p . tramp-handle-file-regular-p) 879 (file-regular-p . tramp-handle-file-regular-p)
880 (file-symlink-p . tramp-handle-file-symlink-p) 880 (file-symlink-p . tramp-handle-file-symlink-p)
881 (file-writable-p . tramp-handle-file-writable-p) 881 (file-writable-p . tramp-sh-handle-file-writable-p)
882 (file-ownership-preserved-p . tramp-handle-file-ownership-preserved-p) 882 (file-ownership-preserved-p . tramp-sh-handle-file-ownership-preserved-p)
883 (file-newer-than-file-p . tramp-handle-file-newer-than-file-p) 883 (file-newer-than-file-p . tramp-sh-handle-file-newer-than-file-p)
884 (file-attributes . tramp-handle-file-attributes) 884 (file-attributes . tramp-sh-handle-file-attributes)
885 (file-modes . tramp-handle-file-modes) 885 (file-modes . tramp-handle-file-modes)
886 (directory-files . tramp-handle-directory-files) 886 (directory-files . tramp-handle-directory-files)
887 (directory-files-and-attributes . tramp-handle-directory-files-and-attributes) 887 (directory-files-and-attributes
888 (file-name-all-completions . tramp-handle-file-name-all-completions) 888 . tramp-sh-handle-directory-files-and-attributes)
889 (file-name-all-completions . tramp-sh-handle-file-name-all-completions)
889 (file-name-completion . tramp-handle-file-name-completion) 890 (file-name-completion . tramp-handle-file-name-completion)
890 (add-name-to-file . tramp-handle-add-name-to-file) 891 (add-name-to-file . tramp-sh-handle-add-name-to-file)
891 (copy-file . tramp-handle-copy-file) 892 (copy-file . tramp-sh-handle-copy-file)
892 (copy-directory . tramp-handle-copy-directory) 893 (copy-directory . tramp-sh-handle-copy-directory)
893 (rename-file . tramp-handle-rename-file) 894 (rename-file . tramp-sh-handle-rename-file)
894 (set-file-modes . tramp-handle-set-file-modes) 895 (set-file-modes . tramp-sh-handle-set-file-modes)
895 (set-file-times . tramp-handle-set-file-times) 896 (set-file-times . tramp-sh-handle-set-file-times)
896 (make-directory . tramp-handle-make-directory) 897 (make-directory . tramp-sh-handle-make-directory)
897 (delete-directory . tramp-handle-delete-directory) 898 (delete-directory . tramp-sh-handle-delete-directory)
898 (delete-file . tramp-handle-delete-file) 899 (delete-file . tramp-sh-handle-delete-file)
899 (directory-file-name . tramp-handle-directory-file-name) 900 (directory-file-name . tramp-handle-directory-file-name)
900 ;; `executable-find' is not official yet. 901 ;; `executable-find' is not official yet.
901 (executable-find . tramp-handle-executable-find) 902 (executable-find . tramp-sh-handle-executable-find)
902 (start-file-process . tramp-handle-start-file-process) 903 (start-file-process . tramp-sh-handle-start-file-process)
903 (process-file . tramp-handle-process-file) 904 (process-file . tramp-sh-handle-process-file)
904 (shell-command . tramp-handle-shell-command) 905 (shell-command . tramp-sh-handle-shell-command)
905 (insert-directory . tramp-handle-insert-directory) 906 (insert-directory . tramp-sh-handle-insert-directory)
906 (expand-file-name . tramp-handle-expand-file-name) 907 (expand-file-name . tramp-sh-handle-expand-file-name)
907 (substitute-in-file-name . tramp-handle-substitute-in-file-name) 908 (substitute-in-file-name . tramp-handle-substitute-in-file-name)
908 (file-local-copy . tramp-handle-file-local-copy) 909 (file-local-copy . tramp-sh-handle-file-local-copy)
909 (file-remote-p . tramp-handle-file-remote-p) 910 (file-remote-p . tramp-handle-file-remote-p)
910 (insert-file-contents . tramp-handle-insert-file-contents) 911 (insert-file-contents . tramp-handle-insert-file-contents)
911 (insert-file-contents-literally 912 (insert-file-contents-literally
912 . tramp-handle-insert-file-contents-literally) 913 . tramp-sh-handle-insert-file-contents-literally)
913 (write-region . tramp-handle-write-region) 914 (write-region . tramp-sh-handle-write-region)
914 (find-backup-file-name . tramp-handle-find-backup-file-name) 915 (find-backup-file-name . tramp-sh-handle-find-backup-file-name)
915 (make-auto-save-file-name . tramp-handle-make-auto-save-file-name) 916 (make-auto-save-file-name . tramp-sh-handle-make-auto-save-file-name)
916 (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory) 917 (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
917 (dired-compress-file . tramp-handle-dired-compress-file) 918 (dired-compress-file . tramp-sh-handle-dired-compress-file)
918 (dired-recursive-delete-directory 919 (dired-recursive-delete-directory
919 . tramp-handle-dired-recursive-delete-directory) 920 . tramp-sh-handle-dired-recursive-delete-directory)
920 (dired-uncache . tramp-handle-dired-uncache) 921 (dired-uncache . tramp-handle-dired-uncache)
921 (set-visited-file-modtime . tramp-handle-set-visited-file-modtime) 922 (set-visited-file-modtime . tramp-sh-handle-set-visited-file-modtime)
922 (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime) 923 (verify-visited-file-modtime . tramp-sh-handle-verify-visited-file-modtime)
923 (file-selinux-context . tramp-handle-file-selinux-context) 924 (file-selinux-context . tramp-sh-handle-file-selinux-context)
924 (set-file-selinux-context . tramp-handle-set-file-selinux-context) 925 (set-file-selinux-context . tramp-sh-handle-set-file-selinux-context)
925 (vc-registered . tramp-handle-vc-registered)) 926 (vc-registered . tramp-sh-handle-vc-registered))
926 "Alist of handler functions. 927 "Alist of handler functions.
927 Operations not mentioned here will be handled by the normal Emacs functions.") 928 Operations not mentioned here will be handled by the normal Emacs functions.")
928 929
929 ;; This must be the last entry, because `identity' always matches. 930 ;; This must be the last entry, because `identity' always matches.
930 ;;;###tramp-autoload 931 ;;;###tramp-autoload
931 (add-to-list 'tramp-foreign-file-name-handler-alist 932 (add-to-list 'tramp-foreign-file-name-handler-alist
932 '(identity . tramp-sh-file-name-handler) 'append) 933 '(identity . tramp-sh-file-name-handler) 'append)
933 934
934 ;;; File Name Handler Functions: 935 ;;; File Name Handler Functions:
935 936
936 (defun tramp-handle-make-symbolic-link 937 (defun tramp-sh-handle-make-symbolic-link
937 (filename linkname &optional ok-if-already-exists) 938 (filename linkname &optional ok-if-already-exists)
938 "Like `make-symbolic-link' for Tramp files. 939 "Like `make-symbolic-link' for Tramp files.
939 If LINKNAME is a non-Tramp file, it is used verbatim as the target of 940 If LINKNAME is a non-Tramp file, it is used verbatim as the target of
940 the symlink. If LINKNAME is a Tramp file, only the localname component is 941 the symlink. If LINKNAME is a Tramp file, only the localname component is
941 used as the target of the symlink. 942 used as the target of the symlink.
986 ln 987 ln
987 (tramp-shell-quote-argument filename) 988 (tramp-shell-quote-argument filename)
988 (tramp-shell-quote-argument l-localname)) 989 (tramp-shell-quote-argument l-localname))
989 t)))) 990 t))))
990 991
991 (defun tramp-handle-load (file &optional noerror nomessage nosuffix must-suffix) 992 (defun tramp-sh-handle-file-truename (filename &optional counter prev-dirs)
992 "Like `load' for Tramp files."
993 (with-parsed-tramp-file-name (expand-file-name file) nil
994 (unless nosuffix
995 (cond ((file-exists-p (concat file ".elc"))
996 (setq file (concat file ".elc")))
997 ((file-exists-p (concat file ".el"))
998 (setq file (concat file ".el")))))
999 (when must-suffix
1000 ;; The first condition is always true for absolute file names.
1001 ;; Included for safety's sake.
1002 (unless (or (file-name-directory file)
1003 (string-match "\\.elc?\\'" file))
1004 (tramp-error
1005 v 'file-error
1006 "File `%s' does not include a `.el' or `.elc' suffix" file)))
1007 (unless noerror
1008 (when (not (file-exists-p file))
1009 (tramp-error v 'file-error "Cannot load nonexistent file `%s'" file)))
1010 (if (not (file-exists-p file))
1011 nil
1012 (let ((tramp-message-show-message (not nomessage)))
1013 (with-progress-reporter v 0 (format "Loading %s" file)
1014 (let ((local-copy (file-local-copy file)))
1015 ;; MUST-SUFFIX doesn't exist on XEmacs, so let it default to nil.
1016 (unwind-protect
1017 (load local-copy noerror t t)
1018 (delete-file local-copy)))))
1019 t)))
1020
1021 ;; Localname manipulation functions that grok Tramp localnames...
1022 (defun tramp-handle-file-name-as-directory (file)
1023 "Like `file-name-as-directory' but aware of Tramp files."
1024 ;; `file-name-as-directory' would be sufficient except localname is
1025 ;; the empty string.
1026 (let ((v (tramp-dissect-file-name file t)))
1027 ;; Run the command on the localname portion only.
1028 (tramp-make-tramp-file-name
1029 (tramp-file-name-method v)
1030 (tramp-file-name-user v)
1031 (tramp-file-name-host v)
1032 (tramp-run-real-handler
1033 'file-name-as-directory (list (or (tramp-file-name-localname v) ""))))))
1034
1035 (defun tramp-handle-file-name-directory (file)
1036 "Like `file-name-directory' but aware of Tramp files."
1037 ;; Everything except the last filename thing is the directory. We
1038 ;; cannot apply `with-parsed-tramp-file-name', because this expands
1039 ;; the remote file name parts. This is a problem when we are in
1040 ;; file name completion.
1041 (let ((v (tramp-dissect-file-name file t)))
1042 ;; Run the command on the localname portion only.
1043 (tramp-make-tramp-file-name
1044 (tramp-file-name-method v)
1045 (tramp-file-name-user v)
1046 (tramp-file-name-host v)
1047 (tramp-run-real-handler
1048 'file-name-directory (list (or (tramp-file-name-localname v) ""))))))
1049
1050 (defun tramp-handle-file-name-nondirectory (file)
1051 "Like `file-name-nondirectory' but aware of Tramp files."
1052 (with-parsed-tramp-file-name file nil
1053 (tramp-run-real-handler 'file-name-nondirectory (list localname))))
1054
1055 (defun tramp-handle-file-truename (filename &optional counter prev-dirs)
1056 "Like `file-truename' for Tramp files." 993 "Like `file-truename' for Tramp files."
1057 (with-parsed-tramp-file-name (expand-file-name filename) nil 994 (with-parsed-tramp-file-name (expand-file-name filename) nil
1058 (with-file-property v localname "file-truename" 995 (with-file-property v localname "file-truename"
1059 (let ((result nil)) ; result steps in reverse order 996 (let ((result nil)) ; result steps in reverse order
1060 (tramp-message v 4 "Finding true name for `%s'" filename) 997 (tramp-message v 4 "Finding true name for `%s'" filename)
1156 (tramp-message v 4 "True name of `%s' is `%s'" filename result) 1093 (tramp-message v 4 "True name of `%s' is `%s'" filename result)
1157 (tramp-make-tramp-file-name method user host result))))) 1094 (tramp-make-tramp-file-name method user host result)))))
1158 1095
1159 ;; Basic functions. 1096 ;; Basic functions.
1160 1097
1161 (defun tramp-handle-file-exists-p (filename) 1098 (defun tramp-sh-handle-file-exists-p (filename)
1162 "Like `file-exists-p' for Tramp files." 1099 "Like `file-exists-p' for Tramp files."
1163 (with-parsed-tramp-file-name filename nil 1100 (with-parsed-tramp-file-name filename nil
1164 (with-file-property v localname "file-exists-p" 1101 (with-file-property v localname "file-exists-p"
1165 (or (not (null (tramp-get-file-property 1102 (or (not (null (tramp-get-file-property
1166 v localname "file-attributes-integer" nil))) 1103 v localname "file-attributes-integer" nil)))
1174 (tramp-shell-quote-argument localname))))))) 1111 (tramp-shell-quote-argument localname)))))))
1175 1112
1176 ;; CCC: This should check for an error condition and signal failure 1113 ;; CCC: This should check for an error condition and signal failure
1177 ;; when something goes wrong. 1114 ;; when something goes wrong.
1178 ;; Daniel Pittman <daniel@danann.net> 1115 ;; Daniel Pittman <daniel@danann.net>
1179 (defun tramp-handle-file-attributes (filename &optional id-format) 1116 (defun tramp-sh-handle-file-attributes (filename &optional id-format)
1180 "Like `file-attributes' for Tramp files." 1117 "Like `file-attributes' for Tramp files."
1181 (unless id-format (setq id-format 'integer)) 1118 (unless id-format (setq id-format 'integer))
1182 ;; Don't modify `last-coding-system-used' by accident. 1119 ;; Don't modify `last-coding-system-used' by accident.
1183 (let ((last-coding-system-used last-coding-system-used)) 1120 (let ((last-coding-system-used last-coding-system-used))
1184 (with-parsed-tramp-file-name (expand-file-name filename) nil 1121 (with-parsed-tramp-file-name (expand-file-name filename) nil
1312 (tramp-get-remote-stat vec) 1249 (tramp-get-remote-stat vec)
1313 (if (eq id-format 'integer) "%u" "\"%U\"") 1250 (if (eq id-format 'integer) "%u" "\"%U\"")
1314 (if (eq id-format 'integer) "%g" "\"%G\"") 1251 (if (eq id-format 'integer) "%g" "\"%G\"")
1315 (tramp-shell-quote-argument localname)))) 1252 (tramp-shell-quote-argument localname))))
1316 1253
1317 (defun tramp-handle-set-visited-file-modtime (&optional time-list) 1254 (defun tramp-sh-handle-set-visited-file-modtime (&optional time-list)
1318 "Like `set-visited-file-modtime' for Tramp files." 1255 "Like `set-visited-file-modtime' for Tramp files."
1319 (unless (buffer-file-name) 1256 (unless (buffer-file-name)
1320 (error "Can't set-visited-file-modtime: buffer `%s' not visiting a file" 1257 (error "Can't set-visited-file-modtime: buffer `%s' not visiting a file"
1321 (buffer-name))) 1258 (buffer-name)))
1322 (if time-list 1259 (if time-list
1346 (when (boundp 'last-coding-system-used) 1283 (when (boundp 'last-coding-system-used)
1347 (set 'last-coding-system-used coding-system-used)) 1284 (set 'last-coding-system-used coding-system-used))
1348 nil))))) 1285 nil)))))
1349 1286
1350 ;; This function makes the same assumption as 1287 ;; This function makes the same assumption as
1351 ;; `tramp-handle-set-visited-file-modtime'. 1288 ;; `tramp-sh-handle-set-visited-file-modtime'.
1352 (defun tramp-handle-verify-visited-file-modtime (buf) 1289 (defun tramp-sh-handle-verify-visited-file-modtime (buf)
1353 "Like `verify-visited-file-modtime' for Tramp files. 1290 "Like `verify-visited-file-modtime' for Tramp files.
1354 At the time `verify-visited-file-modtime' calls this function, we 1291 At the time `verify-visited-file-modtime' calls this function, we
1355 already know that the buffer is visiting a file and that 1292 already know that the buffer is visiting a file and that
1356 `visited-file-modtime' does not return 0. Do not call this 1293 `visited-file-modtime' does not return 0. Do not call this
1357 function directly, unless those two cases are already taken care 1294 function directly, unless those two cases are already taken care
1399 v localname "visited-file-modtime-ild" ""))) 1336 v localname "visited-file-modtime-ild" "")))
1400 ;; If file does not exist, say it is not modified if and 1337 ;; If file does not exist, say it is not modified if and
1401 ;; only if that agrees with the buffer's record. 1338 ;; only if that agrees with the buffer's record.
1402 (t (equal mt '(-1 65535)))))))))) 1339 (t (equal mt '(-1 65535))))))))))
1403 1340
1404 (defun tramp-handle-set-file-modes (filename mode) 1341 (defun tramp-sh-handle-set-file-modes (filename mode)
1405 "Like `set-file-modes' for Tramp files." 1342 "Like `set-file-modes' for Tramp files."
1406 (with-parsed-tramp-file-name filename nil 1343 (with-parsed-tramp-file-name filename nil
1407 (tramp-flush-file-property v localname) 1344 (tramp-flush-file-property v localname)
1408 ;; FIXME: extract the proper text from chmod's stderr. 1345 ;; FIXME: extract the proper text from chmod's stderr.
1409 (tramp-barf-unless-okay 1346 (tramp-barf-unless-okay
1411 (format "chmod %s %s" 1348 (format "chmod %s %s"
1412 (tramp-compat-decimal-to-octal mode) 1349 (tramp-compat-decimal-to-octal mode)
1413 (tramp-shell-quote-argument localname)) 1350 (tramp-shell-quote-argument localname))
1414 "Error while changing file's mode %s" filename))) 1351 "Error while changing file's mode %s" filename)))
1415 1352
1416 (defun tramp-handle-set-file-times (filename &optional time) 1353 (defun tramp-sh-handle-set-file-times (filename &optional time)
1417 "Like `set-file-times' for Tramp files." 1354 "Like `set-file-times' for Tramp files."
1418 (if (file-remote-p filename) 1355 (if (file-remote-p filename)
1419 (with-parsed-tramp-file-name filename nil 1356 (with-parsed-tramp-file-name filename nil
1420 (tramp-flush-file-property v localname) 1357 (tramp-flush-file-property v localname)
1421 (let ((time (if (or (null time) (equal time '(0 0))) 1358 (let ((time (if (or (null time) (equal time '(0 0)))
1484 (string-equal 1421 (string-equal
1485 (tramp-send-command-and-read 1422 (tramp-send-command-and-read
1486 vec (format "echo \\\"`%S`\\\"" result)) 1423 vec (format "echo \\\"`%S`\\\"" result))
1487 "Enforcing"))))) 1424 "Enforcing")))))
1488 1425
1489 (defun tramp-handle-file-selinux-context (filename) 1426 (defun tramp-sh-handle-file-selinux-context (filename)
1490 "Like `file-selinux-context' for Tramp files." 1427 "Like `file-selinux-context' for Tramp files."
1491 (with-parsed-tramp-file-name filename nil 1428 (with-parsed-tramp-file-name filename nil
1492 (with-file-property v localname "file-selinux-context" 1429 (with-file-property v localname "file-selinux-context"
1493 (let ((context '(nil nil nil nil)) 1430 (let ((context '(nil nil nil nil))
1494 (regexp (concat "\\([a-z0-9_]+\\):" "\\([a-z0-9_]+\\):" 1431 (regexp (concat "\\([a-z0-9_]+\\):" "\\([a-z0-9_]+\\):"
1505 (setq context (list (match-string 1) (match-string 2) 1442 (setq context (list (match-string 1) (match-string 2)
1506 (match-string 3) (match-string 4)))))) 1443 (match-string 3) (match-string 4))))))
1507 ;; Return the context. 1444 ;; Return the context.
1508 context)))) 1445 context))))
1509 1446
1510 (defun tramp-handle-set-file-selinux-context (filename context) 1447 (defun tramp-sh-handle-set-file-selinux-context (filename context)
1511 "Like `set-file-selinux-context' for Tramp files." 1448 "Like `set-file-selinux-context' for Tramp files."
1512 (with-parsed-tramp-file-name filename nil 1449 (with-parsed-tramp-file-name filename nil
1513 (if (and (consp context) 1450 (if (and (consp context)
1514 (tramp-remote-selinux-p v) 1451 (tramp-remote-selinux-p v)
1515 (tramp-send-command-and-check 1452 (tramp-send-command-and-check
1528 ;; We always return nil. 1465 ;; We always return nil.
1529 nil) 1466 nil)
1530 1467
1531 ;; Simple functions using the `test' command. 1468 ;; Simple functions using the `test' command.
1532 1469
1533 (defun tramp-handle-file-executable-p (filename) 1470 (defun tramp-sh-handle-file-executable-p (filename)
1534 "Like `file-executable-p' for Tramp files." 1471 "Like `file-executable-p' for Tramp files."
1535 (with-parsed-tramp-file-name filename nil 1472 (with-parsed-tramp-file-name filename nil
1536 (with-file-property v localname "file-executable-p" 1473 (with-file-property v localname "file-executable-p"
1537 ;; Examine `file-attributes' cache to see if request can be 1474 ;; Examine `file-attributes' cache to see if request can be
1538 ;; satisfied without remote operation. 1475 ;; satisfied without remote operation.
1539 (or (tramp-check-cached-permissions v ?x) 1476 (or (tramp-check-cached-permissions v ?x)
1540 (tramp-run-test "-x" filename))))) 1477 (tramp-run-test "-x" filename)))))
1541 1478
1542 (defun tramp-handle-file-readable-p (filename) 1479 (defun tramp-sh-handle-file-readable-p (filename)
1543 "Like `file-readable-p' for Tramp files." 1480 "Like `file-readable-p' for Tramp files."
1544 (with-parsed-tramp-file-name filename nil 1481 (with-parsed-tramp-file-name filename nil
1545 (with-file-property v localname "file-readable-p" 1482 (with-file-property v localname "file-readable-p"
1546 ;; Examine `file-attributes' cache to see if request can be 1483 ;; Examine `file-attributes' cache to see if request can be
1547 ;; satisfied without remote operation. 1484 ;; satisfied without remote operation.
1551 ;; When the remote shell is started, it looks for a shell which groks 1488 ;; When the remote shell is started, it looks for a shell which groks
1552 ;; tilde expansion. Here, we assume that all shells which grok tilde 1489 ;; tilde expansion. Here, we assume that all shells which grok tilde
1553 ;; expansion will also provide a `test' command which groks `-nt' (for 1490 ;; expansion will also provide a `test' command which groks `-nt' (for
1554 ;; newer than). If this breaks, tell me about it and I'll try to do 1491 ;; newer than). If this breaks, tell me about it and I'll try to do
1555 ;; something smarter about it. 1492 ;; something smarter about it.
1556 (defun tramp-handle-file-newer-than-file-p (file1 file2) 1493 (defun tramp-sh-handle-file-newer-than-file-p (file1 file2)
1557 "Like `file-newer-than-file-p' for Tramp files." 1494 "Like `file-newer-than-file-p' for Tramp files."
1558 (cond ((not (file-exists-p file1)) 1495 (cond ((not (file-exists-p file1))
1559 nil) 1496 nil)
1560 ((not (file-exists-p file2)) 1497 ((not (file-exists-p file2))
1561 t) 1498 t)
1586 (tramp-run-test2 1523 (tramp-run-test2
1587 (tramp-get-test-nt-command v) file1 file2)))))))) 1524 (tramp-get-test-nt-command v) file1 file2))))))))
1588 1525
1589 ;; Functions implemented using the basic functions above. 1526 ;; Functions implemented using the basic functions above.
1590 1527
1591 (defun tramp-handle-file-modes (filename) 1528 (defun tramp-sh-handle-file-directory-p (filename)
1592 "Like `file-modes' for Tramp files."
1593 (let ((truename (or (file-truename filename) filename)))
1594 (when (file-exists-p truename)
1595 (tramp-mode-string-to-int (nth 8 (file-attributes truename))))))
1596
1597 (defun tramp-handle-file-directory-p (filename)
1598 "Like `file-directory-p' for Tramp files." 1529 "Like `file-directory-p' for Tramp files."
1599 ;; Care must be taken that this function returns `t' for symlinks 1530 ;; Care must be taken that this function returns `t' for symlinks
1600 ;; pointing to directories. Surely the most obvious implementation 1531 ;; pointing to directories. Surely the most obvious implementation
1601 ;; would be `test -d', but that returns false for such symlinks. 1532 ;; would be `test -d', but that returns false for such symlinks.
1602 ;; CCC: Stefan Monnier says that `test -d' follows symlinks. And 1533 ;; CCC: Stefan Monnier says that `test -d' follows symlinks. And
1606 ;; Alternatives: `cd %s', `test -d %s' 1537 ;; Alternatives: `cd %s', `test -d %s'
1607 (with-parsed-tramp-file-name filename nil 1538 (with-parsed-tramp-file-name filename nil
1608 (with-file-property v localname "file-directory-p" 1539 (with-file-property v localname "file-directory-p"
1609 (tramp-run-test "-d" filename)))) 1540 (tramp-run-test "-d" filename))))
1610 1541
1611 (defun tramp-handle-file-regular-p (filename) 1542 (defun tramp-sh-handle-file-writable-p (filename)
1612 "Like `file-regular-p' for Tramp files."
1613 (and (file-exists-p filename)
1614 (eq ?- (aref (nth 8 (file-attributes filename)) 0))))
1615
1616 (defun tramp-handle-file-symlink-p (filename)
1617 "Like `file-symlink-p' for Tramp files."
1618 (with-parsed-tramp-file-name filename nil
1619 (let ((x (car (file-attributes filename))))
1620 (when (stringp x)
1621 ;; When Tramp is running on VMS, then `file-name-absolute-p'
1622 ;; might do weird things.
1623 (if (file-name-absolute-p x)
1624 (tramp-make-tramp-file-name method user host x)
1625 x)))))
1626
1627 (defun tramp-handle-file-writable-p (filename)
1628 "Like `file-writable-p' for Tramp files." 1543 "Like `file-writable-p' for Tramp files."
1629 (with-parsed-tramp-file-name filename nil 1544 (with-parsed-tramp-file-name filename nil
1630 (with-file-property v localname "file-writable-p" 1545 (with-file-property v localname "file-writable-p"
1631 (if (file-exists-p filename) 1546 (if (file-exists-p filename)
1632 ;; Examine `file-attributes' cache to see if request can be 1547 ;; Examine `file-attributes' cache to see if request can be
1635 (tramp-run-test "-w" filename)) 1550 (tramp-run-test "-w" filename))
1636 ;; If file doesn't exist, check if directory is writable. 1551 ;; If file doesn't exist, check if directory is writable.
1637 (and (tramp-run-test "-d" (file-name-directory filename)) 1552 (and (tramp-run-test "-d" (file-name-directory filename))
1638 (tramp-run-test "-w" (file-name-directory filename))))))) 1553 (tramp-run-test "-w" (file-name-directory filename)))))))
1639 1554
1640 (defun tramp-handle-file-ownership-preserved-p (filename) 1555 (defun tramp-sh-handle-file-ownership-preserved-p (filename)
1641 "Like `file-ownership-preserved-p' for Tramp files." 1556 "Like `file-ownership-preserved-p' for Tramp files."
1642 (with-parsed-tramp-file-name filename nil 1557 (with-parsed-tramp-file-name filename nil
1643 (with-file-property v localname "file-ownership-preserved-p" 1558 (with-file-property v localname "file-ownership-preserved-p"
1644 (let ((attributes (file-attributes filename))) 1559 (let ((attributes (file-attributes filename)))
1645 ;; Return t if the file doesn't exist, since it's true that no 1560 ;; Return t if the file doesn't exist, since it's true that no
1646 ;; information would be lost by an (attempted) delete and create. 1561 ;; information would be lost by an (attempted) delete and create.
1647 (or (null attributes) 1562 (or (null attributes)
1648 (= (nth 2 attributes) (tramp-get-remote-uid v 'integer))))))) 1563 (= (nth 2 attributes) (tramp-get-remote-uid v 'integer)))))))
1649 1564
1650 ;; Other file name ops.
1651
1652 (defun tramp-handle-directory-file-name (directory)
1653 "Like `directory-file-name' for Tramp files."
1654 ;; If localname component of filename is "/", leave it unchanged.
1655 ;; Otherwise, remove any trailing slash from localname component.
1656 ;; Method, host, etc, are unchanged. Does it make sense to try
1657 ;; to avoid parsing the filename?
1658 (with-parsed-tramp-file-name directory nil
1659 (if (and (not (zerop (length localname)))
1660 (eq (aref localname (1- (length localname))) ?/)
1661 (not (string= localname "/")))
1662 (substring directory 0 -1)
1663 directory)))
1664
1665 ;; Directory listings. 1565 ;; Directory listings.
1666 1566
1667 (defun tramp-handle-directory-files 1567 (defun tramp-sh-handle-directory-files-and-attributes
1668 (directory &optional full match nosort files-only)
1669 "Like `directory-files' for Tramp files."
1670 ;; FILES-ONLY is valid for XEmacs only.
1671 (when (file-directory-p directory)
1672 (setq directory (file-name-as-directory (expand-file-name directory)))
1673 (let ((temp (nreverse (file-name-all-completions "" directory)))
1674 result item)
1675
1676 (while temp
1677 (setq item (directory-file-name (pop temp)))
1678 (when (and (or (null match) (string-match match item))
1679 (or (null files-only)
1680 ;; Files only.
1681 (and (equal files-only t) (file-regular-p item))
1682 ;; Directories only.
1683 (file-directory-p item)))
1684 (push (if full (concat directory item) item)
1685 result)))
1686 (if nosort result (sort result 'string<)))))
1687
1688 (defun tramp-handle-directory-files-and-attributes
1689 (directory &optional full match nosort id-format) 1568 (directory &optional full match nosort id-format)
1690 "Like `directory-files-and-attributes' for Tramp files." 1569 "Like `directory-files-and-attributes' for Tramp files."
1691 (unless id-format (setq id-format 'integer)) 1570 (unless id-format (setq id-format 'integer))
1692 (when (file-directory-p directory) 1571 (when (file-directory-p directory)
1693 (setq directory (expand-file-name directory)) 1572 (setq directory (expand-file-name directory))
1758 (if (eq id-format 'integer) "%u" "\"%U\"") 1637 (if (eq id-format 'integer) "%u" "\"%U\"")
1759 (if (eq id-format 'integer) "%g" "\"%G\"")))) 1638 (if (eq id-format 'integer) "%g" "\"%G\""))))
1760 1639
1761 ;; This function should return "foo/" for directories and "bar" for 1640 ;; This function should return "foo/" for directories and "bar" for
1762 ;; files. 1641 ;; files.
1763 (defun tramp-handle-file-name-all-completions (filename directory) 1642 (defun tramp-sh-handle-file-name-all-completions (filename directory)
1764 "Like `file-name-all-completions' for Tramp files." 1643 "Like `file-name-all-completions' for Tramp files."
1765 (unless (save-match-data (string-match "/" filename)) 1644 (unless (save-match-data (string-match "/" filename))
1766 (with-parsed-tramp-file-name (expand-file-name directory) nil 1645 (with-parsed-tramp-file-name (expand-file-name directory) nil
1767 1646
1768 (all-completions 1647 (all-completions
1864 ;; Grab error message from line before last line 1743 ;; Grab error message from line before last line
1865 ;; (it was put there by `cd 2>&1') 1744 ;; (it was put there by `cd 2>&1')
1866 (forward-line -1) 1745 (forward-line -1)
1867 (tramp-error 1746 (tramp-error
1868 v 'file-error 1747 v 'file-error
1869 "tramp-handle-file-name-all-completions: %s" 1748 "tramp-sh-handle-file-name-all-completions: %s"
1870 (buffer-substring 1749 (buffer-substring
1871 (point) (tramp-compat-line-end-position)))) 1750 (point) (tramp-compat-line-end-position))))
1872 ;; For peace of mind, if buffer doesn't end in `fail' 1751 ;; For peace of mind, if buffer doesn't end in `fail'
1873 ;; then it should end in `ok'. If neither are in the 1752 ;; then it should end in `ok'. If neither are in the
1874 ;; buffer something went seriously wrong on the remote 1753 ;; buffer something went seriously wrong on the remote
1875 ;; side. 1754 ;; side.
1876 (unless (looking-at "^ok$") 1755 (unless (looking-at "^ok$")
1877 (tramp-error 1756 (tramp-error
1878 v 'file-error 1757 v 'file-error
1879 "\ 1758 "\
1880 tramp-handle-file-name-all-completions: internal error accessing `%s': `%s'" 1759 tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'"
1881 (tramp-shell-quote-argument localname) (buffer-string)))) 1760 (tramp-shell-quote-argument localname) (buffer-string))))
1882 1761
1883 (while (zerop (forward-line -1)) 1762 (while (zerop (forward-line -1))
1884 (push (buffer-substring 1763 (push (buffer-substring
1885 (point) (tramp-compat-line-end-position)) 1764 (point) (tramp-compat-line-end-position))
1901 (tramp-set-file-property 1780 (tramp-set-file-property
1902 v (concat localname filename) 1781 v (concat localname filename)
1903 "file-name-all-completions" 1782 "file-name-all-completions"
1904 result)))))))) 1783 result))))))))
1905 1784
1906 (defun tramp-handle-file-name-completion
1907 (filename directory &optional predicate)
1908 "Like `file-name-completion' for Tramp files."
1909 (unless (tramp-tramp-file-p directory)
1910 (error
1911 "tramp-handle-file-name-completion invoked on non-tramp directory `%s'"
1912 directory))
1913 (try-completion
1914 filename
1915 (mapcar 'list (file-name-all-completions filename directory))
1916 (when predicate
1917 (lambda (x) (funcall predicate (expand-file-name (car x) directory))))))
1918
1919 ;; cp, mv and ln 1785 ;; cp, mv and ln
1920 1786
1921 (defun tramp-handle-add-name-to-file 1787 (defun tramp-sh-handle-add-name-to-file
1922 (filename newname &optional ok-if-already-exists) 1788 (filename newname &optional ok-if-already-exists)
1923 "Like `add-name-to-file' for Tramp files." 1789 "Like `add-name-to-file' for Tramp files."
1924 (unless (tramp-equal-remote filename newname) 1790 (unless (tramp-equal-remote filename newname)
1925 (with-parsed-tramp-file-name 1791 (with-parsed-tramp-file-name
1926 (if (tramp-tramp-file-p filename) filename newname) nil 1792 (if (tramp-tramp-file-p filename) filename newname) nil
1948 (format "%s %s %s" ln (tramp-shell-quote-argument v1-localname) 1814 (format "%s %s %s" ln (tramp-shell-quote-argument v1-localname)
1949 (tramp-shell-quote-argument v2-localname)) 1815 (tramp-shell-quote-argument v2-localname))
1950 "error with add-name-to-file, see buffer `%s' for details" 1816 "error with add-name-to-file, see buffer `%s' for details"
1951 (buffer-name)))))) 1817 (buffer-name))))))
1952 1818
1953 (defun tramp-handle-copy-file 1819 (defun tramp-sh-handle-copy-file
1954 (filename newname &optional ok-if-already-exists keep-date 1820 (filename newname &optional ok-if-already-exists keep-date
1955 preserve-uid-gid preserve-selinux-context) 1821 preserve-uid-gid preserve-selinux-context)
1956 "Like `copy-file' for Tramp files." 1822 "Like `copy-file' for Tramp files."
1957 (setq filename (expand-file-name filename)) 1823 (setq filename (expand-file-name filename))
1958 (setq newname (expand-file-name newname)) 1824 (setq newname (expand-file-name newname))
1975 (list filename newname ok-if-already-exists keep-date preserve-uid-gid))) 1841 (list filename newname ok-if-already-exists keep-date preserve-uid-gid)))
1976 (t 1842 (t
1977 (tramp-run-real-handler 1843 (tramp-run-real-handler
1978 'copy-file (list filename newname ok-if-already-exists keep-date))))) 1844 'copy-file (list filename newname ok-if-already-exists keep-date)))))
1979 1845
1980 (defun tramp-handle-copy-directory (dirname newname &optional keep-date parents) 1846 (defun tramp-sh-handle-copy-directory
1847 (dirname newname &optional keep-date parents)
1981 "Like `copy-directory' for Tramp files." 1848 "Like `copy-directory' for Tramp files."
1982 (let ((t1 (tramp-tramp-file-p dirname)) 1849 (let ((t1 (tramp-tramp-file-p dirname))
1983 (t2 (tramp-tramp-file-p newname))) 1850 (t2 (tramp-tramp-file-p newname)))
1984 (with-parsed-tramp-file-name (if t1 dirname newname) nil 1851 (with-parsed-tramp-file-name (if t1 dirname newname) nil
1985 (if (and (tramp-get-method-parameter method 'tramp-copy-recursive) 1852 (if (and (tramp-get-method-parameter method 'tramp-copy-recursive)
2011 (when t2 1878 (when t2
2012 (with-parsed-tramp-file-name newname nil 1879 (with-parsed-tramp-file-name newname nil
2013 (tramp-flush-file-property v (file-name-directory localname)) 1880 (tramp-flush-file-property v (file-name-directory localname))
2014 (tramp-flush-file-property v localname)))))) 1881 (tramp-flush-file-property v localname))))))
2015 1882
2016 (defun tramp-handle-rename-file 1883 (defun tramp-sh-handle-rename-file
2017 (filename newname &optional ok-if-already-exists) 1884 (filename newname &optional ok-if-already-exists)
2018 "Like `rename-file' for Tramp files." 1885 "Like `rename-file' for Tramp files."
2019 ;; Check if both files are local -- invoke normal rename-file. 1886 ;; Check if both files are local -- invoke normal rename-file.
2020 ;; Otherwise, use Tramp from local system. 1887 ;; Otherwise, use Tramp from local system.
2021 (setq filename (expand-file-name filename)) 1888 (setq filename (expand-file-name filename))
2039 KEEP-DATE means to make sure that NEWNAME has the same timestamp 1906 KEEP-DATE means to make sure that NEWNAME has the same timestamp
2040 as FILENAME. PRESERVE-UID-GID, when non-nil, instructs to keep 1907 as FILENAME. PRESERVE-UID-GID, when non-nil, instructs to keep
2041 the uid and gid if both files are on the same host. 1908 the uid and gid if both files are on the same host.
2042 PRESERVE-SELINUX-CONTEXT activates selinux commands. 1909 PRESERVE-SELINUX-CONTEXT activates selinux commands.
2043 1910
2044 This function is invoked by `tramp-handle-copy-file' and 1911 This function is invoked by `tramp-sh-handle-copy-file' and
2045 `tramp-handle-rename-file'. It is an error if OP is neither of `copy' 1912 `tramp-sh-handle-rename-file'. It is an error if OP is neither
2046 and `rename'. FILENAME and NEWNAME must be absolute file names." 1913 of `copy' and `rename'. FILENAME and NEWNAME must be absolute
1914 file names."
2047 (unless (memq op '(copy rename)) 1915 (unless (memq op '(copy rename))
2048 (error "Unknown operation `%s', must be `copy' or `rename'" op)) 1916 (error "Unknown operation `%s', must be `copy' or `rename'" op))
2049 (let ((t1 (tramp-tramp-file-p filename)) 1917 (let ((t1 (tramp-tramp-file-p filename))
2050 (t2 (tramp-tramp-file-p newname)) 1918 (t2 (tramp-tramp-file-p newname))
2051 (context (and preserve-selinux-context 1919 (context (and preserve-selinux-context
2462 (unless (eq op 'copy) 2330 (unless (eq op 'copy)
2463 (if (file-regular-p filename) 2331 (if (file-regular-p filename)
2464 (delete-file filename) 2332 (delete-file filename)
2465 (tramp-compat-delete-directory filename 'recursive)))))) 2333 (tramp-compat-delete-directory filename 'recursive))))))
2466 2334
2467 (defun tramp-handle-make-directory (dir &optional parents) 2335 (defun tramp-sh-handle-make-directory (dir &optional parents)
2468 "Like `make-directory' for Tramp files." 2336 "Like `make-directory' for Tramp files."
2469 (setq dir (expand-file-name dir)) 2337 (setq dir (expand-file-name dir))
2470 (with-parsed-tramp-file-name dir nil 2338 (with-parsed-tramp-file-name dir nil
2471 (tramp-flush-directory-property v (file-name-directory localname)) 2339 (tramp-flush-directory-property v (file-name-directory localname))
2472 (save-excursion 2340 (save-excursion
2474 v (format "%s %s" 2342 v (format "%s %s"
2475 (if parents "mkdir -p" "mkdir") 2343 (if parents "mkdir -p" "mkdir")
2476 (tramp-shell-quote-argument localname)) 2344 (tramp-shell-quote-argument localname))
2477 "Couldn't make directory %s" dir)))) 2345 "Couldn't make directory %s" dir))))
2478 2346
2479 (defun tramp-handle-delete-directory (directory &optional recursive) 2347 (defun tramp-sh-handle-delete-directory (directory &optional recursive)
2480 "Like `delete-directory' for Tramp files." 2348 "Like `delete-directory' for Tramp files."
2481 (setq directory (expand-file-name directory)) 2349 (setq directory (expand-file-name directory))
2482 (with-parsed-tramp-file-name directory nil 2350 (with-parsed-tramp-file-name directory nil
2483 (tramp-flush-file-property v (file-name-directory localname)) 2351 (tramp-flush-file-property v (file-name-directory localname))
2484 (tramp-flush-directory-property v localname) 2352 (tramp-flush-directory-property v localname)
2486 v (format "%s %s" 2354 v (format "%s %s"
2487 (if recursive "rm -rf" "rmdir") 2355 (if recursive "rm -rf" "rmdir")
2488 (tramp-shell-quote-argument localname)) 2356 (tramp-shell-quote-argument localname))
2489 "Couldn't delete %s" directory))) 2357 "Couldn't delete %s" directory)))
2490 2358
2491 (defun tramp-handle-delete-file (filename &optional trash) 2359 (defun tramp-sh-handle-delete-file (filename &optional trash)
2492 "Like `delete-file' for Tramp files." 2360 "Like `delete-file' for Tramp files."
2493 (setq filename (expand-file-name filename)) 2361 (setq filename (expand-file-name filename))
2494 (with-parsed-tramp-file-name filename nil 2362 (with-parsed-tramp-file-name filename nil
2495 (tramp-flush-file-property v (file-name-directory localname)) 2363 (tramp-flush-file-property v (file-name-directory localname))
2496 (tramp-flush-file-property v localname) 2364 (tramp-flush-file-property v localname)
2502 2370
2503 ;; Dired. 2371 ;; Dired.
2504 2372
2505 ;; CCC: This does not seem to be enough. Something dies when 2373 ;; CCC: This does not seem to be enough. Something dies when
2506 ;; we try and delete two directories under Tramp :/ 2374 ;; we try and delete two directories under Tramp :/
2507 (defun tramp-handle-dired-recursive-delete-directory (filename) 2375 (defun tramp-sh-handle-dired-recursive-delete-directory (filename)
2508 "Recursively delete the directory given. 2376 "Recursively delete the directory given.
2509 This is like `dired-recursive-delete-directory' for Tramp files." 2377 This is like `dired-recursive-delete-directory' for Tramp files."
2510 (with-parsed-tramp-file-name filename nil 2378 (with-parsed-tramp-file-name filename nil
2511 ;; Run a shell command 'rm -r <localname>' 2379 ;; Run a shell command 'rm -r <localname>'
2512 ;; Code shamelessly stolen from the dired implementation and, um, hacked :) 2380 ;; Code shamelessly stolen from the dired implementation and, um, hacked :)
2526 (tramp-flush-directory-property v localname) 2394 (tramp-flush-directory-property v localname)
2527 (and (file-exists-p filename) 2395 (and (file-exists-p filename)
2528 (tramp-error 2396 (tramp-error
2529 v 'file-error "Failed to recursively delete %s" filename)))) 2397 v 'file-error "Failed to recursively delete %s" filename))))
2530 2398
2531 (defun tramp-handle-dired-compress-file (file &rest ok-flag) 2399 (defun tramp-sh-handle-dired-compress-file (file &rest ok-flag)
2532 "Like `dired-compress-file' for Tramp files." 2400 "Like `dired-compress-file' for Tramp files."
2533 ;; OK-FLAG is valid for XEmacs only, but not implemented. 2401 ;; OK-FLAG is valid for XEmacs only, but not implemented.
2534 ;; Code stolen mainly from dired-aux.el. 2402 ;; Code stolen mainly from dired-aux.el.
2535 (with-parsed-tramp-file-name file nil 2403 (with-parsed-tramp-file-name file nil
2536 (tramp-flush-file-property v localname) 2404 (tramp-flush-file-property v localname)
2580 (concat file ".gz")) 2448 (concat file ".gz"))
2581 ((file-exists-p (concat file ".z")) 2449 ((file-exists-p (concat file ".z"))
2582 (concat file ".z")) 2450 (concat file ".z"))
2583 (t nil)))))))))) 2451 (t nil))))))))))
2584 2452
2585 (defun tramp-handle-dired-uncache (dir &optional dir-p) 2453 (defun tramp-sh-handle-insert-directory
2586 "Like `dired-uncache' for Tramp files."
2587 ;; DIR-P is valid for XEmacs only.
2588 (with-parsed-tramp-file-name
2589 (if (or dir-p (file-directory-p dir)) dir (file-name-directory dir)) nil
2590 (tramp-flush-directory-property v localname)))
2591
2592 (defun tramp-handle-insert-directory
2593 (filename switches &optional wildcard full-directory-p) 2454 (filename switches &optional wildcard full-directory-p)
2594 "Like `insert-directory' for Tramp files." 2455 "Like `insert-directory' for Tramp files."
2595 (setq filename (expand-file-name filename)) 2456 (setq filename (expand-file-name filename))
2596 (with-parsed-tramp-file-name filename nil 2457 (with-parsed-tramp-file-name filename nil
2597 (if (and (featurep 'ls-lisp) 2458 (if (and (featurep 'ls-lisp)
2690 beg 'noerror) 2551 beg 'noerror)
2691 (replace-match (file-relative-name filename) t)) 2552 (replace-match (file-relative-name filename) t))
2692 2553
2693 (goto-char (point-max)))))) 2554 (goto-char (point-max))))))
2694 2555
2695 (defun tramp-handle-unhandled-file-name-directory (filename)
2696 "Like `unhandled-file-name-directory' for Tramp files."
2697 ;; With Emacs 23, we could simply return `nil'. But we must keep it
2698 ;; for backward compatibility.
2699 (expand-file-name "~/"))
2700
2701 ;; Canonicalization of file names. 2556 ;; Canonicalization of file names.
2702 2557
2703 (defun tramp-handle-expand-file-name (name &optional dir) 2558 (defun tramp-sh-handle-expand-file-name (name &optional dir)
2704 "Like `expand-file-name' for Tramp files. 2559 "Like `expand-file-name' for Tramp files.
2705 If the localname part of the given filename starts with \"/../\" then 2560 If the localname part of the given filename starts with \"/../\" then
2706 the result will be a local, non-Tramp, filename." 2561 the result will be a local, non-Tramp, filename."
2707 ;; If DIR is not given, use DEFAULT-DIRECTORY or "/". 2562 ;; If DIR is not given, use DEFAULT-DIRECTORY or "/".
2708 (setq dir (or dir default-directory "/")) 2563 (setq dir (or dir default-directory "/"))
2757 method user host 2612 method user host
2758 (tramp-drop-volume-letter 2613 (tramp-drop-volume-letter
2759 (tramp-run-real-handler 2614 (tramp-run-real-handler
2760 'expand-file-name (list localname)))))))) 2615 'expand-file-name (list localname))))))))
2761 2616
2762 (defun tramp-handle-substitute-in-file-name (filename)
2763 "Like `substitute-in-file-name' for Tramp files.
2764 \"//\" and \"/~\" substitute only in the local filename part.
2765 If the URL Tramp syntax is chosen, \"//\" as method delimeter and \"/~\" at
2766 beginning of local filename are not substituted."
2767 ;; First, we must replace environment variables.
2768 (setq filename (tramp-replace-environment-variables filename))
2769 (with-parsed-tramp-file-name filename nil
2770 (if (equal tramp-syntax 'url)
2771 ;; We need to check localname only. The other parts cannot contain
2772 ;; "//" or "/~".
2773 (if (and (> (length localname) 1)
2774 (or (string-match "//" localname)
2775 (string-match "/~" localname 1)))
2776 (tramp-run-real-handler 'substitute-in-file-name (list filename))
2777 (tramp-make-tramp-file-name
2778 (when method (substitute-in-file-name method))
2779 (when user (substitute-in-file-name user))
2780 (when host (substitute-in-file-name host))
2781 (when localname
2782 (tramp-run-real-handler
2783 'substitute-in-file-name (list localname)))))
2784 ;; Ignore in LOCALNAME everything before "//" or "/~".
2785 (when (and (stringp localname) (string-match ".+?/\\(/\\|~\\)" localname))
2786 (setq filename
2787 (concat (file-remote-p filename)
2788 (replace-match "\\1" nil nil localname)))
2789 ;; "/m:h:~" does not work for completion. We use "/m:h:~/".
2790 (when (string-match "~$" filename)
2791 (setq filename (concat filename "/"))))
2792 (tramp-run-real-handler 'substitute-in-file-name (list filename)))))
2793
2794 ;;; Remote commands: 2617 ;;; Remote commands:
2795 2618
2796 (defun tramp-handle-executable-find (command) 2619 (defun tramp-sh-handle-executable-find (command)
2797 "Like `executable-find' for Tramp files." 2620 "Like `executable-find' for Tramp files."
2798 (with-parsed-tramp-file-name default-directory nil 2621 (with-parsed-tramp-file-name default-directory nil
2799 (tramp-find-executable v command (tramp-get-remote-path v) t))) 2622 (tramp-find-executable v command (tramp-get-remote-path v) t)))
2800 2623
2801 (defun tramp-process-sentinel (proc event) 2624 (defun tramp-process-sentinel (proc event)
2807 (tramp-flush-directory-property vec ""))))) 2630 (tramp-flush-directory-property vec "")))))
2808 2631
2809 ;; We use BUFFER also as connection buffer during setup. Because of 2632 ;; We use BUFFER also as connection buffer during setup. Because of
2810 ;; this, its original contents must be saved, and restored once 2633 ;; this, its original contents must be saved, and restored once
2811 ;; connection has been setup. 2634 ;; connection has been setup.
2812 (defun tramp-handle-start-file-process (name buffer program &rest args) 2635 (defun tramp-sh-handle-start-file-process (name buffer program &rest args)
2813 "Like `start-file-process' for Tramp files." 2636 "Like `start-file-process' for Tramp files."
2814 (with-parsed-tramp-file-name default-directory nil 2637 (with-parsed-tramp-file-name default-directory nil
2815 (unwind-protect 2638 (unwind-protect
2816 ;; When PROGRAM is nil, we just provide a tty. 2639 ;; When PROGRAM is nil, we just provide a tty.
2817 (let ((command 2640 (let ((command
2866 (widen) 2689 (widen)
2867 (goto-char (point-max)))) 2690 (goto-char (point-max))))
2868 (tramp-set-connection-property v "process-name" nil) 2691 (tramp-set-connection-property v "process-name" nil)
2869 (tramp-set-connection-property v "process-buffer" nil)))) 2692 (tramp-set-connection-property v "process-buffer" nil))))
2870 2693
2871 (defun tramp-handle-process-file 2694 (defun tramp-sh-handle-process-file
2872 (program &optional infile destination display &rest args) 2695 (program &optional infile destination display &rest args)
2873 "Like `process-file' for Tramp files." 2696 "Like `process-file' for Tramp files."
2874 ;; The implementation is not complete yet. 2697 ;; The implementation is not complete yet.
2875 (when (and (numberp destination) (zerop destination)) 2698 (when (and (numberp destination) (zerop destination))
2876 (error "Implementation does not handle immediate return")) 2699 (error "Implementation does not handle immediate return"))
2979 ;; Return exit status. 2802 ;; Return exit status.
2980 (if (equal ret -1) 2803 (if (equal ret -1)
2981 (keyboard-quit) 2804 (keyboard-quit)
2982 ret)))) 2805 ret))))
2983 2806
2984 (defun tramp-handle-call-process-region 2807 (defun tramp-sh-handle-call-process-region
2985 (start end program &optional delete buffer display &rest args) 2808 (start end program &optional delete buffer display &rest args)
2986 "Like `call-process-region' for Tramp files." 2809 "Like `call-process-region' for Tramp files."
2987 (let ((tmpfile (tramp-compat-make-temp-file ""))) 2810 (let ((tmpfile (tramp-compat-make-temp-file "")))
2988 (write-region start end tmpfile) 2811 (write-region start end tmpfile)
2989 (when delete (delete-region start end)) 2812 (when delete (delete-region start end))
2990 (unwind-protect 2813 (unwind-protect
2991 (apply 'call-process program tmpfile buffer display args) 2814 (apply 'call-process program tmpfile buffer display args)
2992 (delete-file tmpfile)))) 2815 (delete-file tmpfile))))
2993 2816
2994 (defun tramp-handle-shell-command 2817 (defun tramp-sh-handle-shell-command
2995 (command &optional output-buffer error-buffer) 2818 (command &optional output-buffer error-buffer)
2996 "Like `shell-command' for Tramp files." 2819 "Like `shell-command' for Tramp files."
2997 (let* ((asynchronous (string-match "[ \t]*&[ \t]*\\'" command)) 2820 (let* ((asynchronous (string-match "[ \t]*&[ \t]*\\'" command))
2998 ;; We cannot use `shell-file-name' and `shell-command-switch', 2821 ;; We cannot use `shell-file-name' and `shell-command-switch',
2999 ;; they are variables of the local host. 2822 ;; they are variables of the local host.
3070 (when (with-current-buffer output-buffer (> (point-max) (point-min))) 2893 (when (with-current-buffer output-buffer (> (point-max) (point-min)))
3071 (if (functionp 'display-message-or-buffer) 2894 (if (functionp 'display-message-or-buffer)
3072 (tramp-compat-funcall 'display-message-or-buffer output-buffer) 2895 (tramp-compat-funcall 'display-message-or-buffer output-buffer)
3073 (pop-to-buffer output-buffer)))))))) 2896 (pop-to-buffer output-buffer))))))))
3074 2897
3075 (defun tramp-handle-file-local-copy (filename) 2898 (defun tramp-sh-handle-file-local-copy (filename)
3076 "Like `file-local-copy' for Tramp files." 2899 "Like `file-local-copy' for Tramp files."
3077
3078 (with-parsed-tramp-file-name filename nil 2900 (with-parsed-tramp-file-name filename nil
3079 (unless (file-exists-p filename) 2901 (unless (file-exists-p filename)
3080 (tramp-error 2902 (tramp-error
3081 v 'file-error 2903 v 'file-error
3082 "Cannot make local copy of non-existing file `%s'" filename)) 2904 "Cannot make local copy of non-existing file `%s'" filename))
3151 (signal (car err) (cdr err)))) 2973 (signal (car err) (cdr err))))
3152 2974
3153 (run-hooks 'tramp-handle-file-local-copy-hook) 2975 (run-hooks 'tramp-handle-file-local-copy-hook)
3154 tmpfile))) 2976 tmpfile)))
3155 2977
3156 (defun tramp-handle-file-remote-p (filename &optional identification connected)
3157 "Like `file-remote-p' for Tramp files."
3158 (let ((tramp-verbose 3))
3159 (when (tramp-tramp-file-p filename)
3160 (let* ((v (tramp-dissect-file-name filename))
3161 (p (tramp-get-connection-process v))
3162 (c (and p (processp p) (memq (process-status p) '(run open)))))
3163 ;; We expand the file name only, if there is already a connection.
3164 (with-parsed-tramp-file-name
3165 (if c (expand-file-name filename) filename) nil
3166 (and (or (not connected) c)
3167 (cond
3168 ((eq identification 'method) method)
3169 ((eq identification 'user) user)
3170 ((eq identification 'host) host)
3171 ((eq identification 'localname) localname)
3172 (t (tramp-make-tramp-file-name method user host "")))))))))
3173
3174 (defun tramp-handle-insert-file-contents
3175 (filename &optional visit beg end replace)
3176 "Like `insert-file-contents' for Tramp files."
3177 (barf-if-buffer-read-only)
3178 (setq filename (expand-file-name filename))
3179 (let (result local-copy remote-copy)
3180 (with-parsed-tramp-file-name filename nil
3181 (unwind-protect
3182 (if (not (file-exists-p filename))
3183 ;; We don't raise a Tramp error, because it might be
3184 ;; suppressed, like in `find-file-noselect-1'.
3185 (signal 'file-error
3186 (list "File not found on remote host" filename))
3187
3188 (if (and (tramp-local-host-p v)
3189 (let (file-name-handler-alist)
3190 (file-readable-p localname)))
3191 ;; Short track: if we are on the local host, we can
3192 ;; run directly.
3193 (setq result
3194 (tramp-run-real-handler
3195 'insert-file-contents
3196 (list localname visit beg end replace)))
3197
3198 ;; When we shall insert only a part of the file, we copy
3199 ;; this part.
3200 (when (or beg end)
3201 (setq remote-copy (tramp-make-tramp-temp-file v))
3202 (tramp-send-command
3203 v
3204 (cond
3205 ((and beg end)
3206 (format "tail -c +%d %s | head -c +%d >%s"
3207 (1+ beg) (tramp-shell-quote-argument localname)
3208 (- end beg) remote-copy))
3209 (beg
3210 (format "tail -c +%d %s >%s"
3211 (1+ beg) (tramp-shell-quote-argument localname)
3212 remote-copy))
3213 (end
3214 (format "head -c +%d %s >%s"
3215 (1+ end) (tramp-shell-quote-argument localname)
3216 remote-copy)))))
3217
3218 ;; `insert-file-contents-literally' takes care to avoid
3219 ;; calling jka-compr. By let-binding
3220 ;; `inhibit-file-name-operation', we propagate that care
3221 ;; to the `file-local-copy' operation.
3222 (setq local-copy
3223 (let ((inhibit-file-name-operation
3224 (when (eq inhibit-file-name-operation
3225 'insert-file-contents)
3226 'file-local-copy)))
3227 (cond
3228 ((stringp remote-copy)
3229 (file-local-copy
3230 (tramp-make-tramp-file-name
3231 method user host remote-copy)))
3232 ((stringp tramp-temp-buffer-file-name)
3233 (copy-file filename tramp-temp-buffer-file-name 'ok)
3234 tramp-temp-buffer-file-name)
3235 (t (file-local-copy filename)))))
3236
3237 ;; When the file is not readable for the owner, it
3238 ;; cannot be inserted, even it is redable for the group
3239 ;; or for everybody.
3240 (set-file-modes local-copy (tramp-compat-octal-to-decimal "0600"))
3241
3242 (when (and (null remote-copy)
3243 (tramp-get-method-parameter
3244 method 'tramp-copy-keep-tmpfile))
3245 ;; We keep the local file for performance reasons,
3246 ;; useful for "rsync".
3247 (setq tramp-temp-buffer-file-name local-copy)
3248 (put 'tramp-temp-buffer-file-name 'permanent-local t))
3249
3250 (with-progress-reporter
3251 v 3 (format "Inserting local temp file `%s'" local-copy)
3252 ;; We must ensure that `file-coding-system-alist'
3253 ;; matches `local-copy'.
3254 (let ((file-coding-system-alist
3255 (tramp-find-file-name-coding-system-alist
3256 filename local-copy)))
3257 (setq result
3258 (insert-file-contents
3259 local-copy nil nil nil replace))))))
3260
3261 ;; Save exit.
3262 (progn
3263 (when visit
3264 (setq buffer-file-name filename)
3265 (setq buffer-read-only (not (file-writable-p filename)))
3266 (set-visited-file-modtime)
3267 (set-buffer-modified-p nil))
3268 (when (and (stringp local-copy)
3269 (or remote-copy (null tramp-temp-buffer-file-name)))
3270 (delete-file local-copy))
3271 (when (stringp remote-copy)
3272 (delete-file
3273 (tramp-make-tramp-file-name method user host remote-copy))))))
3274
3275 ;; Result.
3276 (list (expand-file-name filename)
3277 (cadr result))))
3278
3279 ;; This is needed for XEmacs only. Code stolen from files.el. 2978 ;; This is needed for XEmacs only. Code stolen from files.el.
3280 (defun tramp-handle-insert-file-contents-literally 2979 (defun tramp-sh-handle-insert-file-contents-literally
3281 (filename &optional visit beg end replace) 2980 (filename &optional visit beg end replace)
3282 "Like `insert-file-contents-literally' for Tramp files." 2981 "Like `insert-file-contents-literally' for Tramp files."
3283 (let ((format-alist nil) 2982 (let ((format-alist nil)
3284 (after-insert-file-functions nil) 2983 (after-insert-file-functions nil)
3285 (coding-system-for-read 'no-conversion) 2984 (coding-system-for-read 'no-conversion)
3297 ;; Save exit. 2996 ;; Save exit.
3298 (if find-buffer-file-type-function 2997 (if find-buffer-file-type-function
3299 (fset 'find-buffer-file-type find-buffer-file-type-function) 2998 (fset 'find-buffer-file-type find-buffer-file-type-function)
3300 (fmakunbound 'find-buffer-file-type))))) 2999 (fmakunbound 'find-buffer-file-type)))))
3301 3000
3302 (defun tramp-handle-find-backup-file-name (filename) 3001 (defun tramp-sh-handle-make-auto-save-file-name ()
3303 "Like `find-backup-file-name' for Tramp files."
3304 (with-parsed-tramp-file-name filename nil
3305 ;; We set both variables. It doesn't matter whether it is
3306 ;; Emacs or XEmacs.
3307 (let ((backup-directory-alist
3308 ;; Emacs case.
3309 (when (boundp 'backup-directory-alist)
3310 (if (symbol-value 'tramp-backup-directory-alist)
3311 (mapcar
3312 (lambda (x)
3313 (cons
3314 (car x)
3315 (if (and (stringp (cdr x))
3316 (file-name-absolute-p (cdr x))
3317 (not (tramp-file-name-p (cdr x))))
3318 (tramp-make-tramp-file-name method user host (cdr x))
3319 (cdr x))))
3320 (symbol-value 'tramp-backup-directory-alist))
3321 (symbol-value 'backup-directory-alist))))
3322
3323 (bkup-backup-directory-info
3324 ;; XEmacs case.
3325 (when (boundp 'bkup-backup-directory-info)
3326 (if (symbol-value 'tramp-bkup-backup-directory-info)
3327 (mapcar
3328 (lambda (x)
3329 (nconc
3330 (list (car x))
3331 (list
3332 (if (and (stringp (car (cdr x)))
3333 (file-name-absolute-p (car (cdr x)))
3334 (not (tramp-file-name-p (car (cdr x)))))
3335 (tramp-make-tramp-file-name
3336 method user host (car (cdr x)))
3337 (car (cdr x))))
3338 (cdr (cdr x))))
3339 (symbol-value 'tramp-bkup-backup-directory-info))
3340 (symbol-value 'bkup-backup-directory-info)))))
3341
3342 (tramp-run-real-handler 'find-backup-file-name (list filename)))))
3343
3344 (defun tramp-handle-make-auto-save-file-name ()
3345 "Like `make-auto-save-file-name' for Tramp files. 3002 "Like `make-auto-save-file-name' for Tramp files.
3346 Returns a file name in `tramp-auto-save-directory' for autosaving this file." 3003 Returns a file name in `tramp-auto-save-directory' for autosaving this file."
3347 (let ((tramp-auto-save-directory tramp-auto-save-directory) 3004 (let ((tramp-auto-save-directory tramp-auto-save-directory)
3348 (buffer-file-name 3005 (buffer-file-name
3349 (tramp-subst-strs-in-string 3006 (tramp-subst-strs-in-string
3381 (ad-deactivate 'make-auto-save-file-name) 3038 (ad-deactivate 'make-auto-save-file-name)
3382 (prog1 3039 (prog1
3383 (tramp-run-real-handler 'make-auto-save-file-name nil) 3040 (tramp-run-real-handler 'make-auto-save-file-name nil)
3384 (ad-activate 'make-auto-save-file-name))))) 3041 (ad-activate 'make-auto-save-file-name)))))
3385 3042
3386 (defvar tramp-handle-write-region-hook nil
3387 "Normal hook to be run at the end of `tramp-handle-write-region'.")
3388
3389 ;; CCC grok LOCKNAME 3043 ;; CCC grok LOCKNAME
3390 (defun tramp-handle-write-region 3044 (defun tramp-sh-handle-write-region
3391 (start end filename &optional append visit lockname confirm) 3045 (start end filename &optional append visit lockname confirm)
3392 "Like `write-region' for Tramp files." 3046 "Like `write-region' for Tramp files."
3393 (setq filename (expand-file-name filename)) 3047 (setq filename (expand-file-name filename))
3394 (with-parsed-tramp-file-name filename nil 3048 (with-parsed-tramp-file-name filename nil
3395 ;; Following part commented out because we don't know what to do about 3049 ;; Following part commented out because we don't know what to do about
3398 ;; (when (and lockname (stringp lockname)) 3052 ;; (when (and lockname (stringp lockname))
3399 ;; (setq lockname (expand-file-name lockname))) 3053 ;; (setq lockname (expand-file-name lockname)))
3400 ;; (unless (or (eq lockname nil) 3054 ;; (unless (or (eq lockname nil)
3401 ;; (string= lockname filename)) 3055 ;; (string= lockname filename))
3402 ;; (error 3056 ;; (error
3403 ;; "tramp-handle-write-region: LOCKNAME must be nil or equal FILENAME")) 3057 ;; "tramp-sh-handle-write-region: LOCKNAME must be nil or equal FILENAME"))
3404 3058
3405 ;; XEmacs takes a coding system as the seventh argument, not `confirm'. 3059 ;; XEmacs takes a coding system as the seventh argument, not `confirm'.
3406 (when (and (not (featurep 'xemacs)) confirm (file-exists-p filename)) 3060 (when (and (not (featurep 'xemacs)) confirm (file-exists-p filename))
3407 (unless (y-or-n-p (format "File %s exists; overwrite anyway? " filename)) 3061 (unless (y-or-n-p (format "File %s exists; overwrite anyway? " filename))
3408 (tramp-error v 'file-error "File not overwritten"))) 3062 (tramp-error v 'file-error "File not overwritten")))
3647 ;; file names, using just one remote command. The result of this 3301 ;; file names, using just one remote command. The result of this
3648 ;; script is used to fill the file cache with actual values. Now we 3302 ;; script is used to fill the file cache with actual values. Now we
3649 ;; can reset the file name handlers, and we make a second run of 3303 ;; can reset the file name handlers, and we make a second run of
3650 ;; `vc-registered', which returns the expected result without sending 3304 ;; `vc-registered', which returns the expected result without sending
3651 ;; any other remote command. 3305 ;; any other remote command.
3652 (defun tramp-handle-vc-registered (file) 3306 (defun tramp-sh-handle-vc-registered (file)
3653 "Like `vc-registered' for Tramp files." 3307 "Like `vc-registered' for Tramp files."
3654 (tramp-compat-with-temp-message "" 3308 (tramp-compat-with-temp-message ""
3655 (with-parsed-tramp-file-name file nil 3309 (with-parsed-tramp-file-name file nil
3656 (with-progress-reporter 3310 (with-progress-reporter
3657 v 3 (format "Checking `vc-registered' for %s" file) 3311 v 3 (format "Checking `vc-registered' for %s" file)
4789 (error (tramp-error 4443 (error (tramp-error
4790 vec 'file-error 4444 vec 'file-error
4791 "`%s' does not return a valid Lisp expression: `%s'" 4445 "`%s' does not return a valid Lisp expression: `%s'"
4792 command (buffer-string)))))) 4446 command (buffer-string))))))
4793 4447
4794 (defun tramp-mode-string-to-int (mode-string)
4795 "Converts a ten-letter `drwxrwxrwx'-style mode string into mode bits."
4796 (let* (case-fold-search
4797 (mode-chars (string-to-vector mode-string))
4798 (owner-read (aref mode-chars 1))
4799 (owner-write (aref mode-chars 2))
4800 (owner-execute-or-setid (aref mode-chars 3))
4801 (group-read (aref mode-chars 4))
4802 (group-write (aref mode-chars 5))
4803 (group-execute-or-setid (aref mode-chars 6))
4804 (other-read (aref mode-chars 7))
4805 (other-write (aref mode-chars 8))
4806 (other-execute-or-sticky (aref mode-chars 9)))
4807 (save-match-data
4808 (logior
4809 (cond
4810 ((char-equal owner-read ?r) (tramp-compat-octal-to-decimal "00400"))
4811 ((char-equal owner-read ?-) 0)
4812 (t (error "Second char `%c' must be one of `r-'" owner-read)))
4813 (cond
4814 ((char-equal owner-write ?w) (tramp-compat-octal-to-decimal "00200"))
4815 ((char-equal owner-write ?-) 0)
4816 (t (error "Third char `%c' must be one of `w-'" owner-write)))
4817 (cond
4818 ((char-equal owner-execute-or-setid ?x)
4819 (tramp-compat-octal-to-decimal "00100"))
4820 ((char-equal owner-execute-or-setid ?S)
4821 (tramp-compat-octal-to-decimal "04000"))
4822 ((char-equal owner-execute-or-setid ?s)
4823 (tramp-compat-octal-to-decimal "04100"))
4824 ((char-equal owner-execute-or-setid ?-) 0)
4825 (t (error "Fourth char `%c' must be one of `xsS-'"
4826 owner-execute-or-setid)))
4827 (cond
4828 ((char-equal group-read ?r) (tramp-compat-octal-to-decimal "00040"))
4829 ((char-equal group-read ?-) 0)
4830 (t (error "Fifth char `%c' must be one of `r-'" group-read)))
4831 (cond
4832 ((char-equal group-write ?w) (tramp-compat-octal-to-decimal "00020"))
4833 ((char-equal group-write ?-) 0)
4834 (t (error "Sixth char `%c' must be one of `w-'" group-write)))
4835 (cond
4836 ((char-equal group-execute-or-setid ?x)
4837 (tramp-compat-octal-to-decimal "00010"))
4838 ((char-equal group-execute-or-setid ?S)
4839 (tramp-compat-octal-to-decimal "02000"))
4840 ((char-equal group-execute-or-setid ?s)
4841 (tramp-compat-octal-to-decimal "02010"))
4842 ((char-equal group-execute-or-setid ?-) 0)
4843 (t (error "Seventh char `%c' must be one of `xsS-'"
4844 group-execute-or-setid)))
4845 (cond
4846 ((char-equal other-read ?r)
4847 (tramp-compat-octal-to-decimal "00004"))
4848 ((char-equal other-read ?-) 0)
4849 (t (error "Eighth char `%c' must be one of `r-'" other-read)))
4850 (cond
4851 ((char-equal other-write ?w) (tramp-compat-octal-to-decimal "00002"))
4852 ((char-equal other-write ?-) 0)
4853 (t (error "Nineth char `%c' must be one of `w-'" other-write)))
4854 (cond
4855 ((char-equal other-execute-or-sticky ?x)
4856 (tramp-compat-octal-to-decimal "00001"))
4857 ((char-equal other-execute-or-sticky ?T)
4858 (tramp-compat-octal-to-decimal "01000"))
4859 ((char-equal other-execute-or-sticky ?t)
4860 (tramp-compat-octal-to-decimal "01001"))
4861 ((char-equal other-execute-or-sticky ?-) 0)
4862 (t (error "Tenth char `%c' must be one of `xtT-'"
4863 other-execute-or-sticky)))))))
4864
4865 (defun tramp-convert-file-attributes (vec attr) 4448 (defun tramp-convert-file-attributes (vec attr)
4866 "Convert file-attributes ATTR generated by perl script, stat or ls. 4449 "Convert file-attributes ATTR generated by perl script, stat or ls.
4867 Convert file mode bits to string and set virtual device number. 4450 Convert file mode bits to string and set virtual device number.
4868 Return ATTR." 4451 Return ATTR."
4869 (when attr 4452 (when attr
5022 ;; does not exist a remote encoding. 4605 ;; does not exist a remote encoding.
5023 (or (null tramp-copy-size-limit) 4606 (or (null tramp-copy-size-limit)
5024 (> size tramp-copy-size-limit) 4607 (> size tramp-copy-size-limit)
5025 (null (tramp-get-inline-coding vec "remote-encoding" size))))) 4608 (null (tramp-get-inline-coding vec "remote-encoding" size)))))
5026 4609
5027 (defun tramp-local-host-p (vec)
5028 "Return t if this points to the local host, nil otherwise."
5029 ;; We cannot use `tramp-file-name-real-host'. A port is an
5030 ;; indication for an ssh tunnel or alike.
5031 (let ((host (tramp-file-name-host vec)))
5032 (and
5033 (stringp host)
5034 (string-match tramp-local-host-regexp host)
5035 ;; The method shall be applied to one of the shell file name
5036 ;; handler. `tramp-local-host-p' is also called for "smb" and
5037 ;; alike, where it must fail.
5038 (tramp-get-method-parameter
5039 (tramp-file-name-method vec) 'tramp-login-program)
5040 ;; The local temp directory must be writable for the other user.
5041 (file-writable-p
5042 (tramp-make-tramp-file-name
5043 (tramp-file-name-method vec)
5044 (tramp-file-name-user vec)
5045 host
5046 (tramp-compat-temporary-file-directory)))
5047 ;; On some systems, chown runs only for root.
5048 (or (zerop (user-uid))
5049 (zerop (tramp-get-remote-uid vec 'integer))))))
5050
5051 ;; Variables local to connection. 4610 ;; Variables local to connection.
5052 4611
5053 (defun tramp-get-remote-path (vec) 4612 (defun tramp-get-remote-path (vec)
5054 (with-connection-property 4613 (with-connection-property
5055 ;; When `tramp-own-remote-path' is in `tramp-remote-path', we 4614 ;; When `tramp-own-remote-path' is in `tramp-remote-path', we
5130 vec (format "%s -d %s" (tramp-get-test-command vec) dir)) 4689 vec (format "%s -d %s" (tramp-get-test-command vec) dir))
5131 (tramp-send-command-and-check 4690 (tramp-send-command-and-check
5132 vec (format "%s -w %s" (tramp-get-test-command vec) dir))) 4691 vec (format "%s -w %s" (tramp-get-test-command vec) dir)))
5133 dir 4692 dir
5134 (tramp-error vec 'file-error "Directory %s not accessible" dir))))) 4693 (tramp-error vec 'file-error "Directory %s not accessible" dir)))))
5135
5136 (defun tramp-make-tramp-temp-file (vec)
5137 "Create a temporary file on the remote host identified by VEC.
5138 Return the local name of the temporary file."
5139 (let ((prefix
5140 (tramp-make-tramp-file-name
5141 (tramp-file-name-method vec)
5142 (tramp-file-name-user vec)
5143 (tramp-file-name-host vec)
5144 (tramp-drop-volume-letter
5145 (expand-file-name
5146 tramp-temp-name-prefix (tramp-get-remote-tmpdir vec)))))
5147 result)
5148 (while (not result)
5149 ;; `make-temp-file' would be the natural choice for
5150 ;; implementation. But it calls `write-region' internally,
5151 ;; which also needs a temporary file - we would end in an
5152 ;; infinite loop.
5153 (setq result (make-temp-name prefix))
5154 (if (file-exists-p result)
5155 (setq result nil)
5156 ;; This creates the file by side effect.
5157 (set-file-times result)
5158 (set-file-modes result (tramp-compat-octal-to-decimal "0700"))))
5159
5160 ;; Return the local part.
5161 (with-parsed-tramp-file-name result nil localname)))
5162 4694
5163 (defun tramp-get-ls-command (vec) 4695 (defun tramp-get-ls-command (vec)
5164 (with-connection-property vec "ls" 4696 (with-connection-property vec "ls"
5165 (tramp-message vec 5 "Finding a suitable `ls' command") 4697 (tramp-message vec 5 "Finding a suitable `ls' command")
5166 (or 4698 (or