/*
* strregrep - a regex based text replacing function for general purpose use
*
* Copyright (C) 2003 A.L.Lambert
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
/* our error handler */
void ipregex_resolv_err(short int status, short int func) {
/* opps - couldn't even compile the regex - return error and optionally whine about it */
char buffer[LSIZE]; /* where we place the error message */
/* if we ain't in debug mode, why are we here?!?!?! */
if(! cf.debug) return;
/* go get us an error message */
regerror(status, NULL, buffer, LSIZE);
/* depending on what function created error (passed by calling prog), prefix error with text */
if(func == 0) fprintf(stderr, "regex failure: ");
if(func == 1) fprintf(stderr, "regcomp error: ");
if(func == 2) fprintf(stderr, "regexec error: ");
/* print out our error message */
fprintf(stderr, "%s\n", buffer);
return;
}
/* the main show */
int ipregex_resolv(char *string, long int stlen, short int recur) {
long int i, j; /* used for counters in loops */
long int tmp_len; /* temporairy string length storage */
regex_t reg; /* compiled regex variable */
regmatch_t pmatch[1]; /* how many matches we got? */
short int status; /* return value of reg*(); */
char *ptr; /* a pointer for parsing */
char *tmp_string; /* a temp string storage space for parsing */
char ip_regex[1024]; /* where we store the text for an IP search regex */
char ip_addr[1024]; /* where we put the IP address as a string temporairly */
strcpy(ip_regex, " ([0-9]|[0-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\\.([0-9]|[0-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\\.([0-9]|[0-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\\.([0-9]|[0-9][0-9]|1[0-9][0-9]|2[0-5][0-5]) ");
/* if we've been overly-recursive, get out of here without doing anything */
if(recur == -1) return(-1);
/* if we're in debug mode, tell the user the details of how we were called */
if(cf.debug) fprintf(stderr, "ipregex_resolv(%s, %li, %i);\n", string, stlen, recur);
/* make sure we can compile the patern - and if not return error */
status = regcomp(®, ip_regex, REG_EXTENDED);
if(status != 0) { ipregex_resolv_err(status, 1); return ERR; }
/* malloc some space for our tmp_string */
tmp_string = malloc(stlen);
if(tmp_string == NULL) {
perror("malloc");
return ERR;
}
/* see if we have a match in the unprocessed part of string */
status = regexec(®, string, (size_t) 1, pmatch, 0);
if(status == REG_NOMATCH) {
if(tmp_string != NULL) free(tmp_string);
return 0; /* we didn't match anything, return normally */
}
if(status != 0) {
ipregex_resolv_err(status, 2);
if(tmp_string != NULL) free(tmp_string);
return ERR;
} /* we mucked up, return error */
/* recurse now instaed of later so we end up processing the line in reverse for matches */
ptr = string;
ptr = (ptr + pmatch[0].rm_eo);
status = ipregex_resolv(ptr, (stlen - pmatch[0].rm_eo), (recur - 1));
if(status == ERR) {
if(tmp_string != NULL) free(tmp_string);
return ERR; /* if recursion returned error, back out of forest with error all the way */
}
/* copy off the first part of the string that doesn't match */
for(i = 0; i < pmatch[0].rm_so ; ++i, ++j) {
tmp_string[i] = string[i]; /* copy the character */
}
tmp_string[i] = '\0'; /* null terminate the tmp string */
ptr = string;
ptr = (ptr + pmatch[0].rm_so);
sscanf(ptr, "%s", ip_addr);
/* some quick sanity to make sure we're not about to overflow our tmp_string variable */
tmp_len = (strlen(tmp_string) + strlen(tmp_string));
if(tmp_len < stlen) { /* if the new length is shorter than possible length, then */
strcat(tmp_string, " blahblah("); /* add the 'new_text' text to buffer */
strcat(tmp_string, ip_addr); /* add the 'new_text' text to buffer */
strcat(tmp_string, ") ");
} else { /* new length is longer than possible length - we got a problem - error out */
if(cf.debug) fprintf(stderr, "result (%li) too large for size of char *string (%li)\n", tmp_len, stlen);
if(tmp_string != NULL) free(tmp_string);
return ERR;
}
/* finish off adding the rest of the string to tmp_string */
for(i = 0, j = strlen(tmp_string); string[i + pmatch[0].rm_eo] != '\0'; ++i, ++j) {
if(j > stlen) {
if(cf.debug) fprintf(stderr, "result too large for size of char *string[%li]\n", stlen);
tmp_string[j] = '\0';
break; /* just break out of here - we don't have to exit for this one - leave what's done done */
}
tmp_string[j] = string[i + pmatch[0].rm_eo];
}
tmp_string[j] = '\0'; /* null terminate always always always */
/* put the tmp_string onto the end of string */
strcpy(string, tmp_string);
/* free our variables */
if(tmp_string != NULL) free(tmp_string);
regfree(®);
return 0; /* outta here */
}
syntax highlighted by Code2HTML, v. 0.9.1