- call FTP-LOGIN from FTP-CONNECT

- don't store login and password in connection record
- don't try to use password if USER succeeds already
- allow port (instead of file) for logging
- fix protocol bugs between FTP-LS/FTP-DIR and FTP-BUILD-COMMAND-STRING
This commit is contained in:
sperber 2003-01-16 12:36:27 +00:00
parent c9c7eb0a90
commit bb84449320
1 changed files with 41 additions and 32 deletions

View File

@ -85,15 +85,19 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; beware, the log file contains password information! ;; beware, the log file contains password information!
;;: string [ x string x port] -> connection
(define (ftp-connect host . args) (define (ftp-connect host login password passive? . args)
(let-optionals* args ((logfile #f)) (let-optionals* args ((logfile #f))
(let* ((LOG (and logfile (let* ((log (cond
(open-output-file logfile ((output-port? logfile)
(if (file-exists? logfile) logfile)
(bitwise-ior open/write open/append) ((string? logfile)
(bitwise-ior open/write open/create)) (open-output-file logfile
#o600))) (if (file-exists? logfile)
(bitwise-ior open/write open/append)
(bitwise-ior open/write open/create))
#o600))
(else #f)))
(hst-info (host-info host)) (hst-info (host-info host))
(hostname (host-info:name hst-info)) (hostname (host-info:name hst-info))
(srvc-info (service-info "ftp" "tcp")) (srvc-info (service-info "ftp" "tcp"))
@ -103,32 +107,38 @@
(service-info:port srvc-info))) (service-info:port srvc-info)))
(connection (make-ftp-connection hostname (connection (make-ftp-connection hostname
sock sock
LOG "" ""))) passive?
log)))
(ftp-log connection (ftp-log connection
(format #f "~%-- ~a: opened ftp connection to ~a" (format #f "~%-- ~a: opened ftp connection to ~a"
(date->string (date)) (date->string (date))
hostname)) hostname))
(ftp-read-reply connection (exactly-code "220")) ; the initial welcome banner (ftp-read-reply connection (exactly-code "220")) ; the initial welcome banner
(ftp-login connection login password)
connection))) connection)))
;; Send user information to the remote host. Args are optional login ;; Send user information to the remote host. Args are login
;; and password. If they are not provided, the Netrc module is used to ;; and password. If they are not provided, the Netrc module is used to
;; try to determine a login and password for the server. If not found we ;; try to determine a login and password for the server.
;; default to login "anonymous" with password user@host.
;;: connection [ x string x password ] -> status (define (ftp-login connection login password)
(define (ftp-login connection . args) (let* ((netrc-record (netrc-parse))
(let ((netrc-record (netrc-parse))) (login (or login
(let-optionals* args (netrc-lookup-login netrc-record
((login (ftp-connection-host-name connection))))
(netrc-lookup-login netrc-record (password (or password
(ftp-connection-host-name connection))) (netrc-lookup-password netrc-record
(password (ftp-connection-host-name connection)))))
(netrc-lookup-password netrc-record (let ((reply
(ftp-connection-host-name connection)))) (ftp-send-command connection (ftp-build-command-string "USER" login)
(set-ftp-connection-login! connection login) (lambda (code)
(set-ftp-connection-password! connection password) (or (string=? code "331") ; "User name okay, need password."
(ftp-send-command connection (format #f "USER ~a" login) any-code) ; "331" (string=? code "230")))))) ; "User logged in, proceed."
(ftp-send-command connection (format #f "PASS ~a" password))))) ; "230"
(if (string-prefix? "331" reply) ; "User name okay, need password."
(ftp-send-command connection
(ftp-build-command-string "PASS" password)
(exactly-code "230"))))))
;; Type must be one of 'binary or 'text or 'ascii, or a string which will be ;; Type must be one of 'binary or 'text or 'ascii, or a string which will be
;; sent verbatim ;; sent verbatim
@ -241,7 +251,7 @@
(define (ftp-ls connection . maybe-dir) (define (ftp-ls connection . maybe-dir)
(let* ((sock (ftp-open-data-connection connection))) (let* ((sock (ftp-open-data-connection connection)))
(ftp-send-command connection (ftp-send-command connection
(ftp-build-command-string "NLST" maybe-dir) (apply ftp-build-command-string "NLST" maybe-dir)
(code-with-prefix "1")) (code-with-prefix "1"))
(receive (newsock newsockaddr) (receive (newsock newsockaddr)
(accept-connection sock) (accept-connection sock)
@ -255,7 +265,7 @@
(define (ftp-dir connection . maybe-dir) (define (ftp-dir connection . maybe-dir)
(let* ((sock (ftp-open-data-connection connection))) (let* ((sock (ftp-open-data-connection connection)))
(ftp-send-command connection (ftp-send-command connection
(ftp-build-command-string "LIST" maybe-dir) (apply ftp-build-command-string "LIST" maybe-dir)
(code-with-prefix "1")) (code-with-prefix "1"))
(receive (newsock newsockaddr) (receive (newsock newsockaddr)
(accept-connection sock) (accept-connection sock)
@ -347,13 +357,12 @@
;; We cache the login and password to be able to relogin automatically ;; We cache the login and password to be able to relogin automatically
;; if we lose the connection (a la ange-ftp). Not implemented. ;; if we lose the connection (a la ange-ftp). Not implemented.
(define-record-type ftp-connection :ftp-connection (define-record-type ftp-connection :ftp-connection
(make-ftp-connection host-name command-socket logfd login password) (make-ftp-connection host-name command-socket passive-mode? logfd)
ftp-connection? ftp-connection?
(host-name ftp-connection-host-name) (host-name ftp-connection-host-name)
(command-socket ftp-connection-command-socket) (command-socket ftp-connection-command-socket)
(logfd ftp-connection-logfd) (passive-mode? ftp-connection-passive-mode?)
(login ftp-connection-login set-ftp-connection-login!) (logfd ftp-connection-logfd))
(password ftp-connection-password set-ftp-connection-password!))
(define-condition-type 'ftp-error '(error)) (define-condition-type 'ftp-error '(error))
(define ftp-error? (condition-predicate 'ftp-error)) (define ftp-error? (condition-predicate 'ftp-error))