X-Git-Url: http://cgit.sxemacs.org/?a=blobdiff_plain;f=lisp%2Fdns.el;h=f23e87a6bcd4790804e711603bc3360fb46ea6ca;hb=3f8329904865e576f8046a203db287b018094759;hp=1c5b4b6f0822e63dba71340f8aea76b175f684c8;hpb=000d44b99765442c07e930cfac062859b88e1bb4;p=gnus diff --git a/lisp/dns.el b/lisp/dns.el index 1c5b4b6f0..f23e87a6b 100644 --- a/lisp/dns.el +++ b/lisp/dns.el @@ -1,5 +1,5 @@ ;;; dns.el --- Domain Name Service lookups -;; Copyright (C) 2002 Free Software Foundation, Inc. +;; Copyright (C) 2002, 2003 Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; Keywords: network @@ -25,11 +25,17 @@ ;;; Code: +(eval-when-compile (require 'cl)) + (require 'mm-util) (defvar dns-timeout 5 "How many seconds to wait when doing DNS queries.") +(defvar dns-servers nil + "Which DNS servers to query. +If nil, /etc/resolv.conf will be consulted.") + ;;; Internal code: (defvar dns-query-types @@ -121,11 +127,14 @@ (progn (forward-char length) (point))) name)))) (if (stringp ended) - (concat (mapconcat 'identity (nreverse name) ".") "." ended) + (if (null name) + ended + (concat (mapconcat 'identity (nreverse name) ".") "." ended)) (mapconcat 'identity (nreverse name) ".")))) -(defun dns-write (spec) - "Write a DNS packet according to SPEC." +(defun dns-write (spec &optional tcp-p) + "Write a DNS packet according to SPEC. +If TCP-P, the first two bytes of the package with be the length field." (with-temp-buffer (dns-write-bytes (dns-get 'id spec) 2) (dns-write-bytes @@ -170,6 +179,9 @@ (dns-write-bytes (dns-get 'ttl resource) 4) (dns-write-bytes (length (dns-get 'data resource)) 2) (insert (dns-get 'data resource)))) + (when tcp-p + (goto-char (point-min)) + (dns-write-bytes (buffer-size) 2)) (buffer-string))) (defun dns-read (packet) @@ -254,43 +266,91 @@ (mapconcat 'number-to-string (nreverse bytes) "."))) ((eq type 'NS) (dns-read-string-name string buffer)) + ((eq type 'CNAME) + (dns-read-string-name string buffer)) (t string))) (goto-char point)))) +(defun dns-parse-resolv-conf () + (when (file-exists-p "/etc/resolv.conf") + (with-temp-buffer + (insert-file-contents "/etc/resolv.conf") + (goto-char (point-min)) + (while (re-search-forward "^nameserver[\t ]+\\([^ \t\n]+\\)" nil t) + (push (match-string 1) dns-servers)) + (setq dns-servers (nreverse dns-servers))))) + ;;; Interface functions. -(defun query-dns (name &optional type) - "Query a DNS server for NAME of TYPE." +(autoload 'gnus-xmacs-open-network-stream "gnus-xmas" nil nil 'macro) + +(defmacro dns-make-network-process (server) + (if (featurep 'xemacs) + `(let ((coding-system-for-read 'binary) + (coding-system-for-write 'binary)) + (gnus-xmas-open-network-stream "dns" (current-buffer) + ,server "domain" 'udp)) + `(let ((server ,server) + (coding-system-for-read 'binary) + (coding-system-for-write 'binary)) + (if (fboundp 'make-network-process) + (make-network-process + :name "dns" + :coding 'binary + :buffer (current-buffer) + :host server + :service "domain" + :type 'datagram) + ;; Older versions of Emacs doesn't have + ;; `make-network-process', so we fall back on opening a TCP + ;; connection to the DNS server. + (open-network-stream "dns" (current-buffer) server "domain"))))) + +(defun query-dns (name &optional type fullp) + "Query a DNS server for NAME of TYPE. +If FULLP, return the entire record returned." (setq type (or type 'A)) + (unless dns-servers + (dns-parse-resolv-conf) + (unless dns-servers + (error "No DNS server configuration found"))) (mm-with-unibyte-buffer - (let ((coding-system-for-read 'binary) - (coding-system-for-write 'binary)) - (let ((process - (make-network-process - :name "dns" - :coding 'binary - :buffer (current-buffer) - :host "ns2.netfonds.no" - :service "domain" - :type 'datagram)) - (step 100) - (times (* dns-timeout 1000))) + (let ((process (condition-case () + (dns-make-network-process (car dns-servers)) + (error + (message "dns: Got an error while trying to talk to %s" + (car dns-servers)) + nil))) + (tcp-p (and (not (fboundp 'make-network-process)) + (not (featurep 'xemacs)))) + (step 100) + (times (* dns-timeout 1000)) + (id (random 65000))) + (when process (process-send-string process - (dns-write `((id 4) + (dns-write `((id ,id) (opcode query) (queries ((,name (type ,type)))) - (recursion-desired-p t)))) + (recursion-desired-p t)) + tcp-p)) (while (and (zerop (buffer-size)) (> times 0)) (accept-process-output process 0 step) (decf times step)) (ignore-errors (delete-process process)) - (let ((answer (car (dns-get 'answers (dns-read (buffer-string)))))) - (when (eq type (dns-get 'type answer)) - (dns-get 'data answer))))))) - + (when tcp-p + (goto-char (point-min)) + (delete-region (point) (+ (point) 2))) + (unless (zerop (buffer-size)) + (let ((result (dns-read (buffer-string)))) + (if fullp + result + (let ((answer (car (dns-get 'answers result)))) + (when (eq type (dns-get 'type answer)) + (dns-get 'data answer)))))))))) + (provide 'dns) ;;; dns.el ends here