comparison lisp/net/dns.el @ 86917:439fa1afe05a

Refill copyright. (top-level): Don't require mm-util, or cl when compiling. (dns-write-name, dns-read, dns-read-type, query-dns): Replace mm-with-unibyte-buffer with its expansion. (query-dns): Replace decf and ignore-errors with non-cl equivalents.
author Glenn Morris <rgm@gnu.org>
date Sat, 01 Dec 2007 21:02:07 +0000
parents b48d018b85e2
children 107ccd98fa12
comparison
equal deleted inserted replaced
86916:62c3928ba4fb 86917:439fa1afe05a
1 ;;; dns.el --- Domain Name Service lookups 1 ;;; dns.el --- Domain Name Service lookups
2 2
3 ;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 3 ;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
4 ;; Free Software Foundation, Inc.
4 5
5 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org> 6 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
6 ;; Keywords: network 7 ;; Keywords: network
7 8
8 ;; This file is part of GNU Emacs. 9 ;; This file is part of GNU Emacs.
23 ;; Boston, MA 02110-1301, USA. 24 ;; Boston, MA 02110-1301, USA.
24 25
25 ;;; Commentary: 26 ;;; Commentary:
26 27
27 ;;; Code: 28 ;;; Code:
28
29 (eval-when-compile (require 'cl))
30
31 (require 'mm-util)
32 29
33 (defvar dns-timeout 5 30 (defvar dns-timeout 5
34 "How many seconds to wait when doing DNS queries.") 31 "How many seconds to wait when doing DNS queries.")
35 32
36 (defvar dns-servers nil 33 (defvar dns-servers nil
103 (dns-write-bytes (length part)) 100 (dns-write-bytes (length part))
104 (insert part)) 101 (insert part))
105 (dns-write-bytes 0)) 102 (dns-write-bytes 0))
106 103
107 (defun dns-read-string-name (string buffer) 104 (defun dns-read-string-name (string buffer)
108 (mm-with-unibyte-buffer 105 (let (default-enable-multibyte-characters)
109 (insert string) 106 (with-temp-buffer
110 (goto-char (point-min)) 107 (insert string)
111 (dns-read-name buffer))) 108 (goto-char (point-min))
109 (dns-read-name buffer))))
112 110
113 (defun dns-read-name (&optional buffer) 111 (defun dns-read-name (&optional buffer)
114 (let ((ended nil) 112 (let ((ended nil)
115 (name nil) 113 (name nil)
116 length) 114 length)
186 (goto-char (point-min)) 184 (goto-char (point-min))
187 (dns-write-bytes (buffer-size) 2)) 185 (dns-write-bytes (buffer-size) 2))
188 (buffer-string))) 186 (buffer-string)))
189 187
190 (defun dns-read (packet) 188 (defun dns-read (packet)
191 (mm-with-unibyte-buffer 189 (let (default-enable-multibyte-characters)
192 (let ((spec nil) 190 (with-temp-buffer
193 queries answers authorities additionals) 191 (let ((spec nil)
194 (insert packet) 192 queries answers authorities additionals)
195 (goto-char (point-min)) 193 (insert packet)
196 (push (list 'id (dns-read-bytes 2)) spec) 194 (goto-char (point-min))
197 (let ((byte (dns-read-bytes 1))) 195 (push (list 'id (dns-read-bytes 2)) spec)
198 (push (list 'response-p (if (zerop (logand byte (lsh 1 7))) nil t)) 196 (let ((byte (dns-read-bytes 1)))
199 spec) 197 (push (list 'response-p (if (zerop (logand byte (lsh 1 7))) nil t))
200 (let ((opcode (logand byte (lsh 7 3)))) 198 spec)
201 (push (list 'opcode 199 (let ((opcode (logand byte (lsh 7 3))))
202 (cond ((eq opcode 0) 'query) 200 (push (list 'opcode
203 ((eq opcode 1) 'inverse-query) 201 (cond ((eq opcode 0) 'query)
204 ((eq opcode 2) 'status))) 202 ((eq opcode 1) 'inverse-query)
205 spec)) 203 ((eq opcode 2) 'status)))
206 (push (list 'authoritative-p (if (zerop (logand byte (lsh 1 2))) 204 spec))
207 nil t)) spec) 205 (push (list 'authoritative-p (if (zerop (logand byte (lsh 1 2)))
208 (push (list 'truncated-p (if (zerop (logand byte (lsh 1 2))) nil t)) 206 nil t)) spec)
209 spec) 207 (push (list 'truncated-p (if (zerop (logand byte (lsh 1 2))) nil t))
210 (push (list 'recursion-desired-p 208 spec)
211 (if (zerop (logand byte (lsh 1 0))) nil t)) spec)) 209 (push (list 'recursion-desired-p
212 (let ((rc (logand (dns-read-bytes 1) 15))) 210 (if (zerop (logand byte (lsh 1 0))) nil t)) spec))
213 (push (list 'response-code 211 (let ((rc (logand (dns-read-bytes 1) 15)))
214 (cond 212 (push (list 'response-code
215 ((eq rc 0) 'no-error) 213 (cond
216 ((eq rc 1) 'format-error) 214 ((eq rc 0) 'no-error)
217 ((eq rc 2) 'server-failure) 215 ((eq rc 1) 'format-error)
218 ((eq rc 3) 'name-error) 216 ((eq rc 2) 'server-failure)
219 ((eq rc 4) 'not-implemented) 217 ((eq rc 3) 'name-error)
220 ((eq rc 5) 'refused))) 218 ((eq rc 4) 'not-implemented)
221 spec)) 219 ((eq rc 5) 'refused)))
222 (setq queries (dns-read-bytes 2)) 220 spec))
223 (setq answers (dns-read-bytes 2)) 221 (setq queries (dns-read-bytes 2))
224 (setq authorities (dns-read-bytes 2)) 222 (setq answers (dns-read-bytes 2))
225 (setq additionals (dns-read-bytes 2)) 223 (setq authorities (dns-read-bytes 2))
226 (let ((qs nil)) 224 (setq additionals (dns-read-bytes 2))
227 (dotimes (i queries) 225 (let ((qs nil))
228 (push (list (dns-read-name) 226 (dotimes (i queries)
229 (list 'type (dns-inverse-get (dns-read-bytes 2) 227 (push (list (dns-read-name)
230 dns-query-types)) 228 (list 'type (dns-inverse-get (dns-read-bytes 2)
231 (list 'class (dns-inverse-get (dns-read-bytes 2) 229 dns-query-types))
232 dns-classes))) 230 (list 'class (dns-inverse-get (dns-read-bytes 2)
233 qs)) 231 dns-classes)))
234 (push (list 'queries qs) spec)) 232 qs))
235 (dolist (slot '(answers authorities additionals)) 233 (push (list 'queries qs) spec))
236 (let ((qs nil) 234 (dolist (slot '(answers authorities additionals))
237 type) 235 (let ((qs nil)
238 (dotimes (i (symbol-value slot)) 236 type)
239 (push (list (dns-read-name) 237 (dotimes (i (symbol-value slot))
240 (list 'type 238 (push (list (dns-read-name)
241 (setq type (dns-inverse-get (dns-read-bytes 2) 239 (list 'type
242 dns-query-types))) 240 (setq type (dns-inverse-get (dns-read-bytes 2)
243 (list 'class (dns-inverse-get (dns-read-bytes 2) 241 dns-query-types)))
244 dns-classes)) 242 (list 'class (dns-inverse-get (dns-read-bytes 2)
245 (list 'ttl (dns-read-bytes 4)) 243 dns-classes))
246 (let ((length (dns-read-bytes 2))) 244 (list 'ttl (dns-read-bytes 4))
247 (list 'data 245 (let ((length (dns-read-bytes 2)))
248 (dns-read-type 246 (list 'data
249 (buffer-substring 247 (dns-read-type
250 (point) 248 (buffer-substring
251 (progn (forward-char length) (point))) 249 (point)
252 type)))) 250 (progn (forward-char length) (point)))
253 qs)) 251 type))))
254 (push (list slot qs) spec))) 252 qs))
255 (nreverse spec)))) 253 (push (list slot qs) spec)))
254 (nreverse spec)))))
256 255
257 (defun dns-read-int32 () 256 (defun dns-read-int32 ()
258 ;; Full 32 bit Integers can't be handled by Emacs. If we use 257 ;; Full 32 bit Integers can't be handled by Emacs. If we use
259 ;; floats, it works. 258 ;; floats, it works.
260 (format "%.0f" (+ (* (dns-read-bytes 1) 16777216.0) 259 (format "%.0f" (+ (* (dns-read-bytes 1) 16777216.0)
262 261
263 (defun dns-read-type (string type) 262 (defun dns-read-type (string type)
264 (let ((buffer (current-buffer)) 263 (let ((buffer (current-buffer))
265 (point (point))) 264 (point (point)))
266 (prog1 265 (prog1
267 (mm-with-unibyte-buffer 266 (let (default-enable-multibyte-characters)
268 (insert string) 267 (with-temp-buffer
269 (goto-char (point-min)) 268 (insert string)
270 (cond 269 (goto-char (point-min))
271 ((eq type 'A) 270 (cond
272 (let ((bytes nil)) 271 ((eq type 'A)
273 (dotimes (i 4) 272 (let ((bytes nil))
274 (push (dns-read-bytes 1) bytes)) 273 (dotimes (i 4)
275 (mapconcat 'number-to-string (nreverse bytes) "."))) 274 (push (dns-read-bytes 1) bytes))
276 ((eq type 'AAAA) 275 (mapconcat 'number-to-string (nreverse bytes) ".")))
277 (let (hextets) 276 ((eq type 'AAAA)
278 (dotimes (i 8) 277 (let (hextets)
279 (push (dns-read-bytes 2) hextets)) 278 (dotimes (i 8)
280 (mapconcat (lambda (n) (format "%x" n)) (nreverse hextets) ":"))) 279 (push (dns-read-bytes 2) hextets))
281 ((eq type 'SOA) 280 (mapconcat (lambda (n) (format "%x" n))
282 (list (list 'mname (dns-read-name buffer)) 281 (nreverse hextets) ":")))
283 (list 'rname (dns-read-name buffer)) 282 ((eq type 'SOA)
284 (list 'serial (dns-read-int32)) 283 (list (list 'mname (dns-read-name buffer))
285 (list 'refresh (dns-read-int32)) 284 (list 'rname (dns-read-name buffer))
286 (list 'retry (dns-read-int32)) 285 (list 'serial (dns-read-int32))
287 (list 'expire (dns-read-int32)) 286 (list 'refresh (dns-read-int32))
288 (list 'minimum (dns-read-int32)))) 287 (list 'retry (dns-read-int32))
289 ((eq type 'SRV) 288 (list 'expire (dns-read-int32))
290 (list (list 'priority (dns-read-bytes 2)) 289 (list 'minimum (dns-read-int32))))
291 (list 'weight (dns-read-bytes 2)) 290 ((eq type 'SRV)
292 (list 'port (dns-read-bytes 2)) 291 (list (list 'priority (dns-read-bytes 2))
293 (list 'target (dns-read-name buffer)))) 292 (list 'weight (dns-read-bytes 2))
294 ((eq type 'MX) 293 (list 'port (dns-read-bytes 2))
295 (cons (dns-read-bytes 2) (dns-read-name buffer))) 294 (list 'target (dns-read-name buffer))))
296 ((or (eq type 'CNAME) (eq type 'NS) (eq type 'PTR)) 295 ((eq type 'MX)
297 (dns-read-string-name string buffer)) 296 (cons (dns-read-bytes 2) (dns-read-name buffer)))
298 (t string))) 297 ((or (eq type 'CNAME) (eq type 'NS) (eq type 'PTR))
298 (dns-read-string-name string buffer))
299 (t string))))
299 (goto-char point)))) 300 (goto-char point))))
300 301
301 (defun dns-parse-resolv-conf () 302 (defun dns-parse-resolv-conf ()
302 (when (file-exists-p "/etc/resolv.conf") 303 (when (file-exists-p "/etc/resolv.conf")
303 (with-temp-buffer 304 (with-temp-buffer
375 ".in-addr.arpa") 376 ".in-addr.arpa")
376 type 'PTR)) 377 type 'PTR))
377 378
378 (if (not dns-servers) 379 (if (not dns-servers)
379 (message "No DNS server configuration found") 380 (message "No DNS server configuration found")
380 (mm-with-unibyte-buffer 381 (let (default-enable-multibyte-characters)
381 (let ((process (condition-case () 382 (with-temp-buffer
382 (dns-make-network-process (car dns-servers)) 383 (let ((process (condition-case ()
383 (error 384 (dns-make-network-process (car dns-servers))
384 (message "dns: Got an error while trying to talk to %s" 385 (error
385 (car dns-servers)) 386 (message
386 nil))) 387 "dns: Got an error while trying to talk to %s"
387 (tcp-p (and (not (fboundp 'make-network-process)) 388 (car dns-servers))
388 (not (featurep 'xemacs)))) 389 nil)))
389 (step 100) 390 (tcp-p (and (not (fboundp 'make-network-process))
390 (times (* dns-timeout 1000)) 391 (not (featurep 'xemacs))))
391 (id (random 65000))) 392 (step 100)
392 (when process 393 (times (* dns-timeout 1000))
393 (process-send-string 394 (id (random 65000)))
394 process 395 (when process
395 (dns-write `((id ,id) 396 (process-send-string
396 (opcode query) 397 process
397 (queries ((,name (type ,type)))) 398 (dns-write `((id ,id)
398 (recursion-desired-p t)) 399 (opcode query)
399 tcp-p)) 400 (queries ((,name (type ,type))))
400 (while (and (zerop (buffer-size)) 401 (recursion-desired-p t))
401 (> times 0)) 402 tcp-p))
402 (sit-for (/ step 1000.0)) 403 (while (and (zerop (buffer-size))
403 (accept-process-output process 0 step) 404 (> times 0))
404 (decf times step)) 405 (sit-for (/ step 1000.0))
405 (ignore-errors 406 (accept-process-output process 0 step)
406 (delete-process process)) 407 (setq times (- times step)))
407 (when (and tcp-p 408 (condition-case nil
408 (>= (buffer-size) 2)) 409 (delete-process process)
409 (goto-char (point-min)) 410 (error nil))
410 (delete-region (point) (+ (point) 2))) 411 (when (and tcp-p
411 (when (and (>= (buffer-size) 2) 412 (>= (buffer-size) 2))
412 ;; We had a time-out. 413 (goto-char (point-min))
413 (> times 0)) 414 (delete-region (point) (+ (point) 2)))
414 (let ((result (dns-read (buffer-string)))) 415 (when (and (>= (buffer-size) 2)
415 (if fullp 416 ;; We had a time-out.
416 result 417 (> times 0))
417 (let ((answer (car (dns-get 'answers result)))) 418 (let ((result (dns-read (buffer-string))))
418 (when (eq type (dns-get 'type answer)) 419 (if fullp
419 (if (eq type 'TXT) 420 result
420 (dns-get-txt-answer (dns-get 'answers result)) 421 (let ((answer (car (dns-get 'answers result))))
421 (dns-get 'data answer)))))))))))) 422 (when (eq type (dns-get 'type answer))
423 (if (eq type 'TXT)
424 (dns-get-txt-answer (dns-get 'answers result))
425 (dns-get 'data answer)))))))))))))
422 426
423 (provide 'dns) 427 (provide 'dns)
424 428
425 ;;; arch-tag: d0edd0c4-4cce-4538-ae92-06c3356ee80a 429 ;;; arch-tag: d0edd0c4-4cce-4538-ae92-06c3356ee80a
426 ;;; dns.el ends here 430 ;;; dns.el ends here