0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 #include <string.h>
0042 #include <ubf_int.h>
0043 #include <stdlib.h>
0044 #include <errno.h>
0045
0046 #include <fieldtable.h>
0047 #include <fdatatype.h>
0048 #include <ferror.h>
0049 #include <utlist.h>
0050
0051 #include "ndebug.h"
0052 #include "ubf_tls.h"
0053 #include <thlock.h>
0054 #include <ubfdb.h>
0055
0056
0057
0058
0059
0060
0061
0062
0063 #define DL_REV_SEARCH(head,out,elt,cmp) \
0064 do { \
0065 if (head) { \
0066 for(out=head->NDRX_PREV;;out=out->NDRX_PREV) { \
0067 if ((cmp(out,elt))==0) break; \
0068 if (out==head) {out=NULL; break;} \
0069 } \
0070 } \
0071 } while(0)
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 exprivate UBF_field_def_t ** M_bfldidhash2 = NULL;
0095 exprivate UBF_field_def_t ** M_fldnmhash2 = NULL;
0096 exprivate volatile int M_field_def_loaded = EXFALSE;
0097 exprivate int M_hash2_size = 16000;
0098
0099
0100 exprivate void _bfldidhash_add(UBF_field_def_t *p_fld);
0101 exprivate void _fldnmexhash_add(UBF_field_def_t *p_fld);
0102 exprivate int _ubf_load_fld_def(int base,
0103 char *fldinfo,
0104 int (*put_def_line) (UBF_field_def_t *def),
0105 int check_dup,
0106 char *fname,
0107 int line);
0108
0109 static unsigned int str_hash_from_key_fn( void *k );
0110 static int str_keys_equal_fn ( void *key1, void *key2 );
0111
0112
0113
0114
0115
0116
0117 exprivate int init_hash_area(void)
0118 {
0119 int ret=EXSUCCEED;
0120 char *p;
0121 int malloc_size = sizeof(ft_node_t *)*M_hash2_size;
0122 int i;
0123 static int first = 1;
0124 UBF_field_def_t *elt, *tmp, *head;
0125
0126
0127 if (first)
0128 {
0129 if (NULL!=(p=getenv("NDRX_UBFMAXFLDS")))
0130 {
0131 M_hash2_size = atoi(p);
0132 malloc_size = sizeof(ft_node_t *)*M_hash2_size;
0133 }
0134 UBF_LOG(log_debug, "Using NDRX_UBFMAXFLDS: %d", M_hash2_size);
0135 first = 0;
0136 }
0137
0138 if (NULL==M_bfldidhash2)
0139 {
0140 M_bfldidhash2 = NDRX_MALLOC(malloc_size);
0141 if (NULL==M_bfldidhash2)
0142 {
0143 ndrx_Bset_error_fmt(BMALLOC, "Failed to malloc bfldidhash2, requested: %d bytes err: %s",
0144 malloc_size, strerror(errno));
0145 ret=EXFAIL;
0146 goto out;
0147 }
0148 }
0149 else
0150 {
0151
0152
0153
0154 for (i=0; i<M_hash2_size; i++)
0155 {
0156 if (NULL!=M_bfldidhash2[i])
0157 {
0158 head = M_bfldidhash2[i];
0159 DL_FOREACH_SAFE(head,elt,tmp)
0160 {
0161 DL_DELETE(head, elt);
0162 }
0163 }
0164 }
0165 }
0166
0167 if (NULL==M_fldnmhash2)
0168 {
0169 M_fldnmhash2 = NDRX_MALLOC(malloc_size);
0170 if (NULL==M_fldnmhash2)
0171 {
0172 ndrx_Bset_error_fmt(BMALLOC, "Failed to malloc fldnmhash2, requested: %d bytes err: %s",
0173 malloc_size, strerror(errno));
0174 ret=EXFAIL;
0175 goto out;
0176 }
0177 }
0178 else
0179 {
0180
0181
0182
0183 for (i=0; i<M_hash2_size; i++)
0184 {
0185 if (NULL!=M_fldnmhash2[i])
0186 {
0187 head = M_fldnmhash2[i];
0188 DL_FOREACH_SAFE(head,elt,tmp)
0189 {
0190 DL_DELETE(head, elt);
0191 }
0192 }
0193 }
0194 }
0195
0196
0197 memset(M_bfldidhash2, 0, malloc_size);
0198
0199 memset(M_fldnmhash2, 0, malloc_size);
0200
0201 out:
0202 return ret;
0203 }
0204
0205
0206
0207
0208 exprivate void _bfldidhash_add(UBF_field_def_t *p_fld)
0209 {
0210 int hash_key = p_fld->bfldid % M_hash2_size;
0211
0212 DL_APPEND(M_bfldidhash2[hash_key], p_fld);
0213 }
0214
0215
0216
0217
0218
0219
0220
0221 exprivate int UBF_field_def_id_cmp(UBF_field_def_t *a, UBF_field_def_t *b)
0222 {
0223 return (a->bfldid==b->bfldid?EXSUCCEED:EXFAIL);
0224 }
0225
0226
0227
0228
0229 expublic UBF_field_def_t * _bfldidhash_get(BFLDID id)
0230 {
0231
0232 int hash_key = id % M_hash2_size;
0233 UBF_field_def_t *ret=NULL;
0234 UBF_field_def_t tmp;
0235
0236 tmp.bfldid=id;
0237
0238 DL_REV_SEARCH(M_bfldidhash2[hash_key],ret,&tmp,UBF_field_def_id_cmp);
0239
0240 return ret;
0241 }
0242
0243
0244
0245
0246 exprivate void _fldnmexhash_add(UBF_field_def_t *p_fld)
0247 {
0248
0249 int hash_key = str_hash_from_key_fn(p_fld->fldname) % M_hash2_size;
0250 DL_APPEND(M_fldnmhash2[hash_key], p_fld);
0251
0252 #ifdef EXTRA_FT_DEBUG
0253 printf("field [%s] key [%d] result [0%x] - [0%x] added\n", p_fld->fldname, hash_key, p_fld, M_fldnmhash2[hash_key]);
0254 #endif
0255 }
0256
0257
0258
0259
0260
0261
0262
0263
0264 exprivate int UBF_field_def_nm_cmp(UBF_field_def_t *a, UBF_field_def_t *b)
0265 {
0266 return strcmp(a->fldname, b->fldname);
0267 }
0268
0269
0270
0271
0272
0273 expublic UBF_field_def_t * ndrx_fldnmhash_get(char *key)
0274 {
0275
0276 int hash_key = str_hash_from_key_fn(key) % M_hash2_size;
0277 UBF_field_def_t *ret=NULL;
0278 UBF_field_def_t tmp;
0279 NDRX_STRCPY_SAFE(tmp.fldname, key);
0280 DL_REV_SEARCH(M_fldnmhash2[hash_key],ret,&tmp,UBF_field_def_nm_cmp);
0281
0282 #ifdef EXTRA_FT_DEBUG
0283 printf("field [%s] key [%d] result [0%x] - [0%x]\n", key, hash_key, ret, M_bfldidhash2[hash_key]);
0284 #endif
0285 return ret;
0286 }
0287
0288
0289
0290
0291
0292
0293
0294
0295 exprivate int _ubf_load_def_table(void)
0296 {
0297 char *flddir=NULL;
0298 char *flds=NULL;
0299 char *p, *pd;
0300 char *p_flds, *p_flddir;
0301 FILE *fp;
0302 char tmp_flds[FILENAME_MAX+1];
0303 char tmp_flddir[FILENAME_MAX+1];
0304 char tmp[FILENAME_MAX+1];
0305 int exist_fld;
0306
0307 int ret=EXSUCCEED;
0308
0309 flddir = getenv(CONF_FLDTBLDIR);
0310 if (NULL==flddir)
0311 {
0312 ndrx_Bset_error_msg(BFTOPEN, "Field table directory not set - "
0313 "check FLDTBLDIR env var");
0314 ret=EXFAIL;
0315 goto out;
0316 }
0317 UBF_LOG(log_debug,
0318 "Load field dir [%s] (multiple directories supported)", flddir);
0319
0320 flds = getenv(CONF_FIELDTBLS);
0321 if (NULL==flds)
0322 {
0323 ndrx_Bset_error_msg(BFTOPEN, "Field table list not set - "
0324 "check FIELDTBLS env var");
0325 ret=EXFAIL;
0326 goto out;
0327 }
0328
0329 UBF_LOG(log_debug, "About to load fields list [%s]", flds);
0330
0331 _ubf_loader_init();
0332
0333 NDRX_STRCPY_SAFE(tmp_flds, flds);
0334 p=strtok_r(tmp_flds, ",", &p_flds);
0335 while (NULL!=p)
0336 {
0337 exist_fld=EXFALSE;
0338 NDRX_STRCPY_SAFE(tmp_flddir, flddir);
0339 pd=strtok_r(tmp_flddir, ":", &p_flddir);
0340 while ( NULL!=pd && EXFALSE==exist_fld)
0341 {
0342 snprintf(tmp, sizeof(tmp), "%s/%s", pd, p);
0343 UBF_LOG(log_debug, "Open field table file [%s]", tmp);
0344
0345
0346 if (NULL==(fp=NDRX_FOPEN(tmp, "r")))
0347 {
0348 UBF_LOG(log_debug, "Failed to open %s with error: [%s]",
0349 tmp, strerror(errno));
0350 }
0351 else
0352 {
0353 ret=ndrx_ubf_load_def_file(fp, NULL, NULL, NULL, tmp, EXFALSE);
0354 exist_fld=EXTRUE;
0355 NDRX_FCLOSE(fp);
0356 }
0357 pd=strtok_r(NULL, ":", &p_flddir);
0358 }
0359
0360 if ( EXFALSE==exist_fld )
0361 {
0362
0363
0364
0365
0366
0367
0368 userlog("Field table [%s] not found in [%s]", p, flddir);
0369 }
0370
0371 p=strtok_r(NULL, ",", &p_flds);
0372 }
0373
0374
0375
0376 M_field_def_loaded = EXTRUE;
0377
0378 out:
0379
0380 return ret;
0381 }
0382
0383
0384
0385
0386
0387 expublic int _ubf_loader_init(void)
0388 {
0389 return init_hash_area();
0390 }
0391
0392
0393
0394
0395
0396
0397 expublic int ndrx_ubf_load_def_file(FILE *fp,
0398 int (*put_text_line) (char *text),
0399 int (*put_def_line) (UBF_field_def_t *def),
0400 int (*put_got_base_line) (char *base),
0401 char *fname,
0402 int check_dup)
0403 {
0404 int ret=EXSUCCEED;
0405 int base=0;
0406 char tmp[FILENAME_MAX+1];
0407 char fldname[UBFFLDMAX+1];
0408 int line=0;
0409
0410
0411 while (EXSUCCEED==ret && NULL!=fgets(tmp, 1024, fp))
0412 {
0413 line++;
0414
0415 UBF_LOG(log_dump, "Loading debug line [%s]", tmp);
0416
0417 switch (tmp[0])
0418 {
0419 case '$':
0420
0421 if (NULL!=put_text_line)
0422 ret=put_text_line(tmp+1);
0423
0424 case '#':
0425 case '\n':
0426
0427 break;
0428 case '*':
0429
0430 sscanf(tmp, "%s%d", fldname, &base);
0431 if (0!=strcmp("*base", fldname))
0432 {
0433 base=0;
0434 }
0435
0436
0437 if (NULL!=put_got_base_line)
0438 ret=put_got_base_line(tmp);
0439
0440 break;
0441 default:
0442 ret=_ubf_load_fld_def(base, tmp, put_def_line, check_dup,
0443 fname, line);
0444 break;
0445 }
0446 }
0447 return ret;
0448 }
0449
0450
0451
0452
0453 exprivate int _ubf_load_fld_def(int base,
0454 char *fldinfo,
0455 int (*put_def_line) (UBF_field_def_t *def),
0456 int check_dup,
0457 char *fname,
0458 int line)
0459 {
0460 int ret=EXSUCCEED;
0461 char ftype[NDRX_UBF_TYPE_LEN+1]={'\0'};
0462 UBF_field_def_t *fld, *fld2;
0463 UBF_field_def_t *reserved;
0464 dtype_str_t *p = G_dtype_str_map;
0465 _UBF_INT dtype;
0466 BFLDID number;
0467
0468 fld = NDRX_CALLOC(1, sizeof(UBF_field_def_t));
0469 fld2 = NDRX_CALLOC(1, sizeof(UBF_field_def_t));
0470
0471 if (NULL==fld || NULL==fld2)
0472 {
0473 ndrx_Bset_error_msg(BMALLOC, "Failed to allocate field def space!");
0474 ret=EXFAIL;
0475 goto out;
0476 }
0477
0478 sscanf(fldinfo, "%s%d%s", fld->fldname, &(fld->bfldid), ftype);
0479 fld->bfldid+=base;
0480
0481 while(EXEOS!=p->fldname[0])
0482 {
0483 if (0==strcmp(p->fldname, ftype) || (p->altname && 0==strcmp(p->altname, ftype)))
0484 {
0485 fld->fldtype = p->fld_type;
0486 dtype = p->fld_type;
0487 break;
0488 }
0489 p++;
0490 }
0491 dtype<<=EFFECTIVE_BITS;
0492
0493
0494 number = fld->bfldid;
0495 fld->bfldid |= dtype;
0496
0497 UBF_LOG(log_dump, "Adding [%s] - id [%d] - [%s]",
0498 fld->fldname, fld->bfldid, fldinfo);
0499
0500 if (EXEOS==p->fldname[0])
0501 {
0502 ndrx_Bset_error_fmt(BFTSYNTAX, "Failed to find data type for [%s] in %s:%d!",
0503 ftype, fname, line);
0504 ret=EXFAIL;
0505 }
0506 else
0507 {
0508
0509 if (check_dup)
0510 {
0511 if (NULL!=(reserved=ndrx_fldnmhash_get(fld->fldname)))
0512 {
0513
0514 ndrx_Bset_error_fmt(BFTSYNTAX, "Duplicate name [%s] already taken by "
0515 "[%s]:%d %s:%d!",
0516 fld->fldname, reserved->fldname, number,
0517 fname, line);
0518 ret=EXFAIL;
0519 }
0520
0521 if (EXSUCCEED==ret && NULL!=(reserved=_bfldidhash_get(fld->bfldid)))
0522 {
0523
0524 ndrx_Bset_error_fmt(BFTSYNTAX, "Duplicate ID [%s]:%d already taken by [%s]:%d "
0525 "%s:%d!",
0526 fld->fldname, number, reserved->fldname, number,
0527 fname, line);
0528 ret=EXFAIL;
0529 }
0530 }
0531
0532 if (EXSUCCEED==ret)
0533 {
0534 _bfldidhash_add(fld);
0535 *fld2 = *fld;
0536 _fldnmexhash_add(fld2);
0537 }
0538 }
0539
0540
0541
0542
0543 if (EXSUCCEED==ret && NULL!=put_def_line)
0544 {
0545 ret=put_def_line(fld);
0546 }
0547
0548 out:
0549 if (EXSUCCEED!=ret)
0550 {
0551 if (NULL!=fld)
0552 {
0553 NDRX_FREE(fld);
0554 }
0555
0556 if (NULL!=fld2)
0557 {
0558 NDRX_FREE(fld2);
0559 }
0560
0561 }
0562 return ret;
0563 }
0564
0565
0566
0567
0568 static unsigned int str_hash_from_key_fn( void *k )
0569 {
0570 unsigned int hash = 5381;
0571 int c;
0572 char *str = (char *)k;
0573
0574 while ((c = (int)*str++))
0575 hash = ((hash << 5) + hash) + c;
0576
0577 return hash;
0578 }
0579
0580
0581
0582
0583 static int str_keys_equal_fn( void *key1, void *key2 )
0584 {
0585 return (0==strcmp(key1, key2)?1:0);
0586 }
0587
0588
0589
0590
0591
0592 expublic int ndrx_prepare_type_tables(void)
0593 {
0594
0595 if (!M_field_def_loaded)
0596 {
0597
0598 MUTEX_LOCK;
0599 {
0600 int ret=EXSUCCEED;
0601
0602
0603 if (!M_field_def_loaded)
0604 {
0605 ret=_ubf_load_def_table();
0606 }
0607
0608 if (EXSUCCEED==ret)
0609 {
0610
0611 if (EXFAIL==ndrx_ubfdb_Bflddbload())
0612 {
0613 ret=EXFAIL;
0614 }
0615 }
0616
0617 MUTEX_UNLOCK;
0618 return ret;
0619 }
0620 }
0621 else
0622 {
0623 return EXSUCCEED;
0624 }
0625 }
0626
0627
0628
0629
0630 expublic char * ndrx_Bfname_int (BFLDID bfldid)
0631 {
0632 UBF_field_def_t *p_fld;
0633 UBF_TLS_ENTRY;
0634
0635 if (EXSUCCEED!=ndrx_prepare_type_tables())
0636 {
0637 if (BFTOPEN==Berror || BFTSYNTAX==Berror)
0638 {
0639 ndrx_Bunset_error();
0640 }
0641
0642 snprintf(G_ubf_tls->bfname_buf, sizeof(G_ubf_tls->bfname_buf),
0643 "((BFLDID32)%d)", bfldid);
0644
0645 return G_ubf_tls->bfname_buf;
0646 }
0647
0648
0649 p_fld = _bfldidhash_get(bfldid);
0650
0651 if (NULL==p_fld && NULL!=ndrx_G_ubf_db)
0652 {
0653 char *p;
0654 p = ndrx_ubfdb_Bflddbname(bfldid);
0655 if (NULL==p)
0656 {
0657 if (BNOTFLD==Berror)
0658 {
0659 ndrx_Bunset_error();
0660 }
0661 }
0662 else
0663 {
0664 return p;
0665 }
0666 }
0667
0668 if (NULL==p_fld)
0669 {
0670 snprintf(G_ubf_tls->bfname_buf, sizeof(G_ubf_tls->bfname_buf),
0671 "((BFLDID32)%d)", bfldid);
0672 return G_ubf_tls->bfname_buf;
0673 }
0674 else
0675 {
0676 return p_fld->fldname;
0677 }
0678 }
0679
0680
0681
0682
0683
0684
0685 exprivate BFLDID get_from_bfldidstr(char *fldnm)
0686 {
0687 BFLDID ret;
0688 sscanf(fldnm, "((BFLDID32)%d)", &ret);
0689 UBF_LOG(log_warn, "Parsed ((BFLDID32)%%d) from [%s] got id %d",
0690 fldnm, ret);
0691 return ret;
0692 }
0693
0694
0695
0696
0697
0698 expublic BFLDID ndrx_Bfldid_int (char *fldnm)
0699 {
0700 UBF_field_def_t *p_fld=NULL;
0701 BFLDID bfldid;
0702
0703 if (EXSUCCEED!=ndrx_prepare_type_tables())
0704 {
0705
0706 if (0==strncmp(fldnm, "((BFLDID32)", 11))
0707 {
0708 bfldid = get_from_bfldidstr(fldnm);
0709 return bfldid;
0710 }
0711 else
0712 {
0713 return BBADFLDID;
0714 }
0715 }
0716
0717
0718 p_fld = ndrx_fldnmhash_get(fldnm);
0719
0720 if (NULL==p_fld && NULL!=ndrx_G_ubf_db)
0721 {
0722 if (BBADFLDID==(bfldid = ndrx_ubfdb_Bflddbid(fldnm)))
0723 {
0724 if (BNOTFLD==Berror)
0725 {
0726 ndrx_Bunset_error();
0727 }
0728 }
0729 else
0730 {
0731 return bfldid;
0732 }
0733 }
0734
0735 if (NULL!=p_fld)
0736 {
0737 return p_fld->bfldid;
0738 }
0739 else if (0==strncmp(fldnm, "((BFLDID32)", 11))
0740 {
0741 bfldid = get_from_bfldidstr(fldnm);
0742 return bfldid;
0743 }
0744 else
0745 {
0746 return BBADFLDID;
0747 }
0748 }
0749