root/trunk/thirdparty/cl+ssl/bio.lisp

Revision 2698, 3.8 kB (checked in by hans, 10 months ago)

updated cl+ssl from CVS trunk - now with deadlines

Line 
1 ;;; Copyright (C) 2005  David Lichteblau
2 ;;;
3 ;;; See LICENSE for details.
4
5 (in-package cl+ssl)
6
7 (defconstant +bio-type-socket+ (logior 5 #x0400 #x0100))
8 (defconstant +BIO_FLAGS_READ+ 1)
9 (defconstant +BIO_FLAGS_WRITE+ 2)
10 (defconstant +BIO_FLAGS_SHOULD_RETRY+ 8)
11 (defconstant +BIO_CTRL_FLUSH+ 11)
12
13 (cffi:defcstruct bio-method
14   (type :int)
15   (name :pointer)
16   (bwrite :pointer)
17   (bread :pointer)
18   (bputs :pointer)
19   (bgets :pointer)
20   (ctrl :pointer)
21   (create :pointer)
22   (destroy :pointer)
23   (callback-ctrl :pointer))
24
25 (cffi:defcstruct bio
26   (method :pointer)
27   (callback :pointer)
28   (cb-arg :pointer)
29   (init :int)
30   (shutdown :int)
31   (flags :int)
32   (retry-reason :int)
33   (num :int)
34   (ptr :pointer)
35   (next-bio :pointer)
36   (prev-bio :pointer)
37   (references :int)
38   (num-read :unsigned-long)
39   (num-write :unsigned-long)
40   (crypto-ex-data-stack :pointer)
41   (crypto-ex-data-dummy :int))
42
43 (defun make-bio-lisp-method ()
44   (let ((m (cffi:foreign-alloc 'bio-method)))
45     (setf (cffi:foreign-slot-value m 'bio-method 'type)
46           ;; fixme: this is wrong, but presumably still better than some
47           ;; random value here.
48           +bio-type-socket+)
49     (macrolet ((slot (name)
50                  `(cffi:foreign-slot-value m 'bio-method ,name)))
51       (setf (slot 'name) (cffi:foreign-string-alloc "lisp"))
52       (setf (slot 'bwrite) (cffi:callback lisp-write))
53       (setf (slot 'bread) (cffi:callback lisp-read))
54       (setf (slot 'bputs) (cffi:callback lisp-puts))
55       (setf (slot 'bgets) (cffi:null-pointer))
56       (setf (slot 'ctrl) (cffi:callback lisp-ctrl))
57       (setf (slot 'create) (cffi:callback lisp-create))
58       (setf (slot 'destroy) (cffi:callback lisp-destroy))
59       (setf (slot 'callback-ctrl) (cffi:null-pointer)))
60     m))
61
62 (defun bio-new-lisp ()
63   (bio-new *bio-lisp-method*))
64
65
66 ;;; "cargo cult"
67
68 (cffi:defcallback lisp-write :int ((bio :pointer) (buf :pointer) (n :int))
69   bio
70   (dotimes (i n)
71     (write-byte (cffi:mem-ref buf :unsigned-char i) *socket*))
72   (finish-output *socket*)
73   n)
74
75 (defun clear-retry-flags (bio)
76   (setf (cffi:foreign-slot-value bio 'bio 'flags)
77         (logandc2 (cffi:foreign-slot-value bio 'bio 'flags)
78                   (logior +BIO_FLAGS_READ+
79                           +BIO_FLAGS_WRITE+
80                           +BIO_FLAGS_SHOULD_RETRY+))))
81
82 (defun set-retry-read (bio)
83   (setf (cffi:foreign-slot-value bio 'bio 'flags)
84         (logior (cffi:foreign-slot-value bio 'bio 'flags)
85                 +BIO_FLAGS_READ+
86                 +BIO_FLAGS_SHOULD_RETRY+)))
87
88 (cffi:defcallback lisp-read :int ((bio :pointer) (buf :pointer) (n :int))
89   bio buf n
90   (let ((i 0))
91     (handler-case
92         (unless (or (cffi:null-pointer-p buf) (null n))
93           (clear-retry-flags bio)
94           (when (or *blockp* (listen *socket*))
95             (setf (cffi:mem-ref buf :unsigned-char i) (read-byte *socket*))
96             (incf i))
97           (loop
98               while (and (< i n)
99                          (or (null *partial-read-p*) (listen *socket*)))
100               do
101                 (setf (cffi:mem-ref buf :unsigned-char i) (read-byte *socket*))
102                 (incf i))
103           #+(or)
104           (when (zerop i) (set-retry-read bio)))
105       (end-of-file ()))
106     i))
107
108 (cffi:defcallback lisp-puts :int ((bio :pointer) (buf :string))
109   bio buf
110   (error "lisp-puts not implemented"))
111
112 (cffi:defcallback lisp-ctrl :int
113   ((bio :pointer) (cmd :int) (larg :long) (parg :pointer))
114   bio larg parg
115   (cond
116     ((eql cmd +BIO_CTRL_FLUSH+) 1)
117     (t
118       ;; (warn "lisp-ctrl(~A,~A,~A)" cmd larg parg)
119       0)))
120
121 (cffi:defcallback lisp-create :int ((bio :pointer))
122   (setf (cffi:foreign-slot-value bio 'bio 'init) 1)
123   (setf (cffi:foreign-slot-value bio 'bio 'num) 0)
124   (setf (cffi:foreign-slot-value bio 'bio 'ptr) (cffi:null-pointer))
125   (setf (cffi:foreign-slot-value bio 'bio 'flags) 0)
126   1)
127
128 (cffi:defcallback lisp-destroy :int ((bio :pointer))
129   (cond
130     ((cffi:null-pointer-p bio) 0)
131     (t
132       (setf (cffi:foreign-slot-value bio 'bio 'init) 0)
133       (setf (cffi:foreign-slot-value bio 'bio 'flags) 0)
134       1)))
135
136 (setf *bio-lisp-method* nil)            ;force reinit if anything changed here
Note: See TracBrowser for help on using the browser.