//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;
}
Exemple #3
0
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;
}