Function: tramp-ftp-file-name-handler

tramp-ftp-file-name-handler is an autoloaded and byte-compiled function defined in tramp-ftp.el.gz.

Signature

(tramp-ftp-file-name-handler OPERATION &rest ARGS)

Documentation

Invoke the Ange-FTP handler for OPERATION and ARGS.

First arg specifies the OPERATION, second arg is a list of arguments to pass to the OPERATION.

Source Code

;; Defined in /usr/src/emacs/lisp/net/tramp-ftp.el.gz
;;;###tramp-autoload
(defun tramp-ftp-file-name-handler (operation &rest args)
  "Invoke the Ange-FTP handler for OPERATION and ARGS.
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)
	(let (file-name-handler-alist) (require 'ange-ftp)))
    (let ((ange-ftp-name-format
	   (list (nth 0 tramp-file-name-structure)
		 (nth 3 tramp-file-name-structure)
		 (nth 2 tramp-file-name-structure)
		 (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))
      (cond
       ;; If argument is a symlink, `file-directory-p' and
       ;; `file-exists-p' call the traversed file recursively.  So we
       ;; cannot disable the file-name-handler this case.  We set the
       ;; connection property "started" in order to put the remote
       ;; location into the cache, which is helpful for further
       ;; completion.  We don't use `with-parsed-tramp-file-name',
       ;; because this returns another user but the one declared in
       ;; "~/.netrc".
       ((memq operation '(file-directory-p file-exists-p))
	(if (apply #'ange-ftp-hook-function operation args)
	    (let ((v (tramp-dissect-file-name (car args) t)))
	      (setf (tramp-file-name-method v) tramp-ftp-method)
	      (tramp-set-connection-property v "started" t))
	  nil))

       ;; If the second argument of `copy-file' or `rename-file' is a
       ;; remote file name but via FTP, ange-ftp doesn't check this.
       ;; We must copy it locally first, because there is no place in
       ;; ange-ftp for correct handling.
       ((and (memq operation '(copy-file rename-file))
	     (tramp-tramp-file-p (cadr args))
	     (not (tramp-ftp-file-name-p (cadr args))))
	(let* ((filename (car args))
	       (newname (cadr args))
	       (tmpfile (tramp-compat-make-temp-file filename))
	       (args (cddr args)))
	  ;; We must set `ok-if-already-exists' to t in the first
	  ;; step, because the temp file has been created already.
	  (if (eq operation 'copy-file)
	      (apply operation filename tmpfile t (cdr args))
	    (apply operation filename tmpfile t))
	  (unwind-protect
	      (rename-file tmpfile newname (car args))
	    ;; Cleanup.
	    (ignore-errors (delete-file tmpfile)))))

       ;; 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)))))))