diff options
Diffstat (limited to 'src/filter-env/posix.c')
-rw-r--r-- | src/filter-env/posix.c | 547 |
1 files changed, 0 insertions, 547 deletions
diff --git a/src/filter-env/posix.c b/src/filter-env/posix.c deleted file mode 100644 index 2ca2aba..0000000 --- a/src/filter-env/posix.c +++ /dev/null @@ -1,547 +0,0 @@ -#include <sys/types.h> -#include <sys/stat.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <getopt.h> -#include <regex.h> -#include <unistd.h> -#include <ctype.h> -#include <assert.h> -#include "bmh_search.h" - -#define USAGE_FAIL 1 -#define MEM_FAIL 2 -#define IO_FAIL 3 -#define PARSE_FAIL 4 - -#define SPACE_PARSING 4 -#define ESCAPED_PARSING 3 -#define COMMAND_PARSING 2 -#define DOLLARED_QUOTE_PARSING 1 -#define NO_PARSING 0 - -void init_regexes(); -void free_regexes(); -int regex_matches(regex_t *re, const char *buff); -const char *process_scope(FILE *out_fd, const char *buff, const char *end, regex_t *var_re, regex_t *func_re, char endchar); -int append_to_filter_list(char ***list, int *count, int *alloced, const char *string); -const char *build_regex_string(const char **list, int count); -const char *walk_command(const char *p, const char *end, char endchar, const char interpret_level); - - -#define d1printf(expr...) dprintf(1,expr) -#define d2printf(expr...) dprintf(2,expr) -#define dprintf(level,expr...) \ - if(debugging>=level) \ - fprintf(stderr,expr); - -static int debugging; - -int -main(int argc, char *const *argv) -{ - FILE *file_in = NULL; - FILE *file_out = NULL; - char **funcs = NULL; char **vars = NULL; - char *file_buff=NULL; - const char *end = NULL; - int funcs_count = 0; int vars_count = 0; - int funcs_alloced = 0; int vars_alloced = 0; - int c; - size_t file_size=0, buff_alloced = 0; - regex_t vre, *pvre=NULL; - regex_t fre, *pfre=NULL; - const char *fsr, *vsr; - char *temp = NULL; - struct stat st; - debugging = 0; - funcs = (char **)malloc(sizeof(char *)*10); - vars = (char **)malloc(sizeof(char *)*10); - if(funcs == NULL || vars == NULL) { - fprintf(stderr,"failure allocing needed memory\n"); - exit(MEM_FAIL); - } - while((c = getopt(argc, argv, "i:f:v:d")) != EOF) { -// fprintf(stderr,"c=%i\n",c); - switch(c){ - case 'd': - debugging++; - break; - case 'i': - if(file_in != NULL) { - fprintf(stderr,"-i cannot be specified twice. bailing\n"); - exit(USAGE_FAIL); - } - if(stat(optarg, &st)){ - fprintf(stderr,"error stating file %s, bailing\n", optarg); - exit(IO_FAIL); - } - file_size=st.st_size; - file_in=fopen(optarg, "r"); - if(file_in == NULL) { - fprintf(stderr,"error opening file %s, bailing\n", optarg); - exit(IO_FAIL); - } - break; - case 'f': -// fprintf(stderr,"wassube. opt_art=%s\n",optarg); - if(append_to_filter_list(&funcs, &funcs_count, &funcs_alloced,optarg)) { - fprintf(stderr,"-f arg '%s', isn't valid. must be comma delimited\n", - optarg); - exit(USAGE_FAIL); - } - break; - case 'v': - if(append_to_filter_list(&vars, &vars_count, &vars_alloced,optarg)) { - fprintf(stderr,"-v arg '%s', isn't valid. must be comma delimited\n", optarg); - exit(USAGE_FAIL); - } - break; - default: - fprintf(stderr,"Usage [-i file] [-f func1,func2,func3 ] [-v func1,func2,func3 ]\n"); - exit(USAGE_FAIL); - } - } - if(file_size==0) { - file_in = stdin; - } else { - fclose(stdin); - } - file_out = stdout; - - fsr = build_regex_string((const char **)funcs, funcs_count); - d1printf("fsr buffer=%s\n", fsr); - vsr = build_regex_string((const char **)vars, vars_count); - d1printf("vsr buffer=%s\n", vsr); - if(fsr) { - // prefix ^ - if((temp = (char *)malloc(strlen(fsr) + 3)) == NULL) { - fprintf(stderr, "failed allocing needed memory for regex patterns.\n"); - exit(MEM_FAIL); - } - temp[0]='^'; temp[1] = '\0'; - temp = strcat(temp,fsr); - temp = strcat(temp,"$"); - d1printf("fsr pattern is %s\n", temp); - regcomp(&fre, temp, REG_EXTENDED); - free(temp); temp = NULL; - pfre=&fre; - free((void*)fsr); fsr = NULL; - } else - pfre=NULL; - if(vsr) { - if((temp = (char *)malloc(strlen(vsr) + 3)) == NULL) { - fprintf(stderr, "failed allocing needed memory for regex patterns.\n"); - exit(MEM_FAIL); - } - temp[0]='^'; temp[1] = '\0'; - temp = strcat(temp,vsr); - temp = strcat(temp,"$"); - d1printf("vsr pattern is %s\n", temp); - regcomp(&vre, temp, REG_EXTENDED); - free(temp); temp = NULL; - pvre=&vre; - free((void*)vsr); vsr = NULL; - } else - pvre=NULL; - - - if(file_size) { - file_buff = (char *)malloc(file_size + 1); - if(file_buff == NULL) { - fprintf(stderr, "failed allocing needed memory for file.\n"); - exit(MEM_FAIL); - } - if(file_size != fread(file_buff, 1, file_size, file_in)) { - fprintf(stderr, "failed reading file\n"); - exit(IO_FAIL); - } - } else { - if((file_buff = (char *)malloc(4096)) == NULL) { - fprintf(stderr, "failed allocing needed memory for file.\n"); - exit(MEM_FAIL); - } - buff_alloced = 4096; - c=4096; - while(c > 0) { - c=fread(file_buff+file_size, 1, 4096, file_in); - file_size += c; - // realloc +1 for null termination. - if(buff_alloced < file_size + 4096) { - if((file_buff = (char *)realloc(file_buff, buff_alloced + 4096)) == NULL) { - fprintf(stderr, "failed allocing needed memory for file.\n"); - exit(MEM_FAIL); - } - buff_alloced += 4096; - } - } - d1printf("read %i bytes\n", file_size); - } - file_buff[file_size] = '\0'; - fclose(file_in); - - init_regexes(); - end=process_scope(file_out,file_buff, file_buff + file_size,pvre, pfre, '\0'); - d1printf("%i == %i\n", end - file_buff, file_size); - - fflush(file_out); - fclose(file_out); - free_regexes(); - free((void*)fsr); free((void*)vsr); - free(file_buff); - exit(0); -} - -int -append_to_filter_list(char ***list, int *count, int *alloced, const char *string) -{ - char *d = NULL; - char **l = *list; - char *s = NULL; - s = strdup(string); - d = strtok(s, ","); - if(d == NULL) - return 1; - while(d != NULL) { - if(*alloced == *count) { - if( (l=(char **)realloc(l, sizeof(char*) * (*alloced + 10))) == NULL) { - return 1; - } - *alloced+=10; - } - l[*count] = d; - (*count)++; - d=strtok(NULL,","); - } - *list=l; - return 0; -} - -const char * -build_regex_string(const char **list, int count) -{ - char *buff, *p; - const char *p2; - int l = 0, x = 0, escaped = 0; - - for(x=0; x< count; x++) { - l += strlen(list[x]) + 1; - p2=list[x]; - // if it's ., substitute a [^ =] internally. - while(*p2!='\0'){ - if(*p2=='.') - l+=4; - p2++; - } - } - if(l == 0) - return NULL; - //shave off the extra '|' char, add in '(...)'. hence, 3. - buff = malloc(l + 5); - memset(buff,0,l+4); - buff[0] = '('; - p=buff + 1; - for(x=0; x < count; x++) { - p2=list[x]; - escaped=0; - while(*p2 != '\0') { - if(*p2=='.' && escaped==0) { - strcat(p,"[^= ]"); - p += 4; - } else if(*p2 == '\\') { - *p = *p2; - p2++; p++; - if(escaped == 1) - escaped=0; - else - escaped=1; - continue; - } else { - *p = *p2; - } - p++; - p2++; - escaped=0; - } - *p = '|'; - p++; - } - p[-1] = ')'; - p[0] = '\0'; - return buff; -} - -regex_t func_r; -regex_t var_r; - -void -init_regexes() -{ - regcomp(&func_r,"^(function[[:space:]]+|)([^\"'()=[:space:]]+)[[:space:]]*\\(\\)[[:space:]]*\\{",REG_EXTENDED); - regcomp(&var_r,"^([^=[:space:]$(]+)=",REG_EXTENDED); -} -void -free_regexes() -{ - regfree(&func_r); - regfree(&var_r); -} - -/* -fprintf(stderr,"REG_BADRPT:%i\nREG_BADBR:%i\nREG_EBRACE:%i\nREG_EBRACK:%i\nREG_ERANGE:%i\nREG_ECTYPE:%i\nREG_EPAREN:%i\nREG_ESUBREG:%i\nREG_EEND:%i\nREG_EESCAPE:%i\nREG_BADPAT:%i\nREG_ESIZE:%i\nREG_ESPACE:%i\n", -REG_BADRPT,REG_BADBR,REG_EBRACE,REG_EBRACK,REG_ERANGE,REG_ECTYPE,REG_EPAREN,REG_ESUBREG,REG_EEND,REG_EESCAPE, -REG_BADPAT,REG_ESIZE,REG_ESPACE); -*/ - -// zero for doesn't match, !0 for matches. -int -regex_matches(regex_t *re, const char *buff) -{ - regmatch_t match[1]; - match[0].rm_so = match[0].rm_eo = -1; - assert(buff != NULL); - assert(re != NULL); - regexec(re, buff, 1, match, 0); -// fprintf(stderr,"result was %i for %s, returning %i\n", match[0].rm_so, buff,i); - return match[0].rm_so != -1 ? 1 : 0; -} - -const char * -process_scope(FILE *out_fd, const char *buff, const char *end, regex_t *var_re, regex_t *func_re, char endchar) -{ - const char *p = NULL; - const char *window_start = NULL, *window_end = NULL; - const char *new_p = NULL; - const char *com_start = NULL; - const char *s = NULL, *e = NULL; - char *temp_string = NULL; - int x; - - regmatch_t matches[3]; - p=buff; - for(x=0; x < 3; x++) - matches[x].rm_so = -1; - - window_start = buff; - window_end = NULL; - while(p < end && *p != endchar) { - // wander forward to the next non space. - if(window_end != NULL) { - if(out_fd != NULL) - fwrite(window_start, window_end - window_start, 1, out_fd); - window_start = p; - window_end = NULL; - } - com_start = p; - if(isspace(*p)) { - p++; continue; - } - // ignore comments - if(*p == '#') { - while(p < end && *p != '\n') { - p++; - } -// window_end = p; - continue; - } - // actual text. - regexec(&func_r, p, 3, matches, 0); - if(matches[0].rm_so != -1){ - //got us a func match. - if(matches[2].rm_so != -1) { - s = p + matches[2].rm_so; e = p + matches[2].rm_eo; - } else { - s = p; e = p + matches[1].rm_eo; - } - temp_string = (char*)malloc(e - s + 1); - memset(temp_string,0,e - s + 1); - memcpy(temp_string,s, e - s); - d1printf("matched func name '%s'\n", temp_string); - //output it if it doesn't match. - - new_p=process_scope(NULL,p + matches[0].rm_eo, end, NULL, NULL, '}'); - d1printf("ended processing '%s'\n", temp_string); - if(func_re!=NULL && regex_matches(func_re, temp_string)) { - //well, it matched. so it gets skipped. - d1printf("filtering func '%s'\n", temp_string); - window_end = com_start; - } - - p = new_p; -// p += matches[0].rm_eo; - free(temp_string); - temp_string = NULL; - for(x=0; x < 3; x++) - matches[x].rm_so = -1; - - } else { - // check for env assignment - regexec(&var_r, p, 2, matches, 0); - if(matches[0].rm_so == -1) { - //exactly as it sounds, non env assignment. - p=walk_command(p,end,'\0',COMMAND_PARSING); - } else { - //env assignment - temp_string=(char*)malloc(matches[1].rm_eo + 1); - memset(temp_string,0,matches[1].rm_eo + 1); - memcpy(temp_string,p, matches[1].rm_eo); - d1printf("matched env assign '%s'\n", temp_string); - p += matches[0].rm_eo; - for(x=0; x < 3; x++) - matches[x].rm_so = -1; - - if(p >= end) - return p; - if('\''==*p) - p=walk_command(p + 1,end,*p,NO_PARSING); - else if('"' == *p || '`' == *p) - p=walk_command(p + 1,end,*p,ESCAPED_PARSING); - else if('(' == *p) - p=walk_command(p + 1,end,')',ESCAPED_PARSING); - else if(isspace(*p)) { - while(p < end && isspace(*p) && *p != '\n') - p++; - } else if('$' == *p) { - if(p + 1 >= end) { - p++; - continue; - } - if('(' == p[1]) { - p=walk_command(p + 2,end, ')',ESCAPED_PARSING); - } else if('\'' == p[1]) { - p=walk_command(p + 2,end, '\'', DOLLARED_QUOTE_PARSING); - } else if('{' == p[1]) { - p=walk_command(p + 2,end, '}', ESCAPED_PARSING); - } else { - x=0; - while(p < end && (!isspace(*p) || x)) { - if('\\' == *p) - x=1; - else - x=0; - p++; - } - } - p++; - } else { - // blah=cah ; single word. - p=walk_command(p + 1,end, ' ',SPACE_PARSING); - } - if(var_re!=NULL && regex_matches(var_re, temp_string)) { - //this would be filtered. - window_end = com_start; - } - free(temp_string); - temp_string=NULL; - } - } - p++; -// fprintf(stderr,"at byte %i of %i\n", p - buff, strchr(buff,'\0') - buff); - } -// fprintf(stderr, "returning %x\n", p); - if(out_fd != NULL) { - if(window_end == NULL) - window_end = p; - if(window_end > end) - window_end = end; - fwrite(window_start, window_end - window_start, 1,out_fd); - } - return p; -} - -// interpret level == 0, no interprettation (no escaping), 1 == normal command limiting, 2 == wait strictly for -// endchar -const char * -walk_command(const char *p, const char *end, char endchar, const char interpret_level) -{ - int escaped = 0; - int dollared = 0; - int here_count = 0; - regex_t here_re; - char *here_pattern; - regmatch_t match[1]; - char *temp_string = NULL; - const char *end_here; - int x; - while(p < end) { - if(*p == endchar || - (interpret_level == COMMAND_PARSING && (';'==*p || '\n'==*p)) || - (interpret_level == SPACE_PARSING && isspace(*p))) { - if(!escaped) - return p; - } else if(NO_PARSING==interpret_level) { - p++; - continue; - } else if('\\' == *p && !escaped) { - escaped = 1; p++; continue; - } else if(escaped) { - escaped = 0; - } else if(DOLLARED_QUOTE_PARSING == interpret_level) { - p++; - continue; - } else if('<' == *p) { - here_count++; - if(2 == here_count && interpret_level == COMMAND_PARSING) { - p++; - if(p >= end) { - fprintf(stderr, "bailing\n"); - return p; - } - while(p < end && (isspace(*p) || '-' == *p)) - p++; - if('\'' == *p || '"' == *p) { - end_here = walk_command(p + 1,end,*p,NO_PARSING); - p++; - } else { - end_here = walk_command(p,end,' ',SPACE_PARSING); - } -// d1printf("end_here=%.5s\n",end_here); - d2printf("matched '%.*s' for a here word\n", end_here -p, p); - temp_string = malloc(end_here -p + 1); - memcpy(temp_string, p, end_here - p); - temp_string[end_here - p] = '\0'; - // XXX watch this. potential for horkage. need to do the quote removal thing. - //this sucks. - - end_here++; - if(end_here >= end) { - return end_here; - } - end_here = bmh_search(temp_string, end_here, end - end_here); - d1printf("bmh returned %i\n", end_here); - if(end_here) { - d2printf("bmh = %.10s\n", end_here); - p=end_here + strlen(temp_string) -1 ; - d2printf("continuing on at %.10s\n", p); - } else { - p = end; - } - free(temp_string); - here_count = 0; - } else { - d2printf("noticed '<', interpret_level=%i\n", interpret_level); - p++; continue; - } - } else if('$' == *p && !dollared && !escaped) { - dollared = 1; p++; continue; - } else if('{' == *p) { - //process_scope. this gets fun. -// fprintf(stderr,"process_scope called for %.10s\n", p - 10); -// p=process_scope(NULL,p+1,end,NULL,NULL,'}'); - p=walk_command(p+1,end, '}', ESCAPED_PARSING); - // kind of a hack. - } else if('(' == *p && interpret_level == COMMAND_PARSING) { - p=walk_command(p + 1, end, ')',ESCAPED_PARSING); - } else if('`' == *p || '"' == *p) { - p=walk_command(p + 1, end, *p, ESCAPED_PARSING); - } else if('\'' == *p && '"' != endchar) { - p=walk_command(p + 1, end, '\'', NO_PARSING); - } - p++; - escaped=0; - dollared=0; - } - return p; -} |