static int handle_option(int letter, int options) { switch(letter) { case -1: help(); exit(0); case 'c': count_only = TRUE; break; case 'h': filenames = FALSE; break; case 'i': options |= PCRE_CASELESS; break; case 'l': filenames_only = TRUE; break; case 'L': filenames_nomatch_only = TRUE; break; case 'M': multiline = TRUE; options |= PCRE_MULTILINE|PCRE_FIRSTLINE; break; case 'n': number = TRUE; break; case 'q': quiet = TRUE; break; case 'r': recurse = TRUE; break; case 's': silent = TRUE; break; case 'u': options |= PCRE_UTF8; break; case 'v': invert = TRUE; break; case 'w': word_match = TRUE; break; case 'x': whole_lines = TRUE; break; case 'V': fprintf(stderr, "pcregrep version %s using ", VERSION); fprintf(stderr, "PCRE version %s\n", pcre_version()); exit(0); break; default: fprintf(stderr, "pcregrep: Unknown option -%c\n", letter); exit(usage(2)); } return options; }
void sl_init_regexp(sl_vm_t* vm) { vm->lib.Regexp = sl_define_class(vm, "Regexp", vm->lib.Object); sl_class_set_allocator(vm, vm->lib.Regexp, allocate_regexp); vm->lib.Regexp_Match = sl_define_class3(vm, sl_intern(vm, "Match"), vm->lib.Object, vm->lib.Regexp); sl_class_set_allocator(vm, vm->lib.Regexp_Match, allocate_regexp_match); sl_define_method(vm, vm->lib.Regexp, "init", -2, sl_regexp_init); /* sl_define_method(vm, vm->lib.Regexp, "compile", 0, sl_regexp_compile); */ sl_define_method(vm, vm->lib.Regexp, "match", -2, sl_regexp_match); sl_define_method(vm, vm->lib.Regexp, "source", 0, sl_regexp_source); sl_define_method(vm, vm->lib.Regexp, "options", 0, sl_regexp_options); sl_define_method(vm, vm->lib.Regexp, "==", 1, sl_regexp_eq); sl_class_set_const(vm, vm->lib.Regexp, "CASELESS", sl_make_int(vm, PCRE_CASELESS)); sl_class_set_const(vm, vm->lib.Regexp, "EXTENDED", sl_make_int(vm, PCRE_EXTENDED)); sl_class_set_const(vm, vm->lib.Regexp, "PCRE_VERSION", sl_make_cstring(vm, pcre_version())); sl_define_method(vm, vm->lib.Regexp_Match, "regexp", 0, sl_regexp_match_regexp); sl_define_method(vm, vm->lib.Regexp_Match, "[]", 1, sl_regexp_match_index); sl_define_method(vm, vm->lib.Regexp_Match, "byte_offset", 1, sl_regexp_match_byte_offset); sl_define_method(vm, vm->lib.Regexp_Match, "offset", 1, sl_regexp_match_offset); sl_define_method(vm, vm->lib.Regexp_Match, "capture", 1, sl_regexp_match_capture); sl_define_method(vm, vm->lib.Regexp_Match, "length", 0, sl_regexp_match_length); sl_define_method(vm, vm->lib.Regexp_Match, "before", 0, sl_regexp_match_before); sl_define_method(vm, vm->lib.Regexp_Match, "after", 0, sl_regexp_match_after); }
static ib_status_t modpcre_init(ib_engine_t *ib, ib_module_t *m, void *cbdata) { IB_FTRACE_INIT(); ib_status_t rc; /* Register as a matcher provider. */ rc = ib_provider_register(ib, IB_PROVIDER_TYPE_MATCHER, MODULE_NAME_STR, NULL, &modpcre_matcher_iface, NULL); if (rc != IB_OK) { ib_log_error(ib, MODULE_NAME_STR ": Error registering pcre matcher provider: " "%s", ib_status_to_string(rc)); IB_FTRACE_RET_STATUS(IB_OK); } ib_log_debug(ib,"PCRE Status: compiled=\"%d.%d %s\" loaded=\"%s\"", PCRE_MAJOR, PCRE_MINOR, IB_XSTRINGIFY(PCRE_DATE), pcre_version()); /* Register operators. */ ib_operator_register(ib, "pcre", (IB_OP_FLAG_PHASE | IB_OP_FLAG_CAPTURE), pcre_operator_create, NULL, pcre_operator_destroy, NULL, pcre_operator_execute, NULL); /* An alias of pcre. The same callbacks are registered. */ ib_operator_register(ib, "rx", (IB_OP_FLAG_PHASE | IB_OP_FLAG_CAPTURE), pcre_operator_create, NULL, pcre_operator_destroy, NULL, pcre_operator_execute, NULL); /* Register a pcre operator that uses pcre_dfa_exec to match streams. */ ib_operator_register(ib, "dfa", (IB_OP_FLAG_PHASE | IB_OP_FLAG_STREAM), dfa_operator_create, NULL, dfa_operator_destroy, NULL, dfa_operator_execute, NULL); IB_FTRACE_RET_STATUS(IB_OK); }
IoObject *IoRegex_version(IoRegex *self, IoObject *locals, IoMessage *m) { /*doc Regex version Returns a string with PCRE version information. */ return IOSYMBOL(pcre_version()); }
void debug_init(void) { #ifdef HAVE_SYS_UTSNAME_H struct utsname buf; #endif DEBUG_LOCK; if ((debug_file = fopen (GBL_DEBUG_FILE, "w")) == NULL) ERROR_MSG("Couldn't open for writing %s", GBL_DEBUG_FILE); fprintf (debug_file, "\n==============================================================\n\n"); fprintf (debug_file, "-> ${prefix} %s\n", INSTALL_PREFIX); fprintf (debug_file, "-> ${exec_prefix} %s\n", INSTALL_EXECPREFIX); fprintf (debug_file, "-> ${bindir} %s\n", INSTALL_BINDIR); fprintf (debug_file, "-> ${libdir} %s\n", INSTALL_LIBDIR); fprintf (debug_file, "-> ${sysconfdir} %s\n", INSTALL_SYSCONFDIR); fprintf (debug_file, "-> ${datadir} %s\n\n", INSTALL_DATADIR); fprintf (debug_file, "-> %s %s\n\n", GBL_PROGRAM, GBL_VERSION); #ifdef HAVE_SYS_UTSNAME_H uname(&buf); fprintf (debug_file, "-> running on %s %s %s\n", buf.sysname, buf.release, buf.machine); #endif #if defined (__GNUC__) && defined (__GNUC_MINOR__) fprintf (debug_file, "-> compiled with gcc %d.%d (%s)\n", __GNUC__, __GNUC_MINOR__, GCC_VERSION); #endif #if defined (__GLIBC__) && defined (__GLIBC_MINOR__) fprintf (debug_file, "-> glibc version %d.%d\n", __GLIBC__, __GLIBC_MINOR__); #endif fprintf(debug_file, "-> %s\n", pcap_lib_version()); fprintf(debug_file, "-> libnet version %s\n", LIBNET_VERSION); fprintf(debug_file, "-> libz version %s\n", zlibVersion()); #ifdef HAVE_PCRE fprintf(debug_file, "-> libpcre version %s\n", pcre_version()); #endif #ifdef HAVE_OPENSSL fprintf (debug_file, "-> lib %s\n", SSLeay_version(SSLEAY_VERSION)); fprintf (debug_file, "-> headers %s\n", OPENSSL_VERSION_TEXT); #endif #ifdef HAVE_NCURSES fprintf (debug_file, "-> %s\n", curses_version()); #endif #ifdef HAVE_GTK fprintf (debug_file, "-> gtk+ %d.%d.%d\n", gtk_major_version, gtk_minor_version, gtk_micro_version); #endif fprintf (debug_file, "\n\nDEVICE OPENED FOR %s DEBUGGING\n\n", GBL_PROGRAM); fflush(debug_file); DEBUG_UNLOCK; atexit(debug_close); }
void moduleInit() override { Native::registerConstant<KindOfString>( s_PCRE_VERSION.get(), makeStaticString(pcre_version()) ); #define PCRECNS(c) Native::registerConstant<KindOfInt64> \ (makeStaticString("PREG_" #c), PHP_PCRE_##c); PCRECNS(NO_ERROR); PCRECNS(INTERNAL_ERROR); PCRECNS(BACKTRACK_LIMIT_ERROR); PCRECNS(RECURSION_LIMIT_ERROR); PCRECNS(BAD_UTF8_ERROR); PCRECNS(BAD_UTF8_OFFSET_ERROR); #undef PCRECNS #define PREGCNS(c) Native::registerConstant<KindOfInt64> \ (makeStaticString("PREG_" #c), PREG_##c); PREGCNS(PATTERN_ORDER); PREGCNS(SET_ORDER); PREGCNS(OFFSET_CAPTURE); PREGCNS(SPLIT_NO_EMPTY); PREGCNS(SPLIT_DELIM_CAPTURE); PREGCNS(SPLIT_OFFSET_CAPTURE); PREGCNS(GREP_INVERT); #undef PREGCNS HHVM_FE(preg_filter); HHVM_FE(preg_grep); HHVM_FE(preg_match); HHVM_FE(preg_match_all); HHVM_FE(preg_replace); HHVM_FE(preg_replace_callback); HHVM_FE(preg_replace_callback_array); HHVM_FE(preg_split); HHVM_FE(preg_quote); HHVM_FE(preg_last_error); HHVM_FE(ereg_replace); HHVM_FE(eregi_replace); HHVM_FE(ereg); HHVM_FE(eregi); HHVM_FE(split); HHVM_FE(spliti); HHVM_FE(sql_regcase); loadSystemlib(); pcre_config(PCRE_CONFIG_JIT, &s_pcre_has_jit); IniSetting::Bind(this, IniSetting::PHP_INI_ONLY, "hhvm.pcre.jit", &s_pcre_has_jit); }
void init_regexp(void) { /* Register a restart handler for the regexp pool, so that when restarting, * regfree(3) is called on each of the regex_t pointers in a * regex_t-tracking array, thus preventing memory leaks on a long-running * daemon. * * This registration is done here so that it only happens once. */ pr_event_register(NULL, "core.restart", regexp_restart_ev, NULL); pr_event_register(NULL, "core.exit", regexp_exit_ev, NULL); #ifdef PR_USE_PCRE pr_log_debug(DEBUG2, "using PCRE %s", pcre_version()); #endif /* PR_USE_PCRE */ }
virtual void moduleInit() { Native::registerConstant<KindOfString>( s_PCRE_VERSION.get(), makeStaticString(pcre_version()) ); #define PCRECNS(c) Native::registerConstant<KindOfInt64> \ (makeStaticString("PREG_" #c), PHP_PCRE_##c); PCRECNS(NO_ERROR); PCRECNS(INTERNAL_ERROR); PCRECNS(BACKTRACK_LIMIT_ERROR); PCRECNS(RECURSION_LIMIT_ERROR); PCRECNS(BAD_UTF8_ERROR); PCRECNS(BAD_UTF8_OFFSET_ERROR); #undef PCRECNS #define PREGCNS(c) Native::registerConstant<KindOfInt64> \ (makeStaticString("PREG_" #c), PREG_##c); PREGCNS(PATTERN_ORDER); PREGCNS(SET_ORDER); PREGCNS(OFFSET_CAPTURE); PREGCNS(SPLIT_NO_EMPTY); PREGCNS(SPLIT_DELIM_CAPTURE); PREGCNS(SPLIT_OFFSET_CAPTURE); PREGCNS(GREP_INVERT); #undef PREGCNS HHVM_FE(preg_filter); HHVM_FE(preg_grep); HHVM_FE(preg_match); HHVM_FE(preg_match_all); HHVM_FE(preg_replace); HHVM_FE(preg_replace_callback); HHVM_FE(preg_split); HHVM_FE(preg_quote); HHVM_FE(preg_last_error); HHVM_FE(ereg_replace); HHVM_FE(eregi_replace); HHVM_FE(ereg); HHVM_FE(eregi); HHVM_FE(split); HHVM_FE(spliti); HHVM_FE(sql_regcase); loadSystemlib(); }
LUALIB_API int luaopen_lnode(lua_State *L) { #if defined(WITH_OPENSSL) || defined(WITH_PCRE) char buffer[1024]; #endif lua_newtable(L); #ifdef LUVI_VERSION lua_pushstring(L, ""LUVI_VERSION""); lua_setfield(L, -2, "version"); #endif lua_newtable(L); #ifdef WITH_OPENSSL snprintf(buffer, sizeof(buffer), "%s, lua-openssl %s", SSLeay_version(SSLEAY_VERSION), LOPENSSL_VERSION); lua_pushstring(L, buffer); lua_setfield(L, -2, "ssl"); #endif #ifdef WITH_PCRE lua_pushstring(L, pcre_version()); lua_setfield(L, -2, "rex"); #endif #ifdef WITH_ZLIB lua_pushstring(L, zlibVersion()); lua_setfield(L, -2, "zlib"); #endif #ifdef WITH_WINSVC lua_pushboolean(L, 1); lua_setfield(L, -2, "winsvc"); #endif lua_pushstring(L, uv_version_string()); lua_setfield(L, -2, "libuv"); lua_setfield(L, -2, "options"); return 1; }
/* Open the library */ REX_API int REX_OPENLIB (lua_State *L) { if (PCRE_MAJOR > atoi (pcre_version ())) { return luaL_error (L, "%s requires at least version %d of PCRE library", REX_LIBNAME, (int)PCRE_MAJOR); } /* create a new function environment to serve as a metatable for methods */ lua_newtable (L); lua_pushvalue (L, -1); lua_replace (L, LUA_ENVIRONINDEX); lua_pushvalue(L, -1); /* mt.__index = mt */ lua_setfield(L, -2, "__index"); luaL_register (L, NULL, regex_meta); /* register functions */ luaL_register (L, REX_LIBNAME, rexlib); lua_pushliteral (L, REX_VERSION" (for PCRE)"); lua_setfield (L, -2, "_VERSION"); /* create a table and register it as a metatable for "chartables" userdata */ lua_pushinteger (L, INDEX_CHARTABLES_META); lua_newtable (L); lua_pushliteral (L, "access denied"); lua_setfield (L, -2, "__metatable"); luaL_register (L, NULL, chartables_meta); lua_rawset (L, LUA_ENVIRONINDEX); /* create a table for connecting "chartables" userdata to "regex" userdata */ lua_pushinteger (L, INDEX_CHARTABLES_LINK); lua_newtable (L); lua_pushliteral (L, "k"); /* weak keys */ lua_setfield (L, -2, "__mode"); lua_pushvalue (L, -1); /* setmetatable (tb, tb) */ lua_setmetatable (L, -2); lua_rawset (L, LUA_ENVIRONINDEX); return 1; }
bool BnxDriver::ParseArgs(int argc, char *argv[]) { int c; while ((c = getopt(argc, argv, "c:hv")) != -1) { switch (c) { case 'c': SetConfigFile(optarg); break; case 'v': BnxOutStream << BnxBot::GetVersionString() << "\n\n"; BnxOutStream << "libevent: " << event_get_version() << '\n'; #ifdef USE_PCRE BnxOutStream << "pcre: " << pcre_version() << BnxEndl; #endif // USE_PCRE return false; case 'h': default: Usage(); return false; } } return true; }
virtual void moduleInit() { Native::registerConstant<KindOfString>( s_PCRE_VERSION.get(), makeStaticString(pcre_version()) ); HHVM_FE(preg_filter); HHVM_FE(preg_grep); HHVM_FE(preg_match); HHVM_FE(preg_match_all); HHVM_FE(preg_replace); HHVM_FE(preg_replace_callback); HHVM_FE(preg_split); HHVM_FE(preg_quote); HHVM_FE(preg_last_error); HHVM_FE(ereg_replace); HHVM_FE(eregi_replace); HHVM_FE(ereg); HHVM_FE(eregi); HHVM_FE(split); HHVM_FE(spliti); HHVM_FE(sql_regcase); loadSystemlib(); }
/* * File Format * * u32 - magic number * u32 - version * u32 - length of pcre version EXCLUDING nul * char - pcre version string EXCLUDING nul * u32 - number of stems * ** Stems * u32 - length of stem EXCLUDING nul * char - stem char array INCLUDING nul * u32 - number of regexs * ** Regexes * u32 - length of upcoming context INCLUDING nul * char - char array of the raw context * u32 - length of the upcoming regex_str * char - char array of the original regex string including the stem. * u32 - mode bits for >= SELINUX_COMPILED_FCONTEXT_MODE * mode_t for <= SELINUX_COMPILED_FCONTEXT_PCRE_VERS * s32 - stemid associated with the regex * u32 - spec has meta characters * u32 - The specs prefix_len if >= SELINUX_COMPILED_FCONTEXT_PREFIX_LEN * u32 - data length of the pcre regex * char - a bufer holding the raw pcre regex info * u32 - data length of the pcre regex study daya * char - a buffer holding the raw pcre regex study data */ static int write_binary_file(struct saved_data *data, int fd) { struct spec *specs = data->spec_arr; FILE *bin_file; size_t len; uint32_t magic = SELINUX_MAGIC_COMPILED_FCONTEXT; uint32_t section_len; uint32_t i; int rc; bin_file = fdopen(fd, "w"); if (!bin_file) { perror("fopen output_file"); exit(EXIT_FAILURE); } /* write some magic number */ len = fwrite(&magic, sizeof(uint32_t), 1, bin_file); if (len != 1) goto err; /* write the version */ section_len = SELINUX_COMPILED_FCONTEXT_MAX_VERS; len = fwrite(§ion_len, sizeof(uint32_t), 1, bin_file); if (len != 1) goto err; /* write the pcre version */ section_len = strlen(pcre_version()); len = fwrite(§ion_len, sizeof(uint32_t), 1, bin_file); if (len != 1) goto err; len = fwrite(pcre_version(), sizeof(char), section_len, bin_file); if (len != section_len) goto err; /* write the number of stems coming */ section_len = data->num_stems; len = fwrite(§ion_len, sizeof(uint32_t), 1, bin_file); if (len != 1) goto err; for (i = 0; i < section_len; i++) { char *stem = data->stem_arr[i].buf; uint32_t stem_len = data->stem_arr[i].len; /* write the strlen (aka no nul) */ len = fwrite(&stem_len, sizeof(uint32_t), 1, bin_file); if (len != 1) goto err; /* include the nul in the file */ stem_len += 1; len = fwrite(stem, sizeof(char), stem_len, bin_file); if (len != stem_len) goto err; } /* write the number of regexes coming */ section_len = data->nspec; len = fwrite(§ion_len, sizeof(uint32_t), 1, bin_file); if (len != 1) goto err; for (i = 0; i < section_len; i++) { char *context = specs[i].lr.ctx_raw; char *regex_str = specs[i].regex_str; mode_t mode = specs[i].mode; size_t prefix_len = specs[i].prefix_len; int32_t stem_id = specs[i].stem_id; pcre *re = specs[i].regex; pcre_extra *sd = get_pcre_extra(&specs[i]); uint32_t to_write; size_t size; /* length of the context string (including nul) */ to_write = strlen(context) + 1; len = fwrite(&to_write, sizeof(uint32_t), 1, bin_file); if (len != 1) goto err; /* original context strin (including nul) */ len = fwrite(context, sizeof(char), to_write, bin_file); if (len != to_write) goto err; /* length of the original regex string (including nul) */ to_write = strlen(regex_str) + 1; len = fwrite(&to_write, sizeof(uint32_t), 1, bin_file); if (len != 1) goto err; /* original regex string */ len = fwrite(regex_str, sizeof(char), to_write, bin_file); if (len != to_write) goto err; /* binary F_MODE bits */ to_write = mode; len = fwrite(&to_write, sizeof(uint32_t), 1, bin_file); if (len != 1) goto err; /* stem for this regex (could be -1) */ len = fwrite(&stem_id, sizeof(stem_id), 1, bin_file); if (len != 1) goto err; /* does this spec have a metaChar? */ to_write = specs[i].hasMetaChars; len = fwrite(&to_write, sizeof(to_write), 1, bin_file); if (len != 1) goto err; /* For SELINUX_COMPILED_FCONTEXT_PREFIX_LEN */ to_write = prefix_len; len = fwrite(&to_write, sizeof(to_write), 1, bin_file); if (len != 1) goto err; /* determine the size of the pcre data in bytes */ rc = pcre_fullinfo(re, NULL, PCRE_INFO_SIZE, &size); if (rc < 0) goto err; /* write the number of bytes in the pcre data */ to_write = size; len = fwrite(&to_write, sizeof(uint32_t), 1, bin_file); if (len != 1) goto err; /* write the actual pcre data as a char array */ len = fwrite(re, 1, to_write, bin_file); if (len != to_write) goto err; /* determine the size of the pcre study info */ rc = pcre_fullinfo(re, sd, PCRE_INFO_STUDYSIZE, &size); if (rc < 0) goto err; /* write the number of bytes in the pcre study data */ to_write = size; len = fwrite(&to_write, sizeof(uint32_t), 1, bin_file); if (len != 1) goto err; /* write the actual pcre study data as a char array */ len = fwrite(sd->study_data, 1, to_write, bin_file); if (len != to_write) goto err; } rc = 0; out: fclose(bin_file); return rc; err: rc = -1; goto out; }
String *Swig_pcre_version(void) { return NewStringf("PCRE Version: %s", pcre_version()); }
int main(int argc, char **argv) { const struct option long_options[] = { { "help", no_argument, NULL, 'h' }, { "debug", required_argument, NULL, 'd' }, { "daemon", no_argument, NULL, 'D' }, { "user", required_argument, NULL, 'u' }, { "chroot", required_argument, NULL, 'c' }, { "credits", no_argument, NULL, 'C' }, { "config", required_argument, NULL, 'f' }, { "log", required_argument, NULL, 'l' }, { "file", required_argument, NULL, 'F' }, {0, 0, 0, 0} }; static const char *short_options = "l:f:u:d:c:pDhC"; int option_index = 0; /****************************************************************************/ /* libpcap/PLOG (syslog sniffer) local variables */ /****************************************************************************/ #ifdef HAVE_LIBPCAP pthread_t pcap_thread; pthread_attr_t thread_pcap_attr; pthread_attr_init(&thread_pcap_attr); pthread_attr_setdetachstate(&thread_pcap_attr, PTHREAD_CREATE_DETACHED); #endif /****************************************************************************/ /* Perfmonitor local variables */ /****************************************************************************/ pthread_t perfmonitor_thread; pthread_attr_t thread_perfmonitor_attr; pthread_attr_init(&thread_perfmonitor_attr); pthread_attr_setdetachstate(&thread_perfmonitor_attr, PTHREAD_CREATE_DETACHED); /****************************************************************************/ /* Various local variables */ /****************************************************************************/ /* Block all signals, we create a signal handling thread */ sigset_t signal_set; pthread_t sig_thread; sigfillset( &signal_set ); pthread_sigmask( SIG_BLOCK, &signal_set, NULL ); /* Key board handler (displays stats, etc */ pthread_t key_thread; pthread_attr_t key_thread_attr; pthread_attr_init(&key_thread_attr); pthread_attr_setdetachstate(&key_thread_attr, PTHREAD_CREATE_DETACHED); struct sockaddr_in sa; char src_dns_lookup[20]; int dns_flag=0; sbool fifoerr=0; char *syslog_host=NULL; char *syslog_facility=NULL; char *syslog_priority=NULL; char *syslog_level=NULL; char *syslog_tag=NULL; char *syslog_date=NULL; char *syslog_time=NULL; char *syslog_program=NULL; char *syslog_msg=NULL; char syslogstring[MAX_SYSLOGMSG]; signed char c; char *tok; int rc=0; int i; time_t t; struct tm *run; sbool debugflag=0; /* Allocate and clear memory for global structs */ /* Allocate memory for global struct _SaganDebug */ debug = malloc(sizeof(_SaganDebug)); memset(debug, 0, sizeof(_SaganDebug)); /* Allocate memroy for global struct _SaganConfig */ config = malloc(sizeof(_SaganConfig)); memset(config, 0, sizeof(_SaganConfig)); struct _SaganSigArgs *sigargs; sigargs = malloc(sizeof(_SaganSigArgs)); memset(sigargs, 0, sizeof(_SaganSigArgs)); struct _SaganDNSCache *dnscache; dnscache = malloc(sizeof(_SaganDNSCache)); memset(dnscache, 0, sizeof(_SaganDNSCache)); counters = malloc(sizeof(_SaganCounters)); memset(counters, 0, sizeof(_SaganCounters)); flowbit = malloc(sizeof(_Sagan_Flowbit)); memset(flowbit, 0, sizeof(_Sagan_Flowbit)); t = time(NULL); run=localtime(&t); strftime(config->sagan_startutime, sizeof(config->sagan_startutime), "%s", run); strlcpy(config->sagan_config, CONFIG_FILE_PATH, sizeof(config->sagan_config)); /* We set the config->sagan_log_filepath to the system default. It'll be fopen'ed shortly - 06/03/2011 - Champ Clark III */ strlcpy(config->sagan_log_filepath, SAGANLOG, sizeof(config->sagan_log_filepath)); config->sagan_runas = RUNAS; /* Get command line arg's */ while ((c = getopt_long(argc, argv, short_options, long_options, &option_index)) != -1) { switch(c) { if (c == -1) break; case 'h': Sagan_Usage(); exit(0); break; case 'C': Sagan_Credits(); exit(0); break; case 'd': if (Sagan_strstr(optarg, "malformed")) { debug->debugmalformed=1; debugflag=1; } if (Sagan_strstr(optarg, "limits")) { debug->debuglimits=1; debugflag=1; } if (Sagan_strstr(optarg, "syslog")) { debug->debugsyslog=1; debugflag=1; } if (Sagan_strstr(optarg, "load")) { debug->debugload=1; debugflag=1; } if (Sagan_strstr(optarg, "fwsam")) { debug->debugfwsam=1; debugflag=1; } if (Sagan_strstr(optarg, "external")) { debug->debugexternal=1; debugflag=1; } if (Sagan_strstr(optarg, "threads")) { debug->debugthreads=1; debugflag=1; } if (Sagan_strstr(optarg, "flowbit")) { debug->debugflowbit=1; debugflag=1; } if (Sagan_strstr(optarg, "engine")) { debug->debugengine=1; debugflag=1; } if (Sagan_strstr(optarg, "brointel")) { debug->debugbrointel=1; debugflag=1; } #ifdef HAVE_LIBGEOIP if (Sagan_strstr(optarg, "geoip")) { debug->debuggeoip=1; debugflag=1; } #endif #ifdef HAVE_LIBLOGNORM if (Sagan_strstr(optarg, "normalize" )) { debug->debugnormalize=1; debugflag=1; } #endif #ifdef HAVE_LIBESMTP if (Sagan_strstr(optarg, "smtp")) { debug->debugesmtp=1; debugflag=1; } #endif #ifdef HAVE_LIBPCAP if (Sagan_strstr(optarg, "plog")) { debug->debugplog=1; debugflag=1; } #endif #ifdef WITH_WEBSENSE if (Sagan_strstr(optarg, "websense")) { debug->debugwebsense=1; debugflag=1; } #endif /* If option is unknown */ if ( debugflag == 0 ) { fprintf(stderr, "Unknown debug option %s!\n", optarg); exit(1); } break; case 'D': daemonize=1; break; case 'u': config->sagan_runas=optarg; break; case 'c': Sagan_Chroot(optarg); break; case 'F': config->sagan_fifo_flag=1; strlcpy(config->sagan_fifo,optarg,sizeof(config->sagan_fifo) - 1); break; case 'f': strlcpy(config->sagan_config,optarg,sizeof(config->sagan_config) - 1); break; case 'l': strlcpy(config->sagan_log_filepath,optarg,sizeof(config->sagan_log_filepath) - 1); break; default: fprintf(stderr, "Invalid argument! See below for command line switches.\n"); Sagan_Usage(); exit(0); break; } } Sagan_Open_Log_File(OPEN, SAGAN_LOG); Load_Config(); Sagan_Engine_Init(); #ifdef HAVE_LIBLOGNORM Sagan_Liblognorm_Load(); #endif /* Load/init liblognorm definitions. I tried to move this into a subroutine, * but that ended up causing segfaults on ln_normalize() or causing * liblognorm not to function correctly (not parsing fields). Make reloading * a SIGHUP a issue as well. * 12/17/2010 - Champ */ SaganProcSyslog = malloc(config->max_processor_threads * sizeof(struct _Sagan_Proc_Syslog)); pthread_t processor_id[config->max_processor_threads]; pthread_attr_t thread_processor_attr; pthread_attr_init(&thread_processor_attr); pthread_attr_setdetachstate(&thread_processor_attr, PTHREAD_CREATE_DETACHED); Sagan_Log(S_NORMAL, "Configuration file %s loaded and %d rules loaded.", config->sagan_config, counters->rulecount); Sagan_Log(S_NORMAL, "Out of %d rules, %d Flowbit(s) are in use.", counters->rulecount, counters->flowbit_total_counter); Sagan_Log(S_NORMAL, "Sagan version %s is firing up!", VERSION); /* We go ahead and assign values to SaganSigArgs (struct sig_thread_args). This * struct is always used by the sig_handler thread, and sometimes used by the * plog_handler (below). So we assign values now */ sigargs->daemonize = daemonize; #ifdef HAVE_LIBPCAP /* Spawn a thread to 'sniff' syslog traffic (sagan-plog.c). This redirects syslog traffic to the /dev/log socket. This needs "root" access, so we drop priv's after this thread is started */ if ( config->plog_flag ) { rc = pthread_create( &pcap_thread, NULL, (void *)plog_handler, sigargs ); if ( rc != 0 ) { Remove_Lock_File(); Sagan_Log(S_ERROR, "[%s, line %d] Error creating libpcap handler thread [error: %d].", __FILE__, __LINE__, rc); } sleep(1); /* Sleep to avoid race between main() and plog thread plog thread needs "root" rights before sagan_droppriv(). In some cases main() run sagan_droppriv() before thread can complete - Champ Clark - 07/20/2011 */ } #endif Sagan_Droppriv(); /* Become the Sagan user */ Sagan_Log(S_NORMAL, "---------------------------------------------------------------------------"); if ( config->perfmonitor_flag ) { if (( config->perfmonitor_file_stream = fopen(config->perfmonitor_file_name, "a" )) == NULL ) { Remove_Lock_File(); Sagan_Log(S_ERROR, "[%s, line %d] Can't open %s - %s!", __FILE__, __LINE__, config->perfmonitor_file_name, strerror(errno)); } rc = pthread_create( &perfmonitor_thread, NULL, (void *)Sagan_Perfmonitor_Handler, sigargs ); if ( rc != 0 ) { Remove_Lock_File(); Sagan_Log(S_ERROR, "[%s, line %d] Error creating Perfmonitor thread [error: %d].", __FILE__, __LINE__, rc); } } /* Open sagan alert file */ Sagan_Open_Log_File(OPEN, ALERT_LOG); /**************************************************************************** * Display processor information as we load ****************************************************************************/ /* Sagan_Track_Clients processor ********************************************/ if ( config->sagan_track_clients_flag) { if ( config->pp_sagan_track_clients ) Sagan_Log(S_NORMAL, "Client Tracking Processor: %d minute(s)", config->pp_sagan_track_clients); Sagan_Track_Clients_Init(); Sagan_Load_Tracking_Cache(); } /* Sagan Blacklist IP processor *********************************************/ if ( config->blacklist_flag) { Sagan_Blacklist_Init(); Sagan_Blacklist_Load(); } /* Sagan Websense processor ************************************************/ #ifdef WITH_WEBSENSE if ( config->websense_flag ) { curl_global_init(CURL_GLOBAL_ALL); config->websense_last_time = atol(config->sagan_startutime); Sagan_Websense_Init(); Sagan_Log(S_NORMAL, ""); Sagan_Log(S_NORMAL, "Websense URL: %s", config->websense_url); Sagan_Log(S_NORMAL, "Websense Auth: %s", config->websense_auth); Sagan_Log(S_NORMAL, "Websense Device ID: %s", config->websense_device_id); Sagan_Log(S_NORMAL, "Websense Categories File: %s", config->websense_cat); Sagan_Log(S_NORMAL, "Websense Max Cache: %d", config->websense_max_cache); Sagan_Log(S_NORMAL, "Websense Cache Timeout: %d minutes.", config->websense_timeout / 60); Sagan_Log(S_NORMAL, "Websense loaded %d categories.", counters->websense_cat_count); } #endif /* Sagan Bro Intel processor *******************************************/ if ( config->brointel_flag ) { Sagan_Log(S_NORMAL, ""); Sagan_BroIntel_Init(); Sagan_BroIntel_Load_File(); Sagan_Log(S_NORMAL, "Bro Intel::ADDR Loaded: %d", counters->brointel_addr_count); Sagan_Log(S_NORMAL, "Bro Intel::DOMAIN Loaded: %d", counters->brointel_domain_count); Sagan_Log(S_NORMAL, "Bro Intel::FILE_HASH Loaded: %d", counters->brointel_file_hash_count); Sagan_Log(S_NORMAL, "Bro Intel::URL Loaded: %d", counters->brointel_url_count); Sagan_Log(S_NORMAL, "Bro Intel::SOFTWARE Loaded: %d", counters->brointel_software_count); Sagan_Log(S_NORMAL, "Bro Intel::EMAIL Loaded: %d", counters->brointel_email_count); Sagan_Log(S_NORMAL, "Bro Intel::USER_NAME Loaded: %d", counters->brointel_user_name_count); Sagan_Log(S_NORMAL, "Bro Intel::FILE_NAME Loaded: %d", counters->brointel_file_name_count); Sagan_Log(S_NORMAL, "Bro Intel::CERT_HASH Loaded: %d", counters->brointel_cert_hash_count); Sagan_Log(S_NORMAL, "Bro Intel Duplicates Detected: %d", counters->brointel_dups); } /*************************************************************************** * Output plugins ***************************************************************************/ #ifdef HAVE_LIBESMTP if ( config->sagan_esmtp_flag ) { Sagan_Log(S_NORMAL, ""); if ( config->min_email_priority ) Sagan_Log(S_NORMAL, "E-mail on priority %d or higher.", config->min_email_priority); Sagan_Log(S_NORMAL, "E-Mail will be sent from: %s", config->sagan_esmtp_from); Sagan_Log(S_NORMAL, "SMTP server is set to: %s", config->sagan_esmtp_server); } #endif #ifdef WITH_SNORTSAM if ( config->sagan_fwsam_flag ) { Sagan_Log(S_NORMAL, ""); Sagan_Log(S_NORMAL, "Snortsam output plug in enabled."); } #endif if ( config->sagan_external_output_flag ) { Sagan_Log(S_NORMAL, ""); Sagan_Log(S_NORMAL, "External program to be called: %s", config->sagan_extern); } /* Unified2 ****************************************************************/ #if defined(HAVE_DNET_H) || defined(HAVE_DUMBNET_H) if ( config->sagan_unified2_flag ) { Sagan_Log(S_NORMAL, ""); Sagan_Log(S_NORMAL, "Unified2 file: %s", config->unified2_filepath); Sagan_Log(S_NORMAL, "Unified2 limit: %dM", config->unified2_limit / 1024 / 1024 ); Unified2InitFile(); } #endif /*************************************************************************** * Non-Processor/Output option ***************************************************************************/ /* What to "ignore" ********************************************************/ if ( config->sagan_droplist_flag ) { Load_Ignore_List(); Sagan_Log(S_NORMAL, ""); Sagan_Log(S_NORMAL, "Loaded %d ignore/drop list item(s).", counters->droplist_count); } /*************************************************************************** * Continue with normal startup! ***************************************************************************/ Sagan_Log(S_NORMAL, ""); Sagan_Log(S_NORMAL, " ,-._,-. -*> Sagan! <*-"); Sagan_Log(S_NORMAL, " \\/)\"(\\/ Version %s", VERSION); Sagan_Log(S_NORMAL, " (_o_) Champ Clark III & The Quadrant InfoSec Team [quadrantsec.com]"); Sagan_Log(S_NORMAL, " / \\/) Copyright (C) 2009-2015 Quadrant Information Security, et al."); Sagan_Log(S_NORMAL, " (|| ||) Using PCRE version: %s", pcre_version()); Sagan_Log(S_NORMAL, " oo-oo Sagan is processing events....."); Sagan_Log(S_NORMAL, ""); /* Become a daemon if requested */ if ( daemonize ) { Sagan_Log(S_NORMAL, "Becoming a daemon!"); pid_t pid = 0; setsid(); pid = fork(); if (pid == 0) {} else { exit(0); } } /* Create the signal handlers thread _after_ the fork() so it can properly * handly signals - Champ Clark III - 06/13/2011 */ rc = pthread_create( &sig_thread, NULL, (void *)Sig_Handler, sigargs ); if ( rc != 0 ) { Remove_Lock_File(); Sagan_Log(S_ERROR, "[%s, line %d] Error creating signal handler thread. [error: %d]", __FILE__, __LINE__, rc); } /* We don't want the key_handler() if we're in daemon mode! */ if (!daemonize) { rc = pthread_create( &key_thread, NULL, (void *)key_handler, NULL ); if ( rc != 0 ) { Remove_Lock_File(); Sagan_Log(S_ERROR, "[%s, line %d] Error creating key_handler thread. [error: %d]", __FILE__, __LINE__, rc); } } /* We do this after forking so init scripts can complete */ /* Check lock file _after_ thread. If you don't it'll retreive the wrong pid * and incorrectly believe there is a stale lock file if --daemon */ checklockfile(); Sagan_Log(S_NORMAL, "Spawning %d Processor Threads.", config->max_processor_threads); for (i = 0; i < config->max_processor_threads; i++) { rc = pthread_create ( &processor_id[i], &thread_processor_attr, (void *)Sagan_Processor, NULL ); if ( rc != 0 ) { Remove_Lock_File(); Sagan_Log(S_ERROR, "Could not pthread_create() for I/O processors [error: %d]", rc); } } Sagan_Log(S_NORMAL, ""); if ( config->sagan_fifo_flag == 0 ) { Sagan_Log(S_NORMAL, "Attempting to open syslog FIFO (%s).", config->sagan_fifo); } else { Sagan_Log(S_NORMAL, "Attempting to open syslog FILE (%s).", config->sagan_fifo); } while(1) { FILE *fd; fd = fopen(config->sagan_fifo, "r"); if ( config->sagan_fifo_flag == 0 ) { Sagan_Log(S_NORMAL, "Successfully opened FIFO (%s).", config->sagan_fifo); } else { Sagan_Log(S_NORMAL, "Successfully opened FILE (%s) and processing events.....", config->sagan_fifo); } while(fd != NULL) { while(fgets(syslogstring, sizeof(syslogstring), fd) != NULL) { /* If the FIFO was in a error state, let user know the FIFO writer has resumed */ if ( fifoerr == 1 ) { Sagan_Log(S_NORMAL, "FIFO writer has restarted. Processing events."); fifoerr=0; } counters->sagantotal++; syslog_host = strtok_r(syslogstring, "|", &tok); /* If we're using DNS (and we shouldn't be!), we start DNS checks and lookups * here. We cache both good and bad lookups to not over load our DNS server(s). * The only way DNS cache can be cleared is to restart Sagan */ if (config->syslog_src_lookup ) { if ( inet_pton(AF_INET, syslog_host, &(sa.sin_addr)) == 0 ) /* Is inbound a valid IP? */ { dns_flag=0; for(i=0; i <= counters->dns_cache_count ; i++) /* Check cache first */ { if (!strcmp( dnscache[i].hostname, syslog_host)) { syslog_host = dnscache[i].src_ip; dns_flag=1; } } /* If entry was not found in cache, look it up */ if ( dns_flag == 0 ) { /* Do a DNS lookup */ strlcpy(src_dns_lookup, DNS_Lookup(syslog_host), sizeof(src_dns_lookup)); /* Invalid lookups get the config->sagan_host value */ if (src_dns_lookup[0] == '0' ) { strlcpy(src_dns_lookup, config->sagan_host, sizeof(src_dns_lookup)); counters->dns_miss_count++; } /* Add entry to DNS Cache */ dnscache = (_SaganDNSCache *) realloc(dnscache, (counters->dns_cache_count+1) * sizeof(_SaganDNSCache)); strlcpy(dnscache[counters->dns_cache_count].hostname, syslog_host, sizeof(dnscache[counters->dns_cache_count].hostname)); strlcpy(dnscache[counters->dns_cache_count].src_ip, src_dns_lookup, sizeof(dnscache[counters->dns_cache_count].src_ip)); counters->dns_cache_count++; syslog_host = src_dns_lookup; } } } else { /* We check to see if values from our FIFO are valid. If we aren't doing DNS related * stuff (above), we start basic check with the syslog_host */ if (syslog_host == NULL || inet_pton(AF_INET, syslog_host, &(sa.sin_addr)) == 0 ) { syslog_host = config->sagan_host; pthread_mutex_lock(&SaganMalformedCounter); counters->malformed_host++; pthread_mutex_unlock(&SaganMalformedCounter); if ( debug->debugmalformed ) { Sagan_Log(S_WARN, "Sagan received a malformed 'host' (replaced with %s)", config->sagan_host); } } } // if ( config->home_any == 1) { /* We know check the rest of the values */ syslog_facility=strtok_r(NULL, "|", &tok); if ( syslog_facility == NULL ) { syslog_facility = "SAGAN: FACILITY ERROR"; pthread_mutex_lock(&SaganMalformedCounter); counters->malformed_facility++; pthread_mutex_unlock(&SaganMalformedCounter); if ( debug->debugmalformed ) { Sagan_Log(S_WARN, "Sagan received a malformed 'facility'"); } } syslog_priority=strtok_r(NULL, "|", &tok); if ( syslog_priority == NULL ) { syslog_priority = "SAGAN: PRIORITY ERROR"; pthread_mutex_lock(&SaganMalformedCounter); counters->malformed_priority++; pthread_mutex_unlock(&SaganMalformedCounter); if ( debug->debugmalformed ) { Sagan_Log(S_WARN, "Sagan received a malformed 'priority'"); } } syslog_level=strtok_r(NULL, "|", &tok); if ( syslog_level == NULL ) { syslog_level = "SAGAN: LEVEL ERROR"; pthread_mutex_lock(&SaganMalformedCounter); counters->malformed_level++; pthread_mutex_unlock(&SaganMalformedCounter); if ( debug->debugmalformed ) { Sagan_Log(S_WARN, "Sagan received a malformed 'level'"); } } syslog_tag=strtok_r(NULL, "|", &tok); if ( syslog_tag == NULL ) { syslog_tag = "SAGAN: TAG ERROR"; pthread_mutex_lock(&SaganMalformedCounter); counters->malformed_tag++; pthread_mutex_unlock(&SaganMalformedCounter); if ( debug->debugmalformed ) { Sagan_Log(S_WARN, "Sagan received a malformed 'tag'"); } } syslog_date=strtok_r(NULL, "|", &tok); if ( syslog_date == NULL ) { syslog_date = "SAGAN: DATE ERROR"; pthread_mutex_lock(&SaganMalformedCounter); counters->malformed_date++; pthread_mutex_unlock(&SaganMalformedCounter); if ( debug->debugmalformed ) { Sagan_Log(S_WARN, "Sagan received a malformed 'date'"); } } syslog_time=strtok_r(NULL, "|", &tok); if ( syslog_time == NULL ) { syslog_time = "SAGAN: TIME ERROR"; pthread_mutex_lock(&SaganMalformedCounter); counters->malformed_time++; pthread_mutex_unlock(&SaganMalformedCounter); if ( debug->debugmalformed ) { Sagan_Log(S_WARN, "Sagan received a malformed 'time'"); } } syslog_program=strtok_r(NULL, "|", &tok); if ( syslog_program == NULL ) { syslog_program = "SAGAN: PROGRAM ERROR"; pthread_mutex_lock(&SaganMalformedCounter); counters->malformed_program++; pthread_mutex_unlock(&SaganMalformedCounter); if ( debug->debugmalformed ) { Sagan_Log(S_WARN, "Sagan received a malformed 'program'"); } } syslog_msg=strtok_r(NULL, "", &tok); /* In case the message has | in it, we delimit on "" */ if ( syslog_msg == NULL ) { syslog_msg = "SAGAN: MESSAGE ERROR"; pthread_mutex_lock(&SaganMalformedCounter); counters->malformed_message++; pthread_mutex_unlock(&SaganMalformedCounter); if ( debug->debugmalformed ) { Sagan_Log(S_WARN, "Sagan received a malformed 'message' [Syslog Host: %s]", syslog_host); } /* If the message is lost, all is lost. Typically, you don't lose part of the message, * it's more likely to lose all - Champ Clark III 11/17/2011 */ counters->sagan_log_drop++; } /* Strip any \n or \r from the syslog_msg */ if ( strcspn ( syslog_msg, "\n" ) < strlen(syslog_msg) ) syslog_msg[strcspn ( syslog_msg, "\n" )] = '\0'; if ( proc_msgslot < config->max_processor_threads ) { pthread_mutex_lock(&SaganProcWorkMutex); strlcpy(SaganProcSyslog[proc_msgslot].syslog_host, syslog_host, sizeof(SaganProcSyslog[proc_msgslot].syslog_host)); strlcpy(SaganProcSyslog[proc_msgslot].syslog_facility, syslog_facility, sizeof(SaganProcSyslog[proc_msgslot].syslog_facility)); strlcpy(SaganProcSyslog[proc_msgslot].syslog_priority, syslog_priority, sizeof(SaganProcSyslog[proc_msgslot].syslog_priority)); strlcpy(SaganProcSyslog[proc_msgslot].syslog_level, syslog_level, sizeof(SaganProcSyslog[proc_msgslot].syslog_level)); strlcpy(SaganProcSyslog[proc_msgslot].syslog_tag, syslog_tag, sizeof(SaganProcSyslog[proc_msgslot].syslog_tag)); strlcpy(SaganProcSyslog[proc_msgslot].syslog_date, syslog_date, sizeof(SaganProcSyslog[proc_msgslot].syslog_date)); strlcpy(SaganProcSyslog[proc_msgslot].syslog_time, syslog_time, sizeof(SaganProcSyslog[proc_msgslot].syslog_time)); strlcpy(SaganProcSyslog[proc_msgslot].syslog_program, syslog_program, sizeof(SaganProcSyslog[proc_msgslot].syslog_program)); strlcpy(SaganProcSyslog[proc_msgslot].syslog_message, syslog_msg, sizeof(SaganProcSyslog[proc_msgslot].syslog_message)); proc_msgslot++; pthread_cond_signal(&SaganProcDoWork); pthread_mutex_unlock(&SaganProcWorkMutex); } else { counters->worker_thread_exhaustion++; counters->sagan_log_drop++; } if (debug->debugthreads) Sagan_Log(S_DEBUG, "Current \"proc_msgslot\": %d", proc_msgslot); if (debug->debugsyslog) { Sagan_Log(S_DEBUG, "[%s, line %d] **[RAW Syslog]*********************************", __FILE__, __LINE__); Sagan_Log(S_DEBUG, "[%s, line %d] Host: %s | Program: %s | Facility: %s | Priority: %s | Level: %s | Tag: %s", __FILE__, __LINE__, syslog_host, syslog_program, syslog_facility, syslog_priority, syslog_level, syslog_tag); Sagan_Log(S_DEBUG, "[%s, line %d] Raw message: %s", __FILE__, __LINE__, syslog_msg); } } /* while(fgets) */ /* fgets() has returned a error, likely due to the FIFO writer leaving */ /* DEBUG : set a kill flag and join */ /* RMEOVE LOCK */ if ( fifoerr == 0 ) { if ( config->sagan_fifo_flag != 0 ) { Sagan_Log(S_NORMAL, "EOF reached. Waiting for threads to catch up"); sleep(5); fclose(fd); Sagan_Log(S_NORMAL, "Exiting."); /* DEBUG: Rejoin threads */ exit(0); } else { Sagan_Log(S_WARN, "FIFO writer closed. Waiting for FIFO writer to restart...."); fifoerr=1; /* Set flag so our wile(fgets) knows */ } } sleep(1); /* So we don't eat 100% CPU */ } /* while(fd != NULL) */ fclose(fd); /* ???? */ } /* End of while(1) */ } /* End of main */
void dogrep(struct user *user, char *tail) { FILE *fp; int i = 1, errptr, opt = 0; const char *error; char *options, *pattern, *ep; char logfile[256]; /* Check auth level.. */ if (!CheckAuthLevel(user, 250)) return; options = tail; pattern = SeperateWord(tail); if (NULL == options) { Usage(user, 1); return; } invert = FALSE; max_hits = HITS; if ('-' == options[0]) { while (options[i]) { switch (options[i++]) { case 'i': opt |= PCRE_CASELESS; break; case 'v': invert = TRUE; break; case 'l': if (NULL != pattern) { if ((max_hits = (int) strtol(pattern, &ep, 10)) > MAX_HITS) max_hits = MAX_HITS; if (0 == max_hits) max_hits = HITS; pattern = SeperateWord(pattern); } break; case 'V': NoticeToUser(user, "PCRE version %s", pcre_version()); break; default: NoticeToUser(user, "unknown option \"%c\"", options[i - 1]); return; break; } } } else { pattern = options; } SeperateWord(pattern); if (NULL == pattern) { Usage(user, 1); return; } if (NULL == (cpattern = pcre_compile(pattern, opt, &error, &errptr, NULL))) { NoticeToUser(user, "error in regex at offset %d: %s", errptr, error); return; } hints = pcre_study(cpattern, 0, &error); if (NULL != error) { NoticeToUser(user, "error while studing regex: %s", error); return; } NoticeToUser(user, "Log entries%smatching \"%s\"", (TRUE == invert) ? " NOT " : " ", pattern); count = 0; for (i = NUMBEROFLOGFILES; (i >= 0 && count < max_hits); i--) { snprintf(logfile, 256, "%s.%i", LOGFILE, i); if (NULL == (fp = fopen(logfile, "r"))) { NoticeToUser(user, "failed to open: %s (%s)", logfile, strerror(errno)); } else { pcregrep(fp, logfile, user); fclose(fp); } } if (cpattern != NULL) free(cpattern); if (hints != NULL) free(hints); if (count >= max_hits) NoticeToUser(user, "--- More than %d hits, list truncated", max_hits); NoticeToUser(user, "--- End of list - %d matc%s", count, (1 == count) ? "h" : "hes"); NoticeToUser(user, "Done."); }
word loader(CrocThread* t) { loadPCRESharedLib(t); // Check that we have an appropriate libpcre, first.. { auto vers = atoda(pcre_version()); vers = vers.slice(0, strLocateChar(vers, ' ')); auto dotPos = strLocateChar(vers, '.'); auto major = strtol(cast(const char*)vers.ptr, nullptr, 10); auto minor = strtol(cast(const char*)vers.ptr + dotPos + 1, nullptr, 10); if(major < 7 || (major == 7 && minor < 4)) { croc_eh_throwStd(t, "RuntimeError", "Your PCRE library is only version %.*s. You need 7.4 or higher.", cast(int)vers.length, vers.ptr); } int haveUtf8; pcre_config(PCRE_CONFIG_UTF8, &haveUtf8); if(!haveUtf8) croc_eh_throwStd(t, "RuntimeError", "Your PCRE library was not built with UTF-8 support."); } croc_class_new(t, "Regex", 0); croc_pushNull(t); croc_class_addHField(t, -2, _Ptrs); // memblock croc_pushNull(t); croc_class_addHField(t, -2, _Names); // table croc_pushNull(t); croc_class_addHField(t, -2, _GroupIdx); // memblock croc_pushNull(t); croc_class_addHField(t, -2, _Subject); // string croc_pushInt(t, 0); croc_class_addHField(t, -2, _NumGroups); // int croc_pushInt(t, 0); croc_class_addHField(t, -2, _NextStart); // int registerMethods(t, Regex_methodFuncs); registerMethodUV(t, Regex_opApplyFunc); croc_field(t, -1, "match"); croc_class_addMethod(t, -2, "opIndex"); croc_newGlobal(t, "Regex"); #ifdef CROC_BUILTIN_DOCS CrocDoc doc; croc_ex_doc_init(t, &doc, __FILE__); croc_dup(t, 0); croc_ex_doc_push(&doc, moduleDocs); croc_field(t, -1, "Regex"); croc_ex_doc_push(&doc, RegexDocs); docFields(&doc, Regex_methodFuncs); docFieldUV(&doc, Regex_opApplyFunc); docField(&doc, {Regex_opIndex_info, nullptr}); croc_ex_doc_pop(&doc, -1); croc_popTop(t); croc_ex_doc_pop(&doc, -1); croc_ex_doc_finish(&doc); croc_popTop(t); #endif return 0; }
int main(int argc, char **argv) { char **base_paths = NULL; char **paths = NULL; int i; int pcre_opts = PCRE_MULTILINE; int study_opts = 0; double time_diff; worker_t *workers = NULL; int workers_len; int num_cores; #ifdef KJK_BUILD extern void setup_crash_handler(); /* in kjk_crash_handler.cpp */ setup_crash_handler(); #endif set_log_level(LOG_LEVEL_WARN); work_queue = NULL; work_queue_tail = NULL; memset(&stats, 0, sizeof(stats)); root_ignores = init_ignore(NULL, "", 0); out_fd = stdout; #ifdef USE_PCRE_JIT int has_jit = 0; pcre_config(PCRE_CONFIG_JIT, &has_jit); if (has_jit) { study_opts |= PCRE_STUDY_JIT_COMPILE; } #endif gettimeofday(&(stats.time_start), NULL); parse_options(argc, argv, &base_paths, &paths); log_debug("PCRE Version: %s", pcre_version()); #ifdef _WIN32 { SYSTEM_INFO si; GetSystemInfo(&si); num_cores = si.dwNumberOfProcessors; } #else num_cores = (int)sysconf(_SC_NPROCESSORS_ONLN); #endif workers_len = num_cores; if (opts.literal) { workers_len--; } if (opts.workers) { workers_len = opts.workers; } if (workers_len < 1) { workers_len = 1; } log_debug("Using %i workers", workers_len); done_adding_files = FALSE; workers = (worker_t *) ag_calloc(workers_len, sizeof(worker_t)); if (pthread_cond_init(&files_ready, NULL)) { die("pthread_cond_init failed!"); } if (pthread_mutex_init(&print_mtx, NULL)) { die("pthread_mutex_init failed!"); } if (pthread_mutex_init(&stats_mtx, NULL)) { die("pthread_mutex_init failed!"); } if (pthread_mutex_init(&work_queue_mtx, NULL)) { die("pthread_mutex_init failed!"); } if (opts.casing == CASE_SMART) { opts.casing = is_lowercase(opts.query) ? CASE_INSENSITIVE : CASE_SENSITIVE; } if (opts.literal) { if (opts.casing == CASE_INSENSITIVE) { /* Search routine needs the query to be lowercase */ char *c = opts.query; for (; *c != '\0'; ++c) { *c = (char)tolower(*c); } } generate_alpha_skip(opts.query, opts.query_len, alpha_skip_lookup, opts.casing == CASE_SENSITIVE); find_skip_lookup = NULL; generate_find_skip(opts.query, opts.query_len, &find_skip_lookup, opts.casing == CASE_SENSITIVE); if (opts.word_regexp) { init_wordchar_table(); opts.literal_starts_wordchar = is_wordchar(opts.query[0]); opts.literal_ends_wordchar = is_wordchar(opts.query[opts.query_len - 1]); } } else { if (opts.casing == CASE_INSENSITIVE) { pcre_opts |= PCRE_CASELESS; } if (opts.word_regexp) { char *word_regexp_query; ag_asprintf(&word_regexp_query, "\\b%s\\b", opts.query); free(opts.query); opts.query = word_regexp_query; opts.query_len = strlen(opts.query); } compile_study(&opts.re, &opts.re_extra, opts.query, pcre_opts, study_opts); } if (opts.search_stream) { // search_stream(stdin, ""); } else { for (i = 0; i < workers_len; i++) { workers[i].id = i; int rv = pthread_create(&(workers[i].thread), NULL, &search_file_worker, &(workers[i].id)); if (rv != 0) { die("error in pthread_create(): %s", strerror(rv)); } #if defined(HAVE_PTHREAD_SETAFFINITY_NP) && defined(USE_CPU_SET) if (opts.use_thread_affinity) { cpu_set_t cpu_set; CPU_ZERO(&cpu_set); CPU_SET(i % num_cores, &cpu_set); rv = pthread_setaffinity_np(workers[i].thread, sizeof(cpu_set), &cpu_set); if (rv != 0) { die("error in pthread_setaffinity_np(): %s", strerror(rv)); } log_debug("Thread %i set to CPU %i", i, i); } else { log_debug("Thread affinity disabled."); } #else log_debug("No CPU affinity support."); #endif } for (i = 0; paths[i] != NULL; i++) { log_debug("searching path %s for %s", paths[i], opts.query); symhash = NULL; ignores *ig = init_ignore(root_ignores, "", 0); struct stat s; s.st_dev = 0; #ifndef _WIN32 /* The device is ignored if opts.one_dev is false, so it's fine * to leave it at the default 0 */ if (opts.one_dev && lstat(paths[i], &s) == -1) { log_err("Failed to get device information for path %s. Skipping...", paths[i]); } #endif search_dir(ig, base_paths[i], paths[i], 0, s.st_dev); cleanup_ignore(ig); } pthread_mutex_lock(&work_queue_mtx); done_adding_files = TRUE; pthread_cond_broadcast(&files_ready); pthread_mutex_unlock(&work_queue_mtx); for (i = 0; i < workers_len; i++) { if (pthread_join(workers[i].thread, NULL)) { die("pthread_join failed!"); } } } if (opts.stats) { gettimeofday(&(stats.time_end), NULL); time_diff = ((long)stats.time_end.tv_sec * 1000000 + stats.time_end.tv_usec) - ((long)stats.time_start.tv_sec * 1000000 + stats.time_start.tv_usec); time_diff /= 1000000; printf("%ld matches\n%ld files searched\n%ld bytes searched\n%f seconds\n", stats.total_matches, stats.total_files, stats.total_bytes, time_diff); } if (opts.pager) { pclose(out_fd); } cleanup_options(); pthread_cond_destroy(&files_ready); pthread_mutex_destroy(&work_queue_mtx); pthread_mutex_destroy(&stats_mtx); pthread_mutex_destroy(&print_mtx); cleanup_ignore(root_ignores); free(workers); for (i = 0; paths[i] != NULL; i++) { free(paths[i]); free(base_paths[i]); } free(base_paths); free(paths); if (find_skip_lookup) { free(find_skip_lookup); } return !opts.match_found; }
void moduleInit() override { HHVM_RC_STR(PCRE_VERSION, pcre_version()); HHVM_RC_INT(PREG_NO_ERROR, PHP_PCRE_NO_ERROR); HHVM_RC_INT(PREG_INTERNAL_ERROR, PHP_PCRE_INTERNAL_ERROR); HHVM_RC_INT(PREG_BACKTRACK_LIMIT_ERROR, PHP_PCRE_BACKTRACK_LIMIT_ERROR); HHVM_RC_INT(PREG_RECURSION_LIMIT_ERROR, PHP_PCRE_RECURSION_LIMIT_ERROR); HHVM_RC_INT(PREG_BAD_UTF8_ERROR, PHP_PCRE_BAD_UTF8_ERROR); HHVM_RC_INT(PREG_BAD_UTF8_OFFSET_ERROR, PHP_PCRE_BAD_UTF8_OFFSET_ERROR); HHVM_RC_INT_SAME(PREG_PATTERN_ORDER); HHVM_RC_INT_SAME(PREG_SET_ORDER); HHVM_RC_INT_SAME(PREG_OFFSET_CAPTURE); HHVM_RC_INT_SAME(PREG_SPLIT_NO_EMPTY); HHVM_RC_INT_SAME(PREG_SPLIT_DELIM_CAPTURE); HHVM_RC_INT_SAME(PREG_SPLIT_OFFSET_CAPTURE); HHVM_RC_INT_SAME(PREG_GREP_INVERT); #ifdef WNOHANG HHVM_RC_INT_SAME(WNOHANG); #endif #ifdef WUNTRACED HHVM_RC_INT_SAME(WUNTRACED); #endif #ifdef PRIO_PGRP HHVM_RC_INT_SAME(PRIO_PGRP); #endif #ifdef PRIO_USER HHVM_RC_INT_SAME(PRIO_USER); #endif #ifdef PRIO_PROCESS HHVM_RC_INT_SAME(PRIO_PROCESS); #endif HHVM_FE(preg_filter); HHVM_FE(preg_grep); HHVM_FE(preg_match); HHVM_FE(preg_match_all); HHVM_FE(preg_replace); HHVM_FE(preg_replace_callback); HHVM_FE(preg_replace_callback_array); HHVM_FE(preg_split); HHVM_FE(preg_quote); HHVM_FE(preg_last_error); HHVM_FE(ereg_replace); HHVM_FE(eregi_replace); HHVM_FE(ereg); HHVM_FE(eregi); HHVM_FE(split); HHVM_FE(spliti); HHVM_FE(sql_regcase); loadSystemlib(); pcre_config(PCRE_CONFIG_JIT, &s_pcre_has_jit); IniSetting::Bind(this, IniSetting::PHP_INI_ONLY, "hhvm.pcre.jit", &s_pcre_has_jit); }
int main() { std::cout << pcre_version(); return 0; }
void regexp_initialize( void ) { regexpList = LinkedListCreate(); versionAdd( "pcre", (char *)pcre_version() ); }
char* rc_getInfo(pool* p){ return apr_pstrcat(p,"[",REWRITE_CORE_VERSION,"], PCRE ",pcre_version(),NULL); }
int main(int argc, char **argv) { char **base_paths = NULL; char **paths = NULL; int i; int pcre_opts = PCRE_MULTILINE; int study_opts = 0; double time_diff; pthread_t *workers = NULL; int workers_len; set_log_level(LOG_LEVEL_WARN); work_queue = NULL; work_queue_tail = NULL; memset(&stats, 0, sizeof(stats)); root_ignores = init_ignore(NULL, "", 0); out_fd = stdout; #ifdef USE_PCRE_JIT int has_jit = 0; pcre_config(PCRE_CONFIG_JIT, &has_jit); if (has_jit) { study_opts |= PCRE_STUDY_JIT_COMPILE; } #endif gettimeofday(&(stats.time_start), NULL); parse_options(argc, argv, &base_paths, &paths); log_debug("PCRE Version: %s", pcre_version()); #ifdef _WIN32 { SYSTEM_INFO si; GetSystemInfo(&si); workers_len = si.dwNumberOfProcessors; } #else workers_len = (int)sysconf(_SC_NPROCESSORS_ONLN); #endif if (opts.literal) { workers_len--; } if (opts.workers) { workers_len = opts.workers; } if (workers_len < 1) { workers_len = 1; } log_debug("Using %i workers", workers_len); done_adding_files = FALSE; workers = ag_calloc(workers_len, sizeof(pthread_t)); if (pthread_cond_init(&files_ready, NULL)) { die("pthread_cond_init failed!"); } if (pthread_mutex_init(&print_mtx, NULL)) { die("pthread_mutex_init failed!"); } if (pthread_mutex_init(&stats_mtx, NULL)) { die("pthread_mutex_init failed!"); } if (pthread_mutex_init(&work_queue_mtx, NULL)) { die("pthread_mutex_init failed!"); } if (opts.casing == CASE_SMART) { opts.casing = is_lowercase(opts.query) ? CASE_INSENSITIVE : CASE_SENSITIVE; } if (opts.literal) { if (opts.casing == CASE_INSENSITIVE) { /* Search routine needs the query to be lowercase */ char *c = opts.query; for (; *c != '\0'; ++c) { *c = (char)tolower(*c); } } generate_alpha_skip(opts.query, opts.query_len, alpha_skip_lookup, opts.casing == CASE_SENSITIVE); find_skip_lookup = NULL; generate_find_skip(opts.query, opts.query_len, &find_skip_lookup, opts.casing == CASE_SENSITIVE); if (opts.word_regexp) { init_wordchar_table(); opts.literal_starts_wordchar = is_wordchar(opts.query[0]); opts.literal_ends_wordchar = is_wordchar(opts.query[opts.query_len - 1]); } } else { if (opts.casing == CASE_INSENSITIVE) { pcre_opts |= PCRE_CASELESS; } if (opts.word_regexp) { char *word_regexp_query; ag_asprintf(&word_regexp_query, "\\b%s\\b", opts.query); free(opts.query); opts.query = word_regexp_query; opts.query_len = strlen(opts.query); } compile_study(&opts.re, &opts.re_extra, opts.query, pcre_opts, study_opts); } if (opts.search_stream) { search_stream(stdin, ""); } else { for (i = 0; i < workers_len; i++) { int rv = pthread_create(&(workers[i]), NULL, &search_file_worker, &i); if (rv != 0) { die("error in pthread_create(): %s", strerror(rv)); } } for (i = 0; paths[i] != NULL; i++) { log_debug("searching path %s for %s", paths[i], opts.query); symhash = NULL; ignores *ig = init_ignore(root_ignores, "", 0); search_dir(ig, base_paths[i], paths[i], 0); cleanup_ignore(ig); } pthread_mutex_lock(&work_queue_mtx); done_adding_files = TRUE; pthread_cond_broadcast(&files_ready); pthread_mutex_unlock(&work_queue_mtx); for (i = 0; i < workers_len; i++) { if (pthread_join(workers[i], NULL)) { die("pthread_join failed!"); } } } if (opts.stats) { gettimeofday(&(stats.time_end), NULL); time_diff = ((long)stats.time_end.tv_sec * 1000000 + stats.time_end.tv_usec) - ((long)stats.time_start.tv_sec * 1000000 + stats.time_start.tv_usec); time_diff /= 1000000; printf("%ld matches\n%ld files searched\n%ld bytes searched\n%f seconds\n", stats.total_matches, stats.total_files, stats.total_bytes, time_diff); } if (opts.pager) { pclose(out_fd); } cleanup_options(); pthread_cond_destroy(&files_ready); pthread_mutex_destroy(&work_queue_mtx); pthread_mutex_destroy(&stats_mtx); pthread_mutex_destroy(&print_mtx); cleanup_ignore(root_ignores); free(workers); for (i = 0; paths[i] != NULL; i++) { free(paths[i]); free(base_paths[i]); } free(base_paths); free(paths); if (find_skip_lookup) { free(find_skip_lookup); } return !opts.match_found; }
int main(int argc, char **argv) { FILE *infile = stdin; int options = 0; int study_options = 0; int op = 1; int timeit = 0; int showinfo = 0; int showstore = 0; int size_offsets = 45; int size_offsets_max; int *offsets; #if !defined NOPOSIX int posix = 0; #endif int debug = 0; int done = 0; unsigned char buffer[30000]; unsigned char dbuffer[1024]; /* Static so that new_malloc can use it. */ outfile = stdout; /* Scan options */ while (argc > 1 && argv[op][0] == '-') { char *endptr; if (strcmp(argv[op], "-s") == 0 || strcmp(argv[op], "-m") == 0) showstore = 1; else if (strcmp(argv[op], "-t") == 0) timeit = 1; else if (strcmp(argv[op], "-i") == 0) showinfo = 1; else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1; else if (strcmp(argv[op], "-o") == 0 && argc > 2 && ((size_offsets = (int)strtoul(argv[op+1], &endptr, 10)), *endptr == 0)) { op++; argc--; } #if !defined NOPOSIX else if (strcmp(argv[op], "-p") == 0) posix = 1; #endif else { printf("** Unknown or malformed option %s\n", argv[op]); printf("Usage: pcretest [-d] [-i] [-o <n>] [-p] [-s] [-t] [<input> [<output>]]\n"); printf(" -d debug: show compiled code; implies -i\n" " -i show information about compiled pattern\n" " -o <n> set size of offsets vector to <n>\n"); #if !defined NOPOSIX printf(" -p use POSIX interface\n"); #endif printf(" -s output store information\n" " -t time compilation and execution\n"); return 1; } op++; argc--; } /* Get the store for the offsets vector, and remember what it was */ size_offsets_max = size_offsets; offsets = malloc(size_offsets_max * sizeof(int)); if (offsets == NULL) { printf("** Failed to get %d bytes of memory for offsets vector\n", size_offsets_max * sizeof(int)); return 1; } /* Sort out the input and output files */ if (argc > 1) { infile = fopen(argv[op], "r"); if (infile == NULL) { printf("** Failed to open %s\n", argv[op]); return 1; } } if (argc > 2) { outfile = fopen(argv[op+1], "w"); if (outfile == NULL) { printf("** Failed to open %s\n", argv[op+1]); return 1; } } /* Set alternative malloc function */ pcre_malloc = new_malloc; /* Heading line, then prompt for first regex if stdin */ fprintf(outfile, "PCRE version %s\n\n", pcre_version()); /* Main loop */ while (!done) { pcre *re = NULL; pcre_extra *extra = NULL; #if !defined NOPOSIX /* There are still compilers that require no indent */ regex_t preg; int do_posix = 0; #endif const char *error; unsigned char *p, *pp, *ppp; const unsigned char *tables = NULL; int do_study = 0; int do_debug = debug; int do_G = 0; int do_g = 0; int do_showinfo = showinfo; int do_showrest = 0; int utf8 = 0; int erroroffset, len, delimiter; if (infile == stdin) printf(" re> "); if (fgets((char *)buffer, sizeof(buffer), infile) == NULL) break; if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); p = buffer; while (isspace(*p)) p++; if (*p == 0) continue; /* Get the delimiter and seek the end of the pattern; if is isn't complete, read more. */ delimiter = *p++; if (isalnum(delimiter) || delimiter == '\\') { fprintf(outfile, "** Delimiter must not be alphameric or \\\n"); goto SKIP_DATA; } pp = p; for(;;) { while (*pp != 0) { if (*pp == '\\' && pp[1] != 0) pp++; else if (*pp == delimiter) break; pp++; } if (*pp != 0) break; len = sizeof(buffer) - (pp - buffer); if (len < 256) { fprintf(outfile, "** Expression too long - missing delimiter?\n"); goto SKIP_DATA; } if (infile == stdin) printf(" > "); if (fgets((char *)pp, len, infile) == NULL) { fprintf(outfile, "** Unexpected EOF\n"); done = 1; goto CONTINUE; } if (infile != stdin) fprintf(outfile, "%s", (char *)pp); } /* If the first character after the delimiter is backslash, make the pattern end with backslash. This is purely to provide a way of testing for the error message when a pattern ends with backslash. */ if (pp[1] == '\\') *pp++ = '\\'; /* Terminate the pattern at the delimiter */ *pp++ = 0; /* Look for options after final delimiter */ options = 0; study_options = 0; log_store = showstore; /* default from command line */ while (*pp != 0) { switch (*pp++) { case 'g': do_g = 1; break; case 'i': options |= PCRE_CASELESS; break; case 'm': options |= PCRE_MULTILINE; break; case 's': options |= PCRE_DOTALL; break; case 'x': options |= PCRE_EXTENDED; break; case '+': do_showrest = 1; break; case 'A': options |= PCRE_ANCHORED; break; case 'D': do_debug = do_showinfo = 1; break; case 'E': options |= PCRE_DOLLAR_ENDONLY; break; case 'G': do_G = 1; break; case 'I': do_showinfo = 1; break; case 'M': log_store = 1; break; #if !defined NOPOSIX case 'P': do_posix = 1; break; #endif case 'S': do_study = 1; break; case 'U': options |= PCRE_UNGREEDY; break; case 'X': options |= PCRE_EXTRA; break; case '8': options |= PCRE_UTF8; utf8 = 1; break; case 'L': ppp = pp; while (*ppp != '\n' && *ppp != ' ') ppp++; *ppp = 0; if (setlocale(LC_CTYPE, (const char *)pp) == NULL) { fprintf(outfile, "** Failed to set locale \"%s\"\n", pp); goto SKIP_DATA; } tables = pcre_maketables(); pp = ppp; break; case '\n': case ' ': break; default: fprintf(outfile, "** Unknown option '%c'\n", pp[-1]); goto SKIP_DATA; } } /* Handle compiling via the POSIX interface, which doesn't support the timing, showing, or debugging options, nor the ability to pass over local character tables. */ #if !defined NOPOSIX if (posix || do_posix) { int rc; int cflags = 0; if ((options & PCRE_CASELESS) != 0) cflags |= REG_ICASE; if ((options & PCRE_MULTILINE) != 0) cflags |= REG_NEWLINE; rc = regcomp(&preg, (char *)p, cflags); /* Compilation failed; go back for another re, skipping to blank line if non-interactive. */ if (rc != 0) { (void)regerror(rc, &preg, (char *)buffer, sizeof(buffer)); fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer); goto SKIP_DATA; } } /* Handle compiling via the native interface */ else #endif /* !defined NOPOSIX */ { if (timeit) { register int i; clock_t time_taken; clock_t start_time = clock(); for (i = 0; i < LOOPREPEAT; i++) { re = pcre_compile((char *)p, options, &error, &erroroffset, tables); if (re != NULL) free(re); } time_taken = clock() - start_time; fprintf(outfile, "Compile time %.3f milliseconds\n", ((double)time_taken * 1000.0) / ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC)); } re = pcre_compile((char *)p, options, &error, &erroroffset, tables); /* Compilation failed; go back for another re, skipping to blank line if non-interactive. */ if (re == NULL) { fprintf(outfile, "Failed: %s at offset %d\n", error, erroroffset); SKIP_DATA: if (infile != stdin) { for (;;) { if (fgets((char *)buffer, sizeof(buffer), infile) == NULL) { done = 1; goto CONTINUE; } len = (int)strlen((char *)buffer); while (len > 0 && isspace(buffer[len-1])) len--; if (len == 0) break; } fprintf(outfile, "\n"); } goto CONTINUE; } /* Compilation succeeded; print data if required. There are now two info-returning functions. The old one has a limited interface and returns only limited data. Check that it agrees with the newer one. */ if (do_showinfo) { unsigned long int get_options; int old_first_char, old_options, old_count; int count, backrefmax, first_char, need_char; size_t size; if (do_debug) print_internals(re); new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options); new_info(re, NULL, PCRE_INFO_SIZE, &size); new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count); new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax); new_info(re, NULL, PCRE_INFO_FIRSTCHAR, &first_char); new_info(re, NULL, PCRE_INFO_LASTLITERAL, &need_char); old_count = pcre_info(re, &old_options, &old_first_char); if (count < 0) fprintf(outfile, "Error %d from pcre_info()\n", count); else { if (old_count != count) fprintf(outfile, "Count disagreement: pcre_fullinfo=%d pcre_info=%d\n", count, old_count); if (old_first_char != first_char) fprintf(outfile, "First char disagreement: pcre_fullinfo=%d pcre_info=%d\n", first_char, old_first_char); if (old_options != (int)get_options) fprintf(outfile, "Options disagreement: pcre_fullinfo=%ld pcre_info=%d\n", get_options, old_options); } if (size != gotten_store) fprintf(outfile, "Size disagreement: pcre_fullinfo=%d call to malloc for %d\n", size, gotten_store); fprintf(outfile, "Capturing subpattern count = %d\n", count); if (backrefmax > 0) fprintf(outfile, "Max back reference = %d\n", backrefmax); if (get_options == 0) fprintf(outfile, "No options\n"); else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s\n", ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "", ((get_options & PCRE_CASELESS) != 0)? " caseless" : "", ((get_options & PCRE_EXTENDED) != 0)? " extended" : "", ((get_options & PCRE_MULTILINE) != 0)? " multiline" : "", ((get_options & PCRE_DOTALL) != 0)? " dotall" : "", ((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "", ((get_options & PCRE_EXTRA) != 0)? " extra" : "", ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "", ((get_options & PCRE_UTF8) != 0)? " utf8" : ""); if (((((real_pcre *)re)->options) & PCRE_ICHANGED) != 0) fprintf(outfile, "Case state changes\n"); if (first_char == -1) { fprintf(outfile, "First char at start or follows \\n\n"); } else if (first_char < 0) { fprintf(outfile, "No first char\n"); } else { if (isprint(first_char)) fprintf(outfile, "First char = \'%c\'\n", first_char); else fprintf(outfile, "First char = %d\n", first_char); } if (need_char < 0) { fprintf(outfile, "No need char\n"); } else { if (isprint(need_char)) fprintf(outfile, "Need char = \'%c\'\n", need_char); else fprintf(outfile, "Need char = %d\n", need_char); } } /* If /S was present, study the regexp to generate additional info to help with the matching. */ if (do_study) { if (timeit) { register int i; clock_t time_taken; clock_t start_time = clock(); for (i = 0; i < LOOPREPEAT; i++) extra = pcre_study(re, study_options, &error); time_taken = clock() - start_time; if (extra != NULL) free(extra); fprintf(outfile, " Study time %.3f milliseconds\n", ((double)time_taken * 1000.0)/ ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC)); } extra = pcre_study(re, study_options, &error); if (error != NULL) fprintf(outfile, "Failed to study: %s\n", error); else if (extra == NULL) fprintf(outfile, "Study returned NULL\n"); else if (do_showinfo) { uschar *start_bits = NULL; new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits); if (start_bits == NULL) fprintf(outfile, "No starting character set\n"); else { int i; int c = 24; fprintf(outfile, "Starting character set: "); for (i = 0; i < 256; i++) { if ((start_bits[i/8] & (1<<(i%8))) != 0) { if (c > 75) { fprintf(outfile, "\n "); c = 2; } if (isprint(i) && i != ' ') { fprintf(outfile, "%c ", i); c += 2; } else { fprintf(outfile, "\\x%02x ", i); c += 5; } } } fprintf(outfile, "\n"); } } } } /* Read data lines and test them */ for (;;) { unsigned char *q; unsigned char *bptr = dbuffer; int *use_offsets = offsets; int use_size_offsets = size_offsets; int count, c; int copystrings = 0; int getstrings = 0; int getlist = 0; int gmatched = 0; int start_offset = 0; int g_notempty = 0; options = 0; if (infile == stdin) printf("data> "); if (fgets((char *)buffer, sizeof(buffer), infile) == NULL) { done = 1; goto CONTINUE; } if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); len = (int)strlen((char *)buffer); while (len > 0 && isspace(buffer[len-1])) len--; buffer[len] = 0; if (len == 0) break; p = buffer; while (isspace(*p)) p++; q = dbuffer; while ((c = *p++) != 0) { int i = 0; int n = 0; if (c == '\\') switch ((c = *p++)) { case 'a': c = 7; break; case 'b': c = '\b'; break; case 'e': c = 27; break; case 'f': c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'v': c = '\v'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': c -= '0'; while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9') c = c * 8 + *p++ - '0'; break; case 'x': /* Handle \x{..} specially - new Perl thing for utf8 */ if (*p == '{') { unsigned char *pt = p; c = 0; while (isxdigit(*(++pt))) c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'W'); if (*pt == '}') { unsigned char buffer[8]; int ii, utn; utn = ord2utf8(c, buffer); for (ii = 0; ii < utn - 1; ii++) *q++ = buffer[ii]; c = buffer[ii]; /* Last byte */ p = pt + 1; break; } /* Not correct form; fall through */ } /* Ordinary \x */ c = 0; while (i++ < 2 && isxdigit(*p)) { c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'W'); p++; } break; case 0: /* Allows for an empty line */ p--; continue; case 'A': /* Option setting */ options |= PCRE_ANCHORED; continue; case 'B': options |= PCRE_NOTBOL; continue; case 'C': while(isdigit(*p)) n = n * 10 + *p++ - '0'; copystrings |= 1 << n; continue; case 'G': while(isdigit(*p)) n = n * 10 + *p++ - '0'; getstrings |= 1 << n; continue; case 'L': getlist = 1; continue; case 'N': options |= PCRE_NOTEMPTY; continue; case 'O': while(isdigit(*p)) n = n * 10 + *p++ - '0'; if (n > size_offsets_max) { size_offsets_max = n; free(offsets); use_offsets = offsets = malloc(size_offsets_max * sizeof(int)); if (offsets == NULL) { printf("** Failed to get %d bytes of memory for offsets vector\n", size_offsets_max * sizeof(int)); return 1; } } use_size_offsets = n; if (n == 0) use_offsets = NULL; continue; case 'Z': options |= PCRE_NOTEOL; continue; } *q++ = c; } *q = 0; len = q - dbuffer; /* Handle matching via the POSIX interface, which does not support timing. */ #if !defined NOPOSIX if (posix || do_posix) { int rc; int eflags = 0; regmatch_t *pmatch = malloc(sizeof(regmatch_t) * use_size_offsets); if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL; if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL; rc = regexec(&preg, (const char *)bptr, use_size_offsets, pmatch, eflags); if (rc != 0) { (void)regerror(rc, &preg, (char *)buffer, sizeof(buffer)); fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer); } else { size_t i; for (i = 0; i < use_size_offsets; i++) { if (pmatch[i].rm_so >= 0) { fprintf(outfile, "%2d: ", (int)i); pchars(dbuffer + pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so, utf8); fprintf(outfile, "\n"); if (i == 0 && do_showrest) { fprintf(outfile, " 0+ "); pchars(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo, utf8); fprintf(outfile, "\n"); } } } } free(pmatch); } /* Handle matching via the native interface - repeats for /g and /G */ else #endif /* !defined NOPOSIX */ for (;; gmatched++) /* Loop for /g or /G */ { if (timeit) { register int i; clock_t time_taken; clock_t start_time = clock(); for (i = 0; i < LOOPREPEAT; i++) count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets); time_taken = clock() - start_time; fprintf(outfile, "Execute time %.3f milliseconds\n", ((double)time_taken * 1000.0)/ ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC)); } count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets); if (count == 0) { fprintf(outfile, "Matched, but too many substrings\n"); count = use_size_offsets/3; } /* Matched */ if (count >= 0) { int i; for (i = 0; i < count * 2; i += 2) { if (use_offsets[i] < 0) fprintf(outfile, "%2d: <unset>\n", i/2); else { fprintf(outfile, "%2d: ", i/2); pchars(bptr + use_offsets[i], use_offsets[i+1] - use_offsets[i], utf8); fprintf(outfile, "\n"); if (i == 0) { if (do_showrest) { fprintf(outfile, " 0+ "); pchars(bptr + use_offsets[i+1], len - use_offsets[i+1], utf8); fprintf(outfile, "\n"); } } } } for (i = 0; i < 32; i++) { if ((copystrings & (1 << i)) != 0) { char copybuffer[16]; int rc = pcre_copy_substring((char *)bptr, use_offsets, count, i, copybuffer, sizeof(copybuffer)); if (rc < 0) fprintf(outfile, "copy substring %d failed %d\n", i, rc); else fprintf(outfile, "%2dC %s (%d)\n", i, copybuffer, rc); } } for (i = 0; i < 32; i++) { if ((getstrings & (1 << i)) != 0) { const char *substring; int rc = pcre_get_substring((char *)bptr, use_offsets, count, i, &substring); if (rc < 0) fprintf(outfile, "get substring %d failed %d\n", i, rc); else { fprintf(outfile, "%2dG %s (%d)\n", i, substring, rc); /* free((void *)substring); */ pcre_free_substring(substring); } } } if (getlist) { const char **stringlist; int rc = pcre_get_substring_list((char *)bptr, use_offsets, count, &stringlist); if (rc < 0) fprintf(outfile, "get substring list failed %d\n", rc); else { for (i = 0; i < count; i++) fprintf(outfile, "%2dL %s\n", i, stringlist[i]); if (stringlist[i] != NULL) fprintf(outfile, "string list not terminated by NULL\n"); /* free((void *)stringlist); */ pcre_free_substring_list(stringlist); } } } /* Failed to match. If this is a /g or /G loop and we previously set g_notempty after a null match, this is not necessarily the end. We want to advance the start offset, and continue. Fudge the offset values to achieve this. We won't be at the end of the string - that was checked before setting g_notempty. */ else { if (g_notempty != 0) { use_offsets[0] = start_offset; use_offsets[1] = start_offset + 1; } else { if (gmatched == 0) /* Error if no previous matches */ { if (count == -1) fprintf(outfile, "No match\n"); else fprintf(outfile, "Error %d\n", count); } break; /* Out of the /g loop */ } } /* If not /g or /G we are done */ if (!do_g && !do_G) break; /* If we have matched an empty string, first check to see if we are at the end of the subject. If so, the /g loop is over. Otherwise, mimic what Perl's /g options does. This turns out to be rather cunning. First we set PCRE_NOTEMPTY and PCRE_ANCHORED and try the match again at the same point. If this fails (picked up above) we advance to the next character. */ g_notempty = 0; if (use_offsets[0] == use_offsets[1]) { if (use_offsets[0] == len) break; g_notempty = PCRE_NOTEMPTY | PCRE_ANCHORED; } /* For /g, update the start offset, leaving the rest alone */ if (do_g) start_offset = use_offsets[1]; /* For /G, update the pointer and length */ else { bptr += use_offsets[1]; len -= use_offsets[1]; } } /* End of loop for /g and /G */ } /* End of loop for data lines */ CONTINUE: #if !defined NOPOSIX if (posix || do_posix) regfree(&preg); #endif if (re != NULL) free(re); if (extra != NULL) free(extra); if (tables != NULL) { free((void *)tables); setlocale(LC_CTYPE, "C"); } } fprintf(outfile, "\n"); return 0; }
/* Makes OCaml-string from PCRE-version */ CAMLprim value pcre_version_stub(value __unused v_unit) { return caml_copy_string((char *) pcre_version()); }
int main(int argc, char **argv) { set_log_level(LOG_LEVEL_WARN); #ifdef AG_DEBUG set_log_level(LOG_LEVEL_DEBUG); int i = 0; for (i = 0; i < argc; i++) { fprintf(stderr, "%s ", argv[i]); } fprintf(stderr, "\n"); #endif char *query = NULL; char *path = NULL; int pcre_opts = 0; int study_opts = 0; const char *pcre_err = NULL; int pcre_err_offset = 0; pcre *re = NULL; pcre_extra *re_extra = NULL; struct timeval time_start, time_end; double time_diff = 0.0; gettimeofday(&time_start, NULL); parse_options(argc, argv, &query, &path); if (opts.casing == CASE_INSENSITIVE) { pcre_opts = pcre_opts | PCRE_CASELESS; } log_debug("PCRE Version: %s", pcre_version()); if (!opts.literal) { re = pcre_compile(query, pcre_opts, &pcre_err, &pcre_err_offset, NULL); if (re == NULL) { log_err("pcre_compile failed at position %i. Error: %s", pcre_err_offset, pcre_err); exit(1); } #ifdef USE_PRCE_JIT int has_jit = 0; pcre_config(PCRE_CONFIG_JIT, &has_jit); if (has_jit) { study_opts = study_opts | PCRE_STUDY_JIT_COMPILE; } #endif re_extra = pcre_study(re, study_opts, &pcre_err); if (re_extra == NULL) { log_err("pcre_study failed. Error: %s", pcre_err); exit(1); } } search_dir(re, re_extra, path, 0); if (opts.stats) { gettimeofday(&time_end, NULL); time_diff = ((long)time_end.tv_sec * 1000000 + time_end.tv_usec) - ((long)time_start.tv_sec * 1000000 + time_start.tv_usec); time_diff = time_diff / 1000000; printf("%ld files\n%ld bytes\n%f seconds\n", total_file_count, total_byte_count, time_diff); } pcre_free(re); pcre_free(re_extra); /* TODO I'm pretty sure I should call pcre_free_study() here */ free(query); free(path); cleanup_ignore_patterns(); return(0); }
char const *regex_version(void) { return pcre_version(); }
int main(int argc, char **argv) { char **paths = NULL; int i; int pcre_opts = PCRE_MULTILINE; int study_opts = 0; double time_diff; pthread_t *workers = NULL; int workers_len; set_log_level(LOG_LEVEL_WARN); work_queue = NULL; work_queue_tail = NULL; memset(&stats, 0, sizeof(stats)); root_ignores = init_ignore(NULL); out_fd = stdout; #ifdef USE_PCRE_JIT int has_jit = 0; pcre_config(PCRE_CONFIG_JIT, &has_jit); if (has_jit) { study_opts |= PCRE_STUDY_JIT_COMPILE; } #endif gettimeofday(&(stats.time_start), NULL); parse_options(argc, argv, &paths); log_debug("PCRE Version: %s", pcre_version()); if (opts.workers) { workers_len = opts.workers; } else { /* Experiments show that two worker threads appear to be optimal, both * on dual-core and quad-core systems. See * http://geoff.greer.fm/2012/09/07/the-silver-searcher-adding-pthreads/. * On single-core CPUs, more than one worker thread makes no sense. */ int ncpus = (int)sysconf(_SC_NPROCESSORS_ONLN); workers_len = (ncpus >= 2) ? 2 : 1; } log_debug("Using %i workers", workers_len); done_adding_files = FALSE; workers = ag_calloc(workers_len, sizeof(pthread_t)); if (pthread_cond_init(&files_ready, NULL)) { log_err("pthread_cond_init failed!"); exit(2); } if (pthread_mutex_init(&print_mtx, NULL)) { log_err("pthread_mutex_init failed!"); exit(2); } if (pthread_mutex_init(&stats_mtx, NULL)) { log_err("pthread_mutex_init failed!"); exit(2); } if (pthread_mutex_init(&work_queue_mtx, NULL)) { log_err("pthread_mutex_init failed!"); exit(2); } if (opts.casing == CASE_SMART) { opts.casing = contains_uppercase(opts.query) ? CASE_SENSITIVE : CASE_INSENSITIVE; } if (opts.literal) { if (opts.casing == CASE_INSENSITIVE) { /* Search routine needs the query to be lowercase */ char *c = opts.query; for (; *c != '\0'; ++c) { *c = (char) tolower(*c); } } generate_skip_lookup(opts.query, opts.query_len, skip_lookup, opts.casing == CASE_SENSITIVE); if (opts.word_regexp) { init_wordchar_table(); opts.literal_starts_wordchar = is_wordchar(opts.query[0]); opts.literal_ends_wordchar = is_wordchar(opts.query[opts.query_len - 1]); } } else { if (opts.casing == CASE_INSENSITIVE) { pcre_opts = pcre_opts | PCRE_CASELESS; } if (opts.word_regexp) { char *word_regexp_query; asprintf(&word_regexp_query, "\\b%s\\b", opts.query); free(opts.query); opts.query = word_regexp_query; opts.query_len = strlen(opts.query); } compile_study(&opts.re, &opts.re_extra, opts.query, pcre_opts, study_opts); } if (opts.search_stream) { search_stream(stdin, ""); } else { for (i = 0; i < workers_len; i++) { int ptc_rc = pthread_create(&(workers[i]), NULL, &search_file_worker, NULL); check_err(ptc_rc, "create worker thread"); } for (i = 0; paths[i] != NULL; i++) { log_debug("searching path %s for %s", paths[i], opts.query); search_dir(root_ignores, paths[i], 0); } done_adding_files = TRUE; pthread_cond_broadcast(&files_ready); for (i = 0; i < workers_len; i++) { if (pthread_join(workers[i], NULL)) { log_err("pthread_join failed!"); exit(2); } } } if (opts.stats) { gettimeofday(&(stats.time_end), NULL); time_diff = ((long)stats.time_end.tv_sec * 1000000 + stats.time_end.tv_usec) - ((long)stats.time_start.tv_sec * 1000000 + stats.time_start.tv_usec); time_diff /= 1000000; printf("%ld matches\n%ld files searched\n%ld bytes searched\n%f seconds\n", stats.total_matches, stats.total_files, stats.total_bytes, time_diff); } if (opts.pager) { pclose(out_fd); } pthread_cond_destroy(&files_ready); pthread_mutex_destroy(&work_queue_mtx); pthread_mutex_destroy(&stats_mtx); pthread_mutex_destroy(&print_mtx); cleanup_ignore(root_ignores); free(workers); free(paths); return 0; }
static int Lpcre_version (lua_State *L) { lua_pushstring (L, pcre_version ()); return 1; }
int main (int argc, char *argv[]) { int i, j, n, res; regex_t regex; char buffer[1024]; regmatch_t matches[MAX_MATCHES]; /* At least one argument, -h | --help | <regex> */ if (argc < 2) { usage (argv[0]); exit (1); } /* Help */ if ( (strcmp (argv[1], "-h") == 0) || (strcmp (argv[1], "--help") == 0) ) { usage (argv[0]); exit (0); } /* Show version */ if ( (strcmp (argv[1], "-v") == 0) || (strcmp (argv[1], "--version") == 0) ) { printf ("Pcre version is %s\n", pcre_version()); exit (0); } /* Compile regex */ res = regcomp (®ex, argv[1], 0); if (res != 0) { (void) regerror (res, ®ex, buffer, sizeof(buffer)); fprintf (stderr, "ERROR: Compilation has failed with error: %s\n", buffer); exit (1); } /* Check strings */ for (i = 3; i <= argc; i++) { /* Compile */ res = regexec (®ex, argv[i-1], MAX_MATCHES, matches, 0); if (res == REG_NOMATCH) { printf ("No match\n"); continue; } if (res != 0) { (void) regerror (res, ®ex, buffer, sizeof(buffer)); fprintf (stderr, "ERROR: Execution has failed with error: %s\n", buffer); exit (1); } /* Print result */ print_match (matches[0]); /* Count matching substrings */ n = 0; for (j = MAX_MATCHES - 1; j >= 0; j--) { if (matches[j].rm_so != -1) { n = j; break; } } /* Print matching substrings */ for (j = 1; j <= n; j++) { print_match (matches[j]); } } /* Cleanup */ regfree (®ex); /* Done */ exit (0); }