- (integer 0 255), or throws some kind of error. See gethostbyaddr(3) for
-grisly details."
- (sockint::with-in-addr packed-addr ()
- (let ((addr-vector (coerce address 'vector)))
- (loop for i from 0 below (length addr-vector)
- do (setf (sb-alien:deref (sockint::in-addr-addr packed-addr) i)
- (elt addr-vector i)))
- (make-host-ent (sockint::gethostbyaddr packed-addr
- 4
- sockint::af-inet)))))
-
-(defun make-host-ent (h)
- (if (sb-grovel::foreign-nullp h) (name-service-error "gethostbyname"))
- (let* ((length (sockint::hostent-length h))
- (aliases (loop for i = 0 then (1+ i)
- for al = (sb-alien:deref (sockint::hostent-aliases h) i)
- while al
- collect al))
- (address0 (sockint::hostent-addresses h))
- (addresses
- (loop for i = 0 then (1+ i)
- for ad = (sb-alien:deref address0 i)
- until (sb-alien:null-alien ad)
- collect (ecase (sockint::hostent-type h)
- (#.sockint::af-inet
- (loop for i from 0 below length
- collect (sb-alien:deref ad i)))
- (#.sockint::af-local
- (sb-alien:cast ad sb-alien:c-string))))))
- (make-instance 'host-ent
- :name (sockint::hostent-name h)
- :type (sockint::hostent-type h)
- :aliases aliases
- :addresses addresses)))
+ (integer 0 255), or signals a NAME-SERVICE-ERROR. See gethostbyaddr(3)
+ or gethostinfo(3) for details."
+ #+sb-bsd-sockets-addrinfo
+ (get-name-info address)
+ #-sb-bsd-sockets-addrinfo
+ (sb-thread::with-system-mutex (**gethostby-lock** :allow-with-interrupts t)
+ (sockint::with-in-addr packed-addr ()
+ (let ((addr-vector (coerce address 'vector)))
+ (loop for i from 0 below (length addr-vector)
+ do (setf (sb-alien:deref (sockint::in-addr-addr packed-addr) i)
+ (elt addr-vector i)))
+ (make-host-ent (sockint::gethostbyaddr packed-addr
+ 4
+ sockint::af-inet))))))
+
+;;; Emulate the above two functions with getaddrinfo / getnameinfo
+
+#+sb-bsd-sockets-addrinfo
+(defun get-address-info (node)
+ (sb-alien:with-alien ((buf (sb-alien:array (* sockint::addrinfo) 1)))
+ (let* ((res (sb-alien:addr (sb-alien:deref buf 0)))
+ (err (sockint::getaddrinfo node nil nil res)))
+ (if (zerop err)
+ (let ((host-ent (make-instance 'host-ent
+ :name node
+ :type sockint::af-inet
+ :aliases nil
+ :addresses nil)))
+ (loop for sap = (sb-alien:deref res) then (sockint::addrinfo-next info)
+ until (sb-alien::null-alien sap)
+ for info = (sb-alien:cast sap (* sockint::addrinfo))
+ ;; Only handle AF_INET currently.
+ do (when (eq (sockint::addrinfo-family info) sockint::af-inet)
+ (let* ((sockaddr (sockint::addrinfo-addr info))
+ (address (sockint::sockaddr-in-addr sockaddr)))
+ ;; The same effective result can be multiple time
+ ;; in the list, with different socktypes. Only record
+ ;; each address once.
+ (setf (slot-value host-ent 'addresses)
+ (adjoin (naturalize-unsigned-byte-8-array address
+ 4)
+ (host-ent-addresses host-ent)
+ :test 'equalp)))))
+ (sockint::freeaddrinfo (sb-alien:deref res))
+ host-ent)
+ (addrinfo-error "getaddrinfo" err)))))
+
+(defconstant ni-max-host 1025)