2011/12/31

どうしても最後に Common Lisp のコードを書いておかないと

年が越せない。

#+nil
(eval-when (:compile-toplevel :load-toplevel :execute)
(ql:quickload :iolib)
(ql:quickload :quek))


(quek:sdefpackage :httpd
(:use :cl))

(in-package :httpd)

(named-readtables:in-readtable quek:|#"|)

(defvar *httpd*)

(alexandria:define-constant +crlf+ (format nil "~c~c" #\cr #\lf) :test #'equalp)

(defun start (&key (port 8888))
(setf *httpd* (make-instance 'iolib.multiplex:event-base))
(let ((socket (iolib.sockets:make-socket :address-family :ipv4
:type :stream
:connect :passive
:local-host "0.0.0.0"
:local-port port)))
(iolib.sockets::listen-on socket)
(describe socket)
(iolib.multiplex::set-io-handler
*httpd*
(iolib.streams::fd-of socket)
:read (lambda (fd event exception)
(declare (ignore fd event exception))
(let ((client-socket (iolib.sockets:accept-connection socket)))
(let ((fd (iolib.streams:fd-of client-socket)))
(iolib.multiplex:set-io-handler
*httpd* fd
:read (lambda (_fd event exception)
(declare (ignore _fd event exception))
(unwind-protect
(handler client-socket)
(iomux:remove-fd-handlers *httpd* fd :read t)
(close client-socket))))))))
(unwind-protect
(iolib.multiplex:event-dispatch *httpd*)
(close socket))))

(defun handler (client-socket)
(let ((buffer (make-array 4096 :element-type '(unsigned-byte 8))))
(multiple-value-bind (buffer nbytes) (iolib.sockets:receive-from client-socket :buffer buffer)
(multiple-value-bind (buffer nbytes) (request buffer nbytes)
(iolib.sockets:send-to client-socket buffer :end nbytes)))))

(defun request (buffer nbytes)
(declare (ignore nbytes))
(let* ((start (position #x20 buffer))
(end (position #x20 buffer :start (+ start 2)))
(path (sb-ext:octets-to-string buffer
:external-format :utf-8
:start (1+ start)
:end end))
(symbol-name (string-upcase path))
(symbol (or (find-symbol symbol-name :httpd) '/404)))
(funcall symbol)))


(defun /hello ()
(make-response "<html><body><h1>hello</h1></body></html>"))

(defun /404 ()
(make-response "<html><body><h1>404</h1></body></html>"))

(defun make-response (content)
(let* ((response #"""HTTP/1.0 200#,+crlf+,Content-Type: text/html; charset=utf-8;#,+crlf+,#,+crlf+,#,content""")
(buffer (sb-ext:string-to-octets response :external-format :utf-8)))
(values buffer (length buffer))))

2011/12/18

AQUOS PHONE 102SH 買った

金曜日に 4 年以上使っていた 702SCII から AQUOS PHONE 102SH に移行した。 iPhone 3G の方が動きはスムーズたと思った。ときどき動きがひっかかる。バックグラウンドでたくさんのプロセスが動いているようだから、いらないものを殺せばスムーズになるのかもしれない。

ConnectBot 入れたらすんなり端末から外部のサーバに ssh できるようになった。これで緊急時にもなんとか対応できる。 4.5 インチで 1280 × 720 ドットだとすごく文字が小さいけどね。 ssh できればサーバで emacs slime sbcl を動かして Common Lisp 端末とすることもできる。

702SCII はこどものおもちゃとなり、もじぴったんとかでよろこんで遊んでいる。