1 /*****************************************************************
3 ** @(#) ncparse.c -- A very simple named.conf parser
5 ** Copyright (c) Apr 2005 - Nov 2007, Holger Zuleger HZnet. All rights reserved.
7 ** This software is open source.
9 ** Redistribution and use in source and binary forms, with or without
10 ** modification, are permitted provided that the following conditions
13 ** Redistributions of source code must retain the above copyright notice,
14 ** this list of conditions and the following disclaimer.
16 ** Redistributions in binary form must reproduce the above copyright notice,
17 ** this list of conditions and the following disclaimer in the documentation
18 ** and/or other materials provided with the distribution.
20 ** Neither the name of Holger Zuleger HZnet nor the names of its contributors may
21 ** be used to endorse or promote products derived from this software without
22 ** specific prior written permission.
24 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 ** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27 ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
28 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 ** POSSIBILITY OF SUCH DAMAGE.
36 *****************************************************************/
48 # define TOK_STRING 257
50 # define TOK_INCLUDE 259
54 # define TOK_MASTER 262
55 # define TOK_SLAVE 263
58 # define TOK_FORWARD 266
59 # define TOK_DELEGATION 267
64 # define TOK_UNKNOWN 511
66 /* list of "named.conf" keywords we are interested in */
67 static struct KeyWords {
71 { "STRING", TOK_STRING },
72 { "include", TOK_INCLUDE },
73 { "directory", TOK_DIR },
76 #if 0 /* we don't need the type keyword; master, slave etc. is sufficient */
79 { "master", TOK_MASTER },
80 { "slave", TOK_SLAVE },
83 { "forward", TOK_FORWARD },
84 { "delegation-only", TOK_DELEGATION },
86 { NULL, TOK_UNKNOWN },
90 static const char *tok2str (int tok)
95 while ( kw[i].name && kw[i].tok != tok )
102 static int searchkw (const char *keyword)
106 dbg_val ("ncparse: searchkw (%s)\n", keyword);
108 while ( kw[i].name && strcmp (kw[i].name, keyword) != 0 )
114 static int gettok (FILE *fp, char *val, size_t valsize)
124 while ( (c = getc (fp)) != EOF && isspace (c) )
127 if ( c == '#' ) /* single line comment ? */
129 while ( (c = getc (fp)) != EOF && c != '\n' )
137 if ( c == '{' || c == '}' || c == ';' )
140 if ( c == '/' ) /* begin of C comment ? */
142 if ( (c = getc (fp)) == '*' ) /* yes! */
144 lastc = EOF; /* read until end of c comment */
145 while ( (c = getc (fp)) != EOF && !(lastc == '*' && c == '/') )
148 else if ( c == '/' ) /* is it a C single line comment ? */
150 while ( (c = getc (fp)) != EOF && c != '\n' )
161 bufend = val + valsize - 1;
162 while ( (c = getc (fp)) != EOF && p < bufend && c != '\"' )
165 /* if string buffer is too small, eat up rest of string */
166 while ( c != EOF && c != '\"' )
173 bufend = buf + sizeof (buf) - 1;
176 while ( (c = getc (fp)) != EOF && p < bufend && (isalpha (c) || c == '-') );
180 if ( (c = searchkw (buf)) != TOK_UNKNOWN )
182 } while ( c != EOF );
187 /*****************************************************************
189 ** parse_namedconf (const char *filename, chroot_dir, dir, dirsize, int (*func) ())
191 ** Very dumb named.conf parser.
192 ** - In a zone declaration the _first_ keyword MUST be "type"
193 ** - For every master zone "func (directory, zone, filename)" will be called
195 *****************************************************************/
196 int parse_namedconf (const char *filename, const char *chroot_dir, char *dir, size_t dirsize, int (*func) ())
201 #if 1 /* this is potentialy too small for key data, but we don't need the keys... */
208 char zonefile[255+1];
210 dbg_val ("parse_namedconf: parsing file \"%s\" \n", filename);
212 assert (filename != NULL);
213 assert (dir != NULL && dirsize != 0);
214 assert (func != NULL);
217 if ( (fp = fopen (filename, "r")) == NULL )
220 while ( (tok = gettok (fp, strval, sizeof strval)) != EOF )
222 if ( tok > 0 && tok < 256 )
224 error ("parse_namedconf: token found with value %-10d: %c\n", tok, tok);
225 lg_mesg (LG_ERROR, "parse_namedconf: token found with value %-10d: %c", tok, tok);
227 else if ( tok == TOK_DIR )
229 if ( gettok (fp, strval, sizeof (strval)) == TOK_STRING )
231 dbg_val2 ("parse_namedconf: directory found \"%s\" (dir is %s)\n",
233 if ( *strval != '/' && *dir )
234 snprintf (path, sizeof (path), "%s/%s", dir, strval);
236 snprintf (path, sizeof (path), "%s", strval);
238 /* prepend chroot directory (do it only once) */
239 if ( chroot_dir && *chroot_dir )
241 snprintf (dir, dirsize, "%s%s%s", chroot_dir, *path == '/' ? "": "/", path);
245 snprintf (dir, dirsize, "%s", path);
246 dbg_val ("parse_namedconf: new dir \"%s\" \n", dir);
249 else if ( tok == TOK_INCLUDE )
251 if ( gettok (fp, strval, sizeof (strval)) == TOK_STRING )
253 if ( *strval != '/' && *dir )
254 snprintf (path, sizeof (path), "%s/%s", dir, strval);
256 snprintf (path, sizeof (path), "%s", strval);
257 if ( !parse_namedconf (path, chroot_dir, dir, dirsize, func) )
262 error ("parse_namedconf: need a filename after \"include\"!\n");
263 lg_mesg (LG_ERROR, "parse_namedconf: need a filename after \"include\"!");
266 else if ( tok == TOK_VIEW )
268 if ( gettok (fp, strval, sizeof (strval)) != TOK_STRING )
270 snprintf (view, sizeof view, "%s", strval); /* store the name of the view */
272 else if ( tok == TOK_ZONE )
274 if ( gettok (fp, strval, sizeof (strval)) != TOK_STRING )
276 snprintf (zone, sizeof zone, "%s", strval); /* store the name of the zone */
278 if ( gettok (fp, strval, sizeof (strval)) != TOK_MASTER )
280 if ( gettok (fp, strval, sizeof (strval)) != TOK_FILE )
282 if ( gettok (fp, strval, sizeof (strval)) != TOK_STRING )
284 snprintf (zonefile, sizeof zonefile, "%s", strval); /* this is the filename */
286 dbg_val4 ("dir %s view %s zone %s file %s\n", dir, view, zone, zonefile);
287 (*func) (dir, view, zone, zonefile);
290 dbg_val3 ("%-10s(%d): %s\n", tok2str(tok), tok, strval);
298 int printzone (const char *dir, const char *view, const char *zone, const char *file)
300 printf ("printzone ");
301 printf ("view \"%s\" " , view);
302 printf ("zone \"%s\" " , zone);
305 printf ("%s/", dir, file);
313 main (int argc, char *argv[])
315 char directory[255+1];
321 parse_namedconf ("/var/named/named.conf", NULL, directory, sizeof (directory), printzone);
323 parse_namedconf (argv[1], NULL, directory, sizeof (directory), printzone);