chiark / gitweb /
zone: Delete redundant functions.
[zone] / zone.lisp
index 79c6c19cbdbb049aca520d27bd2e7acc1a9beddc..1d7e18d0ea2ec11962c7d8dd001b476313d53444 100644 (file)
--- a/zone.lisp
+++ b/zone.lisp
 ;;; it under the terms of the GNU General Public License as published by
 ;;; the Free Software Foundation; either version 2 of the License, or
 ;;; (at your option) any later version.
-;;; 
+;;;
 ;;; This program is distributed in the hope that it will be useful,
 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ;;; GNU General Public License for more details.
-;;; 
+;;;
 ;;; You should have received a copy of the GNU General Public License
 ;;; along with this program; if not, write to the Free Software Foundation,
 ;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
@@ -49,7 +49,7 @@ (defun to-integer (x)
 
 (defun from-mixed-base (base val)
   "BASE is a list of the ranges for the `digits' of a mixed-base
-representation.  Convert VAL, a list of digits, into an integer."
+   representation.  Convert VAL, a list of digits, into an integer."
   (do ((base base (cdr base))
        (val (cdr val) (cdr val))
        (a (car val) (+ (* a (car base)) (car val))))
@@ -57,7 +57,7 @@ (defun from-mixed-base (base val)
 
 (defun to-mixed-base (base val)
   "BASE is a list of the ranges for the `digits' of a mixed-base
-representation.  Convert VAL, an integer, into a list of digits."
+   representation.  Convert VAL, an integer, into a list of digits."
   (let ((base (reverse base))
        (a nil))
     (loop
@@ -70,8 +70,8 @@ (defun to-mixed-base (base val)
 
 (defun timespec-seconds (ts)
   "Convert a timespec TS to seconds.  A timespec may be a real count of
-seconds, or a list (COUNT UNIT): UNIT may be any of a number of obvious time
-units."
+   seconds, or a list (COUNT UNIT): UNIT may be any of a number of obvious
+   time units."
   (cond ((null ts) 0)
        ((realp ts) (floor ts))
        ((atom ts)
@@ -99,9 +99,9 @@ (defun hash-table-keys (ht)
 
 (defun iso-date (&optional time &key datep timep (sep #\ ))
   "Construct a textual date or time in ISO format.  The TIME is the universal
-time to convert, which defaults to now; DATEP is whether to emit the date;
-TIMEP is whether to emit the time, and SEP (default is space) is how to
-separate the two."
+   time to convert, which defaults to now; DATEP is whether to emit the date;
+   TIMEP is whether to emit the time, and SEP (default is space) is how to
+   separate the two."
   (multiple-value-bind
       (sec min hr day mon yr dow dstp tz)
       (decode-universal-time (if (or (null time) (eq time :now))
@@ -144,8 +144,18 @@ (defstruct (zone (:predicate zonep))
 ;;;--------------------------------------------------------------------------
 ;;; Zone defaults.  It is intended that scripts override these.
 
+#+ecl
+(cffi:defcfun gethostname :int
+  (name :pointer)
+  (len :uint))
+
 (defvar *default-zone-source*
-  (let ((hn (unix:unix-gethostname)))
+  (let ((hn #+cmu (unix:unix-gethostname)
+           #+clisp (unix:get-host-name)
+           #+ecl (cffi:with-foreign-pointer-as-string (buffer 256 len)
+                   (let ((rc (gethostname buffer len)))
+                     (unless (zerop rc)
+                       (error "gethostname(2) failed (rc = ~A)." rc))))))
     (and hn (concatenate 'string (canonify-hostname hn) ".")))
   "The default zone source: the current host's name.")
 
@@ -175,7 +185,7 @@ (defvar *default-mx-priority* 50
 
 (defun make-zone-serial (name)
   "Given a zone NAME, come up with a new serial number.  This will (very
-carefully) update a file ZONE.serial in the current directory."
+   carefully) update a file ZONE.serial in the current directory."
   (let* ((file (format nil "~(~A~).serial" name))
         (last (with-open-file (in file
                                   :direction :input
@@ -223,7 +233,7 @@   (defsubp nil)
 
 (defstruct (zone-subdomain (:conc-name zs-))
   "A subdomain.  Slightly weird.  Used internally by zone-process-records
-below, and shouldn't escape."
+   below, and shouldn't escape."
   name
   ttl
   records)
@@ -233,7 +243,7 @@ (defstruct (zone-subdomain (:conc-name zs-))
 
 (defun zone-process-records (rec ttl func)
   "Sort out the list of records in REC, calling FUNC for each one.  TTL is
-the default time-to-live for records which don't specify one."
+   the default time-to-live for records which don't specify one."
   (labels ((sift (rec ttl)
             (collecting (top sub)
               (loop
@@ -283,7 +293,7 @@ (defun zone-process-records (rec ttl func)
 
 (defun zone-parse-host (f zname)
   "Parse a host name F: if F ends in a dot then it's considered absolute;
-otherwise it's relative to ZNAME."
+   otherwise it's relative to ZNAME."
   (setf f (stringify f))
   (cond ((string= f "@") (stringify zname))
        ((and (plusp (length f))
@@ -293,7 +303,7 @@ (defun zone-parse-host (f zname)
                                         (stringify zname))))))
 (defun default-rev-zone (base bytes)
   "Return the default reverse-zone name for the given BASE address and number
-of fixed leading BYTES."
+   of fixed leading BYTES."
   (join-strings #\. (collecting ()
                      (loop for i from (- 3 bytes) downto 0
                            do (collect (ipaddr-byte base i)))
@@ -301,7 +311,7 @@ (defun default-rev-zone (base bytes)
 
 (defun zone-name-from-net (net &optional bytes)
   "Given a NET, and maybe the BYTES to use, convert to the appropriate
-subdomain of in-addr.arpa."
+   subdomain of in-addr.arpa."
   (let ((ipn (net-get-as-ipnet net)))
     (with-ipnet (net mask) ipn
       (unless bytes
@@ -339,54 +349,16 @@ (defun zone-net-from-name (name)
     (setf addr (ash addr (* 8 (- 4 n))))
     (make-ipnet addr (* 8 n))))
 
-(defun zone-reverse-records (records net list bytes dom)
-  "Construct a reverse zone given a forward zone's RECORDS list, the NET that
-the reverse zone is to serve, a LIST to collect the records into, how
-many BYTES of data need to end up in the zone, and the DOM-ain suffix."
-  (dolist (zr records)
-    (when (and (eq (zr-type zr) :a)
-              (not (zr-defsubp zr))
-              (ipaddr-networkp (zr-data zr) net))
-      (collect (make-zone-record
-               :name (string-downcase
-                      (join-strings
-                       #\.
-                       (collecting ()
-                         (dotimes (i bytes)
-                           (collect (logand #xff (ash (zr-data zr)
-                                                      (* -8 i)))))
-                         (collect dom))))
-               :type :ptr
-               :ttl (zr-ttl zr)
-               :data (zr-name zr))
-              list))))
-
-(defun zone-reverse (data name list)
-  "Process a :reverse record's DATA, for a domain called NAME, and add the
-records to the LIST."
-  (destructuring-bind
-      (net &key bytes zones)
-      (listify data)
-    (setf net (zone-parse-net net name))
-    (dolist (z (or (listify zones)
-                  (hash-table-keys *zones*)))
-      (zone-reverse-records (zone-records (zone-find z))
-                           net
-                           list
-                           (or bytes
-                               (ipnet-changeable-bytes (ipnet-mask net)))
-                           name))))
-
 (defun zone-parse-net (net name)
-  "Given a NET, and the NAME of a domain to guess from if NET is null,
-return the ipnet for the network."
+  "Given a NET, and the NAME of a domain to guess from if NET is null, return
+   the ipnet for the network."
   (if net
       (net-get-as-ipnet net)
       (zone-net-from-name name)))
 
 (defun zone-cidr-delg-default-name (ipn bytes)
   "Given a delegated net IPN and the parent's number of changing BYTES,
-return the default deletate zone prefix."
+   return the default deletate zone prefix."
   (with-ipnet (net mask) ipn
     (join-strings #\.
                  (reverse
@@ -397,7 +369,7 @@ (defun zone-cidr-delg-default-name (ipn bytes)
 
 (defun zone-cidr-delegation (data name ttl list)
   "Given :cidr-delegation info DATA, for a record called NAME and the current
-TTL, write lots of CNAME records to LIST."
+   TTL, write lots of CNAME records to LIST."
   (destructuring-bind
       (net &key bytes)
       (listify (car data))
@@ -412,7 +384,7 @@ (defun zone-cidr-delegation (data name ttl list)
        (unless (ipnet-subnetp net tnet)
          (error "~A is not a subnet of ~A."
                 (ipnet-pretty tnet)
-                (ipnet-pretty net)))            
+                (ipnet-pretty net)))
        (unless tdom
          (setf tdom
                (join-strings #\.
@@ -434,7 +406,7 @@ (defun zone-cidr-delegation (data name ttl list)
                      :ttl ttl
                      :data (join-strings #\. (list tail tdom)))
                     list)))))))
-                                                 
+
 ;;;--------------------------------------------------------------------------
 ;;; Zone form parsing.
 
@@ -444,8 +416,8 @@ (defun zone-parse-head (head)
      (NAME &key :source :admin :refresh :retry
                 :expire :min-ttl :ttl :serial)
 
-though a singleton NAME needn't be a list.  Returns the default TTL and an
-soa structure representing the zone head."
+   though a singleton NAME needn't be a list.  Returns the default TTL and an
+   soa structure representing the zone head."
   (destructuring-bind
       (zname
        &key
@@ -475,34 +447,35 @@ (defmacro defzoneparse (types (name data list
                                    (defsubp (gensym "DEFSUBP")))
                        &body body)
   "Define a new zone record type (or TYPES -- a list of synonyms is
-permitted).  The arguments are as follows:
+   permitted).  The arguments are as follows:
 
-NAME   The name of the record to be added.
+   NAME                The name of the record to be added.
 
-DATA   The content of the record to be added (a single object, unevaluated).
+   DATA                The content of the record to be added (a single object,
+               unevaluated).
 
-LIST   A function to add a record to the zone.  See below.
+   LIST                A function to add a record to the zone.  See below.
 
-ZNAME  The name of the zone being constructed.
+   ZNAME       The name of the zone being constructed.
 
-TTL    The TTL for this record.
+   TTL         The TTL for this record.
 
-DEFSUBP        Whether this is the default subdomain for this entry.
+   DEFSUBP     Whether this is the default subdomain for this entry.
 
-You get to choose your own names for these.  ZNAME, TTL and DEFSUBP are
-optional: you don't have to accept them if you're not interested.
+   You get to choose your own names for these.  ZNAME, TTL and DEFSUBP are
+   optional: you don't have to accept them if you're not interested.
 
-The LIST argument names a function to be bound in the body to add a new
-low-level record to the zone.  It has the prototype
+   The LIST argument names a function to be bound in the body to add a new
+   low-level record to the zone.  It has the prototype
 
-  (LIST &key :name :type :data :ttl :defsubp)
+     (LIST &key :name :type :data :ttl :defsubp)
 
-Except for defsubp, these default to the above arguments (even if you didn't
-accept the arguments)."
+   Except for defsubp, these default to the above arguments (even if you
+   didn't accept the arguments)."
   (setf types (listify types))
   (let* ((type (car types))
         (func (intern (format nil "ZONE-PARSE/~:@(~A~)" type))))
-    (multiple-value-bind (doc decls body) (parse-body body)
+    (with-parsed-body (body decls doc) body
       (with-gensyms (col tname ttype tttl tdata tdefsubp i)
        `(progn
           (dolist (,i ',types)
@@ -551,18 +524,18 @@ (defun zone-parse-records (zone records)
                            (zr-defsubp zr)))))
          (zone-process-records records
                                (zone-default-ttl zone)
-                               #'parse-record ))
+                               #'parse-record))
       (setf (zone-records zone) (nconc (zone-records zone) rec)))))
 
 (defun zone-parse (zf)
   "Parse a ZONE form.  The syntax of a zone form is as follows:
 
-ZONE-FORM:
-  ZONE-HEAD ZONE-RECORD*
+   ZONE-FORM:
+     ZONE-HEAD ZONE-RECORD*
 
-ZONE-RECORD:
-  ((NAME*) ZONE-RECORD*)
-| SYM ARGS"
+   ZONE-RECORD:
+     ((NAME*) ZONE-RECORD*)
+   | SYM ARGS"
   (multiple-value-bind (zname ttl soa) (zone-parse-head (car zf))
     (let ((zone (make-zone :name zname
                           :default-ttl ttl
@@ -573,7 +546,7 @@ (defun zone-parse (zf)
 
 (defun zone-create (zf)
   "Zone construction function.  Given a zone form ZF, construct the zone and
-add it to the table."
+   add it to the table."
   (let* ((zone (zone-parse zf))
         (name (zone-name zone)))
     (setf (zone-find name) zone)
@@ -648,7 +621,7 @@ (defzoneparse :net (name data rec)
       (rec :name (zone-parse-host "broadcast" name)
           :type :a
           :data (ipnet-broadcast n)))))
-  
+
 (defzoneparse (:rev :reverse) (name data rec)
   ":reverse ((NET :bytes BYTES) ZONE*)"
   (setf data (listify data))
@@ -692,7 +665,7 @@ (defzoneparse (:cidr-delegation :cidr) (name data rec)
        (unless (ipnet-subnetp net tnet)
          (error "~A is not a subnet of ~A."
                 (ipnet-pretty tnet)
-                (ipnet-pretty net)))            
+                (ipnet-pretty net)))
        (unless tdom
          (with-ipnet (net mask) tnet
            (setf tdom
@@ -753,8 +726,8 @@ (defun zone-write (zone &optional (stream *standard-output*))
 ;;; Zone file `~(~A~)'
 ;;;   (generated ~A)
 
-$ORIGIN ~@0*~(~A.~)
-$TTL ~@2*~D~2%"
+$ORIGIN ~0@*~(~A.~)
+$TTL ~2@*~D~2%"
            (zone-name zone)
            (iso-date :now :datep t :timep t)
            (zone-default-ttl zone))
@@ -795,7 +768,7 @@ (defun zone-write (zone &optional (stream *standard-output*))
 
 (defun zone-save (zones)
   "Write the named ZONES to files.  If no zones are given, write all the
-zones."
+   zones."
   (unless zones
     (setf zones (hash-table-keys *zones*)))
   (safely (safe)