1 %{ 2 /* $OpenBSD: keynote-ver.l,v 1.19 2015/12/23 23:55:30 mmcc 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 == NULL) { 54 keynote_errno = ERROR_MEMORY; 55 return -1; 56 } 57 strlcpy(kvlval.s.string, kvtext, len); 58 BEGIN(MIDDLEPART); 59 return VSTRING; 60 } 61 <KEYSTATE,SECONDPART>{litstring} { kvlval.s.string = calloc(strlen(kvtext) - 1, 62 sizeof(char)); 63 if (kvlval.s.string == NULL) { 64 keynote_errno = ERROR_MEMORY; 65 return -1; 66 } 67 mystrncpy(kvlval.s.string, kvtext + 1, 68 strlen(kvtext) - 2); 69 BEGIN(FIRSTPART); 70 return STRING; 71 } 72 <FIRSTPART,KEYSTATE>{comment} ; 73 [ \t\n] ; 74 . { keynote_errno = ERROR_SYNTAX; return -1; REJECT; } 75 76 %% 77 78 /* 79 * Return RESULT_TRUE if character is octal digit, RESULT_FALSE otherwise. 80 */ 81 static int 82 is_octal(char c) 83 { 84 switch (c) 85 { 86 case '0': case '1': case '2': case '3': 87 case '4': case '5': case '6': case '7': 88 return RESULT_TRUE; 89 90 default: 91 return RESULT_FALSE; 92 } 93 } 94 95 /* 96 * Return octal value (non-zero) if argument starts with such a 97 * representation, otherwise 0. 98 */ 99 static unsigned char 100 get_octal(char *s, int len, int *adv) 101 { 102 unsigned char res = 0; 103 104 if (*s == '0') 105 { 106 if (len > 0) 107 { 108 if (is_octal(*(s + 1))) 109 { 110 res = *(s + 1) - '0'; 111 *adv = 2; 112 113 if (is_octal(*(s + 2)) && (len - 1 > 0)) 114 { 115 res = res * 8 + (*(s + 2) - '0'); 116 *adv = 3; 117 } 118 } 119 } 120 } 121 else 122 if (is_octal(*s) && (len - 1 > 0)) /* Non-zero leading */ 123 { 124 if (is_octal(*(s + 1)) && 125 is_octal(*(s + 2))) 126 { 127 *adv = 3; 128 res = (((*s) - '0') * 64) + 129 (((*(s + 1)) - '0') * 8) + 130 ((*(s + 2)) - '0'); 131 } 132 } 133 134 return res; 135 } 136 137 /* 138 * Copy at most len characters to string s1 from string s2, taking 139 * care of escaped characters in the process. String s1 is assumed 140 * to have enough space, and be zero'ed. 141 */ 142 void 143 mystrncpy(char *s1, char *s2, int len) 144 { 145 unsigned char c; 146 int advance; 147 148 if (len == 0) 149 return; 150 151 while (len-- > 0) 152 { 153 if (*s2 == '\\') 154 { 155 s2++; 156 157 if (len-- <= 0) 158 break; 159 160 if (*s2 == '\n') 161 { 162 while (isspace((unsigned char)*(++s2)) && (len-- > 0)) 163 ; 164 } 165 else 166 if ((c = get_octal(s2, len, &advance)) != 0) 167 { 168 len -= advance - 1; 169 s2 += advance; 170 *s1++ = c; 171 } 172 else 173 if (*s2 == 'n') /* Newline */ 174 { 175 *s1++ = '\n'; 176 s2++; 177 } 178 else 179 if (*s2 == 't') /* Tab */ 180 { 181 *s1++ = '\t'; 182 s2++; 183 } 184 else 185 if (*s2 == 'r') /* Linefeed */ 186 { 187 *s1++ = '\r'; 188 s2++; 189 } 190 else 191 if (*s2 == 'f') /* Formfeed */ 192 { 193 *s1++ = '\f'; 194 s2++; 195 } 196 else 197 if ((*s1++ = *s2++) == 0) 198 break; 199 200 continue; 201 } 202 203 if ((*s1++ = *s2++) == 0) 204 break; 205 } 206 } 207 208 /* 209 * Parse a file that contains environment variable/value pairs. 210 * Return -1 on failure. 211 */ 212 int 213 read_environment(char *filename) 214 { 215 YY_BUFFER_STATE kvfoo; 216 FILE *fp; 217 int i; 218 219 if ((fp = fopen(filename, "r")) == NULL) { 220 perror(filename); 221 return -1; 222 } 223 224 kvfoo = kv_create_buffer(fp, YY_BUF_SIZE); 225 kv_switch_to_buffer(kvfoo); 226 BEGIN(FIRSTPART); 227 i = kvparse(); 228 kv_delete_buffer(kvfoo); 229 fclose(fp); 230 switch (i) 231 { 232 case 0: 233 return 0; 234 235 default: 236 if (keynote_errno == ERROR_MEMORY) 237 fprintf(stderr, 238 "Memory error while processing environment file <%s>\n", 239 filename); 240 else 241 fprintf(stderr, 242 "Syntax error in environment file <%s>, line %d\n", 243 filename, kvlineno); 244 return -1; 245 } 246 247 /* Used to avoid compiler (-Wall) warnings. Never reached */ 248 if (0) 249 { 250 yyunput(0, NULL); 251 } 252 } 253 254 /* 255 * Parse a key. 256 */ 257 void 258 parse_key(char *buf) 259 { 260 YY_BUFFER_STATE key_state; 261 int err; 262 263 key_state = kv_scan_string(buf); 264 BEGIN(KEYSTATE); 265 err = kvparse(); 266 kv_delete_buffer(key_state); 267 268 if (err != 0) 269 if (keynote_errno == 0) 270 keynote_errno = ERROR_SYNTAX; 271 } 272