//merges config from parent static char *ngx_http_dclass_merge_conf(ngx_conf_t *cf, void *parent, void *child) { int ret,i; ngx_http_dclass_conf_t *prev = parent; ngx_http_dclass_conf_t *conf = child; ngx_conf_merge_value(conf->enable, prev->enable, 0); ngx_conf_merge_str_value(conf->hfield, prev->hfield, ""); for(i=0;i<NGX_HTTP_DCLASS_INDEXES;i++) { if(conf->dtree_loc[i].data) { conf->head[i]=ngx_pcalloc(cf->pool,sizeof(dclass_index)); dclass_init_index(conf->head[i]); ret=dclass_load_file(conf->head[i],(char*)conf->dtree_loc[i].data); if(ret<=0) ret=openddr_load_resources(conf->head[i],(char*)conf->dtree_loc[i].data); if(ret<0) return NGX_CONF_ERROR; ngx_log_error(NGX_HTTP_DCLASS_LOGLEVEL,cf->log,0,"dClass: init %d: loaded %zu nodes from '%s'", i,conf->head[i]->dti.node_count,conf->dtree_loc[i].data); } else if(prev->head[i]) conf->head[i]=prev->head[i]; } return NGX_CONF_OK; }
//merges config from parent static char * ngx_http_dclass_merge_conf(ngx_conf_t *cf, void *parent, void *child) { int ret=0; ngx_http_dclass_conf_t *prev = parent; ngx_http_dclass_conf_t *conf = child; ngx_conf_merge_value(conf->enable, prev->enable, 0); ngx_conf_merge_str_value(conf->hfield, prev->hfield, ""); if(conf->dtree_loc.data) { conf->head=ngx_pcalloc(cf->pool,sizeof(dclass_index)); dclass_init_index(conf->head); ret=dclass_load_file(conf->head,(char*)conf->dtree_loc.data); if(ret<=0) ret=openddr_load_resources(conf->head,(char*)conf->dtree_loc.data); if(ret<0) return NGX_CONF_ERROR; } else if(prev->head) conf->head=prev->head; return NGX_CONF_OK; }
int main(int argc,char **args) { int ret,i; int openddr=0; long count,ttime; char buf[1024]; char *loadFile="../dtrees/openddr.dtree"; char *outFile=""; char *parameter=NULL; struct timespec startn,endn,diffn,total; dclass_index di; dtree_dt_index *h=&di.dti; const dclass_keyvalue *kvd; for(i=1;i<argc;i++) { //-l [dtree file] if(!strcmp(args[i],"-l") && argc>(++i)) loadFile=args[i]; //-o [output dtree file] else if(!strcmp(args[i],"-o") && argc>(++i)) outFile=args[i]; //-m [open ddr resource dir] else if(!strcmp(args[i],"-d") && argc>(++i)) { openddr=1; loadFile=args[i]; } else if(!strncmp(args[i],"-h",2) || !strncmp(args[i],"--h",3)) { printf("Usage: dclass_client [OPTIONS] [FILE|STRING]\n\n"); printf(" -l <path> load dtree from file\n"); printf(" -o <path> store dtree to file\n"); printf(" -d <folder path> load OpenDDR resources xmls\n"); printf(" FILE STRING text file\n"); printf(" STRING test string\n"); return 0; } //[test string] | [test file] else parameter=args[i]; } printf("dClass - Device classification (version %s)\n",dclass_get_version()); printf("Loading %s: '%s'\n",openddr?"openddr":"dtree",loadFile); clock_gettime(CLOCK_REALTIME,&startn); if(openddr) ret=openddr_load_resources(&di,loadFile); else ret=dclass_load_file(&di,loadFile); clock_gettime(CLOCK_REALTIME,&endn); dtree_timersubn(&endn,&startn,&diffn); printf("load dtree tokens: %d time: %lds %ldms %ldus %ldns\n", ret,diffn.tv_sec,diffn.tv_nsec/1000000,diffn.tv_nsec/1000%1000,diffn.tv_nsec%1000); printf("dtree stats: nodes: %zu slabs: %zu mem: %zu bytes strings: %zu(%zu,%zu)\n", h->node_count,h->slab_count,h->size,h->dc_count,h->dc_slab_count,h->dc_slab_pos); clock_gettime(CLOCK_REALTIME,&startn); count=dtree_print(h,&dclass_get_id); clock_gettime(CLOCK_REALTIME,&endn); dtree_timersubn(&endn,&startn,&diffn); printf("walk tree: %ld tokens %zu nodes time: %lds %ldms %ldus %ldns\n", count,h->node_count,diffn.tv_sec,diffn.tv_nsec/1000000,diffn.tv_nsec/1000%1000,diffn.tv_nsec%1000); if(*outFile) { printf("Dumping dtree: '%s'\n",outFile); ret=dclass_write_file(&di,outFile); printf("Wrote %d entries\n",ret); } clock_gettime(CLOCK_REALTIME,&startn); kvd=dclass_classify(&di,"Mozilla/5.0 (Linux; U; Android 2.2; en; HTC Aria A6380 Build/ERE27) AppleWebKit/540.13+ (KHTML, like Gecko) Version/3.1 Mobile Safari/524.15.0"); clock_gettime(CLOCK_REALTIME,&endn); dtree_timersubn(&endn,&startn,&diffn); printf("HTC Aria UA lookup: '%s' time: %lds %ldms %ldus %ldns\n", kvd->id,diffn.tv_sec,diffn.tv_nsec/1000000,diffn.tv_nsec/1000%1000,diffn.tv_nsec%1000); if(parameter) { FILE *f; if((f=fopen(parameter,"r"))) { printf("UA file: '%s'\n",parameter); count=0; memset(&total,0,sizeof(total)); while(fgets(buf,sizeof(buf),f)) { #if DTREE_TEST_UALOOKUP int slen=strlen(buf)-1; if(buf[slen]=='\n') buf[slen]='\0'; printf("UA: '%s'\n",buf); fflush(stdout); #endif clock_gettime(CLOCK_REALTIME,&startn); kvd=dclass_classify(&di,buf); clock_gettime(CLOCK_REALTIME,&endn); dtree_timersubn(&endn,&startn,&diffn); total.tv_sec+=diffn.tv_sec; total.tv_nsec+=diffn.tv_nsec; count++; #if DTREE_TEST_UALOOKUP printf("UA lookup %ld: '%s' time: %lds %ldms %ldus %ldns\n", count,kvd->id,diffn.tv_sec,diffn.tv_nsec/1000000,diffn.tv_nsec/1000%1000,diffn.tv_nsec%1000); #endif } fclose(f); if(!count) count=1; ttime=(total.tv_sec*1000*1000*1000)+total.tv_nsec; ttime/=count; printf("TOTAL average time: %ld lookups, %lds %ldms %ldus %ldns\n", count,ttime/1000000000,ttime/1000000%1000000,ttime/1000%1000,ttime%1000); } else { printf("UA: '%s'\n",parameter); clock_gettime(CLOCK_REALTIME,&startn); kvd=dclass_classify(&di,parameter); clock_gettime(CLOCK_REALTIME,&endn); dtree_timersubn(&endn,&startn,&diffn); printf("Param UA lookup: '%s' time: %lds %ldms %ldus %ldns\n", kvd->id,diffn.tv_sec,diffn.tv_nsec/1000000,diffn.tv_nsec/1000%1000,diffn.tv_nsec%1000); if(kvd && kvd->size) { printf("OpenDDR attributes => "); for(i=0;i<kvd->size;i++) printf("%s: '%s' ",kvd->keys[i],kvd->values[i]); printf("\n"); } } } dclass_free(&di); return 0; }