tramp-ftp.el 6.47 KB
Newer Older
Michael Albinus's avatar
Michael Albinus committed
1
;;; tramp-ftp.el --- Tramp convenience functions for Ange-FTP -*- coding: iso-8859-1; -*-
2

Michael Albinus's avatar
Michael Albinus committed
3 4
;; Copyright (C) 2002, 2003, 2004, 2005, 2006,
;;   2007 Free Software Foundation, Inc.
5

Michael Albinus's avatar
Michael Albinus committed
6
;; Author: Michael Albinus <michael.albinus@gmx.de>
7 8 9 10 11 12
;; Keywords: comm, processes

;; This file is part of GNU Emacs.

;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
13 14
;; the Free Software Foundation; either version 3 of the License, or
;; (at your option) any later version.
15 16 17 18 19 20 21

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
22 23
;; along with GNU Emacs; see the file COPYING.  If not, see
;; <http://www.gnu.org/licenses/>.
24 25 26

;;; Commentary:

27 28
;; Convenience functions for calling Ange-FTP from Tramp.
;; Most of them are displaced from tramp.el.
29 30 31 32 33

;;; Code:

(require 'tramp)

Michael Albinus's avatar
Michael Albinus committed
34
(eval-when-compile (require 'custom))
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

;; Disable Ange-FTP from file-name-handler-alist.
;; To handle EFS, the following functions need to be dealt with:
;;
;; * dired-before-readin-hook contains efs-dired-before-readin
;; * file-name-handler-alist contains efs-file-handler-function
;;   and efs-root-handler-function and efs-sifn-handler-function
;; * find-file-hooks contains efs-set-buffer-mode
;;
;; But it won't happen for EFS since the XEmacs maintainers
;; don't want to use a unified filename syntax.
(defun tramp-disable-ange-ftp ()
  "Turn Ange-FTP off.
This is useful for unified remoting.  See
`tramp-file-name-structure-unified' and
`tramp-file-name-structure-separate' for details.  Requests suitable
for Ange-FTP will be forwarded to Ange-FTP.  Also see the variables
`tramp-ftp-method', `tramp-default-method', and
`tramp-default-method-alist'.

This function is not needed in Emacsen which include Tramp, but is
present for backward compatibility."
  (let ((a1 (rassq 'ange-ftp-hook-function file-name-handler-alist))
	(a2 (rassq 'ange-ftp-completion-hook-function file-name-handler-alist)))
    (setq file-name-handler-alist
	  (delete a1 (delete a2 file-name-handler-alist)))))
Michael Albinus's avatar
Michael Albinus committed
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94

(eval-after-load "ange-ftp"
  '(when (functionp 'tramp-disable-ange-ftp)
     (tramp-disable-ange-ftp)))

;;;###autoload
(defun tramp-ftp-enable-ange-ftp ()
  ;; The following code is commented out in Ange-FTP.

  ;;; This regexp takes care of real ange-ftp file names (with a slash
  ;;; and colon).
  ;;; Don't allow the host name to end in a period--some systems use /.:
  (or (assoc "^/[^/:]*[^/:.]:" file-name-handler-alist)
      (setq file-name-handler-alist
	    (cons '("^/[^/:]*[^/:.]:" . ange-ftp-hook-function)
		  file-name-handler-alist)))

  ;;; This regexp recognizes absolute filenames with only one component,
  ;;; for the sake of hostname completion.
  (or (assoc "^/[^/:]*\\'" file-name-handler-alist)
      (setq file-name-handler-alist
	    (cons '("^/[^/:]*\\'" . ange-ftp-completion-hook-function)
		  file-name-handler-alist)))

  ;;; This regexp recognizes absolute filenames with only one component
  ;;; on Windows, for the sake of hostname completion.
  (and (memq system-type '(ms-dos windows-nt))
       (or (assoc "^[a-zA-Z]:/[^/:]*\\'" file-name-handler-alist)
	   (setq file-name-handler-alist
		 (cons '("^[a-zA-Z]:/[^/:]*\\'" .
			 ange-ftp-completion-hook-function)
		       file-name-handler-alist)))))

(add-hook 'tramp-ftp-unload-hook 'tramp-ftp-enable-ange-ftp)
95 96 97 98 99 100 101 102 103 104 105 106

;; Define FTP method ...
(defcustom tramp-ftp-method "ftp"
  "*When this method name is used, forward all calls to Ange-FTP."
  :group 'tramp
  :type 'string)

;; ... and add it to the method list.
(add-to-list 'tramp-methods (cons tramp-ftp-method nil))

;; Add some defaults for `tramp-default-method-alist'
(add-to-list 'tramp-default-method-alist
107
	     (list "\\`ftp\\." "" tramp-ftp-method))
108
(add-to-list 'tramp-default-method-alist
109
	     (list "" "\\`\\(anonymous\\|ftp\\)\\'" tramp-ftp-method))
110 111

;; Add completion function for FTP method.
112 113 114 115 116 117 118
(tramp-set-completion-function
 tramp-ftp-method
 '((tramp-parse-netrc "~/.netrc")))

;; If there is URL syntax, `substitute-in-file-name' needs special
;; handling.
(put 'substitute-in-file-name 'ange-ftp 'tramp-handle-substitute-in-file-name)
119 120 121 122 123 124 125

(defun tramp-ftp-file-name-handler (operation &rest args)
  "Invoke the Ange-FTP handler for OPERATION.
First arg specifies the OPERATION, second arg is a list of arguments to
pass to the OPERATION."
  (save-match-data
    (or (boundp 'ange-ftp-name-format)
126
	(require 'ange-ftp))
Kai Großjohann's avatar
Kai Großjohann committed
127 128 129 130
    (let ((ange-ftp-name-format
	   (list (nth 0 tramp-file-name-structure)
		 (nth 3 tramp-file-name-structure)
		 (nth 2 tramp-file-name-structure)
131 132 133 134 135 136 137 138
		 (nth 4 tramp-file-name-structure)))
	  ;; ange-ftp uses `ange-ftp-ftp-name-arg' and `ange-ftp-ftp-name-res'
	  ;; for optimization in `ange-ftp-ftp-name'. If Tramp wasn't active,
	  ;; there could be incorrect values from previous calls in case the
	  ;; "ftp" method is used in the Tramp file name. So we unset
	  ;; those values.
	  (ange-ftp-ftp-name-arg "")
	  (ange-ftp-ftp-name-res nil))
Kai Großjohann's avatar
Kai Großjohann committed
139
      (cond
140
       ;; If argument is a symlink, `file-directory-p' and `file-exists-p'
Kai Großjohann's avatar
Kai Großjohann committed
141
       ;; call the traversed file recursively. So we cannot disable the
142
       ;; file-name-handler this case.
Kai Großjohann's avatar
Kai Großjohann committed
143 144 145 146 147 148 149 150 151 152
       ((memq operation '(file-directory-p file-exists-p))
	(apply 'ange-ftp-hook-function operation args))
	;; Normally, the handlers must be discarded
	(t (let* ((inhibit-file-name-handlers
		   (list 'tramp-file-name-handler
			 'tramp-completion-file-name-handler
			 (and (eq inhibit-file-name-operation operation)
			      inhibit-file-name-handlers)))
		  (inhibit-file-name-operation operation))
	     (apply 'ange-ftp-hook-function operation args)))))))
153 154 155 156

(defun tramp-ftp-file-name-p (filename)
  "Check if it's a filename that should be forwarded to Ange-FTP."
  (let ((v (tramp-dissect-file-name filename)))
157
    (string= (tramp-file-name-method v) tramp-ftp-method)))
158 159 160 161 162 163 164 165 166 167

(add-to-list 'tramp-foreign-file-name-handler-alist
	     (cons 'tramp-ftp-file-name-p 'tramp-ftp-file-name-handler))

(provide 'tramp-ftp)

;;; TODO:

;; * In case of "/ftp:host:file" this works only for functions which
;;   are defined in `tramp-file-name-handler-alist'.  Call has to be
Kai Großjohann's avatar
Kai Großjohann committed
168 169
;;   pretended in `tramp-file-name-handler' otherwise.
;;   Furthermore, there are no backup files on FTP hosts.
170 171
;;   Worth further investigations.

Miles Bader's avatar
Miles Bader committed
172
;;; arch-tag: 759fb338-5c63-4b99-bd36-b4d59db91cff
173
;;; tramp-ftp.el ends here