]> code.delx.au - gnu-emacs/blobdiff - lisp/net/tramp.el
(tramp-unified-filenames): Improve previos doc fix.
[gnu-emacs] / lisp / net / tramp.el
index 9ea8514153e48d044fb38a48d25329dc605c1838..54bb69464982a569645dba870609d8fbab0f8276 100644 (file)
 ;;;###autoload
 (defvar tramp-unified-filenames (not (featurep 'xemacs))
   "Non-nil means to use unified Ange-FTP/Tramp filename syntax.
-Nil means to use a separate filename syntax for Tramp.")
+Otherwise, use a separate filename syntax for Tramp.")
 
 ;; Load foreign methods.  Because they do require Tramp internally, this
 ;; must be done with the `eval-after-load' trick.
@@ -676,7 +676,7 @@ various functions for details."
   (if (and (fboundp 'executable-find)
           (executable-find "plink"))
       "plink"
-    "ssh")
+    "scp")
   "*Default method to use for transferring files.
 See `tramp-methods' for possibilities.
 Also see `tramp-default-method-alist'."
@@ -1821,8 +1821,6 @@ while (my $data = <STDIN>) {
 Escape sequence %s is replaced with name of Perl binary.
 This string is passed to `format', so percent characters need to be doubled.")
 
-; These values conform to `file-attributes' from XEmacs 21.2.
-; GNU Emacs and other tools not checked.
 (defconst tramp-file-mode-type-map '((0  . "-")  ; Normal file (SVID-v2 and XPG2)
                                     (1  . "p")  ; fifo
                                     (2  . "c")  ; character device
@@ -1927,17 +1925,12 @@ on the FILENAME argument, even if VISIT was a string.")
   "Alist of handler functions.
 Operations not mentioned here will be handled by the normal Emacs functions.")
 
-;; Handlers for partial tramp file names. For GNU Emacs just
-;; `file-name-all-completions' is needed. The other ones are necessary
-;; for XEmacs.
+;; Handlers for partial tramp file names.  For Emacs just
+;; `file-name-all-completions' is needed.
+;;;###autoload
 (defconst tramp-completion-file-name-handler-alist
-  '(
-    (file-name-directory . tramp-completion-handle-file-name-directory)
-    (file-name-nondirectory . tramp-completion-handle-file-name-nondirectory)
-    (file-exists-p . tramp-completion-handle-file-exists-p)
-    (file-name-all-completions . tramp-completion-handle-file-name-all-completions)
-    (file-name-completion . tramp-completion-handle-file-name-completion)
-    (expand-file-name . tramp-completion-handle-expand-file-name))
+  '((file-name-all-completions . tramp-completion-handle-file-name-all-completions)
+    (file-name-completion . tramp-completion-handle-file-name-completion))
   "Alist of completion handler functions.
 Used for file names matching `tramp-file-name-regexp'. Operations not
 mentioned here will be handled by `tramp-file-name-handler-alist' or the
@@ -2025,11 +2018,10 @@ If VAR is nil, then we bind `v' to the structure and `multi-method',
      ,@body))
 
 (put 'with-parsed-tramp-file-name 'lisp-indent-function 2)
-;; To be activated for debugging containing this macro
-;; It works only when VAR is nil.  Otherwise, it can be deactivated by
-;; (put 'with-parsed-tramp-file-name 'edebug-form-spec 0)
-;; I'm too stupid to write a precise SPEC for it.
-(put 'with-parsed-tramp-file-name 'edebug-form-spec t)
+;; Enable debugging.
+(def-edebug-spec with-parsed-tramp-file-name (form symbolp body))
+;; Highlight as keyword.
+(font-lock-add-keywords 'emacs-lisp-mode '("\\<with-parsed-tramp-file-name\\>"))
 
 (defmacro tramp-let-maybe (variable value &rest body)
   "Let-bind VARIABLE to VALUE in BODY, but only if VARIABLE is not obsolete.
@@ -2172,28 +2164,11 @@ target of the symlink differ."
 ;; Localname manipulation functions that grok TRAMP localnames...
 (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
+  ;; Everything except the last filename thing is the directory.
   (with-parsed-tramp-file-name file nil
-    ;; For the following condition, two possibilities should be tried:
-    ;; (1) (string= localname "")
-    ;; (2) (or (string= localname "") (string= localname "/"))
-    ;; The second variant fails when completing a "/" directory on
-    ;; the remote host, that is a filename which looks like
-    ;; "/user@host:/".  But maybe wildcards fail with the first variant.
-    ;; We should do some investigation.
-    (if (string= localname "")
-       ;; For a filename like "/[foo]", we return "/".  The `else'
-       ;; case would return "/[foo]" unchanged.  But if we do that,
-       ;; then `file-expand-wildcards' ceases to work.  It's not
-       ;; quite clear to me what's the intuition that tells that this
-       ;; behavior is the right behavior, but oh, well.
-       "/"
-      ;; run the command on the localname portion only
-      ;; CCC: This should take into account the remote machine type, no?
-      ;;  --daniel <daniel@danann.net>
-      (tramp-make-tramp-file-name multi-method method user host
-                                 ;; This will not recurse...
-                                 (or (file-name-directory localname) "")))))
+    ;; Run the command on the localname portion only.
+    (tramp-make-tramp-file-name
+     multi-method method user host (file-name-directory (or localname "")))))
 
 (defun tramp-handle-file-name-nondirectory (file)
   "Like `file-name-nondirectory' but aware of TRAMP files."
@@ -2929,7 +2904,7 @@ and `rename'.  FILENAME and NEWNAME must be absolute file names."
   (unless ok-if-already-exists
     (when (file-exists-p newname)
       (signal 'file-already-exists
-              (list newname))))
+              (list "File already exists" newname))))
   (let ((t1 (tramp-tramp-file-p filename))
        (t2 (tramp-tramp-file-p newname))
        v1-multi-method v1-method v1-user v1-host v1-localname
@@ -3002,10 +2977,10 @@ and `rename'.  FILENAME and NEWNAME must be absolute file names."
       ;; copy-program can be invoked.
       (if (and (not v1-multi-method)
               (not v2-multi-method)
-              (or (tramp-method-out-of-band-p
-                   v1-multi-method v1-method v1-user v1-host)
-                  (tramp-method-out-of-band-p
-                   v2-multi-method v2-method v2-user v2-host)))
+              (or (and t1 (tramp-method-out-of-band-p
+                            v1-multi-method v1-method v1-user v1-host))
+                  (and t2 (tramp-method-out-of-band-p
+                            v2-multi-method v2-method v2-user v2-host))))
          (tramp-do-copy-or-rename-file-out-of-band
           op filename newname keep-date)
        ;; Use the generic method via a Tramp buffer.
@@ -3596,7 +3571,8 @@ This will break if COMMAND prints a newline, followed by the value of
   ;; for `find-grep-dired' and `find-name-dired' in Emacs 22.
   (if (tramp-tramp-file-p default-directory)
       (with-parsed-tramp-file-name default-directory nil
-       (let ((asynchronous (string-match "[ \t]*&[ \t]*\\'" command))
+       (let ((curbuf (current-buffer))
+             (asynchronous (string-match "[ \t]*&[ \t]*\\'" command))
              status)
          (unless output-buffer
            (setq output-buffer
@@ -3698,6 +3674,7 @@ This will break if COMMAND prints a newline, followed by the value of
          (unless (zerop (buffer-size))
            (when tramp-display-shell-command-buffer
              (display-buffer output-buffer)))
+         (set-buffer curbuf)
          status))
     ;; The following is only executed if something strange was
     ;; happening.  Emit a helpful message and do it anyway.
@@ -3910,37 +3887,50 @@ This will break if COMMAND prints a newline, followed by the value of
 (defun tramp-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."
-  (when tramp-auto-save-directory
-    (unless (file-exists-p tramp-auto-save-directory)
-      (make-directory tramp-auto-save-directory t)))
-  ;; jka-compr doesn't like auto-saving, so by appending "~" to the
-  ;; file name we make sure that jka-compr isn't used for the
-  ;; auto-save file.
-  (let ((buffer-file-name
-        (if tramp-auto-save-directory
-            (expand-file-name
-             (tramp-subst-strs-in-string
-              '(("_" . "|")
-                ("/" . "_a")
-                (":" . "_b")
-                ("|" . "__")
-                ("[" . "_l")
-                ("]" . "_r"))
-              (buffer-file-name))
-             tramp-auto-save-directory)
-          (buffer-file-name))))
-    ;; Run plain `make-auto-save-file-name'.  There might be an advice when
-    ;; it is not a magic file name operation (since Emacs 22).
-    ;; We must deactivate it temporarily.
-    (if (not (ad-is-active 'make-auto-save-file-name))
-       (tramp-run-real-handler
-        'make-auto-save-file-name nil)
-      ;; else
-      (ad-deactivate 'make-auto-save-file-name)
-      (prog1
-       (tramp-run-real-handler
-       'make-auto-save-file-name nil)
-       (ad-activate 'make-auto-save-file-name)))))
+  (let ((tramp-auto-save-directory tramp-auto-save-directory))
+    ;; File name must be unique.  This is ensured with Emacs 22 (see
+    ;; UNIQUIFY element of `auto-save-file-name-transforms'); but for
+    ;; all other cases we must do it ourselves.
+    (when (boundp 'auto-save-file-name-transforms)
+      (mapcar
+       '(lambda (x)
+         (when (and (string-match (car x) buffer-file-name)
+                    (not (car (cddr x))))
+           (setq tramp-auto-save-directory
+                 (or tramp-auto-save-directory temporary-file-directory))))
+       (symbol-value 'auto-save-file-name-transforms)))
+    ;; Create directory.
+    (when tramp-auto-save-directory
+      (unless (file-exists-p tramp-auto-save-directory)
+       (make-directory tramp-auto-save-directory t)))
+    ;; jka-compr doesn't like auto-saving, so by appending "~" to the
+    ;; file name we make sure that jka-compr isn't used for the
+    ;; auto-save file.
+    (let ((buffer-file-name
+          (if tramp-auto-save-directory
+              (expand-file-name
+               (tramp-subst-strs-in-string
+                '(("_" . "|")
+                  ("/" . "_a")
+                  (":" . "_b")
+                  ("|" . "__")
+                  ("[" . "_l")
+                  ("]" . "_r"))
+                (buffer-file-name))
+               tramp-auto-save-directory)
+            (buffer-file-name))))
+      ;; Run plain `make-auto-save-file-name'.  There might be an advice when
+      ;; it is not a magic file name operation (since Emacs 22).
+      ;; We must deactivate it temporarily.
+      (if (not (ad-is-active 'make-auto-save-file-name))
+         (tramp-run-real-handler
+          'make-auto-save-file-name nil)
+       ;; else
+       (ad-deactivate 'make-auto-save-file-name)
+       (prog1
+           (tramp-run-real-handler
+            'make-auto-save-file-name nil)
+         (ad-activate 'make-auto-save-file-name))))))
 
 
 ;; CCC grok APPEND, LOCKNAME, CONFIRM
@@ -4144,7 +4134,8 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file."
 ;;         (inhibit-file-name-operation operation))
 ;;     (apply operation args)))
 
-(defun tramp-run-real-handler (operation args)
+;;;###autoload
+(progn (defun tramp-run-real-handler (operation args)
   "Invoke normal file name handler for OPERATION.
 First arg specifies the OPERATION, second arg is a list of arguments to
 pass to the OPERATION."
@@ -4157,13 +4148,14 @@ pass to the OPERATION."
            ,(and (eq inhibit-file-name-operation operation)
                  inhibit-file-name-handlers)))
         (inhibit-file-name-operation operation))
-    (apply operation args)))
+    (apply operation args))))
 
 ;; This function is used from `tramp-completion-file-name-handler' functions
 ;; only, if `tramp-completion-mode' is true. But this cannot be checked here
 ;; because the check is based on a full filename, not available for all
 ;; basic I/O operations.
-(defun tramp-completion-run-real-handler (operation args)
+;;;###autoload
+(progn (defun tramp-completion-run-real-handler (operation args)
   "Invoke `tramp-file-name-handler' for OPERATION.
 First arg specifies the OPERATION, second arg is a list of arguments to
 pass to the OPERATION."
@@ -4175,7 +4167,7 @@ pass to the OPERATION."
            ,(and (eq inhibit-file-name-operation operation)
                  inhibit-file-name-handlers)))
         (inhibit-file-name-operation operation))
-    (apply operation args)))
+    (apply operation args))))
 
 ;; We handle here all file primitives.  Most of them have the file
 ;; name as first parameter; nevertheless we check for them explicitly
@@ -4272,12 +4264,25 @@ ARGS are the arguments OPERATION has been called with."
 (defun tramp-file-name-handler (operation &rest args)
   "Invoke Tramp file name handler.
 Falls back to normal file name handler if no tramp file name handler exists."
+;;  (setq edebug-trace t)
+;;  (edebug-trace "%s" (with-output-to-string (backtrace)))
   (save-match-data
     (let* ((filename (apply 'tramp-file-name-for-operation operation args))
+          (completion (tramp-completion-mode filename))
           (foreign (tramp-find-foreign-file-name-handler filename)))
-      (cond
-       (foreign (apply foreign operation args))
-       (t (tramp-run-real-handler operation args))))))
+      (with-parsed-tramp-file-name filename nil
+       (cond
+        ;; When we are in completion mode, some operations shouldn' be
+        ;; handled by backend.
+        ((and completion (memq operation '(expand-file-name)))
+         (tramp-run-real-handler operation args))
+        ((and completion (zerop (length localname))
+              (memq operation '(file-exists-p file-directory-p)))
+         t)
+        ;; Call the backend function.
+        (foreign (apply foreign operation args))
+        ;; Nothing to do for us.
+        (t (tramp-run-real-handler operation args)))))))
 
 
 ;; In Emacs, there is some concurrency due to timers.  If a timer
@@ -4325,32 +4330,48 @@ Fall back to normal file name handler if no Tramp handler exists."
       (setq tramp-locked tl))))
 
 ;;;###autoload
-(defun tramp-completion-file-name-handler (operation &rest args)
+(progn (defun tramp-completion-file-name-handler (operation &rest args)
   "Invoke tramp file name completion handler.
 Falls back to normal file name handler if no tramp file name handler exists."
-;;   (setq tramp-debug-buffer t)
-;;   (tramp-message 1 "%s %s" operation args)
-;;   (tramp-message 1 "%s %s\n%s"
-;;              operation args (with-output-to-string (backtrace)))
+;;  (setq edebug-trace t)
+;;  (edebug-trace "%s" (with-output-to-string (backtrace)))
   (let ((fn (assoc operation tramp-completion-file-name-handler-alist)))
     (if fn
        (save-match-data (apply (cdr fn) args))
-      (tramp-completion-run-real-handler operation args))))
+      (tramp-completion-run-real-handler operation args)))))
 
 ;;;###autoload
