(in-package harder) (defvar *posts* (list)) (when (probe-file #p"posts.txt") (let ((*read-eval* nil)) (with-open-file (in #p"posts.txt") (loop for post = (read in nil nil) while post do (push post *posts*))))) (defun serve () (let ((socket (usocket:socket-listen "127.0.0.1" 8070)) (connection nil)) (loop (handler-case (unwind-protect (setf connection (usocket:socket-accept socket :element-type 'character)) (usocket:wait-for-input connection) (let* ((*read-eval* nil) (stream (usocket:socket-stream connection))) (loop initially (format *terminal-io* "Connected at ~d~%" (get-universal-time)) for item-type = (read-char stream) for alist = (read stream) for message = (read-line stream) do (assert (consp alist)) do (unless (or (string= message "") (string= message "/r (with-open-file (s #p"posts.txt" :direction :output :if-exists :append :if-does-not-exist :create) (prin1 (cons alist message) s) (terpri s))) do (if (or (string= message "/r (format stream "~{~a~%~}" (mapcan (lambda (post) (if (subsetp alist (car post) :test 'equalp) (list post) nil)) *posts*)) (format stream "~{~a~%~}~%" (mapcan (lambda (post) (if (subsetp alist (car post) :test 'equalp) (list post) nil)) (push (cons alist message) *posts*)))) do (return)) (format *terminal-io* "finished message") (terpri stream) (force-output stream) (sleep 0.5)) (progn (format *terminal-io* "Connection closing at ~D~%" (get-universal-time)) (usocket:socket-close connection))) (t (e) (format *terminal-io* "Serve error: ~a, quitting at ~d" e (get-universal-time)) (sleep (random 5))))))) (serve)