static int add_rule(rt_data_t *rdata, char *grplst, str *prefix, rt_info_t *rule) { long int t; char *tmp; char *ep; int n; tmp=grplst; n=0; /* parse the grplst */ while(tmp && (*tmp!=0)) { errno = 0; t = strtol(tmp, &ep, 10); if (ep == tmp) { LM_ERR("bad grp id '%c' (%d)[%s]\n", *ep, (int)(ep-grplst), grplst); goto error; } if ((!IS_SPACE(*ep)) && (*ep != SEP) && (*ep != SEP1) && (*ep!=0)) { LM_ERR("bad char %c (%d) [%s]\n", *ep, (int)(ep-grplst), grplst); goto error; } if (errno == ERANGE && (t== LONG_MAX || t== LONG_MIN)) { LM_ERR("out of bounds\n"); goto error; } n++; /* add rule -> has prefix? */ if (prefix->len) { /* add the routing rule */ if ( add_prefix(rdata->pt, prefix, rule, (unsigned int)t)!=0 ) { LM_ERR("failed to add prefix route\n"); goto error; } } else { if ( add_rt_info( &rdata->noprefix, rule, (unsigned int)t)!=0 ) { LM_ERR("failed to add prefixless route\n"); goto error; } } /* keep parsing */ if(IS_SPACE(*ep)) EAT_SPACE(ep); if(ep && (*ep == SEP || *ep == SEP1)) ep++; tmp = ep; } if(n==0) { LM_ERR("no id in grp list [%s]\n", grplst); goto error; } return 0; error: return -1; }
int getpart(char **outbuf, size_t *outlen, const char *main, const char *sub, FILE *stream) { # define MAX_TAG_LEN 79 char couter[MAX_TAG_LEN+1]; /* current outermost section */ char cmain[MAX_TAG_LEN+1]; /* current main section */ char csub[MAX_TAG_LEN+1]; /* current sub section */ char ptag[MAX_TAG_LEN+1]; /* potential tag */ char patt[MAX_TAG_LEN+1]; /* potential attributes */ char *buffer = NULL; char *ptr; char *end; union { ssize_t sig; size_t uns; } len; size_t bufsize = 0; size_t outalloc = 256; int in_wanted_part = 0; int base64 = 0; int error; enum { STATE_OUTSIDE = 0, STATE_OUTER = 1, STATE_INMAIN = 2, STATE_INSUB = 3, STATE_ILLEGAL = 4 } state = STATE_OUTSIDE; *outlen = 0; *outbuf = malloc(outalloc); if(!*outbuf) return GPE_OUT_OF_MEMORY; *(*outbuf) = '\0'; couter[0] = cmain[0] = csub[0] = ptag[0] = patt[0] = '\0'; while((error = readline(&buffer, &bufsize, stream)) == GPE_OK) { ptr = buffer; EAT_SPACE(ptr); if('<' != *ptr) { if(in_wanted_part) { show(("=> %s", buffer)); error = appenddata(outbuf, outlen, &outalloc, buffer, base64); if(error) break; } continue; } ptr++; if('/' == *ptr) { /* ** closing section tag */ ptr++; end = ptr; EAT_WORD(end); if((len.sig = end - ptr) > MAX_TAG_LEN) { error = GPE_NO_BUFFER_SPACE; break; } memcpy(ptag, ptr, len.uns); ptag[len.uns] = '\0'; if((STATE_INSUB == state) && !strcmp(csub, ptag)) { /* end of current sub section */ state = STATE_INMAIN; csub[0] = '\0'; if(in_wanted_part) { /* end of wanted part */ in_wanted_part = 0; break; } } else if((STATE_INMAIN == state) && !strcmp(cmain, ptag)) { /* end of current main section */ state = STATE_OUTER; cmain[0] = '\0'; if(in_wanted_part) { /* end of wanted part */ in_wanted_part = 0; break; } } else if((STATE_OUTER == state) && !strcmp(couter, ptag)) { /* end of outermost file section */ state = STATE_OUTSIDE; couter[0] = '\0'; if(in_wanted_part) { /* end of wanted part */ in_wanted_part = 0; break; } } } else if(!in_wanted_part) { /* ** opening section tag */ /* get potential tag */ end = ptr; EAT_WORD(end); if((len.sig = end - ptr) > MAX_TAG_LEN) { error = GPE_NO_BUFFER_SPACE; break; } memcpy(ptag, ptr, len.uns); ptag[len.uns] = '\0'; /* ignore comments, doctypes and xml declarations */ if(('!' == ptag[0]) || ('?' == ptag[0])) { show(("* ignoring (%s)", buffer)); continue; } /* get all potential attributes */ ptr = end; EAT_SPACE(ptr); end = ptr; while(*end && ('>' != *end)) end++; if((len.sig = end - ptr) > MAX_TAG_LEN) { error = GPE_NO_BUFFER_SPACE; break; } memcpy(patt, ptr, len.uns); patt[len.uns] = '\0'; if(STATE_OUTSIDE == state) { /* outermost element (<testcase>) */ strcpy(couter, ptag); state = STATE_OUTER; continue; } else if(STATE_OUTER == state) { /* start of a main section */ strcpy(cmain, ptag); state = STATE_INMAIN; continue; } else if(STATE_INMAIN == state) { /* start of a sub section */ strcpy(csub, ptag); state = STATE_INSUB; if(!strcmp(cmain, main) && !strcmp(csub, sub)) { /* start of wanted part */ in_wanted_part = 1; if(strstr(patt, "base64=")) /* bit rough test, but "mostly" functional, */ /* treat wanted part data as base64 encoded */ base64 = 1; } continue; } } if(in_wanted_part) { show(("=> %s", buffer)); error = appenddata(outbuf, outlen, &outalloc, buffer, base64); if(error) break; } } /* while */ if(buffer) free(buffer); if(error != GPE_OK) { if(error == GPE_END_OF_FILE) error = GPE_OK; else { if(*outbuf) free(*outbuf); *outbuf = NULL; *outlen = 0; } } return error; }
const char *spitout(FILE *stream, const char *main, const char *sub, size_t *size) { char buffer[8192]; /* big enough for anything */ char cmain[128]=""; /* current main section */ char csub[128]=""; /* current sub section */ char *ptr; char *end; char display = 0; char *string; size_t stringlen=0; size_t stralloc=256; char base64 = 0; /* set to 1 if true */ enum { STATE_OUTSIDE, STATE_OUTER, STATE_INMAIN, STATE_INSUB, STATE_ILLEGAL } state = STATE_OUTSIDE; string = malloc(stralloc); if(!string) return NULL; string[0] = 0; /* zero first byte in case of no data */ while(fgets(buffer, sizeof(buffer), stream)) { ptr = buffer; /* pass white spaces */ EAT_SPACE(ptr); if('<' != *ptr) { if(display) { show(("=> %s", buffer)); string = appendstring(string, buffer, &stringlen, &stralloc, base64); show(("* %s\n", buffer)); } continue; } ptr++; EAT_SPACE(ptr); if('/' == *ptr) { /* end of a section */ ptr++; EAT_SPACE(ptr); end = ptr; EAT_WORD(end); *end = 0; if((state == STATE_INSUB) && !strcmp(csub, ptr)) { /* this is the end of the currently read sub section */ state--; csub[0]=0; /* no sub anymore */ display=0; } else if((state == STATE_INMAIN) && !strcmp(cmain, ptr)) { /* this is the end of the currently read main section */ state--; cmain[0]=0; /* no main anymore */ display=0; } else if(state == STATE_OUTER) { /* this is the end of the outermost file section */ state--; } } else if(!display) { /* this is the beginning of a section */ end = ptr; EAT_WORD(end); *end = 0; switch(state) { case STATE_OUTSIDE: /* Skip over the outermost element (<testcase>), but if it turns out to be a comment, completely ignore it below */ strcpy(cmain, ptr); state = STATE_OUTER; break; case STATE_OUTER: strcpy(cmain, ptr); state = STATE_INMAIN; break; case STATE_INMAIN: strcpy(csub, ptr); state = STATE_INSUB; break; default: break; } if(!end[1] != '>') { /* There might be attributes here. Check for those we know of and care about. */ if(strstr(&end[1], "base64=")) { /* rough and dirty, but "mostly" functional */ /* Treat all data as base64 encoded */ base64 = 1; } } } if(display) { string = appendstring(string, buffer, &stringlen, &stralloc, base64); show(("* %s\n", buffer)); } if((STATE_INSUB == state) && !strcmp(cmain, main) && !strcmp(csub, sub)) { show(("* (%d bytes) %s\n", stringlen, buffer)); display = 1; /* start displaying */ } else if ((*cmain == '?') || (*cmain == '!') || (*csub == '!')) { /* Ignore comments, DOCTYPEs and XML declarations */ show(("%d ignoring (%s/%s)\n", state, cmain, csub)); state--; } else { show(("%d (%s/%s): %s\n", state, cmain, csub, buffer)); display = 0; /* no display */ } } *size = stringlen; return string; }
int parse_destination_list(rt_data_t* rd, char *dstlist, pgw_list_t** pgwl_ret, unsigned short *len, int no_resize) { #define PGWL_SIZE 32 pgw_list_t *pgwl=NULL, *p=NULL; unsigned int size, pgwl_size; long int t; char *tmp, *ep; str id; /* temporary list of gw while parsing */ pgwl_size = PGWL_SIZE; pgwl = (pgw_list_t*)pkg_malloc(pgwl_size*sizeof(pgw_list_t)); if (pgwl==NULL) { LM_ERR("no more shm mem\n"); goto error; } memset(pgwl, 0, pgwl_size*sizeof(pgw_list_t)); /* parset the destination list */ tmp = dstlist; size = 0; /* parse the dstlst */ while(tmp && (*tmp!=0)) { /* need a larger array ? */ if(size>=pgwl_size){ p=(pgw_list_t*)pkg_malloc((pgwl_size*2)*sizeof(pgw_list_t)); if (p==NULL) { LM_ERR("not enough shm mem to resize\n"); goto error; } memset( p+pgwl_size, 0, 2*pgwl_size*sizeof(pgw_list_t)); memcpy( p, pgwl, pgwl_size*sizeof(pgw_list_t)); pkg_free(pgwl); pgwl_size*=2; pgwl=p; } /* go over spaces */ EAT_SPACE(tmp); /* carrier id or GW id ? */ if (*tmp==CARRIER_MARKER) { pgwl[size].is_carrier = 1; tmp++; } /* eat the destination ID (alphanumerical) */ id.s = tmp; while( *tmp && (isalpha(*tmp) || isdigit(*tmp) || (*tmp)=='_' || (*tmp)=='-') ) tmp++; if (id.s == tmp) { LM_ERR("bad id '%c' (%d)[%s]\n", *tmp, (int)(tmp-dstlist), dstlist); goto error; } id.len = tmp - id.s ; /* look for the destination */ if (pgwl[size].is_carrier) { pgwl[size].dst.carrier = get_carrier_by_id(rd->carriers, &id); } else { pgwl[size].dst.gw = get_gw_by_id(rd->pgw_l, &id); } if (pgwl[size].dst.gw==NULL) LM_WARN("destination ID <%.*s> was not found\n",id.len,id.s); /* consume spaces */ EAT_SPACE(tmp); /* any weight? */ if (*tmp=='=') { tmp++; /* expect the weight value (int) */ errno = 0; t = strtol(tmp, &ep, 10); if (ep == tmp) { LM_ERR("bad weight value '%c' (%d)[%s]\n", *ep, (int)(ep-dstlist), dstlist); goto error; } if (errno == ERANGE && (t== LONG_MAX || t== LONG_MIN)) { LM_ERR("weight value out of bounds\n"); goto error; } tmp = ep; pgwl[size].weight = t; /* consume spaces */ EAT_SPACE(tmp); } /* valid record ? */ if (pgwl[size].dst.gw==NULL) { /* reset current record and do not count */ memset( pgwl+size, 0, sizeof(pgw_list_t)); } else { /* count record */ size++; } /* separator */ if ( (*tmp==SEP) || (*tmp==SEP1) ) { tmp++; } else if (*tmp!=0) { LM_ERR("bad char %c (%d) [%s]\n", *tmp, (int)(ep-dstlist), dstlist); goto error; } } if (size==0) { LM_DBG("empty destination list\n"); pkg_free(pgwl); *len = 0; *pgwl_ret = NULL; return 0; } /* done with parsing, build the final array and return */ if (no_resize) { *len = size; *pgwl_ret = pgwl; return 0; } p=(pgw_list_t*)shm_malloc(size*sizeof(pgw_list_t)); if (p==NULL) { LM_ERR("not enough shm mem for final build\n"); goto error; } memcpy( p, pgwl, size*sizeof(pgw_list_t)); pkg_free(pgwl); *len = size; *pgwl_ret = p; return 0; error: if (pgwl) pkg_free(pgwl); *len = 0; *pgwl_ret = NULL; return -1; }
rt_info_t* build_rt_info( int id, int priority, tmrec_t *trec, /* script routing table index */ int route_idx, /* list of destinations indexes */ char* dstlst, char* attrs, pgw_t* pgw_l ) { char *tmp=NULL; char *ep=NULL; rt_info_t* rt = NULL; int *idx = NULL, *t_idx=NULL; int n=0, idx_size=0,i, grp_idx=0; long t=0; pgw_t *pgw=NULL; rt = (rt_info_t*)shm_malloc(sizeof(rt_info_t)+(attrs?strlen(attrs):0)); if (rt==NULL) { LM_ERR("no more shm mem(1)\n"); goto err_exit; } memset(rt, 0, sizeof(rt_info_t)); idx_size = IDX_SIZE; if( NULL == (idx = (int*)shm_malloc(2*idx_size*sizeof(int)))) { LM_ERR("no more shm mem(2)\n"); goto err_exit; } memset(idx, 0, 2*idx_size*sizeof(int)); rt->id = id; rt->priority = priority; rt->time_rec = trec; rt->route_idx = route_idx; if (attrs && strlen(attrs)) { rt->attrs.s = (char*)(rt+1); rt->attrs.len = strlen(attrs); memcpy(rt->attrs.s,attrs,rt->attrs.len); } tmp=dstlst; n=0; /* parse the dstlst */ while(tmp && (*tmp!=0)) { errno = 0; t = strtol(tmp, &ep, 10); if (ep == tmp) { LM_ERR("bad id '%c' (%d)[%s]\n", *ep, (int)(ep-dstlst), dstlst); goto err_exit; } if ((!IS_SPACE(*ep)) && (*ep != SEP) && (*ep != SEP1) && (*ep != SEP_GRP) && (*ep!=0)) { LM_ERR("bad char %c (%d) [%s]\n", *ep, (int)(ep-dstlst), dstlst); goto err_exit; } if (errno == ERANGE && (t== LONG_MAX || t== LONG_MIN)) { LM_ERR("out of bounds\n"); goto err_exit; } idx[2*n]=t; idx[2*n+1]=grp_idx; if(*ep == SEP_GRP) grp_idx++; n++; /* reallocate the array which keeps the parsed indexes */ if(n>=idx_size){ if(NULL==((t_idx)=(int*)shm_malloc((idx_size*2*2)*sizeof(int)))) { LM_ERR("out of shm\n"); goto err_exit; } memset(t_idx+(2*idx_size), 0, 2*idx_size*sizeof(int)); memcpy(t_idx, idx, 2*idx_size*sizeof(int)); shm_free(idx); idx_size*=2; idx=t_idx; } if(IS_SPACE(*ep)) EAT_SPACE(ep); if(ep && (*ep == SEP || *ep == SEP1 || *ep == SEP_GRP)) ep++; tmp = ep; } if(n==0) { LM_ERR("invalid n\n"); goto err_exit; } /* create the pgwl */ rt->pgwa_len = n; if(NULL == (rt->pgwl=(pgw_list_t*)shm_malloc(rt->pgwa_len*sizeof(pgw_list_t)))) { goto err_exit; } memset(rt->pgwl, 0, rt->pgwa_len*sizeof(pgw_list_t)); /* translate GW ids to GW pointers */ for(i=0;i<n; i++){ if ( NULL == (pgw = get_pgw(pgw_l, idx[2*i]))) { LM_ERR("invalid GW id %d\n", idx[2*i]); goto err_exit; } rt->pgwl[i].pgw=pgw; rt->pgwl[i].grpid=idx[2*i+1]; /* LM_DBG("added to gwlist [%d/%d/%p]\n", idx[2*i], idx[2*i+1], pgw); */ } shm_free(idx); return rt; err_exit: if(NULL!=idx) shm_free(idx); if((NULL != rt) && (NULL!=rt->pgwl)) shm_free(rt->pgwl); if(NULL!=rt) shm_free(rt); return NULL; }