Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
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;
}
Esempio n. 4
0
/*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;
}
Esempio n. 5
0
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
}
Esempio n. 6
0
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 */
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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);
}
Esempio n. 9
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", &regex, &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;
}
Esempio n. 11
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);
}
Esempio n. 12
0
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;
}
Esempio n. 14
0
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);
    }
}
Esempio n. 16
0
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;
}
Esempio n. 17
0
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;
}
Esempio n. 18
0
File: node.c Progetto: czchen/r3
/**
 * 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
}
Esempio n. 19
0
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;
}
Esempio n. 20
0
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;
}
Esempio n. 21
0
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;
}
Esempio n. 22
0
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);
  }
}
Esempio n. 23
0
/*
 * 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(&regex, (const char*)fop->op.func.string, REG_EXTENDED | REG_NOSUB | REG_ICASE );
         if (err) {
            regerror(err, &regex, errbuf, sizeof(errbuf));
            SCRIPT_ERROR("%s", errbuf);
         } 
         
         regfree(&regex);
                        
      } 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;
}
Esempio n. 24
0
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(&regex->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
}
Esempio n. 25
0
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;
}
Esempio n. 26
0
/*********************************************************************
 *
 * 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;

}
Esempio n. 27
0
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;
}
Esempio n. 28
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;
}
Esempio n. 29
0
/*! \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, &regex))
	{
		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;
}