-(put 'tramp-completion-file-name-handler 'safe-magic t)
+(defsubst tramp-register-file-name-handlers ()
+  "Add tramp file name handlers to `file-name-handler-alist'."
+  (add-to-list 'file-name-handler-alist
+              (cons tramp-file-name-regexp 'tramp-file-name-handler))
+  ;; `partial-completion-mode' is unknown in XEmacs.  So we should
+  ;; load it unconditionally there.  In the GNU Emacs case, method/
+  ;; user/host name completion shall be bound to `partial-completion-mode'.
+  (when (or (not (boundp 'partial-completion-mode))
+           (symbol-value 'partial-completion-mode)
+           (featurep 'ido))
+    (add-to-list 'file-name-handler-alist
+                (cons tramp-completion-file-name-regexp
+                      'tramp-completion-file-name-handler))
+    (put 'tramp-completion-file-name-handler 'safe-magic t))
+  ;; If jka-compr is already loaded, move it to the front of
+  ;; `file-name-handler-alist'.
+  (let ((jka (rassoc 'jka-compr-handler file-name-handler-alist)))
+    (when jka
+      (setq file-name-handler-alist
+           (cons jka (delete jka file-name-handler-alist))))))
 
-;; Register in file name handler alist
-;;;###autoload
-(add-to-list 'file-name-handler-alist
-            (cons tramp-file-name-regexp 'tramp-file-name-handler))
-;;;###autoload
-(add-to-list 'file-name-handler-alist
-            (cons tramp-completion-file-name-regexp
-                  'tramp-completion-file-name-handler))
+;; During autoload, it shall be checked whether
+;; `partial-completion-mode' is active.  Therefore registering will be
+;; delayed.
+;;;###autoload(add-hook
+;;;###autoload 'after-init-hook
+;;;###autoload '(lambda () (tramp-register-file-name-handlers)))
+(tramp-register-file-name-handlers)
 
 ;;;###autoload
-(defun tramp-unload-file-name-handler-alist ()
+(defun tramp-unload-file-name-handlers ()
   (setq file-name-handler-alist
        (delete (rassoc 'tramp-file-name-handler
                        file-name-handler-alist)
@@ -4358,17 +4379,7 @@ Falls back to normal file name handler if no tramp file name handler exists."
                                file-name-handler-alist)
                        file-name-handler-alist))))
 
-(add-hook 'tramp-unload-hook 'tramp-unload-file-name-handler-alist)
-
-(defun tramp-repair-jka-compr ()
-  "If jka-compr is already loaded, move it to the front of
-`file-name-handler-alist'.  On Emacs 22 or so this will not be
-necessary anymore."
-  (let ((jka (rassoc 'jka-compr-handler file-name-handler-alist)))
-    (when jka
-      (setq file-name-handler-alist
-           (cons jka (delete jka file-name-handler-alist))))))
-(tramp-repair-jka-compr)
+(add-hook 'tramp-unload-hook 'tramp-unload-file-name-handlers)
 
 
 ;;; Interactions with other packages:
@@ -4483,31 +4494,10 @@ necessary anymore."
                                 last-input-event) ?\ ))))))
     t)))
 
-(defun tramp-completion-handle-file-exists-p (filename)
-  "Like `file-exists-p' for tramp files."
-  (if (tramp-completion-mode filename)
-      (tramp-run-real-handler
-       'file-exists-p (list filename))
-    (tramp-completion-run-real-handler
-     'file-exists-p (list filename))))
-
-;; Localname manipulation in case of partial TRAMP file names.
-(defun tramp-completion-handle-file-name-directory (file)
-  "Like `file-name-directory' but aware of TRAMP files."
-  (if (tramp-completion-mode file)
-      "/"
-    (tramp-completion-run-real-handler
-     'file-name-directory (list file))))
-
-;; Localname manipulation in case of partial TRAMP file names.
-(defun tramp-completion-handle-file-name-nondirectory (file)
-  "Like `file-name-nondirectory' but aware of TRAMP files."
-  (substring
-   file (length (tramp-completion-handle-file-name-directory file))))
-
 ;; Method, host name and user name completion.
 ;; `tramp-completion-dissect-file-name' returns a list of
 ;; tramp-file-name structures. For all of them we return possible completions.
+;;;###autoload
 (defun tramp-completion-handle-file-name-all-completions (filename directory)
   "Like `file-name-all-completions' for partial tramp files."
 
@@ -4562,7 +4552,8 @@ necessary anymore."
          ;; unify list, remove nil elements
          (while result
            (let ((car (car result)))
-             (when car (add-to-list 'result1 car))
+             (when car (add-to-list
+                        'result1 (substring car (length directory))))
              (setq result (cdr result))))
 
          ;; Complete local parts
@@ -4581,6 +4572,7 @@ necessary anymore."
     (setq tramp-completion-mode nil)))
 
 ;; Method, host name and user name completion for a file.
+;;;###autoload
 (defun tramp-completion-handle-file-name-completion (filename directory)
   "Like `file-name-completion' for tramp files."
   (try-completion filename
@@ -4707,8 +4699,7 @@ remote host and localname (filename on remote host)."
    (lambda (method)
      (and method
          (string-match (concat "^" (regexp-quote partial-method)) method)
-         ;; we must remove leading "/".
-         (substring (tramp-make-tramp-file-name nil method nil nil nil) 1)))
+         (tramp-make-tramp-file-name nil method nil nil nil)))
    (delete "multi" (mapcar 'car tramp-methods))))
 
 ;; Compares partial user and host names with possible completions.
@@ -4741,8 +4732,7 @@ PARTIAL-USER must match USER, PARTIAL-HOST must match HOST."
            host nil)))
 
   (unless (zerop (+ (length user) (length host)))
-    ;; we must remove leading "/".
-    (substring (tramp-make-tramp-file-name nil method user host nil) 1)))
+    (tramp-make-tramp-file-name nil method user host nil)))
 
 (defun tramp-parse-rhosts (filename)
   "Return a list of (user host) tuples allowed to access.
@@ -4961,15 +4951,6 @@ User may be nil."
      (forward-line 1)
      result))
 
-(defun tramp-completion-handle-expand-file-name (name &optional dir)
-  "Like `expand-file-name' for tramp files."
-  (let ((fullname (concat (or dir default-directory) name)))
-    (if (tramp-completion-mode fullname)
-       (tramp-run-real-handler
-        'expand-file-name (list name dir))
-      (tramp-completion-run-real-handler
-       'expand-file-name (list name dir)))))
-
 ;;; Internal Functions:
 
 (defun tramp-maybe-send-perl-script (multi-method method user host script name)
@@ -5055,15 +5036,16 @@ hosts, or files, disagree."
 (defun tramp-touch (file time)
   "Set the last-modified timestamp of the given file.
 TIME is an Emacs internal time value as returned by `current-time'."
-  (let ((touch-time (format-time-string "%Y%m%d%H%M.%S" time)))
+  (let ((touch-time (format-time-string "%Y%m%d%H%M.%S" time t)))
     (if (tramp-tramp-file-p file)
        (with-parsed-tramp-file-name file nil
          (let ((buf (tramp-get-buffer multi-method method user host)))
            (unless (zerop (tramp-send-command-and-check
                            multi-method method user host
-                           (format "touch -t %s %s"
+                           (format "TZ=UTC; export TZ; touch -t %s %s"
                                    touch-time
-                                   localname)))
+                                   (tramp-shell-quote-argument localname))
+                           t))
              (pop-to-buffer buf)
              (error "tramp-touch: touch failed, see buffer `%s' for details"
                     buf))))
@@ -6784,8 +6766,8 @@ Return ATTR."
   ;; Set file's gid change bit.  Possible only when id-format is 'integer.
   (when (numberp (nth 3 attr))
     (setcar (nthcdr 9 attr)
-           (not (= (nth 3 attr)
-                   (tramp-get-remote-gid multi-method method user host)))))
+           (not (eql (nth 3 attr)
+                     (tramp-get-remote-gid multi-method method user host)))))
   ;; Set virtual device number.
   (setcar (nthcdr 11 attr)
           (tramp-get-device multi-method method user host))
@@ -7235,10 +7217,7 @@ Invokes `password-read' if available, `read-passwd' else."
 
 (defun tramp-time-diff (t1 t2)
   "Return the difference between the two times, in seconds.
-T1 and T2 are time values (as returned by `current-time' for example).
-
-NOTE: This function will fail if the time difference is too large to
-fit in an integer."
+T1 and T2 are time values (as returned by `current-time' for example)."
   ;; Pacify byte-compiler with `symbol-function'.
   (cond ((and (fboundp 'subtract-time)
              (fboundp 'float-time))
@@ -7249,10 +7228,9 @@ fit in an integer."
          (funcall (symbol-function 'time-to-seconds)
                  (funcall (symbol-function 'subtract-time) t1 t2)))
         ((fboundp 'itimer-time-difference)
-         (floor (funcall
-                (symbol-function 'itimer-time-difference)
-                (if (< (length t1) 3) (append t1 '(0)) t1)
-                (if (< (length t2) 3) (append t2 '(0)) t2))))
+        (funcall (symbol-function 'itimer-time-difference)
+                 (if (< (length t1) 3) (append t1 '(0)) t1)
+                 (if (< (length t2) 3) (append t2 '(0)) t2)))
         (t
          ;; snarfed from Emacs 21 time-date.el; combining
         ;; time-to-seconds and subtract-time
@@ -7628,9 +7606,10 @@ Therefore, the contents of files might be included in the debug buffer(s).")
 ;; - Cleanup autoloads
 ;;;###autoload
 (defun tramp-unload-tramp ()
+  "Discard Tramp from loading remote files."
   (interactive)
   ;; When Tramp is not loaded yet, its autoloads are still active.
-  (tramp-unload-file-name-handler-alist)
+  (tramp-unload-file-name-handlers)
   ;; ange-ftp settings must be enabled.
   (when (functionp 'tramp-ftp-enable-ange-ftp)
     (funcall (symbol-function 'tramp-ftp-enable-ange-ftp)))