Function: ange-ftp-start-process

ange-ftp-start-process is a byte-compiled function defined in ange-ftp.el.gz.

Signature

(ange-ftp-start-process HOST USER NAME)

Documentation

Spawn a new FTP process ready to connect to machine HOST and give it NAME.

If HOST is only FTP-able through a gateway machine then spawn a shell on the gateway machine to do the FTP instead.

Source Code

;; Defined in /usr/src/emacs/lisp/net/ange-ftp.el.gz
(defun ange-ftp-start-process (host user name)
  "Spawn a new FTP process ready to connect to machine HOST and give it NAME.
If HOST is only FTP-able through a gateway machine then spawn a shell
on the gateway machine to do the FTP instead."
  ;; If `non-essential' is non-nil, don't reopen a new connection.  It
  ;; will be caught in Tramp.
  (when non-essential
    (throw 'non-essential 'non-essential))
  (let* ((use-gateway (ange-ftp-use-gateway-p host))
	 (use-smart-ftp (and (not ange-ftp-gateway-host)
			     (ange-ftp-use-smart-gateway-p host)))
	 (ftp-prog (if (or use-gateway
			   use-smart-ftp)
		       ange-ftp-gateway-ftp-program-name
		     ange-ftp-ftp-program-name))
	 (args (append (list ftp-prog) ange-ftp-ftp-program-args))
	 ;; Without the following binding, ange-ftp-start-process
	 ;; recurses on file-accessible-directory-p, since it needs to
	 ;; restart its process in order to determine anything about
	 ;; default-directory.
	 (file-name-handler-alist)
	 (default-directory
	   (if (ange-ftp-real-file-accessible-directory-p default-directory)
	       default-directory
	     exec-directory))
	 proc)
    ;; It would be nice to make process-connection-type nil,
    ;; but that doesn't work: ftp never responds.
    ;; Can anyone find a fix for that?
    (let ((process-connection-type t)
	  ;; Copy this so we don't alter it permanently.
	  (process-environment (copy-tree process-environment))
	  (buffer (get-buffer-create name)))
      (with-current-buffer buffer
	(internal-ange-ftp-mode))
      ;; This tells GNU ftp not to output any fancy escape sequences.
      (setenv "TERM" "dumb")
      (if use-gateway
	  (if ange-ftp-gateway-program-interactive
	      (setq proc (ange-ftp-gwp-start host user name args))
	    (setq proc (apply 'start-process name name
			      (append (list ange-ftp-gateway-program
					    ange-ftp-gateway-host)
				      args))))
	(setq proc (apply 'start-process name name args))))
    (with-current-buffer (process-buffer proc)
      (goto-char (point-max))
      (set-marker (process-mark proc) (point)))
    (set-process-query-on-exit-flag proc nil)
    (set-process-sentinel proc 'ange-ftp-process-sentinel)
    (set-process-filter proc 'ange-ftp-process-filter)
    ;; On Windows, the standard ftp client buffers its output (because
    ;; stdout is a pipe handle) so the startup message may never appear:
    ;; `accept-process-output' at this point would hang indefinitely.
    ;; However, sending an innocuous command ("help foo") forces some
    ;; output that will be ignored, which is just as good.  Once we
    ;; start sending normal commands, the output no longer appears to be
    ;; buffered, and everything works correctly.  My guess is that the
    ;; output of interest is being sent to stderr which is not buffered.
    (when (eq system-type 'windows-nt)
      ;; force ftp output to be treated as DOS text, otherwise the
      ;; output of "help foo" confuses the EOL detection logic.
      (set-process-coding-system proc 'raw-text-dos)
      (process-send-string proc "help foo\n"))
    (accept-process-output proc)	;wait for ftp startup message
    proc))