etc/services - sync with NetBSD-8
[minix.git] / external / bsd / bind / dist / contrib / zkt-1.1.3 / ncparse.c
blobe569ec7020cb3237eb167874128d841a14f0d3f5
1 /* $NetBSD: ncparse.c,v 1.1.1.1 2015/07/08 15:37:48 christos Exp $ */
3 /*****************************************************************
4 **
5 ** @(#) ncparse.c -- A very simple named.conf parser
6 **
7 ** Copyright (c) Apr 2005 - Nov 2007, Holger Zuleger HZnet. All rights reserved.
8 **
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
13 ** are met:
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 *****************************************************************/
39 # include <stdio.h>
40 # include <string.h>
41 # include <ctype.h>
42 # include <assert.h>
43 # include "debug.h"
44 # include "misc.h"
45 # include "log.h"
46 #define extern
47 # include "ncparse.h"
48 #undef extern
50 # define TOK_STRING 257
51 # define TOK_DIR 258
52 # define TOK_INCLUDE 259
54 # define TOK_ZONE 260
55 # define TOK_TYPE 261
56 # define TOK_MASTER 262
57 # define TOK_SLAVE 263
58 # define TOK_STUB 264
59 # define TOK_HINT 265
60 # define TOK_FORWARD 266
61 # define TOK_DELEGATION 267
62 # define TOK_VIEW 268
64 # define TOK_FILE 270
66 # define TOK_UNKNOWN 511
68 /* list of "named.conf" keywords we are interested in */
69 static struct KeyWords {
70 char *name;
71 int tok;
72 } kw[] = {
73 { "STRING", TOK_STRING },
74 { "include", TOK_INCLUDE },
75 { "directory", TOK_DIR },
76 { "file", TOK_FILE },
77 { "zone", TOK_ZONE },
78 #if 0 /* we don't need the type keyword; master, slave etc. is sufficient */
79 { "type", TOK_TYPE },
80 #endif
81 { "master", TOK_MASTER },
82 { "slave", TOK_SLAVE },
83 { "stub", TOK_STUB },
84 { "hint", TOK_HINT },
85 { "forward", TOK_FORWARD },
86 { "delegation-only", TOK_DELEGATION },
87 { "view", TOK_VIEW },
88 { NULL, TOK_UNKNOWN },
91 #ifdef DBG
92 static const char *tok2str (int tok)
94 int i;
96 i = 0;
97 while ( kw[i].name && kw[i].tok != tok )
98 i++;
100 return kw[i].name;
102 #endif
104 static int searchkw (const char *keyword)
106 int i;
108 dbg_val ("ncparse: searchkw (%s)\n", keyword);
109 i = 0;
110 while ( kw[i].name && strcmp (kw[i].name, keyword) != 0 )
111 i++;
113 return kw[i].tok;
116 static int gettok (FILE *fp, char *val, size_t valsize)
118 int lastc;
119 int c;
120 char buf[255+1];
121 char *p;
122 char *bufend;
124 *val = '\0';
125 do {
126 while ( (c = getc (fp)) != EOF && isspace (c) )
129 if ( c == '#' ) /* single line comment ? */
131 while ( (c = getc (fp)) != EOF && c != '\n' )
133 continue;
136 if ( c == EOF )
137 return EOF;
139 if ( c == '{' || c == '}' || c == ';' )
140 continue;
142 if ( c == '/' ) /* begin of C comment ? */
144 if ( (c = getc (fp)) == '*' ) /* yes! */
146 lastc = EOF; /* read until end of c comment */
147 while ( (c = getc (fp)) != EOF && !(lastc == '*' && c == '/') )
148 lastc = c;
150 else if ( c == '/' ) /* is it a C single line comment ? */
152 while ( (c = getc (fp)) != EOF && c != '\n' )
155 else /* no ! */
156 ungetc (c, fp);
157 continue;
160 if ( c == '\"' )
162 p = val;
163 bufend = val + valsize - 1;
164 while ( (c = getc (fp)) != EOF && p < bufend && c != '\"' )
165 *p++ = c;
166 *p = '\0';
167 /* if string buffer is too small, eat up rest of string */
168 while ( c != EOF && c != '\"' )
169 c = getc (fp);
171 return TOK_STRING;
174 p = buf;
175 bufend = buf + sizeof (buf) - 1;
177 *p++ = tolower (c);
178 while ( (c = getc (fp)) != EOF && p < bufend && (isalpha (c) || c == '-') );
179 *p = '\0';
180 ungetc (c, fp);
182 if ( (c = searchkw (buf)) != TOK_UNKNOWN )
183 return c;
184 } while ( c != EOF );
186 return EOF;
189 /*****************************************************************
191 ** parse_namedconf (const char *filename, chroot_dir, dir, dirsize, int (*func) ())
193 ** Very dumb named.conf parser.
194 ** - In a zone declaration the _first_ keyword MUST be "type"
195 ** - For every master zone "func (directory, zone, filename)" will be called
197 *****************************************************************/
198 int parse_namedconf (const char *filename, const char *chroot_dir, char *dir, size_t dirsize, int (*func) ())
200 FILE *fp;
201 int tok;
202 char path[511+1];
203 #if 1 /* this is potentialy too small for key data, but we don't need the keys... */
204 char strval[255+1];
205 #else
206 char strval[4095+1];
207 #endif
208 char view[255+1];
209 char zone[255+1];
210 char zonefile[255+1];
212 dbg_val ("parse_namedconf: parsing file \"%s\" \n", filename);
214 assert (filename != NULL);
215 assert (dir != NULL && dirsize != 0);
216 assert (func != NULL);
218 view[0] = '\0';
219 if ( (fp = fopen (filename, "r")) == NULL )
220 return 0;
222 while ( (tok = gettok (fp, strval, sizeof strval)) != EOF )
224 if ( tok > 0 && tok < 256 )
226 error ("parse_namedconf: token found with value %-10d: %c\n", tok, tok);
227 lg_mesg (LG_ERROR, "parse_namedconf: token found with value %-10d: %c", tok, tok);
229 else if ( tok == TOK_DIR )
231 if ( gettok (fp, strval, sizeof (strval)) == TOK_STRING )
233 dbg_val2 ("parse_namedconf: directory found \"%s\" (dir is %s)\n",
234 strval, dir);
235 if ( *strval != '/' && *dir )
236 snprintf (path, sizeof (path), "%s/%s", dir, strval);
237 else
238 snprintf (path, sizeof (path), "%s", strval);
240 /* prepend chroot directory (do it only once) */
241 if ( chroot_dir && *chroot_dir )
243 snprintf (dir, dirsize, "%s%s%s", chroot_dir, *path == '/' ? "": "/", path);
244 chroot_dir = NULL;
246 else
247 snprintf (dir, dirsize, "%s", path);
248 dbg_val ("parse_namedconf: new dir \"%s\" \n", dir);
251 else if ( tok == TOK_INCLUDE )
253 if ( gettok (fp, strval, sizeof (strval)) == TOK_STRING )
255 if ( *strval != '/' && *dir )
256 snprintf (path, sizeof (path), "%s/%s", dir, strval);
257 else
258 snprintf (path, sizeof (path), "%s", strval);
259 if ( !parse_namedconf (path, chroot_dir, dir, dirsize, func) )
260 return 0;
262 else
264 error ("parse_namedconf: need a filename after \"include\"!\n");
265 lg_mesg (LG_ERROR, "parse_namedconf: need a filename after \"include\"!");
268 else if ( tok == TOK_VIEW )
270 if ( gettok (fp, strval, sizeof (strval)) != TOK_STRING )
271 continue;
272 snprintf (view, sizeof view, "%s", strval); /* store the name of the view */
274 else if ( tok == TOK_ZONE )
276 if ( gettok (fp, strval, sizeof (strval)) != TOK_STRING )
277 continue;
278 snprintf (zone, sizeof zone, "%s", strval); /* store the name of the zone */
280 if ( gettok (fp, strval, sizeof (strval)) != TOK_MASTER )
281 continue;
282 if ( gettok (fp, strval, sizeof (strval)) != TOK_FILE )
283 continue;
284 if ( gettok (fp, strval, sizeof (strval)) != TOK_STRING )
285 continue;
286 snprintf (zonefile, sizeof zonefile, "%s", strval); /* this is the filename */
288 dbg_val4 ("dir %s view %s zone %s file %s\n", dir, view, zone, zonefile);
289 (*func) (dir, view, zone, zonefile);
291 else
292 dbg_val3 ("%-10s(%d): %s\n", tok2str(tok), tok, strval);
294 fclose (fp);
296 return 1;
299 #ifdef TEST_NCPARSE
300 int printzone (const char *dir, const char *view, const char *zone, const char *file)
302 printf ("printzone ");
303 printf ("view \"%s\" " , view);
304 printf ("zone \"%s\" " , zone);
305 printf ("file ");
306 if ( dir && *dir )
307 printf ("%s/", dir, file);
308 printf ("%s", file);
309 putchar ('\n');
310 return 1;
313 char *progname;
315 main (int argc, char *argv[])
317 char directory[255+1];
319 progname = argv[0];
321 directory[0] = '\0';
322 if ( --argc == 0 )
323 parse_namedconf ("/var/named/named.conf", NULL, directory, sizeof (directory), printzone);
324 else
325 parse_namedconf (argv[1], NULL, directory, sizeof (directory), printzone);
327 #endif