1;;; tramp-ftp.el --- Tramp convenience functions for Ange-FTP -*- coding: iso-8859-1; -*- 2 3;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 4 5;; Author: Michael Albinus <michael.albinus@gmx.de> 6;; Keywords: comm, processes 7 8;; This file is part of GNU Emacs. 9 10;; GNU Emacs is free software; you can redistribute it and/or modify 11;; it under the terms of the GNU General Public License as published by 12;; the Free Software Foundation; either version 2, or (at your option) 13;; any later version. 14 15;; GNU Emacs is distributed in the hope that it will be useful, 16;; but WITHOUT ANY WARRANTY; without even the implied warranty of 17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18;; GNU General Public License for more details. 19 20;; You should have received a copy of the GNU General Public License 21;; along with GNU Emacs; see the file COPYING. If not, write to the 22;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 23;; Boston, MA 02110-1301, USA. 24 25;;; Commentary: 26 27;; Convenience functions for calling Ange-FTP from Tramp. 28;; Most of them are displaced from tramp.el. 29 30;;; Code: 31 32(require 'tramp) 33 34(eval-when-compile 35 (require 'cl) 36 (require 'custom) 37 ;; Emacs 19.34 compatibility hack -- is this needed? 38 (or (>= emacs-major-version 20) 39 (load "cl-seq"))) 40 41;; Disable Ange-FTP from file-name-handler-alist. 42;; To handle EFS, the following functions need to be dealt with: 43;; 44;; * dired-before-readin-hook contains efs-dired-before-readin 45;; * file-name-handler-alist contains efs-file-handler-function 46;; and efs-root-handler-function and efs-sifn-handler-function 47;; * find-file-hooks contains efs-set-buffer-mode 48;; 49;; But it won't happen for EFS since the XEmacs maintainers 50;; don't want to use a unified filename syntax. 51(defun tramp-disable-ange-ftp () 52 "Turn Ange-FTP off. 53This is useful for unified remoting. See 54`tramp-file-name-structure-unified' and 55`tramp-file-name-structure-separate' for details. Requests suitable 56for Ange-FTP will be forwarded to Ange-FTP. Also see the variables 57`tramp-ftp-method', `tramp-default-method', and 58`tramp-default-method-alist'. 59 60This function is not needed in Emacsen which include Tramp, but is 61present for backward compatibility." 62 (let ((a1 (rassq 'ange-ftp-hook-function file-name-handler-alist)) 63 (a2 (rassq 'ange-ftp-completion-hook-function file-name-handler-alist))) 64 (setq file-name-handler-alist 65 (delete a1 (delete a2 file-name-handler-alist))))) 66 67(eval-after-load "ange-ftp" 68 '(when (functionp 'tramp-disable-ange-ftp) 69 (tramp-disable-ange-ftp))) 70 71;;;###autoload 72(defun tramp-ftp-enable-ange-ftp () 73 ;; The following code is commented out in Ange-FTP. 74 75 ;;; This regexp takes care of real ange-ftp file names (with a slash 76 ;;; and colon). 77 ;;; Don't allow the host name to end in a period--some systems use /.: 78 (or (assoc "^/[^/:]*[^/:.]:" file-name-handler-alist) 79 (setq file-name-handler-alist 80 (cons '("^/[^/:]*[^/:.]:" . ange-ftp-hook-function) 81 file-name-handler-alist))) 82 83 ;;; This regexp recognizes absolute filenames with only one component, 84 ;;; for the sake of hostname completion. 85 (or (assoc "^/[^/:]*\\'" file-name-handler-alist) 86 (setq file-name-handler-alist 87 (cons '("^/[^/:]*\\'" . ange-ftp-completion-hook-function) 88 file-name-handler-alist))) 89 90 ;;; This regexp recognizes absolute filenames with only one component 91 ;;; on Windows, for the sake of hostname completion. 92 (and (memq system-type '(ms-dos windows-nt)) 93 (or (assoc "^[a-zA-Z]:/[^/:]*\\'" file-name-handler-alist) 94 (setq file-name-handler-alist 95 (cons '("^[a-zA-Z]:/[^/:]*\\'" . 96 ange-ftp-completion-hook-function) 97 file-name-handler-alist))))) 98 99(add-hook 'tramp-ftp-unload-hook 'tramp-ftp-enable-ange-ftp) 100 101;; Define FTP method ... 102(defcustom tramp-ftp-method "ftp" 103 "*When this method name is used, forward all calls to Ange-FTP." 104 :group 'tramp 105 :type 'string) 106 107;; ... and add it to the method list. 108(add-to-list 'tramp-methods (cons tramp-ftp-method nil)) 109 110;; Add some defaults for `tramp-default-method-alist' 111(add-to-list 'tramp-default-method-alist 112 (list "\\`ftp\\." "" tramp-ftp-method)) 113(add-to-list 'tramp-default-method-alist 114 (list "" "\\`\\(anonymous\\|ftp\\)\\'" tramp-ftp-method)) 115 116;; Add completion function for FTP method. 117(unless (memq system-type '(windows-nt)) 118 (tramp-set-completion-function 119 tramp-ftp-method 120 '((tramp-parse-netrc "~/.netrc")))) 121 122(defun tramp-ftp-file-name-handler (operation &rest args) 123 "Invoke the Ange-FTP handler for OPERATION. 124First arg specifies the OPERATION, second arg is a list of arguments to 125pass to the OPERATION." 126 (save-match-data 127 (or (boundp 'ange-ftp-name-format) 128 (require 'ange-ftp)) 129 (let ((ange-ftp-name-format 130 (list (nth 0 tramp-file-name-structure) 131 (nth 3 tramp-file-name-structure) 132 (nth 2 tramp-file-name-structure) 133 (nth 4 tramp-file-name-structure))) 134 ;; ange-ftp uses `ange-ftp-ftp-name-arg' and `ange-ftp-ftp-name-res' 135 ;; for optimization in `ange-ftp-ftp-name'. If Tramp wasn't active, 136 ;; there could be incorrect values from previous calls in case the 137 ;; "ftp" method is used in the Tramp file name. So we unset 138 ;; those values. 139 (ange-ftp-ftp-name-arg "") 140 (ange-ftp-ftp-name-res nil)) 141 (cond 142 ;; If argument is a symlink, `file-directory-p' and `file-exists-p' 143 ;; call the traversed file recursively. So we cannot disable the 144 ;; file-name-handler this case. 145 ((memq operation '(file-directory-p file-exists-p)) 146 (apply 'ange-ftp-hook-function operation args)) 147 ;; Normally, the handlers must be discarded 148 (t (let* ((inhibit-file-name-handlers 149 (list 'tramp-file-name-handler 150 'tramp-completion-file-name-handler 151 (and (eq inhibit-file-name-operation operation) 152 inhibit-file-name-handlers))) 153 (inhibit-file-name-operation operation)) 154 (apply 'ange-ftp-hook-function operation args))))))) 155 156(defun tramp-ftp-file-name-p (filename) 157 "Check if it's a filename that should be forwarded to Ange-FTP." 158 (let ((v (tramp-dissect-file-name filename))) 159 (string= 160 (tramp-find-method 161 (tramp-file-name-multi-method v) 162 (tramp-file-name-method v) 163 (tramp-file-name-user v) 164 (tramp-file-name-host v)) 165 tramp-ftp-method))) 166 167(add-to-list 'tramp-foreign-file-name-handler-alist 168 (cons 'tramp-ftp-file-name-p 'tramp-ftp-file-name-handler)) 169 170(provide 'tramp-ftp) 171 172;;; TODO: 173 174;; * In case of "/ftp:host:file" this works only for functions which 175;; are defined in `tramp-file-name-handler-alist'. Call has to be 176;; pretended in `tramp-file-name-handler' otherwise. 177;; Furthermore, there are no backup files on FTP hosts. 178;; Worth further investigations. 179;; * Map /multi:ssh:out@gate:ftp:kai@real.host:/path/to.file 180;; on Ange-FTP gateways. 181 182;;; arch-tag: 759fb338-5c63-4b99-bd36-b4d59db91cff 183;;; tramp-ftp.el ends here 184