Mercurial > emacs
changeset 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 | d131be972bc8 |
children | 0fe64d68a522 |
files | lisp/ChangeLog lisp/net/tramp-gvfs.el lisp/net/tramp-sh.el lisp/net/tramp-smb.el lisp/net/tramp.el |
diffstat | 5 files changed, 636 insertions(+), 619 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/ChangeLog Mon Oct 04 21:34:35 2010 +0200 +++ b/lisp/ChangeLog Mon Oct 04 21:44:08 2010 +0200 @@ -1,3 +1,31 @@ +2010-10-04 Michael Albinus <michael.albinus@gmx.de> + + 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-*'. + 2010-10-04 Glenn Morris <rgm@gnu.org> * calendar/appt.el (appt-add): Ensure reminders are enabled.
--- a/lisp/net/tramp-gvfs.el Mon Oct 04 21:34:35 2010 +0200 +++ b/lisp/net/tramp-gvfs.el Mon Oct 04 21:44:08 2010 +0200 @@ -104,10 +104,6 @@ (require 'tramp) -;; We call several `tramp-handle-*' functions directly. So we must -;; reqire that package as well. -(require 'tramp-sh) - (require 'dbus) (require 'url-parse) (require 'url-util) @@ -405,6 +401,7 @@ (file-name-directory . tramp-handle-file-name-directory) (file-name-nondirectory . tramp-handle-file-name-nondirectory) ;; `file-name-sans-versions' performed by default handler. + ;; CCC: Must be checked! (file-newer-than-file-p . tramp-handle-file-newer-than-file-p) (file-ownership-preserved-p . ignore) (file-readable-p . tramp-gvfs-handle-file-readable-p)
--- a/lisp/net/tramp-sh.el Mon Oct 04 21:34:35 2010 +0200 +++ b/lisp/net/tramp-sh.el Mon Oct 04 21:44:08 2010 +0200 @@ -620,7 +620,7 @@ ;; unless this spits out a complete line, including the '\n' at the ;; end. ;; The device number is returned as "-1", because there will be a virtual -;; device number set in `tramp-handle-file-attributes'. +;; device number set in `tramp-sh-handle-file-attributes'. (defconst tramp-perl-file-attributes "%s -e ' @stat = lstat($ARGV[0]); @@ -867,62 +867,63 @@ ;; get-file-buffer. (defconst tramp-sh-file-name-handler-alist '((load . tramp-handle-load) - (make-symbolic-link . tramp-handle-make-symbolic-link) + (make-symbolic-link . tramp-sh-handle-make-symbolic-link) (file-name-as-directory . tramp-handle-file-name-as-directory) (file-name-directory . tramp-handle-file-name-directory) (file-name-nondirectory . tramp-handle-file-name-nondirectory) - (file-truename . tramp-handle-file-truename) - (file-exists-p . tramp-handle-file-exists-p) - (file-directory-p . tramp-handle-file-directory-p) - (file-executable-p . tramp-handle-file-executable-p) - (file-readable-p . tramp-handle-file-readable-p) + (file-truename . tramp-sh-handle-file-truename) + (file-exists-p . tramp-sh-handle-file-exists-p) + (file-directory-p . tramp-sh-handle-file-directory-p) + (file-executable-p . tramp-sh-handle-file-executable-p) + (file-readable-p . tramp-sh-handle-file-readable-p) (file-regular-p . tramp-handle-file-regular-p) (file-symlink-p . tramp-handle-file-symlink-p) - (file-writable-p . tramp-handle-file-writable-p) - (file-ownership-preserved-p . tramp-handle-file-ownership-preserved-p) - (file-newer-than-file-p . tramp-handle-file-newer-than-file-p) - (file-attributes . tramp-handle-file-attributes) + (file-writable-p . tramp-sh-handle-file-writable-p) + (file-ownership-preserved-p . tramp-sh-handle-file-ownership-preserved-p) + (file-newer-than-file-p . tramp-sh-handle-file-newer-than-file-p) + (file-attributes . tramp-sh-handle-file-attributes) (file-modes . tramp-handle-file-modes) (directory-files . tramp-handle-directory-files) - (directory-files-and-attributes . tramp-handle-directory-files-and-attributes) - (file-name-all-completions . tramp-handle-file-name-all-completions) + (directory-files-and-attributes + . tramp-sh-handle-directory-files-and-attributes) + (file-name-all-completions . tramp-sh-handle-file-name-all-completions) (file-name-completion . tramp-handle-file-name-completion) - (add-name-to-file . tramp-handle-add-name-to-file) - (copy-file . tramp-handle-copy-file) - (copy-directory . tramp-handle-copy-directory) - (rename-file . tramp-handle-rename-file) - (set-file-modes . tramp-handle-set-file-modes) - (set-file-times . tramp-handle-set-file-times) - (make-directory . tramp-handle-make-directory) - (delete-directory . tramp-handle-delete-directory) - (delete-file . tramp-handle-delete-file) + (add-name-to-file . tramp-sh-handle-add-name-to-file) + (copy-file . tramp-sh-handle-copy-file) + (copy-directory . tramp-sh-handle-copy-directory) + (rename-file . tramp-sh-handle-rename-file) + (set-file-modes . tramp-sh-handle-set-file-modes) + (set-file-times . tramp-sh-handle-set-file-times) + (make-directory . tramp-sh-handle-make-directory) + (delete-directory . tramp-sh-handle-delete-directory) + (delete-file . tramp-sh-handle-delete-file) (directory-file-name . tramp-handle-directory-file-name) ;; `executable-find' is not official yet. - (executable-find . tramp-handle-executable-find) - (start-file-process . tramp-handle-start-file-process) - (process-file . tramp-handle-process-file) - (shell-command . tramp-handle-shell-command) - (insert-directory . tramp-handle-insert-directory) - (expand-file-name . tramp-handle-expand-file-name) + (executable-find . tramp-sh-handle-executable-find) + (start-file-process . tramp-sh-handle-start-file-process) + (process-file . tramp-sh-handle-process-file) + (shell-command . tramp-sh-handle-shell-command) + (insert-directory . tramp-sh-handle-insert-directory) + (expand-file-name . tramp-sh-handle-expand-file-name) (substitute-in-file-name . tramp-handle-substitute-in-file-name) - (file-local-copy . tramp-handle-file-local-copy) + (file-local-copy . tramp-sh-handle-file-local-copy) (file-remote-p . tramp-handle-file-remote-p) (insert-file-contents . tramp-handle-insert-file-contents) (insert-file-contents-literally - . tramp-handle-insert-file-contents-literally) - (write-region . tramp-handle-write-region) - (find-backup-file-name . tramp-handle-find-backup-file-name) - (make-auto-save-file-name . tramp-handle-make-auto-save-file-name) + . tramp-sh-handle-insert-file-contents-literally) + (write-region . tramp-sh-handle-write-region) + (find-backup-file-name . tramp-sh-handle-find-backup-file-name) + (make-auto-save-file-name . tramp-sh-handle-make-auto-save-file-name) (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory) - (dired-compress-file . tramp-handle-dired-compress-file) + (dired-compress-file . tramp-sh-handle-dired-compress-file) (dired-recursive-delete-directory - . tramp-handle-dired-recursive-delete-directory) + . tramp-sh-handle-dired-recursive-delete-directory) (dired-uncache . tramp-handle-dired-uncache) - (set-visited-file-modtime . tramp-handle-set-visited-file-modtime) - (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime) - (file-selinux-context . tramp-handle-file-selinux-context) - (set-file-selinux-context . tramp-handle-set-file-selinux-context) - (vc-registered . tramp-handle-vc-registered)) + (set-visited-file-modtime . tramp-sh-handle-set-visited-file-modtime) + (verify-visited-file-modtime . tramp-sh-handle-verify-visited-file-modtime) + (file-selinux-context . tramp-sh-handle-file-selinux-context) + (set-file-selinux-context . tramp-sh-handle-set-file-selinux-context) + (vc-registered . tramp-sh-handle-vc-registered)) "Alist of handler functions. Operations not mentioned here will be handled by the normal Emacs functions.") @@ -933,7 +934,7 @@ ;;; File Name Handler Functions: -(defun tramp-handle-make-symbolic-link +(defun tramp-sh-handle-make-symbolic-link (filename linkname &optional ok-if-already-exists) "Like `make-symbolic-link' for Tramp files. If LINKNAME is a non-Tramp file, it is used verbatim as the target of @@ -988,71 +989,7 @@ (tramp-shell-quote-argument l-localname)) t)))) -(defun tramp-handle-load (file &optional noerror nomessage nosuffix must-suffix) - "Like `load' for Tramp files." - (with-parsed-tramp-file-name (expand-file-name file) nil - (unless nosuffix - (cond ((file-exists-p (concat file ".elc")) - (setq file (concat file ".elc"))) - ((file-exists-p (concat file ".el")) - (setq file (concat file ".el"))))) - (when must-suffix - ;; The first condition is always true for absolute file names. - ;; Included for safety's sake. - (unless (or (file-name-directory file) - (string-match "\\.elc?\\'" file)) - (tramp-error - v 'file-error - "File `%s' does not include a `.el' or `.elc' suffix" file))) - (unless noerror - (when (not (file-exists-p file)) - (tramp-error v 'file-error "Cannot load nonexistent file `%s'" file))) - (if (not (file-exists-p file)) - nil - (let ((tramp-message-show-message (not nomessage))) - (with-progress-reporter v 0 (format "Loading %s" file) - (let ((local-copy (file-local-copy file))) - ;; MUST-SUFFIX doesn't exist on XEmacs, so let it default to nil. - (unwind-protect - (load local-copy noerror t t) - (delete-file local-copy))))) - t))) - -;; Localname manipulation functions that grok Tramp localnames... -(defun tramp-handle-file-name-as-directory (file) - "Like `file-name-as-directory' but aware of Tramp files." - ;; `file-name-as-directory' would be sufficient except localname is - ;; the empty string. - (let ((v (tramp-dissect-file-name file t))) - ;; Run the command on the localname portion only. - (tramp-make-tramp-file-name - (tramp-file-name-method v) - (tramp-file-name-user v) - (tramp-file-name-host v) - (tramp-run-real-handler - 'file-name-as-directory (list (or (tramp-file-name-localname v) "")))))) - -(defun tramp-handle-file-name-directory (file) - "Like `file-name-directory' but aware of Tramp files." - ;; Everything except the last filename thing is the directory. We - ;; cannot apply `with-parsed-tramp-file-name', because this expands - ;; the remote file name parts. This is a problem when we are in - ;; file name completion. - (let ((v (tramp-dissect-file-name file t))) - ;; Run the command on the localname portion only. - (tramp-make-tramp-file-name - (tramp-file-name-method v) - (tramp-file-name-user v) - (tramp-file-name-host v) - (tramp-run-real-handler - 'file-name-directory (list (or (tramp-file-name-localname v) "")))))) - -(defun tramp-handle-file-name-nondirectory (file) - "Like `file-name-nondirectory' but aware of Tramp files." - (with-parsed-tramp-file-name file nil - (tramp-run-real-handler 'file-name-nondirectory (list localname)))) - -(defun tramp-handle-file-truename (filename &optional counter prev-dirs) +(defun tramp-sh-handle-file-truename (filename &optional counter prev-dirs) "Like `file-truename' for Tramp files." (with-parsed-tramp-file-name (expand-file-name filename) nil (with-file-property v localname "file-truename" @@ -1158,7 +1095,7 @@ ;; Basic functions. -(defun tramp-handle-file-exists-p (filename) +(defun tramp-sh-handle-file-exists-p (filename) "Like `file-exists-p' for Tramp files." (with-parsed-tramp-file-name filename nil (with-file-property v localname "file-exists-p" @@ -1176,7 +1113,7 @@ ;; CCC: This should check for an error condition and signal failure ;; when something goes wrong. ;; Daniel Pittman <daniel@danann.net> -(defun tramp-handle-file-attributes (filename &optional id-format) +(defun tramp-sh-handle-file-attributes (filename &optional id-format) "Like `file-attributes' for Tramp files." (unless id-format (setq id-format 'integer)) ;; Don't modify `last-coding-system-used' by accident. @@ -1314,7 +1251,7 @@ (if (eq id-format 'integer) "%g" "\"%G\"") (tramp-shell-quote-argument localname)))) -(defun tramp-handle-set-visited-file-modtime (&optional time-list) +(defun tramp-sh-handle-set-visited-file-modtime (&optional time-list) "Like `set-visited-file-modtime' for Tramp files." (unless (buffer-file-name) (error "Can't set-visited-file-modtime: buffer `%s' not visiting a file" @@ -1348,8 +1285,8 @@ nil))))) ;; This function makes the same assumption as -;; `tramp-handle-set-visited-file-modtime'. -(defun tramp-handle-verify-visited-file-modtime (buf) +;; `tramp-sh-handle-set-visited-file-modtime'. +(defun tramp-sh-handle-verify-visited-file-modtime (buf) "Like `verify-visited-file-modtime' for Tramp files. At the time `verify-visited-file-modtime' calls this function, we already know that the buffer is visiting a file and that @@ -1401,7 +1338,7 @@ ;; only if that agrees with the buffer's record. (t (equal mt '(-1 65535)))))))))) -(defun tramp-handle-set-file-modes (filename mode) +(defun tramp-sh-handle-set-file-modes (filename mode) "Like `set-file-modes' for Tramp files." (with-parsed-tramp-file-name filename nil (tramp-flush-file-property v localname) @@ -1413,7 +1350,7 @@ (tramp-shell-quote-argument localname)) "Error while changing file's mode %s" filename))) -(defun tramp-handle-set-file-times (filename &optional time) +(defun tramp-sh-handle-set-file-times (filename &optional time) "Like `set-file-times' for Tramp files." (if (file-remote-p filename) (with-parsed-tramp-file-name filename nil @@ -1486,7 +1423,7 @@ vec (format "echo \\\"`%S`\\\"" result)) "Enforcing"))))) -(defun tramp-handle-file-selinux-context (filename) +(defun tramp-sh-handle-file-selinux-context (filename) "Like `file-selinux-context' for Tramp files." (with-parsed-tramp-file-name filename nil (with-file-property v localname "file-selinux-context" @@ -1507,7 +1444,7 @@ ;; Return the context. context)))) -(defun tramp-handle-set-file-selinux-context (filename context) +(defun tramp-sh-handle-set-file-selinux-context (filename context) "Like `set-file-selinux-context' for Tramp files." (with-parsed-tramp-file-name filename nil (if (and (consp context) @@ -1530,7 +1467,7 @@ ;; Simple functions using the `test' command. -(defun tramp-handle-file-executable-p (filename) +(defun tramp-sh-handle-file-executable-p (filename) "Like `file-executable-p' for Tramp files." (with-parsed-tramp-file-name filename nil (with-file-property v localname "file-executable-p" @@ -1539,7 +1476,7 @@ (or (tramp-check-cached-permissions v ?x) (tramp-run-test "-x" filename))))) -(defun tramp-handle-file-readable-p (filename) +(defun tramp-sh-handle-file-readable-p (filename) "Like `file-readable-p' for Tramp files." (with-parsed-tramp-file-name filename nil (with-file-property v localname "file-readable-p" @@ -1553,7 +1490,7 @@ ;; expansion will also provide a `test' command which groks `-nt' (for ;; newer than). If this breaks, tell me about it and I'll try to do ;; something smarter about it. -(defun tramp-handle-file-newer-than-file-p (file1 file2) +(defun tramp-sh-handle-file-newer-than-file-p (file1 file2) "Like `file-newer-than-file-p' for Tramp files." (cond ((not (file-exists-p file1)) nil) @@ -1588,13 +1525,7 @@ ;; Functions implemented using the basic functions above. -(defun tramp-handle-file-modes (filename) - "Like `file-modes' for Tramp files." - (let ((truename (or (file-truename filename) filename))) - (when (file-exists-p truename) - (tramp-mode-string-to-int (nth 8 (file-attributes truename)))))) - -(defun tramp-handle-file-directory-p (filename) +(defun tramp-sh-handle-file-directory-p (filename) "Like `file-directory-p' for Tramp files." ;; Care must be taken that this function returns `t' for symlinks ;; pointing to directories. Surely the most obvious implementation @@ -1608,23 +1539,7 @@ (with-file-property v localname "file-directory-p" (tramp-run-test "-d" filename)))) -(defun tramp-handle-file-regular-p (filename) - "Like `file-regular-p' for Tramp files." - (and (file-exists-p filename) - (eq ?- (aref (nth 8 (file-attributes filename)) 0)))) - -(defun tramp-handle-file-symlink-p (filename) - "Like `file-symlink-p' for Tramp files." - (with-parsed-tramp-file-name filename nil - (let ((x (car (file-attributes filename)))) - (when (stringp x) - ;; When Tramp is running on VMS, then `file-name-absolute-p' - ;; might do weird things. - (if (file-name-absolute-p x) - (tramp-make-tramp-file-name method user host x) - x))))) - -(defun tramp-handle-file-writable-p (filename) +(defun tramp-sh-handle-file-writable-p (filename) "Like `file-writable-p' for Tramp files." (with-parsed-tramp-file-name filename nil (with-file-property v localname "file-writable-p" @@ -1637,7 +1552,7 @@ (and (tramp-run-test "-d" (file-name-directory filename)) (tramp-run-test "-w" (file-name-directory filename))))))) -(defun tramp-handle-file-ownership-preserved-p (filename) +(defun tramp-sh-handle-file-ownership-preserved-p (filename) "Like `file-ownership-preserved-p' for Tramp files." (with-parsed-tramp-file-name filename nil (with-file-property v localname "file-ownership-preserved-p" @@ -1647,45 +1562,9 @@ (or (null attributes) (= (nth 2 attributes) (tramp-get-remote-uid v 'integer))))))) -;; Other file name ops. - -(defun tramp-handle-directory-file-name (directory) - "Like `directory-file-name' for Tramp files." - ;; If localname component of filename is "/", leave it unchanged. - ;; Otherwise, remove any trailing slash from localname component. - ;; Method, host, etc, are unchanged. Does it make sense to try - ;; to avoid parsing the filename? - (with-parsed-tramp-file-name directory nil - (if (and (not (zerop (length localname))) - (eq (aref localname (1- (length localname))) ?/) - (not (string= localname "/"))) - (substring directory 0 -1) - directory))) - ;; Directory listings. -(defun tramp-handle-directory-files - (directory &optional full match nosort files-only) - "Like `directory-files' for Tramp files." - ;; FILES-ONLY is valid for XEmacs only. - (when (file-directory-p directory) - (setq directory (file-name-as-directory (expand-file-name directory))) - (let ((temp (nreverse (file-name-all-completions "" directory))) - result item) - - (while temp - (setq item (directory-file-name (pop temp))) - (when (and (or (null match) (string-match match item)) - (or (null files-only) - ;; Files only. - (and (equal files-only t) (file-regular-p item)) - ;; Directories only. - (file-directory-p item))) - (push (if full (concat directory item) item) - result))) - (if nosort result (sort result 'string<))))) - -(defun tramp-handle-directory-files-and-attributes +(defun tramp-sh-handle-directory-files-and-attributes (directory &optional full match nosort id-format) "Like `directory-files-and-attributes' for Tramp files." (unless id-format (setq id-format 'integer)) @@ -1760,7 +1639,7 @@ ;; This function should return "foo/" for directories and "bar" for ;; files. -(defun tramp-handle-file-name-all-completions (filename directory) +(defun tramp-sh-handle-file-name-all-completions (filename directory) "Like `file-name-all-completions' for Tramp files." (unless (save-match-data (string-match "/" filename)) (with-parsed-tramp-file-name (expand-file-name directory) nil @@ -1866,7 +1745,7 @@ (forward-line -1) (tramp-error v 'file-error - "tramp-handle-file-name-all-completions: %s" + "tramp-sh-handle-file-name-all-completions: %s" (buffer-substring (point) (tramp-compat-line-end-position)))) ;; For peace of mind, if buffer doesn't end in `fail' @@ -1877,7 +1756,7 @@ (tramp-error v 'file-error "\ -tramp-handle-file-name-all-completions: internal error accessing `%s': `%s'" +tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'" (tramp-shell-quote-argument localname) (buffer-string)))) (while (zerop (forward-line -1)) @@ -1903,22 +1782,9 @@ "file-name-all-completions" result)))))))) -(defun tramp-handle-file-name-completion - (filename directory &optional predicate) - "Like `file-name-completion' for Tramp files." - (unless (tramp-tramp-file-p directory) - (error - "tramp-handle-file-name-completion invoked on non-tramp directory `%s'" - directory)) - (try-completion - filename - (mapcar 'list (file-name-all-completions filename directory)) - (when predicate - (lambda (x) (funcall predicate (expand-file-name (car x) directory)))))) - ;; cp, mv and ln -(defun tramp-handle-add-name-to-file +(defun tramp-sh-handle-add-name-to-file (filename newname &optional ok-if-already-exists) "Like `add-name-to-file' for Tramp files." (unless (tramp-equal-remote filename newname) @@ -1950,7 +1816,7 @@ "error with add-name-to-file, see buffer `%s' for details" (buffer-name)))))) -(defun tramp-handle-copy-file +(defun tramp-sh-handle-copy-file (filename newname &optional ok-if-already-exists keep-date preserve-uid-gid preserve-selinux-context) "Like `copy-file' for Tramp files." @@ -1977,7 +1843,8 @@ (tramp-run-real-handler 'copy-file (list filename newname ok-if-already-exists keep-date))))) -(defun tramp-handle-copy-directory (dirname newname &optional keep-date parents) +(defun tramp-sh-handle-copy-directory + (dirname newname &optional keep-date parents) "Like `copy-directory' for Tramp files." (let ((t1 (tramp-tramp-file-p dirname)) (t2 (tramp-tramp-file-p newname))) @@ -2013,7 +1880,7 @@ (tramp-flush-file-property v (file-name-directory localname)) (tramp-flush-file-property v localname)))))) -(defun tramp-handle-rename-file +(defun tramp-sh-handle-rename-file (filename newname &optional ok-if-already-exists) "Like `rename-file' for Tramp files." ;; Check if both files are local -- invoke normal rename-file. @@ -2041,9 +1908,10 @@ the uid and gid if both files are on the same host. PRESERVE-SELINUX-CONTEXT activates selinux commands. -This function is invoked by `tramp-handle-copy-file' and -`tramp-handle-rename-file'. It is an error if OP is neither of `copy' -and `rename'. FILENAME and NEWNAME must be absolute file names." +This function is invoked by `tramp-sh-handle-copy-file' and +`tramp-sh-handle-rename-file'. It is an error if OP is neither +of `copy' and `rename'. FILENAME and NEWNAME must be absolute +file names." (unless (memq op '(copy rename)) (error "Unknown operation `%s', must be `copy' or `rename'" op)) (let ((t1 (tramp-tramp-file-p filename)) @@ -2464,7 +2332,7 @@ (delete-file filename) (tramp-compat-delete-directory filename 'recursive)))))) -(defun tramp-handle-make-directory (dir &optional parents) +(defun tramp-sh-handle-make-directory (dir &optional parents) "Like `make-directory' for Tramp files." (setq dir (expand-file-name dir)) (with-parsed-tramp-file-name dir nil @@ -2476,7 +2344,7 @@ (tramp-shell-quote-argument localname)) "Couldn't make directory %s" dir)))) -(defun tramp-handle-delete-directory (directory &optional recursive) +(defun tramp-sh-handle-delete-directory (directory &optional recursive) "Like `delete-directory' for Tramp files." (setq directory (expand-file-name directory)) (with-parsed-tramp-file-name directory nil @@ -2488,7 +2356,7 @@ (tramp-shell-quote-argument localname)) "Couldn't delete %s" directory))) -(defun tramp-handle-delete-file (filename &optional trash) +(defun tramp-sh-handle-delete-file (filename &optional trash) "Like `delete-file' for Tramp files." (setq filename (expand-file-name filename)) (with-parsed-tramp-file-name filename nil @@ -2504,7 +2372,7 @@ ;; CCC: This does not seem to be enough. Something dies when ;; we try and delete two directories under Tramp :/ -(defun tramp-handle-dired-recursive-delete-directory (filename) +(defun tramp-sh-handle-dired-recursive-delete-directory (filename) "Recursively delete the directory given. This is like `dired-recursive-delete-directory' for Tramp files." (with-parsed-tramp-file-name filename nil @@ -2528,7 +2396,7 @@ (tramp-error v 'file-error "Failed to recursively delete %s" filename)))) -(defun tramp-handle-dired-compress-file (file &rest ok-flag) +(defun tramp-sh-handle-dired-compress-file (file &rest ok-flag) "Like `dired-compress-file' for Tramp files." ;; OK-FLAG is valid for XEmacs only, but not implemented. ;; Code stolen mainly from dired-aux.el. @@ -2582,14 +2450,7 @@ (concat file ".z")) (t nil)))))))))) -(defun tramp-handle-dired-uncache (dir &optional dir-p) - "Like `dired-uncache' for Tramp files." - ;; DIR-P is valid for XEmacs only. - (with-parsed-tramp-file-name - (if (or dir-p (file-directory-p dir)) dir (file-name-directory dir)) nil - (tramp-flush-directory-property v localname))) - -(defun tramp-handle-insert-directory +(defun tramp-sh-handle-insert-directory (filename switches &optional wildcard full-directory-p) "Like `insert-directory' for Tramp files." (setq filename (expand-file-name filename)) @@ -2692,15 +2553,9 @@ (goto-char (point-max)))))) -(defun tramp-handle-unhandled-file-name-directory (filename) - "Like `unhandled-file-name-directory' for Tramp files." - ;; With Emacs 23, we could simply return `nil'. But we must keep it - ;; for backward compatibility. - (expand-file-name "~/")) - ;; Canonicalization of file names. -(defun tramp-handle-expand-file-name (name &optional dir) +(defun tramp-sh-handle-expand-file-name (name &optional dir) "Like `expand-file-name' for Tramp files. If the localname part of the given filename starts with \"/../\" then the result will be a local, non-Tramp, filename." @@ -2759,41 +2614,9 @@ (tramp-run-real-handler 'expand-file-name (list localname)))))))) -(defun tramp-handle-substitute-in-file-name (filename) - "Like `substitute-in-file-name' for Tramp files. -\"//\" and \"/~\" substitute only in the local filename part. -If the URL Tramp syntax is chosen, \"//\" as method delimeter and \"/~\" at -beginning of local filename are not substituted." - ;; First, we must replace environment variables. - (setq filename (tramp-replace-environment-variables filename)) - (with-parsed-tramp-file-name filename nil - (if (equal tramp-syntax 'url) - ;; We need to check localname only. The other parts cannot contain - ;; "//" or "/~". - (if (and (> (length localname) 1) - (or (string-match "//" localname) - (string-match "/~" localname 1))) - (tramp-run-real-handler 'substitute-in-file-name (list filename)) - (tramp-make-tramp-file-name - (when method (substitute-in-file-name method)) - (when user (substitute-in-file-name user)) - (when host (substitute-in-file-name host)) - (when localname - (tramp-run-real-handler - 'substitute-in-file-name (list localname))))) - ;; Ignore in LOCALNAME everything before "//" or "/~". - (when (and (stringp localname) (string-match ".+?/\\(/\\|~\\)" localname)) - (setq filename - (concat (file-remote-p filename) - (replace-match "\\1" nil nil localname))) - ;; "/m:h:~" does not work for completion. We use "/m:h:~/". - (when (string-match "~$" filename) - (setq filename (concat filename "/")))) - (tramp-run-real-handler 'substitute-in-file-name (list filename))))) - ;;; Remote commands: -(defun tramp-handle-executable-find (command) +(defun tramp-sh-handle-executable-find (command) "Like `executable-find' for Tramp files." (with-parsed-tramp-file-name default-directory nil (tramp-find-executable v command (tramp-get-remote-path v) t))) @@ -2809,7 +2632,7 @@ ;; We use BUFFER also as connection buffer during setup. Because of ;; this, its original contents must be saved, and restored once ;; connection has been setup. -(defun tramp-handle-start-file-process (name buffer program &rest args) +(defun tramp-sh-handle-start-file-process (name buffer program &rest args) "Like `start-file-process' for Tramp files." (with-parsed-tramp-file-name default-directory nil (unwind-protect @@ -2868,7 +2691,7 @@ (tramp-set-connection-property v "process-name" nil) (tramp-set-connection-property v "process-buffer" nil)))) -(defun tramp-handle-process-file +(defun tramp-sh-handle-process-file (program &optional infile destination display &rest args) "Like `process-file' for Tramp files." ;; The implementation is not complete yet. @@ -2981,7 +2804,7 @@ (keyboard-quit) ret)))) -(defun tramp-handle-call-process-region +(defun tramp-sh-handle-call-process-region (start end program &optional delete buffer display &rest args) "Like `call-process-region' for Tramp files." (let ((tmpfile (tramp-compat-make-temp-file ""))) @@ -2991,7 +2814,7 @@ (apply 'call-process program tmpfile buffer display args) (delete-file tmpfile)))) -(defun tramp-handle-shell-command +(defun tramp-sh-handle-shell-command (command &optional output-buffer error-buffer) "Like `shell-command' for Tramp files." (let* ((asynchronous (string-match "[ \t]*&[ \t]*\\'" command)) @@ -3072,9 +2895,8 @@ (tramp-compat-funcall 'display-message-or-buffer output-buffer) (pop-to-buffer output-buffer)))))))) -(defun tramp-handle-file-local-copy (filename) +(defun tramp-sh-handle-file-local-copy (filename) "Like `file-local-copy' for Tramp files." - (with-parsed-tramp-file-name filename nil (unless (file-exists-p filename) (tramp-error @@ -3153,131 +2975,8 @@ (run-hooks 'tramp-handle-file-local-copy-hook) tmpfile))) -(defun tramp-handle-file-remote-p (filename &optional identification connected) - "Like `file-remote-p' for Tramp files." - (let ((tramp-verbose 3)) - (when (tramp-tramp-file-p filename) - (let* ((v (tramp-dissect-file-name filename)) - (p (tramp-get-connection-process v)) - (c (and p (processp p) (memq (process-status p) '(run open))))) - ;; We expand the file name only, if there is already a connection. - (with-parsed-tramp-file-name - (if c (expand-file-name filename) filename) nil - (and (or (not connected) c) - (cond - ((eq identification 'method) method) - ((eq identification 'user) user) - ((eq identification 'host) host) - ((eq identification 'localname) localname) - (t (tramp-make-tramp-file-name method user host ""))))))))) - -(defun tramp-handle-insert-file-contents - (filename &optional visit beg end replace) - "Like `insert-file-contents' for Tramp files." - (barf-if-buffer-read-only) - (setq filename (expand-file-name filename)) - (let (result local-copy remote-copy) - (with-parsed-tramp-file-name filename nil - (unwind-protect - (if (not (file-exists-p filename)) - ;; We don't raise a Tramp error, because it might be - ;; suppressed, like in `find-file-noselect-1'. - (signal 'file-error - (list "File not found on remote host" filename)) - - (if (and (tramp-local-host-p v) - (let (file-name-handler-alist) - (file-readable-p localname))) - ;; Short track: if we are on the local host, we can - ;; run directly. - (setq result - (tramp-run-real-handler - 'insert-file-contents - (list localname visit beg end replace))) - - ;; When we shall insert only a part of the file, we copy - ;; this part. - (when (or beg end) - (setq remote-copy (tramp-make-tramp-temp-file v)) - (tramp-send-command - v - (cond - ((and beg end) - (format "tail -c +%d %s | head -c +%d >%s" - (1+ beg) (tramp-shell-quote-argument localname) - (- end beg) remote-copy)) - (beg - (format "tail -c +%d %s >%s" - (1+ beg) (tramp-shell-quote-argument localname) - remote-copy)) - (end - (format "head -c +%d %s >%s" - (1+ end) (tramp-shell-quote-argument localname) - remote-copy))))) - - ;; `insert-file-contents-literally' takes care to avoid - ;; calling jka-compr. By let-binding - ;; `inhibit-file-name-operation', we propagate that care - ;; to the `file-local-copy' operation. - (setq local-copy - (let ((inhibit-file-name-operation - (when (eq inhibit-file-name-operation - 'insert-file-contents) - 'file-local-copy))) - (cond - ((stringp remote-copy) - (file-local-copy - (tramp-make-tramp-file-name - method user host remote-copy))) - ((stringp tramp-temp-buffer-file-name) - (copy-file filename tramp-temp-buffer-file-name 'ok) - tramp-temp-buffer-file-name) - (t (file-local-copy filename))))) - - ;; When the file is not readable for the owner, it - ;; cannot be inserted, even it is redable for the group - ;; or for everybody. - (set-file-modes local-copy (tramp-compat-octal-to-decimal "0600")) - - (when (and (null remote-copy) - (tramp-get-method-parameter - method 'tramp-copy-keep-tmpfile)) - ;; We keep the local file for performance reasons, - ;; useful for "rsync". - (setq tramp-temp-buffer-file-name local-copy) - (put 'tramp-temp-buffer-file-name 'permanent-local t)) - - (with-progress-reporter - v 3 (format "Inserting local temp file `%s'" local-copy) - ;; We must ensure that `file-coding-system-alist' - ;; matches `local-copy'. - (let ((file-coding-system-alist - (tramp-find-file-name-coding-system-alist - filename local-copy))) - (setq result - (insert-file-contents - local-copy nil nil nil replace)))))) - - ;; Save exit. - (progn - (when visit - (setq buffer-file-name filename) - (setq buffer-read-only (not (file-writable-p filename))) - (set-visited-file-modtime) - (set-buffer-modified-p nil)) - (when (and (stringp local-copy) - (or remote-copy (null tramp-temp-buffer-file-name))) - (delete-file local-copy)) - (when (stringp remote-copy) - (delete-file - (tramp-make-tramp-file-name method user host remote-copy)))))) - - ;; Result. - (list (expand-file-name filename) - (cadr result)))) - ;; This is needed for XEmacs only. Code stolen from files.el. -(defun tramp-handle-insert-file-contents-literally +(defun tramp-sh-handle-insert-file-contents-literally (filename &optional visit beg end replace) "Like `insert-file-contents-literally' for Tramp files." (let ((format-alist nil) @@ -3299,49 +2998,7 @@ (fset 'find-buffer-file-type find-buffer-file-type-function) (fmakunbound 'find-buffer-file-type))))) -(defun tramp-handle-find-backup-file-name (filename) - "Like `find-backup-file-name' for Tramp files." - (with-parsed-tramp-file-name filename nil - ;; We set both variables. It doesn't matter whether it is - ;; Emacs or XEmacs. - (let ((backup-directory-alist - ;; Emacs case. - (when (boundp 'backup-directory-alist) - (if (symbol-value 'tramp-backup-directory-alist) - (mapcar - (lambda (x) - (cons - (car x) - (if (and (stringp (cdr x)) - (file-name-absolute-p (cdr x)) - (not (tramp-file-name-p (cdr x)))) - (tramp-make-tramp-file-name method user host (cdr x)) - (cdr x)))) - (symbol-value 'tramp-backup-directory-alist)) - (symbol-value 'backup-directory-alist)))) - - (bkup-backup-directory-info - ;; XEmacs case. - (when (boundp 'bkup-backup-directory-info) - (if (symbol-value 'tramp-bkup-backup-directory-info) - (mapcar - (lambda (x) - (nconc - (list (car x)) - (list - (if (and (stringp (car (cdr x))) - (file-name-absolute-p (car (cdr x))) - (not (tramp-file-name-p (car (cdr x))))) - (tramp-make-tramp-file-name - method user host (car (cdr x))) - (car (cdr x)))) - (cdr (cdr x)))) - (symbol-value 'tramp-bkup-backup-directory-info)) - (symbol-value 'bkup-backup-directory-info))))) - - (tramp-run-real-handler 'find-backup-file-name (list filename))))) - -(defun tramp-handle-make-auto-save-file-name () +(defun tramp-sh-handle-make-auto-save-file-name () "Like `make-auto-save-file-name' for Tramp files. Returns a file name in `tramp-auto-save-directory' for autosaving this file." (let ((tramp-auto-save-directory tramp-auto-save-directory) @@ -3383,11 +3040,8 @@ (tramp-run-real-handler 'make-auto-save-file-name nil) (ad-activate 'make-auto-save-file-name))))) -(defvar tramp-handle-write-region-hook nil - "Normal hook to be run at the end of `tramp-handle-write-region'.") - ;; CCC grok LOCKNAME -(defun tramp-handle-write-region +(defun tramp-sh-handle-write-region (start end filename &optional append visit lockname confirm) "Like `write-region' for Tramp files." (setq filename (expand-file-name filename)) @@ -3400,7 +3054,7 @@ ;; (unless (or (eq lockname nil) ;; (string= lockname filename)) ;; (error - ;; "tramp-handle-write-region: LOCKNAME must be nil or equal FILENAME")) + ;; "tramp-sh-handle-write-region: LOCKNAME must be nil or equal FILENAME")) ;; XEmacs takes a coding system as the seventh argument, not `confirm'. (when (and (not (featurep 'xemacs)) confirm (file-exists-p filename)) @@ -3649,7 +3303,7 @@ ;; can reset the file name handlers, and we make a second run of ;; `vc-registered', which returns the expected result without sending ;; any other remote command. -(defun tramp-handle-vc-registered (file) +(defun tramp-sh-handle-vc-registered (file) "Like `vc-registered' for Tramp files." (tramp-compat-with-temp-message "" (with-parsed-tramp-file-name file nil @@ -4791,77 +4445,6 @@ "`%s' does not return a valid Lisp expression: `%s'" command (buffer-string)))))) -(defun tramp-mode-string-to-int (mode-string) - "Converts a ten-letter `drwxrwxrwx'-style mode string into mode bits." - (let* (case-fold-search - (mode-chars (string-to-vector mode-string)) - (owner-read (aref mode-chars 1)) - (owner-write (aref mode-chars 2)) - (owner-execute-or-setid (aref mode-chars 3)) - (group-read (aref mode-chars 4)) - (group-write (aref mode-chars 5)) - (group-execute-or-setid (aref mode-chars 6)) - (other-read (aref mode-chars 7)) - (other-write (aref mode-chars 8)) - (other-execute-or-sticky (aref mode-chars 9))) - (save-match-data - (logior - (cond - ((char-equal owner-read ?r) (tramp-compat-octal-to-decimal "00400")) - ((char-equal owner-read ?-) 0) - (t (error "Second char `%c' must be one of `r-'" owner-read))) - (cond - ((char-equal owner-write ?w) (tramp-compat-octal-to-decimal "00200")) - ((char-equal owner-write ?-) 0) - (t (error "Third char `%c' must be one of `w-'" owner-write))) - (cond - ((char-equal owner-execute-or-setid ?x) - (tramp-compat-octal-to-decimal "00100")) - ((char-equal owner-execute-or-setid ?S) - (tramp-compat-octal-to-decimal "04000")) - ((char-equal owner-execute-or-setid ?s) - (tramp-compat-octal-to-decimal "04100")) - ((char-equal owner-execute-or-setid ?-) 0) - (t (error "Fourth char `%c' must be one of `xsS-'" - owner-execute-or-setid))) - (cond - ((char-equal group-read ?r) (tramp-compat-octal-to-decimal "00040")) - ((char-equal group-read ?-) 0) - (t (error "Fifth char `%c' must be one of `r-'" group-read))) - (cond - ((char-equal group-write ?w) (tramp-compat-octal-to-decimal "00020")) - ((char-equal group-write ?-) 0) - (t (error "Sixth char `%c' must be one of `w-'" group-write))) - (cond - ((char-equal group-execute-or-setid ?x) - (tramp-compat-octal-to-decimal "00010")) - ((char-equal group-execute-or-setid ?S) - (tramp-compat-octal-to-decimal "02000")) - ((char-equal group-execute-or-setid ?s) - (tramp-compat-octal-to-decimal "02010")) - ((char-equal group-execute-or-setid ?-) 0) - (t (error "Seventh char `%c' must be one of `xsS-'" - group-execute-or-setid))) - (cond - ((char-equal other-read ?r) - (tramp-compat-octal-to-decimal "00004")) - ((char-equal other-read ?-) 0) - (t (error "Eighth char `%c' must be one of `r-'" other-read))) - (cond - ((char-equal other-write ?w) (tramp-compat-octal-to-decimal "00002")) - ((char-equal other-write ?-) 0) - (t (error "Nineth char `%c' must be one of `w-'" other-write))) - (cond - ((char-equal other-execute-or-sticky ?x) - (tramp-compat-octal-to-decimal "00001")) - ((char-equal other-execute-or-sticky ?T) - (tramp-compat-octal-to-decimal "01000")) - ((char-equal other-execute-or-sticky ?t) - (tramp-compat-octal-to-decimal "01001")) - ((char-equal other-execute-or-sticky ?-) 0) - (t (error "Tenth char `%c' must be one of `xtT-'" - other-execute-or-sticky))))))) - (defun tramp-convert-file-attributes (vec attr) "Convert file-attributes ATTR generated by perl script, stat or ls. Convert file mode bits to string and set virtual device number. @@ -5024,30 +4607,6 @@ (> size tramp-copy-size-limit) (null (tramp-get-inline-coding vec "remote-encoding" size))))) -(defun tramp-local-host-p (vec) - "Return t if this points to the local host, nil otherwise." - ;; We cannot use `tramp-file-name-real-host'. A port is an - ;; indication for an ssh tunnel or alike. - (let ((host (tramp-file-name-host vec))) - (and - (stringp host) - (string-match tramp-local-host-regexp host) - ;; The method shall be applied to one of the shell file name - ;; handler. `tramp-local-host-p' is also called for "smb" and - ;; alike, where it must fail. - (tramp-get-method-parameter - (tramp-file-name-method vec) 'tramp-login-program) - ;; The local temp directory must be writable for the other user. - (file-writable-p - (tramp-make-tramp-file-name - (tramp-file-name-method vec) - (tramp-file-name-user vec) - host - (tramp-compat-temporary-file-directory))) - ;; On some systems, chown runs only for root. - (or (zerop (user-uid)) - (zerop (tramp-get-remote-uid vec 'integer)))))) - ;; Variables local to connection. (defun tramp-get-remote-path (vec) @@ -5133,33 +4692,6 @@ dir (tramp-error vec 'file-error "Directory %s not accessible" dir))))) -(defun tramp-make-tramp-temp-file (vec) - "Create a temporary file on the remote host identified by VEC. -Return the local name of the temporary file." - (let ((prefix - (tramp-make-tramp-file-name - (tramp-file-name-method vec) - (tramp-file-name-user vec) - (tramp-file-name-host vec) - (tramp-drop-volume-letter - (expand-file-name - tramp-temp-name-prefix (tramp-get-remote-tmpdir vec))))) - result) - (while (not result) - ;; `make-temp-file' would be the natural choice for - ;; implementation. But it calls `write-region' internally, - ;; which also needs a temporary file - we would end in an - ;; infinite loop. - (setq result (make-temp-name prefix)) - (if (file-exists-p result) - (setq result nil) - ;; This creates the file by side effect. - (set-file-times result) - (set-file-modes result (tramp-compat-octal-to-decimal "0700")))) - - ;; Return the local part. - (with-parsed-tramp-file-name result nil localname))) - (defun tramp-get-ls-command (vec) (with-connection-property vec "ls" (tramp-message vec 5 "Finding a suitable `ls' command")
--- a/lisp/net/tramp-smb.el Mon Oct 04 21:34:35 2010 +0200 +++ b/lisp/net/tramp-smb.el Mon Oct 04 21:44:08 2010 +0200 @@ -31,10 +31,6 @@ (eval-when-compile (require 'cl)) ; block, return (require 'tramp) -;; We call several `tramp-handle-*' functions directly. So we must -;; reqire that package as well. -(require 'tramp-sh) - ;; Define SMB method ... ;;;###tramp-autoload (defconst tramp-smb-method "smb"
--- a/lisp/net/tramp.el Mon Oct 04 21:34:35 2010 +0200 +++ b/lisp/net/tramp.el Mon Oct 04 21:44:08 2010 +0200 @@ -761,7 +761,7 @@ (defconst tramp-localname-regexp ".*$" "*Regexp matching localnames.") -;; File name format. +;;; File name format: (defconst tramp-file-name-structure (list @@ -1009,10 +1009,6 @@ ;;; Internal functions which must come first: - -;; ------------------------------------------------------------ -;; -- Tramp file names -- -;; ------------------------------------------------------------ ;; Conversion functions between external representation and ;; internal data structure. Convenience functions for internal ;; data structure. @@ -1658,9 +1654,6 @@ '(minibuffer-electric-separator minibuffer-electric-tilde))) -(defvar tramp-handle-file-local-copy-hook nil - "Normal hook to be run at the end of `tramp-handle-file-local-copy'.") - (defun tramp-find-file-name-coding-system-alist (filename tmpname) "Like `find-operation-coding-system' for Tramp filenames. Tramp's `insert-file-contents' and `write-region' work over @@ -1952,9 +1945,29 @@ ;; `tramp-file-name-handler' must be registered before evaluation of ;; site-start and init files, because there might exist remote files ;; already, f.e. files kept via recentf-mode. -;;;###autoload(tramp-register-file-name-handlers) +;;;###autoload (tramp-register-file-name-handlers) +(defun tramp-exists-file-name-handler (operation &rest args) + "Check, whether OPERATION runs a file name handler." + ;; The file name handler is determined on base of either an + ;; argument, `buffer-file-name', or `default-directory'. + (ignore-errors + (let* ((buffer-file-name "/") + (default-directory "/") + (fnha file-name-handler-alist) + (check-file-name-operation operation) + (file-name-handler-alist + (list + (cons "/" + (lambda (operation &rest args) + "Returns OPERATION if it is the one to be checked." + (if (equal check-file-name-operation operation) + operation + (let ((file-name-handler-alist fnha)) + (apply operation args)))))))) + (equal (apply operation args) operation)))) + ;;;###autoload (defun tramp-unload-file-name-handlers () (setq file-name-handler-alist @@ -2554,20 +2567,360 @@ (forward-line 1) result)) -(defun tramp-delete-temp-file-function () - "Remove temporary files related to current buffer." - (when (stringp tramp-temp-buffer-file-name) - (ignore-errors (delete-file tramp-temp-buffer-file-name)))) - -(add-hook 'kill-buffer-hook 'tramp-delete-temp-file-function) -(add-hook 'tramp-cache-unload-hook - (lambda () - (remove-hook 'kill-buffer-hook - 'tramp-delete-temp-file-function))) - -;; ------------------------------------------------------------ -;; -- Functions for establishing connection -- -;; ------------------------------------------------------------ +;;; Common file name handler functions for different backends: + +(defvar tramp-handle-file-local-copy-hook nil + "Normal hook to be run at the end of `tramp-*-handle-file-local-copy'.") + +(defvar tramp-handle-write-region-hook nil + "Normal hook to be run at the end of `tramp-*-handle-write-region'.") + +(defun tramp-handle-directory-file-name (directory) + "Like `directory-file-name' for Tramp files." + ;; If localname component of filename is "/", leave it unchanged. + ;; Otherwise, remove any trailing slash from localname component. + ;; Method, host, etc, are unchanged. Does it make sense to try + ;; to avoid parsing the filename? + (with-parsed-tramp-file-name directory nil + (if (and (not (zerop (length localname))) + (eq (aref localname (1- (length localname))) ?/) + (not (string= localname "/"))) + (substring directory 0 -1) + directory))) + +(defun tramp-handle-directory-files + (directory &optional full match nosort files-only) + "Like `directory-files' for Tramp files." + ;; FILES-ONLY is valid for XEmacs only. + (when (file-directory-p directory) + (setq directory (file-name-as-directory (expand-file-name directory))) + (let ((temp (nreverse (file-name-all-completions "" directory))) + result item) + + (while temp + (setq item (directory-file-name (pop temp))) + (when (and (or (null match) (string-match match item)) + (or (null files-only) + ;; Files only. + (and (equal files-only t) (file-regular-p item)) + ;; Directories only. + (file-directory-p item))) + (push (if full (concat directory item) item) + result))) + (if nosort result (sort result 'string<))))) + +(defun tramp-handle-dired-uncache (dir &optional dir-p) + "Like `dired-uncache' for Tramp files." + ;; DIR-P is valid for XEmacs only. + (with-parsed-tramp-file-name + (if (or dir-p (file-directory-p dir)) dir (file-name-directory dir)) nil + (tramp-flush-directory-property v localname))) + +(defun tramp-handle-file-modes (filename) + "Like `file-modes' for Tramp files." + (let ((truename (or (file-truename filename) filename))) + (when (file-exists-p truename) + (tramp-mode-string-to-int (nth 8 (file-attributes truename)))))) + +;; Localname manipulation functions that grok Tramp localnames... +(defun tramp-handle-file-name-as-directory (file) + "Like `file-name-as-directory' but aware of Tramp files." + ;; `file-name-as-directory' would be sufficient except localname is + ;; the empty string. + (let ((v (tramp-dissect-file-name file t))) + ;; Run the command on the localname portion only. + (tramp-make-tramp-file-name + (tramp-file-name-method v) + (tramp-file-name-user v) + (tramp-file-name-host v) + (tramp-run-real-handler + 'file-name-as-directory (list (or (tramp-file-name-localname v) "")))))) + +(defun tramp-handle-file-name-completion + (filename directory &optional predicate) + "Like `file-name-completion' for Tramp files." + (unless (tramp-tramp-file-p directory) + (error + "tramp-handle-file-name-completion invoked on non-tramp directory `%s'" + directory)) + (try-completion + filename + (mapcar 'list (file-name-all-completions filename directory)) + (when predicate + (lambda (x) (funcall predicate (expand-file-name (car x) directory)))))) + +(defun tramp-handle-file-name-directory (file) + "Like `file-name-directory' but aware of Tramp files." + ;; Everything except the last filename thing is the directory. We + ;; cannot apply `with-parsed-tramp-file-name', because this expands + ;; the remote file name parts. This is a problem when we are in + ;; file name completion. + (let ((v (tramp-dissect-file-name file t))) + ;; Run the command on the localname portion only. + (tramp-make-tramp-file-name + (tramp-file-name-method v) + (tramp-file-name-user v) + (tramp-file-name-host v) + (tramp-run-real-handler + 'file-name-directory (list (or (tramp-file-name-localname v) "")))))) + +(defun tramp-handle-file-name-nondirectory (file) + "Like `file-name-nondirectory' but aware of Tramp files." + (with-parsed-tramp-file-name file nil + (tramp-run-real-handler 'file-name-nondirectory (list localname)))) + +(defun tramp-handle-file-regular-p (filename) + "Like `file-regular-p' for Tramp files." + (and (file-exists-p filename) + (eq ?- (aref (nth 8 (file-attributes filename)) 0)))) + +(defun tramp-handle-file-remote-p (filename &optional identification connected) + "Like `file-remote-p' for Tramp files." + (let ((tramp-verbose 3)) + (when (tramp-tramp-file-p filename) + (let* ((v (tramp-dissect-file-name filename)) + (p (tramp-get-connection-process v)) + (c (and p (processp p) (memq (process-status p) '(run open))))) + ;; We expand the file name only, if there is already a connection. + (with-parsed-tramp-file-name + (if c (expand-file-name filename) filename) nil + (and (or (not connected) c) + (cond + ((eq identification 'method) method) + ((eq identification 'user) user) + ((eq identification 'host) host) + ((eq identification 'localname) localname) + (t (tramp-make-tramp-file-name method user host ""))))))))) + +(defun tramp-handle-file-symlink-p (filename) + "Like `file-symlink-p' for Tramp files." + (with-parsed-tramp-file-name filename nil + (let ((x (car (file-attributes filename)))) + (when (stringp x) + ;; When Tramp is running on VMS, then `file-name-absolute-p' + ;; might do weird things. + (if (file-name-absolute-p x) + (tramp-make-tramp-file-name method user host x) + x))))) + +(defun tramp-handle-find-backup-file-name (filename) + "Like `find-backup-file-name' for Tramp files." + (with-parsed-tramp-file-name filename nil + ;; We set both variables. It doesn't matter whether it is + ;; Emacs or XEmacs. + (let ((backup-directory-alist + ;; Emacs case. + (when (boundp 'backup-directory-alist) + (if (symbol-value 'tramp-backup-directory-alist) + (mapcar + (lambda (x) + (cons + (car x) + (if (and (stringp (cdr x)) + (file-name-absolute-p (cdr x)) + (not (tramp-file-name-p (cdr x)))) + (tramp-make-tramp-file-name method user host (cdr x)) + (cdr x)))) + (symbol-value 'tramp-backup-directory-alist)) + (symbol-value 'backup-directory-alist)))) + + (bkup-backup-directory-info + ;; XEmacs case. + (when (boundp 'bkup-backup-directory-info) + (if (symbol-value 'tramp-bkup-backup-directory-info) + (mapcar + (lambda (x) + (nconc + (list (car x)) + (list + (if (and (stringp (car (cdr x))) + (file-name-absolute-p (car (cdr x))) + (not (tramp-file-name-p (car (cdr x))))) + (tramp-make-tramp-file-name + method user host (car (cdr x))) + (car (cdr x)))) + (cdr (cdr x)))) + (symbol-value 'tramp-bkup-backup-directory-info)) + (symbol-value 'bkup-backup-directory-info))))) + + (tramp-run-real-handler 'find-backup-file-name (list filename))))) + +(defun tramp-handle-insert-file-contents + (filename &optional visit beg end replace) + "Like `insert-file-contents' for Tramp files." + (barf-if-buffer-read-only) + (setq filename (expand-file-name filename)) + (let (result local-copy remote-copy) + (with-parsed-tramp-file-name filename nil + (unwind-protect + (if (not (file-exists-p filename)) + ;; We don't raise a Tramp error, because it might be + ;; suppressed, like in `find-file-noselect-1'. + (signal 'file-error + (list "File not found on remote host" filename)) + + (if (and (tramp-local-host-p v) + (let (file-name-handler-alist) + (file-readable-p localname))) + ;; Short track: if we are on the local host, we can + ;; run directly. + (setq result + (tramp-run-real-handler + 'insert-file-contents + (list localname visit beg end replace))) + + ;; When we shall insert only a part of the file, we copy + ;; this part. + (when (or beg end) + (setq remote-copy (tramp-make-tramp-temp-file v)) + ;; This is defined in tramp-sh.el. Let's assume this + ;; is loaded already. + (tramp-compat-funcall 'tramp-send-command + v + (cond + ((and beg end) + (format "tail -c +%d %s | head -c +%d >%s" + (1+ beg) (tramp-shell-quote-argument localname) + (- end beg) remote-copy)) + (beg + (format "tail -c +%d %s >%s" + (1+ beg) (tramp-shell-quote-argument localname) + remote-copy)) + (end + (format "head -c +%d %s >%s" + (1+ end) (tramp-shell-quote-argument localname) + remote-copy))))) + + ;; `insert-file-contents-literally' takes care to avoid + ;; calling jka-compr. By let-binding + ;; `inhibit-file-name-operation', we propagate that care + ;; to the `file-local-copy' operation. + (setq local-copy + (let ((inhibit-file-name-operation + (when (eq inhibit-file-name-operation + 'insert-file-contents) + 'file-local-copy))) + (cond + ((stringp remote-copy) + (file-local-copy + (tramp-make-tramp-file-name + method user host remote-copy))) + ((stringp tramp-temp-buffer-file-name) + (copy-file filename tramp-temp-buffer-file-name 'ok) + tramp-temp-buffer-file-name) + (t (file-local-copy filename))))) + + ;; When the file is not readable for the owner, it + ;; cannot be inserted, even it is redable for the group + ;; or for everybody. + (set-file-modes local-copy (tramp-compat-octal-to-decimal "0600")) + + (when (and (null remote-copy) + (tramp-get-method-parameter + method 'tramp-copy-keep-tmpfile)) + ;; We keep the local file for performance reasons, + ;; useful for "rsync". + (setq tramp-temp-buffer-file-name local-copy) + (put 'tramp-temp-buffer-file-name 'permanent-local t)) + + (with-progress-reporter + v 3 (format "Inserting local temp file `%s'" local-copy) + ;; We must ensure that `file-coding-system-alist' + ;; matches `local-copy'. + (let ((file-coding-system-alist + (tramp-find-file-name-coding-system-alist + filename local-copy))) + (setq result + (insert-file-contents + local-copy nil nil nil replace)))))) + + ;; Save exit. + (progn + (when visit + (setq buffer-file-name filename) + (setq buffer-read-only (not (file-writable-p filename))) + (set-visited-file-modtime) + (set-buffer-modified-p nil)) + (when (and (stringp local-copy) + (or remote-copy (null tramp-temp-buffer-file-name))) + (delete-file local-copy)) + (when (stringp remote-copy) + (delete-file + (tramp-make-tramp-file-name method user host remote-copy)))))) + + ;; Result. + (list (expand-file-name filename) + (cadr result)))) + +(defun tramp-handle-load (file &optional noerror nomessage nosuffix must-suffix) + "Like `load' for Tramp files." + (with-parsed-tramp-file-name (expand-file-name file) nil + (unless nosuffix + (cond ((file-exists-p (concat file ".elc")) + (setq file (concat file ".elc"))) + ((file-exists-p (concat file ".el")) + (setq file (concat file ".el"))))) + (when must-suffix + ;; The first condition is always true for absolute file names. + ;; Included for safety's sake. + (unless (or (file-name-directory file) + (string-match "\\.elc?\\'" file)) + (tramp-error + v 'file-error + "File `%s' does not include a `.el' or `.elc' suffix" file))) + (unless noerror + (when (not (file-exists-p file)) + (tramp-error v 'file-error "Cannot load nonexistent file `%s'" file))) + (if (not (file-exists-p file)) + nil + (let ((tramp-message-show-message (not nomessage))) + (with-progress-reporter v 0 (format "Loading %s" file) + (let ((local-copy (file-local-copy file))) + ;; MUST-SUFFIX doesn't exist on XEmacs, so let it default to nil. + (unwind-protect + (load local-copy noerror t t) + (delete-file local-copy))))) + t))) + +(defun tramp-handle-substitute-in-file-name (filename) + "Like `substitute-in-file-name' for Tramp files. +\"//\" and \"/~\" substitute only in the local filename part. +If the URL Tramp syntax is chosen, \"//\" as method delimeter and \"/~\" at +beginning of local filename are not substituted." + ;; First, we must replace environment variables. + (setq filename (tramp-replace-environment-variables filename)) + (with-parsed-tramp-file-name filename nil + (if (equal tramp-syntax 'url) + ;; We need to check localname only. The other parts cannot contain + ;; "//" or "/~". + (if (and (> (length localname) 1) + (or (string-match "//" localname) + (string-match "/~" localname 1))) + (tramp-run-real-handler 'substitute-in-file-name (list filename)) + (tramp-make-tramp-file-name + (when method (substitute-in-file-name method)) + (when user (substitute-in-file-name user)) + (when host (substitute-in-file-name host)) + (when localname + (tramp-run-real-handler + 'substitute-in-file-name (list localname))))) + ;; Ignore in LOCALNAME everything before "//" or "/~". + (when (and (stringp localname) (string-match ".+?/\\(/\\|~\\)" localname)) + (setq filename + (concat (file-remote-p filename) + (replace-match "\\1" nil nil localname))) + ;; "/m:h:~" does not work for completion. We use "/m:h:~/". + (when (string-match "~$" filename) + (setq filename (concat filename "/")))) + (tramp-run-real-handler 'substitute-in-file-name (list filename))))) + +(defun tramp-handle-unhandled-file-name-directory (filename) + "Like `unhandled-file-name-directory' for Tramp files." + ;; With Emacs 23, we could simply return `nil'. But we must keep it + ;; for backward compatibility. + (expand-file-name "~/")) + +;;; Functions for establishing connection: ;; The following functions are actions to be taken when seeing certain ;; prompts from the remote host. See the variable @@ -2666,7 +3019,7 @@ (throw 'tramp-action 'process-died)))) (t nil))) -;; Functions for processing the actions. +;;; Functions for processing the actions: (defun tramp-process-one-action (proc vec actions) "Wait for output from the shell and perform one action." @@ -2714,7 +3067,7 @@ ((eq exit 'process-died) "Process died") (t "Login failed"))))))) -;; Utility functions. +:;; Utility functions: (defun tramp-accept-process-output (&optional proc timeout timeout-msecs) "Like `accept-process-output' for Tramp processes. @@ -2902,27 +3255,145 @@ (let ((entry (assoc param (assoc method tramp-methods)))) (when entry (cadr entry)))) -;; Auto saving to a special directory. - -(defun tramp-exists-file-name-handler (operation &rest args) - "Check, whether OPERATION runs a file name handler." - ;; The file name handler is determined on base of either an - ;; argument, `buffer-file-name', or `default-directory'. - (ignore-errors - (let* ((buffer-file-name "/") - (default-directory "/") - (fnha file-name-handler-alist) - (check-file-name-operation operation) - (file-name-handler-alist - (list - (cons "/" - (lambda (operation &rest args) - "Returns OPERATION if it is the one to be checked." - (if (equal check-file-name-operation operation) - operation - (let ((file-name-handler-alist fnha)) - (apply operation args)))))))) - (equal (apply operation args) operation)))) +(defun tramp-mode-string-to-int (mode-string) + "Converts a ten-letter `drwxrwxrwx'-style mode string into mode bits." + (let* (case-fold-search + (mode-chars (string-to-vector mode-string)) + (owner-read (aref mode-chars 1)) + (owner-write (aref mode-chars 2)) + (owner-execute-or-setid (aref mode-chars 3)) + (group-read (aref mode-chars 4)) + (group-write (aref mode-chars 5)) + (group-execute-or-setid (aref mode-chars 6)) + (other-read (aref mode-chars 7)) + (other-write (aref mode-chars 8)) + (other-execute-or-sticky (aref mode-chars 9))) + (save-match-data + (logior + (cond + ((char-equal owner-read ?r) (tramp-compat-octal-to-decimal "00400")) + ((char-equal owner-read ?-) 0) + (t (error "Second char `%c' must be one of `r-'" owner-read))) + (cond + ((char-equal owner-write ?w) (tramp-compat-octal-to-decimal "00200")) + ((char-equal owner-write ?-) 0) + (t (error "Third char `%c' must be one of `w-'" owner-write))) + (cond + ((char-equal owner-execute-or-setid ?x) + (tramp-compat-octal-to-decimal "00100")) + ((char-equal owner-execute-or-setid ?S) + (tramp-compat-octal-to-decimal "04000")) + ((char-equal owner-execute-or-setid ?s) + (tramp-compat-octal-to-decimal "04100")) + ((char-equal owner-execute-or-setid ?-) 0) + (t (error "Fourth char `%c' must be one of `xsS-'" + owner-execute-or-setid))) + (cond + ((char-equal group-read ?r) (tramp-compat-octal-to-decimal "00040")) + ((char-equal group-read ?-) 0) + (t (error "Fifth char `%c' must be one of `r-'" group-read))) + (cond + ((char-equal group-write ?w) (tramp-compat-octal-to-decimal "00020")) + ((char-equal group-write ?-) 0) + (t (error "Sixth char `%c' must be one of `w-'" group-write))) + (cond + ((char-equal group-execute-or-setid ?x) + (tramp-compat-octal-to-decimal "00010")) + ((char-equal group-execute-or-setid ?S) + (tramp-compat-octal-to-decimal "02000")) + ((char-equal group-execute-or-setid ?s) + (tramp-compat-octal-to-decimal "02010")) + ((char-equal group-execute-or-setid ?-) 0) + (t (error "Seventh char `%c' must be one of `xsS-'" + group-execute-or-setid))) + (cond + ((char-equal other-read ?r) + (tramp-compat-octal-to-decimal "00004")) + ((char-equal other-read ?-) 0) + (t (error "Eighth char `%c' must be one of `r-'" other-read))) + (cond + ((char-equal other-write ?w) (tramp-compat-octal-to-decimal "00002")) + ((char-equal other-write ?-) 0) + (t (error "Nineth char `%c' must be one of `w-'" other-write))) + (cond + ((char-equal other-execute-or-sticky ?x) + (tramp-compat-octal-to-decimal "00001")) + ((char-equal other-execute-or-sticky ?T) + (tramp-compat-octal-to-decimal "01000")) + ((char-equal other-execute-or-sticky ?t) + (tramp-compat-octal-to-decimal "01001")) + ((char-equal other-execute-or-sticky ?-) 0) + (t (error "Tenth char `%c' must be one of `xtT-'" + other-execute-or-sticky))))))) + +(defun tramp-local-host-p (vec) + "Return t if this points to the local host, nil otherwise." + ;; We cannot use `tramp-file-name-real-host'. A port is an + ;; indication for an ssh tunnel or alike. + (let ((host (tramp-file-name-host vec))) + (and + (stringp host) + (string-match tramp-local-host-regexp host) + ;; The method shall be applied to one of the shell file name + ;; handler. `tramp-local-host-p' is also called for "smb" and + ;; alike, where it must fail. + (tramp-get-method-parameter + (tramp-file-name-method vec) 'tramp-login-program) + ;; The local temp directory must be writable for the other user. + (file-writable-p + (tramp-make-tramp-file-name + (tramp-file-name-method vec) + (tramp-file-name-user vec) + host + (tramp-compat-temporary-file-directory))) + ;; On some systems, chown runs only for root. + (or (zerop (user-uid)) + ;; This is defined in tramp-sh.el. Let's assume this is + ;; loaded already. + (zerop (tramp-compat-funcall 'tramp-get-remote-uid vec 'integer)))))) + +(defun tramp-make-tramp-temp-file (vec) + "Create a temporary file on the remote host identified by VEC. +Return the local name of the temporary file." + (let ((prefix + (tramp-make-tramp-file-name + (tramp-file-name-method vec) + (tramp-file-name-user vec) + (tramp-file-name-host vec) + (tramp-drop-volume-letter + (expand-file-name + tramp-temp-name-prefix + ;; This is defined in tramp-sh.el. Let's assume this is + ;; loaded already. + (tramp-compat-funcall 'tramp-get-remote-tmpdir vec))))) + result) + (while (not result) + ;; `make-temp-file' would be the natural choice for + ;; implementation. But it calls `write-region' internally, + ;; which also needs a temporary file - we would end in an + ;; infinite loop. + (setq result (make-temp-name prefix)) + (if (file-exists-p result) + (setq result nil) + ;; This creates the file by side effect. + (set-file-times result) + (set-file-modes result (tramp-compat-octal-to-decimal "0700")))) + + ;; Return the local part. + (with-parsed-tramp-file-name result nil localname))) + +(defun tramp-delete-temp-file-function () + "Remove temporary files related to current buffer." + (when (stringp tramp-temp-buffer-file-name) + (ignore-errors (delete-file tramp-temp-buffer-file-name)))) + +(add-hook 'kill-buffer-hook 'tramp-delete-temp-file-function) +(add-hook 'tramp-cache-unload-hook + (lambda () + (remove-hook 'kill-buffer-hook + 'tramp-delete-temp-file-function))) + +;;; Auto saving to a special directory: (unless (tramp-exists-file-name-handler 'make-auto-save-file-name) (defadvice make-auto-save-file-name @@ -2982,9 +3453,7 @@ (setq alist (cdr alist)))) string)) -;; ------------------------------------------------------------ -;; -- Compatibility functions section -- -;; ------------------------------------------------------------ +;;; Compatibility functions section: (defun tramp-read-passwd (proc &optional prompt) "Read a password from user (compat function). @@ -3108,11 +3577,6 @@ (tramp-compat-funcall 'set-process-query-on-exit-flag process flag) (tramp-compat-funcall 'process-kill-without-query process flag))) - -;; ------------------------------------------------------------ -;; -- Kludges section -- -;; ------------------------------------------------------------ - ;; Currently (as of Emacs 20.5), the function `shell-quote-argument' ;; does not deal well with newline characters. Newline is replaced by ;; backslash newline. But if, say, the string `a backslash newline b'