1 %{ 2 /* $OpenBSD: keynote-ver.l,v 1.16 2013/11/29 19:00:51 deraadt Exp $ */ 3 /* 4 * The author of this code is Angelos D. Keromytis (angelos@dsl.cis.upenn.edu) 5 * 6 * This code was written by Angelos D. Keromytis in Philadelphia, PA, USA, 7 * in April-May 1998 8 * 9 * Copyright (C) 1998, 1999 by Angelos D. Keromytis. 10 * 11 * Permission to use, copy, and modify this software with or without fee 12 * is hereby granted, provided that this entire notice is included in 13 * all copies of any software which is or includes a copy or 14 * modification of this software. 15 * 16 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTY. IN PARTICULAR, THE AUTHORS MAKES NO 18 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 19 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 20 * PURPOSE. 21 */ 22 23 #include <sys/time.h> 24 #include <sys/types.h> 25 26 #include <ctype.h> 27 #include <regex.h> 28 #include <string.h> 29 #include <time.h> 30 #include <unistd.h> 31 32 #include "z.tab.h" 33 #include "header.h" 34 #include "keynote.h" 35 36 static void mystrncpy(char *, char *, int); 37 %} 38 vstring [a-zA-Z0-9][a-zA-Z0-9_]* 39 litstring \"(((\\\n)|(\\.)|(\\\\)|([^\\\n\"]))*)\" 40 comment "#"[^\n]* 41 %s FIRSTPART MIDDLEPART SECONDPART KEYSTATE 42 %pointer 43 %option noyywrap yylineno never-interactive 44 %% 45 46 <MIDDLEPART>"=" { 47 BEGIN(SECONDPART); 48 return EQ; 49 } 50 <FIRSTPART>{vstring} { 51 int len = strlen(kvtext) + 1; 52 kvlval.s.string = calloc(len, sizeof(char)); 53 if (kvlval.s.string == (char *) NULL) 54 { 55 keynote_errno = ERROR_MEMORY; 56 return -1; 57 } 58 strlcpy(kvlval.s.string, kvtext, len); 59 BEGIN(MIDDLEPART); 60 return VSTRING; 61 } 62 <KEYSTATE,SECONDPART>{litstring} { kvlval.s.string = calloc(strlen(kvtext) - 1, 63 sizeof(char)); 64 if (kvlval.s.string == (char *) NULL) 65 { 66 keynote_errno = ERROR_MEMORY; 67 return -1; 68 } 69 mystrncpy(kvlval.s.string, kvtext + 1, 70 strlen(kvtext) - 2); 71 BEGIN(FIRSTPART); 72 return STRING; 73 } 74 <FIRSTPART,KEYSTATE>{comment} ; 75 [ \t\n] ; 76 . { keynote_errno = ERROR_SYNTAX; return -1; REJECT; } 77 78 %% 79 80 /* 81 * Return RESULT_TRUE if character is octal digit, RESULT_FALSE otherwise. 82 */ 83 static int 84 is_octal(char c) 85 { 86 switch (c) 87 { 88 case '0': case '1': case '2': case '3': 89 case '4': case '5': case '6': case '7': 90 return RESULT_TRUE; 91 92 default: 93 return RESULT_FALSE; 94 } 95 } 96 97 /* 98 * Return octal value (non-zero) if argument starts with such a 99 * representation, otherwise 0. 100 */ 101 static unsigned char 102 get_octal(char *s, int len, int *adv) 103 { 104 unsigned char res = 0; 105 106 if (*s == '0') 107 { 108 if (len > 0) 109 { 110 if (is_octal(*(s + 1))) 111 { 112 res = *(s + 1) - '0'; 113 *adv = 2; 114 115 if (is_octal(*(s + 2)) && (len - 1 > 0)) 116 { 117 res = res * 8 + (*(s + 2) - '0'); 118 *adv = 3; 119 } 120 } 121 } 122 } 123 else 124 if (is_octal(*s) && (len - 1 > 0)) /* Non-zero leading */ 125 { 126 if (is_octal(*(s + 1)) && 127 is_octal(*(s + 2))) 128 { 129 *adv = 3; 130 res = (((*s) - '0') * 64) + 131 (((*(s + 1)) - '0') * 8) + 132 ((*(s + 2)) - '0'); 133 } 134 } 135 136 return res; 137 } 138 139 /* 140 * Copy at most len characters to string s1 from string s2, taking 141 * care of escaped characters in the process. String s1 is assumed 142 * to have enough space, and be zero'ed. 143 */ 144 void 145 mystrncpy(char *s1, char *s2, int len) 146 { 147 unsigned char c; 148 int advance; 149 150 if (len == 0) 151 return; 152 153 while (len-- > 0) 154 { 155 if (*s2 == '\\') 156 { 157 s2++; 158 159 if (len-- <= 0) 160 break; 161 162 if (*s2 == '\n') 163 { 164 while (isspace((unsigned char)*(++s2)) && (len-- > 0)) 165 ; 166 } 167 else 168 if ((c = get_octal(s2, len, &advance)) != 0) 169 { 170 len -= advance - 1; 171 s2 += advance; 172 *s1++ = c; 173 } 174 else 175 if (*s2 == 'n') /* Newline */ 176 { 177 *s1++ = '\n'; 178 s2++; 179 } 180 else 181 if (*s2 == 't') /* Tab */ 182 { 183 *s1++ = '\t'; 184 s2++; 185 } 186 else 187 if (*s2 == 'r') /* Linefeed */ 188 { 189 *s1++ = '\r'; 190 s2++; 191 } 192 else 193 if (*s2 == 'f') /* Formfeed */ 194 { 195 *s1++ = '\f'; 196 s2++; 197 } 198 else 199 if ((*s1++ = *s2++) == 0) 200 break; 201 202 continue; 203 } 204 205 if ((*s1++ = *s2++) == 0) 206 break; 207 } 208 } 209 210 /* 211 * Parse a file that contains environment variable/value pairs. 212 * Return -1 on failure. 213 */ 214 int 215 read_environment(char *filename) 216 { 217 YY_BUFFER_STATE kvfoo; 218 FILE *fp; 219 int i; 220 221 fp = fopen(filename, "r"); 222 if (fp == (FILE *) NULL) 223 { 224 perror(filename); 225 return -1; 226 } 227 228 kvfoo = kv_create_buffer(fp, YY_BUF_SIZE); 229 kv_switch_to_buffer(kvfoo); 230 BEGIN(FIRSTPART); 231 i = kvparse(); 232 kv_delete_buffer(kvfoo); 233 fclose(fp); 234 switch (i) 235 { 236 case 0: 237 return 0; 238 239 default: 240 if (keynote_errno == ERROR_MEMORY) 241 fprintf(stderr, 242 "Memory error while processing environment file <%s>\n", 243 filename); 244 else 245 fprintf(stderr, 246 "Syntax error in environment file <%s>, line %d\n", 247 filename, kvlineno); 248 return -1; 249 } 250 251 /* Used to avoid compiler (-Wall) warnings. Never reached */ 252 if (0) 253 { 254 yyunput(0, NULL); 255 yy_flex_realloc(0, 0); 256 } 257 } 258 259 /* 260 * Parse a key. 261 */ 262 void 263 parse_key(char *buf) 264 { 265 YY_BUFFER_STATE key_state; 266 int err; 267 268 key_state = kv_scan_string(buf); 269 BEGIN(KEYSTATE); 270 err = kvparse(); 271 kv_delete_buffer(key_state); 272 273 if (err != 0) 274 if (keynote_errno == 0) 275 keynote_errno = ERROR_SYNTAX; 276 } 277