1/*	$KAME: cftoken.l,v 1.67 2001/12/12 18:23:41 sakane Exp $	*/
2
3%{
4#include <sys/types.h>
5#include <sys/param.h>
6#include <sys/socket.h>
7
8#include <netinet/in.h>
9#include <netinet/ipsec.h>
10
11#include <stdlib.h>
12#include <stdio.h>
13#include <string.h>
14#include <errno.h>
15#include <limits.h>
16#include <ctype.h>
17#ifdef HAVE_STDARG_H
18#include <stdarg.h>
19#else
20#include <varargs.h>
21#endif
22
23#include "var.h"
24#include "misc.h"
25#include "vmbuf.h"
26#include "plog.h"
27#include "debug.h"
28
29#include "algorithm.h"
30#include "cfparse.h"
31#include "cftoken.h"
32#include "localconf.h"
33#include "oakley.h"
34#include "isakmp_var.h"
35#include "isakmp.h"
36#include "ipsec_doi.h"
37#include "proposal.h"
38#ifdef GC
39#include "gcmalloc.h"
40#endif
41
42#include "y.tab.h"
43
44int yyerrorcount = 0;
45
46#if defined(YIPS_DEBUG)
47#  define YYDB plog(LLV_DEBUG2, LOCATION, NULL,                                \
48		"begin <%d>%s\n", yy_start, yytext);
49#  define YYD {                                                                \
50	plog(LLV_DEBUG2, LOCATION, NULL, "<%d>%s",                             \
51	    yy_start, loglevel >= LLV_DEBUG2 ? "\n" : "");                     \
52}
53#else
54#  define YYDB
55#  define YYD
56#endif /* defined(YIPS_DEBUG) */
57
58#define MAX_INCLUDE_DEPTH 10
59
60static struct include_stack {
61	char *path;
62	FILE *fp;
63	YY_BUFFER_STATE state;
64	int lineno;
65} incstack[MAX_INCLUDE_DEPTH];
66static int incstackp = 0;
67
68static int yy_first_time = 1;
69%}
70
71/* common seciton */
72nl		\n
73ws		[ \t]+
74digit		[0-9]
75letter		[A-Za-z]
76hexdigit	[0-9A-Fa-f]
77/*octet		(([01]?{digit}?{digit})|((2([0-4]{digit}))|(25[0-5]))) */
78special		[()+\|\?\*]
79comma		\,
80dot		\.
81slash		\/
82bcl		\{
83ecl		\}
84blcl		\[
85elcl		\]
86percent		\%
87semi		\;
88comment		\#.*
89ccomment	"/*"
90bracketstring	\<[^>]*\>
91quotedstring	\"[^"]*\"
92addrstring	[a-fA-F0-9:]([a-fA-F0-9:\.]*|[a-fA-F0-9:\.]*%[a-zA-Z0-9]*)
93decstring	{digit}+
94hexstring	0x{hexdigit}+
95
96%s S_INI S_PTH S_INF S_LOG S_PAD S_LST S_RTRY
97%s S_ALGST S_ALGCL
98%s S_SAINF S_SAINFS
99%s S_RMT S_RMTS S_RMTP
100%s S_SA
101
102%%
103%{
104	if (yy_first_time) {
105		BEGIN S_INI;
106		yy_first_time = 0;
107	}
108%}
109
110	/* path */
111<S_INI>path		{ BEGIN S_PTH; YYDB; return(PATH); }
112<S_PTH>include		{ YYD; yylval.num = LC_PATHTYPE_INCLUDE;
113				return(PATHTYPE); }
114<S_PTH>pre_shared_key	{ YYD; yylval.num = LC_PATHTYPE_PSK;
115				return(PATHTYPE); }
116<S_PTH>certificate	{ YYD; yylval.num = LC_PATHTYPE_CERT;
117				return(PATHTYPE); }
118<S_PTH>backupsa		{ YYD; yylval.num = LC_PATHTYPE_BACKUPSA;
119				return(PATHTYPE); }
120<S_PTH>{semi}		{ BEGIN S_INI; YYDB; return(EOS); }
121
122	/* include */
123<S_INI>include		{ YYDB; return(INCLUDE); }
124
125	/* self information */
126<S_INI>identifier	{ BEGIN S_INF; YYDB; yywarn("it is obsoleted.  use \"my_identifier\" in each remote directives."); return(IDENTIFIER); }
127<S_INF>{semi}		{ BEGIN S_INI; return(EOS); }
128
129	/* special */
130<S_INI>complex_bundle	{ YYDB; return(COMPLEX_BUNDLE); }
131
132	/* logging */
133<S_INI>log		{ BEGIN S_LOG; YYDB; return(LOGGING); }
134<S_LOG>info		{ YYD; yywarn("it is obsoleted.  use \"notify\""); yylval.num = 0; return(LOGLEV); }
135<S_LOG>notify		{ YYD; yylval.num = 0; return(LOGLEV); }
136<S_LOG>debug		{ YYD; yylval.num = 1; return(LOGLEV); }
137<S_LOG>debug2		{ YYD; yylval.num = 2; return(LOGLEV); }
138<S_LOG>debug3		{ YYD; yywarn("it is osboleted.  use \"debug2\""); yylval.num = 2; return(LOGLEV); }
139<S_LOG>debug4		{ YYD; yywarn("it is obsoleted.  use \"debug2\""); yylval.num = 2; return(LOGLEV); }
140<S_LOG>{semi}		{ BEGIN S_INI; return(EOS); }
141
142	/* padding */
143<S_INI>padding		{ BEGIN S_PAD; YYDB; return(PADDING); }
144<S_PAD>{bcl}		{ return(BOC); }
145<S_PAD>randomize	{ YYD; return(PAD_RANDOMIZE); }
146<S_PAD>randomize_length	{ YYD; return(PAD_RANDOMIZELEN); }
147<S_PAD>maximum_length	{ YYD; return(PAD_MAXLEN); }
148<S_PAD>strict_check	{ YYD; return(PAD_STRICT); }
149<S_PAD>exclusive_tail	{ YYD; return(PAD_EXCLTAIL); }
150<S_PAD>{ecl}		{ BEGIN S_INI; return(EOC); }
151
152	/* listen */
153<S_INI>listen		{ BEGIN S_LST; YYDB; return(LISTEN); }
154<S_LST>{bcl}		{ return(BOC); }
155<S_LST>isakmp		{ YYD; return(X_ISAKMP); }
156<S_LST>admin		{ YYD; return(X_ADMIN); }
157<S_LST>strict_address	{ YYD; return(STRICT_ADDRESS); }
158<S_LST>{ecl}		{ BEGIN S_INI; return(EOC); }
159
160	/* timer */
161<S_INI>timer		{ BEGIN S_RTRY; YYDB; return(RETRY); }
162<S_RTRY>{bcl}		{ return(BOC); }
163<S_RTRY>counter		{ YYD; return(RETRY_COUNTER); }
164<S_RTRY>interval	{ YYD; return(RETRY_INTERVAL); }
165<S_RTRY>persend		{ YYD; return(RETRY_PERSEND); }
166<S_RTRY>phase1		{ YYD; return(RETRY_PHASE1); }
167<S_RTRY>phase2		{ YYD; return(RETRY_PHASE2); }
168<S_RTRY>{ecl}		{ BEGIN S_INI; return(EOC); }
169
170	/* sainfo */
171<S_INI>sainfo		{ BEGIN S_SAINF; YYDB; return(SAINFO); }
172<S_SAINF>anonymous	{ YYD; return(ANONYMOUS); }
173<S_SAINF>{blcl}any{elcl}	{ YYD; return(PORTANY); }
174<S_SAINF>any		{ YYD; return(ANY); }
175	/* sainfo spec */
176<S_SAINF>{bcl}		{ BEGIN S_SAINFS; return(BOC); }
177<S_SAINF>{semi}		{ BEGIN S_INI; return(EOS); }
178<S_SAINFS>{ecl}		{ BEGIN S_INI; return(EOC); }
179<S_SAINFS>pfs_group	{ YYD; return(PFS_GROUP); }
180<S_SAINFS>identifier	{ YYD; yywarn("it is obsoleted.  use \"my_identifier\"."); return(IDENTIFIER); }
181<S_SAINFS>my_identifier	{ YYD; return(MY_IDENTIFIER); }
182<S_SAINFS>lifetime	{ YYD; return(LIFETIME); }
183<S_SAINFS>time		{ YYD; return(LIFETYPE_TIME); }
184<S_SAINFS>byte		{ YYD; return(LIFETYPE_BYTE); }
185<S_SAINFS>encryption_algorithm { YYD; yylval.num = algclass_ipsec_enc; return(ALGORITHM_CLASS); }
186<S_SAINFS>authentication_algorithm { YYD; yylval.num = algclass_ipsec_auth; return(ALGORITHM_CLASS); }
187<S_SAINFS>compression_algorithm	{ YYD; yylval.num = algclass_ipsec_comp; return(ALGORITHM_CLASS); }
188<S_SAINFS>{comma}	{ YYD; return(COMMA); }
189
190	/* remote */
191<S_INI>remote		{ BEGIN S_RMT; YYDB; return(REMOTE); }
192<S_RMT>anonymous	{ YYD; return(ANONYMOUS); }
193	/* remote spec */
194<S_RMT>{bcl}		{ BEGIN S_RMTS; return(BOC); }
195<S_RMTS>{ecl}		{ BEGIN S_INI; return(EOC); }
196<S_RMTS>exchange_mode	{ YYD; return(EXCHANGE_MODE); }
197<S_RMTS>{comma}		{ YYD; /* XXX ignored, but to be handled. */ ; }
198<S_RMTS>base		{ YYD; yylval.num = ISAKMP_ETYPE_BASE; return(EXCHANGETYPE); }
199<S_RMTS>main		{ YYD; yylval.num = ISAKMP_ETYPE_IDENT; return(EXCHANGETYPE); }
200<S_RMTS>aggressive	{ YYD; yylval.num = ISAKMP_ETYPE_AGG; return(EXCHANGETYPE); }
201<S_RMTS>doi		{ YYD; return(DOI); }
202<S_RMTS>ipsec_doi	{ YYD; yylval.num = IPSEC_DOI; return(DOITYPE); }
203<S_RMTS>situation	{ YYD; return(SITUATION); }
204<S_RMTS>identity_only	{ YYD; yylval.num = IPSECDOI_SIT_IDENTITY_ONLY; return(SITUATIONTYPE); }
205<S_RMTS>secrecy		{ YYD; yylval.num = IPSECDOI_SIT_SECRECY; return(SITUATIONTYPE); }
206<S_RMTS>integrity	{ YYD; yylval.num = IPSECDOI_SIT_INTEGRITY; return(SITUATIONTYPE); }
207<S_RMTS>identifier	{ YYD; yywarn("it is obsoleted.  use \"my_identifier\"."); return(IDENTIFIER); }
208<S_RMTS>my_identifier	{ YYD; return(MY_IDENTIFIER); }
209<S_RMTS>peers_identifier	{ YYD; return(PEERS_IDENTIFIER); }
210<S_RMTS>verify_identifier	{ YYD; return(VERIFY_IDENTIFIER); }
211<S_RMTS>certificate_type	{ YYD; return(CERTIFICATE_TYPE); }
212<S_RMTS>x509		{ YYD; yylval.num = ISAKMP_CERT_X509SIGN; return(CERT_X509); }
213<S_RMTS>peers_certfile	{ YYD; return(PEERS_CERTFILE); }
214<S_RMTS>dnssec		{ YYD; return(DNSSEC); }
215<S_RMTS>verify_cert	{ YYD; return(VERIFY_CERT); }
216<S_RMTS>send_cert	{ YYD; return(SEND_CERT); }
217<S_RMTS>send_cr		{ YYD; return(SEND_CR); }
218<S_RMTS>dh_group	{ YYD; return(DH_GROUP); }
219<S_RMTS>nonce_size	{ YYD; return(NONCE_SIZE); }
220<S_RMTS>generate_policy	{ YYD; return(GENERATE_POLICY); }
221<S_RMTS>support_mip6	{ YYD; return(SUPPORT_MIP6); }
222<S_RMTS>initial_contact	{ YYD; return(INITIAL_CONTACT); }
223<S_RMTS>proposal_check	{ YYD; return(PROPOSAL_CHECK); }
224<S_RMTS>obey		{ YYD; yylval.num = PROP_CHECK_OBEY; return(PROPOSAL_CHECK_LEVEL); }
225<S_RMTS>strict		{ YYD; yylval.num = PROP_CHECK_STRICT; return(PROPOSAL_CHECK_LEVEL); }
226<S_RMTS>exact		{ YYD; yylval.num = PROP_CHECK_EXACT; return(PROPOSAL_CHECK_LEVEL); }
227<S_RMTS>claim		{ YYD; yylval.num = PROP_CHECK_CLAIM; return(PROPOSAL_CHECK_LEVEL); }
228<S_RMTS>keepalive	{ YYD; return(KEEPALIVE); }
229<S_RMTS>passive		{ YYD; return(PASSIVE); }
230<S_RMTS>lifetime	{ YYD; return(LIFETIME); }
231<S_RMTS>time		{ YYD; return(LIFETYPE_TIME); }
232<S_RMTS>byte		{ YYD; return(LIFETYPE_BYTE); }
233	/* remote proposal */
234<S_RMTS>proposal	{ BEGIN S_RMTP; YYDB; return(PROPOSAL); }
235<S_RMTP>{bcl}		{ return(BOC); }
236<S_RMTP>{ecl}		{ BEGIN S_RMTS; return(EOC); }
237<S_RMTP>lifetime	{ YYD; return(LIFETIME); }
238<S_RMTP>time		{ YYD; return(LIFETYPE_TIME); }
239<S_RMTP>byte		{ YYD; return(LIFETYPE_BYTE); }
240<S_RMTP>encryption_algorithm { YYD; yylval.num = algclass_isakmp_enc; return(ALGORITHM_CLASS); }
241<S_RMTP>authentication_method { YYD; yylval.num = algclass_isakmp_ameth; return(ALGORITHM_CLASS); }
242<S_RMTP>hash_algorithm	{ YYD; yylval.num = algclass_isakmp_hash; return(ALGORITHM_CLASS); }
243<S_RMTP>dh_group	{ YYD; return(DH_GROUP); }
244<S_RMTP>gssapi_id	{ YYD; return(GSSAPI_ID); }
245
246	/* parameter */
247on		{ YYD; yylval.num = TRUE; return(SWITCH); }
248off		{ YYD; yylval.num = FALSE; return(SWITCH); }
249
250	/* prefix */
251{slash}{digit}{1,3} {
252			YYD;
253			yytext++;
254			yylval.num = atoi(yytext);
255			return(PREFIX);
256		}
257
258	/* port number */
259{blcl}{decstring}{elcl}	{
260			char *p = yytext;
261			YYD;
262			while (*++p != ']') ;
263			*p = 0;
264			yytext++;
265			yylval.num = atoi(yytext);
266			return(PORT);
267		}
268
269	/* upper protocol */
270esp		{ YYD; yylval.num = IPPROTO_ESP; return(UL_PROTO); }
271ah		{ YYD; yylval.num = IPPROTO_AH; return(UL_PROTO); }
272ipcomp		{ YYD; yylval.num = IPPROTO_IPCOMP; return(UL_PROTO); }
273icmp		{ YYD; yylval.num = IPPROTO_ICMP; return(UL_PROTO); }
274icmp6		{ YYD; yylval.num = IPPROTO_ICMPV6; return(UL_PROTO); }
275tcp		{ YYD; yylval.num = IPPROTO_TCP; return(UL_PROTO); }
276udp		{ YYD; yylval.num = IPPROTO_UDP; return(UL_PROTO); }
277
278	/* algorithm type */
279des_iv64	{ YYD; yylval.num = algtype_des_iv64;	return(ALGORITHMTYPE); }
280des		{ YYD; yylval.num = algtype_des;	return(ALGORITHMTYPE); }
2813des		{ YYD; yylval.num = algtype_3des;	return(ALGORITHMTYPE); }
282rc5		{ YYD; yylval.num = algtype_rc5;	return(ALGORITHMTYPE); }
283idea 		{ YYD; yylval.num = algtype_idea;	return(ALGORITHMTYPE); }
284cast128		{ YYD; yylval.num = algtype_cast128;	return(ALGORITHMTYPE); }
285blowfish	{ YYD; yylval.num = algtype_blowfish;	return(ALGORITHMTYPE); }
2863idea		{ YYD; yylval.num = algtype_3idea;	return(ALGORITHMTYPE); }
287des_iv32	{ YYD; yylval.num = algtype_des_iv32;	return(ALGORITHMTYPE); }
288rc4 		{ YYD; yylval.num = algtype_rc4;	return(ALGORITHMTYPE); }
289null_enc	{ YYD; yylval.num = algtype_null_enc;	return(ALGORITHMTYPE); }
290rijndael	{ YYD; yylval.num = algtype_rijndael;	return(ALGORITHMTYPE); }
291aes		{ YYD; yylval.num = algtype_rijndael;	return(ALGORITHMTYPE); }
292twofish		{ YYD; yylval.num = algtype_twofish;	return(ALGORITHMTYPE); }
293non_auth	{ YYD; yylval.num = algtype_non_auth;	return(ALGORITHMTYPE); }
294hmac_md5	{ YYD; yylval.num = algtype_hmac_md5;	return(ALGORITHMTYPE); }
295hmac_sha1	{ YYD; yylval.num = algtype_hmac_sha1;	return(ALGORITHMTYPE); }
296hmac_sha2_256	{ YYD; yylval.num = algtype_hmac_sha2_256;	return(ALGORITHMTYPE); }
297hmac_sha2_384	{ YYD; yylval.num = algtype_hmac_sha2_384;	return(ALGORITHMTYPE); }
298hmac_sha2_512	{ YYD; yylval.num = algtype_hmac_sha2_512;	return(ALGORITHMTYPE); }
299des_mac		{ YYD; yylval.num = algtype_des_mac;	return(ALGORITHMTYPE); }
300kpdk		{ YYD; yylval.num = algtype_kpdk;	return(ALGORITHMTYPE); }
301md5		{ YYD; yylval.num = algtype_md5;	return(ALGORITHMTYPE); }
302sha1		{ YYD; yylval.num = algtype_sha1;	return(ALGORITHMTYPE); }
303tiger		{ YYD; yylval.num = algtype_tiger;	return(ALGORITHMTYPE); }
304sha2_256	{ YYD; yylval.num = algtype_sha2_256;	return(ALGORITHMTYPE); }
305sha2_384	{ YYD; yylval.num = algtype_sha2_384;	return(ALGORITHMTYPE); }
306sha2_512	{ YYD; yylval.num = algtype_sha2_512;	return(ALGORITHMTYPE); }
307oui		{ YYD; yylval.num = algtype_oui;	return(ALGORITHMTYPE); }
308deflate		{ YYD; yylval.num = algtype_deflate;	return(ALGORITHMTYPE); }
309lzs		{ YYD; yylval.num = algtype_lzs;	return(ALGORITHMTYPE); }
310modp768		{ YYD; yylval.num = algtype_modp768;	return(ALGORITHMTYPE); }
311modp1024	{ YYD; yylval.num = algtype_modp1024;	return(ALGORITHMTYPE); }
312modp1536	{ YYD; yylval.num = algtype_modp1536;	return(ALGORITHMTYPE); }
313ec2n155		{ YYD; yylval.num = algtype_ec2n155;	return(ALGORITHMTYPE); }
314ec2n185		{ YYD; yylval.num = algtype_ec2n185;	return(ALGORITHMTYPE); }
315modp2048	{ YYD; yylval.num = algtype_modp2048;	return(ALGORITHMTYPE); }
316modp3072	{ YYD; yylval.num = algtype_modp3072;	return(ALGORITHMTYPE); }
317modp4096	{ YYD; yylval.num = algtype_modp4096;	return(ALGORITHMTYPE); }
318modp6144	{ YYD; yylval.num = algtype_modp6144;	return(ALGORITHMTYPE); }
319modp8192	{ YYD; yylval.num = algtype_modp8192;	return(ALGORITHMTYPE); }
320pre_shared_key	{ YYD; yylval.num = algtype_psk;	return(ALGORITHMTYPE); }
321rsasig		{ YYD; yylval.num = algtype_rsasig;	return(ALGORITHMTYPE); }
322dsssig		{ YYD; yylval.num = algtype_dsssig;	return(ALGORITHMTYPE); }
323rsaenc		{ YYD; yylval.num = algtype_rsaenc;	return(ALGORITHMTYPE); }
324rsarev		{ YYD; yylval.num = algtype_rsarev;	return(ALGORITHMTYPE); }
325gssapi_krb	{ YYD; yylval.num = algtype_gssapikrb;	return(ALGORITHMTYPE); }
326
327	/* identifier type */
328vendor_id	{ YYD; yywarn("it is obsoleted."); return(VENDORID); }
329user_fqdn	{ YYD; yylval.num = IDTYPE_USERFQDN; return(IDENTIFIERTYPE); }
330fqdn		{ YYD; yylval.num = IDTYPE_FQDN; return(IDENTIFIERTYPE); }
331keyid		{ YYD; yylval.num = IDTYPE_KEYID; return(IDENTIFIERTYPE); }
332address		{ YYD; yylval.num = IDTYPE_ADDRESS; return(IDENTIFIERTYPE); }
333asn1dn		{ YYD; yylval.num = IDTYPE_ASN1DN; return(IDENTIFIERTYPE); }
334certname	{ YYD; yywarn("certname will be obsoleted in near future."); yylval.num = IDTYPE_ASN1DN; return(IDENTIFIERTYPE); }
335
336	/* units */
337B|byte|bytes		{ YYD; return(UNITTYPE_BYTE); }
338KB			{ YYD; return(UNITTYPE_KBYTES); }
339MB			{ YYD; return(UNITTYPE_MBYTES); }
340TB			{ YYD; return(UNITTYPE_TBYTES); }
341sec|secs|second|seconds	{ YYD; return(UNITTYPE_SEC); }
342min|mins|minute|minutes	{ YYD; return(UNITTYPE_MIN); }
343hour|hours		{ YYD; return(UNITTYPE_HOUR); }
344
345	/* boolean */
346yes		{ YYD; yylval.num = TRUE; return(BOOLEAN); }
347no		{ YYD; yylval.num = FALSE; return(BOOLEAN); }
348
349{decstring}	{
350			char *bp;
351
352			YYD;
353			yylval.num = strtol(yytext, &bp, 10);
354			return(NUMBER);
355		}
356
357{hexstring}	{
358			char *p;
359
360			YYD;
361			yylval.val = vmalloc(yyleng + (yyleng & 1) + 1);
362			if (yylval.val == NULL) {
363				yyerror("vmalloc failed");
364				return -1;
365			}
366
367			p = yylval.val->v;
368			*p++ = '0';
369			*p++ = 'x';
370
371			/* fixed string if length is odd. */
372			if (yyleng & 1)
373				*p++ = '0';
374			memcpy(p, &yytext[2], yyleng - 1);
375
376			return(HEXSTRING);
377		}
378
379{quotedstring}	{
380			u_char *p = yytext;
381
382			YYD;
383			while (*++p != '"') ;
384			*p = '\0';
385
386			yylval.val = vmalloc(yyleng - 1);
387			if (yylval.val == NULL) {
388				yyerror("vmalloc failed");
389				return -1;
390			}
391			memcpy(yylval.val->v, &yytext[1], yylval.val->l);
392
393			return(QUOTEDSTRING);
394		}
395
396{addrstring}	{
397			YYD;
398
399			yylval.val = vmalloc(yyleng + 1);
400			if (yylval.val == NULL) {
401				yyerror("vmalloc failed");
402				return -1;
403			}
404			memcpy(yylval.val->v, yytext, yylval.val->l);
405
406			return(ADDRSTRING);
407		}
408
409<<EOF>>		{
410			if ( --incstackp < 0 ) {
411				yyterminate();
412			} else {
413				yy_delete_buffer(YY_CURRENT_BUFFER);
414				yy_switch_to_buffer(incstack[incstackp].state);
415			}
416		}
417
418	/* ... */
419{ws}		{ ; }
420{nl}		{ incstack[incstackp].lineno++; }
421{comment}	{ YYD; }
422{semi}		{ return(EOS); }
423.		{ yymore(); }
424
425%%
426
427void
428yyerror(char *s, ...)
429{
430	char fmt[512];
431
432	va_list ap;
433#ifdef HAVE_STDARG_H
434	va_start(ap, s);
435#else
436	va_start(ap);
437#endif
438	snprintf(fmt, sizeof(fmt), "%s:%d: \"%s\" %s\n",
439		incstack[incstackp].path, incstack[incstackp].lineno,
440		yytext, s);
441	plogv(LLV_ERROR, LOCATION, NULL, fmt, ap);
442	va_end(ap);
443
444	yyerrorcount++;
445}
446
447void
448yywarn(char *s, ...)
449{
450	char fmt[512];
451
452	va_list ap;
453#ifdef HAVE_STDARG_H
454	va_start(ap, s);
455#else
456	va_start(ap);
457#endif
458	snprintf(fmt, sizeof(fmt), "%s:%d: \"%s\" %s\n",
459		incstack[incstackp].path, incstack[incstackp].lineno,
460		yytext, s);
461	plogv(LLV_WARNING, LOCATION, NULL, fmt, ap);
462	va_end(ap);
463}
464
465int
466yycf_switch_buffer(path)
467	char *path;
468{
469	/* got the include file name */
470	if (incstackp >= MAX_INCLUDE_DEPTH) {
471		plog(LLV_ERROR, LOCATION, NULL,
472			"Includes nested too deeply");
473		return -1;
474	}
475
476	incstack[incstackp++].state = YY_CURRENT_BUFFER;
477
478	if (yycf_set_buffer(path) != 0)
479		return -1;
480
481	yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
482
483	BEGIN(S_INI);
484
485	return 0;
486}
487
488int
489yycf_set_buffer(path)
490	char *path;
491{
492	yyin = fopen(path, "r");
493	if (yyin == NULL) {
494		fprintf(stderr, "failed to open file %s (%s)\n",
495			path, strerror(errno));
496		plog(LLV_ERROR, LOCATION, NULL,
497			"failed to open file %s (%s)\n",
498			path, strerror(errno));
499		return -1;
500	}
501
502	/* initialize */
503	incstack[incstackp].fp = yyin;
504	incstack[incstackp].path = strdup(path);
505	incstack[incstackp].lineno = 1;
506
507	return 0;
508}
509
510void
511yycf_init_buffer()
512{
513	int i;
514
515	for (i = 0; i < MAX_INCLUDE_DEPTH; i++)
516		memset(&incstack[i], 0, sizeof(incstack[i]));
517	incstackp = 0;
518}
519
520void
521yycf_clean_buffer()
522{
523	int i;
524
525	for (i = 0; i < MAX_INCLUDE_DEPTH; i++) {
526		if (incstack[i].path != NULL) {
527			fclose(incstack[i].fp);
528			racoon_free(incstack[i].path);
529			incstack[i].path = NULL;
530		}
531	}
532}
533
534