am_config_t *am_parse_config_xml(unsigned long instance_id, const char *xml, size_t xml_sz, char log_enable) { static const char *thisfunc = "am_parse_config_xml():"; am_config_t *r = NULL; char *begin, *stream = NULL; size_t data_sz; pcre *x = NULL; const char *error = NULL; int erroroffset; am_xml_parser_ctx_t xctx = {.setting_value = 0, .conf = NULL, .rgx = NULL, .parser = NULL, .log_enable = log_enable, .data_sz = 0, .data = NULL, .status = AM_SUCCESS}; if (xml == NULL || xml_sz == 0) { AM_LOG_ERROR(instance_id, "%s memory allocation error", thisfunc); return NULL; } /* match [key]=value returned within <value>[key]=value_of_a_key</value> element */ x = pcre_compile("(?<=\\[)(.+?)(?=\\])\\]\\s*\\=\\s*(.+)", 0, &error, &erroroffset, NULL); if (x == NULL) { AM_LOG_ERROR(instance_id, "%s pcre error %s", thisfunc, error == NULL ? "" : error); } r = calloc(1, sizeof (am_config_t)); if (r == NULL) { AM_LOG_ERROR(instance_id, "%s memory allocation error", thisfunc); pcre_free(x); return NULL; } r->instance_id = instance_id; begin = strstr(xml, "![CDATA["); if (begin != NULL) { char *end = strstr(begin + 8, "]]>"); if (end != NULL) { stream = begin + 8; data_sz = end - (begin + 8); } } else { /* no CDATA */ stream = (char *) xml; data_sz = xml_sz; } if (stream != NULL && data_sz > 0) { XML_Parser parser = XML_ParserCreate("UTF-8"); xctx.parser = &parser; xctx.conf = r; xctx.rgx = x; XML_SetUserData(parser, &xctx); XML_SetElementHandler(parser, start_element, end_element); XML_SetCharacterDataHandler(parser, character_data); XML_SetEntityDeclHandler(parser, entity_declaration); if (XML_Parse(parser, stream, (int) data_sz, XML_TRUE) == XML_STATUS_ERROR) { const char *message = XML_ErrorString(XML_GetErrorCode(parser)); XML_Size line = XML_GetCurrentLineNumber(parser); XML_Size col = XML_GetCurrentColumnNumber(parser); AM_LOG_ERROR(instance_id, "%s xml parser error (%lu:%lu) %s", thisfunc, (unsigned long) line, (unsigned long) col, message); am_config_free(&r); r = NULL; } else { r->ts = time(NULL); } XML_ParserFree(parser); } if (xctx.status != AM_SUCCESS) { AM_LOG_ERROR(instance_id, "%s %s", thisfunc, am_strerror(xctx.status)); } pcre_free(x); decrypt_agent_passwords(r); update_agent_configuration_ttl(r); return r; }
static bool StringMatchInternal(const char *regex, const char *str, int *start, int *end) { assert(regex); assert(str); if (strcmp(regex, str) == 0) { if (start) { *start = 0; } if (end) { *end = strlen(str); } return true; } pcre *pattern = NULL; { const char *errorstr; int erroffset; pattern = pcre_compile(regex, PCRE_MULTILINE | PCRE_DOTALL, &errorstr, &erroffset, NULL); } assert(pattern); if (pattern == NULL) { return false; } int ovector[STRING_MATCH_OVECCOUNT] = { 0 }; int result = pcre_exec(pattern, NULL, str, strlen(str), 0, 0, ovector, STRING_MATCH_OVECCOUNT); if (result) { if (start) { *start = ovector[0]; } if (end) { *end = ovector[1]; } } else { if (start) { *start = 0; } if (end) { *end = 0; } } free(pattern); return result >= 0; }
/*! \brief Convert the file content into regular expresions and store them in pcres */ static int load_pcres(int action) { int i, j; FILE *f; char line[FILE_MAX_LINE]; char **patterns = NULL; pcre *pcre_tmp = NULL; int pcre_size; int pcre_rc; const char *pcre_error; int pcre_erroffset; int num_pcres_tmp = 0; pcre **pcres_tmp = NULL; /* Get the lock */ lock_get(reload_lock); if (!(f = fopen(file, "r"))) { LM_ERR("could not open file '%s'\n", file); goto err; } /* Array containing each pattern in the file */ if ((patterns = pkg_malloc(sizeof(char*) * max_groups)) == 0) { LM_ERR("no more memory for patterns\n"); fclose(f); goto err; } for (i=0; i<max_groups; i++) { patterns[i] = NULL; } for (i=0; i<max_groups; i++) { if ((patterns[i] = pkg_malloc(sizeof(char) * group_max_size)) == 0) { LM_ERR("no more memory for patterns[%d]\n", i); fclose(f); goto err; } memset(patterns[i], '\0', group_max_size); } /* Read the file and extract the patterns */ memset(line, '\0', FILE_MAX_LINE); i = -1; while (fgets(line, FILE_MAX_LINE, f) != NULL) { /* Ignore comments and lines starting by space, tab, CR, LF */ if(isspace(line[0]) || line[0]=='#') { memset(line, '\0', FILE_MAX_LINE); continue; } /* First group */ if (i == -1 && line[0] != '[') { LM_ERR("first group must be initialized with [0] before any regular expression\n"); fclose(f); goto err; } /* New group */ if (line[0] == '[') { i++; /* Check if there are more patterns than the max value */ if (i >= max_groups) { LM_ERR("max patterns exceded\n"); fclose(f); goto err; } /* Start the regular expression with '(' */ patterns[i][0] = '('; memset(line, '\0', FILE_MAX_LINE); continue; } /* Check if the patter size is too big (aprox) */ if (strlen(patterns[i]) + strlen(line) >= group_max_size - 2) { LM_ERR("pattern max file exceded\n"); fclose(f); goto err; } /* Append ')' at the end of the line */ if (line[strlen(line) - 1] == '\n') { line[strlen(line)] = line[strlen(line) - 1]; line[strlen(line) - 2] = ')'; } else { /* This is the last char in the file and it's not \n */ line[strlen(line)] = ')'; } /* Append '(' at the beginning of the line */ memcpy(patterns[i]+strlen(patterns[i]), "(", 1); /* Append the line to the current pattern */ memcpy(patterns[i]+strlen(patterns[i]), line, strlen(line)); memset(line, '\0', FILE_MAX_LINE); } num_pcres_tmp = i + 1; fclose(f); /* Fix the patterns */ for (i=0; i < num_pcres_tmp; i++) { /* Convert empty groups in unmatcheable regular expression ^$ */ if (strlen(patterns[i]) == 1) { patterns[i][0] = '^'; patterns[i][1] = '$'; patterns[i][2] = '\0'; continue; } /* Delete possible '\n' at the end of the pattern */ if (patterns[i][strlen(patterns[i])-1] == '\n') { patterns[i][strlen(patterns[i])-1] = '\0'; } /* Replace '\n' with '|' (except at the end of the pattern) */ for (j=0; j < strlen(patterns[i]); j++) { if (patterns[i][j] == '\n' && j != strlen(patterns[i])-1) { patterns[i][j] = '|'; } } /* Add ')' at the end of the pattern */ patterns[i][strlen(patterns[i])] = ')'; } /* Log the group patterns */ LM_NOTICE("num groups = %d\n\n", num_pcres_tmp); for (i=0; i < num_pcres_tmp; i++) { LM_NOTICE("<group[%d]>%s</group[%d]> (size = %i)\n", i, patterns[i], i, (int)strlen(patterns[i])); } /* Temporal pointer of pcres */ if ((pcres_tmp = pkg_malloc(sizeof(pcre *) * num_pcres_tmp)) == 0) { LM_ERR("no more memory for pcres_tmp\n"); goto err; } for (i=0; i<num_pcres_tmp; i++) { pcres_tmp[i] = NULL; } /* Compile the patters */ for (i=0; i<num_pcres_tmp; i++) { pcre_tmp = pcre_compile(patterns[i], pcre_options, &pcre_error, &pcre_erroffset, NULL); if (pcre_tmp == NULL) { LM_ERR("pcre_tmp compilation of '%s' failed at offset %d: %s\n", patterns[i], pcre_erroffset, pcre_error); goto err; } pcre_rc = pcre_fullinfo(pcre_tmp, NULL, PCRE_INFO_SIZE, &pcre_size); if (pcre_rc) { printf("pcre_fullinfo on compiled pattern[%i] yielded error: %d\n", i, pcre_rc); goto err; } if ((pcres_tmp[i] = pkg_malloc(pcre_size)) == 0) { LM_ERR("no more memory for pcres_tmp[%i]\n", i); goto err; } memcpy(pcres_tmp[i], pcre_tmp, pcre_size); pcre_free(pcre_tmp); pkg_free(patterns[i]); } /* Copy to shared memory */ if (action == RELOAD) { for(i=0; i<*num_pcres; i++) { /* Use the previous num_pcres value */ if (pcres[i]) { shm_free(pcres[i]); } } shm_free(pcres); } if ((pcres = shm_malloc(sizeof(pcre *) * num_pcres_tmp)) == 0) { LM_ERR("no more memory for pcres\n"); goto err; } for (i=0; i<num_pcres_tmp; i++) { pcres[i] = NULL; } for (i=0; i<num_pcres_tmp; i++) { pcre_rc = pcre_fullinfo(pcres_tmp[i], NULL, PCRE_INFO_SIZE, &pcre_size); if ((pcres[i] = shm_malloc(pcre_size)) == 0) { LM_ERR("no more memory for pcres[%i]\n", i); goto err; } memcpy(pcres[i], pcres_tmp[i], pcre_size); } *num_pcres = num_pcres_tmp; *pcres_addr = pcres; /* Free used memory */ for (i=0; i<num_pcres_tmp; i++) { pkg_free(pcres_tmp[i]); } pkg_free(pcres_tmp); pkg_free(patterns); lock_release(reload_lock); return 0; err: if (patterns) { for(i=0; i<max_groups; i++) { if (patterns[i]) { pkg_free(patterns[i]); } } pkg_free(patterns); } if (pcres_tmp) { for (i=0; i<num_pcres_tmp; i++) { if (pcres_tmp[i]) { pkg_free(pcres_tmp[i]); } } pkg_free(pcres_tmp); } if (reload_lock) { lock_release(reload_lock); } if (action == START) { free_shared_memory(); } return -1; }
/*zwraca NULL - ok inaczej komunkat błedu- niezgodny*/ char* bmdconf_read_and_parse_config(FILE *fileconf,struct bmdconf_mem_list **dumped ) { char *wiersz,*sub1,*sub2; char *aktualna_sekcja=NULL; long nr_wiersza=1; const char *error_pointer; int error_offset; int subpatterns[20]; pcre *sekcja_regex, *assign_regex,*komentarz_regex; char *wzorzec_sekcja="^\\[([_a-zA-Z][_0-9a-zA-Z]*?)\\]\\s*(#.*)*$"; char *wzorzec_assign="^([_a-zA-Z][_0-9a-zA-Z]*)\\s*=\\s*\"([^\"]*?)\"\\s*(#.*)*$"; char *wzorzec_komentarz="^\\s*(#.*)*$"; struct bmdconf_lista *sekcje=NULL; struct bmdconf_lista *opcje=NULL; bmdconf_init_list(dumped); /*wozrzec_sekcja - do sprawdzania poprawnosci dekaracji sekcji*/ sekcja_regex=pcre_compile(wzorzec_sekcja,PCRE_UTF8,&error_pointer,&error_offset,NULL); /*wzorzec_assign - do sprawdzenia poprawnosci przpisania wartosci do pola*/ assign_regex=pcre_compile(wzorzec_assign,PCRE_UTF8,&error_pointer,&error_offset,NULL); /*wzorzez_komentarz - do sprawdzenia poprawnośći pustej lini, komentarza*/ komentarz_regex=pcre_compile(wzorzec_komentarz,PCRE_UTF8,&error_pointer,&error_offset,NULL); bmdconf_init_lista(&sekcje); while( (wiersz=bmdconf_wiersz_pliku(fileconf))!=NULL ) { /*jesli linia pusta "\n"*/ if(strcmp(wiersz,"\n")==0) { nr_wiersza++; free(wiersz); continue; } /*jesli deklaracja sekcji*/ if( pcre_exec(sekcja_regex,NULL,wiersz,(int)strlen(wiersz),0,0,subpatterns,20) > 0 ) { /*tworzenie nowej listy do sprawdzania wielokrotnosci wystepowania tej samej opcji w sekcji */ bmdconf_niszcz_liste(&opcje); bmdconf_init_lista(&opcje); if(aktualna_sekcja!=NULL) free(aktualna_sekcja); aktualna_sekcja=bmdconf_substr(wiersz,subpatterns[2],subpatterns[3]); /*jesli nie ma w liscie sekcji, a wiec nowa deklaracja*/ if(bmdconf_znajdz_element(&sekcje,aktualna_sekcja)==0) bmdconf_dodaj_element(&sekcje,aktualna_sekcja); /*znalazl w liscie sekcji wiec podwojna deklaracja*/ else { free(aktualna_sekcja); bmdconf_niszcz_liste(&sekcje); bmdconf_niszcz_liste(&opcje); bmdconf_delete_list(dumped); sub1=bmdconf_itostr(nr_wiersza); sub2=bmdconf_strmerge("Blad w lini nr:",sub1); bmdconf_strmerge_free(sub1); sub1=bmdconf_strmerge(sub2," -> wielokrotna deklaracja sekcji"); bmdconf_strmerge_free(sub2); pcre_free(sekcja_regex); pcre_free(assign_regex); pcre_free(komentarz_regex); free(wiersz); return sub1; } nr_wiersza++; } else { /*jesli przypisanie wartosci do pola*/ if( pcre_exec(assign_regex,NULL,wiersz,(int)strlen(wiersz),0,0,subpatterns,20) > 0 ) { /*brak deklaracji sekcji na poczatku pliku*/ if(aktualna_sekcja==NULL) { bmdconf_delete_list(dumped); bmdconf_niszcz_liste(&sekcje); bmdconf_niszcz_liste(&opcje); sub1=bmdconf_itostr(nr_wiersza); sub2=bmdconf_strmerge("Blad: brak deklaracji sekcji -> linia:",sub1); bmdconf_strmerge_free(sub1); pcre_free(sekcja_regex); pcre_free(assign_regex); pcre_free(komentarz_regex); free(wiersz); return sub2; } /**/ sub1=bmdconf_substr(wiersz, subpatterns[2],subpatterns[3]); if(subpatterns[4]!=subpatterns[5]) { sub2=bmdconf_substr(wiersz, subpatterns[4],subpatterns[5]); } else { sub2=(char*)malloc(sizeof(char)); sub2[0]='\0'; } /*nie ma w liscie opcji tych, ktore pojawily sie w sekcji*/ if(bmdconf_znajdz_element(&opcje,sub1)==0) bmdconf_dodaj_element(&opcje,sub1); /*powtorzyla sie opcja w sekcji*/ else { free(aktualna_sekcja);/*dodane po wyciekach*/ bmdconf_delete_list(dumped); bmdconf_niszcz_liste(&sekcje); bmdconf_niszcz_liste(&opcje); bmdconf_substr_free(sub1); bmdconf_substr_free(sub2); sub1=bmdconf_itostr(nr_wiersza); sub2=bmdconf_strmerge("Blad w lini nr:",sub1); bmdconf_strmerge_free(sub1); sub1=bmdconf_strmerge(sub2," -> powtorne wystapienie opcji w sekcji"); bmdconf_strmerge_free(sub2); pcre_free(sekcja_regex); pcre_free(assign_regex); pcre_free(komentarz_regex); free(wiersz); return sub1; } bmdconf_add_list_item(dumped,nr_wiersza,aktualna_sekcja,sub1,sub2); bmdconf_substr_free(sub1); bmdconf_substr_free(sub2); nr_wiersza++; } else { /*jesli linia niezgodna z formatem*/ if( pcre_exec(komentarz_regex,NULL,wiersz,(int)strlen(wiersz),0,0,subpatterns,20) <= 0 ) { bmdconf_delete_list(dumped); bmdconf_niszcz_liste(&sekcje); bmdconf_niszcz_liste(&opcje); if(aktualna_sekcja!=NULL) free(aktualna_sekcja); sub1=bmdconf_itostr(nr_wiersza); sub2=bmdconf_strmerge("Blad skladni w lini nr:",sub1); bmdconf_strmerge_free(sub1); pcre_free(sekcja_regex); pcre_free(assign_regex); pcre_free(komentarz_regex); free(wiersz); return sub2; } /*komentarz badz spajce/tab*/ else nr_wiersza++; } } free(wiersz); } if(aktualna_sekcja!=NULL) free(aktualna_sekcja); bmdconf_niszcz_liste(&sekcje); /*dodane po wyciekach*/ bmdconf_niszcz_liste(&opcje); /**/ pcre_free(sekcja_regex); pcre_free(assign_regex); pcre_free(komentarz_regex); return NULL; }
FileScanner::FileScanner(sync_queue<std::string> &in_queue, sync_queue<MatchList> &output_queue, std::string regex, bool ignore_case, bool word_regexp, bool pattern_is_literal) : m_in_queue(in_queue), m_output_queue(output_queue), m_regex(regex), m_ignore_case(ignore_case), m_word_regexp(word_regexp), m_pattern_is_literal(pattern_is_literal), m_next_core(0), m_use_mmap(false), m_manually_assign_cores(false) { #ifdef HAVE_LIBPCRE // Compile the regex. const char *error; int error_offset; int options = 0; // For now, we won't support capturing. () will be treated as (?:). options = PCRE_NO_AUTO_CAPTURE; if(ignore_case) { // Ignore case while matching. options |= PCRE_CASELESS; } if(m_pattern_is_literal) { // Surround the pattern with \Q...\E so it's treated as a literal string. regex = "\\Q" + regex + "\\E"; } if(m_word_regexp) { // Surround the regex with \b (word boundary) assertions. regex = "\\b(?:" + regex + ")\\b"; } m_pcre_regex = pcre_compile(regex.c_str(), options, &error, &error_offset, NULL); if (m_pcre_regex == NULL) { // Regex compile failed, we can't continue. /// @todo GRVS - This should be as simple as putting a C++11 "std::to_string(error_offset)" into the string below. /// However, there's an issue with at least Cygwin's std lib and/or gcc itself which makes to_string() unavailable /// (see e.g. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61580 (fixed on gcc trunk 2015-11-13), /// https://sourceware.org/ml/cygwin/2015-01/msg00251.html). Since I don't want to wait for the fix to trickle /// out and I don't know how widespread the issue is, we'll do it the old-fashioned way. std::ostringstream ss; ss << error_offset; throw FileScannerException(std::string("Compilation of regex \"") + regex + "\" failed at offset " + ss.str() + ": " + error); } m_pcre_extra = pcre_study(m_pcre_regex, PCRE_STUDY_JIT_COMPILE, &error); if(error != NULL) { // Study error. pcre_free(m_pcre_regex); throw FileScannerException("PCRE study error: " + *error); } #endif }
void Pcompile (char const *pattern, size_t size) { #if !HAVE_LIBPCRE error (EXIT_TROUBLE, 0, "%s", _("support for the -P option is not compiled into " "this --disable-perl-regexp binary")); #else int e; char const *ep; char *re = xnmalloc (4, size + 7); int flags = (PCRE_MULTILINE | (match_icase ? PCRE_CASELESS : 0)); char const *patlim = pattern + size; char *n = re; char const *p; char const *pnul; if (using_utf8 ()) flags |= PCRE_UTF8; else if (MB_CUR_MAX != 1) error (EXIT_TROUBLE, 0, _("-P supports only unibyte and UTF-8 locales")); /* FIXME: Remove these restrictions. */ if (memchr (pattern, '\n', size)) error (EXIT_TROUBLE, 0, _("the -P option only supports a single pattern")); *n = '\0'; if (match_lines) strcpy (n, "^(?:"); if (match_words) strcpy (n, "(?<!\\w)(?:"); n += strlen (n); /* The PCRE interface doesn't allow NUL bytes in the pattern, so replace each NUL byte in the pattern with the four characters "\000", removing a preceding backslash if there are an odd number of backslashes before the NUL. FIXME: This method does not work with some multibyte character encodings, notably Shift-JIS, where a multibyte character can end in a backslash byte. */ for (p = pattern; (pnul = memchr (p, '\0', patlim - p)); p = pnul + 1) { memcpy (n, p, pnul - p); n += pnul - p; for (p = pnul; pattern < p && p[-1] == '\\'; p--) continue; n -= (pnul - p) & 1; strcpy (n, "\\000"); n += 4; } memcpy (n, p, patlim - p); n += patlim - p; *n = '\0'; if (match_words) strcpy (n, ")(?!\\w)"); if (match_lines) strcpy (n, ")$"); cre = pcre_compile (re, flags, &ep, &e, pcre_maketables ()); if (!cre) error (EXIT_TROUBLE, 0, "%s", ep); extra = pcre_study (cre, PCRE_STUDY_JIT_COMPILE, &ep); if (ep) error (EXIT_TROUBLE, 0, "%s", ep); # if PCRE_STUDY_JIT_COMPILE if (pcre_fullinfo (cre, extra, PCRE_INFO_JIT, &e)) error (EXIT_TROUBLE, 0, _("internal error (should never happen)")); /* The PCRE documentation says that a 32 KiB stack is the default. */ if (e) jit_stack_size = 32 << 10; # endif free (re); int sub[NSUB]; empty_match[false] = pcre_exec (cre, extra, "", 0, 0, PCRE_NOTBOL, sub, NSUB); empty_match[true] = pcre_exec (cre, extra, "", 0, 0, 0, sub, NSUB); #endif /* HAVE_LIBPCRE */ }
static vips* _parse_cluster_vips(range_request* rr, const char* cluster) { struct stat st; int ovector[30]; char line[32768]; int line_no; FILE* fp; apr_pool_t* req_pool = range_request_pool(rr); apr_pool_t* lr_pool = range_request_lr_pool(rr); libcrange* lr = range_request_lr(rr); set* cache = libcrange_get_cache(lr, "nodescf:cluster_vips"); const char* vips_path = apr_psprintf(req_pool, "%s/%s/vips.cf", nodescf_path, cluster); vips* v; if (!cache) { cache = set_new(lr_pool, 0); libcrange_set_cache(lr, "nodescf:cluster_vips", cache); } if (stat(vips_path, &st) == -1) { range_request_warn_type(rr, "NOVIPS", cluster); return _empty_vips(rr); } v = set_get_data(cache, vips_path); if (!v) { v = apr_palloc(lr_pool, sizeof(struct vips)); apr_pool_create(&v->pool, lr_pool); v->vips = set_new(v->pool, 0); v->viphosts = set_new(v->pool, 0); v->mtime = st.st_mtime; set_add(cache, vips_path, v); } else { time_t cached_mtime = v->mtime; if (cached_mtime != st.st_mtime) { apr_pool_clear(v->pool); v->vips = set_new(v->pool, 0); v->viphosts = set_new(v->pool, 0); v->mtime = st.st_mtime; } else /* current cached copy is good */ return v; } /* create / update the current cached copy */ fp = fopen(vips_path, "r"); if (!fp) { range_request_warn_type(rr, "NOVIPS", cluster); return _empty_vips(rr); } if (!vips_re) { const char* error; vips_re = pcre_compile("^(\\S+)\\s+(\\S+)\\s+(\\S+)\\s*$", 0, &error, ovector, NULL); assert(vips_re); } line_no = 0; while (fgets(line, sizeof line, fp)) { int len; int count; char* p; line_no++; line[sizeof line - 1] = '\0'; len = strlen(line); if (len+1 >= sizeof(line) && line[len - 1] != '\n') { /* incomplete line */ fprintf(stderr, "%s:%d lines > 32767 chars not supported\n", vips_path, line_no); exit(-1); } line[--len] = '\0'; /* get rid of the \n */ for (p = line; *p; ++p) if (*p == '#') { *p = '\0'; break; } len = strlen(line); if (len == 0) continue; for (p = &line[len - 1]; isspace(*p); --p) { *p = '\0'; --len; } if (!*line) continue; /* 68.142.248.161 as301000 eth0:1 */ count = pcre_exec(vips_re, NULL, line, len, 0, 0, ovector, 30); if (count == 4) { line[ovector[3]] = '\0'; line[ovector[5]] = '\0'; line[ovector[7]] = '\0'; set_add(v->vips, &line[ovector[2]], 0); set_add(v->viphosts, &line[ovector[4]], 0); } } fclose(fp); return v; }
void SearchContext::searchProc() { int id = searchID_; HANDLE findHandle = INVALID_HANDLE_VALUE; StringList paths; paths = params_.paths; RegexList filespecRegexes; pcre *matchRegex = NULL; directoriesSearched_ = 0; directoriesSkipped_ = 0; filesSearched_ = 0; filesSkipped_ = 0; filesWithHits_ = 0; linesWithHits_ = 0; hits_ = 0; unsigned int startTick = GetTickCount(); bool filespecUsesRegexes = ((params_.flags & SF_FILESPEC_REGEXES) != 0); bool matchUsesRegexes = ((params_.flags & SF_MATCH_REGEXES) != 0); delete pokeData_; pokeData_ = new PokeData; if(matchUsesRegexes) { const char *error; int erroffset; int flags = 0; if(!(params_.flags & SF_MATCH_CASE_SENSITIVE)) flags |= PCRE_CASELESS; matchRegex = pcre_compile(params_.match.c_str(), flags, &error, &erroffset, NULL); if(!matchRegex) { MessageBox(window_, error, "Match Regex Error", MB_OK); goto cleanup; } } for(StringList::iterator it = params_.filespecs.begin(); it != params_.filespecs.end(); ++it) { std::string regexString = it->c_str(); if(!filespecUsesRegexes) convertWildcard(regexString); int flags = 0; if(!(params_.flags & SF_FILESPEC_CASE_SENSITIVE)) flags |= PCRE_CASELESS; const char *error; int erroffset; pcre *regex = pcre_compile(regexString.c_str(), flags, &error, &erroffset, NULL); if(regex) filespecRegexes.push_back(regex); else { MessageBox(window_, error, "Filespec Regex Error", MB_OK); goto cleanup; } } PostMessage(window_, WM_SEARCHCONTEXT_STATE, 1, 0); while(!paths.empty()) { directoriesSearched_++; stopCheck(); std::string currentSearchPath = paths.back(); std::string currentSearchWildcard = currentSearchPath + "\\*"; paths.pop_back(); WIN32_FIND_DATA wfd; findHandle = FindFirstFile(currentSearchWildcard.c_str(), &wfd); if(findHandle == INVALID_HANDLE_VALUE) continue; while(FindNextFile(findHandle, &wfd)) { stopCheck(); bool isDirectory = ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0); if((wfd.cFileName[0] == '.') || (wfd.cFileName[0] == 0)) { if(isDirectory) directoriesSkipped_++; else filesSkipped_++; continue; } std::string filename = currentSearchPath; filename += "\\"; filename += wfd.cFileName; if(isDirectory) { if(params_.flags & SF_RECURSIVE) paths.push_back(filename); } else { if(searchFile(id, filename, filespecRegexes, matchRegex)) { filesSearched_++; } else { filesSkipped_++; } poke(id, "", HighlightList(), 0, false); } } if(findHandle != INVALID_HANDLE_VALUE) { FindClose(findHandle); } } cleanup: for(RegexList::iterator it = filespecRegexes.begin(); it != filespecRegexes.end(); ++it) { pcre_free(*it); } if(matchRegex) pcre_free(matchRegex); filespecRegexes.clear(); if(!stop_) { unsigned int endTick = GetTickCount(); char buffer[512]; float sec = (endTick - startTick) / 1000.0f; const char *verb = "searched"; if(params_.flags & SF_REPLACE) verb = "updated"; sprintf(buffer, "\n%d hits in %d lines across %d files.\n%d directories scanned, %d files %s, %d files skipped (%3.3f sec)", hits_, linesWithHits_, filesWithHits_, directoriesSearched_, filesSearched_, verb, filesSkipped_, sec); poke(id, buffer, HighlightList(), 0, true); } delete pokeData_; pokeData_ = NULL; PostMessage(window_, WM_SEARCHCONTEXT_STATE, 0, 0); }
static void CL_RE_Trigger_f (void) { int c,i,m; char *name; char *regexpstr; pcre_trigger_t *trig; pcre *re; pcre_extra *re_extra; const char *error; int error_offset; qbool newtrigger=false; qbool re_search = false; c = Cmd_Argc(); if (c > 3) { Com_Printf ("re_trigger <trigger name> <regexp>\n"); return; } if (c == 2 && IsRegexp(Cmd_Argv(1))) { re_search = true; } if (c == 1 || re_search) { if (!re_triggers) { Com_Printf ("no regexp_triggers defined\n"); } else { if (re_search && !ReSearchInit(Cmd_Argv(1))) return; Com_Printf ("List of re_triggers:\n"); for (trig=re_triggers, i=m=0; trig; trig=trig->next, i++) { if (!re_search || ReSearchMatch(trig->name)) { Com_Printf ("%s : \"%s\" : %d\n", trig->name, trig->regexpstr, trig->counter); m++; } } Com_Printf ("------------\n%i/%i re_triggers\n", m, i); if (re_search) ReSearchDone(); } return; } name = Cmd_Argv(1); trig = CL_FindReTrigger (name); if (c == 2) { if (trig) { Com_Printf ("%s: \"%s\"\n", trig->name, trig->regexpstr); Com_Printf (" options: mask=%d interval=%g%s%s%s%s%s\n", trig->flags & 0xFF, trig->min_interval, trig->flags & RE_FINAL ? " final" : "", trig->flags & RE_REMOVESTR ? " remove" : "", trig->flags & RE_NOLOG ? " nolog" : "", trig->flags & RE_ENABLED ? "" : " disabled", trig->flags & RE_NOACTION ? " noaction" : "" ); Com_Printf (" matched %d times\n", trig->counter); } else { Com_Printf ("re_trigger \"%s\" not found\n", name); } return; } if (c == 3) { regexpstr = Cmd_Argv(2); if (!trig) { // allocate new trigger newtrigger = true; trig = (pcre_trigger_t *) Q_malloc(sizeof(pcre_trigger_t)); trig->next = re_triggers; re_triggers = trig; trig->name = Q_strdup(name); trig->flags = RE_PRINT_ALL | RE_ENABLED; // catch all printed messages by default } error = NULL; if ((re = pcre_compile(regexpstr, 0, &error, &error_offset, NULL))) { error = NULL; re_extra = pcre_study(re, 0, &error); if (error) { Com_Printf ("Regexp study error: %s\n", &error); } else { if (!newtrigger) { (pcre_free)(trig->regexp); if (trig->regexp_extra) (pcre_free)(trig->regexp_extra); Q_free(trig->regexpstr); } trig->regexpstr = Q_strdup(regexpstr); trig->regexp = re; trig->regexp_extra = re_extra; return; } } else { Com_Printf ("Invalid regexp: %s\n", error); } prev = NULL; RemoveReTrigger(trig); } }
static int process_file(struct saved_data *data, const char *filename) { struct spec *spec; unsigned int line_num; char *line_buf = NULL; size_t line_len; ssize_t len; FILE *context_file; context_file = fopen(filename, "r"); if (!context_file) { fprintf(stderr, "Error opening %s: %s\n", filename, strerror(errno)); return -1; } line_num = 0; while ((len = getline(&line_buf, &line_len, context_file)) != -1) { char *context; char *mode; char *regex; char *cp, *anchored_regex; char *buf_p; pcre *re; pcre_extra *sd; const char *err; int items, erroff, rc; size_t regex_len; int32_t stem_id; len = strlen(line_buf); if (line_buf[len - 1] == '\n') line_buf[len - 1] = 0; buf_p = line_buf; while (isspace(*buf_p)) buf_p++; /* Skip comment lines and empty lines. */ if (*buf_p == '#' || *buf_p == 0) continue; items = sscanf(line_buf, "%ms %ms %ms", ®ex, &mode, &context); if (items < 2 || items > 3) { fprintf(stderr, "invalid entry, skipping:%s", line_buf); continue; } if (items == 2) { context = mode; mode = NULL; } rc = grow_specs(data); if (rc) { fprintf(stderr, "grow_specs failed: %s\n", strerror(errno)); return rc; } spec = &data->spec_arr[data->nspec]; spec->lr.ctx_raw = context; spec->mode = string_to_mode(mode); if (spec->mode == -1) { fprintf(stderr, "%s: line %d has invalid file type %s\n", regex, line_num + 1, mode); spec->mode = 0; } free(mode); spec->regex_str = regex; stem_id = find_stem_from_spec(data, regex); spec->stem_id = stem_id; /* skip past the fixed stem part */ if (stem_id != -1) regex += data->stem_arr[stem_id].len; regex_len = strlen(regex); cp = anchored_regex = malloc(regex_len + 3); if (!cp) { fprintf(stderr, "Malloc Failed: %s\n", strerror(errno)); return -1; } *cp++ = '^'; memcpy(cp, regex, regex_len); cp += regex_len; *cp++ = '$'; *cp = '\0'; spec_hasMetaChars(spec); re = pcre_compile(anchored_regex, 0, &err, &erroff, NULL); if (!re) { fprintf(stderr, "PCRE compilation failed for %s at offset %d: %s\n", anchored_regex, erroff, err); return -1; } spec->regex = re; sd = pcre_study(re, 0, &err); if (!sd) { fprintf(stderr, "PCRE study failed for %s: %s\n", anchored_regex, err); return -1; } free(anchored_regex); spec->sd = sd; line_num++; data->nspec++; } free(line_buf); fclose(context_file); return 0; }
void f_pcre_create(INT32 args) { struct pike_string *regexp; /* Regexp pattern */ pcre_extra *extra = NULL; /* result from study, if enabled */ pcre *re = NULL; /* compiled regexp */ int opts = 0; /* Regexp compile options */ const char *errmsg; /* Error message pointer */ int erroffset; /* Error offset */ int do_study = 1; /* Study the regexp when it's compiled */ char *pp; /* Temporary char pointer */ unsigned const char *table = NULL; /* Translation table */ #if HAVE_SETLOCALE char *locale = setlocale(LC_CTYPE, NULL); /* Get current locale for * translation table. */ #endif free_regexp(Pike_fp->current_object); switch(args) { case 2: switch(Pike_sp[-1].type) { case T_STRING: opts = parse_options(Pike_sp[-1].u.string->str, &do_study); if(opts < 0) Pike_error("PCRE.Regexp->create(): Unknown option modifier '%c'.\n", -opts); break; case T_INT: if(Pike_sp[-1].u.integer == 0) { break; } /* Fallthrough */ default: Pike_error("Bad argument 2 to PCRE.Regexp->create() - expected string.\n"); break; } /* Fall through */ case 1: if(Pike_sp[-args].type != T_STRING || Pike_sp[-args].u.string->size_shift > 0) { Pike_error("PCRE.Regexp->create(): Invalid argument 1. Expected 8-bit string.\n"); } regexp = Pike_sp[-args].u.string; if((INT32)strlen(regexp->str) != regexp->len) Pike_error("PCRE.Regexp->create(): Regexp pattern contains null characters. Use \\0 instead.\n"); break; case 0: /* Regexp() compatibility */ return; default: Pike_error("PCRE.Regexp->create(): Invalid number of arguments. Expected 1 or 2.\n"); } #if HAVE_SETLOCALE if (strcmp(locale, "C")) table = pcre_maketables(); #endif /* Compile the pattern and handle errors */ re = pcre_compile(regexp->str, opts, &errmsg, &erroffset, table); if(re == NULL) { Pike_error("Failed to compile regexp: %s at offset %d\n", errmsg, erroffset); } /* If study option was specified, study the pattern and store the result in extra for passing to pcre_exec. */ if (do_study) { extra = pcre_study(re, 0, &errmsg); if (errmsg != NULL) { Pike_error("Error while studying pattern: %s", errmsg); } } THIS->regexp = re; THIS->extra = extra; THIS->pattern = regexp; add_ref(regexp); pop_n_elems(args); }
static int maildir_filter_ruleupdate_utf8(struct maildirfilter *r, struct maildirfilterrule *p, const char *name, enum maildirfiltertype type, int flags, const char *header, const char *value, const char *folder, const char *fromhdr, int *errcode) { const char *c; struct maildirfilterrule *pom; /* ** Before creating a new rule, validate all input. */ *errcode=0; /* rule name: may not contain quotes or control characters. */ *errcode=MF_ERR_BADRULENAME; if (!*name || strlen(name) > 200) return (-1); for (c=name; *c; c++) if ((unsigned char)*c < ' ' || *c == '\'' || *c == '"' || *c == '`') return (-1); /* rule name: may not already exist */ *errcode=MF_ERR_EXISTS; for (pom=r->first; pom->next; pom=pom->next) { if (p!=pom && !strcmp(name, pom->rulename_utf8)) return (-1); } /* rule type: we must know what it is */ switch (type) { case startswith: case endswith: case contains: case hasrecipient: case mimemultipart: case textplain: case islargerthan: case anymessage: break; default: *errcode=MF_ERR_BADRULETYPE; break; } ; /* header: */ *errcode=MF_ERR_BADRULEHEADER; c=header; if (strlen(c) > 200) return (-1); if (*c == 0) { switch (type) { case hasrecipient: case islargerthan: case mimemultipart: case textplain: case anymessage: break; case contains: case startswith: case endswith: if (flags & MFR_BODY) break; /* FALLTHRU */ default: /* required */ return (-1); } } else for ( ; *c; c++) { /* no control characters */ if ((unsigned char)*c <= ' ' || *c == MDIRSEP[0] || *c == '\'' || *c == '\\' || *c == '"' || *c == '`' || *c == '/') return (-1); } /* rule pattern */ *errcode=MF_ERR_BADRULEVALUE; c=value; if (strlen(c) > 200) return (-1); if (*c == 0) { switch (type) { case mimemultipart: case textplain: case anymessage: break; default: /* required */ return (-1); } } else if (!(flags & MFR_PLAINSTRING)) { /* ** Let PCRE decide if this is a valid pattern. ** ** One exception: the forward slash character, and some other ** special characters, must always be escaped. */ while (*c) { if (*c == '/' || *c == '$' || *c == '!' || *c == '`' || (int)(unsigned char)*c < ' ' || *c == '\'' || *c == '"') return (-1); /* must be escaped */ if (type == islargerthan) { if (!isdigit((int)(unsigned char)*c)) return (-1); } if (*c == '(') { if (type == hasrecipient) return (-1); ++c; if (*c == ')') return (-1); continue; } if (*c == ')') { if (type == hasrecipient) return (-1); ++c; continue; } if (*c == '[') /* This is a set */ { if (type == hasrecipient) return (-1); ++c; for (;;) { if (*c == '\'' || *c == '"' || *c == '`') return (-1); /* must be quoted*/ if (*c == '\\') ++c; if (!*c) return (-1); if ((int)(unsigned char)*c < ' ') return (-1); ++c; if (*c == ']') break; if (*c != '-') continue; ++c; if (*c == '\'' || *c == '"' || *c == '`') return (-1); /* must be quoted*/ if (*c == '\\') ++c; if ((int)(unsigned char)*c < ' ') return (-1); if (!*c) return (-1); ++c; if (*c == ']') break; } ++c; continue; } if (*c == '\\') { if (type == hasrecipient) return (-1); ++c; } if (!*c) return (-1); ++c; } #if HAVE_PCRE_H switch (type) { case contains: case startswith: case endswith: { const char *errptr; int errindex; pcre *p=pcre_compile(value, PCRE_UTF8, &errptr, &errindex, 0); if (p == NULL) return -1; pcre_free(p); } break; default: break; } #endif } /* validate FROM header */ *errcode=MF_ERR_BADFROMHDR; while (fromhdr && *fromhdr && isspace((int)(unsigned char)*fromhdr)) ++fromhdr; for (c=fromhdr; *c; c++) if ((int)(unsigned char)*c < ' ') return (-1); *errcode=MF_ERR_BADRULEFOLDER; /* validate name of destination folder */ c=folder; if (!c) return (-1); if (strlen(c) > 200) return (-1); if (*c == '*' || *c == '!') { /* Forward, or bounce with an error */ ++c; for ( ; *c; c++) { if (strchr("'\"$\\`;(){}#&<>~", *c) || (unsigned char)*c < ' ') return (-1); } } else if (*c == '+') /* Autorespond */ { struct maildir_filter_autoresp_info ai; if (maildir_filter_autoresp_info_init_str(&ai, c+1)) return (-1); maildir_filter_autoresp_info_free(&ai); } else if (strcmp(c, "exit") == 0) /* Purge */ { } else { char *s; if (strcmp(c, INBOX) && strncmp(c, INBOX ".", sizeof(INBOX))) return -1; s=maildir_name2dir(".", c); if (!s) return -1; free(s); } /* OK, we're good */ *errcode=MF_ERR_INTERNAL; if (p->rulename_utf8) free(p->rulename_utf8); if ((p->rulename_utf8=strdup(name)) == 0) return (-1); p->type=type; if (p->fieldname_utf8) free(p->fieldname_utf8); if ((p->fieldname_utf8=strdup(header ? header:"")) == 0) return (-1); if (p->fieldvalue_utf8) free(p->fieldvalue_utf8); if ((p->fieldvalue_utf8=strdup(value ? value:"")) == 0) return (-1); if (p->tofolder) free(p->tofolder); if ((p->tofolder=malloc(strlen(folder)+1)) == 0) return (-1); strcpy(p->tofolder, folder); if (p->fromhdr) free(p->fromhdr); if ((p->fromhdr=strdup(fromhdr ? fromhdr:"")) == NULL) return (-1); p->flags=flags; return (0); }
int filter_request_headers(request_rec *r, const char *value){ /* Filters all request headers from the Internet request. leave MOD_BUT_SESSION in request leave SESSION_STORE_FREE_COOKIES in request unset all other cookies the client is sending const char *insert_cookie = NULL; const char *new_cookie = NULL; const char *existing_cookie = NULL; */ const char *insert_cookie = NULL; const char *new_cookie = NULL; const char *existing_cookie = NULL; mod_but_server_t *config = ap_get_module_config(r->server->module_config, &but_module); ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: FILTER REQUEST HEADER [%s]", value); /* First, we unset all headers here */ apr_table_unset(r->headers_in, "Cookie"); ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: Unsetting all request headers"); if(value){ pcre *re; // the regular expression const char *error; // error text for the failed regex compilation int error_offset; // offset of the regex compilation error, if any int rc = 0; // return code of pcre_exec int re_vector[3072]; char *qa = (char *)apr_pstrdup(r->pool, value); char *p, *last; /* Loop through all a=b; c=d; e=f values Cookies are sent in a single line from the browser Cookie: jsessionid=1234; foo=3322; */ ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: REQUEST FILTER: COOKIES BEFORE PARSING: [%s]", value); ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: config->cookie_name [%s]", config->cookie_name); for(p = (char *)apr_strtok(qa, "; ", &last); p != NULL; p = (char *)apr_strtok(NULL, "; ", &last)) { /* Make sure we insert the MOD_BUT_SESSION into headers_in, after we unset all */ char *p1 = strstr(p, config->cookie_name); if(p1){ /* If we are here, we are analyzing the MOD_BUT_SESSION Cookie */ ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: MOD_BUT_SESSION FOUND [%s]", p1); p1 += strlen(config->cookie_name); if(*p1 == '=') { char *mod_but_session = (char *)apr_pstrdup(r->pool, p1+1); ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: MOD_BUT_SESSION (NOTES) [%s]", mod_but_session); apr_table_set(r->notes, config->cookie_name , mod_but_session); } }else{ /* Now let's see the other cookies the client sends */ if (p == NULL){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: P IS NULL [%s]", p); }else { if(config->session_store_free_cookies){ re = pcre_compile(config->session_store_free_cookies, 0, &error, &error_offset, NULL); if (re == NULL) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: return code of pcre_compile in Cookie Store is NULL"); } rc = pcre_exec(re, NULL, p, strlen(p), 0, 0, re_vector, 3072); if (rc < 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: REQUEST FILTER: INVALID COOKIE SENT BY CLIENT (POTENTIALLY HACKING ATTEMPT) [%s]", p); } if (rc == 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: PCRE output vector too small (%d)", 3072/3-1); ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: Problems with the following ARGS = %s", value); return DECLINED; } if (rc > 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: REQUEST FILTER: FREE COOKIE FOUND [%s]", p); /* Please note, apr_table_unset(r->hearders_in, "Cookie") was done in mod_but.c (CORE) Here we add our "wanted" cookies again into the request header. */ insert_cookie = (char *)apr_psprintf(r->pool, "%s;", p); existing_cookie = apr_table_get(r->notes, "REQUEST_COOKIES"); if (insert_cookie != NULL){ if (apr_table_get(r->notes, "REQUEST_COOKIES") == NULL) { new_cookie=apr_pstrcat(r->pool, insert_cookie, NULL); } else { new_cookie=apr_pstrcat(r->pool, existing_cookie, insert_cookie, NULL); } apr_table_set(r->notes, "REQUEST_COOKIES", new_cookie); ap_log_rerror(PC_LOG_INFO, r, "mod_but_cookiestore.c: ADD COOKIE [%s] into r->notes", apr_table_get(r->notes, "REQUEST_COOKIES")); } //apr_table_addn(r->headers_in, "Cookie", "dummycookie=dummy;" ); } } } } } } return DECLINED; }
static void normalizeKey(const char *key, char *normalizedKey, size_t outlen) { // key is a NULL-terminated string, normalize it and store it in // normalizedKey, with no longer than outlen, may not null terminated // if outlen is too small vector<std::string> &specialPrefix = RuntimeOption::APCSizeSpecialPrefix; vector<std::string> &prefixReplace = RuntimeOption::APCSizePrefixReplace; for (unsigned int i = 0; i < specialPrefix.size(); i++) { const char *prefix = specialPrefix[i].c_str(); if (strncmp(key, prefix, specialPrefix[i].length()) == 0) { strncpy(normalizedKey, prefixReplace[i].c_str(), outlen); return; } } vector<std::string> &specialMiddle = RuntimeOption::APCSizeSpecialMiddle; vector<std::string> &middleReplace = RuntimeOption::APCSizeMiddleReplace; for (unsigned int i = 0; i < specialMiddle.size(); i++) { const char *middle = specialMiddle[i].c_str(); if (strstr(key, middle) != NULL) { strncpy(normalizedKey, middleReplace[i].c_str(), outlen); return; } } const char *error; int erroffset; static const pcre *re_lower = pcre_compile("/[a-z]/", 0, &error, &erroffset, NULL); if (index(key, ':') == NULL && !regex_match(re_lower, key)) { strncpy(normalizedKey, "ALL_CAPS_N_NUMBERS", outlen); return; } static const pcre *re_hash = pcre_compile("[a-f0-9]{8,}", 0, &error, &erroffset, NULL); static const char *re_hash_replace = "{H}"; static const pcre *re_number = pcre_compile("-?\\d+", 0, &error, &erroffset, NULL); static const char *re_number_replace = "{N}"; static const pcre *re_locale = pcre_compile("\\b[a-z][a-z]_[A-Z][A-Z]\\b", 0, &error, &erroffset, NULL); static const char *re_locale_replace = "{L}"; static const pcre *re_i18n = pcre_compile("^i{N}n", 0, &error, &erroffset, NULL); static const char *re_i18n_replace = "i18n"; char *tempBuf = (char *)calloc(outlen + 1, 1); strncpy(tempBuf, key, outlen); tempBuf[outlen] = '\0'; bool isReplaced; isReplaced = regex_replace(re_locale, tempBuf, re_locale_replace, normalizedKey, outlen); if (isReplaced) { strncpy(tempBuf, normalizedKey, outlen); tempBuf[outlen] = '\0'; } isReplaced = regex_replace(re_hash, tempBuf, re_hash_replace, normalizedKey, outlen); if (isReplaced) { strncpy(tempBuf, normalizedKey, outlen); tempBuf[outlen] = '\0'; } isReplaced = regex_replace(re_number, tempBuf, re_number_replace, normalizedKey, outlen); if (isReplaced) { strncpy(tempBuf, normalizedKey, outlen); tempBuf[outlen] = '\0'; } isReplaced = regex_replace(re_i18n, tempBuf, re_i18n_replace, normalizedKey, outlen); if (isReplaced) { strncpy(tempBuf, normalizedKey, outlen); tempBuf[outlen] = '\0'; } strncpy(normalizedKey, tempBuf, outlen); free(tempBuf); }
static void thunar_sbr_replace_renamer_pcre_update (ThunarSbrReplaceRenamer *replace_renamer) { const gchar *error_message = NULL; GdkColor back; GdkColor text; gchar *tooltip; gchar *message; glong offset; gint error_offset = -1; /* pre-compile the pattern if regexp is enabled */ if (G_UNLIKELY (replace_renamer->regexp)) { /* release the previous pattern (if any) */ if (G_LIKELY (replace_renamer->pcre_pattern != NULL)) pcre_free (replace_renamer->pcre_pattern); /* try to compile the new pattern */ replace_renamer->pcre_pattern = pcre_compile (replace_renamer->pattern, (replace_renamer->case_sensitive ? 0 : PCRE_CASELESS) | PCRE_UTF8, &error_message, &error_offset, 0); if (G_LIKELY (replace_renamer->pcre_pattern != NULL)) { /* determine the subpattern capture count */ if (pcre_fullinfo (replace_renamer->pcre_pattern, NULL, PCRE_INFO_CAPTURECOUNT, &replace_renamer->pcre_capture_count) != 0) { /* shouldn't happen, but just to be sure */ pcre_free (replace_renamer->pcre_pattern); replace_renamer->pcre_pattern = NULL; } } } /* check if there was an error compiling the pattern */ if (G_UNLIKELY (error_message != NULL)) { /* convert the message to UTF-8 */ message = g_locale_to_utf8 (error_message, -1, NULL, NULL, NULL); if (G_LIKELY (message != NULL)) { /* determine the UTF-8 char offset */ offset = g_utf8_pointer_to_offset (replace_renamer->pattern, replace_renamer->pattern + error_offset); /* setup a tooltip with the error message */ tooltip = g_strdup_printf (_("Invalid regular expression, at character position %ld: %s"), offset, message); gtk_tooltips_set_tip (replace_renamer->tooltips, replace_renamer->pattern_entry, tooltip, NULL); g_free (tooltip); } g_free (message); /* check if the entry is realized */ if (GTK_WIDGET_REALIZED (replace_renamer->pattern_entry)) { /* if GTK+ wouldn't be that stupid with style properties and * type plugins, this would be themable, but unfortunately * GTK+ is totally broken, and so it's hardcoded. */ gdk_color_parse ("#ff6666", &back); gdk_color_parse ("White", &text); /* setup a red background/text color to indicate the error */ gtk_widget_modify_base (replace_renamer->pattern_entry, GTK_STATE_NORMAL, &back); gtk_widget_modify_text (replace_renamer->pattern_entry, GTK_STATE_NORMAL, &text); } } else { /* check if the entry is realized */ if (GTK_WIDGET_REALIZED (replace_renamer->pattern_entry)) { /* reset background/text color */ gtk_widget_modify_base (replace_renamer->pattern_entry, GTK_STATE_NORMAL, NULL); gtk_widget_modify_text (replace_renamer->pattern_entry, GTK_STATE_NORMAL, NULL); } /* reset to default tooltip */ gtk_tooltips_set_tip (replace_renamer->tooltips, replace_renamer->pattern_entry, _("Enter the text to search for in the file names."), NULL); } }
int main(int argc, char **argv) { int c; const char *pcreErrorStr; int pcreErrorOffset; if (argc == 1) { fprintf(stdout, "Usage: %s [ -i interface ] [ -d ] [ -f filter ]\n", argv[0]); return EXIT_FAILURE; } while ((c = getopt (argc, argv, "di:f:")) != -1) { switch (c) { case 'd': debug_mode += 1; break; case 'i': strncpy(capture_dev, optarg, 255); break; case 'f': strncpy(capture_filter_exp, optarg, 255); break; case '?': if (optopt == 'c') { fprintf (stderr, "Option -%c requires an argument.\n", optopt); } else if (isprint (optopt)) { fprintf (stderr, "Unknown option `-%c'.\n", optopt); } else { fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); } return EXIT_FAILURE; } } if (debug_mode >= 1) { fprintf(stderr, "[DEBUG] Parsed options:\n"); fprintf(stderr, " debug_mode = %d\n", debug_mode); fprintf(stderr, " capture_dev = %s\n", capture_dev); fprintf(stderr, " capture_filter_exp = %s\n", capture_filter_exp); fprintf(stderr, "-----------------------\n"); } if ((capture_handle = open_for_capture(capture_dev, capture_filter_exp)) == NULL) { return EXIT_FAILURE; } char *regex = "(\\<\\?xml[^\\>]+\\>\\s*\\<SOAP-ENV:Envelope[^\\>]+>.+?\\</SOAP-ENV:Envelope[^\\>]*>)"; re = pcre_compile(regex, (PCRE_CASELESS | PCRE_DOTALL), &pcreErrorStr, &pcreErrorOffset, NULL); if(re == NULL) { fprintf(stderr, "Couldn't compile '%s': %s\n", regex, pcreErrorStr); return EXIT_FAILURE; } ree = pcre_study(re, 0, &pcreErrorStr); if(pcreErrorStr != NULL) { fprintf(stderr, "Couldn't study '%s': %s\n", regex, pcreErrorStr); return EXIT_FAILURE; } struct pcap_pkthdr pkt_header; /* The header that pcap gives us */ memset(&prev_package, 0, sizeof(prev_package)); signal(SIGINT, handle_sig); while (!sigQuit) { const u_char *packet = pcap_next(capture_handle, &pkt_header); if (!packet) { if (debug_mode >= 3) { fprintf(stderr, "-- Skipping non packet\n"); } continue; } handle_packet(packet); } /* close the capture */ pcap_close(capture_handle); // Free up the regular expression. pcre_free(re); // Free up the EXTRA PCRE value (may be NULL at this point) if(ree != NULL) { pcre_free(ree); } return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { char *msg; int running; int argi, seq; struct timeval *timeout = NULL; pcre *hostexp = NULL; pcre *exhostexp = NULL; pcre *testexp = NULL; pcre *extestexp = NULL; pcre *colorexp = NULL; const char *errmsg = NULL; int errofs = 0; FILE *logfd = stdout; /* Handle program options. */ for (argi = 1; (argi < argc); argi++) { if (strcmp(argv[argi], "--debug") == 0) { /* * A global "debug" variable is available. If * it is set, then "dbgprintf()" outputs debug messages. */ debug = 1; } else if (strncmp(argv[argi], "--timeout=", 10) == 0) { /* * You can have a timeout when waiting for new * messages. If it happens, you will get a "@@idle\n" * message with sequence number 0. * If you dont want a timeout, just pass a NULL for the timeout parameter. */ timeout = (struct timeval *)(malloc(sizeof(struct timeval))); timeout->tv_sec = (atoi(argv[argi]+10)); timeout->tv_usec = 0; } else if (argnmatch(argv[argi], "--hosts=")) { char *exp = strchr(argv[argi], '=') + 1; hostexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (hostexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--exhosts=")) { char *exp = strchr(argv[argi], '=') + 1; exhostexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (exhostexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--tests=")) { char *exp = strchr(argv[argi], '=') + 1; testexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (testexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--extests=")) { char *exp = strchr(argv[argi], '=') + 1; extestexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (extestexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--colors=")) { char *exp = strchr(argv[argi], '=') + 1; colorexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (colorexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--outfile=")) { char *fn = strchr(argv[argi], '=') + 1; logfd = fopen(fn, "a"); if (logfd == NULL) { printf("Cannot open logfile %s: %s\n", fn, strerror(errno)); logfd = stdout; } } else { printf("Unknown option %s\n", argv[argi]); printf("Usage: %s [--hosts=EXP] [--tests=EXP] [--exhosts=EXP] [--extests=EXP] [--color=EXP] [--outfile=FILENAME]\n", argv[0]); return 0; } } running = 1; while (running) { char *eoln, *restofmsg, *p; char *metadata[MAX_META+1]; int metacount; msg = get_hobbitd_message(C_LAST, argv[0], &seq, timeout); if (msg == NULL) { /* * get_hobbitd_message will return NULL if hobbitd_channel closes * the input pipe. We should shutdown when that happens. */ running = 0; continue; } /* * Now we have a message. So do something with it. * * The first line of the message is always a '|' separated * list of meta-data about the message. After the first * line, the content varies by channel. */ /* Split the message in the first line (with meta-data), and the rest */ eoln = strchr(msg, '\n'); if (eoln) { *eoln = '\0'; restofmsg = eoln+1; } else { restofmsg = ""; } /* * Now parse the meta-data into elements. * We use our own "gettok()" routine which works * like strtok(), but can handle empty elements. */ metacount = 0; p = gettok(msg, "|"); while (p && (metacount < MAX_META)) { metadata[metacount++] = p; p = gettok(NULL, "|"); } metadata[metacount] = NULL; /* * A "shutdown" message is sent when the master daemon * terminates. The child workers should shutdown also. */ if (strncmp(metadata[0], "@@shutdown", 10) == 0) { printf("Shutting down\n"); running = 0; continue; } /* * A "logrotate" message is sent when the Hobbit logs are * rotated. The child workers must re-open their logfiles, * typically stdin and stderr - the filename is always * provided in the HOBBITCHANNEL_LOGFILENAME environment. */ else if (strncmp(metadata[0], "@@logrotate", 11) == 0) { char *fn = xgetenv("HOBBITCHANNEL_LOGFILENAME"); if (fn && strlen(fn)) { freopen(fn, "a", stdout); freopen(fn, "a", stderr); } continue; } /* * An "idle" message appears when get_hobbitd_message() * exceeds the timeout setting (ie. you passed a timeout * value). This allows your worker module to perform * some internal processing even though no messages arrive. */ else if (strncmp(metadata[0], "@@idle", 6) == 0) { printf("Got an 'idle' message\n"); } /* * The "drophost", "droptest", "renamehost" and "renametst" * indicates that a host/test was deleted or renamed. If the * worker module maintains some internal storage (in memory * or persistent file-storage), it should act on these * messages to maintain data consistency. */ else if ((metacount > 3) && (strncmp(metadata[0], "@@drophost", 10) == 0)) { printf("Got a 'drophost' message for host '%s'\n", metadata[3]); } else if ((metacount > 4) && (strncmp(metadata[0], "@@droptest", 10) == 0)) { printf("Got a 'droptest' message for host '%s' test '%s'\n", metadata[3], metadata[4]); } else if ((metacount > 4) && (strncmp(metadata[0], "@@renamehost", 12) == 0)) { printf("Got a 'renamehost' message for host '%s' -> '%s'\n", metadata[3], metadata[4]); } else if ((metacount > 5) && (strncmp(metadata[0], "@@renametest", 12) == 0)) { printf("Got a 'renametest' message for host '%s' test '%s' -> '%s'\n", metadata[3], metadata[4], metadata[5]); } /* * What happens next is up to the worker module. * * For this sample module, we'll just print out the data we got. */ else { int ovector[30]; int match, i; char *hostname = metadata[4]; char *testname = metadata[5]; char *color = metadata[7]; if (hostexp) { match = (pcre_exec(hostexp, NULL, hostname, strlen(hostname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (!match) continue; } if (exhostexp) { match = (pcre_exec(exhostexp, NULL, hostname, strlen(hostname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (match) continue; } if (testexp) { match = (pcre_exec(testexp, NULL, testname, strlen(testname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (!match) continue; } if (exhostexp) { match = (pcre_exec(extestexp, NULL, testname, strlen(testname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (match) continue; } if (colorexp) { match = (pcre_exec(colorexp, NULL, color, strlen(color), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (!match) continue; } printf("## "); for (i=0; (i < metacount); i++) printf("%s ", metadata[i]); printf("\n"); printf("%s\n", restofmsg); } } return 0; }
/** * This function combines ['/foo', '/bar', '/{slug}'] into (/foo)|(/bar)|/([^/]+)} * */ void r3_tree_compile_patterns(node * n) { char * cpat; char * p; cpat = zcalloc(sizeof(char) * 128); if (cpat==NULL) return; p = cpat; strncat(p, "^", 1); p++; edge *e = NULL; for ( int i = 0 ; i < n->edge_len ; i++ ) { e = n->edges[i]; if ( e->has_slug ) { char * slug_pat = slug_compile(e->pattern, e->pattern_len); strcat(p, slug_pat); } else { strncat(p++,"(", 1); strncat(p, e->pattern, e->pattern_len); p += e->pattern_len; strncat(p++,")", 1); } if ( i + 1 < n->edge_len && n->edge_len > 1 ) { strncat(p++,"|",1); } } info("pattern: %s\n",cpat); n->ov_cnt = (1 + n->edge_len) * 3; n->ov = (int*) zcalloc(sizeof(int) * n->ov_cnt); n->combined_pattern = cpat; n->combined_pattern_len = p - cpat; const char *error; int erroffset; unsigned int option_bits = 0; if (n->pcre_pattern) { pcre_free(n->pcre_pattern); } n->pcre_pattern = pcre_compile( n->combined_pattern, /* the pattern */ option_bits, /* default options */ &error, /* for error message */ &erroffset, /* for error offset */ NULL); /* use default character tables */ if (n->pcre_pattern == NULL) { printf("PCRE compilation failed at offset %d: %s, pattern: %s\n", erroffset, error, n->combined_pattern); return; } #ifdef PCRE_STUDY_JIT_COMPILE if (n->pcre_extra) { pcre_free_study(n->pcre_extra); } n->pcre_extra = pcre_study(n->pcre_pattern, 0, &error); if (n->pcre_extra == NULL) { printf("PCRE study failed at offset %s\n", error); return; } #endif }
ngx_int_t ngx_regex_compile(ngx_regex_compile_t *rc) { int n, erroff; char *p; pcre *re; const char *errstr; ngx_regex_elt_t *elt; ngx_regex_malloc_init(rc->pool); re = pcre_compile((const char *) rc->pattern.data, (int) rc->options, &errstr, &erroff, NULL); /* ensure that there is no current pool */ ngx_regex_malloc_done(); if (re == NULL) { if ((size_t) erroff == rc->pattern.len) { rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, "pcre_compile() failed: %s in \"%V\"", errstr, &rc->pattern) - rc->err.data; } else { rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, "pcre_compile() failed: %s in \"%V\" at \"%s\"", errstr, &rc->pattern, rc->pattern.data + erroff) - rc->err.data; } return NGX_ERROR; } rc->regex = ngx_pcalloc(rc->pool, sizeof(ngx_regex_t)); if (rc->regex == NULL) { goto nomem; } rc->regex->code = re; /* do not study at runtime */ if (ngx_pcre_studies != NULL) { elt = ngx_list_push(ngx_pcre_studies); if (elt == NULL) { goto nomem; } elt->regex = rc->regex; elt->name = rc->pattern.data; } n = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &rc->captures); if (n < 0) { p = "pcre_fullinfo(\"%V\", PCRE_INFO_CAPTURECOUNT) failed: %d"; goto failed; } if (rc->captures == 0) { return NGX_OK; } n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMECOUNT, &rc->named_captures); if (n < 0) { p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMECOUNT) failed: %d"; goto failed; } if (rc->named_captures == 0) { return NGX_OK; } n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &rc->name_size); if (n < 0) { p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMEENTRYSIZE) failed: %d"; goto failed; } n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMETABLE, &rc->names); if (n < 0) { p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMETABLE) failed: %d"; goto failed; } return NGX_OK; failed: rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n) - rc->err.data; return NGX_ERROR; nomem: rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, "regex \"%V\" compilation failed: no memory", &rc->pattern) - rc->err.data; return NGX_ERROR; }
static bool CompareResultEqualOrFiltered(const ExecConfig *config, const char *filename, const char *prev_file) { Log(LOG_LEVEL_VERBOSE, "Comparing files %s with %s", prev_file, filename); bool rtn = true; FILE *old_fp = safe_fopen(prev_file, "r"); FILE *new_fp = safe_fopen(filename, "r"); if (new_fp) { const char *errptr; int erroffset; pcre_extra *regex_extra = NULL; // Match timestamps and remove them. Not Y21K safe! :-) pcre *regex = pcre_compile(LOGGING_TIMESTAMP_REGEX, PCRE_MULTILINE, &errptr, &erroffset, NULL); if (!regex) { UnexpectedError("Compiling regular expression failed"); rtn = false; } else { regex_extra = pcre_study(regex, 0, &errptr); } size_t old_line_size = CF_BUFSIZE; char *old_line = xmalloc(old_line_size); size_t new_line_size = CF_BUFSIZE; char *new_line = xmalloc(new_line_size); bool any_new_msg_present = false; while (regex) { char *old_msg = NULL; if (old_fp) { while (CfReadLine(&old_line, &old_line_size, old_fp) >= 0) { if (!LineIsFiltered(config, old_line)) { old_msg = old_line; break; } } } char *new_msg = NULL; while (CfReadLine(&new_line, &new_line_size, new_fp) >= 0) { if (!LineIsFiltered(config, new_line)) { any_new_msg_present = true; new_msg = new_line; break; } } if (!old_msg || !new_msg) { // Return difference in most cases, when there is a new // message line, but if there isn't one, return equal, even // if strictly speaking they aren't, since we don't want to // send an empty email. if (any_new_msg_present && old_msg != new_msg) { rtn = false; } break; } // Remove timestamps from lines before comparison. char *index; if (pcre_exec(regex, regex_extra, old_msg, strlen(old_msg), 0, 0, NULL, 0) >= 0) { index = strstr(old_msg, ": "); if (index != NULL) { old_msg = index + 2; } } if (pcre_exec(regex, regex_extra, new_msg, strlen(new_msg), 0, 0, NULL, 0) >= 0) { index = strstr(new_msg, ": "); if (index != NULL) { new_msg = index + 2; } } if (strcmp(old_msg, new_msg) != 0) { rtn = false; break; } } free(old_line); free(new_line); if (regex_extra) { free(regex_extra); } pcre_free(regex); } else { /* no previous file */ rtn = false; } if (old_fp) { fclose(old_fp); } if (new_fp) { fclose(new_fp); } if (!ThreadLock(cft_count)) { Log(LOG_LEVEL_ERR, "Severe lock error when mailing in exec"); return 1; } /* replace old file with new*/ unlink(prev_file); if (!LinkOrCopy(filename, prev_file, true)) { Log(LOG_LEVEL_INFO, "Could not symlink or copy '%s' to '%s'", filename, prev_file); rtn = false; } ThreadUnlock(cft_count); return rtn; }
static set* _cluster_keys(range_request* rr, apr_pool_t* pool, const char* cluster, const char* cluster_file) { char line[32768]; char* p; int ovector[30]; apr_array_header_t* working_range; set* sections; char* section; char* cur_section; apr_pool_t* req_pool = range_request_pool(rr); int line_no; FILE* fp = fopen(cluster_file, "r"); if (!fp) { range_request_warn(rr, "%s: %s not readable", cluster, cluster_file); return set_new(pool, 0); } if (!include_re) { const char* error; include_re = pcre_compile(INCLUDE_RE, 0, &error, ovector, NULL); assert(include_re); exclude_re = pcre_compile(EXCLUDE_RE, 0, &error, ovector, NULL); assert(exclude_re); } sections = set_new(pool, 0); section = cur_section = NULL; working_range = apr_array_make(req_pool, 1, sizeof(char*)); line_no = 0; while (fgets(line, sizeof line, fp)) { int len; int count; line_no++; line[sizeof line - 1] = '\0'; len = strlen(line); if (len+1 >= sizeof(line) && line[len - 1] != '\n') { /* incomplete line */ fprintf(stderr, "%s:%d lines > 32767 chars not supported\n", cluster_file, line_no); exit(-1); } line[--len] = '\0'; /* get rid of the \n */ for (p = line; *p; ++p) if (*p == '#') { *p = '\0'; break; } len = strlen(line); if (len == 0) continue; for (p = &line[len - 1]; isspace(*p); --p) { *p = '\0'; --len; } if (!*line) continue; if (!(isspace(*line))) { cur_section = apr_pstrdup(pool, line); continue; } if (section && strcmp(cur_section, section) != 0) { set_add(sections, section, apr_array_pstrcat(pool, working_range, ',')); working_range = apr_array_make(req_pool, 1, sizeof(char*)); } section = cur_section; count = pcre_exec(include_re, NULL, line, len, 0, 0, ovector, 30); if (count > 0) { line[ovector[3]] = '\0'; *(char**)apr_array_push(working_range) = apr_psprintf(pool, "(%s)", _substitute_dollars(pool, cluster, &line[ovector[2]])); continue; } count = pcre_exec(exclude_re, NULL, line, len, 0, 0, ovector, 30); if (count > 0) { line[ovector[3]] = '\0'; *(char**)apr_array_push(working_range) = apr_psprintf(pool, "-(%s)", _substitute_dollars(pool, cluster, &line[ovector[2]])); } } fclose(fp); if (cur_section) set_add(sections, cur_section, apr_array_pstrcat(pool, working_range, ',')); set_add(sections, "KEYS", _join_elements(pool, ',', sections)); set_add(sections, "UP", set_get_data(sections, "CLUSTER")); if (set_get(sections, "ALL") && set_get(sections, "CLUSTER")) set_add(sections, "DOWN", apr_psprintf(pool, "(%s)-(%s)", (char*)set_get_data(sections, "ALL"), (char*)set_get_data(sections, "CLUSTER"))); return sections; }
void mne_search_loop() { char *term = NULL; const char *error; int erroffset; mne_search_initialize(); printf("\nType 'exit' to... you know what.\n"); while (1) { printf("regex: "); size_t term_bytes = 1024; getline(&term, &term_bytes, stdin); term[strlen(term) - 1] = 0; /* Remove newline. */ if (strlen(term) == 0) { free(term); term = NULL; continue; } if (strncmp(term, "exit", 4) == 0) { exiting = 1; mne_search_ready(); free(term); term = NULL; break; } re = pcre_compile(term, 0, &error, &erroffset, NULL); if (re == NULL) { printf("Regex compilation failed at offset %d: %s\n", erroffset, error); free(term); term = NULL; continue; } re_extra = pcre_study(re, PCRE_STUDY_JIT_COMPILE, &error); if (error != NULL) { printf("pcre_study() failed: %s\n", error); pcre_free_study(re_extra); re_extra = NULL; pcre_free(re); free(term); term = NULL; continue; } printf("\n"); gettimeofday(&begin, NULL); threads_complete = 0; pthread_mutex_unlock(&all_done_mutex); pthread_mutex_lock(&all_done_mutex); mne_search_ready(); pthread_mutex_lock(&all_done_mutex); gettimeofday(&end, NULL); int total = mne_search_print_results(); if (total == MAX_SEARCH_RESULTS_PER_THREAD * num_cores) printf("Hit match limit!\n"); printf("%d matches. ", total); mne_print_duration(&end, &begin); printf(".\n"); free(term); term = NULL; pcre_free(re); if (re_extra != NULL) pcre_free_study(re_extra); } }
/* * parse a function and its arguments and fill the structure */ int encode_function(char *string, struct filter_op *fop) { char *str = strdup(string); int ret = -ENOTFOUND; char *name, *args; int nargs = 0, i; char **dec_args = NULL; char *tok; memset(fop, 0, sizeof(struct filter_op)); /* get the name of the function */ name = ec_strtok(string, "(", &tok); /* get all the args */ args = name + strlen(name) + 1; /* analyze the arguments */ dec_args = decode_args(args, &nargs); /* this fop is a function */ fop->opcode = FOP_FUNC; /* check if it is a known function */ if (!strcmp(name, "search")) { if (nargs == 2) { /* get the level (DATA or DECODED) */ if (encode_offset(dec_args[0], fop) == ESUCCESS) { /* encode offset wipe the fop !! */ fop->opcode = FOP_FUNC; fop->op.func.op = FFUNC_SEARCH; fop->op.func.string = (u_char*)strdup(dec_args[1]); fop->op.func.slen = strescape((char*)fop->op.func.string, (char*)fop->op.func.string); ret = ESUCCESS; } } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "regex")) { if (nargs == 2) { int err; regex_t regex; char errbuf[100]; /* get the level (DATA or DECODED) */ if (encode_offset(dec_args[0], fop) == ESUCCESS) { /* encode offset wipe the fop !! */ fop->opcode = FOP_FUNC; fop->op.func.op = FFUNC_REGEX; fop->op.func.string = (u_char*)strdup(dec_args[1]); fop->op.func.slen = strescape((char*)fop->op.func.string, (char*)fop->op.func.string); ret = ESUCCESS; } /* check if the regex is valid */ err = regcomp(®ex, (const char*)fop->op.func.string, REG_EXTENDED | REG_NOSUB | REG_ICASE ); if (err) { regerror(err, ®ex, errbuf, sizeof(errbuf)); SCRIPT_ERROR("%s", errbuf); } regfree(®ex); } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "pcre_regex")) { #ifndef HAVE_PCRE WARNING("The script contains pcre_regex, but you don't have support for it."); #else pcre *pregex; const char *errbuf = NULL; int erroff; if (nargs == 2) { /* get the level (DATA or DECODED) */ if (encode_offset(dec_args[0], fop) == ESUCCESS) { /* encode offset wipe the fop !! */ fop->opcode = FOP_FUNC; fop->op.func.op = FFUNC_PCRE; fop->op.func.string = strdup(dec_args[1]); fop->op.func.slen = strlen(fop->op.func.string); ret = ESUCCESS; } /* check if the pcre is valid */ pregex = pcre_compile(fop->op.func.string, 0, &errbuf, &erroff, NULL ); if (pregex == NULL) SCRIPT_ERROR("%s\n", errbuf); pcre_free(pregex); } else if (nargs == 3) { fop->opcode = FOP_FUNC; fop->op.func.op = FFUNC_PCRE; /* substitution always at layer DATA */ fop->op.func.level = 5; fop->op.func.string = strdup(dec_args[1]); fop->op.func.slen = strlen(fop->op.func.string); fop->op.func.replace = strdup(dec_args[2]); fop->op.func.rlen = strlen(fop->op.func.replace); ret = ESUCCESS; /* check if the pcre is valid */ pregex = pcre_compile(fop->op.func.string, 0, &errbuf, &erroff, NULL ); if (pregex == NULL) SCRIPT_ERROR("%s\n", errbuf); pcre_free(pregex); } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); #endif } else if (!strcmp(name, "replace")) { if (nargs == 2) { fop->op.func.op = FFUNC_REPLACE; /* replace always operate at DATA level */ fop->op.func.level = 5; fop->op.func.string = (u_char*)strdup(dec_args[0]); fop->op.func.slen = strescape((char*)fop->op.func.string, (char*)fop->op.func.string); fop->op.func.replace = (u_char*)strdup(dec_args[1]); fop->op.func.rlen = strescape((char*)fop->op.func.replace, (char*)fop->op.func.replace); ret = ESUCCESS; } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "inject")) { if (nargs == 1) { fop->op.func.op = FFUNC_INJECT; /* inject always operate at DATA level */ fop->op.func.level = 5; fop->op.func.string = (u_char*)strdup(dec_args[0]); fop->op.func.slen = strlen((const char*)fop->op.func.string); ret = ESUCCESS; } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "execinject")) { if (nargs == 1) { fop->op.func.op = FFUNC_EXECINJECT; /* execinject always operate at DATA level */ fop->op.func.level = 5; fop->op.func.string = (u_char*)strdup(dec_args[0]); fop->op.func.slen = strlen((const char*)fop->op.func.string); ret = ESUCCESS; } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "log")) { if (nargs == 2) { /* get the level (DATA or DECODED) */ if (encode_offset(dec_args[0], fop) == ESUCCESS) { /* encode offset wipe the fop !! */ fop->opcode = FOP_FUNC; fop->op.func.op = FFUNC_LOG; fop->op.func.string = (u_char*)strdup(dec_args[1]); fop->op.func.slen = strlen((const char*)fop->op.func.string); ret = ESUCCESS; } } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "drop")) { if (nargs == 0) { fop->op.func.op = FFUNC_DROP; ret = ESUCCESS; } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "kill")) { if (nargs == 0) { fop->op.func.op = FFUNC_KILL; ret = ESUCCESS; } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "msg")) { if (nargs == 1) { fop->op.func.op = FFUNC_MSG; fop->op.func.string = (u_char*)strdup(dec_args[0]); fop->op.func.slen = strescape((char*)fop->op.func.string, (char*)fop->op.func.string); ret = ESUCCESS; } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "exec")) { if (nargs == 1) { fop->op.func.op = FFUNC_EXEC; fop->op.func.string = (u_char*)strdup(dec_args[0]); fop->op.func.slen = strlen((const char*)fop->op.func.string); ret = ESUCCESS; } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "exit")) { if (nargs == 0) { fop->opcode = FOP_EXIT; ret = ESUCCESS; } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } /* free the array */ for (i = 0; i < nargs; i++) SAFE_FREE(dec_args[i]); SAFE_FREE(dec_args); SAFE_FREE(str); return ret; }
int regex_compile(tvh_regex_t *regex, const char *re_str, int flags, int subsys) { #if ENABLE_PCRE || ENABLE_PCRE2 regex->is_posix = 0; if (flags & TVHREGEX_POSIX) { regex->is_posix = 1; #endif int options = REG_EXTENDED; if (flags & TVHREGEX_CASELESS) options |= REG_ICASE; if (!regcomp(®ex->re_posix_code, re_str, options)) return 0; tvherror(subsys, "Unable to compile regex '%s'", re_str); return -1; #if ENABLE_PCRE || ENABLE_PCRE2 } else { #if ENABLE_PCRE const char *estr; int eoff; int options = PCRE_UTF8; if (flags & TVHREGEX_CASELESS) options |= PCRE_CASELESS; #if PCRE_STUDY_JIT_COMPILE regex->re_jit_stack = NULL; #endif regex->re_extra = NULL; regex->re_code = pcre_compile(re_str, options, &estr, &eoff, NULL); if (regex->re_code == NULL) { tvherror(subsys, "Unable to compile PCRE '%s': %s", re_str, estr); } else { regex->re_extra = pcre_study(regex->re_code, PCRE_STUDY_JIT_COMPILE, &estr); if (regex->re_extra == NULL && estr) tvherror(subsys, "Unable to study PCRE '%s': %s", re_str, estr); else { #if PCRE_STUDY_JIT_COMPILE regex->re_jit_stack = pcre_jit_stack_alloc(32*1024, 512*1024); if (regex->re_jit_stack) pcre_assign_jit_stack(regex->re_extra, NULL, regex->re_jit_stack); #endif return 0; } } return -1; #elif ENABLE_PCRE2 PCRE2_UCHAR8 ebuf[128]; int ecode; PCRE2_SIZE eoff; size_t jsz; uint32_t options; assert(regex->re_jit_stack == NULL); regex->re_jit_stack = NULL; regex->re_match = NULL; regex->re_mcontext = pcre2_match_context_create(NULL); options = PCRE2_UTF; if (flags & TVHREGEX_CASELESS) options |= PCRE2_CASELESS; regex->re_code = pcre2_compile((PCRE2_SPTR8)re_str, -1, options, &ecode, &eoff, NULL); if (regex->re_code == NULL) { (void)pcre2_get_error_message(ecode, ebuf, 120); tvherror(subsys, "Unable to compile PCRE2 '%s': %s", re_str, ebuf); } else { regex->re_match = pcre2_match_data_create(TVHREGEX_MAX_MATCHES, NULL); if (re_str[0] && pcre2_jit_compile(regex->re_code, PCRE2_JIT_COMPLETE) >= 0) { jsz = 0; if (pcre2_pattern_info(regex->re_code, PCRE2_INFO_JITSIZE, &jsz) >= 0 && jsz > 0) { regex->re_jit_stack = pcre2_jit_stack_create(32 * 1024, 512 * 1024, NULL); if (regex->re_jit_stack) pcre2_jit_stack_assign(regex->re_mcontext, NULL, regex->re_jit_stack); } } return 0; } return -1; #endif } #endif }
BoolExpr* evaluateBoolExpr(BoolExpr* be) { int m, p, erroff, ovec[PCREOVECCOUNT]; double j, k, **n, *o; char* c, *s, *t; const char* err; List* stack, *prop, *stackiter; Value* v, *u, *w; pcre *re; re = NULL; stack = be->stack; for (m=0;stack->next && stack->next->next;m++) stack = stack->next->next; n = malloc((m+2)*sizeof(double*)); m = -1; stack = newList(); o = NULL; stackiter = be->stack; while (stackiter) { s = NULL; t = NULL; w = NULL; v = NULL; u = stackiter->data; if (u->type == '|' || u->type == '&') { addToListEnd(stack, n[m]); addToListEnd(stack, u); stackiter = stackiter->next; continue; } n[++m] = calloc(1, sizeof(double)); if (u->type != 'b') { v = evaluateValue(u); w = v; if (v == NULL) { freeList(stack); m++; for (p=0;p<m;p++) { free(n[p]); } free(n); return NULL; } if (v->type == 's') { s = v->data; } j = evaluateValueAsBool(v); if (u->type != 'v') freeValue(v); } else { j = evaluateValueAsBool(u); } if (isnan(j)) { m++; for (p=0;p<m;p++) { free(n[p]); } free(n); freeList(stack); return NULL; } stackiter = stackiter->next; if (j) *n[m] = 1; if (!stackiter) { break; } c = (char*)stackiter->data; stackiter = stackiter->next; if (c[0] == '|' || c[0] == '&') { addToListEnd(stack, n[m]); addToListEnd(stack, c); continue; } n[++m] = calloc(1, sizeof(double)); u = stackiter->data; if (u->type != 'b') { v = evaluateValue(u); if (v == NULL) { freeList(stack); m++; for (p=0;p<m;p++) { free(n[p]); } free(n); return NULL; } if (v->type == 's') { t = v->data; } if (u->type != 'v') freeValue(v); } k = evaluateValueAsBool(stackiter->data); if (isnan(k)) { m++; for (p=0;p<m;p++) { free(n[p]); } free(n); freeList(stack); return NULL; } stackiter = stackiter->next; if (c[0] == '~') { if (w == NULL) { continue; } s = valueToString(w); t = valueToString(v); re = pcre_compile(t, 0, &err, &erroff, NULL); if (pcre_exec(re, NULL, s, strlen(s), 0, 0, ovec, PCREOVECCOUNT) > -1) *n[m] = 1; free(s); free(t); if (re) pcre_free(re); continue; } if (c[0] == '?') { if (w == NULL || v == NULL) continue; if (w->type == v->type) { if (v->type != 'l' || ((List*)v->data)->data == NULL) { *n[m] = 1; continue; } prop = ((List*)((List*)v->data)->data)->next; while (prop != NULL) { if (!findInTree(((List*)((List*)w->data)->data)->data, ((Variable*)prop->data)->name)) break; prop = prop->next; } if (prop == NULL) *n[m] = 1; } } if (t != NULL && s != NULL) { if (s == t && c[0] == '=') { *n[m] = 1; continue; } for (p=0;s[p] != '\0' && s[p] == t[p];p++); if ((c[0] == '<' && s[p] < t[p]) || (c[0] == '>' && s[p] > t[p])) *n[m] = 1; continue; } p = 0; if (c[0] == '=') { if (fabs(j) < IOTA) { if (j < 0) j = -0.0; else j = 0.0; } if (fabs(k) < IOTA) { if (k < 0) k = -0.0; else k = 0.0; } } if (j>k) { if (j<=0.0) { if (fabs((j-k)/k)>=EPSILON) p = 1; } else { if (fabs((j-k)/j)>=EPSILON) p = 1; } } else { if (k<=0.0) { if (fabs((k-j)/j)>=EPSILON) p = -1; } else { if (fabs((k-j)/k)>=EPSILON) p = -1; } } if ((c[0] == '<' && p<0) || (c[0] == '>' && p>0) || (c[0] == '=' && !p)) { *n[m] = 1; } } if (m > -1) o = n[m]; if (stack->data && m > -1) { addToListEnd(stack, n[m]); } m++; stackiter = NULL; if (stack->data) stackiter = stack; while (stackiter) { j = *(double*)stackiter->data; if (!(stackiter->next)) { o = (double*)stackiter->data; if (j) *o = 1; else *o = 0; break; } stackiter = stackiter->next; c = stackiter->data; stackiter = stackiter->next; o = (double*)stackiter->data; k = *o; if (((j && k) && c[0] == '&') || ((j || k) && c[0] == '|')) *o = 1; else *o = 0; } if (o == NULL) be->lasteval = 1; else be->lasteval = *o; for (p=0;p<m;p++) { free(n[p]); } free(n); freeList(stack); if (be->neg) be->lasteval = !be->lasteval; return be; }
/********************************************************************* * * Function : pcrs_compile * * Description : Takes the three arguments to a perl s/// command * and compiles a pcrs_job structure from them. * * Parameters : * 1 : pattern = string with perl-style pattern * 2 : substitute = string with perl-style substitute * 3 : options = string with perl-style options * 4 : errptr = pointer to an integer in which error * conditions can be returned. * * Returns : a corresponding pcrs_job data structure, or NULL * if an error was encountered. In that case, *errptr * has the reason. * *********************************************************************/ pcrs_job *pcrs_compile(const char *pattern, const char *substitute, const char *options, int *errptr) { pcrs_job *newjob; int flags; int capturecount; const char *error; *errptr = 0; /* * Handle NULL arguments */ if (pattern == NULL) pattern = ""; if (substitute == NULL) substitute = ""; /* * Get and init memory */ if (NULL == (newjob = (pcrs_job *)malloc(sizeof(pcrs_job)))) { *errptr = PCRS_ERR_NOMEM; return NULL; } memset(newjob, '\0', sizeof(pcrs_job)); /* * Evaluate the options */ newjob->options = pcrs_parse_perl_options(options, &flags); newjob->flags = flags; /* * Compile the pattern */ newjob->pattern = pcre_compile(pattern, newjob->options, &error, errptr, NULL); if (newjob->pattern == NULL) { pcrs_free_job(newjob); return NULL; } /* * Generate hints. This has little overhead, since the * hints will be NULL for a boring pattern anyway. */ newjob->hints = pcre_study(newjob->pattern, 0, &error); if (error != NULL) { *errptr = PCRS_ERR_STUDY; pcrs_free_job(newjob); return NULL; } /* * Determine the number of capturing subpatterns. * This is needed for handling $+ in the substitute. */ if (0 > (*errptr = pcre_fullinfo(newjob->pattern, newjob->hints, PCRE_INFO_CAPTURECOUNT, &capturecount))) { pcrs_free_job(newjob); return NULL; } /* * Compile the substitute */ if (NULL == (newjob->substitute = pcrs_compile_replacement(substitute, newjob->flags & PCRS_TRIVIAL, capturecount, errptr))) { pcrs_free_job(newjob); return NULL; } return newjob; }
int main(int argc, char *argv[]) { char *msg; int running; int argi, seq; struct timespec *timeout = NULL; pcre *hostexp = NULL; pcre *exhostexp = NULL; pcre *testexp = NULL; pcre *extestexp = NULL; pcre *colorexp = NULL; const char *errmsg = NULL; int errofs = 0; FILE *logfd = stdout; int batchtimeout = 30; char *batchcmd = NULL; strbuffer_t *batchbuf = NULL; time_t lastmsgtime = 0; int hostnameitem = 4, testnameitem = 5, coloritem = 7; /* Handle program options. */ for (argi = 1; (argi < argc); argi++) { if (strcmp(argv[argi], "--debug") == 0) { /* * A global "debug" variable is available. If * it is set, then "dbgprintf()" outputs debug messages. */ debug = 1; } else if (strncmp(argv[argi], "--timeout=", 10) == 0) { /* * You can have a timeout when waiting for new * messages. If it happens, you will get a "@@idle\n" * message with sequence number 0. * If you dont want a timeout, just pass a NULL for the timeout parameter. */ timeout = (struct timespec *)(malloc(sizeof(struct timespec))); timeout->tv_sec = (atoi(argv[argi]+10)); timeout->tv_nsec = 0; } else if (strcmp(argv[argi], "--client") == 0) { hostnameitem = 3; testnameitem = 4; errprintf("Expecting to be fed from 'client' channel\n"); } else if (argnmatch(argv[argi], "--hosts=")) { char *exp = strchr(argv[argi], '=') + 1; hostexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (hostexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--exhosts=")) { char *exp = strchr(argv[argi], '=') + 1; exhostexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (exhostexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--tests=")) { char *exp = strchr(argv[argi], '=') + 1; testexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (testexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--extests=")) { char *exp = strchr(argv[argi], '=') + 1; extestexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (extestexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--colors=")) { char *exp = strchr(argv[argi], '=') + 1; colorexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (colorexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--outfile=")) { char *fn = strchr(argv[argi], '=') + 1; logfd = fopen(fn, "a"); if (logfd == NULL) { printf("Cannot open logfile %s: %s\n", fn, strerror(errno)); logfd = stdout; } } else if (argnmatch(argv[argi], "--batch-timeout=")) { char *p = strchr(argv[argi], '='); batchtimeout = atoi(p+1); timeout = (struct timespec *)(malloc(sizeof(struct timespec))); timeout->tv_sec = batchtimeout; timeout->tv_nsec = 0; } else if (argnmatch(argv[argi], "--batch-command=")) { char *p = strchr(argv[argi], '='); batchcmd = strdup(p+1); batchbuf = newstrbuffer(0); } else { printf("Unknown option %s\n", argv[argi]); printf("Usage: %s [--hosts=EXP] [--tests=EXP] [--exhosts=EXP] [--extests=EXP] [--color=EXP] [--outfile=FILENAME] [--batch-timeout=N] [--batch-command=COMMAND]\n", argv[0]); return 0; } } signal(SIGCHLD, SIG_IGN); running = 1; while (running) { char *eoln, *restofmsg, *p; char *metadata[MAX_META+1]; int metacount; msg = get_xymond_message(C_LAST, argv[0], &seq, timeout); if (msg == NULL) { /* * get_xymond_message will return NULL if xymond_channel closes * the input pipe. We should shutdown when that happens. */ running = 0; continue; } /* * Now we have a message. So do something with it. * * The first line of the message is always a '|' separated * list of meta-data about the message. After the first * line, the content varies by channel. */ /* Split the message in the first line (with meta-data), and the rest */ eoln = strchr(msg, '\n'); if (eoln) { *eoln = '\0'; restofmsg = eoln+1; } else { restofmsg = ""; } /* * Now parse the meta-data into elements. * We use our own "gettok()" routine which works * like strtok(), but can handle empty elements. */ metacount = 0; memset(&metadata, 0, sizeof(metadata)); p = gettok(msg, "|"); while (p && (metacount < MAX_META)) { metadata[metacount++] = p; p = gettok(NULL, "|"); } metadata[metacount] = NULL; /* * A "shutdown" message is sent when the master daemon * terminates. The child workers should shutdown also. */ if (strncmp(metadata[0], "@@shutdown", 10) == 0) { printf("Shutting down\n"); running = 0; continue; } /* * A "logrotate" message is sent when the Xymon logs are * rotated. The child workers must re-open their logfiles, * typically stdin and stderr - the filename is always * provided in the XYMONDHANNEL_LOGFILENAME environment. */ else if (strncmp(metadata[0], "@@logrotate", 11) == 0) { char *fn = xgetenv("XYMONCHANNEL_LOGFILENAME"); if (fn && strlen(fn)) { reopen_file(fn, "a", stdout); reopen_file(fn, "a", stderr); } continue; } /* * A "reload" means the hosts.cfg file has changed. */ else if (strncmp(metadata[0], "@@reload", 8) == 0) { /* Nothing ... right now */ } /* * An "idle" message appears when get_xymond_message() * exceeds the timeout setting (ie. you passed a timeout * value). This allows your worker module to perform * some internal processing even though no messages arrive. */ else if (strncmp(metadata[0], "@@idle", 6) == 0) { dbgprintf("Got an 'idle' message\n"); } /* * The "drophost", "droptest", "renamehost" and "renametst" * indicates that a host/test was deleted or renamed. If the * worker module maintains some internal storage (in memory * or persistent file-storage), it should act on these * messages to maintain data consistency. */ else if ((metacount > 3) && (strncmp(metadata[0], "@@drophost", 10) == 0)) { dbgprintf("Got a 'drophost' message for host '%s'\n", metadata[3]); } else if ((metacount > 3) && (strncmp(metadata[0], "@@dropstate", 11) == 0)) { dbgprintf("Got a 'dropstate' message for host '%s'\n", metadata[3]); } else if ((metacount > 4) && (strncmp(metadata[0], "@@droptest", 10) == 0)) { dbgprintf("Got a 'droptest' message for host '%s' test '%s'\n", metadata[3], metadata[4]); } else if ((metacount > 4) && (strncmp(metadata[0], "@@renamehost", 12) == 0)) { dbgprintf("Got a 'renamehost' message for host '%s' -> '%s'\n", metadata[3], metadata[4]); } else if ((metacount > 5) && (strncmp(metadata[0], "@@renametest", 12) == 0)) { dbgprintf("Got a 'renametest' message for host '%s' test '%s' -> '%s'\n", metadata[3], metadata[4], metadata[5]); } /* * Process this message. */ else { int ovector[30]; int match, i; char *hostname = metadata[hostnameitem]; char *testname = metadata[testnameitem]; char *color = metadata[coloritem]; /* See if we should handle the batched messages we've got */ if (batchcmd && ((lastmsgtime + batchtimeout) < gettimer()) && (STRBUFLEN(batchbuf) > 0)) { pid_t childpid = fork(); int childres = 0; if (childpid < 0) { /* Fork failed! */ errprintf("Fork failed: %s\n", strerror(errno)); } else if (childpid == 0) { /* Child */ FILE *cmdpipe = popen(batchcmd, "w"); if (cmdpipe) { /* Write the data to the batch command pipe */ int n, bytesleft = STRBUFLEN(batchbuf); char *outp = STRBUF(batchbuf); while (bytesleft) { n = fwrite(outp, 1, bytesleft, cmdpipe); if (n >= 0) { bytesleft -= n; outp += n; } else { errprintf("Error while writing data to batch command\n"); bytesleft = 0; } } childres = pclose(cmdpipe); } else { errprintf("Could not open pipe to batch command '%s'\n", batchcmd); childres = 127; } exit(childres); } else if (childpid > 0) { /* Parent continues */ } clearstrbuffer(batchbuf); } if (hostexp) { match = (pcre_exec(hostexp, NULL, hostname, strlen(hostname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (!match) continue; } if (exhostexp) { match = (pcre_exec(exhostexp, NULL, hostname, strlen(hostname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (match) continue; } if (testexp) { match = (pcre_exec(testexp, NULL, testname, strlen(testname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (!match) continue; } if (exhostexp) { match = (pcre_exec(extestexp, NULL, testname, strlen(testname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (match) continue; } if (colorexp) { match = (pcre_exec(colorexp, NULL, color, strlen(color), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (!match) continue; } lastmsgtime = gettimer(); if (batchcmd) { addtobuffer(batchbuf, "## "); for (i=0; (i < metacount); i++) { addtobuffer(batchbuf, metadata[i]); addtobuffer(batchbuf, " "); } addtobuffer(batchbuf, "\n"); addtobuffer(batchbuf, restofmsg); addtobuffer(batchbuf, "\n"); } else { fprintf(logfd, "## "); for (i=0; (i < metacount); i++) fprintf(logfd, "%s ", metadata[i]); fprintf(logfd, "\n"); fprintf(logfd, "%s\n", restofmsg); } } } return 0; }
static bool load_config(plugin_state_t *pstate, invalidate_t **ilist) { FILE *fs; struct stat s; size_t path_len; char *path; char line[LINE_MAX]; time_t now; pcre *config_re; const char *errptr; int erroffset, ovector[OVECTOR_SIZE], rc; int ln = 0; invalidate_t *iptr, *i; if (pstate->config_file[0] != '/') { path_len = strlen(TSConfigDirGet()) + strlen(pstate->config_file) + 2; path = alloca(path_len); snprintf(path, path_len, "%s/%s", TSConfigDirGet(), pstate->config_file); } else { path = pstate->config_file; } if (stat(path, &s) < 0) { TSDebug(LOG_PREFIX, "Could not stat %s", path); return false; } if (s.st_mtime > pstate->last_load) { now = time(NULL); if (!(fs = fopen(path, "r"))) { TSDebug(LOG_PREFIX, "Could not open %s for reading", path); return false; } config_re = pcre_compile("^([^#].+?)\\s+(\\d+)\\s*$", 0, &errptr, &erroffset, NULL); while (fgets(line, LINE_MAX, fs) != NULL) { ln++; TSDebug(LOG_PREFIX, "Processing: %d %s", ln, line); rc = pcre_exec(config_re, NULL, line, strlen(line), 0, 0, ovector, OVECTOR_SIZE); if (rc == 3) { i = (invalidate_t *)TSmalloc(sizeof(invalidate_t)); init_invalidate_t(i); pcre_get_substring(line, ovector, rc, 1, &i->regex_text); i->epoch = now; i->expiry = atoi(line + ovector[4]); i->regex = pcre_compile(i->regex_text, 0, &errptr, &erroffset, NULL); if (i->expiry <= i->epoch) { TSDebug(LOG_PREFIX, "Rule is already expired!"); free_invalidate_t(i); } else if (i->regex == NULL) { TSDebug(LOG_PREFIX, "%s did not compile", i->regex_text); free_invalidate_t(i); } else { i->regex_extra = pcre_study(i->regex, 0, &errptr); if (!*ilist) { *ilist = i; TSDebug(LOG_PREFIX, "Created new list and Loaded %s %d %d", i->regex_text, (int)i->epoch, (int)i->expiry); } else { iptr = *ilist; while (1) { if (strcmp(i->regex_text, iptr->regex_text) == 0) { if (iptr->expiry != i->expiry) { TSDebug(LOG_PREFIX, "Updating duplicate %s", i->regex_text); iptr->epoch = i->epoch; iptr->expiry = i->expiry; } free_invalidate_t(i); i = NULL; break; } else if (!iptr->next) { break; } else { iptr = iptr->next; } } if (i) { iptr->next = i; TSDebug(LOG_PREFIX, "Loaded %s %d %d", i->regex_text, (int)i->epoch, (int)i->expiry); } } } } else { TSDebug(LOG_PREFIX, "Skipping line %d", ln); } } pcre_free(config_re); fclose(fs); pstate->last_load = s.st_mtime; return true; } else { TSDebug(LOG_PREFIX, "File mod time is not newer: %d >= %d", (int)pstate->last_load, (int)s.st_mtime); } return false; }
/*! \brief Return true if the argument matches the regular expression parameter */ static int w_pcre_match(struct sip_msg* _msg, char* _s1, char* _s2) { str string; str regex; pcre *pcre_re = NULL; int pcre_rc; const char *pcre_error; int pcre_erroffset; if (_s1 == NULL) { LM_ERR("bad parameters\n"); return -2; } if (_s2 == NULL) { LM_ERR("bad parameters\n"); return -2; } if (fixup_get_svalue(_msg, (gparam_p)_s1, &string)) { LM_ERR("cannot print the format for string\n"); return -3; } if (fixup_get_svalue(_msg, (gparam_p)_s2, ®ex)) { LM_ERR("cannot print the format for regex\n"); return -3; } pcre_re = pcre_compile(regex.s, pcre_options, &pcre_error, &pcre_erroffset, NULL); if (pcre_re == NULL) { LM_ERR("pcre_re compilation of '%s' failed at offset %d: %s\n", regex.s, pcre_erroffset, pcre_error); return -4; } pcre_rc = pcre_exec( pcre_re, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ string.s, /* the matching string */ (int)(string.len), /* the length of the subject */ 0, /* start at offset 0 in the string */ 0, /* default options */ NULL, /* output vector for substring information */ 0); /* number of elements in the output vector */ /* Matching failed: handle error cases */ if (pcre_rc < 0) { switch(pcre_rc) { case PCRE_ERROR_NOMATCH: LM_DBG("'%s' doesn't match '%s'\n", string.s, regex.s); break; default: LM_DBG("matching error '%d'\n", pcre_rc); break; } pcre_free(pcre_re); return -1; } pcre_free(pcre_re); LM_DBG("'%s' matches '%s'\n", string.s, regex.s); return 1; }
static int parse_image_info(void *conf) { void *(*old_pcre_malloc)(size_t); void (*old_pcre_free)(void *); pcre *expr;//正则 char *pattern; const char *error;//正则错误内容 int pcre_state=0;//匹配图片规则状态,0为成功 -1为失败 int erroffset;//正则错误位置 int ovector[30];//识别器读取原图图片到GD对象 int expr_res;//正则匹配指针 int i=0;//循环用 ngx_image_conf_t *info = conf; info->request_filename = NULL; old_pcre_malloc = pcre_malloc; old_pcre_free = pcre_free; pcre_malloc = malloc; pcre_free = free; if(strchr(info->dest_file,'!')) { info->pcre_type = 0; //pattern = "([^<]*)!([a-z])(\\d{2,4})x(\\d{2,4}).([a-zA-Z]{3,4})";//正则表达式 pattern = "([^<]*)\\/([^<]*)!([a-z])(\\d{2,4})x(\\d{2,4}).([a-zA-Z]{3,4})";//正则表达式 } else { info->pcre_type = 1; //pattern = "([^<]*).([a-z])(\\d{2,4})x(\\d{2,4}).([a-zA-Z]{3,4})";//正则表达式 pattern = "([^<]*)\\/([^<]*).([a-z])(\\d{2,4})x(\\d{2,4}).([a-zA-Z]{3,4})";//正则表达式 } expr = pcre_compile((const char *)pattern,0,&error,&erroffset,NULL); if(expr != NULL) { expr_res = pcre_exec(expr,NULL,(const char *)info->dest_file,ngx_strlen(info->dest_file),0,0,ovector,30); if(expr_res > 5) { for(i=0; i<expr_res; i++) { char *substring_start = info->dest_file + ovector[2*i]; int substring_length = ovector[2*i+1] - ovector[2*i]; sprintf(info->buffer[i],"%.*s",substring_length,substring_start); //printf("%d : %.*s\n",i,substring_length,substring_start); } info->source_file = info->buffer[1]; if(info->pcre_type == 1) { /** combind source_file **/ strcat(info->source_file,"/"); strcat(info->source_file,info->buffer[2]); strcat(info->source_file,"."); strcat(info->source_file,info->buffer[6]); /** combind request_filename **/ info->request_filename = info->buffer[2]; strcat(info->request_filename,"."); strcat(info->request_filename,info->buffer[6]); } else { /** combind source_file **/ strcat(info->source_file,"/"); strcat(info->source_file,info->buffer[2]); /** combind request_filename **/ info->request_filename = info->buffer[2]; } info->local_dir = dirname(info->buffer[1]); info->dest_file = info->buffer[0]; info->m_type = info->buffer[3]; info->max_width = atoi(info->buffer[4]); info->max_height = atoi(info->buffer[5]); info->max_width = (info->max_width > 2000) ? 2000 : info->max_width; info->max_height = (info->max_height > 2000) ? 2000 : info->max_height; if(info->max_width <= 0 || info->max_height <=0 ){ //如果图片小于等于0,则可以判断请求无效了 pcre_free(expr); pcre_malloc = old_pcre_malloc; pcre_free = old_pcre_free; return -1; } //printf("source_file:%s\n",info->source_file); if(file_exists(info->source_file) == -1)//原图不存在 { download(conf); } if(file_exists(info->source_file) == 0) { pcre_state = calc_image_info(conf); pcre_free(expr); pcre_malloc = old_pcre_malloc; pcre_free = old_pcre_free; return pcre_state; } } pcre_free(expr); //恢复Nginx默认PCRE内存分配 pcre_malloc = old_pcre_malloc; pcre_free = old_pcre_free; //END } return -1; }