Clean up logging in ftpd:

- hold relevant data in new SERVER-STATE fluid
- specify log destination as a port, not a file
This commit is contained in:
sperber 2003-01-28 10:49:45 +00:00
parent a44ab62741
commit eb20aec688
3 changed files with 83 additions and 89 deletions

View File

@ -1,4 +1,4 @@
\chapter{FTP server}\label{cha:ftpd}
\chapter{FTP Server}\label{cha:ftpd}
The \ex{ftpd} structure contains a complete anonymous ftp server.
@ -38,10 +38,10 @@ the optional second one. Here they are:
represented as a list of strings, one for each line of output.
\end{desc}
\defun{with-logfile}{file-name [options]}{options}
\defun{with-log-port}{output-port [options]}{options}
\begin{desc}
If this is non-\sharpf, ex{ftpd} makes a log entry for each file
sent or retrieved in \var{file-name}. Defaults to \sharpf.
If this is non-\sharpf, ex{ftpd} outputs a log entry for each file
sent or retrieved on \var{output-port}. Defaults to \sharpf.
\end{desc}
\defun{with-dns-lookup?}{boolean [options]}{options}

View File

@ -23,12 +23,12 @@
(define-record-type ftpd-options :ftpd-options
(really-make-ftpd-options port anonymous-home banner
logfile dns-lookup?)
log-port dns-lookup?)
ftpd-options?
(port ftpd-options-port set-ftpd-options-port!)
(anonymous-home ftpd-options-anonymous-home set-ftpd-options-anonymous-home!)
(banner ftpd-options-banner set-ftpd-options-banner!)
(logfile ftpd-options-logfile set-ftpd-options-logfile!)
(log-port ftpd-options-log-port set-ftpd-options-log-port!)
(dns-lookup? ftpd-options-dns-lookup? set-ftpd-options-dns-lookup?!))
(define (make-default-ftpd-options)
@ -45,7 +45,7 @@
(really-make-ftpd-options (ftpd-options-port options)
(ftpd-options-anonymous-home options)
(ftpd-options-banner options)
(ftpd-options-logfile options)
(ftpd-options-log-port options)
(ftpd-options-dns-lookup? options)))
(define (make-ftpd-options-transformer set-option!)
@ -62,8 +62,8 @@
(make-ftpd-options-transformer set-ftpd-options-anonymous-home!))
(define with-banner
(make-ftpd-options-transformer set-ftpd-options-banner!))
(define with-logfile
(make-ftpd-options-transformer set-ftpd-options-logfile!))
(define with-log-port
(make-ftpd-options-transformer set-ftpd-options-log-port!))
(define with-dns-lookup?
(make-ftpd-options-transformer set-ftpd-options-dns-lookup?!))
@ -77,10 +77,18 @@
(loop (transformer value options)
(cddr stuff))))))
(define-record-type server-state :server-state
(really-make-server-state log-lock log-port)
server-state?
(log-lock server-state-log-lock)
(log-port server-state-log-port))
(define (make-server-state log-port)
(really-make-server-state (make-lock) log-port))
(define-record-type session :session
(really-make-session control-input-port
control-output-port
logfile-lock
logged-in?
authenticated?
anonymous?
@ -91,14 +99,12 @@
reply-code
type
data-socket
passive-socket
maybe-log-port)
passive-socket)
session?
(control-input-port session-control-input-port
set-session-control-input-port!)
(control-output-port session-control-output-port
set-session-control-output-port!)
(logfile-lock session-logfile-lock)
(logged-in? session-logged-in?
set-session-logged-in?!)
(authenticated? session-authenticated?
@ -112,7 +118,7 @@
(to-be-renamed session-to-be-renamed
set-session-to-be-renamed!)
(replies session-replies
set-session-replies!)
set-session-replies!)
(reply-code session-reply-code
set-session-reply-code!)
(type session-type
@ -120,13 +126,10 @@
(data-socket session-data-socket
set-session-data-socket!)
(passive-socket session-passive-socket
set-session-passive-socket!)
(maybe-log-port session-maybe-log-port
set-session-maybe-log-port!))
set-session-passive-socket!))
(define (make-session input-port output-port maybe-log-port)
(define (make-session input-port output-port)
(really-make-session input-port output-port
(make-lock)
#f ; logged-in?
#f ; autenticated?
#f ; anonymous?
@ -138,10 +141,10 @@
'ascii ; type
#f ; data-socket
#f ; passive-socket
maybe-log-port
))
(define session (make-fluid #f))
(define server-state (make-fluid #f))
(define options (make-fluid #f))
(define (make-session-selector selector)
@ -156,8 +159,6 @@
(make-session-selector session-control-input-port))
(define the-session-control-output-port
(make-session-selector session-control-output-port))
(define the-session-logfile-lock
(make-session-selector session-logfile-lock))
(define the-session-logged-in? (make-session-selector session-logged-in?))
(define the-session-authenticated? (make-session-selector session-authenticated?))
@ -170,7 +171,6 @@
(define the-session-type (make-session-selector session-type))
(define the-session-data-socket (make-session-selector session-data-socket))
(define the-session-passive-socket (make-session-selector session-passive-socket))
(define the-session-maybe-log-port (make-session-selector session-maybe-log-port))
(define set-the-session-control-input-port!
(make-session-modifier set-session-control-input-port!))
@ -198,8 +198,19 @@
(make-session-modifier set-session-data-socket!))
(define set-the-session-passive-socket!
(make-session-modifier set-session-passive-socket!))
(define set-the-session-maybe-log-port!
(make-session-modifier set-session-maybe-log-port!))
(define (make-server-state-selector selector)
(lambda ()
(selector (fluid server-state))))
(define (make-server-state-modifier setter)
(lambda (value)
(setter (fluid server-state) value)))
(define the-server-state-log-lock
(make-server-state-selector server-state-log-lock))
(define the-server-state-log-port
(make-server-state-selector server-state-log-port))
(define (make-ftpd-options-selector selector)
(lambda ()
@ -211,16 +222,16 @@
(make-ftpd-options-selector ftpd-options-anonymous-home))
(define the-ftpd-options-banner
(make-ftpd-options-selector ftpd-options-banner))
(define the-ftpd-options-logfile
(make-ftpd-options-selector ftpd-options-logfile))
(define the-ftpd-options-log-port
(make-ftpd-options-selector ftpd-options-log-port))
(define the-ftpd-options-dns-lookup?
(make-ftpd-options-selector ftpd-options-dns-lookup?))
;;; LOG -------------------------------------------------------
(define (log level format-message . args)
(syslog level
(apply format #f (string-append "(thread ~D) " format-message)
(thread-uid (current-thread)) args)))
(syslog level
(apply format #f (string-append "(thread ~D) " format-message)
(thread-uid (current-thread)) args)))
(define (log-command level command-name . argument)
(if (null? argument)
@ -228,7 +239,7 @@
(if (not (null? (cdr argument)))
(log level "handling ~A command with argument ~S"
command-name argument)
(log level "handling ~A command with argument ~S" ; does this ever happen?
(log level "handling ~A command with argument ~S" ; does this ever happen?
command-name (car argument)))))
;; Extended logging like wu.ftpd:
@ -261,53 +272,35 @@
; 1 RFC931 Authentication
; 13 authenticated user id (if available, '*' otherwise)
;
(define file-log
(let ((maybe-dns-lookup (lambda (ip)
(if (the-ftpd-options-dns-lookup?)
(or (dns-lookup-ip ip)
ip))
ip)))
(lambda (start-transfer-seconds info full-path direction)
(if (the-session-maybe-log-port)
(begin
(obtain-lock (the-session-logfile-lock))
(format (the-session-maybe-log-port)
"~A ~A ~A ~A ~A ~A _ ~A a nop@ssword ftp 0 *~%"
(format-date "~a ~b ~d ~H:~M:~S ~Y" (date)) ; current date and time
(- (current-seconds) start-transfer-seconds) ; transfer time in secs
(maybe-dns-lookup
(socket-address->string
(socket-remote-address (the-session-data-socket)) #f)) ; remote host ip
(file-info:size info) ; file size in bytes
(string-map (lambda (c)
(if (eq? c #\space) #\_ c))
full-path) ; name of file (spaces replaced by "_")
(case (the-session-type)
((ascii) "a")
((image) "b")
(else "?")) ; transfer type
direction ; incoming / outgoing file
; anonymous access
; password (no password given)
; service name
; authentication mode
; authenticated user id'
)
(force-output (the-session-maybe-log-port))
(release-lock (the-session-logfile-lock)))))))
(define (file-log start-transfer-seconds info full-path direction)
(if (the-server-state-log-port)
(begin
(obtain-lock (the-server-state-log-lock))
(format (the-server-state-log-port)
"~A ~A ~A ~A ~A ~A _ ~A a nop@ssword ftp 0 *~%"
(format-date "~a ~b ~d ~H:~M:~S ~Y" (date))
(- (current-seconds) start-transfer-seconds)
(maybe-dns-lookup
(socket-address->string
(socket-remote-address (the-session-data-socket)) #f))
(file-info:size info)
(string-map (lambda (c)
(if (eq? c #\space) #\_ c))
full-path)
(case (the-session-type)
((ascii) "a")
((image) "b")
(else "?"))
direction)
(force-output (the-server-state-log-port))
(release-lock (the-server-state-log-lock)))))
(define (maybe-dns-lookup ip)
(if (the-ftpd-options-dns-lookup?)
(or (dns-lookup-ip ip)
ip)
ip))
(define (maybe-open-logfile maybe-logfile)
(with-errno-handler
((errno packet)
(else
(format (current-error-port)
"[ftpd] Warning: Unable to write logs to ~S. Logging is now made to (current-error-port).~%[ftpd] (To disable logging at all, either leave the logfile argument or give #f as logfile)~%"
maybe-logfile)
(current-error-port)))
(and maybe-logfile
(open-output-file maybe-logfile
(bitwise-ior open/create open/append)))))
;;; CONVERTERS ------------------------------------------------
(define (protocol-family->string protocol-family)
(cond ((= protocol-family protocol-family/unspecified)
@ -338,12 +331,11 @@
#f
(lambda ()
(log (syslog-level notice)
"starting daemon on port ~D with ~S as anonymous home and logfile ~S"
"starting daemon on port ~D with ~S as anonymous home"
(ftpd-options-port ftpd-options)
(expand-file-name (ftpd-options-anonymous-home ftpd-options)
(cwd))
(ftpd-options-logfile ftpd-options))
(let ((maybe-log-port (maybe-open-logfile (ftpd-options-logfile ftpd-options))))
(cwd)))
(let ((the-server-state (make-server-state (ftpd-options-log-port ftpd-options))))
(bind-listen-accept-loop
protocol-family/internet
(lambda (socket address)
@ -355,10 +347,11 @@
socket
address
remote-address
maybe-log-port)))))
the-server-state)))))
(ftpd-options-port ftpd-options))))))
(define (handle-connection-encapsulated ftpd-options socket address remote-address maybe-log-port)
(define (handle-connection-encapsulated ftpd-options socket address remote-address
the-server-state)
(call-with-current-continuation
(lambda (exit)
(with-errno-handler*
@ -382,7 +375,7 @@
(handle-connection ftpd-options
(socket:inport socket)
(socket:outport socket)
maybe-log-port))
the-server-state))
(lambda ()
(log (syslog-level debug)
"shutting down socket ~S"
@ -417,7 +410,7 @@
(handle-connection ftpd-options
(current-input-port)
(current-output-port)
(maybe-open-logfile (ftpd-options-logfile ftpd-options))))))
(make-server-state (ftpd-options-log-port ftpd-options))))))
(define (set-ftp-socket-options! socket)
;; If the client closes the connection, we won't lose when we try to
@ -431,7 +424,7 @@
(set-socket-option socket level/socket socket/oob-inline #t))
(define (handle-connection ftpd-options input-port output-port maybe-log-port)
(define (handle-connection ftpd-options input-port output-port the-server-state)
(log (syslog-level debug)
"handling connection with input port ~A, output port ~A"
input-port
@ -447,7 +440,8 @@
(escape 'fick-dich-ins-knie))
(lambda ()
(let-fluids
session (make-session input-port output-port maybe-log-port)
session (make-session input-port output-port)
server-state the-server-state
options ftpd-options
(lambda ()
(display-banner)
@ -1305,7 +1299,7 @@
(define (signal-error! code message)
(replace-reply! code message)
(signal 'ftpd-error))
(signal 'ftpd-error code message))
(define (register-reply! code . messages)
(if (the-session-reply-code)

View File

@ -203,7 +203,7 @@
;; FTP server
(define-interface ftpd-interface
(export with-port with-anonymous-home with-banner with-logfile with-dns-lookup?
(export with-port with-anonymous-home with-banner with-log-port with-dns-lookup?
make-ftpd-options
ftpd
ftpd-inetd))