;;;;
;;;; Date Started: Feb 2002
;;;;
-;;;; $Id: postgresql-socket-api.cl,v 1.7 2002/03/26 17:16:18 kevin Exp $
+;;;; $Id: postgresql-socket-api.cl,v 1.13 2002/04/06 23:23:47 kevin Exp $
;;;;
;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg
;;;; and Copyright (c) 1999-2001 by Pierre R. Mai
((:bytea 17)
(:int2 21)
(:int4 23)
+ (:int8 20)
(:float4 700)
(:float8 701)))
;;; Support for encrypted password transmission
-(defconstant +crypt-library+ "/usr/lib/libcrypt.so"
- "Name of the shared library to load in order to access the crypt
-function named by `*crypt-function-name*'.")
-
(defvar *crypt-library-loaded* nil)
(defun crypt-password (password salt)
"Encrypt a password for transmission to a PostgreSQL server."
(unless *crypt-library-loaded*
- (uffi:load-foreign-library +crypt-library+ :supporting-libaries '("c"))
- (eval (uffi:def-function "crypt"
- ((key :cstring)
- (salt :cstring))
+ (uffi:load-foreign-library
+ (find-foreign-library "libcrypt"
+ '("/usr/lib/" "/usr/local/lib/" "/lib/"))
+ :supporting-libaries '("c"))
+ (eval '(uffi:def-function "crypt"
+ ((key :cstring)
+ (salt :cstring))
:returning :cstring))
(setq *crypt-library-loaded* t))
(uffi:with-cstring (password-cstring password)
(defun read-field (socket type)
(let ((length (- (read-socket-value 'int32 socket) 4)))
(case type
- (:int
+ ((:int32 :int64)
(read-integer-from-socket socket length))
(:double
(read-double-from-socket socket length))
(uffi:def-constant +char-code-upper-e+ (char-code #\E))
(defun read-integer-from-socket (socket length)
- (let ((val 0)
- (first-char (read-byte socket))
- (minusp nil))
- (declare (fixnum first-char))
- (if (zerop length)
- nil
- (progn
- (cond
- ((= first-char +char-code-minus+)
- (setq minusp t))
- ((= first-char +char-code-plus+)
- ) ; nothing to do
- (t
- (setq val (- first-char +char-code-zero+))))
- (dotimes (i (1- length))
- (declare (fixnum i))
- (setq val (+
- (* 10 val)
- (- (read-byte socket) +char-code-zero+))))
- (if minusp
- (- val)
- val)))))
+ (declare (fixnum length))
+ (if (zerop length)
+ nil
+ (let ((val 0)
+ (first-char (read-byte socket))
+ (minusp nil))
+ (declare (fixnum first-char))
+ (decf length) ;; read first char
+ (cond
+ ((= first-char +char-code-minus+)
+ (setq minusp t))
+ ((= first-char +char-code-plus+)
+ ) ;; nothing to do
+ (t
+ (setq val (- first-char +char-code-zero+))))
+
+ (dotimes (i length)
+ (declare (fixnum i))
+ (setq val (+
+ (* 10 val)
+ (- (read-byte socket) +char-code-zero+))))
+ (if minusp
+ (- val)
+ val))))
(defmacro ascii-digit (int)
(let ((offset (gensym)))
nil))))
(defun read-double-from-socket (socket length)
+ (declare (fixnum length))
(let ((before-decimal 0)
(after-decimal 0)
(decimal-count 0)
(minusp nil)
(result nil)
(char (read-byte socket)))
- (declare (fixnum char))
+ (declare (fixnum char exponent decimal-count))
(decf length) ;; already read first character
(cond
((= char +char-code-minus+)
- (setq minusp t)
- (setq char (read-byte socket))
- (decf length))
+ (setq minusp t))
((= char +char-code-plus+)
- (setq char (read-byte socket))
- (decf length)))
+ )
+ ((= char +char-code-period+)
+ (setq decimalp t))
+ (t
+ (setq before-decimal (ascii-digit char))
+ (unless before-decimal
+ (error "Unexpected value"))))
- (dotimes (i length)
- (let ((weight (ascii-digit char)))
- (cond
- ((and weight (not decimalp)) ;; before decimal point
- (setq before-decimal (+ weight (* 10 before-decimal)))
- (setq char (read-byte socket)))
- ((and weight decimalp) ;; after decimal point
- (setq after-decimal (+ weight (* 10 after-decimal)))
- (incf decimal-count)
- (setq char (read-byte socket)))
- ((and (= char +char-code-period+))
- (setq decimalp t)
- (setq char (read-byte socket)))
- ((or (= char +char-code-lower-e+) ;; E is for exponent
- (= char +char-code-upper-e+))
- (setq exponent (read-integer-from-socket socket (- length i)))
- (format t "~&exp: ~a" exponent)
- (setq exponent (or exponent 0))
- (setq i length))
+ (block loop
+ (dotimes (i length)
+ (setq char (read-byte socket))
+ ;; (format t "~&len:~D, i:~D, char:~D, minusp:~A, decimalp:~A" length i char minusp decimalp)
+ (let ((weight (ascii-digit char)))
+ (cond
+ ((and weight (not decimalp)) ;; before decimal point
+ (setq before-decimal (+ weight (* 10 before-decimal))))
+ ((and weight decimalp) ;; after decimal point
+ (setq after-decimal (+ weight (* 10 after-decimal)))
+ (incf decimal-count))
+ ((and (= char +char-code-period+))
+ (setq decimalp t))
+ ((or (= char +char-code-lower-e+) ;; E is for exponent
+ (= char +char-code-upper-e+))
+ (setq exponent (read-integer-from-socket socket (- length i 1)))
+ (setq exponent (or exponent 0))
+ (return-from loop))
(t
(break "Unexpected value"))
)
- ))
+ )))
(setq result (* (+ (coerce before-decimal 'double-float)
(* after-decimal
(expt 10 (- decimal-count))))