char *parsestr1( char *d, char *c) //try identic strings!, "xxx*NULL" combination { char *tmp, *tmp2, ch; unsigned int i; while (*c) { if(*c == '/' ){ c++; switch (*c){ case '*':/* printf("d1:%s\n", d);*/ c++; while(1){tmp = parsestr1(d, c); if (tmp) return tmp; if(! *d) break; d++;} return NULL;//depend on continues parsing //if * in b string -> some symbols between // !a*(b+c) = !(a+!(b+c))-> /!/Ba/\/!/Bb/\c/\/E/E case 'B': c++; tmp = NULL; tmp2 = c; i = 0; while(*tmp2){ if(*tmp2 == '/' && *(tmp2+1) == '/') tmp2++; //tmp2+=2 else if(*tmp2 == '/' && *(tmp2+1) == 'B' && i <= 1024) i++; //if(/B) else if(*tmp2 == '/' && *(tmp2+1) == 'E'){ //if(/E) -optional if(i == 0){tmp = tmp2; break;} else i--; } tmp2++; } //tmp - end of compare-string //tmp2 - can be used, while(1){ //not matched tmp2 = parsestr1(d, c); if(tmp2) break; while(1){ if(*c == '/' && *(c+1) == '/') c++; //c+=2 else if(*c == '/' && *(c+1) == '\\'){c = c + 2; break;} // if(/\) else if((tmp && (c == tmp)) || (*c == '\0')) return NULL; //end of compare-strings - no matches - return NULL c++; } } //printf("str:%s d=%s c=%s\n", tmp2,d,c); if(tmp) {d = tmp2; /*tmp2 is not always the end of string!! check it out*/ c = tmp + 2; continue;} else return tmp2; case '\\': case 'E': point[1] = d;//NEW 20.03.2016 return d; /* set number to /n10n */ case 'n': c++; tmp = c; while(*tmp && *tmp != 'n') tmp++; int digi = 0; i = 0; while(c[i] >= '0' && c[i] <= '9'){ digi = digi*10 + (c[i] - '0'); i++; if(i > 5) break;} number = digi; //set number to digi c = tmp; if(*tmp) c++; //if not end - increase c. continue; /* skip zero or one character*/ case '0': tmp = d; while(tmp <= d+1){tmp = parsestr1(tmp, c+1); if (tmp) return tmp; tmp++;} return NULL; /* skip one symbol in d, exept \0 */ case '|': c++; if(*d == '\0') return NULL; d++; continue; /* by /.x. skip x-symbol all at once */ case '.': if(*c != *(c+2) || *(c+1)=='\0') return NULL; //error! - or make it with continue c=c+1; while(*d == *c) d++; c=c+2; continue; /* by /,x, skip x-symbol 0 or 1-time */ case ',': if(*c != *(c+2) || *(c+1)=='\0') return NULL; //error! c=c+1; tmp = d; while((d <= tmp+1) && (*d == *c)) d++; c=c+2; continue; //used in *search[] /* by /lxl get last x-symbol in string 1 or more times */ case 'l': /* by /LxL get last x-symbol in string 0 or more times*/ case 'L': if(*c != *(c+2) || *(c+1)=='\0') return NULL; //error! i=0;c=c+1; tmp=d; while(*tmp){if(*tmp == *c){ d=tmp+1;i=1;} tmp++;} if(*(c+1)=='l'&&i==0)return NULL;c=c+2; continue; //used in serv-others_1.htm /* by /NxN x-symbol is not in string */ case 'N': if(*c != *(c+2) || *(c+1)=='\0') return NULL; //error! c=c+1; if(*c == *d) return NULL; c=c+2; d++; continue; //used in /* skip all blanks or tabs or enters in d */ // case ' ': tmp = d; while(*d == ' ' || *d == '\t' || *d == '\n' || *d == '\r') d++; if(tmp == d) return NULL; c++; continue; case ' ': while(*d == ' ' || *d == '\t' || *d == '\n' || *d == '\r') d++; c++; continue; /* /<xCHARS/> matches CHARS with d, continue if matches and return null if not */ case '<': c++; switch(*c){ case '-': // /<-CHARS/> matches chars 1 or more times case '*': // /<*CHARS/> matches chars zero or more times c++; tmp = c; i=0; while((*c != '/'|| c[1] != '>') && *c){ if(*c == '\\'){ c++; switch(*c){ case '\\': ch = '\\';break; case 't': ch = '\t';break; case 'n': ch = '\n';break; case '\"': ch = '\"';break; default: c--; ch = *c; break; } } else ch = *c; if(ch==*d){ do{d++;}while(ch==*d); c = tmp; i=1; continue; } c++;} if(*(tmp-1)=='-' && i==0) return NULL; if(*c == '/') c=c+2; continue; case '0': // /<0CHARS/> matches chars zero or 1 time case '1': // /<1CHARS/> matches chars one time case 'N': // /<NCHARS/> all chars not matches one time i = 0;tmp = c; c++; while((*c != '/'|| c[1] != '>') && *c){ if(*c == '\\'){ c++; switch(*c){ case '\\': ch = '\\';break; case 't': ch = '\t';break; case 'n': ch = '\n';break; case '\"': ch = '\"';break; case '0': ch = '\0';break;//check if *d == '\0'. //In /* is set until zero, inclusive zero! default: c--; ch = *c; break; } } else ch = *c; if(ch == *d) i = 1; c++;} if(*(tmp)=='1' && i==0) return NULL; if(*(tmp)=='N' && i==1) return NULL; if(*c == '/') c=c+2; if(*d != '\0' && (*(tmp)=='1' || *(tmp)=='N' || (*(tmp)=='0' && i==1))) d++; continue; default: case '\0': c--; continue; // rest='<\0' } case '[': if(parsestr1(d, c+1)){ /*point[0] = d;*/ return d;} return NULL; //if [ in b so this pointer will be returned, and c is move forward. BEGINNofSTR case ']':/* printf("d:%s\n", d);*/ tmp = parsestr1(d, c+1); if(!tmp) return NULL; //case tmp=d (*(c+1) = '/0')[ end braces in end of string] if(tmp == d && *tmp){ tmp++; point[1] = tmp;} /*if(*d) point[0] = d+1; else */ point[0] = d; // point[0] points on character to be zeroed ch_zero = *d; *d = '\0'; return tmp;//depend on continues(if /[ goes after /] - begin) // make end of string hier!, check rest as (]...) and return next to end char. /* second '/' charakter is to match */ case '/': break; // case '\0': continue;//need to check it!!!!!! /* end of string is to match */ case '\0': if(*d != '\0') return NULL; return d; case '!': //Negotiation NEW // \!\*ab -no more "ab" in rest of string tmp = parsestr1(d, c+1); if(tmp) return NULL; else { point[1] = d; return d;} case '?': // /?variable?/ - nicht eingebetet(simple) case 'Q': // /Qvar?/ - eingebetet ch = *c; //in ch: Q or ? c++; char *m; tmp = c; tmp2 = NULL; while(*tmp){ if(*tmp == '?' && *(tmp+1) == '/'){ i = tmp - c; if((i > 1) && (i < 33)){ m = malloc(i); if(m){ strmycpy(m, c, i); tmp2 = get_var(NULL, m); //get_var and get_variable free(m); } } c=tmp+2; break; } tmp++; } if(tmp2 && *tmp2){ if(ch == '?'){ i = strlen(tmp2); if(i && strncmp(d, tmp2, i)) return NULL; d = d + i; }else{ static int time = 0; time++; if(time < 10){ unsigned long long size = strncpy_(NULL, tmp2, 0)+1; //this is max. size of tmp2-string if(size > 1 && (m = malloc(size))){ strncpy_(m, tmp2, size); tmp = parsestr1(d, m); free(m); if(!tmp){time--; return NULL;} d = tmp; //if(*d != '\0') d++; //???????? } }else printf("parsestr: max. counter\n"); time--; } } else return NULL; continue; //it's or c++ or c=tmp+2 case '-': if(*(c+1) == '-') { d=d-1; c=c+2;} // /-- -means d-1 continue; default: c--; } } else if(*c == '\\'){ c++; switch(*c){ /* new string is to match */ case 'n': if(*d != '\n') return NULL; c++; d++; continue; case 't': if(*d != '\t') return NULL; c++; d++; continue; case 'r': if(*d != '\r') return NULL; c++; d++; continue; /* \" string is to match */ case '\"': if(*d != '\"') return NULL; c++; d++; continue; //need to change it /* \0 the same as "bla/"; if after is "bla\02" -> "bla\0" + number=2 */ case '0': if(*d != '\0') return NULL; c++; int digi = 0; i = 0; while(c[i] >= '0' && c[i] <= '9'){ digi = digi*10 + (c[i] - '0'); i++; if(i > 5) break;} if(i) number = digi; //set number to digi return d; case '\\': break; default: c--; } } // if (tolower(*c) != tolower(*d)) break; if (*c != *d) return NULL; if (!(*d)) {printf("PARSESTR1<<<<<<</n");break;} //not happens *d=*c=='\0' c++; d++; } point[1] = d; return (char *) d;//ENDofSTR }
inline void include_(char *line, char *var_head, FILE *out) //SSI made total brutal, no checks of file path, and include must be along in string of file! { char *var_head2; struct parsestr strct; do{ if ((var_head2 = parsestr2(&strct, var_head,"par=\"/[/*/]\"/ "))!=NULL){ //<!--#include par="size:web_name:name:pattern" --> /*collect parameters in a array*/ char *a, *ptr; int i = 0, str_size, val_size; struct cfg_parse1 *cfg_pointer; *cfg_p = (struct cfg_parse1 *)malloc(sizeof(struct cfg_parse1)); cfg_pointer = *cfg_p; if(cfg_pointer == NULL) continue; ptr = var_head2; while(i < 3){ a = w_strtok(&ptr, ':'); if(a) switch(i){ case 0: val_size = atoi(a); if(!val_size || val_size > 300) return; //size is in impassable range - so skip it all (whole parameter string will be skipped!) a = ptr; str_size = strlen(a)+1; ptr = (char*)malloc(str_size + 2*val_size);//str = "[part of var_head2][value][new_value]" if(ptr == NULL){ i = 5; continue; } strcpy(ptr, a); cfg_pointer->type = CFG_PAR; cfg_pointer->str = ptr; cfg_pointer->size = val_size; cfg_pointer->changed = 0; cfg_pointer->saved = 0; cfg_pointer->value = ptr + str_size; // *(cfg_pointer->value) = '\0'; cfg_pointer->new_value = ptr + str_size + val_size; // *(cfg_pointer->new_value) = '\0'; memset(cfg_pointer->value, 0, 2*val_size);//fill with zeros cfg_pointer->name = NULL; cfg_pointer->pattern = NULL; cfg_pointer->web_name = NULL; cfg_pointer->next = NULL; break; case 1: cfg_pointer->web_name = a; break; case 2: cfg_pointer->name = a; cfg_pointer->pattern = ptr; break; } else { printf("par=\"\" not full, broken by %d\n", i+1); break; } i++; } if(i != 5){ printf("Collected parameter: %s:%s:%lld:%s\n", cfg_pointer->web_name, cfg_pointer->name, cfg_pointer->size, cfg_pointer->pattern); cfg_p = &(cfg_pointer->next); }else{ printf("ERROR allocate memory\n"); if(cfg_p && *cfg_p){ free(*cfg_p); *cfg_p = NULL; //main criteria to abort moving in array. } } } else if ((var_head2 = parsestr2(&strct, var_head,"readcfg/ "))!=NULL){ //<!--#include readcfg --> /*start to fill parameters from config to collected array*/ ReadConfiguration(); } else if ((var_head2 = parsestr2(&strct, var_head,"area=\"/[/*/]\"/ "))!=NULL){ //<!--#include area="size:web_name" --> /*collect parameters in a array*/ char *a, *ptr; int i = 0, str_size; long long val_size; struct cfg_parse1 *cfg_pointer; *cfg_p = (struct cfg_parse1 *)malloc(sizeof(struct cfg_parse1)); cfg_pointer = *cfg_p; if(cfg_pointer == NULL) continue; ptr = var_head2; while(i < 2){ a = w_strtok(&ptr, ':'); if(a) switch(i){ case 0: val_size = atoll(a); if(val_size > 32 *1024) return; //size is in impassable range - so skip it all (whole parameter string will be skipped!) a = ptr; str_size = strlen(a)+1; ptr = (char*)malloc(str_size + val_size);//str = "[part of var_head2][value]" if(ptr == NULL){ i = 5; continue; } strcpy(ptr, a); cfg_pointer->type = (val_size != 0) ? CFG_AREA : CFG_TMP; cfg_pointer->str = ptr; cfg_pointer->size = val_size; cfg_pointer->changed = 0; cfg_pointer->saved = 0; if(val_size != 0){//AREA="size:name" cfg_pointer->value = ptr + str_size; cfg_pointer->new_value = ptr + str_size; memset(cfg_pointer->value, 0, val_size);//fill memory with 0 }else{//AREA="0:temp_name" cfg_pointer->value = NULL; cfg_pointer->new_value = NULL; } cfg_pointer->name = NULL; //ptr + str_size - 1; cfg_pointer->pattern = NULL; //ptr + str_size - 1; cfg_pointer->web_name = NULL; cfg_pointer->next = NULL; break; case 1: cfg_pointer->web_name = a; break; } else { printf("area=\"\" not full, broken by %d\n", i+1); break; } i++; } if(i != 5){ printf("Collected parameter: [%s:%lld]\n", cfg_pointer->web_name, cfg_pointer->size); cfg_p = &(cfg_pointer->next); }else{ printf("ERROR allocate memory\n"); if(cfg_p && *cfg_p){ free(*cfg_p); *cfg_p = NULL; //main criteria to abort moving in array. } } } else //printf("include file: %s\n", var_head); if ((var_head2 = parsestr2(&strct, var_head,"file=\"/[/*/N\\N/]\"/ "))!=NULL){ //<!--#include file="..\".." --> //printf("include file: %s\n", var_head2); copy_file_include(var_head2, out); } else if ((var_head2 = parsestr2(&strct, var_head,"exec=\"/[/*/]\"/ "))!=NULL){ //<!--#include exec="..." --> my_system(out, var_head2); } else if ((var_head2 = parsestr2(&strct, var_head,"shell=\"\"/[/*/]\"\"/ "))!=NULL){ //<!--#include shell=""..."" --> my_shell(out, var_head2); } else if ((var_head2 = parsestr2(&strct, var_head,"cgi=\"/[/*/]\"/ "))!=NULL){ //<!--#include cgi="..." --> if(DoCGI(out, var_head2)) fprintf(out, "Not Found: %s\n", var_head2);// what about arg?? else free_par_tmp();//clear all "temp"-parameters } else if((var_head2 = parsestr2(&strct, var_head, "tbl_select=\"/[/*/]\"/ "))!=NULL){ show_tbl(var_head2, out); } else if((var_head2 = parsestr2(&strct, var_head, "tbl_check=\"/[/*/]\"/ "))!=NULL){ show_tbl_chck(var_head2, out); } else if((var_head2 = parsestr2(&strct, var_head, "chtbl_stat=\"/[/*/]\"/ "))!=NULL){ change_tbl_stat(var_head2); } else if((var_head2 = parsestr2(&strct, var_head, "InIt/ "))!=NULL){ //<!--#include InIt --> ReadConfiguration(); } else if((var_head2 = parsestr2(&strct, var_head, "write_par=\"/[/*/N\\N/]\"/ "))!=NULL){ //<!--#include write_par="par:value" --> // write_par par:value this is used in copy_CGI.c - the same code! char *tmp, *tmp2; long long size; tmp2 = w_strtok(&var_head2, ':'); if(tmp2 && *tmp2 && *var_head2){ tmp = get_var(&size, tmp2); if(tmp && size){ strncpy_(tmp, var_head2, size-1); // tmp[size-1] = '\0'; } // if(tmp2 != var_head2) *(var_head2-1) = ':'; } }//need some end hier (else) }while(var_head2 && (var_head = strct.end)); //end of parsing string }
static void ImgDirs( char* dirs, // out const char* shapepath, // in: shape file path FILE* file) // in { char s[SLEN]; Fgets(s, SLEN-1, file); // will skip blank lines and comments, if any static const char* const whitespace = " \t\n\r"; char* token = strtok(s, whitespace); if (!token || 0 != strcmp(token, "Directories")) Err("Expected \"Directories\" in line %d of %s", LineNbr(file), shapepath); token = strtok(NULL, whitespace); if (!token) Err("Cannot read image directories in line %d of %s", LineNbr(file), shapepath); strncpy_(dirs, token, SLEN); ConvertBackslashesToForwardAndStripFinalSlash(dirs); }