xref: /openbsd-src/lib/libkeynote/keynote.l (revision b299522fd25c4b1512a62ab573611a44254df5a8)
1983e9580Sangelos %{
2*b299522fSmillert /* $OpenBSD: keynote.l,v 1.24 2017/08/28 17:07:19 millert Exp $ */
3983e9580Sangelos /*
4983e9580Sangelos  * The author of this code is Angelos D. Keromytis (angelos@dsl.cis.upenn.edu)
5983e9580Sangelos  *
6983e9580Sangelos  * This code was written by Angelos D. Keromytis in Philadelphia, PA, USA,
7983e9580Sangelos  * in April-May 1998
8983e9580Sangelos  *
9983e9580Sangelos  * Copyright (C) 1998, 1999 by Angelos D. Keromytis.
10983e9580Sangelos  *
115e4ac158Sderaadt  * Permission to use, copy, and modify this software with or without fee
12983e9580Sangelos  * is hereby granted, provided that this entire notice is included in
13983e9580Sangelos  * all copies of any software which is or includes a copy or
14983e9580Sangelos  * modification of this software.
15983e9580Sangelos  *
16983e9580Sangelos  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
17983e9580Sangelos  * IMPLIED WARRANTY. IN PARTICULAR, THE AUTHORS MAKES NO
18983e9580Sangelos  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
19983e9580Sangelos  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
20983e9580Sangelos  * PURPOSE.
21983e9580Sangelos  */
22983e9580Sangelos 
23e0758482Smsf #include <sys/time.h>
24983e9580Sangelos #include <sys/types.h>
25e0758482Smsf 
26983e9580Sangelos #include <ctype.h>
2785616838Smsf #include <regex.h>
28983e9580Sangelos #include <string.h>
29e0758482Smsf #include <time.h>
309186b70cSangelos #include <unistd.h>
31a8a6ad51Sangelos 
32983e9580Sangelos #include "k.tab.h"
33a8a6ad51Sangelos #include "keynote.h"
34983e9580Sangelos #include "assertion.h"
35983e9580Sangelos 
36983e9580Sangelos static void mystrncpy(char *, char *, int);
37983e9580Sangelos 
38983e9580Sangelos struct lex_list
39983e9580Sangelos {
40983e9580Sangelos     int   lex_type;
41983e9580Sangelos     void *lex_s;
42983e9580Sangelos };
43983e9580Sangelos 
44313d0fe7Smmcc static struct lex_list *keynote_lex_list = NULL;
45983e9580Sangelos static int    keynote_max_lex_list = 32;
46983e9580Sangelos static int    keynote_lex_counter = 0;
47983e9580Sangelos static int    first_tok = 0;
48983e9580Sangelos %}
49983e9580Sangelos digit		[0-9]
50983e9580Sangelos specnumber      [1-9][0-9]*
514812cf71Sangelos number		{digit}+
524812cf71Sangelos flt		{digit}+"."{digit}+
53983e9580Sangelos vstring		[a-zA-Z_][a-zA-Z0-9_]*
54f416c374Sangelos litstring	\"(((\\\n)|(\\.)|([^\\\n\"]))*)\"
55983e9580Sangelos variable	{vstring}
56983e9580Sangelos comment		"#"[^\n]*
57983e9580Sangelos %s ACTIONSTRING LOCALINIT KEYPREDICATE SIGNERINIT KEYNOTEVERSION
58983e9580Sangelos %pointer
59*b299522fSmillert %option noinput noyywrap never-interactive yylineno
60983e9580Sangelos %%
61983e9580Sangelos %{
62983e9580Sangelos     /*
63983e9580Sangelos      * Return a preset token, so we can have more than one grammars
64983e9580Sangelos      * in yacc.
65983e9580Sangelos      */
66983e9580Sangelos     extern int first_tok;
67983e9580Sangelos 
68983e9580Sangelos     if (first_tok)
69983e9580Sangelos     {
70983e9580Sangelos 	int holdtok = first_tok;
71983e9580Sangelos 
72983e9580Sangelos 	first_tok = 0;
73983e9580Sangelos 	return holdtok;
74983e9580Sangelos     }
75983e9580Sangelos %}
76983e9580Sangelos 
77983e9580Sangelos <KEYPREDICATE>{specnumber}"-of"		{
78983e9580Sangelos 					  knlval.intval = atoi(kntext);
79983e9580Sangelos 					  return KOF;
80983e9580Sangelos 					}
81983e9580Sangelos <ACTIONSTRING,KEYPREDICATE>"("		return OPENPAREN;
82983e9580Sangelos <ACTIONSTRING,KEYPREDICATE>")"		return CLOSEPAREN;
83983e9580Sangelos <ACTIONSTRING,KEYPREDICATE>"&&"		return AND;
84983e9580Sangelos <ACTIONSTRING,KEYPREDICATE>"||"		return OR;
85983e9580Sangelos <ACTIONSTRING>"+"			return PLUS;
86983e9580Sangelos <ACTIONSTRING>"->"              return HINT;
87983e9580Sangelos <ACTIONSTRING>"{"               return OPENBLOCK;
88983e9580Sangelos <ACTIONSTRING>"}"               return CLOSEBLOCK;
89983e9580Sangelos <ACTIONSTRING>";"               return SEMICOLON;
90983e9580Sangelos <ACTIONSTRING>"!"		return NOT;
91983e9580Sangelos <ACTIONSTRING>"~="		return REGEXP;
92983e9580Sangelos <ACTIONSTRING>"=="		return EQ;
93983e9580Sangelos <ACTIONSTRING>"!="		return NE;
94983e9580Sangelos <ACTIONSTRING>"<"		return LT;
95983e9580Sangelos <ACTIONSTRING>">"		return GT;
96983e9580Sangelos <ACTIONSTRING>"<="		return LE;
97983e9580Sangelos <ACTIONSTRING>">="		return GE;
98983e9580Sangelos <ACTIONSTRING>"-"		return MINUS;
99983e9580Sangelos <ACTIONSTRING>"*"		return MULT;
100983e9580Sangelos <ACTIONSTRING>"/"		return DIV;
101983e9580Sangelos <ACTIONSTRING>"%"		return MOD;
102983e9580Sangelos <ACTIONSTRING>"^"		return EXP;
103983e9580Sangelos "."		                return DOTT;
104983e9580Sangelos <ACTIONSTRING>"true"            return TRUE;
105983e9580Sangelos <ACTIONSTRING>"false"           return FALSE;
106983e9580Sangelos {comment}		/* eat up comments */
107983e9580Sangelos <LOCALINIT>"="	                return EQQ;
108983e9580Sangelos <KEYPREDICATE>"," 		return COMMA;
109983e9580Sangelos <ACTIONSTRING,KEYPREDICATE,SIGNERINIT,LOCALINIT>{variable} {
110f91597c4Sderaadt 					int len;
111983e9580Sangelos                                         if (keynote_exceptionflag ||
112983e9580Sangelos 					    keynote_donteval)
113983e9580Sangelos 					{
114313d0fe7Smmcc 					    knlval.string = NULL;
115983e9580Sangelos 					    return VARIABLE;
116983e9580Sangelos 					}
117983e9580Sangelos 
118f91597c4Sderaadt 					len = strlen(kntext) + 1;
119f91597c4Sderaadt 					knlval.string = calloc(len, sizeof(char));
120313d0fe7Smmcc                                         if (knlval.string == NULL)
121983e9580Sangelos 					{
122983e9580Sangelos 					    keynote_errno = ERROR_MEMORY;
123983e9580Sangelos 					    return -1;
124983e9580Sangelos 					}
125f91597c4Sderaadt 		  	          	strlcpy(knlval.string, kntext, len);
126983e9580Sangelos 					if (keynote_lex_add(knlval.string,
127983e9580Sangelos 							    LEXTYPE_CHAR) ==
128983e9580Sangelos 					    -1)
129983e9580Sangelos 					  return -1;
130983e9580Sangelos 		  	         	return VARIABLE;
131983e9580Sangelos 			      	      }
132983e9580Sangelos "$"                             return DEREF;
133983e9580Sangelos <ACTIONSTRING>"@"	    	return OPENNUM;
134983e9580Sangelos <ACTIONSTRING>"&"	    	return OPENFLT;
135983e9580Sangelos <ACTIONSTRING>{flt}	      {
136983e9580Sangelos 				knlval.doubval = atof(kntext);
137983e9580Sangelos 				return FLOAT;
138983e9580Sangelos 			      }
139983e9580Sangelos <KEYNOTEVERSION>{number}      {
140f91597c4Sderaadt 				int len;
141f91597c4Sderaadt 
142983e9580Sangelos                                 if (keynote_exceptionflag ||
143983e9580Sangelos 				    keynote_donteval)
144983e9580Sangelos 				{
145313d0fe7Smmcc 				    knlval.string = NULL;
146983e9580Sangelos 				    return STRING;
147983e9580Sangelos 				}
148983e9580Sangelos 
149f91597c4Sderaadt 				len = strlen(kntext) + 1;
150f91597c4Sderaadt 				knlval.string = calloc(len, sizeof(char));
151313d0fe7Smmcc                                 if (knlval.string == NULL)
152983e9580Sangelos 				{
153983e9580Sangelos 				    keynote_errno = ERROR_MEMORY;
154983e9580Sangelos 				    return -1;
155983e9580Sangelos 				}
156f91597c4Sderaadt 		  	        strlcpy(knlval.string, kntext, len);
157983e9580Sangelos 				if (keynote_lex_add(knlval.string,
158983e9580Sangelos 						    LEXTYPE_CHAR) == -1)
159983e9580Sangelos 				  return -1;
160983e9580Sangelos 		  	        return STRING;
161983e9580Sangelos 			      }
162983e9580Sangelos <ACTIONSTRING>{number}	      {
163983e9580Sangelos 				knlval.intval = atoi(kntext);
164983e9580Sangelos 				return NUM;
165983e9580Sangelos 			      }
166983e9580Sangelos {litstring}                   {
167983e9580Sangelos                                 if (keynote_exceptionflag ||
168983e9580Sangelos 				    keynote_donteval)
169983e9580Sangelos 				{
170313d0fe7Smmcc 				    knlval.string = NULL;
171983e9580Sangelos 				    return STRING;
172983e9580Sangelos 				}
173983e9580Sangelos 
174983e9580Sangelos 				knlval.string = calloc(strlen(kntext) - 1,
175983e9580Sangelos 						       sizeof(char));
176313d0fe7Smmcc                                 if (knlval.string == NULL)
177983e9580Sangelos 				{
178983e9580Sangelos 				    keynote_errno = ERROR_MEMORY;
179983e9580Sangelos 				    return -1;
180983e9580Sangelos 				}
181983e9580Sangelos 
182983e9580Sangelos 				mystrncpy(knlval.string, kntext + 1,
183983e9580Sangelos 					  strlen(kntext) - 2);
184983e9580Sangelos 
185983e9580Sangelos 				if (keynote_lex_add(knlval.string,
186983e9580Sangelos 						    LEXTYPE_CHAR) == -1)
187983e9580Sangelos 				  return -1;
188983e9580Sangelos 				return STRING;
189983e9580Sangelos                               }
190983e9580Sangelos [ \t\n]
191983e9580Sangelos .                             { keynote_errno = ERROR_SYNTAX;
192983e9580Sangelos                                 return -1;
1934812cf71Sangelos 				REJECT; /* Avoid -Wall warning. Not reached */
194983e9580Sangelos                               }
195983e9580Sangelos %%
196983e9580Sangelos 
197983e9580Sangelos /*
198983e9580Sangelos  * Zap everything.
199983e9580Sangelos  */
200983e9580Sangelos static void
201983e9580Sangelos keynote_lex_zap(void)
202983e9580Sangelos {
203983e9580Sangelos     int i;
204983e9580Sangelos 
205983e9580Sangelos     if (keynote_lex_counter == 0)
206983e9580Sangelos       return;
207983e9580Sangelos 
208983e9580Sangelos     for (i = 0; i < keynote_max_lex_list; i++)
209313d0fe7Smmcc       if (keynote_lex_list[i].lex_s != NULL)
210983e9580Sangelos       {
211983e9580Sangelos 	  switch (keynote_lex_list[i].lex_type)
212983e9580Sangelos 	  {
213983e9580Sangelos 	      case LEXTYPE_CHAR:
214983e9580Sangelos 	          free(keynote_lex_list[i].lex_s);
215983e9580Sangelos 		  break;
216983e9580Sangelos 	  }
217983e9580Sangelos 
218983e9580Sangelos 	  keynote_lex_counter--;
219313d0fe7Smmcc 	  keynote_lex_list[i].lex_s = NULL;
220983e9580Sangelos 	  keynote_lex_list[i].lex_type = 0;
221983e9580Sangelos       }
222983e9580Sangelos }
223983e9580Sangelos 
224983e9580Sangelos /*
225983e9580Sangelos  * Initialize.
226983e9580Sangelos  */
227983e9580Sangelos static int
228983e9580Sangelos keynote_lex_init(void)
229983e9580Sangelos {
230313d0fe7Smmcc     if (keynote_lex_list != NULL)
231983e9580Sangelos       memset(keynote_lex_list, 0,
232983e9580Sangelos 	     keynote_max_lex_list * sizeof(struct lex_list));
233983e9580Sangelos     else
234983e9580Sangelos     {
235313d0fe7Smmcc 	keynote_lex_list = calloc(keynote_max_lex_list,
236983e9580Sangelos 					              sizeof(struct lex_list));
237313d0fe7Smmcc         if (keynote_lex_list == NULL)
238983e9580Sangelos 	{
239983e9580Sangelos 	    keynote_errno = ERROR_MEMORY;
240983e9580Sangelos 	    return -1;
241983e9580Sangelos 	}
242983e9580Sangelos     }
243983e9580Sangelos 
244983e9580Sangelos     return RESULT_TRUE;
245983e9580Sangelos }
246983e9580Sangelos 
247983e9580Sangelos /*
248983e9580Sangelos  * Add the string in a list of allocated but "dangling" memory references.
249983e9580Sangelos  * If out of memory, free the string and return -1 (and set keynote_errno).
250983e9580Sangelos  */
251983e9580Sangelos int
252983e9580Sangelos keynote_lex_add(void *s, int type)
253983e9580Sangelos {
254983e9580Sangelos     struct lex_list *p;
255983e9580Sangelos     int i;
256983e9580Sangelos 
257313d0fe7Smmcc     if (s == NULL)
258983e9580Sangelos       return RESULT_TRUE;
259983e9580Sangelos 
260983e9580Sangelos     for (i = 0; i < keynote_max_lex_list; i++)
261313d0fe7Smmcc       if (keynote_lex_list[i].lex_s == NULL)
262983e9580Sangelos       {
263983e9580Sangelos     	  keynote_lex_list[i].lex_s = (void *) s;
264983e9580Sangelos 	  keynote_lex_list[i].lex_type = type;
265983e9580Sangelos 	  keynote_lex_counter++;
266983e9580Sangelos      	  return RESULT_TRUE;
267983e9580Sangelos       }
268983e9580Sangelos 
269983e9580Sangelos     /* Not enough space, increase the size of the array */
270983e9580Sangelos     keynote_max_lex_list *= 2;
271983e9580Sangelos 
272862a1c7fSbluhm     p = (struct lex_list *) reallocarray(keynote_lex_list,
273862a1c7fSbluhm 					 keynote_max_lex_list,
274983e9580Sangelos 					 sizeof(struct lex_list));
275313d0fe7Smmcc     if (p == NULL)
276983e9580Sangelos     {
277983e9580Sangelos 	switch (type)
278983e9580Sangelos 	{
279983e9580Sangelos 	    case LEXTYPE_CHAR:
280983e9580Sangelos 	        free(s);
281983e9580Sangelos 		break;
282983e9580Sangelos 	}
283983e9580Sangelos 
284984ef80bSangelos         keynote_max_lex_list /= 2;
285983e9580Sangelos 	keynote_errno = ERROR_MEMORY;
286983e9580Sangelos         return -1;
287983e9580Sangelos     }
288983e9580Sangelos 
289441ae911Sderaadt     keynote_lex_list = p;
290983e9580Sangelos     keynote_lex_list[i].lex_s = s;
291983e9580Sangelos     keynote_lex_list[i++].lex_type = type;
292983e9580Sangelos     keynote_lex_counter++;
293983e9580Sangelos 
294983e9580Sangelos     /* Zero out the rest */
295983e9580Sangelos     memset(&(keynote_lex_list[i]), 0,
296983e9580Sangelos 	   (keynote_max_lex_list - i) * sizeof(struct lex_list));
297983e9580Sangelos 
298983e9580Sangelos     return RESULT_TRUE;
299983e9580Sangelos }
300983e9580Sangelos 
301983e9580Sangelos /*
302983e9580Sangelos  * Remove string.
303983e9580Sangelos  */
304983e9580Sangelos void
305983e9580Sangelos keynote_lex_remove(void *s)
306983e9580Sangelos {
307983e9580Sangelos     int i;
308983e9580Sangelos 
309983e9580Sangelos     for (i = 0; i < keynote_max_lex_list; i++)
310983e9580Sangelos       if (keynote_lex_list[i].lex_s == s)
311983e9580Sangelos       {
312983e9580Sangelos 	  memset(&(keynote_lex_list[i]), 0, sizeof(struct lex_list));
313983e9580Sangelos 	  keynote_lex_counter--;
314983e9580Sangelos 	  return;
315983e9580Sangelos       }
316983e9580Sangelos }
317983e9580Sangelos 
318983e9580Sangelos /*
319983e9580Sangelos  * Return RESULT_TRUE if character is octal digit, RESULT_FALSE otherwise.
320983e9580Sangelos  */
321983e9580Sangelos static int
322983e9580Sangelos is_octal(char c)
323983e9580Sangelos {
324983e9580Sangelos     switch (c)
325983e9580Sangelos     {
326983e9580Sangelos 	case '0': case '1': case '2': case '3':
327983e9580Sangelos 	case '4': case '5': case '6': case '7':
328983e9580Sangelos 	    return RESULT_TRUE;
329983e9580Sangelos 
330983e9580Sangelos 	default:
331983e9580Sangelos 	    return RESULT_FALSE;
332983e9580Sangelos     }
333983e9580Sangelos }
334983e9580Sangelos 
335983e9580Sangelos /*
336983e9580Sangelos  * Return octal value (non-zero) if argument starts with such a
337983e9580Sangelos  * representation, otherwise 0.
338983e9580Sangelos  */
339983e9580Sangelos static unsigned char
340983e9580Sangelos get_octal(char *s, int len, int *adv)
341983e9580Sangelos {
342983e9580Sangelos     unsigned char res = 0;
343983e9580Sangelos 
344983e9580Sangelos     if (*s == '0')
345983e9580Sangelos     {
346983e9580Sangelos 	if (len > 0)
347983e9580Sangelos 	{
348983e9580Sangelos 	    if (is_octal(*(s + 1)))
349983e9580Sangelos 	    {
350983e9580Sangelos 		res = *(s + 1) - '0';
351983e9580Sangelos 		*adv = 2;
352983e9580Sangelos 
353983e9580Sangelos 		if (is_octal(*(s + 2)) && (len - 1 > 0))
354983e9580Sangelos 		{
355983e9580Sangelos 		    res = res * 8 + (*(s + 2) - '0');
356983e9580Sangelos 		    *adv = 3;
357983e9580Sangelos 		}
358983e9580Sangelos 	    }
359983e9580Sangelos 	}
360983e9580Sangelos     }
361983e9580Sangelos     else
362983e9580Sangelos       if (is_octal(*s) && (len - 1 > 0))  /* Non-zero leading */
363983e9580Sangelos       {
364983e9580Sangelos 	  if (is_octal(*(s + 1)) &&
365983e9580Sangelos 	      is_octal(*(s + 2)))
366983e9580Sangelos 	  {
367983e9580Sangelos 	      *adv = 3;
368983e9580Sangelos 	      res = (((*s) - '0') * 64) +
369983e9580Sangelos 		    (((*(s + 1)) - '0') * 8) +
370983e9580Sangelos 		    ((*(s + 2)) - '0');
371983e9580Sangelos 	  }
372983e9580Sangelos       }
373983e9580Sangelos 
374983e9580Sangelos     return res;
375983e9580Sangelos }
376983e9580Sangelos 
377983e9580Sangelos /*
378983e9580Sangelos  * Copy at most len characters to string s1 from string s2, taking
379983e9580Sangelos  * care of escaped characters in the process. String s1 is assumed
380983e9580Sangelos  * to have enough space, and be zero'ed.
381983e9580Sangelos  */
382983e9580Sangelos static void
383983e9580Sangelos mystrncpy(char *s1, char *s2, int len)
384983e9580Sangelos {
385983e9580Sangelos     unsigned char c;
386983e9580Sangelos     int advance;
387983e9580Sangelos 
388983e9580Sangelos     if (len == 0)
389983e9580Sangelos       return;
390983e9580Sangelos 
391983e9580Sangelos     while (len-- > 0)
392983e9580Sangelos     {
393983e9580Sangelos         if (*s2 == '\\')
394983e9580Sangelos 	{
395983e9580Sangelos 	    s2++;
396983e9580Sangelos 
397983e9580Sangelos 	    if (len-- <= 0)
398983e9580Sangelos 	      break;
399983e9580Sangelos 
400983e9580Sangelos 	    if (*s2 == '\n')
401983e9580Sangelos 	    {
40280c62621Sderaadt 		while (isspace((unsigned char)*(++s2)) && (len-- > 0))
403983e9580Sangelos 		  ;
404983e9580Sangelos 	    }
405983e9580Sangelos 	    else
406983e9580Sangelos 	      if ((c = get_octal(s2, len, &advance)) != 0)
407983e9580Sangelos 	      {
408983e9580Sangelos 		  len -= advance - 1;
409983e9580Sangelos 		  s2 += advance;
410983e9580Sangelos 		  *s1++ = c;
411983e9580Sangelos 	      }
412983e9580Sangelos 	      else
413983e9580Sangelos 		if (*s2 == 'n')  /* Newline */
414983e9580Sangelos 		{
415983e9580Sangelos 		    *s1++ = '\n';
416983e9580Sangelos 		    s2++;
417983e9580Sangelos 		}
418983e9580Sangelos 		else
419983e9580Sangelos 		  if (*s2 == 't')  /* Tab */
420983e9580Sangelos 		  {
421983e9580Sangelos 		      *s1++ = '\t';
422983e9580Sangelos 		      s2++;
423983e9580Sangelos 		  }
424983e9580Sangelos 		  else
425983e9580Sangelos 		    if (*s2 == 'r')  /* Linefeed */
426983e9580Sangelos 		    {
427983e9580Sangelos 			*s1++ = '\r';
428983e9580Sangelos 			s2++;
429983e9580Sangelos 		    }
430983e9580Sangelos 		    else
431983e9580Sangelos 		      if (*s2 == 'f')  /* Formfeed */
432983e9580Sangelos 		      {
433983e9580Sangelos 			  *s1++ = '\f';
434983e9580Sangelos 			  s2++;
435983e9580Sangelos 		      }
436983e9580Sangelos 		      else
437983e9580Sangelos 			if ((*s1++ = *s2++) == 0)
438983e9580Sangelos 			  break;
439983e9580Sangelos 
440983e9580Sangelos 	    continue;
441983e9580Sangelos 	}
442983e9580Sangelos 
443983e9580Sangelos         if ((*s1++ = *s2++) == 0)
444983e9580Sangelos 	  break;
445983e9580Sangelos      }
446983e9580Sangelos }
447983e9580Sangelos 
448983e9580Sangelos /*
449983e9580Sangelos  * Evaluate an assertion, with as->as_result holding the result.
450983e9580Sangelos  * Return RESULT_TRUE if all ok. Also return the result.
451983e9580Sangelos  */
452983e9580Sangelos int
453983e9580Sangelos keynote_evaluate_assertion(struct assertion *as)
454983e9580Sangelos {
455983e9580Sangelos     YY_BUFFER_STATE keynote_bs;
456983e9580Sangelos 
4576957a4a4Sjmc     /* Non-existent Conditions field means highest return value */
458313d0fe7Smmcc     if (as->as_conditions_s == NULL)
459983e9580Sangelos     {
460983e9580Sangelos 	as->as_result = keynote_current_session->ks_values_num - 1;
461983e9580Sangelos 	return RESULT_TRUE;
462983e9580Sangelos     }
463983e9580Sangelos 
464983e9580Sangelos     if (keynote_lex_init() != RESULT_TRUE)
465983e9580Sangelos       return -1;
466983e9580Sangelos 
467983e9580Sangelos     keynote_used_variable = 0;
468983e9580Sangelos     keynote_init_list = as->as_env;     /* Setup the local-init var list */
469983e9580Sangelos 
470983e9580Sangelos     keynote_bs = kn_scan_bytes(as->as_conditions_s,
471983e9580Sangelos 			       as->as_conditions_e - as->as_conditions_s);
472983e9580Sangelos     BEGIN(ACTIONSTRING);	/* We're doing conditions-string parsing */
473983e9580Sangelos     first_tok = ACTSTR;
474983e9580Sangelos     as->as_result = 0;
475983e9580Sangelos     keynote_returnvalue = 0;
476983e9580Sangelos 
477983e9580Sangelos     switch (knparse())
478983e9580Sangelos     {
479983e9580Sangelos 	case 1:  /* Fall through */
480983e9580Sangelos 	    keynote_errno = ERROR_SYNTAX;
481983e9580Sangelos 	case -1:
482983e9580Sangelos 	    as->as_result = 0;
483983e9580Sangelos 	    break;
484983e9580Sangelos 
485983e9580Sangelos 	case 0:
486983e9580Sangelos 	    as->as_result = keynote_returnvalue;
487983e9580Sangelos 	    break;
488983e9580Sangelos     }
489983e9580Sangelos 
490983e9580Sangelos     keynote_env_cleanup(&keynote_temp_list, 1);
491983e9580Sangelos     keynote_lex_zap();
4929186b70cSangelos     kn_delete_buffer(keynote_bs);
493983e9580Sangelos 
494983e9580Sangelos     keynote_used_variable = 0;
495983e9580Sangelos     keynote_returnvalue = 0;
496313d0fe7Smmcc     keynote_temp_list = NULL;
497313d0fe7Smmcc     keynote_init_list = NULL;
498983e9580Sangelos 
499983e9580Sangelos     if (keynote_errno != 0)
500983e9580Sangelos       return -1;
501983e9580Sangelos     else
502983e9580Sangelos       return RESULT_TRUE;
503983e9580Sangelos }
504983e9580Sangelos 
505983e9580Sangelos /*
506983e9580Sangelos  * Parse/evaluate a key predicate field.
507bdbb5d20Sangelos  * Store keys in key predicate as keylist in as->as_keylist, if second
508983e9580Sangelos  * argument is true.
509983e9580Sangelos  */
510983e9580Sangelos int
511983e9580Sangelos keynote_parse_keypred(struct assertion *as, int record)
512983e9580Sangelos {
513983e9580Sangelos     YY_BUFFER_STATE keypred_state;
514983e9580Sangelos     int p = 0, err;
515983e9580Sangelos 
516313d0fe7Smmcc     if (as->as_keypred_s == NULL)
517983e9580Sangelos       return keynote_current_session->ks_values_num - 1;
518983e9580Sangelos 
519983e9580Sangelos     if (keynote_lex_init() != RESULT_TRUE)
520983e9580Sangelos       return -1;
521983e9580Sangelos 
522983e9580Sangelos     keynote_used_variable = 0;
523983e9580Sangelos     keynote_returnvalue = 0;
524983e9580Sangelos     keynote_justrecord = record; /* Just want the list of keys in predicate */
525983e9580Sangelos     keynote_init_list = as->as_env;
526983e9580Sangelos 
527983e9580Sangelos     keypred_state = kn_scan_bytes(as->as_keypred_s,
528983e9580Sangelos 				  as->as_keypred_e - as->as_keypred_s);
529983e9580Sangelos     BEGIN(KEYPREDICATE);
530983e9580Sangelos     first_tok = KEYPRE;
531983e9580Sangelos 
532983e9580Sangelos     err = knparse();
533983e9580Sangelos     if (err != 0)
534983e9580Sangelos       if (keynote_errno == 0)
535983e9580Sangelos 	keynote_errno = ERROR_SYNTAX;
536983e9580Sangelos 
5379186b70cSangelos     kn_delete_buffer(keypred_state);
538983e9580Sangelos     keynote_lex_zap();
539983e9580Sangelos     keynote_cleanup_kth();
540983e9580Sangelos 
541313d0fe7Smmcc     keynote_init_list = NULL;
542983e9580Sangelos     keynote_justrecord = 0;
543983e9580Sangelos     p = keynote_returnvalue;
544983e9580Sangelos     keynote_returnvalue = 0;
545983e9580Sangelos 
546983e9580Sangelos     if (record)
547983e9580Sangelos     {
548983e9580Sangelos 	if (keynote_errno != 0)
549983e9580Sangelos 	{
550983e9580Sangelos 	    keynote_keylist_free(keynote_keypred_keylist);
551313d0fe7Smmcc 	    keynote_keypred_keylist = NULL;
552983e9580Sangelos 	    return -1;
553983e9580Sangelos 	}
554983e9580Sangelos 	else
555983e9580Sangelos 	{
556983e9580Sangelos 	    /* Mark for re-processing if/when environment changes */
557983e9580Sangelos 	    if (keynote_used_variable)
558983e9580Sangelos 	    {
559983e9580Sangelos 		keynote_used_variable = 0;
560983e9580Sangelos 		as->as_internalflags |= ASSERT_IFLAG_WEIRDLICS;
561983e9580Sangelos 	    }
562983e9580Sangelos 
563bdbb5d20Sangelos 	    if (as->as_keylist)
564bdbb5d20Sangelos               keynote_keylist_free(as->as_keylist);
565983e9580Sangelos 	    as->as_keylist = keynote_keypred_keylist;
566313d0fe7Smmcc 	    keynote_keypred_keylist = NULL;
567983e9580Sangelos 	    return RESULT_TRUE;
568983e9580Sangelos 	}
569983e9580Sangelos     }
570983e9580Sangelos     else
571983e9580Sangelos       return p;
572983e9580Sangelos }
573983e9580Sangelos 
574983e9580Sangelos /* Evaluate an authorizer or signature field. Return RESULT_TRUE on success.
575983e9580Sangelos  * Store key in as->as_authorizer. Second argument is set only for Authorizer
576983e9580Sangelos  * field parsing.
577983e9580Sangelos  */
578983e9580Sangelos int
579983e9580Sangelos keynote_evaluate_authorizer(struct assertion *as, int flag)
580983e9580Sangelos {
581983e9580Sangelos     YY_BUFFER_STATE authorizer_state;
582983e9580Sangelos     int err;
583983e9580Sangelos 
584983e9580Sangelos     if (keynote_lex_init() != RESULT_TRUE)
585983e9580Sangelos       return -1;
586983e9580Sangelos 
587983e9580Sangelos     keynote_init_list = as->as_env;
588983e9580Sangelos     keynote_justrecord = 1;
589983e9580Sangelos     keynote_used_variable = 0;
590983e9580Sangelos 
591313d0fe7Smmcc     if ((flag) && (as->as_authorizer != NULL))
592983e9580Sangelos     {
593983e9580Sangelos 	keynote_free_key(as->as_authorizer, as->as_signeralgorithm);
594313d0fe7Smmcc 	as->as_authorizer = NULL;
595983e9580Sangelos     }
596983e9580Sangelos 
597983e9580Sangelos     if (flag)
598983e9580Sangelos       authorizer_state = kn_scan_bytes(as->as_authorizer_string_s,
599983e9580Sangelos 				       as->as_authorizer_string_e -
600983e9580Sangelos 				       as->as_authorizer_string_s);
601983e9580Sangelos     else
602983e9580Sangelos       authorizer_state = kn_scan_bytes(as->as_signature_string_s,
603983e9580Sangelos 				       as->as_signature_string_e -
604983e9580Sangelos 				       as->as_signature_string_s);
605983e9580Sangelos 
606983e9580Sangelos     BEGIN(SIGNERINIT);
607983e9580Sangelos     if (flag)
608983e9580Sangelos       first_tok = SIGNERKEY;
609983e9580Sangelos     else
610983e9580Sangelos       first_tok = SIGNATUREENTRY;
611983e9580Sangelos 
612983e9580Sangelos     err = knparse();
613983e9580Sangelos     if ((err != 0) && (keynote_errno == 0))
614983e9580Sangelos       keynote_errno = ERROR_SYNTAX;
615983e9580Sangelos 
6169186b70cSangelos     kn_delete_buffer(authorizer_state);
617983e9580Sangelos     keynote_lex_zap();
618983e9580Sangelos 
619983e9580Sangelos     keynote_justrecord = 0;
620313d0fe7Smmcc     keynote_init_list = NULL;
621983e9580Sangelos     keynote_returnvalue = 0;
622983e9580Sangelos 
623313d0fe7Smmcc     if (keynote_keypred_keylist != NULL)
624983e9580Sangelos     {
625983e9580Sangelos 	if (flag)
626983e9580Sangelos 	{
627983e9580Sangelos 	    if (keynote_used_variable)
628983e9580Sangelos 	      as->as_internalflags |= ASSERT_IFLAG_WEIRDAUTH;
629983e9580Sangelos 
630983e9580Sangelos 	    as->as_authorizer = keynote_keypred_keylist->key_key;
631983e9580Sangelos 	    as->as_signeralgorithm = keynote_keypred_keylist->key_alg;
632983e9580Sangelos 	}
633983e9580Sangelos 	else
634983e9580Sangelos 	{
635983e9580Sangelos 	    if (keynote_used_variable)
636983e9580Sangelos 	      as->as_internalflags |= ASSERT_IFLAG_WEIRDSIG;
637983e9580Sangelos 
638983e9580Sangelos 	    as->as_signature = keynote_keypred_keylist->key_key;
639983e9580Sangelos 	}
640983e9580Sangelos 
641313d0fe7Smmcc 	keynote_keypred_keylist->key_key = NULL;
642983e9580Sangelos 	keynote_keylist_free(keynote_keypred_keylist);
643313d0fe7Smmcc 	keynote_keypred_keylist = NULL;
644983e9580Sangelos     }
645983e9580Sangelos 
646983e9580Sangelos     keynote_used_variable = 0;
647983e9580Sangelos 
648983e9580Sangelos     if (keynote_errno != 0)
649983e9580Sangelos       return -1;
650983e9580Sangelos     else
651983e9580Sangelos       return RESULT_TRUE;
652983e9580Sangelos }
653983e9580Sangelos 
654983e9580Sangelos /*
655c5ba4a6fSangelos  * Exportable front-end to keynote_get_private_key().
656c5ba4a6fSangelos  */
657c5ba4a6fSangelos char *
658c5ba4a6fSangelos kn_get_string(char *buf)
659c5ba4a6fSangelos {
660c5ba4a6fSangelos     return keynote_get_private_key(buf);
661c5ba4a6fSangelos }
662c5ba4a6fSangelos 
663c5ba4a6fSangelos /*
664c5ba4a6fSangelos  * Parse a private key -- actually, it can deal with any kind of string.
665983e9580Sangelos  */
666983e9580Sangelos char *
667983e9580Sangelos keynote_get_private_key(char *buf)
668983e9580Sangelos {
669983e9580Sangelos     YY_BUFFER_STATE pkey;
670983e9580Sangelos     char *s;
671983e9580Sangelos     int err;
672983e9580Sangelos 
673983e9580Sangelos     if (keynote_lex_init() != RESULT_TRUE)
674313d0fe7Smmcc       return NULL;
675983e9580Sangelos 
676313d0fe7Smmcc     keynote_privkey = NULL;
677983e9580Sangelos     pkey = kn_scan_bytes(buf, strlen(buf));
678983e9580Sangelos     first_tok = PRIVATEKEY;
679983e9580Sangelos     err = knparse();
680983e9580Sangelos     kn_delete_buffer(pkey);
681983e9580Sangelos     keynote_lex_zap();
682983e9580Sangelos 
683983e9580Sangelos     if (err != 0)
684983e9580Sangelos     {
685313d0fe7Smmcc 	if (keynote_privkey != NULL)
686983e9580Sangelos 	{
687983e9580Sangelos 	    free(keynote_privkey);
688313d0fe7Smmcc 	    keynote_privkey = NULL;
689983e9580Sangelos 	}
690983e9580Sangelos 
691983e9580Sangelos 	if (keynote_errno == 0)
692983e9580Sangelos 	  keynote_errno = ERROR_SYNTAX;
693983e9580Sangelos 
694313d0fe7Smmcc 	return NULL;
695983e9580Sangelos     }
696983e9580Sangelos 
697983e9580Sangelos     s = keynote_privkey;
698313d0fe7Smmcc     keynote_privkey = NULL;
699983e9580Sangelos     return s;
700983e9580Sangelos }
701983e9580Sangelos 
702983e9580Sangelos /*
703983e9580Sangelos  * Parse Local-Constants and KeyNote-Version fields.
704983e9580Sangelos  */
705983e9580Sangelos struct environment *
706983e9580Sangelos keynote_get_envlist(char *buf, char *bufend, int whichfield)
707983e9580Sangelos {
708313d0fe7Smmcc     struct environment *en = NULL;
709983e9580Sangelos     YY_BUFFER_STATE localinit_state;
710983e9580Sangelos     int err;
711983e9580Sangelos 
712983e9580Sangelos     if (keynote_lex_init() != RESULT_TRUE)
713313d0fe7Smmcc       return NULL;
714983e9580Sangelos 
715983e9580Sangelos     localinit_state = kn_scan_bytes(buf, bufend - buf);
716983e9580Sangelos     if (whichfield == 0)
717983e9580Sangelos     {
718983e9580Sangelos 	BEGIN(LOCALINIT);	/* We're doing Local-Constants parsing */
719983e9580Sangelos 	first_tok = LOCINI;
720983e9580Sangelos     }
721983e9580Sangelos     else
722983e9580Sangelos     {
723983e9580Sangelos 	BEGIN(KEYNOTEVERSION);	/* KeyNote-Version parsing */
724983e9580Sangelos       	first_tok = KNVERSION;
725983e9580Sangelos     }
726983e9580Sangelos 
727983e9580Sangelos     err = knparse();
728983e9580Sangelos     if (err != 0)
729983e9580Sangelos       if (keynote_errno == 0)
730983e9580Sangelos 	keynote_errno = ERROR_SYNTAX;
731983e9580Sangelos 
732983e9580Sangelos     kn_delete_buffer(localinit_state);
733983e9580Sangelos     keynote_lex_zap();
734983e9580Sangelos 
735983e9580Sangelos     if (!whichfield)
736983e9580Sangelos     {
737983e9580Sangelos 	if (keynote_errno != 0)
738983e9580Sangelos 	  keynote_env_cleanup(&keynote_init_list, 1);
739983e9580Sangelos 	else
740983e9580Sangelos 	  en = keynote_init_list;
741983e9580Sangelos 
742313d0fe7Smmcc     	keynote_init_list = NULL;
743983e9580Sangelos     }
744983e9580Sangelos 
7454812cf71Sangelos     /* Avoid compiler (-Wall) warnings. Never reached. */
7464812cf71Sangelos     if (0)
7474812cf71Sangelos     {
7484812cf71Sangelos 	yyunput(0, NULL);
7494812cf71Sangelos     }
7504812cf71Sangelos 
751983e9580Sangelos     return en;
752983e9580Sangelos }
753