1 /* $NetBSD: zfparse.c,v 1.1.1.1 2015/07/08 15:37:48 christos Exp $ */
3 /*****************************************************************
5 ** @(#) zfparse.c -- A zone file parser
7 ** Copyright (c) Jan 2010 - Jan 2010, Holger Zuleger HZnet. All rights reserved.
9 ** This software is open source.
11 ** Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions
15 ** Redistributions of source code must retain the above copyright notice,
16 ** this list of conditions and the following disclaimer.
18 ** Redistributions in binary form must reproduce the above copyright notice,
19 ** this list of conditions and the following disclaimer in the documentation
20 ** and/or other materials provided with the distribution.
22 ** Neither the name of Holger Zuleger HZnet nor the names of its contributors may
23 ** be used to endorse or promote products derived from this software without
24 ** specific prior written permission.
26 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 ** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
30 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 ** POSSIBILITY OF SUCH DAMAGE.
38 *****************************************************************/
42 # include <unistd.h> /* for link(), unlink() */
48 # include "config_zkt.h"
58 extern const char *progname
;
60 /*****************************************************************
61 ** is_multiline_rr (const char *s)
62 *****************************************************************/
63 static const char *is_multiline_rr (int *multi_line_rr
, const char *p
)
65 while ( *p
&& *p
!= ';' )
70 while ( *p
&& *p
!= '\"' );
81 /*****************************************************************
82 ** skipws (const char *s)
83 *****************************************************************/
84 static const char *skipws (const char *s
)
86 while ( *s
&& (*s
== ' ' || *s
== '\t' || *s
== '\n') )
91 /*****************************************************************
92 ** skiplabel (const char *s)
93 *****************************************************************/
94 static const char *skiplabel (const char *s
)
96 while ( *s
&& *s
!= ';' && *s
!= ' ' && *s
!= '\t' && *s
!= '\n' )
101 /*****************************************************************
103 *****************************************************************/
104 static void setminmax (long *pmin
, long val
, long *pmax
)
112 /*****************************************************************
114 *****************************************************************/
115 static long get_ttl (const char *s
)
121 sscanf (s
, "%ld%c", &lval
, &quantity
);
122 quantity
= tolower (quantity
);
123 if ( quantity
== 'm' )
125 else if ( quantity
== 'h' )
127 else if ( quantity
== 'd' )
129 else if ( quantity
== 'w' )
131 else if ( quantity
== 'y' )
137 /*****************************************************************
139 *****************************************************************/
140 int addkeydb (const char *file
, const char *keydbfile
)
144 if ( (fp
= fopen (file
, "a")) == NULL
)
148 fprintf (fp
, "$INCLUDE %s\t; this is the database of public DNSKEY RR\n", keydbfile
);
155 /*****************************************************************
157 ** parse the BIND zone file 'file' and store the minimum and
158 ** maximum ttl value in the corresponding parameter.
159 ** if keydbfile is set, check if this file is already include.
160 ** if inclfiles is not NULL store a list of included files names
162 ** return 0 if keydbfile is not included
163 ** return 1 if keydbfile is included
164 ** return -1 on error
165 *****************************************************************/
166 int parsezonefile (const char *file
, long *pminttl
, long *pmaxttl
, const char *keydbfile
, char *inclfiles
, size_t *plen
)
177 assert (file
!= NULL
);
178 assert (pminttl
!= NULL
);
179 assert (pmaxttl
!= NULL
);
181 dbg_val4 ("parsezonefile (\"%s\", %ld, %ld, \"%s\")\n", file
, *pminttl
, *pmaxttl
, keydbfile
);
183 if ( (infp
= fopen (file
, "r")) == NULL
)
185 error ("parsezonefile: couldn't open file \"%s\" for input\n", file
);
192 while ( fgets (buf
, sizeof buf
, infp
) != NULL
)
195 if ( buf
[len
-1] != '\n' ) /* line too long ? */
196 fprintf (stderr
, "line too long\n");
200 if ( multi_line_rr
) /* skip line if it's part of a multiline rr */
202 is_multiline_rr (&multi_line_rr
, p
);
206 if ( *p
== '$' ) /* special directive ? */
208 if ( strncmp (p
+1, "TTL", 3) == 0 ) /* $TTL ? */
211 dbg_val3 ("%s:%d:ttl %ld\n", file
, lnr
, ttl
);
212 setminmax (pminttl
, ttl
, pmaxttl
);
214 else if ( strncmp (p
+1, "INCLUDE", 7) == 0 ) /* $INCLUDE ? */
218 sscanf (p
+9, "%30s", fname
);
219 dbg_val ("$INCLUDE directive for file \"%s\" found\n", fname
);
220 if ( strcmp (fname
, keydbfile
) == 0 )
224 if ( inclfiles
&& plen
)
226 len
= snprintf (inclfiles
, *plen
, ",%s", fname
);
227 if ( *plen
<= len
) /* no space left in include file string */
228 return keydbfilefound
;
232 int ret
= parsezonefile (fname
, pminttl
, pmaxttl
, keydbfile
, inclfiles
, plen
);
233 if ( ret
) /* keydb found or read error ? */
234 keydbfilefound
= ret
;
238 else if ( !isspace (*p
) ) /* label ? */
242 if ( *p
== ';' ) /* skip line if it's a comment line */
245 /* skip class (hesiod is not supported now) */
246 if ( (toupper (*p
) == 'I' && toupper (p
[1]) == 'N') ||
247 (toupper (*p
) == 'C' && toupper (p
[1]) == 'H') )
251 if ( isdigit (*p
) ) /* ttl ? */
254 dbg_val3 ("%s:%d:ttl %ld\n", file
, lnr
, ttl
);
255 setminmax (pminttl
, ttl
, pmaxttl
);
258 /* check the rest of the line if it's the beginning of a multi_line_rr */
259 is_multiline_rr (&multi_line_rr
, p
);
265 dbg_val5 ("parsezonefile (\"%s\", %ld, %ld, \"%s\") ==> %d\n",
266 file
, *pminttl
, *pmaxttl
, keydbfile
, keydbfilefound
);
267 return keydbfilefound
;
272 const char *progname
;
273 int main (int argc
, char *argv
[])
282 dnskeydb
= "dnskey.db";
286 keydbfound
= parsezonefile (argv
[1], &minttl
, &maxttl
, dnskeydb
);
287 if ( keydbfound
< 0 )
288 error ("can't parse zone file %s\n", argv
[1]);
290 if ( dnskeydb
&& !keydbfound
)
292 printf ("$INCLUDE %s directive added \n", dnskeydb
);
293 addkeydb (argv
[1], dnskeydb
);
296 printf ("minttl = %ld\n", minttl
);
297 printf ("maxttl = %ld\n", maxttl
);