1 /*
2  * Copyright (c) 2013
3  *      Inferno Nettverk A/S, Norway.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. The above copyright notice, this list of conditions and the following
9  *    disclaimer must appear in all copies of the software, derivative works
10  *    or modified versions, and any portions thereof, aswell as in all
11  *    supporting documentation.
12  * 2. All advertising materials mentioning features or use of this software
13  *    must display the following acknowledgement:
14  *      This product includes software developed by
15  *      Inferno Nettverk A/S, Norway.
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * Inferno Nettverk A/S requests users of this software to return to
31  *
32  *  Software Distribution Coordinator  or  sdc@inet.no
33  *  Inferno Nettverk A/S
34  *  Oslo Research Park
35  *  Gaustadall�en 21
36  *  NO-0349 Oslo
37  *  Norway
38  *
39  * any improvements or extensions that they make and grant Inferno Nettverk A/S
40  * the rights to redistribute these changes.
41  *
42  */
43 
44 #include "common.h"
45 
46 static const char rcsid[] =
47 "$Id: parse_util.c,v 1.7 2013/10/25 12:55:01 karls Exp $";
48 
49 extern unsigned char parsingconfig;
50 extern char          *atype;
51 extern int           yylineno;
52 extern char          *yytext;
53 
54 static char *
55 getparsingerror(char *buf, const size_t buflen);
56 /*
57  * Writes the text related to the current parsing error to the string
58  * "buf", which of size buflen.
59  */
60 
61 
62 void
yyerror(const char * fmt,...)63 yyerror(const char *fmt, ...)
64 {
65    va_list ap;
66    char buf[2048];
67    size_t bufused;
68 
69    if (parsingconfig) {
70       char prefix[512];
71 
72       bufused = snprintf(buf, sizeof(buf), "%s: ",
73                          getparsingerror(prefix, sizeof(prefix)));
74    }
75    else
76       bufused = 0;
77 
78    va_start(ap, fmt);
79    vsnprintf(&buf[bufused], sizeof(buf) - bufused, fmt, ap);
80    va_end(ap);
81 
82    if (errno == 0)
83       serrx("%s.  Please see the %s manual for more information", buf, PRODUCT);
84    else
85       serrx("%s: %s.  Please see the %s manual for more information",
86             buf, strerror(errno), PRODUCT);
87 }
88 
89 void
yyerrorx(const char * fmt,...)90 yyerrorx(const char *fmt, ...)
91 {
92    va_list ap;
93    char buf[2048];
94    size_t bufused;
95 
96    if (parsingconfig) {
97       char prefix[512];
98 
99       bufused = snprintf(buf, sizeof(buf), "%s: ",
100                          getparsingerror(prefix, sizeof(prefix)));
101    }
102    else
103       bufused = 0;
104 
105    va_start(ap, fmt);
106    vsnprintf(&buf[bufused], sizeof(buf) - bufused, fmt, ap);
107    va_end(ap);
108 
109    serrx("%s.  Please see the %s manual for more information", buf, PRODUCT);
110 }
111 
112 void
yywarn(const char * fmt,...)113 yywarn(const char *fmt, ...)
114 {
115    va_list ap;
116    char buf[2048];
117    size_t bufused;
118 
119    if (parsingconfig) {
120       char prefix[512];
121 
122       bufused = snprintf(buf, sizeof(buf), "%s: ",
123                          getparsingerror(prefix, sizeof(prefix)));
124    }
125    else
126       bufused = 0;
127 
128    va_start(ap, fmt);
129    vsnprintf(&buf[bufused], sizeof(buf) - bufused, fmt, ap);
130    va_end(ap);
131 
132    if (errno == 0)
133       swarnx("%s.  Please see the %s manual for more information",
134              buf, PRODUCT);
135    else
136       swarnx("%s.  %s.  Please see the %s manual for more information",
137              buf, strerror(errno), PRODUCT);
138 }
139 
140 void
yywarnx(const char * fmt,...)141 yywarnx(const char *fmt, ...)
142 {
143    va_list ap;
144    char buf[2048];
145    size_t bufused;
146 
147    if (parsingconfig) {
148       char prefix[512];
149 
150       bufused = snprintf(buf, sizeof(buf), "%s: ",
151                          getparsingerror(prefix, sizeof(prefix)));
152    }
153    else
154       bufused = 0;
155 
156    va_start(ap, fmt);
157    vsnprintf(&buf[bufused], sizeof(buf) - bufused, fmt, ap);
158    va_end(ap);
159 
160    swarnx("%s.  Please see the %s manual for more information", buf, PRODUCT);
161 }
162 
163 void
yylog(const int loglevel,const char * fmt,...)164 yylog(const int loglevel, const char *fmt, ...)
165 {
166    va_list ap;
167    char buf[2048];
168    size_t bufused;
169 
170    if (parsingconfig) {
171       char prefix[512];
172 
173       bufused = snprintf(buf, sizeof(buf), "%s: ",
174                          getparsingerror(prefix, sizeof(prefix)));
175    }
176    else
177       bufused = 0;
178 
179    va_start(ap, fmt);
180    vsnprintf(&buf[bufused], sizeof(buf) - bufused, fmt, ap);
181    va_end(ap);
182 
183    slog(loglevel, "%s.  Please see the %s manual for more information",
184         buf, PRODUCT);
185 }
186 
187 
188 void
yyerrorx_hasnetmask(void)189 yyerrorx_hasnetmask(void)
190 {
191 
192    yyerrorx("A netmask has been specified for this %s, but no netmask "
193             "should be specified in this context",
194             atype2string(*atype));
195 }
196 
197 void
yyerrorx_nonetmask(void)198 yyerrorx_nonetmask(void)
199 {
200 
201    yyerrorx("No netmask has been specified for this %s, but a netmask "
202             "must be specified in this context.  "
203             "You can specify a netmask using the standard "
204             "\"/ <netmask bits>\" syntax",
205             atype2string(*atype));
206 }
207 
208 void
yyerrorx_nolib(library)209 yyerrorx_nolib(library)
210    const char *library;
211 {
212 
213    yyerrorx("in order to set the given keyword/value, %s must be linked "
214             "with an external %s library at compiletime.  When %s was "
215             "compiled, no such linking was done, perhaps due to no "
216             "usable %s library being installed on the system at the time.  "
217             "If a %s library has since been installed on this system, "
218             "please rerun ./configure in %s's source directory, recompile "
219             "and reinstall %s",
220             PRODUCT,
221             library,
222             PRODUCT,
223             library,
224             library,
225             PRODUCT,
226             PRODUCT);
227 }
228 
229 void
yywarnx_deprecated(oldkeyword,newkeyword)230 yywarnx_deprecated(oldkeyword, newkeyword)
231    const char *oldkeyword;
232    const char *newkeyword;
233 {
234 
235    if (newkeyword == NULL)
236       yywarnx("keyword \"%s\" is deprecated and no longer used.  "
237               "Please remove the keyword from %s's config file (%s)",
238               oldkeyword, PRODUCT, sockscf.option.configfile);
239    else
240       yywarnx("keyword \"%s\" is deprecated - assuming the new keyword \"%s\" "
241               "was meant.  Please update %s's config file (%s) to use the "
242               "new keyword as appropriate",
243               oldkeyword,
244               newkeyword,
245               PRODUCT,
246               sockscf.option.configfile);
247 }
248 
249 
250 static char *
getparsingerror(buf,buflen)251 getparsingerror(buf, buflen)
252    char *buf;
253    const size_t buflen;
254 {
255 #if 0 /* something wrong with the lex-file. */
256    const char *strip = " \n\t";
257    char visbuf1[100], visbuf2[sizeof(visbuf1)], yytextvis[100],
258         *l1 = previouslexline, *l2 = currentlexline;
259 
260    SKIPLEADING(l1, strip);
261    STRIPTRAILING(l1, strlen(l1), strip);
262 
263    SKIPLEADING(l2, strip);
264    STRIPTRAILING(l2, strlen(l2), strip);
265 
266    snprintfn(buf, buflen,
267              "%s: problem on line %d near \"%s %s\", at token \"%.20s\"",
268              sockscf.option.configfile,
269              yylineno,
270              str2vis(l1, strlen(l1), visbuf1, sizeof(visbuf1)),
271              str2vis(l2, strlen(l2), visbuf2, sizeof(visbuf2)),
272              (yytext == NULL || *yytext == NUL) ?
273                  "<start of line>" : str2vis(yytext,
274                                              strlen(yytext),
275                                              yytextvis,
276                                              sizeof(yytextvis)));
277 #else
278    char yytextvis[100];
279 
280    snprintfn(buf, buflen,
281              "%s: problem on line %d near token \"%.20s\"",
282              sockscf.option.configfile,
283              yylineno,
284              (yytext == NULL || *yytext == NUL) ?
285                  "'start of line'" : str2vis(yytext,
286                                              strlen(yytext),
287                                              yytextvis,
288                                              sizeof(yytextvis)));
289 #endif
290 
291    return buf;
292 }
293