%array /* force yytext to be an array; Solaris lex requires this first */ %{ /* ** Copyright (C) 2005-2007 by Carnegie Mellon University. ** ** @OPENSOURCE_HEADER_START@ ** ** Use of the SILK system and related source code is subject to the terms ** of the following licenses: ** ** GNU Public License (GPL) Rights pursuant to Version 2, June 1991 ** Government Purpose License Rights (GPLR) pursuant to DFARS 252.225-7013 ** ** NO WARRANTY ** ** ANY INFORMATION, MATERIALS, SERVICES, INTELLECTUAL PROPERTY OR OTHER ** PROPERTY OR RIGHTS GRANTED OR PROVIDED BY CARNEGIE MELLON UNIVERSITY ** PURSUANT TO THIS LICENSE (HEREINAFTER THE "DELIVERABLES") ARE ON AN ** "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY ** KIND, EITHER EXPRESS OR IMPLIED AS TO ANY MATTER INCLUDING, BUT NOT ** LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE, ** MERCHANTABILITY, INFORMATIONAL CONTENT, NONINFRINGEMENT, OR ERROR-FREE ** OPERATION. CARNEGIE MELLON UNIVERSITY SHALL NOT BE LIABLE FOR INDIRECT, ** SPECIAL OR CONSEQUENTIAL DAMAGES, SUCH AS LOSS OF PROFITS OR INABILITY ** TO USE SAID INTELLECTUAL PROPERTY, UNDER THIS LICENSE, REGARDLESS OF ** WHETHER SUCH PARTY WAS AWARE OF THE POSSIBILITY OF SUCH DAMAGES. ** LICENSEE AGREES THAT IT WILL NOT MAKE ANY WARRANTY ON BEHALF OF ** CARNEGIE MELLON UNIVERSITY, EXPRESS OR IMPLIED, TO ANY PERSON ** CONCERNING THE APPLICATION OF OR THE RESULTS TO BE OBTAINED WITH THE ** DELIVERABLES UNDER THIS LICENSE. ** ** Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie ** Mellon University, its trustees, officers, employees, and agents from ** all claims or demands made against them (and any related losses, ** expenses, or attorney's fees) arising out of, or relating to Licensee's ** and/or its sub licensees' negligent use or willful misuse of or ** negligent conduct or willful misconduct regarding the Software, ** facilities, or other rights or assistance granted by Carnegie Mellon ** University under this License, including, but not limited to, any ** claims of product liability, personal injury, death, damage to ** property, or violation of any laws or regulations. ** ** Carnegie Mellon University Software Engineering Institute authored ** documents are sponsored by the U.S. Department of Defense under ** Contract F19628-00-C-0003. Carnegie Mellon University retains ** copyrights in all material produced under this contract. The U.S. ** Government retains a non-exclusive, royalty-free license to publish or ** reproduce these documents, or allow others to do so, for U.S. ** Government purposes only pursuant to the copyright license under the ** contract clause at 252.227.7013. ** ** @OPENSOURCE_HEADER_END@ */ /* ** Tokenizer for probe configuration file. ** */ #include "silk.h" RCSIDENT("$SiLK: probeconfscan.l 7569 2007-06-18 16:08:47Z mthomas $"); #include "probeconfscan.h" #include "probeconfparse.h" /* EXPORTED VARIABLES */ /* current file name */ const char *probescan_filename; /* Global error count for return status of probeConfParse */ int g_probe_err; /* current line number */ int probescan_line; /* keyword we read; for printing messages in the parser. */ char probescan_clause[128]; /* LOCAL FUNCTIONS */ static int stash(int tok); static int ifname_to_tok(void); static void err_bad_line(int is_id); %} %option noyywrap never-interactive %option prefix="probeconfscan_" outfile="lex.yy.c" /* create a state that says we have read a keyword and are parsing a * clause */ %s CLAUSE /* create a state for an unrecognized keyword */ %s BADLINE /* basic character classes */ idchar [-._/A-Za-z0-9] notidchar [^-._/A-Za-z0-9\n] /* an ID must have at least one non-number character; note that this * must also match hostnames and IP addresses */ id [-._/A-Za-z0-9]+ /* comment; ignore, and increment line count */ comment (#.*\n) /* whitespace; we ignore it */ ws [ \t\r]+ /* end of line; increment line count */ nl \n %% {ws} ; {comment} { ++probescan_line; BEGIN(INITIAL); } {comment} { ++probescan_line; BEGIN(INITIAL); return EOL; } {nl} { ++probescan_line; BEGIN(INITIAL); } {nl} { ++probescan_line; BEGIN(INITIAL); return EOL; } {id}-interfaces?{notidchar} | {id}-index{notidchar} | {id}-indexes{notidchar} { if (ifname_to_tok()) { return INTERFACE; } else { BEGIN(BADLINE); yyless(0); } } {id}-ipblocks?{notidchar} { if (ifname_to_tok()) { return IPBLOCK; } else { BEGIN(BADLINE); yyless(0); } } accept-from-host{notidchar} { return stash(ACCEPT_FROM_HOST_T); } class{notidchar} | classes{notidchar} { return stash(CLASS_T); } isp-ips?{notidchar} { return stash(ISP_IP_T); } listen-as-host{notidchar} { return stash(LISTEN_AS_HOST_T); } listen-on-port{notidchar} { return stash(LISTEN_ON_PORT_T); } listen-on-unix-domain-socket{notidchar} | listen-on-unix-socket{notidchar} { return stash(LISTEN_ON_USOCKET_T);} log-flags{notidchar} { return stash(LOG_FLAGS_T); } poll-directory{notidchar} { return stash(POLL_DIRECTORY_T); } priority{notidchar} { return stash(PRIORITY_T); } probe-name{notidchar} { return stash(PROBE_NAME_T); } probe-type{notidchar} { return stash(PROBE_TYPE_T); } protocol{notidchar} { return stash(PROTOCOL_T); } read-from-file{notidchar} { return stash(READ_FROM_FILE_T); } sensor-probe{notidchar} { return stash(SENSOR_PROBE_T); } sensor{notidchar} { return stash(SENSOR_T); } . { BEGIN(BADLINE); yyless(0); } remainder { return REMAINDER_T; } {id} { yylval.string = yytext; return ID; } "," { return COMMA; } {idchar}.+ { err_bad_line(1); } {notidchar}.+ { err_bad_line(0); } . { /* unknown */ return yytext[0]; } %% /* * stash(int) * * Stash the current keyword (using the yyleng and yytext * globals), put us into a CLAUSE start-state, and return the * value we were passed. */ static int stash(int tok) { /* make certain the keyword fits in our buffer */ assert(yyleng < ((int)sizeof(probescan_clause))); /* copy it in */ strcpy(probescan_clause, yytext); /* remember we got an extra character, so terminate the keyword a * character earlier, and unput that character */ probescan_clause[yyleng-1] = '\0'; unput(yytext[yyleng-1]); /* we're starting a clause */ BEGIN(CLAUSE); /* return whatever we were passed */ return tok; } /* * found_an_id = ifname_to_tok(); * * Called when the scanner reads an -interface, -index, * or -ipblock line. This function checks if is a known * ifmap_group_id_name. If it is, yylval is set to the * ifmap_group_id and 1 is returned. When not found, 0 is * returned. * * When called, 'yytext' contains the entire -index phrase. */ static int ifname_to_tok(void) { static int len[NUM_IFMAPS]; size_t i; int found_it = 0; /* Keep a static structure of string lengths since we use this * often. */ if (!len[0]) { for (i = 0; i < NUM_IFMAPS; ++i) { len[i] = (int)strlen(ifmap_group_id_name[i]); } } /* Compare the names */ for (i = 0; i < NUM_IFMAPS; ++i) { if ((yyleng > len[i]) && (yytext[(len[i])] == '-') && (0 == strncmp(ifmap_group_id_name[i], yytext, len[i]))) { yylval.u32 = i; found_it = 1; break; } } /* Return if not found */ if ( !found_it) { goto END; } /* make certain the keyword fits in our buffer */ assert(yyleng < ((int)sizeof(probescan_clause))); /* copy it in */ strcpy(probescan_clause, yytext); /* remember we got an extra character, so terminate the keyword a * character earlier, and unput that character */ probescan_clause[yyleng-1] = '\0'; unput(yytext[yyleng-1]); /* we're starting a clause */ BEGIN(CLAUSE); /* return result of looking for token */ END: return found_it; } /* * err_bad_line(is_id); * * Called when the scanner reads a bad line of input. This * function prints an error and increases the global error count. * * If 'is_id' is 0, we have a single uknown character; otherwise we * have a bad keyword. At this point yytext holds the entire bad * line. */ static void err_bad_line(int is_id) { size_t i; /* Make sure the parser lets the application know that things failed. */ ++g_probe_err; /* Handle a bad character; this is easy */ if (is_id == 0) { skAppPrintErr((PARSE_MSG_ERROR "\tUnexpected character '%c'"), probescan_filename, probescan_line, yytext[0]); return; } /* Handle a bad keyword. Copy the first keyword into * probescan_clause[] so we can print it. */ for (i = 0; i < sizeof(probescan_clause)-1; ++i) { /* This switch has the same character classes as our {idchar}. */ switch (yytext[i]) { case '\0': goto END_WORD; case '-': case '.': case '_': case '/': probescan_clause[i] = yytext[i]; break; default: if (isalnum((int)yytext[i])) { probescan_clause[i] = yytext[i]; } else { goto END_WORD; } break; } } END_WORD: probescan_clause[i] = '\0'; skAppPrintErr((PARSE_MSG_ERROR "\tUnrecognized keyword '%s'"), probescan_filename, probescan_line, probescan_clause); } int probeConfParse(const char *filename) { YY_BUFFER_STATE yybuf = ((YY_BUFFER_STATE)0); if (filename == NULL) { return -1; } /* clear the error count */ g_probe_err = 0; /* open the file */ probescan_filename = filename; if (0 == strcmp(probescan_filename, "stdin")) { yyin = stdin; } else if (!fileExists(probescan_filename)) { skAppPrintErr("'%s' does not exist or is not a regular file", probescan_filename); return -1; } else { yyin = fopen(probescan_filename, "r"); if (!yyin) { skAppPrintErr("Cannot open file '%s'", probescan_filename); return -1; } } /* set line number */ probescan_line = 1; /* set up scanner */ yybuf = yy_create_buffer(yyin, YY_BUF_SIZE); yy_switch_to_buffer(yybuf); BEGIN(INITIAL); /* setup the probe */ probe_start(); /* parse */ while (!feof(yyin)) { yyparse(); } /* force output of last probe */ probe_end(); /* close */ if (yyin != stdin) { fclose(yyin); } yy_delete_buffer(yybuf); /* return non-zero if we had errors */ if (g_probe_err > 0) { return -1; } return 0; } /* ** Local Variables: ** mode:c ** indent-tabs-mode:nil ** c-basic-offset:4 ** End: */