1 ;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp -*-
3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4 ; Copyright (C) 2006 by Stelian Ionescu ;
6 ; This program is free software; you can redistribute it and/or modify ;
7 ; it under the terms of the GNU General Public License as published by ;
8 ; the Free Software Foundation; either version 2 of the License, or ;
9 ; (at your option) any later version. ;
11 ; This program is distributed in the hope that it will be useful, ;
12 ; but WITHOUT ANY WARRANTY; without even the implied warranty of ;
13 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;
14 ; GNU General Public License for more details. ;
16 ; You should have received a copy of the GNU General Public License ;
17 ; along with this program; if not, write to the ;
18 ; Free Software Foundation, Inc., ;
19 ; 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ;
20 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
22 ;; (declaim (optimize (speed 2) (safety 2) (space 1) (debug 2)))
23 (declaim (optimize (speed 0) (safety 2) (space 0) (debug 2)))
25 (in-package :net.sockets
)
27 (defun load-file (path)
28 (with-open-file (fin path
)
29 (let ((big-string (make-string (file-length fin
))))
30 (read-sequence big-string fin
)
33 (defun space-char-p (char)
34 (declare (type character char
))
35 (or (char-equal char
#\Space
)
36 (char-equal char
#\Tab
)))
38 (defun split-string-by-spaces (string &key
(start 0) end empty-seqs
)
39 (declare (type string string
)
40 (type unsigned-byte start
)
41 (type (or unsigned-byte null
) end
))
42 (let ((substring-length (or end
(length string
))))
43 (assert (>= substring-length start
))
45 :with substr-start
:= (1- start
) :and substr-end
:= (1- start
)
46 :with dummy-char
:= #\Space
47 :for index
:upto substring-length
48 :for char
:= (if (eql index substring-length
) dummy-char
(char string index
))
49 :when
(and (space-char-p char
)
50 (setf substr-start
(1+ substr-end
)
52 (or (> substr-end substr-start
) empty-seqs
))
53 :collect
(subseq string substr-start substr-end
))))
55 (defun search-in-etc-file (path predicate
&optional
(match-all t
))
56 (let ((file (load-file path
))
58 (with-input-from-string (string-stream file
)
60 :for line
:= (read-line string-stream nil nil
)
61 :for comment-start
:= (or (position #\
# line
)
64 (destructuring-bind (&optional col1 col2
&rest other-cols
)
65 (split-string-by-spaces line
:empty-seqs nil
:end comment-start
)
66 (when col2
; skip invalid lines
67 (let ((result (funcall predicate col1 col2 other-cols
)))
72 :finally
(setf results
(nreverse results
))))
75 (defun vector-ipv6-good-p (vector ipv6
)
77 (let ((len (length vector
)))
83 (defun search-etc-hosts-ip (file ip ipv6
)
84 (let ((line (search-in-etc-file file
85 #'(lambda (col1 col2 other-cols
)
86 (let ((vector (string-address->vector col1
)))
87 (when (and (vector-ipv6-good-p vector ipv6
)
88 (vector-equal vector ip
))
90 (make-host col2
(make-address vector
) other-cols
)))
92 (map-host-ipv4-addresses-to-ipv6 host
)
97 (defun merge-lines-into-one-host (lines ipv6
)
98 (flet ((pushnew-alias (alias place cname
)
99 (when (string-not-equal alias cname
)
100 (pushnew alias place
:test
#'string-equal
)
103 (let (ips aliases host
)
104 (destructuring-bind (first-ip cname first-aliases
) (car lines
)
105 (setf ips
(list first-ip
))
106 (mapc #'(lambda (alias) (setf aliases
(pushnew-alias alias aliases cname
)))
108 (mapc #'(lambda (line)
109 (destructuring-bind (ip alias more-aliases
) line
111 (mapc #'(lambda (alias) (setf aliases
(pushnew-alias alias aliases cname
)))
112 (cons alias more-aliases
))))
114 (setf host
(make-host cname
115 (mapcar #'make-address
(nreverse ips
))
118 (map-host-ipv4-addresses-to-ipv6 host
)
121 (defun search-etc-hosts-name (file name ipv6
)
122 (let ((lines (search-in-etc-file file
123 #'(lambda (col1 col2 other-cols
)
124 (let ((vector (string-address->vector col1
)))
125 (when (and (vector-ipv6-good-p vector ipv6
)
126 (or (string-equal name col2
)
127 (member name other-cols
128 :test
#'string-equal
)))
129 (list vector col2 other-cols
))))
132 (merge-lines-into-one-host lines ipv6
))))