/* * *presult is "did comparison match or not" */ static int radius_do_cmp(REQUEST *request, int *presult, FR_TOKEN lt, const char *pleft, FR_TOKEN token, FR_TOKEN rt, const char *pright, int cflags, int modreturn) { int result; uint32_t lint, rint; VALUE_PAIR *vp = NULL; #ifdef HAVE_REGEX_H char buffer[8192]; #else cflags = cflags; /* -Wunused */ #endif rt = rt; /* -Wunused */ if (lt == T_BARE_WORD) { /* * Maybe check the last return code. */ if (token == T_OP_CMP_TRUE) { int isreturn; /* * Looks like a return code, treat is as such. */ isreturn = fr_str2int(modreturn_table, pleft, -1); if (isreturn != -1) { *presult = (modreturn == isreturn); return TRUE; } } /* * Bare words on the left can be attribute names. */ if (!(radius_get_vp(request, pleft, &vp) < 0)) { VALUE_PAIR myvp; /* * VP exists, and that's all we're looking for. */ if (token == T_OP_CMP_TRUE) { *presult = (vp != NULL); return TRUE; } if (!vp) { const DICT_ATTR *da; /* * The attribute on the LHS may * have been a dynamically * registered callback. i.e. it * doesn't exist as a VALUE_PAIR. * If so, try looking for it. */ da = dict_attrbyname(pleft); if (da && (da->vendor == 0) && radius_find_compare(da->attr)) { VALUE_PAIR *check = pairmake(pleft, pright, token); *presult = (radius_callback_compare(request, NULL, check, NULL, NULL) == 0); RDEBUG3(" Callback returns %d", *presult); pairfree(&check); return TRUE; } RDEBUG2(" (Attribute %s was not found)", pleft); *presult = 0; return TRUE; } #ifdef HAVE_REGEX_H /* * Regex comparisons treat everything as * strings. */ if ((token == T_OP_REG_EQ) || (token == T_OP_REG_NE)) { vp_prints_value(buffer, sizeof(buffer), vp, 0); pleft = buffer; goto do_checks; } #endif memcpy(&myvp, vp, sizeof(myvp)); if (!pairparsevalue(&myvp, pright)) { RDEBUG2("Failed parsing \"%s\": %s", pright, fr_strerror()); return FALSE; } myvp.op = token; *presult = paircmp(&myvp, vp); RDEBUG3(" paircmp -> %d", *presult); return TRUE; } /* else it's not a VP in a list */ } #ifdef HAVE_REGEX_H do_checks: #endif switch (token) { case T_OP_GE: case T_OP_GT: case T_OP_LE: case T_OP_LT: if (!all_digits(pright)) { RDEBUG2(" (Right field is not a number at: %s)", pright); return FALSE; } rint = strtoul(pright, NULL, 0); if (!all_digits(pleft)) { RDEBUG2(" (Left field is not a number at: %s)", pleft); return FALSE; } lint = strtoul(pleft, NULL, 0); break; default: lint = rint = 0; /* quiet the compiler */ break; } switch (token) { case T_OP_CMP_TRUE: /* * Check for truth or falsehood. */ if (all_digits(pleft)) { lint = strtoul(pleft, NULL, 0); result = (lint != 0); } else { result = (*pleft != '\0'); } break; case T_OP_CMP_EQ: result = (strcmp(pleft, pright) == 0); break; case T_OP_NE: result = (strcmp(pleft, pright) != 0); break; case T_OP_GE: result = (lint >= rint); break; case T_OP_GT: result = (lint > rint); break; case T_OP_LE: result = (lint <= rint); break; case T_OP_LT: result = (lint < rint); break; #ifdef HAVE_REGEX_H case T_OP_REG_EQ: { int i, compare; regex_t reg; regmatch_t rxmatch[REQUEST_MAX_REGEX + 1]; /* * Include substring matches. */ compare = regcomp(®, pright, cflags); if (compare != 0) { if (debug_flag) { char errbuf[128]; regerror(compare, ®, errbuf, sizeof(errbuf)); DEBUGE("Failed compiling regular expression: %s", errbuf); } return FALSE; } compare = regexec(®, pleft, REQUEST_MAX_REGEX + 1, rxmatch, 0); regfree(®); /* * Add new %{0}, %{1}, etc. */ if (compare == 0) for (i = 0; i <= REQUEST_MAX_REGEX; i++) { char *r; free(request_data_get(request, request, REQUEST_DATA_REGEX | i)); /* * No %{i}, skip it. * We MAY have %{2} without %{1}. */ if (rxmatch[i].rm_so == -1) continue; /* * Copy substring into allocated buffer */ r = rad_malloc(rxmatch[i].rm_eo -rxmatch[i].rm_so + 1); memcpy(r, pleft + rxmatch[i].rm_so, rxmatch[i].rm_eo - rxmatch[i].rm_so); r[rxmatch[i].rm_eo - rxmatch[i].rm_so] = '\0'; request_data_add(request, request, REQUEST_DATA_REGEX | i, r, free); } result = (compare == 0); } break; case T_OP_REG_NE: { int compare; regex_t reg; regmatch_t rxmatch[REQUEST_MAX_REGEX + 1]; /* * Include substring matches. */ compare = regcomp(®, pright, cflags); if (compare != 0) { if (debug_flag) { char errbuf[128]; regerror(compare, ®, errbuf, sizeof(errbuf)); DEBUGE("Failed compiling regular expression: %s", errbuf); } return FALSE; } compare = regexec(®, pleft, REQUEST_MAX_REGEX + 1, rxmatch, 0); regfree(®); result = (compare != 0); } break; #endif default: DEBUGE("Comparison operator %s is not supported", fr_token_name(token)); result = FALSE; break; } *presult = result; return TRUE; }
char * xstormy16_cgen_build_insn_regex (CGEN_INSN *insn) { CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn); const char *mnem = CGEN_INSN_MNEMONIC (insn); char rxbuf[CGEN_MAX_RX_ELEMENTS]; char *rx = rxbuf; const CGEN_SYNTAX_CHAR_TYPE *syn; int reg_err; syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc)); /* Mnemonics come first in the syntax string. */ if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) return _("missing mnemonic in syntax string"); ++syn; /* Generate a case sensitive regular expression that emulates case insensitive matching in the "C" locale. We cannot generate a case insensitive regular expression because in Turkish locales, 'i' and 'I' are not equal modulo case conversion. */ /* Copy the literal mnemonic out of the insn. */ for (; *mnem; mnem++) { char c = *mnem; if (ISALPHA (c)) { *rx++ = '['; *rx++ = TOLOWER (c); *rx++ = TOUPPER (c); *rx++ = ']'; } else *rx++ = c; } /* Copy any remaining literals from the syntax string into the rx. */ for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn) { if (CGEN_SYNTAX_CHAR_P (* syn)) { char c = CGEN_SYNTAX_CHAR (* syn); switch (c) { /* Escape any regex metacharacters in the syntax. */ case '.': case '[': case '\\': case '*': case '^': case '$': #ifdef CGEN_ESCAPE_EXTENDED_REGEX case '?': case '{': case '}': case '(': case ')': case '*': case '|': case '+': case ']': #endif *rx++ = '\\'; *rx++ = c; break; default: if (ISALPHA (c)) { *rx++ = '['; *rx++ = TOLOWER (c); *rx++ = TOUPPER (c); *rx++ = ']'; } else *rx++ = c; break; } } else { /* Replace non-syntax fields with globs. */ *rx++ = '.'; *rx++ = '*'; } } /* Trailing whitespace ok. */ * rx++ = '['; * rx++ = ' '; * rx++ = '\t'; * rx++ = ']'; * rx++ = '*'; /* But anchor it after that. */ * rx++ = '$'; * rx = '\0'; CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t)); reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB); if (reg_err == 0) return NULL; else { static char msg[80]; regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80); regfree ((regex_t *) CGEN_INSN_RX (insn)); free (CGEN_INSN_RX (insn)); (CGEN_INSN_RX (insn)) = NULL; return msg; } }
/*! \brief Parse DNS NAPTR record used in ENUM ---*/ static int parse_naptr(unsigned char *dst, int dstsize, char *tech, int techsize, unsigned char *answer, int len, unsigned char *naptrinput) { char tech_return[80]; char *oanswer = (char *)answer; char flags[512] = ""; char services[512] = ""; char *p; char regexp[512] = ""; char repl[512] = ""; char tempdst[512] = ""; char errbuff[512] = ""; char delim; char *delim2; char *pattern, *subst, *d; int res; int regexp_len, rc; static const int max_bt = 10; /* max num of regexp backreference allowed, must remain 10 to guarantee a valid backreference index */ int size, matchindex; /* size is the size of the backreference sub. */ size_t d_len = sizeof(tempdst) - 1; regex_t preg; regmatch_t pmatch[max_bt]; tech_return[0] = '\0'; dst[0] = '\0'; if (len < sizeof(struct naptr)) { ast_log(LOG_WARNING, "NAPTR record length too short\n"); return -1; } answer += sizeof(struct naptr); len -= sizeof(struct naptr); if ((res = parse_ie(flags, sizeof(flags) - 1, answer, len)) < 0) { ast_log(LOG_WARNING, "Failed to get flags from NAPTR record\n"); return -1; } else { answer += res; len -= res; } if ((res = parse_ie(services, sizeof(services) - 1, answer, len)) < 0) { ast_log(LOG_WARNING, "Failed to get services from NAPTR record\n"); return -1; } else { answer += res; len -= res; } if ((res = parse_ie(regexp, sizeof(regexp) - 1, answer, len)) < 0) { ast_log(LOG_WARNING, "Failed to get regexp from NAPTR record\n"); return -1; } else { answer += res; len -= res; } if ((res = dn_expand((unsigned char *)oanswer, (unsigned char *)answer + len, (unsigned char *)answer, repl, sizeof(repl) - 1)) < 0) { ast_log(LOG_WARNING, "Failed to expand hostname\n"); return -1; } ast_debug(3, "NAPTR input='%s', flags='%s', services='%s', regexp='%s', repl='%s'\n", naptrinput, flags, services, regexp, repl); if (tolower(flags[0]) != 'u') { ast_log(LOG_WARNING, "NAPTR Flag must be 'U' or 'u'.\n"); return -1; } p = strstr(services, "e2u+"); if (p == NULL) p = strstr(services, "E2U+"); if (p){ p = p + 4; if (strchr(p, ':')){ p = strchr(p, ':') + 1; } ast_copy_string(tech_return, p, sizeof(tech_return)); } else { p = strstr(services, "+e2u"); if (p == NULL) p = strstr(services, "+E2U"); if (p) { *p = 0; p = strchr(services, ':'); if (p) *p = 0; ast_copy_string(tech_return, services, sizeof(tech_return)); } } regexp_len = strlen(regexp); if (regexp_len < 7) { ast_log(LOG_WARNING, "Regex too short to be meaningful.\n"); return -1; } /* this takes the first character of the regexp (which is a delimiter) * and uses that character to find the index of the second delimiter */ delim = regexp[0]; delim2 = strchr(regexp + 1, delim); if ((delim2 == NULL) || (regexp[regexp_len - 1] != delim)) { /* is the second delimiter found, and is the end of the regexp a delimiter */ ast_log(LOG_WARNING, "Regex delimiter error (on \"%s\").\n", regexp); return -1; } else if (strchr((delim2 + 1), delim) == NULL) { /* if the second delimiter is found, make sure there is a third instance. this could be the end one instead of the middle */ ast_log(LOG_WARNING, "Regex delimiter error (on \"%s\").\n", regexp); return -1; } pattern = regexp + 1; /* pattern is the regex without the begining and ending delimiter */ *delim2 = 0; /* zero out the middle delimiter */ subst = delim2 + 1; /* dst substring is everything after the second delimiter. */ regexp[regexp_len - 1] = 0; /* zero out the last delimiter */ /* * now do the regex wizardry. */ if (regcomp(&preg, pattern, REG_EXTENDED | REG_NEWLINE)) { ast_log(LOG_WARNING, "NAPTR Regex compilation error (regex = \"%s\").\n", regexp); return -1; } if (preg.re_nsub > ARRAY_LEN(pmatch)) { ast_log(LOG_WARNING, "NAPTR Regex compilation error: too many subs.\n"); regfree(&preg); return -1; } /* pmatch is an array containing the substring indexes for the regex backreference sub. * max_bt is the maximum number of backreferences allowed to be stored in pmatch */ if ((rc = regexec(&preg, (char *) naptrinput, max_bt, pmatch, 0))) { regerror(rc, &preg, errbuff, sizeof(errbuff)); ast_log(LOG_WARNING, "NAPTR Regex match failed. Reason: %s\n", errbuff); regfree(&preg); return -1; } regfree(&preg); d = tempdst; d_len--; /* perform the backreference sub. Search the subst for backreferences, * when a backreference is found, retrieve the backreferences number. * use the backreference number as an index for pmatch to retrieve the * beginning and ending indexes of the substring to insert as the backreference. * if no backreference is found, continue copying the subst into tempdst */ while (*subst && (d_len > 0)) { if ((subst[0] == '\\') && isdigit(subst[1])) { /* is this character the beginning of a backreference */ matchindex = (int) (subst[1] - '0'); if (matchindex >= ARRAY_LEN(pmatch)) { ast_log(LOG_WARNING, "Error during regex substitution. Invalid pmatch index.\n"); return -1; } /* pmatch len is 10. we are garanteed a single char 0-9 is a valid index */ size = pmatch[matchindex].rm_eo - pmatch[matchindex].rm_so; if (size > d_len) { ast_log(LOG_WARNING, "Not enough space during NAPTR regex substitution.\n"); return -1; } /* are the pmatch indexes valid for the input length */ if ((strlen((char *) naptrinput) >= pmatch[matchindex].rm_eo) && (pmatch[matchindex].rm_so <= pmatch[matchindex].rm_eo)) { memcpy(d, (naptrinput + (int) pmatch[matchindex].rm_so), size); /* copy input substring into backreference marker */ d_len -= size; subst += 2; /* skip over backreference characters to next valid character */ d += size; } else { ast_log(LOG_WARNING, "Error during regex substitution. Invalid backreference index.\n"); return -1; } } else if (isprint(*subst)) { *d++ = *subst++; d_len--; } else { ast_log(LOG_WARNING, "Error during regex substitution.\n"); return -1; } } *d = 0; ast_copy_string((char *) dst, tempdst, dstsize); dst[dstsize - 1] = '\0'; if (*tech != '\0'){ /* check if it is requested NAPTR */ if (!strncasecmp(tech, "ALL", techsize)){ return 0; /* return or count any RR */ } if (!strncasecmp(tech_return, tech, sizeof(tech_return) < techsize ? sizeof(tech_return): techsize)){ ast_copy_string(tech, tech_return, techsize); return 0; /* we got our RR */ } else { /* go to the next RR in the DNS answer */ return 1; } } /* tech was not specified, return first parsed RR */ ast_copy_string(tech, tech_return, techsize); return 0; }
/** * Generic service test. * * @file */ int check_generic(Socket_T socket) { Generic_T g= NULL; char *buf; #ifdef HAVE_REGEX_H int regex_return; #endif ASSERT(socket); if(socket_get_Port(socket)) g = ((Port_T)(socket_get_Port(socket)))->generic; buf = CALLOC(sizeof(char), Run.expectbuffer + 1); while (g != NULL) { if (g->send != NULL) { /* Unescape any \0x00 escaped chars in g's send string to allow sending a string containing \0 bytes also */ char *X = Str_dup(g->send); int l = Util_handle0Escapes(X); if(socket_write(socket, X, l) < 0) { socket_setError(socket, "GENERIC: error sending data -- %s\n", STRERROR); FREE(X); FREE(buf); return FALSE; } else DEBUG("GENERIC: successfully sent: '%s'\n", g->send); FREE(X); } else if (g->expect != NULL) { int n; /* Need read, not readln here */ if((n= socket_read(socket, buf, Run.expectbuffer))<0) { socket_setError(socket, "GENERIC: error receiving data -- %s\n", STRERROR); FREE(buf); return FALSE; } buf[n]= 0; #ifdef HAVE_REGEX_H regex_return= regexec(g->expect, buf, 0, NULL, 0); if (regex_return != 0) { char e[STRLEN]; regerror(regex_return, g->expect, e, STRLEN); socket_setError(socket, "GENERIC: receiving unexpected data [%s] -- %s\n", Str_trunc(buf, STRLEN - 4), e); FREE(buf); return FALSE; } else DEBUG("GENERIC: successfully received: '%s'\n", Str_trunc(buf, STRLEN - 4)); #else /* w/o regex support */ if (strncmp(buf, g->expect, strlen(g->expect)) != 0) { socket_setError(socket, "GENERIC: receiving unexpected data [%s]\n", Str_trunc(buf, STRLEN - 4)); FREE(buf); return FALSE; } else DEBUG("GENERIC: successfully received: '%s'\n", Str_trunc(buf, STRLEN - 4)); #endif } else { /* This should not happen */ socket_setError(socket, "GENERIC: unexpected strangeness\n"); FREE(buf); return FALSE; } g= g->next; } FREE(buf); return TRUE; }
int common_check_files(struct recording_entity *re, void *opt_ss) { int err = 0; int temp = 0; int retval = 0; int i, n_files; //int len; //struct recording_entity **temprecer; struct common_io_info *ioi = re->opt; struct opt_s *opt = (struct opt_s *)opt_ss; if (opt->optbits & WRITE_TO_SINGLE_FILE) { char filename[FILENAME_MAX]; struct stat statbuf; sprintf(filename, "%s%i/%s/%s", ROOTDIRS, ioi->id, opt->filename, opt->filename); D("Writing/reading to/from single file %s", filename); err = stat(filename, &statbuf); CHECK_ERR("Stat main data file"); afi_single_all_found(opt->fi, ioi->id); opt->cumul = afi_get_n_files(opt->fi); return 0; } char *dirname = (char *)malloc(sizeof(char) * FILENAME_MAX); CHECK_ERR_NONNULL(dirname, "Dirname malloc"); regex_t regex; sprintf(dirname, "%s%i%s%s%s", ROOTDIRS, ioi->id, "/", opt->filename, "/"); D("Checking for files and updating fileholders on %s", dirname); /* GRRR can't get [:digit:]{8} to work so I'll just do it manually */ char *regstring = (char *)malloc(sizeof(char) * FILENAME_MAX); CHECK_ERR_NONNULL(regstring, "Malloc regexp string"); sprintf(regstring, "^%s.[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]", opt->filename); //err = regcomp(®ex, "^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]", 0); err = regcomp(®ex, regstring, 0); if (err != 0) { E("Error in forming regcomp"); free(regstring); return -1; } /* print all the files and directories within directory */ struct dirent **namelist; //int j; n_files = scandir(dirname, &namelist, NULL, NULL); if (n_files < 0) { // could not open directory perror("Check files"); retval = EXIT_FAILURE; } else { for (i = 0; i < n_files; i++) { err = regexec(®ex, namelist[i]->d_name, 0, NULL, 0); /* If we match a data file */ if (!err) { D("Regexp matched %s", namelist[i]->d_name); /* Grab the INDEXING_LENGTH last chars from ent->d_name, which is the */ /* The files index */ char *start_of_index = namelist[i]->d_name + (strlen(namelist[i]->d_name)) - INDEXING_LENGTH; temp = atoi(start_of_index); if ((unsigned long)temp >= afi_get_n_files(opt->fi)) { E("Extra files found in dir named! Temp read %i, " "the_index: %s", temp, start_of_index); } else { D("Identified %s as %d", start_of_index, temp); afi_set_found(opt->fi, temp, ioi->id); opt->cumul_found++; } } else if (err == REG_NOMATCH) { D("Regexp didn't match %s", namelist[i]->d_name); } else { char msgbuf[100]; regerror(err, ®ex, msgbuf, sizeof(msgbuf)); E("Regex match failed: %s", msgbuf); } free(namelist[i]); } free(namelist); } D("Finished reading files in dir"); free(regstring); free(dirname); regfree(®ex); return retval; }
static int do_test(void) { static const char *pat[] = { ".?.?.?.?.?.?.?Log\\.13", "(.?)(.?)(.?)(.?)(.?)(.?)(.?)Log\\.13", "((((((((((.?))))))))))((((((((((.?))))))))))((((((((((.?))))))))))" "((((((((((.?))))))))))((((((((((.?))))))))))((((((((((.?))))))))))" "((((((((((.?))))))))))Log\\.13" }; char *buf, *string; const char *fname = "tst-regex2.dat"; struct stat st; unsigned len; int testno; int exitcode = 0; int fd = open(fname, O_RDONLY); if (fd < 0) { printf("Couldn't open %s: %s\n", fname, strerror(errno)); return 1; } if (fstat(fd, &st) < 0) { printf("Couldn't fstat %s: %s\n", fname, strerror(errno)); return 1; } len = st.st_size; string = buf = malloc(len + 1); if (buf == NULL) { printf("Couldn't allocate %u bytes\n", len + 1); return 1; } if (read(fd, buf, st.st_size) != (ssize_t) st.st_size) { printf("Couldn't read %s\n", fname); return 1; } close(fd); buf[len] = '\0'; #if defined __UCLIBC_HAS_XLOCALE__ || !defined __UCLIBC__ setlocale(LC_ALL, "de_DE.UTF-8"); #endif for (testno = 0; testno < 2; ++testno) { int i; for (i = 0; i < sizeof(pat) / sizeof(pat[0]); ++i) { struct timeval start, stop; regex_t rbuf; int err; printf("test %d pattern %d '%s'\n", testno, i, pat[i]); gettimeofday(&start, NULL); err = regcomp(&rbuf, pat[i], REG_EXTENDED | (testno ? REG_NOSUB : 0)); if (err != 0) { char errstr[300]; regerror(err, &rbuf, errstr, sizeof(errstr)); puts(errstr); exitcode = 1; goto contin1; } regmatch_t pmatch[71]; err = regexec(&rbuf, string, 71, pmatch, 0); if (err == REG_NOMATCH) { puts("regexec failed"); exitcode = 1; goto contin1; } if (testno == 0) { if (pmatch[0].rm_eo != pmatch[0].rm_so + 13 || pmatch[0].rm_eo > len || pmatch[0].rm_so < len - 100 || strncmp(string + pmatch[0].rm_so, " ChangeLog.13 for earlier changes", sizeof " ChangeLog.13 for earlier changes" - 1 ) != 0 ) { puts("regexec without REG_NOSUB did not find the correct match"); exitcode = 1; goto contin1; } if (i > 0) { int j, k, l; for (j = 0, l = 1; j < 7; ++j) { for (k = 0; k < (i == 1 ? 1 : 10); ++k, ++l) { if (pmatch[l].rm_so != pmatch[0].rm_so + j || pmatch[l].rm_eo != pmatch[l].rm_so + 1 ) { printf("pmatch[%d] incorrect\n", l); exitcode = 1; goto contin1; } } } } } gettimeofday(&stop, NULL); stop.tv_sec -= start.tv_sec; if (stop.tv_usec < start.tv_usec) { stop.tv_sec--; stop.tv_usec += 1000000; } stop.tv_usec -= start.tv_usec; printf(" %lu.%06lus\n", (unsigned long) stop.tv_sec, (unsigned long) stop.tv_usec); contin1: regfree(&rbuf); } } for (testno = 2; testno < 4; ++testno) { int i; for (i = 0; i < sizeof(pat) / sizeof(pat[0]); ++i) { struct timeval start, stop; struct re_pattern_buffer rpbuf; struct re_registers regs; const char *s; int match; printf("test %d pattern %d '%s'\n", testno, i, pat[i]); gettimeofday(&start, NULL); re_set_syntax(RE_SYNTAX_POSIX_EGREP | (testno == 3 ? RE_NO_SUB : 0)); memset(&rpbuf, 0, sizeof(rpbuf)); s = re_compile_pattern(pat[i], strlen(pat[i]), &rpbuf); if (s != NULL) { printf("%s\n", s); exitcode = 1; goto contin2; } memset(®s, 0, sizeof(regs)); match = re_search(&rpbuf, string, len, 0, len, ®s); if (match < 0) { printf("re_search failed (err:%d)\n", match); exitcode = 1; goto contin2; } if (match + 13 > len) { printf("re_search: match+13 > len (%d > %d)\n", match + 13, len); exitcode = 1; goto contin2; } if (match < len - 100) { printf("re_search: match < len-100 (%d < %d)\n", match, len - 100); exitcode = 1; goto contin2; } if (strncmp(string + match, " ChangeLog.13 for earlier changes", sizeof(" ChangeLog.13 for earlier changes") - 1 ) != 0 ) { printf("re_search did not find the correct match" "(found '%s' instead)\n", string + match); exitcode = 1; goto contin2; } if (testno == 2) { int expected = 72; if (i == 0) expected = 2; if (i == 1) expected = 9; if (regs.num_regs != expected) { printf("incorrect num_regs %d, expected %d\n", regs.num_regs, expected); exitcode = 1; goto contin2; } if (regs.start[0] != match || regs.end[0] != match + 13) { printf("incorrect regs.{start,end}[0] = { %d, %d }," " expected { %d, %d }\n", regs.start[0], regs.end[0], match, match + 13 ); exitcode = 1; goto contin2; } if (regs.start[regs.num_regs - 1] != -1 || regs.end[regs.num_regs - 1] != -1 ) { printf("incorrect regs.{start,end}[num_regs - 1] = { %d, %d }," " expected { -1, -1 }\n", regs.start[regs.num_regs - 1], regs.end[regs.num_regs - 1] ); exitcode = 1; goto contin2; } if (i > 0) { int j, k, l; for (j = 0, l = 1; j < 7; ++j) { for (k = 0; k < (i == 1 ? 1 : 10); ++k, ++l) { if (regs.start[l] != match + j || regs.end[l] != match + j + 1 ) { printf("incorrect regs.{start,end}[%d] = { %d, %d }," " expected { %d, %d }\n", l, regs.start[l], regs.end[l], match + j, match + j + 1 ); exitcode = 1; goto contin2; } } } } } gettimeofday(&stop, NULL); stop.tv_sec -= start.tv_sec; if (stop.tv_usec < start.tv_usec) { stop.tv_sec--; stop.tv_usec += 1000000; } stop.tv_usec -= start.tv_usec; printf(" %lu.%06lus\n", (unsigned long) stop.tv_sec, (unsigned long) stop.tv_usec); contin2: regfree(&rpbuf); } } return exitcode; }
/* - regprop - printable representation of opcode */ static char * regprop( char* op) { register char *p; static char buf[50]; (void) strcpy(buf, ":"); switch (OP(op)) { case BOL: p = "BOL"; break; case EOL: p = "EOL"; break; case ANY: p = "ANY"; break; case ANYOF: p = "ANYOF"; break; case ANYBUT: p = "ANYBUT"; break; case BRANCH: p = "BRANCH"; break; case EXACTLY: p = "EXACTLY"; break; case NOTHING: p = "NOTHING"; break; case BACK: p = "BACK"; break; case END: p = "END"; break; case OPEN+1: case OPEN+2: case OPEN+3: case OPEN+4: case OPEN+5: case OPEN+6: case OPEN+7: case OPEN+8: case OPEN+9: sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN); p = NULL; break; case CLOSE+1: case CLOSE+2: case CLOSE+3: case CLOSE+4: case CLOSE+5: case CLOSE+6: case CLOSE+7: case CLOSE+8: case CLOSE+9: sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE); p = NULL; break; case STAR: p = "STAR"; break; case PLUS: p = "PLUS"; break; default: regerror("corrupted opcode"); break; } if (p != NULL) (void) strcat(buf, p); return(buf); }
int main (int argc, char **argv) { int ret = 0; char *line = NULL; size_t line_len = 0; ssize_t len; FILE *f; char *pattern = NULL, *string = NULL; regmatch_t rm[20]; size_t pattern_alloced = 0, string_alloced = 0; int ignorecase = 0; int pattern_valid = 0, rm_valid = 0; size_t linenum; mtrace (); if (argc < 2) { fprintf (stderr, "Missing test filename\n"); return 1; } f = fopen (argv[1], "r"); if (f == NULL) { fprintf (stderr, "Couldn't open %s\n", argv[1]); return 1; } if ((len = getline (&line, &line_len, f)) <= 0 || strncmp (line, "# PCRE", 6) != 0) { fprintf (stderr, "Not a PCRE test file\n"); fclose (f); free (line); return 1; } linenum = 1; while ((len = getline (&line, &line_len, f)) > 0) { char *p; unsigned long num; ++linenum; if (line[len - 1] == '\n') line[--len] = '\0'; if (line[0] == '#') continue; if (line[0] == '\0') { /* End of test. */ ignorecase = 0; pattern_valid = 0; rm_valid = 0; continue; } if (line[0] == '/') { /* Pattern. */ p = strrchr (line + 1, '/'); pattern_valid = 0; rm_valid = 0; if (p == NULL) { printf ("%zd: Invalid pattern line: %s\n", linenum, line); ret = 1; continue; } if (p[1] == 'i' && p[2] == '\0') ignorecase = 1; else if (p[1] != '\0') { printf ("%zd: Invalid pattern line: %s\n", linenum, line); ret = 1; continue; } if (pattern_alloced < (size_t) (p - line)) { pattern = realloc (pattern, p - line); if (pattern == NULL) { printf ("%zd: Cannot record pattern: %m\n", linenum); ret = 1; break; } pattern_alloced = p - line; } memcpy (pattern, line + 1, p - line - 1); pattern[p - line - 1] = '\0'; pattern_valid = 1; continue; } if (strncmp (line, " ", 4) == 0) { regex_t re; int n; if (!pattern_valid) { printf ("%zd: No previous valid pattern %s\n", linenum, line); continue; } if (string_alloced < (size_t) (len - 3)) { string = realloc (string, len - 3); if (string == NULL) { printf ("%zd: Cannot record search string: %m\n", linenum); ret = 1; break; } string_alloced = len - 3; } memcpy (string, line + 4, len - 3); n = regcomp (&re, pattern, REG_EXTENDED | (ignorecase ? REG_ICASE : 0)); if (n != 0) { char buf[500]; regerror (n, &re, buf, sizeof (buf)); printf ("%zd: regcomp failed for %s: %s\n", linenum, pattern, buf); ret = 1; continue; } if (regexec (&re, string, 20, rm, 0)) { rm[0].rm_so = -1; rm[0].rm_eo = -1; } regfree (&re); rm_valid = 1; continue; } if (!rm_valid) { printf ("%zd: No preceeding pattern or search string\n", linenum); ret = 1; continue; } if (strcmp (line, "No match") == 0) { if (rm[0].rm_so != -1 || rm[0].rm_eo != -1) { printf ("%zd: /%s/ on %s unexpectedly matched %d..%d\n", linenum, pattern, string, rm[0].rm_so, rm[0].rm_eo); ret = 1; } continue; } p = line; if (*p == ' ') ++p; num = strtoul (p, &p, 10); if (num >= 20 || *p != ':' || p[1] != ' ') { printf ("%zd: Invalid line %s\n", linenum, line); ret = 1; continue; } if (rm[num].rm_so == -1 || rm[num].rm_eo == -1) { if (strcmp (p + 2, "<unset>") != 0) { printf ("%zd: /%s/ on %s unexpectedly failed to match register %ld %d..%d\n", linenum, pattern, string, num, rm[num].rm_so, rm[num].rm_eo); ret = 1; } continue; } if (rm[num].rm_eo < rm[num].rm_so || rm[num].rm_eo - rm[num].rm_so != len - (p + 2 - line) || strncmp (p + 2, string + rm[num].rm_so, rm[num].rm_eo - rm[num].rm_so) != 0) { printf ("%zd: /%s/ on %s unexpectedly failed to match %s for register %ld %d..%d\n", linenum, pattern, string, p + 2, num, rm[num].rm_so, rm[num].rm_eo); ret = 1; continue; } } free (pattern); free (string); free (line); fclose (f); return ret; }
u_char * var_logmatch_table(struct variable *vp, oid * name, size_t * length, int exact, size_t * var_len, WriteMethod ** write_method) { static long long_ret; static char message[256]; int iindex; struct logmatchstat *logmatch; if (vp->magic == LOGMATCH_INFO) { if (header_generic(vp, name, length, exact, var_len, write_method) == MATCH_FAILED) return (NULL); } else { if (header_simple_table (vp, name, length, exact, var_len, write_method, logmatchCount)) return (NULL); } iindex = name[*length - 1] - 1; logmatch = &logmatchTable[iindex]; if (logmatch->myRegexError == 0) updateLogmatch(iindex); switch (vp->magic) { case LOGMATCH_INFO: long_ret = MAXLOGMATCH; return (u_char *) & long_ret; case LOGMATCH_INDEX: long_ret = iindex + 1; return (u_char *) & long_ret; case LOGMATCH_NAME: *var_len = strlen(logmatch->name); return (u_char *) logmatch->name; case LOGMATCH_FILENAME: *var_len = strlen(logmatch->filename); return (u_char *) logmatch->filename; case LOGMATCH_REGEX: *var_len = strlen(logmatch->regEx); return (u_char *) logmatch->regEx; case LOGMATCH_GLOBALCTR: case LOGMATCH_GLOBALCNT: long_ret = (logmatch->globalMatchCounter); return (u_char *) & long_ret; case LOGMATCH_CURRENTCTR: case LOGMATCH_CURRENTCNT: long_ret = (logmatch->currentMatchCounter); return (u_char *) & long_ret; case LOGMATCH_COUNTER: case LOGMATCH_COUNT: long_ret = (logmatch->matchCounter); logmatch->matchCounter = 0; return (u_char *) & long_ret; case LOGMATCH_FREQ: long_ret = logmatch->frequency; return (u_char *) & long_ret; case LOGMATCH_ERROR: if (logmatch->frequency >= 0 && logmatch->myRegexError == 0) long_ret = 0; else long_ret = 1; return (u_char *) & long_ret; case LOGMATCH_MSG: regerror(logmatch->myRegexError, &(logmatch->regexBuffer), message, sizeof(message)); *var_len = strlen(message); return (u_char *) message; default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_logmatch_table\n", vp->magic)); } return NULL; }
CONDITION UTL_RegexMatch(char *regex, char *stm) { #if (HAVE_REGEX_H && HAVE_REGCOMP) int ret, regexReturn; char *new_rstring; regex_t preg; char errorBuff[256]; regmatch_t pmatch; new_rstring = UTL_ConvertRegex(regex); regexReturn = regcomp(&preg, new_rstring, 0); if (regexReturn != 0) { regerror(regexReturn, &preg, errorBuff, sizeof(errorBuff)); fprintf(stderr, "%d\n", regexReturn); fprintf(stderr, "%s\n", errorBuff); free(new_rstring); return (UTL_NOMATCH); } else { ret = regexec(&preg, stm, 1, &pmatch, 0); switch (ret) { case 0: free(new_rstring); return (UTL_MATCH); break; default: free(new_rstring); return (UTL_NOMATCH); break; } } #elif HAVE_RE_COMP int ret; char *new_rstring; new_rstring = UTL_ConvertRegex(regex); if (re_comp(new_rstring) != (char *) 0) { free(new_rstring); return (UTL_NOMATCH); } else { ret = re_exec(stm); switch (ret) { case 0: case -1: free(new_rstring); return (UTL_NOMATCH); break; case 1: free(new_rstring); return (UTL_MATCH); break; } } #else #error No suitable regular expression library found, sorry. #endif }
static void parse_wiggle_format_line(WIGGLE_READER_T *reader, const char *line) { reader->format = INVALID_FMT; int status = regexec( &fixed_format_regex, line, NUM_MATCHES, matches, 0 ); if (!status) { reader->format = FIXED_WIGGLE_FMT; } else if (status != REG_NOMATCH ) { regerror(status, &fixed_format_regex, error_message, ERROR_MESSAGE_SIZE); die( "Error checking for fixed step wiggle file: %s\n" "error message is %s\n", reader->filename, error_message ); } else { status = regexec(&var_format_regex, line, NUM_MATCHES, matches, 0); if (!status) { reader->format = VAR_WIGGLE_FMT; } else if (status != REG_NOMATCH ) { regerror(status, &var_format_regex, error_message, ERROR_MESSAGE_SIZE); die( "Error checking for variable step wiggle file: %s\n" "error message is %s\n", reader->filename, error_message ); } } if (reader->format == FIXED_WIGGLE_FMT) { const int CHROM_GROUP = 1; int len = matches[CHROM_GROUP].rm_eo - matches[CHROM_GROUP].rm_so; catch_match_too_long(len, line, reader->filename); myfree(reader->chrom); reader->chrom = mm_malloc(len + 1); char *last = strncpy(reader->chrom, line + matches[CHROM_GROUP].rm_so, len) + len; *last = 0; // Terminate string const int START_GROUP = 2; len = matches[START_GROUP].rm_eo - matches[START_GROUP].rm_so; catch_match_too_long(len, line, reader->filename); last = strncpy(buffer, line + matches[START_GROUP].rm_so, len) + len; *last = 0; // Terminate string reader->start = strtod(buffer, NULL); const int STEP_GROUP = 3; len = matches[STEP_GROUP].rm_eo - matches[STEP_GROUP].rm_so; catch_match_too_long(len, line, reader->filename); last = strncpy(buffer, line + matches[STEP_GROUP].rm_so, len) + len; *last = 0; // Terminate string reader->step = strtod(buffer, NULL); // Optional match, may not be present const int SPAN_GROUP = 5; len = matches[SPAN_GROUP].rm_eo - matches[SPAN_GROUP].rm_so; if (len > 0) { catch_match_too_long(len, line, reader->filename); last = strncpy(buffer, line + matches[SPAN_GROUP].rm_so, len) + len; *last = 0; // Terminate string reader->span = strtod(buffer, NULL); } } else if (reader->format == VAR_WIGGLE_FMT) { const int CHROM_GROUP = 1; int len = matches[CHROM_GROUP].rm_eo - matches[CHROM_GROUP].rm_so; catch_match_too_long(len, line, reader->filename); // Check if chromosome has changed since last call. if (reader->chrom == NULL || strncmp(reader->chrom, line + matches[CHROM_GROUP].rm_so, len) != 0) { myfree(reader->chrom); reader->chrom = mm_malloc(len + 1); } char *last = strncpy(reader->chrom, line + matches[CHROM_GROUP].rm_so, len) + len; *last = 0; // Terminate string // Optional match, may not be present const int SPAN_GROUP = 3; len = matches[SPAN_GROUP].rm_eo - matches[SPAN_GROUP].rm_so; if (len > 0) { catch_match_too_long(len, line, reader->filename); last = strncpy(buffer, line + matches[SPAN_GROUP].rm_so, len) + len; *last = 0; // Terminate string reader->span = strtod(buffer, NULL); } } else { die( "Unable to determine type of wiggle format in %s.\n", reader->filename ); } }
/******************************************************************** * This function initializes the regular expressions used to parse * the elements of a wiggle file. ********************************************************************/ static void setup_wiggle_regexp(WIGGLE_READER_T *reader) { int status; // Initialize regular express for parsing fixed step format record // Expected format is: // fixedStep chrom=<str> start=<integer number> [span=<integer number>] status = regcomp( &fixed_format_regex, "fixedStep[[:space:]]+" "chrom=([^[:space:]:]+)[[:space:]]+" "start=([[:digit:]]+)[[:space:]]+" "step=([[:digit:]]+)" "([[:space:]]+span=)?([[:digit:]]+)?", REG_EXTENDED | REG_ICASE | REG_NEWLINE ); if (status != 0) { regerror(status, &fixed_format_regex, error_message, ERROR_MESSAGE_SIZE); die( "Error while intitializing regular expression\n" "for parsing fixed step wiggle file: %s\n", error_message ); } // Initialize regular express for parsing variable step format record // Expected format is: // variableStep chrom=<str> [span=<integer number>] status = regcomp( &var_format_regex, "variableStep[[:space:]]+" "chrom=([^[:space:]:]+)" "([[:space:]]+span=)?([[:digit:]]+)?", REG_EXTENDED | REG_ICASE | REG_NEWLINE ); if (status != 0) { regerror(status, &var_format_regex, error_message, ERROR_MESSAGE_SIZE); die( "Error while intitializing regular expression\n" "for parsing variable step wiggle file: %s\n", error_message ); } // Initialize regular express for parsing variable step value record // Expected format is: // <number> <floating point number> status = regcomp( &var_value_regex, "([^[:space:]:]+)[[:space:]]+([^[:space:]:]+)", REG_EXTENDED | REG_ICASE | REG_NEWLINE ); if (status != 0) { regerror(status, &var_value_regex, error_message, ERROR_MESSAGE_SIZE); die( "Error while intitializing regular expression\n" "for parsing variable step data in wiggle file: %s\n", error_message ); } // Initialize regular express for parsing fixed step value record // Expected format is: // <floating point number> status = regcomp( &fixed_value_regex, "([^[:space:]:]+)", REG_EXTENDED | REG_ICASE | REG_NEWLINE ); if (status != 0) { regerror(status, &fixed_value_regex, error_message, ERROR_MESSAGE_SIZE); die( "Error while intitializing regular expression\n" "for parsing fixed step data in wiggle file: %s\n", error_message ); } }
void parseDomainFile(AtomPtr file, DomainPtr **domains_return, regex_t **regex_return) { struct stat ss; int rc; if(*domains_return) { DomainPtr *domain = *domains_return; while(*domain) { free(*domain); domain++; } free(*domains_return); *domains_return = NULL; } if(*regex_return) { regfree(*regex_return); *regex_return = NULL; } if(!file || file->length == 0) return; domains = malloc(64 * sizeof(DomainPtr)); if(domains == NULL) { do_log(L_ERROR, "Couldn't allocate domain list.\n"); return; } dlen = 0; dsize = 64; regexbuf = malloc(512); if(regexbuf == NULL) { do_log(L_ERROR, "Couldn't allocate regex.\n"); free(domains); return; } rlen = 0; rsize = 512; rc = stat(file->string, &ss); if(rc < 0) { if(errno != ENOENT) do_log_error(L_WARN, errno, "Couldn't stat file %s", file->string); } else { if(!S_ISDIR(ss.st_mode)) readDomainFile(file->string); else { char *fts_argv[2]; FTS *fts; FTSENT *fe; fts_argv[0] = file->string; fts_argv[1] = NULL; fts = fts_open(fts_argv, FTS_LOGICAL, NULL); if(fts) { while(1) { fe = fts_read(fts); if(!fe) break; if(fe->fts_info != FTS_D && fe->fts_info != FTS_DP && fe->fts_info != FTS_DC && fe->fts_info != FTS_DNR) readDomainFile(fe->fts_accpath); } fts_close(fts); } else { do_log_error(L_ERROR, errno, "Couldn't scan directory %s", file->string); } } } if(dlen > 0) { domains[dlen] = NULL; } else { free(domains); domains = NULL; } regex_t *regex; if(rlen > 0) { regex = malloc(sizeof(regex_t)); rc = regcomp(regex, regexbuf, REG_EXTENDED | REG_NOSUB); if(rc != 0) { char errbuf[100]; regerror(rc, regex, errbuf, 100); do_log(L_ERROR, "Couldn't compile regex: %s.\n", errbuf); free(regex); regex = NULL; } } else { regex = NULL; } free(regexbuf); *domains_return = domains; *regex_return = regex; return; }
int main(int argc, char *argv[]) { int i, rcc; invoke_spec **spec; int num = argc - 1; #ifndef CP_HAS_POLL struct timeval delay; delay.tv_sec = 0; delay.tv_usec = 50000; #endif if (argc < 2) { printf("do this: %s \"url\"\n", argv[0]); return 1; } if ((rcc = regcomp(&url_re, url_re_lit, REG_EXTENDED | REG_ICASE)) != 0) { char errbuf[0x100]; regerror(rcc, &url_re, errbuf, 0x100); printf("regex error: %s\n", errbuf); return 2; } cp_log_init("test_httpclient.log", LOG_LEVEL_DEBUG); cp_httpclient_init(); spec = malloc(num * sizeof(invoke_spec)); ids = malloc(num * sizeof(int)); for (i = 0; i < num; i++) { spec[i] = parse_prm(argv[i + 1]); ids[i] = i; } for (i = 0; i < num; i++) cp_httpclient_fetch_nb(spec[i]->client, spec[i]->uri, &ids[i], write_result, 1 /* run in backgroun thread */); /* wait for transfers to exit */ #ifdef CP_HAS_POLL while (results < num) poll(NULL, 0, 200); #else while (results < num) select(0, NULL, NULL, NULL, &delay); #endif for (i = 0; i < num; i++) { cp_httpclient_destroy(spec[i]->client); cp_string_drop_content(spec[i]->uri); free(spec[i]); } free(spec); free(ids); cp_httpclient_shutdown(); cp_log_close(); regfree(&url_re); return 0; }
/* - regmatch - main matching routine * * Conceptually the strategy is simple: check to see whether the current * node matches, call self recursively to see whether the rest matches, * and then act accordingly. In practice we make some effort to avoid * recursion, in particular by going through "ordinary" nodes (that don't * need to know whether the rest of the match failed) by a loop instead of * by recursion. */ static int /* 0 failure, 1 success */ regmatch( char* prog) { register char *scan; /* Current node. */ char *next; /* Next node. */ scan = prog; #ifdef DEBUG if (scan != NULL && regnarrate) fprintf(stderr, "%s(\n", regprop(scan)); #endif while (scan != NULL) { #ifdef DEBUG if (regnarrate) fprintf(stderr, "%s...\n", regprop(scan)); #endif next = regnext(scan); switch (OP(scan)) { case BOL: if (reginput != regbol) return(0); break; case EOL: if (*reginput != '\0') return(0); break; case ANY: if (*reginput == '\0') return(0); reginput++; break; case EXACTLY: { register int len; register char *opnd; opnd = OPERAND(scan); /* Inline the first character, for speed. */ if (*opnd != *reginput) return(0); len = strlen(opnd); if (len > 1 && strncmp(opnd, reginput, len) != 0) return(0); reginput += len; } break; case ANYOF: if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL) return(0); reginput++; break; case ANYBUT: if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL) return(0); reginput++; break; case NOTHING: break; case BACK: break; case OPEN+1: case OPEN+2: case OPEN+3: case OPEN+4: case OPEN+5: case OPEN+6: case OPEN+7: case OPEN+8: case OPEN+9: case OPEN+10: case OPEN+11: case OPEN+12: case OPEN+13: case OPEN+14: case OPEN+15: { register int no; register char *save; no = OP(scan) - OPEN; save = reginput; if (regmatch(next)) { /* * Don't set startp if some later * invocation of the same parentheses * already has. */ if (regstartp[no] == NULL) regstartp[no] = save; return(1); } else return(0); } break; case CLOSE+1: case CLOSE+2: case CLOSE+3: case CLOSE+4: case CLOSE+5: case CLOSE+6: case CLOSE+7: case CLOSE+8: case CLOSE+9: case CLOSE+10: case CLOSE+11: case CLOSE+12: case CLOSE+13: case CLOSE+14: case CLOSE+15: { register int no; register char *save; no = OP(scan) - CLOSE; save = reginput; if (regmatch(next)) { /* * Don't set endp if some later * invocation of the same parentheses * already has. */ if (regendp[no] == NULL) regendp[no] = save; return(1); } else return(0); } break; case BRANCH: { register char *save; if (OP(next) != BRANCH) /* No choice. */ next = OPERAND(scan); /* Avoid recursion. */ else { do { save = reginput; if (regmatch(OPERAND(scan))) return(1); reginput = save; scan = regnext(scan); } while (scan != NULL && OP(scan) == BRANCH); return(0); /* NOTREACHED */ } } break; case STAR: case PLUS: { register char nextch; register int no; register char *save; register int min; /* * Lookahead to avoid useless match attempts * when we know what character comes next. */ nextch = '\0'; if (OP(next) == EXACTLY) nextch = *OPERAND(next); min = (OP(scan) == STAR) ? 0 : 1; save = reginput; no = regrepeat(OPERAND(scan)); while (no >= min) { /* If it could work, try it. */ if (nextch == '\0' || *reginput == nextch) if (regmatch(next)) return(1); /* Couldn't or didn't -- back up. */ no--; reginput = save + no; } return(0); } break; case END: return(1); /* Success! */ break; default: regerror("memory corruption"); return(0); break; } scan = next; } /* * We get here only if there's trouble -- normally "case END" is * the terminating point. */ regerror("corrupted pointers"); return(0); }
/* * Set up the agent, running as a daemon. */ int main(int argc, char **argv) { int sep = __pmPathSeparator(); int c; int i; char namebuf[30]; char mypath[MAXPATHLEN]; __pmSetProgname(argv[0]); __pmGetUsername(&username); if (getcwd(startdir, sizeof(startdir)) == NULL) { fprintf(stderr, "%s: getcwd() failed: %s\n", pmProgname, pmErrStr(-oserror())); exit(1); } snprintf(mypath, sizeof(mypath), "%s%c" "mailq" "%c" "help", pmGetConfig("PCP_PMDAS_DIR"), sep, sep); pmdaDaemon(&dispatch, PMDA_INTERFACE_2, pmProgname, MAILQ, "mailq.log", mypath); while ((c = pmdaGetOptions(argc, argv, &opts, &dispatch)) != EOF) { switch (c) { case 'b': if (mailq_histogram(opts.optarg) < 0) opts.errors++; break; case 'r': regexstring = opts.optarg; c = regcomp(&mq_regex, regexstring, REG_EXTENDED | REG_NOSUB); if (c != 0) { regerror(c, &mq_regex, mypath, sizeof(mypath)); pmprintf("%s: cannot compile regular expression: %s\n", pmProgname, mypath); opts.errors++; } break; } } if (opts.optind == argc - 1) queuedir = argv[opts.optind]; else if (opts.optind != argc) opts.errors++; if (opts.errors) { pmdaUsageMessage(&opts); exit(1); } if (opts.username) username = opts.username; if (histo == NULL) { /* default histo bins, if not already done above ... */ numhisto = 7; histo = (histo_t *)malloc(numhisto * sizeof(histo[0])); if (histo == NULL) { __pmNoMem("histo", numhisto * sizeof(histo[0]), PM_FATAL_ERR); } histo[0].delay = 7 * 24 * 3600; histo[1].delay = 3 * 24 * 3600; histo[2].delay = 24 * 3600; histo[3].delay = 8 * 3600; histo[4].delay = 4 * 3600; histo[5].delay = 1 * 3600; histo[6].delay = 0; } else { /* need to add last one and sort on descending time */ numhisto++; histo = (histo_t *)realloc(histo, numhisto * sizeof(histo[0])); if (histo == NULL) { __pmNoMem("histo", numhisto * sizeof(histo[0]), PM_FATAL_ERR); } histo[numhisto-1].delay = 0; qsort(histo, numhisto, sizeof(histo[0]), compare_delay); } _delay = (pmdaInstid *)malloc(numhisto * sizeof(_delay[0])); if (_delay == NULL) __pmNoMem("_delay", numhisto * sizeof(_delay[0]), PM_FATAL_ERR); for (i = 0; i < numhisto; i++) { time_t tmp; _delay[i].i_inst = histo[i].delay; histo[i].count = 0; if (histo[i].delay == 0) sprintf(namebuf, "recent"); else if (histo[i].delay < 60) sprintf(namebuf, "%d-secs", (int)histo[i].delay); else if (histo[i].delay < 60 * 60) { tmp = histo[i].delay / 60; if (tmp <= 1) sprintf(namebuf, "1-min"); else sprintf(namebuf, "%d-mins", (int)tmp); } else if (histo[i].delay < 24 * 60 * 60) { tmp = histo[i].delay / (60 * 60); if (tmp <= 1) sprintf(namebuf, "1-hour"); else sprintf(namebuf, "%d-hours", (int)tmp); } else { tmp = histo[i].delay / (24 * 60 * 60); if (tmp <= 1) sprintf(namebuf, "1-day"); else sprintf(namebuf, "%d-days", (int)tmp); } _delay[i].i_name = strdup(namebuf); if (_delay[i].i_name == NULL) { __pmNoMem("_delay[i].i_name", strlen(namebuf), PM_FATAL_ERR); } } indomtab[DELAY_INDOM].it_numinst = numhisto; indomtab[DELAY_INDOM].it_set = _delay; pmdaOpenLog(&dispatch); mailq_init(&dispatch); pmdaConnect(&dispatch); pmdaMain(&dispatch); exit(0); }
// Check if the requested asymmetrics file has changed and reload it if needed static void checkAsymmetricFile(AsymmetricClients *aptr) { char buf[512], errbuf[256], *which; regex_t *re, **regs; int i, size, code; Bool firstTime = False; struct stat statbuf; FILE *file; str line; if (stat(aptr->file, &statbuf) < 0) return; // ignore missing file if (statbuf.st_mtime <= aptr->timestamp) return; // not changed which = (aptr == &sipAsymmetrics ? "SIP" : "RTP"); if (!aptr->clients) { // if we are here the first time allocate memory to hold the regexps // initial size of array // (hopefully not reached so we won't need to realloc) size = 32; aptr->clients = (regex_t**)pkg_malloc(size*sizeof(regex_t**)); if (!aptr->clients) { LM_WARN("cannot allocate memory for the %s asymmetric client list." " %s asymmetric clients will not be handled properly.\n", which, which); return; // ignore as it is not fatal } aptr->size = size; aptr->count = 0; firstTime = True; } else { // else clean old stuff for (i=0; i<aptr->count; i++) { regfree(aptr->clients[i]); pkg_free(aptr->clients[i]); aptr->clients[i] = NULL; } aptr->count = 0; } // read new file = fopen(aptr->file, "r"); i = 0; // this will count on which line are we in the file while (!feof(file)) { if (!fgets(buf, 512, file)) break; i++; line.s = buf; line.len = strlen(buf); trim(&line); if (line.len == 0 || line.s[0] == '#') continue; // comment or empty line. ignore line.s[line.len] = 0; re = (regex_t*)pkg_malloc(sizeof(regex_t)); if (!re) { LM_WARN("cannot allocate memory for all the %s asymmetric " "clients listed in file. Some of them will not be " "handled properly.\n", which); break; } code = regcomp(re, line.s, REG_EXTENDED|REG_ICASE|REG_NOSUB); if (code == 0) { if (aptr->count+1 > aptr->size) { size = aptr->size * 2; regs = aptr->clients; regs = (regex_t**)pkg_realloc(regs, size*sizeof(regex_t**)); if (!regs) { LM_WARN("cannot allocate memory for all the %s asymmetric " "clients listed in file. Some of them will not be " "handled properly.\n", which); break; } aptr->clients = regs; aptr->size = size; } aptr->clients[aptr->count] = re; aptr->count++; } else { regerror(code, re, errbuf, 256); LM_WARN("cannot compile line %d of the %s asymmetric clients file " "into a regular expression (will be ignored): %s", i, which, errbuf); pkg_free(re); } } aptr->timestamp = statbuf.st_mtime; LM_INFO("%sloaded %s asymmetric clients file containing %d entr%s.\n", firstTime ? "" : "re", which, aptr->count, aptr->count==1 ? "y" : "ies"); }