1 %{
2 /*        $NetBSD: nsparser.y,v 1.12 2012/03/20 17:44:18 matt Exp $   */
3 
4 /*-
5  * Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Luke Mewburn.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include <sys/cdefs.h>
34 #if defined(LIBC_SCCS) && !defined(lint)
35 __RCSID("$NetBSD: nsparser.y,v 1.12 2012/03/20 17:44:18 matt Exp $");
36 #endif /* LIBC_SCCS and not lint */
37 
38 #include "namespace.h"
39 
40 #include <assert.h>
41 #define _NS_PRIVATE
42 #include <nsswitch.h>
43 #include <stdio.h>
44 #include <string.h>
45 #include <syslog.h>
46 
47 
48 static    void      _nsaddsrctomap(const char *);
49 
50 static    ns_dbt              curdbt;
51 static    ns_src              cursrc;
52 
53 extern char *       _nsyytext;
54 extern int _nsyylineno;
55 %}
56 
57 %union {
58           char *str;
59           int   mapval;
60 }
61 
62 %token    NL
63 %token    SUCCESS UNAVAIL NOTFOUND TRYAGAIN
64 %token    RETURN CONTINUE
65 %token    <str> STRING
66 
67 %type     <mapval> Status Action
68 
69 %%
70 
71 File
72           :         /* empty */
73           | Lines
74           ;
75 
76 Lines
77           : Entry
78           | Lines Entry
79           ;
80 
81 Entry
82           : NL
83           | Database ':' NL
84           | Database ':' Srclist NL
85                     {
86                               int lineno;
87 
88                               lineno = _nsyylineno - (*_nsyytext == '\n' ? 1 : 0);
89                               if (_nsdbtput(&curdbt) == -1)
90                                         syslog(LOG_WARNING,
91                                             "libc nsdispatch: %s line %d: %s",
92                                             _PATH_NS_CONF, lineno,
93                                             "error adding entry");
94                     }
95           | error NL
96                     {
97                               yyerrok;
98                     }
99           ;
100 
101 Database
102           : STRING
103                     {
104                               curdbt.name = yylval.str;
105                               curdbt.srclist = NULL;
106                               curdbt.srclistsize = 0;
107                     }
108           ;
109 
110 Srclist
111           : Item
112           | Srclist Item
113           ;
114 
115 Item
116           : STRING
117                     {
118                               cursrc.flags = NS_SUCCESS;
119                               _nsaddsrctomap($1);
120                     }
121           | STRING '[' { cursrc.flags = NS_SUCCESS; } Criteria ']'
122                     {
123                               _nsaddsrctomap($1);
124                     }
125           ;
126 
127 Criteria
128           : Criterion
129           | Criteria Criterion
130           ;
131 
132 Criterion
133           : Status '=' Action
134                     {
135                               if ($3)             /* if action == RETURN set RETURN bit */
136                                         cursrc.flags |= $1;
137                               else                /* else unset it */
138                                         cursrc.flags &= ~$1;
139                     }
140           ;
141 
142 Status
143           : SUCCESS { $$ = NS_SUCCESS; }
144           | UNAVAIL { $$ = NS_UNAVAIL; }
145           | NOTFOUND          { $$ = NS_NOTFOUND; }
146           | TRYAGAIN          { $$ = NS_TRYAGAIN; }
147           ;
148 
149 Action
150           : RETURN  { $$ = 1L; }
151           | CONTINUE          { $$ = 0L; }
152           ;
153 
154 %%
155 
156 static void
157 _nsaddsrctomap(const char *elem)
158 {
159           unsigned int        i;
160           int                 lineno;
161 
162           _DIAGASSERT(elem != NULL);
163 
164           lineno = _nsyylineno - (*_nsyytext == '\n' ? 1 : 0);
165           if (curdbt.srclistsize > 0) {
166                     if ((strcasecmp(elem, NSSRC_COMPAT) == 0) ||
167                         (strcasecmp(curdbt.srclist[0].name, NSSRC_COMPAT) == 0)) {
168                               syslog(LOG_WARNING,
169                                   "libc nsdispatch: %s line %d: %s",
170                                   _PATH_NS_CONF, lineno,
171                                   "'compat' used with other sources");
172                               return;
173                     }
174           }
175           for (i = 0; i < curdbt.srclistsize; i++) {
176                     if (strcasecmp(curdbt.srclist[i].name, elem) == 0) {
177                               syslog(LOG_WARNING,
178                                   "libc nsdispatch: %s line %d: %s '%s'",
179                                   _PATH_NS_CONF, lineno,
180                                   "duplicate source", elem);
181                               return;
182                     }
183           }
184           cursrc.name = elem;
185           if (_nsdbtaddsrc(&curdbt, &cursrc) == -1) {
186                     syslog(LOG_WARNING,
187                         "libc nsdispatch: %s line %d: %s '%s'",
188                         _PATH_NS_CONF, lineno,
189                         "error adding", elem);
190           }
191 }
192