chiark / gitweb /
zone: Write output to DOMAIN.zone, rather than just DOMAIN.
[zone] / zone.lisp
index 153ce717121deac2cea5503429ec54e3e3cd752f..e83aa754b85a75c649d740a4743a5372612f33dc 100644 (file)
--- a/zone.lisp
+++ b/zone.lisp
@@ -40,6 +40,7 @@ (defpackage #:zone
             #:*default-mx-priority* #:*default-zone-admin*
             #:zone-find #:zone-parse #:zone-write #:zone-create #:defzone
             #:defrevzone #:zone-save
+          #:defzoneparse #:zone-parse-host
           #:timespec-seconds #:make-zone-serial))
 (in-package #:zone)
 
@@ -211,6 +212,11 @@ (defun resolve-hostname (name)
   (let ((he (ext:lookup-host-entry name)))
     (and he
         (ext:host-entry-addr he))))
+(defun canonify-hostname (name)
+  "Resolve a hostname to canonical form using the DNS, or return nil."
+  (let ((he (ext:lookup-host-entry name)))
+    (and he
+        (ext:host-entry-name he))))
 (defun parse-ipaddr (addr)
   "Convert the string ADDR into an IP address: tries all sorts of things:
 
@@ -365,7 +371,7 @@ (defstruct (zone (:predicate zonep))
 
 (defvar *default-zone-source*
   (let ((hn (unix:unix-gethostname)))
-    (and hn (resolve-hostname hn)))
+    (and hn (concatenate 'string (canonify-hostname hn) ".")))
   "The default zone source: the current host's name.")
 (defvar *default-zone-refresh* (* 24 60 60)
   "Default zone refresh interval: one day.")
@@ -673,7 +679,7 @@ (defun zone-parse-head (head)
   (destructuring-bind
       (zname
        &key
-       (source (concatenate 'string *default-zone-source* "."))
+       (source *default-zone-source*)
        (admin (or *default-zone-admin*
                  (format nil "hostmaster@~A" zname)))
        (refresh *default-zone-refresh*)
@@ -805,6 +811,19 @@ (defzoneparse :alias (name data rec :zname zname)
     (rec :name (zone-parse-host a zname)
         :type :cname
         :data name)))
+(defzoneparse :net (name data rec)
+  ":net (NETWORK*)"
+  (dolist (net (listify data))
+    (let ((n (net-get-as-ipnet net)))
+      (rec :name (zone-parse-host "net" name)
+          :type :a
+          :data (ipnet-net n))
+      (rec :name (zone-parse-host "mask" name)
+          :type :a
+          :data (ipnet-mask n))
+      (rec :name (zone-parse-host "broadcast" name)
+          :type :a
+          :data (ipnet-broadcast n)))))
   
 (defzoneparse (:rev :reverse) (name data rec)
   ":reverse ((NET :bytes BYTES) ZONE*)"
@@ -998,8 +1017,9 @@ (defun zone-save (zones)
        (unless zz
          (error "Unknown zone `~A'." z))
        (let ((stream (safely-open-output-stream safe
-                                                (string-downcase
-                                                 (stringify z)))))
+                                                (format nil
+                                                        "~(~A~).zone"
+                                                        z))))
          (zone-write zz stream))))))
 
 ;;;----- That's all, folks --------------------------------------------------