Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief VIEW buffer type support - parser
0003  *
0004  * @file view_parser.c
0005  */
0006 /* -----------------------------------------------------------------------------
0007  * Enduro/X Middleware Platform for Distributed Transaction Processing
0008  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0009  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0010  * This software is released under one of the following licenses:
0011  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0012  * See LICENSE file for full text.
0013  * -----------------------------------------------------------------------------
0014  * AGPL license:
0015  *
0016  * This program is free software; you can redistribute it and/or modify it under
0017  * the terms of the GNU Affero General Public License, version 3 as published
0018  * by the Free Software Foundation;
0019  *
0020  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0021  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0022  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0023  * for more details.
0024  *
0025  * You should have received a copy of the GNU Affero General Public License along 
0026  * with this program; if not, write to the Free Software Foundation, Inc.,
0027  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0028  *
0029  * -----------------------------------------------------------------------------
0030  * A commercial use license is available from Mavimax, Ltd
0031  * contact@mavimax.com
0032  * -----------------------------------------------------------------------------
0033  */
0034 #include <string.h>
0035 #include <stdio.h>
0036 #include <stdlib.h>
0037 #include <memory.h>
0038 #include <errno.h>
0039 #include <dirent.h>
0040 
0041 #include <ndrstandard.h>
0042 #include <ndebug.h>
0043 
0044 #include <userlog.h>
0045 #include <view_cmn.h>
0046 #include <ubfview.h>
0047 #include <ferror.h>
0048 
0049 #include "Exfields.h"
0050 /*---------------------------Externs------------------------------------*/
0051 /*---------------------------Macros-------------------------------------*/
0052 #define API_ENTRY {ndrx_Bunset_error(); \
0053 }
0054 /*---------------------------Enums--------------------------------------*/
0055 /*---------------------------Typedefs-----------------------------------*/
0056 /*---------------------------Globals------------------------------------*/
0057 /*---------------------------Statics------------------------------------*/
0058 exprivate MUTEX_LOCKDECL(M_view_change_lock);
0059 exprivate MUTEX_LOCKDECL(M_views_init_lock);
0060 exprivate int M_no_ubf_proc = EXFALSE; /* Do not process UBF during loading... */
0061 exprivate  volatile int M_views_loaded = EXFALSE; /* Is views loaded? */
0062 /*---------------------------Prototypes---------------------------------*/
0063 
0064 /**
0065  * Load the directories by CONF_VIEWDIR
0066  * @return EXSUCCEED/EXFAIL
0067  */
0068 exprivate int ndrx_view_load_directories(void)
0069 {
0070     int ret = EXSUCCEED;
0071 
0072     char *tok;
0073     char *saveptr1;
0074     char *env;
0075     char dirs[PATH_MAX+1];
0076     env = getenv(CONF_VIEWDIR);
0077     if (NULL==env)
0078     {
0079         UBF_LOG(log_error, "Missing env [%s]", CONF_VIEWDIR);
0080         ndrx_Bset_error_fmt(BEUNIX, "Missing env [%s]", CONF_VIEWDIR);
0081         EXFAIL_OUT(ret);
0082     }
0083 
0084     NDRX_STRCPY_SAFE(dirs, env);
0085 
0086     UBF_LOG(log_debug, "Splitting: [%s]", dirs);
0087     tok=strtok_r (dirs,":", &saveptr1);
0088     while( tok != NULL )
0089     {
0090         UBF_LOG(log_debug, "Loading directory [%s]...", tok);
0091         if (EXSUCCEED!=ndrx_view_load_directory(tok))
0092         {
0093             EXFAIL_OUT(ret);
0094         }
0095 
0096         tok=strtok_r (NULL,":", &saveptr1);
0097     }
0098 
0099 
0100 out:
0101 
0102     if (EXSUCCEED==ret)
0103     {
0104         __sync_synchronize();
0105         M_views_loaded = EXTRUE;
0106         UBF_LOG(log_info, "Views loaded OK");
0107     }
0108 
0109     return ret;
0110 }
0111 
0112 /**
0113  * Configure view loader
0114  * @param no_ubf_proc Do not process UBF during loading...
0115  */
0116 expublic void ndrx_view_loader_configure(int no_ubf_proc)
0117 {
0118     M_no_ubf_proc = no_ubf_proc;
0119     UBF_LOG(log_warn, "Do not process UBF: %s", M_no_ubf_proc?"Yes":"No");
0120 }
0121 
0122 /**
0123  * Load single view file
0124  * @param fname - full path to the file to load
0125  * @param is_compiled - is this compiled format or source format
0126  * @return  EXSUCCEED/EXFAIL
0127  */
0128 expublic int ndrx_view_load_file(char *fname, int is_compiled)
0129 {
0130     int ret = EXSUCCEED;
0131     FILE *f = NULL;
0132     char buf[PATH_MAX*2];
0133     int orglen;
0134     ndrx_typedview_t *v = NULL;
0135     char *saveptr1 = NULL; /* lookup section  */
0136     char *saveptr2 = NULL; /* lookup section  */
0137     char *tok, *tok2;
0138     enum states { INFILE, INVIEW} state = INFILE;
0139     enum nulltypes { NTYPNO, NTYPSTD, NTYPSQUOTE, NTYPDQUOTE} nulltype = NTYPNO;
0140     int len;
0141     int was_quotes;
0142     char *p, *p2, *pend, *null_val_start, *p3;
0143     long line=0;
0144     dtype_str_t *dtyp;
0145     ndrx_typedview_field_t *fld = NULL;
0146     int i;
0147     int esc_open;
0148     int dim_size;
0149     /* Additional checks for compiled object: */
0150     int file_platform_ok = EXFALSE;
0151     int file_arch_ok = EXFALSE;
0152     int file_wsize_ok = EXFALSE;
0153     int view_ssize_ok;
0154     int view_cksum_ok;
0155     
0156     API_ENTRY;
0157     
0158     UBF_LOG(log_debug, "%s - enter", __func__);
0159     
0160     if (NULL==(f=NDRX_FOPEN(fname, "r")))
0161     {
0162         int err = errno;
0163         UBF_LOG(log_error, "Failed to open view file [%s]: %s", 
0164                 fname, strerror(err));
0165         ndrx_Bset_error_fmt(BVFOPEN, "Failed to open view file [%s]: %s", 
0166                 fname, strerror(err));
0167         EXFAIL_OUT(ret);
0168     }
0169     
0170     /* Read line by line... */
0171     while (NULL!=fgets(buf, sizeof(buf), f))
0172     {
0173         line++;
0174         
0175         /* remove trailing newline... */
0176         ndrx_chomp(buf);
0177         
0178         orglen = strlen(buf);
0179         
0180         UBF_LOG(log_dump, "Got VIEW file line: [%s], line: %ld", buf, line);
0181         
0182         if ('#'==buf[0])
0183         {
0184             /* this is comment, ignore */
0185             
0186             if (is_compiled)
0187             {
0188                 if (0==strncmp("#@__platform=", buf, 13))
0189                 {
0190                     UBF_LOG(log_debug, "Found platform data, parsing...");
0191                     tok2=strtok_r (buf,";", &saveptr2);
0192                     while( tok2 != NULL ) 
0193                     {
0194                         int cmplen;
0195                         char *p3;
0196                         /* get the setting... */
0197                         p3 = strchr(tok2, '=');
0198                         cmplen = p3-tok2;
0199 
0200                         if (0==strncmp("#@__platform", tok2, cmplen))
0201                         {
0202                             if (0!=strcmp(NDRX_BUILD_OS_NAME, p3+1))
0203                             {
0204                                 UBF_LOG(log_error, "Invalid platform, expected: "
0205                                         "[%s] got [%s] - please recompile the "
0206                                         "view file with viewc, line: %ld", 
0207                                         NDRX_BUILD_OS_NAME, p3+1, line);
0208                                 ndrx_Bset_error_fmt(BBADVIEW, "Invalid platform "
0209                                         "expected: [%s] got [%s] - please recompile "
0210                                         "the view file with viewc, line: %ld", 
0211                                         NDRX_BUILD_OS_NAME, p3+1, line);
0212                                 EXFAIL_OUT(ret);
0213                             }
0214                             else
0215                             {
0216                                 file_platform_ok = EXTRUE;
0217                             }
0218                         }
0219                         else if (0==strncmp("@__arch", tok2, cmplen))
0220                         {
0221                             if (0!=strcmp(NDRX_CPUARCH, p3+1))
0222                             {
0223                                 UBF_LOG(log_error, "Invalid CPU arch, expected: "
0224                                             "[%s] got [%s] - please recompile the "
0225                                             "view file with viewc, line: %ld", 
0226                                             NDRX_CPUARCH, p3+1, line);
0227                                 ndrx_Bset_error_fmt(BBADVIEW, "Invalid CPU arch, expected: "
0228                                         "expected: [%s] got [%s] - please recompile "
0229                                         "the view file with viewc, line: %ld", 
0230                                         NDRX_CPUARCH, p3+1, line);
0231                                 EXFAIL_OUT(ret);
0232                             }
0233                             else
0234                             {
0235                                 file_arch_ok = EXTRUE;
0236                             }
0237                         }
0238                         else if (0==strncmp("@__wsize", tok2, cmplen))
0239                         {
0240                             int ws=atoi(p3+1);
0241                             
0242                             if (ws!=NDRX_WORD_SIZE)
0243                             {
0244                                 UBF_LOG(log_error, "Invalid platform word size, expected: "
0245                                         "[%d] got [%d] - please recompile the "
0246                                         "view file with viewc, line: %ld", 
0247                                         NDRX_WORD_SIZE, ws, line);
0248                                 ndrx_Bset_error_fmt(BBADVIEW, "Invalid platfrom "
0249                                         "word size, expected: "
0250                                         "expected: [%d] got [%d] - please recompile "
0251                                         "the view file with viewc, line: %ld", 
0252                                         NDRX_WORD_SIZE, ws, line);
0253                                 EXFAIL_OUT(ret);
0254                             }
0255                             else
0256                             {
0257                                 file_wsize_ok = EXTRUE;
0258                             }
0259                         }
0260                         
0261                         /* Ignore others...  */
0262                         
0263                         tok2=strtok_r (NULL,";", &saveptr2);
0264                     }
0265                 }
0266                 else if (0==strncmp("#@__ssize=", buf, 10))
0267                 {
0268                     UBF_LOG(log_debug, "Structure data, parsing...");
0269                     tok2=strtok_r (buf,";", &saveptr2);
0270                     while( tok2 != NULL ) 
0271                     {
0272                         int cmplen;
0273                         char *p3;
0274                         /* get the setting... */
0275                         p3 = strchr(tok2, '=');
0276                         cmplen = p3-tok2;
0277 
0278                         if (0==strncmp("#@__ssize", tok2, cmplen))
0279                         {
0280                             v->ssize = atol(p3+1);
0281                             
0282                             UBF_LOG(log_debug, "Struct size loaded: [%ld]",
0283                                     v->ssize);
0284                             
0285                             if (v->ssize<0)
0286                             {
0287                                 UBF_LOG(log_error, "Invalid size %ld, line %ld", 
0288                                         v->ssize, line);
0289                                 ndrx_Bset_error_fmt(BBADVIEW, "Invalid size %ld, line %ld", 
0290                                         v->ssize, line);
0291                                 EXFAIL_OUT(ret);   
0292                             }
0293                             
0294                             view_ssize_ok = EXTRUE;
0295             
0296                         }
0297                         else if (0==strncmp("@__cksum", tok2, cmplen))
0298                         {
0299                             long cksum = atoll(p3+1);
0300                             long cksum_built = v->cksum;
0301                             
0302                             if (cksum!=cksum_built)
0303                             {
0304                                 UBF_LOG(log_error, "Invalid VIEW [%s] checksum, expected: "
0305                                         "[%ld] got [%ld] - please recompile the "
0306                                         "view file with viewc, line: %ld", 
0307                                         v->vname, cksum_built, cksum, line);
0308                                 ndrx_Bset_error_fmt(BBADVIEW, "Invalid VIEW [%s] "
0309                                         "checksum, expected: "
0310                                         "[%ld] got [%ld] - please recompile the "
0311                                         "view file with viewc, line: %ld", 
0312                                         v->vname, cksum_built, cksum, line);
0313                                 EXFAIL_OUT(ret);
0314                             }
0315                             
0316                             view_cksum_ok = EXTRUE;
0317                         }
0318                        
0319                         /* Ignore others...  */
0320                         
0321                         tok2=strtok_r (NULL,";", &saveptr2);
0322                     }
0323                 }
0324             }
0325             
0326             continue;
0327         }
0328         else if (('\n'==buf[0]) || (('\r'==buf[0]) && ('\n'==buf[1])))
0329         {
0330             /* this is newline, ignore */
0331             continue;
0332         }
0333         else if (EXEOS==buf[0])
0334         {
0335             /* Some strange line? */
0336             continue;
0337         }
0338         
0339         /* Remove trailing white space.. */
0340         ndrx_str_rstrip(buf, NDRX_VIEW_FIELD_SEPERATORS);
0341         
0342         p = buf;
0343         /* Strip off the leading white space */
0344         while (' '==*p || '\t'==*p)
0345         {
0346             p++;
0347         }
0348         
0349         /* tokenize the line  */
0350         if (INFILE==state)
0351         {   
0352             tok = strtok_r(p, NDRX_VIEW_FIELD_SEPERATORS, &saveptr1);
0353             
0354             if (0!=strcmp(tok, NDRX_VIEW_TOKEN_START))
0355             {
0356                 /* Not in view -> FAIL */
0357                 UBF_LOG(log_error, "Expected [%s] but got [%s], line: %ld", 
0358                         NDRX_VIEW_TOKEN_START, tok, line);
0359                 ndrx_Bset_error_fmt(BVFSYNTAX, "Expected [%s] but got [%s], line: %ld", 
0360                         NDRX_VIEW_TOKEN_START, tok, line);
0361                 EXFAIL_OUT(ret);
0362             }
0363 
0364             if (NULL==(tok = strtok_r(NULL, NDRX_VIEW_FIELD_SEPERATORS, &saveptr1)))
0365             {
0366                 UBF_LOG(log_error, "Missing identifier after %s, line: %ld", 
0367                         NDRX_VIEW_TOKEN_START, line);
0368                 ndrx_Bset_error_fmt(BVFSYNTAX, "Missing identifier after %s, line: %ld", 
0369                         NDRX_VIEW_TOKEN_START, line);
0370                 EXFAIL_OUT(ret);
0371             }
0372             
0373             len = strlen(tok);
0374             if (len > NDRX_VIEW_NAME_LEN)
0375             {
0376                 UBF_LOG(log_error, "View identifier [%s] too long! Max len: %d,"
0377                         " but got: %d, line: %ld", 
0378                         tok, NDRX_VIEW_NAME_LEN, len, line);
0379                 ndrx_Bset_error_fmt(BVFSYNTAX, "View identifier [%s] too long!"
0380                         " Max len: %d, but got: %d, line: %ld", 
0381                         tok, NDRX_VIEW_NAME_LEN, len, line);
0382                 EXFAIL_OUT(ret);
0383             }
0384             
0385             /* Got view ok, allocate the object */
0386             v = NDRX_CALLOC(1, sizeof(ndrx_typedview_t));
0387 
0388             if (NULL==v)
0389             {
0390                 int err = errno;
0391                 UBF_LOG(log_error, "Failed to allocate ndrx_typedview_t: %s, "
0392                         "line: %ld", 
0393                         strerror(err), line);
0394 
0395                 ndrx_Bset_error_fmt(BEUNIX, "Failed to allocate "
0396                         "ndrx_typedview_t: %s, line: %ld", 
0397                         strerror(err), line);
0398                 EXFAIL_OUT(ret);    
0399             }
0400             
0401             NDRX_STRCPY_SAFE(v->vname, tok);
0402             /* setup file name too */
0403             NDRX_STRCPY_SAFE(v->filename, fname);
0404             
0405             UBF_LOG(log_debug, "Parsing view [%s]", v->vname);
0406             state = INVIEW;
0407             view_ssize_ok = EXFALSE;
0408             view_cksum_ok = EXFALSE;
0409             
0410         }
0411         else if (INVIEW==state)
0412         {
0413             short typ=EXFAIL;
0414             short typfull=EXFAIL;
0415             
0416             tok = strtok_r(p, NDRX_VIEW_FIELD_SEPERATORS, &saveptr1);
0417             UBF_LOG(log_dump, "Got token [%s]", (NULL==tok?"<NULL>":tok));
0418             
0419             if (0==strcmp(NDRX_VIEW_TOKEN_END, tok))
0420             {
0421                 /* Bug #191 */
0422                 if (is_compiled && (!view_ssize_ok || !view_cksum_ok))
0423                 {
0424                     UBF_LOG(log_error, "Compiled view data not found ssize=%d, cksum=%d, "
0425                         "line: %ld",  view_ssize_ok, view_cksum_ok, line);
0426 
0427                     ndrx_Bset_error_fmt(BBADVIEW, "Compiled view data not found "
0428                             "ssize=%d, cksum=%d, line: %ld",  
0429                             view_ssize_ok, view_cksum_ok, line);
0430                     EXFAIL_OUT(ret);    
0431                 }
0432                 
0433                 UBF_LOG(log_debug, "View [%s] finishing off -> add to hash", 
0434                         v->vname);
0435                 EXHASH_ADD_STR(ndrx_G_view_hash, vname, v);
0436                 v = NULL;
0437                 state = INFILE;
0438                 continue;
0439             }
0440             
0441             /******************************************************************* 
0442              * OK this is the string line... 
0443              * The first is field type name
0444              * Here we might get 'int'. this will be internally stored as long.
0445              *******************************************************************/
0446             dtyp = G_dtype_str_map;
0447             while(EXEOS!=dtyp->fldname[0])
0448             {
0449                 if (0==strcmp(dtyp->fldname, tok) || 
0450                         (dtyp->altname && 0==strcmp(dtyp->altname, tok)))
0451                 {
0452                     typ = dtyp->fld_type;
0453                     break;
0454                 }
0455                 dtyp++;
0456             }
0457             
0458             if (BFLD_INT==typ)
0459             {
0460                 if (0==strcmp(tok, "int"))
0461                 {
0462                     typ = BFLD_LONG; 
0463                     typfull = BFLD_INT;
0464                 }
0465                 else
0466                 {
0467                     UBF_LOG(log_error, "Invalid data type [%s], line: %ld", 
0468                             tok, line);
0469                     ndrx_Bset_error_fmt(BVFSYNTAX, "Invalid data type [%s], line: %ld", 
0470                             tok, line);
0471                     EXFAIL_OUT(ret);
0472                 }
0473             }
0474             else
0475             {
0476                 typfull = typ;
0477             }
0478             
0479             /* Allocate the field block  */
0480             fld = NDRX_CALLOC(1, sizeof(ndrx_typedview_field_t));
0481 
0482             if (NULL==fld)
0483             {
0484                 int err = errno;
0485                 UBF_LOG(log_error, "Failed to allocate ndrx_typedview_field_t: %s,"
0486                         " line: %ld", 
0487                         strerror(err), line);
0488 
0489                 ndrx_Bset_error_fmt(BEUNIX, "Failed to allocate ndrx_typedview_field_t: "
0490                         "%s, line: %ld", 
0491                         strerror(err));
0492                 EXFAIL_OUT(ret);    
0493             }
0494             
0495             fld->typecode = typ;
0496             fld->typecode_full = typfull;
0497             NDRX_STRCPY_SAFE(fld->type_name, tok);
0498             
0499             /* Add type to checksum */
0500             ndrx_view_cksum_update(v, fld->type_name, strlen(fld->type_name));
0501             UBF_LOG(log_dump, "Got type code UBF=%d full code=%d", 
0502                     fld->typecode, fld->typecode_full);
0503             
0504             /******************************************************************* 
0505              * C Field name 
0506              *******************************************************************/
0507             tok = strtok_r(NULL, NDRX_VIEW_FIELD_SEPERATORS, &saveptr1);
0508             UBF_LOG(log_dump, "Got token [%s]", (NULL==tok?"<NULL>":tok));
0509             
0510             if (NULL==tok)
0511             {
0512                 UBF_LOG(log_error, "Expected C field name, got EOS, line: %ld");
0513                 ndrx_Bset_error_fmt(BVFSYNTAX, "Expected C field name, got EOS, "
0514                         "line %ld", line);
0515                 EXFAIL_OUT(ret);
0516             }
0517             
0518             len = strlen(tok);
0519             if (len>NDRX_VIEW_CNAME_LEN)
0520             {
0521                 UBF_LOG(log_error, "C field identifier [%s] too long! Max len: %d,"
0522                         " but got: %d, line: %ld", 
0523                         tok, NDRX_VIEW_CNAME_LEN, len, line);
0524                 
0525                 ndrx_Bset_error_fmt(BVFSYNTAX, "C field identifier [%s] too long!"
0526                         " Max len: %d, but got: %d, line: %ld", 
0527                         tok, NDRX_VIEW_CNAME_LEN, len, line);
0528                 
0529                 EXFAIL_OUT(ret);
0530             }
0531             
0532             /* TODO: Might consider to validate the identifier
0533              * but anyway this will be done by compiler... Thus to save the loading
0534              * time, we will skip this step.
0535              */
0536             NDRX_STRCPY_SAFE(fld->cname, tok);
0537             
0538             /* Add cname to checksum */
0539             ndrx_view_cksum_update(v, fld->cname, strlen(fld->cname));
0540             
0541             UBF_LOG(log_dump, "Got c identifier [%s]", fld->cname);
0542             
0543             /******************************************************************* 
0544              * FB Name -> projection to fielded buffer.
0545              *******************************************************************/
0546             tok = strtok_r(NULL, NDRX_VIEW_FIELD_SEPERATORS, &saveptr1);
0547             UBF_LOG(log_dump, "Got token [%s]", (NULL==tok?"<NULL>":tok));
0548             
0549             if (NULL==tok)
0550             {
0551                 UBF_LOG(log_error, "Expected FB Name field, got EOS, line: %ld", 
0552                         line);
0553                 ndrx_Bset_error_fmt(BVFSYNTAX, "Expected FB Name field, "
0554                         "got EOS, line: %ld", line);
0555                 EXFAIL_OUT(ret);
0556             }
0557             
0558             len = strlen(tok);
0559             if (len>UBFFLDMAX)
0560             {
0561                 UBF_LOG(log_error, "UBF name identifier [%s] too long! Max len: %d,"
0562                         " but got: %d, line: %ld", 
0563                         tok, UBFFLDMAX, len, line);
0564                 
0565                 ndrx_Bset_error_fmt(BVFSYNTAX, "UBF name identifier [%s] too long!"
0566                         " Max len: %d, but got: %d, line: %ld", 
0567                         tok, UBFFLDMAX, len, line);
0568                 
0569                 EXFAIL_OUT(ret);
0570             }
0571             
0572             /* ok, save the field */
0573             NDRX_STRCPY_SAFE(fld->fbname, tok);
0574             UBF_LOG(log_dump, "Got UBF identifier [%s]", fld->fbname);
0575             
0576             /*TODO: add - to defines ... */
0577             if (is_compiled && !M_no_ubf_proc && 0!=strcmp("-", fld->fbname))
0578             {
0579                 UBF_LOG(log_dump, "About to resolve field id..");
0580                 
0581                 fld->ubfid = Bfldid(fld->fbname);
0582                 
0583                 if (BBADFLDID==fld->ubfid)
0584                 {
0585                     UBF_LOG(log_error, "Failed to resolve id for field [%s], line: %ld", 
0586                         fld->fbname, line);
0587                 
0588                     ndrx_Bset_error_fmt(BBADFLD, "Failed to resolve id for "
0589                             "field [%s], line: %ld", 
0590                         fld->fbname, line);
0591 
0592                     EXFAIL_OUT(ret);
0593                 }
0594             }
0595             else
0596             {
0597                 fld->ubfid = BBADFLDID;
0598             }
0599             
0600             /******************************************************************* 
0601              * Parse count...
0602              *******************************************************************/
0603             tok = strtok_r(NULL, NDRX_VIEW_FIELD_SEPERATORS, &saveptr1);
0604             UBF_LOG(log_dump, "Got token [%s]", (NULL==tok?"<NULL>":tok));
0605             fld->count = (short)atoi(tok);
0606             
0607             if (fld->count<1)
0608             {
0609                 UBF_LOG(log_error, "Invalid count: %d (parsed from [%s]), line: %ld", 
0610                         fld->count, tok, line);
0611                 
0612                 ndrx_Bset_error_fmt(BVFSYNTAX, "Invalid count: %d "
0613                         "(parsed from [%s]), line: %ld", 
0614                         fld->count, tok, line);
0615                 
0616                 EXFAIL_OUT(ret);
0617             }
0618             
0619             if (fld->count>NDRX_VIEW_FLD_COUNT_MAX)
0620             {
0621                 UBF_LOG(log_error, "Invalid count: %d (parsed from [%s]) max: %d,"
0622                         " line: %ld", 
0623                         fld->count, tok, NDRX_VIEW_FLD_COUNT_MAX, line);
0624                 
0625                 ndrx_Bset_error_fmt(BVFSYNTAX, "Invalid count: %d (parsed from [%s]) "
0626                         "max: %d, line: %ld", 
0627                         fld->count, tok, NDRX_VIEW_FLD_COUNT_MAX, line);
0628                 
0629                 EXFAIL_OUT(ret);
0630             }
0631 
0632             /* Add count to checksum */
0633             ndrx_view_cksum_update(v, tok, strlen(tok));
0634             
0635             UBF_LOG(log_dump, "Got count [%hd]", fld->count);
0636             
0637             /******************************************************************* 
0638              * Parse flags
0639              *******************************************************************/
0640             tok = strtok_r(NULL, NDRX_VIEW_FIELD_SEPERATORS, &saveptr1);
0641             UBF_LOG(log_dump, "Got token [%s]", (NULL==tok?"<NULL>":tok));
0642             
0643             if (NULL==tok)
0644             {
0645                 UBF_LOG(log_error, "Expected flags, got EOS, line: %ld", 
0646                         line);
0647                 ndrx_Bset_error_fmt(BVFSYNTAX, "Expected flags, got EOS, line: %ld",
0648                         line);
0649                 EXFAIL_OUT(ret);
0650             }
0651             
0652             len = strlen(tok);
0653             if (len>NDRX_VIEW_FLAGS_LEN)
0654             {
0655                 UBF_LOG(log_error, "Flags [%s] too long! Max len: %d,"
0656                         " but got: %d, line: %ld", 
0657                         tok, NDRX_VIEW_FLAGS_LEN, len, line);
0658                 
0659                 ndrx_Bset_error_fmt(BVFSYNTAX, "Flags [%s] too long!"
0660                         " Max len: %d, but got: %d, line: %ld", 
0661                         tok, NDRX_VIEW_FLAGS_LEN, len, line);
0662                 
0663                 EXFAIL_OUT(ret);
0664             }
0665             
0666             /* Decode flags & build binary flags... */
0667             NDRX_STRCPY_SAFE(fld->flagsstr, tok);
0668             
0669             for (i=0; i<len; i++)
0670             {
0671                 switch (tok[i])
0672                 {
0673                     case 'C':
0674                         /* Add element count indicator:
0675                          * C_<field>
0676                          * if C is used, then buffer shall include the number
0677                          * this special field 'short' type to include the element
0678                          * counts transfered from or to buffer. This goes to UBF
0679                          * as the id = field number + 1
0680                          */
0681                         fld->flags|=NDRX_VIEW_FLAG_ELEMCNT_IND_C;
0682                         break;
0683                     case 'F':
0684                         /* One way mapping struct -> to UBF 
0685                          * meaning that transfer the data to target only if dong
0686                          * C->UBF
0687                          */
0688                         fld->flags|=NDRX_VIEW_FLAG_1WAYMAP_C2UBF_F;
0689                         
0690                         if (0==strcmp(fld->fbname, NDRX_VIEW_EMPTY_PARAM))
0691                         {
0692                             ndrx_Bset_error_fmt(BVFSYNTAX, "FB name not set, but "
0693                                     "F flag found, line: %ld", line);
0694                             EXFAIL_OUT(ret);
0695                         }
0696                         
0697                         break;
0698                     case 'L':
0699                         /* Add length indicator
0700                          * L_<field> or L_<field>[N] - in case if count > 0
0701                          * One way mapping struct -> to UBF */
0702                         fld->flags|=NDRX_VIEW_FLAG_LEN_INDICATOR_L;
0703                         
0704                         if (BFLD_STRING != fld->typecode_full && 
0705                                 BFLD_CARRAY != fld->typecode_full)
0706                         {
0707                             ndrx_Bset_error_fmt(BVFSYNTAX, "Flag L not valid for type %s! "
0708                                     "L is valid only for string and carray, on line %ld", 
0709                                     fld->type_name, line);
0710                             EXFAIL_OUT(ret);
0711                         }
0712                         break;
0713                     case 'N':
0714                         /* Zero way mapping */
0715                         fld->flags|=NDRX_VIEW_FLAG_0WAYMAP_N;
0716                         
0717                         break;
0718                     case 'P':
0719                         /* Interpret the NULL value's last char as the filler
0720                          * of the C field trailing.
0721                          */
0722                         fld->flags|=NDRX_VIEW_FLAG_NULLFILLER_P;
0723                         break;
0724                     case 'S':
0725                         /*One way mapping UBF -> C struct
0726                          * If set then transfer data from UBF -> to C at and not
0727                          * vice versa.
0728                          */
0729                         fld->flags|=NDRX_VIEW_FLAG_1WAYMAP_UBF2C_S;
0730                         
0731                         if (0==strcmp(fld->fbname, NDRX_VIEW_EMPTY_PARAM))
0732                         {
0733                             ndrx_Bset_error_fmt(BVFSYNTAX, "FB name not set, but "
0734                                     "S flag found, line: %ld", line);
0735                             EXFAIL_OUT(ret);
0736                         }
0737                         
0738                         break;
0739                     case '-':
0740                         UBF_LOG(log_dump, "No flags set...");
0741                         break;    
0742                     default:
0743                         UBF_LOG(log_error, "Unknown field flag [%c], line: %ld", 
0744                                 tok[i], line);
0745 
0746                         ndrx_Bset_error_fmt(BVFSYNTAX, "Unknown field flag [%c], "
0747                                 "line: %ld", 
0748                                 tok[i], line);
0749 
0750                         EXFAIL_OUT(ret);
0751                         break;
0752                 }
0753             }/* for tok[i] */
0754             
0755             if ((fld->flags & NDRX_VIEW_FLAG_1WAYMAP_C2UBF_F || 
0756                     fld->flags & NDRX_VIEW_FLAG_1WAYMAP_UBF2C_S) && 
0757                     fld->flags & NDRX_VIEW_FLAG_0WAYMAP_N)
0758             {
0759                 ndrx_Bset_error_fmt(BVFSYNTAX, "F & S flags are not compatible with N flag, "
0760                                 "line: %ld", 
0761                                 tok[i], line);
0762                 EXFAIL_OUT(ret);
0763             }
0764             
0765             /* Add flags to checksum */
0766             ndrx_view_cksum_update(v, fld->flagsstr, strlen(fld->flagsstr));
0767 
0768             UBF_LOG(log_dump, "Got flags [%s] -> %lx", fld->flagsstr, fld->flags);
0769             
0770             /******************************************************************* 
0771              * Parse size
0772              *******************************************************************/
0773             tok = strtok_r(NULL, NDRX_VIEW_FIELD_SEPERATORS, &saveptr1);
0774             UBF_LOG(log_dump, "Got token [%s]", (NULL==tok?"<NULL>":tok));
0775             
0776             if (0==strcmp(tok, "-"))
0777             {
0778                 UBF_LOG(log_dump, "Empty token -> no size");
0779                 
0780                 if (fld->typecode==BFLD_CARRAY || fld->typecode==BFLD_STRING)
0781                 {
0782                     UBF_LOG(log_error, "Size must be specified for string or "
0783                             "carray, line: %ld", line);
0784 
0785                     ndrx_Bset_error_fmt(BVFSYNTAX, "Size must be specified for string or "
0786                             "carray, line: %ld", line);
0787 
0788                     EXFAIL_OUT(ret);
0789                 }
0790             }
0791             else
0792             {
0793                 fld->size = (short)atoi(tok);
0794 
0795                 if (fld->size>NDRX_VIEW_FLD_SIZE_MAX)
0796                 {
0797                     UBF_LOG(log_error, "Invalid size: %d (parsed from [%s]) max: %d,"
0798                             " line: %ld", 
0799                             fld->size, tok, NDRX_VIEW_FLD_SIZE_MAX, line);
0800 
0801                     ndrx_Bset_error_fmt(BVFSYNTAX, "Invalid size: %d (parsed from [%s]) "
0802                             "max: %d, line: %ld", 
0803                             fld->size, tok, NDRX_VIEW_FLD_SIZE_MAX, line);
0804 
0805                     EXFAIL_OUT(ret);
0806                 }
0807             }
0808             
0809             /* Add size to checksum */
0810             ndrx_view_cksum_update(v, tok, strlen(tok));
0811             
0812             UBF_LOG(log_dump, "Got size [%hd]", fld->size);
0813             
0814             /******************************************************************* 
0815              * Parse NULL value & the system flags..
0816              *******************************************************************/
0817 
0818             p2 = tok+strlen(tok);
0819             p3 = fld->nullval_bin;
0820             pend = buf + orglen;
0821             was_quotes = EXFALSE;
0822             /*UBF_LOG(log_debug, "p2=%p pend=%p", p2, pend);*/
0823             
0824             /* Search the opening of the data block */
0825             while (p2<pend)
0826             {
0827                 /*UBF_LOG(log_debug, "At: %p testing [%c]", p2, *p2);*/
0828                 
0829                 if (*p2!=EXEOS && *p2!=' ' && *p2!='\t')
0830                 {
0831                     break;
0832                 }
0833                 /*UBF_LOG(log_debug, "At: %p skipping [%c]", p2, *p2);*/
0834                 
0835                 p2++;
0836             }
0837             
0838             /* looks like this function is too big (after this place) for xlC and getting:
0839              * 506-754 (S) The parameter type is not valid for a function of this linkage type
0840              * when using __sync_synchronize() after this place.
0841              * Thus any use of __sync_synchronize() shall be done before this big func, strange.
0842              */
0843             UBF_LOG(log_dump, "At %p value [%c]", p2, *p2);
0844             
0845             if (p2==pend)
0846             {
0847                 UBF_LOG(log_error, "Missing NULL value, line: %ld", 
0848                                 tok[i], line);
0849 
0850                 ndrx_Bset_error_fmt(BVFSYNTAX, "Missing NULL value, line: %ld", 
0851                         tok[i], line);
0852                 EXFAIL_OUT(ret);
0853             }
0854             
0855             /* detect the null value type (if have one..) */
0856             
0857             if (*p2=='\'')
0858             {
0859                 nulltype = NTYPSQUOTE;
0860                 fld->nullval_quotes = NDRX_VIEW_QUOTES_SINGLE;
0861                 p2++;
0862                 null_val_start = p2;
0863             }
0864             else if (*p2=='"')
0865             {
0866                 nulltype = NTYPDQUOTE;
0867                 fld->nullval_quotes = NDRX_VIEW_QUOTES_DOUBLE;
0868                 p2++;
0869                 null_val_start = p2;
0870             }
0871             else
0872             {
0873                 fld->nullval_quotes = NDRX_VIEW_QUOTES_NONE;
0874                 nulltype = NTYPSTD;
0875                 null_val_start = p2;
0876             }
0877             
0878             /* scan for closing element... */
0879             esc_open = EXFALSE;
0880             while (p2<pend)
0881             {
0882                 if (!esc_open && '\\'==*p2)
0883                 {
0884                     esc_open = EXTRUE;
0885                 }
0886                 else if (esc_open)
0887                 {
0888                     /* so previous was escape... */
0889                     switch (*p2)
0890                     {
0891                         case '0':
0892                             *p3='\0';
0893                             break;
0894                         case 'n':
0895                             *p3='\n';
0896                             break;
0897                         case 't':
0898                             *p3='\t';
0899                             break;
0900                         case 'f':
0901                             *p3='\f';
0902                             break;
0903                         case '\\':
0904                             *p3='\\';
0905                             break;
0906                         case '\'':
0907                             *p3='\'';
0908                             break;
0909                         case '"':
0910                             *p3='"';
0911                             break;
0912                         case 'v':
0913                             *p3='\v';
0914                             break;
0915                         default:
0916                             *p3=*p2; /* default unknown chars.. */
0917                             break;   
0918                     }
0919                     p3++;
0920                     fld->nullval_bin_len++;
0921                     esc_open = EXFALSE;
0922                 }
0923                 else if (*p2=='\'' || *p2=='"')
0924                 {
0925                     if (nulltype != NTYPSQUOTE && nulltype != NTYPDQUOTE)
0926                     {
0927                         UBF_LOG(log_error, "Un-escaped quote [%c], line %ld", 
0928                                 *p2, line);
0929 
0930                         ndrx_Bset_error_fmt(BVFSYNTAX, "Un-escaped quote [%c], line %ld", 
0931                                 *p2, line);
0932                         EXFAIL_OUT(ret);
0933                     }
0934                     
0935                     /* this is terminator of our value... */
0936                     *p2=EXEOS;
0937                     NDRX_STRCPY_SAFE(fld->nullval, null_val_start);
0938                     
0939                     nulltype = NTYPNO;
0940                             
0941                     break;
0942                 }
0943                 else if (nulltype != NTYPSQUOTE && nulltype != NTYPDQUOTE &&
0944                         (*p2==' ' || *p2=='\t'))
0945                 {
0946                     UBF_LOG(log_dump, "Terminating non quoted NULL data");
0947                     /* Terminate value here too.. */
0948                     
0949                     *p2=EXEOS;
0950                     NDRX_STRCPY_SAFE(fld->nullval, null_val_start);
0951                     nulltype = NTYPNO;
0952                     break;
0953                     
0954                 }
0955                 else
0956                 {
0957                     fld->nullval_bin_len++;
0958                     *p3=*p2;
0959                     p3++;
0960                 }
0961                 
0962                 p2++;
0963             }
0964             
0965             if (nulltype != NTYPNO)
0966             {
0967                 if (nulltype == NTYPSTD)
0968                 {
0969                     /* we are at the end... (no compiled data) */
0970                     UBF_LOG(log_dump, "At th end, no compiled data");
0971                     *p2 = EXEOS;
0972                     NDRX_STRCPY_SAFE(fld->nullval, null_val_start);
0973                     nulltype = NTYPNO;
0974                     
0975                 }
0976                 else
0977                 {
0978                     UBF_LOG(log_error, "Looks like unclosed quotes for "
0979                             "NULL value, line %ld", line);
0980 
0981                     ndrx_Bset_error_fmt(BVFSYNTAX, "Looks like unclosed quotes for "
0982                             "NULL value, line %ld", line);
0983                     EXFAIL_OUT(ret);
0984                 }
0985             }
0986             
0987             UBF_LOG(log_dump, "Got NULL value [%s]", fld->nullval);
0988             
0989             /* for doubles, etc... parsing! */
0990             fld->nullval_bin[fld->nullval_bin_len]=EXEOS;
0991             
0992             UBF_DUMP(log_dump, "Got binary version of NULL value", fld->nullval_bin,
0993                         fld->nullval_bin_len);
0994                      
0995             if (!fld->nullval_quotes)
0996             {
0997                 if (0==strcmp(fld->nullval, "NONE"))
0998                 {
0999                     fld->nullval_none = EXTRUE;
1000                     UBF_LOG(log_debug, "NONE keyword specified -> no NULL value...");
1001                 }
1002                 else if (0==strcmp(fld->nullval, "-"))
1003                 {
1004                     fld->nullval_bin[0] = EXEOS;
1005                     fld->nullval_bin_len = 1;
1006                     fld->nullval_default = EXTRUE;
1007                     UBF_LOG(log_dump, "Default NULL value used...");
1008                 }
1009             }
1010             
1011             /* Build pre-compile compare value... */
1012             if (fld->nullval_default || fld->nullval_none)
1013             {
1014                 /* These are loaded by calloc:
1015                 fld->nullval_short=0;
1016                 fld->nullval_int=0;
1017                 fld->nullval_long=0;
1018                 fld->nullval_float=0.0;
1019                 fld->nullval_double=0.0;
1020                 */
1021             }
1022             else
1023             {
1024                 switch (fld->typecode_full)
1025                 {
1026                     case BFLD_SHORT:
1027                         fld->nullval_short = (short)atoi(fld->nullval_bin);
1028                         UBF_LOG(log_dump, "nullval_short=%hd (%s)", 
1029                                 fld->nullval_short, fld->nullval_bin);
1030                         break;
1031                     case BFLD_INT:
1032                         fld->nullval_int = atoi(fld->nullval_bin);
1033                         UBF_LOG(log_dump, "nullval_int=%hd (%s)", 
1034                                 fld->nullval_int, fld->nullval_bin);
1035                         break;
1036                     case BFLD_LONG:
1037                         fld->nullval_long = atol(fld->nullval_bin);
1038                         UBF_LOG(log_dump, "nullval_long=%hd (%s)", 
1039                                 fld->nullval_long, fld->nullval_bin);
1040                         break;
1041                     case BFLD_FLOAT:
1042                         fld->nullval_float = (float)atof(fld->nullval_bin);
1043                         UBF_LOG(log_dump, "nullval_float=%f (%s)", 
1044                                 fld->nullval_float, fld->nullval_bin);
1045                         break;
1046                     case BFLD_DOUBLE:
1047                         fld->nullval_double = atof(fld->nullval_bin);
1048                         UBF_LOG(log_dump, "nullval_double=%lf (%s)", 
1049                                 fld->nullval_double, fld->nullval_bin);
1050                         break;
1051                     case BFLD_STRING:
1052                         
1053                         /* needs currently to use count only.. */
1054                         dim_size = fld->size;
1055                         /* -1 for EOS */
1056                         if (dim_size-1 < fld->nullval_bin_len)
1057                         {
1058                             UBF_LOG(log_error, "Invalid NULL length: %d, "
1059                                     "string buffer max with out EOS: %d"
1060                                 ", line %ld", fld->nullval_bin_len, dim_size-1, line);
1061 
1062                             ndrx_Bset_error_fmt(BBADVIEW, "Invalid NULL length: %d, "
1063                                     "string buffer max with out EOS: %d"
1064                                 ", line %ld", fld->nullval_bin_len, dim_size-1, line);
1065                             EXFAIL_OUT(ret);
1066                         }
1067                         break;
1068                     case BFLD_CARRAY:
1069                         dim_size = fld->size;
1070                         
1071                         if (dim_size < fld->nullval_bin_len)
1072                         {
1073                             UBF_LOG(log_error, "Invalid NULL length: %d, "
1074                                     "carray buffer max: %d"
1075                                 ", line %ld", fld->nullval_bin_len, dim_size, line);
1076 
1077                             ndrx_Bset_error_fmt(BBADVIEW, "Invalid NULL length: %d, "
1078                                     "carray buffer max: %d"
1079                                 ", line %ld", fld->nullval_bin_len, dim_size, line);
1080                             EXFAIL_OUT(ret);
1081                         }
1082                         break;
1083                 }
1084             }
1085             
1086             /* Add null value too to the checksum */
1087             ndrx_view_cksum_update(v, fld->nullval, strlen(fld->nullval));
1088             
1089             /******************************************************************* 
1090              * Parse NULL value & the system flags..
1091              *******************************************************************/
1092             
1093             if (p2<pend)
1094             {
1095                 p2++;
1096                 
1097                 tok = strtok_r(p2, NDRX_VIEW_FIELD_SEPERATORS, &saveptr1);
1098                 
1099                 /* Extract compiled data... */
1100                 
1101                 if (NULL==tok)
1102                 {
1103                     if (is_compiled) 
1104                     {
1105                         UBF_LOG(log_error, "Expected compiled data, but not found"
1106                             ", line %ld", line);
1107 
1108                         ndrx_Bset_error_fmt(BBADVIEW, "Expected compiled data, but not found"
1109                             ", line %ld", line);
1110                         EXFAIL_OUT(ret);
1111                     }
1112                     else
1113                     {
1114                         UBF_LOG(log_dump, "No compiled data found at the view file...");
1115                     }
1116                 }
1117                 else
1118                 {
1119                     /* OK we got some token... */
1120                     UBF_LOG(log_dump, "Compiled data: [%s]", tok);
1121                     
1122                     len=strlen(tok);
1123                     
1124                     if (len>NDRX_VIEW_COMPFLAGS_LEN)
1125                     {
1126                         UBF_LOG(log_error, "Compiled data [%s] too long! Max len: %d,"
1127                             " but got: %d, line: %ld", 
1128                             tok, NDRX_VIEW_COMPFLAGS_LEN, len, line);
1129                 
1130                         ndrx_Bset_error_fmt(BBADVIEW, "Compiled data [%s] too long! Max len: %d,"
1131                             " but got: %d, line: %ld", 
1132                             tok, NDRX_VIEW_COMPFLAGS_LEN, len, line);
1133 
1134                         EXFAIL_OUT(ret);
1135                     }
1136                     
1137                     /* ok now extract the data... 
1138                      * Initially we will have a format:
1139                      * <key>=value;..;<key>=<value>
1140                      */
1141                     tok2=strtok_r (tok,";", &saveptr2);
1142                     fld->length_fld_offset=EXFAIL;
1143                     fld->count_fld_offset=EXFAIL;
1144                     while( tok2 != NULL ) 
1145                     {
1146                         int cmplen;
1147                         char *p3;
1148                         /* get the setting... */
1149                         p3 = strchr(tok2, '=');
1150                         cmplen = p3-tok2;
1151 
1152                         if (0==strncmp("offset", tok2, cmplen))
1153                         {
1154                             fld->offset = atol(p3+1);
1155                         }
1156                         else if (0==strncmp("fldsize", tok2, cmplen))
1157                         {
1158                             fld->fldsize = atol(p3+1);
1159                         }
1160                         else if (0==strncmp("loffs", tok2, cmplen))
1161                         {
1162                             fld->length_fld_offset = atol(p3+1);
1163                         }
1164                         else if (0==strncmp("coffs", tok2, cmplen))
1165                         {
1166                             fld->count_fld_offset = atol(p3+1);
1167                         }
1168                         
1169                         /* Ignore others...  */
1170                         
1171                         tok2=strtok_r (NULL,";", &saveptr2);
1172                     }
1173                     
1174                     UBF_LOG(log_dump, "Compiled offset loaded: %ld, element size: %ld", 
1175                             fld->offset, fld->fldsize);
1176                 }
1177                 
1178             }
1179             else if (is_compiled) 
1180             {
1181                 UBF_LOG(log_error, "Expected compiled data, but not found"
1182                     ", line %ld", line);
1183 
1184                 ndrx_Bset_error_fmt(BBADVIEW, "Expected compiled data, but not found"
1185                     ", line %ld", line);
1186                 EXFAIL_OUT(ret);
1187             }
1188             else
1189             {
1190                 UBF_LOG(log_dump, "No compiled data found at the view file...");
1191             }
1192             
1193             /******************************************************************* 
1194              * Finally add field to linked list...
1195              *******************************************************************/
1196             DL_APPEND(v->fields, fld);
1197             
1198             /* Add field to HASH too */
1199             
1200             EXHASH_ADD_STR(v->fields_h, cname, fld);
1201             
1202             fld = NULL;            
1203         }
1204     }
1205     
1206     if (INFILE!=state)
1207     {
1208         UBF_LOG(log_error, "Invalid state [%d] -> VIEW not terminated with "
1209                 "END, line: %ld", state, line);
1210         ndrx_Bset_error_fmt(BVFSYNTAX, "Invalid state [%d] -> VIEW not terminated with "
1211                 "END, line: %ld", state, line);
1212         EXFAIL_OUT(ret);
1213     }
1214     
1215     /* Bug #191 */
1216     if (is_compiled && (!file_platform_ok || !file_arch_ok || !file_wsize_ok))
1217     {
1218         UBF_LOG(log_error, "Compiled view data not found platform=%d "
1219                 "arch=%d wsize=%d, line: %ld",  
1220                 file_platform_ok, file_arch_ok, file_wsize_ok, line);
1221         
1222         ndrx_Bset_error_fmt(BBADVIEW, "Compiled view data not found platform=%d "
1223                 "arch=%d wsize=%d, line: %ld",  
1224                 file_platform_ok, file_arch_ok, file_wsize_ok, line);
1225         
1226         EXFAIL_OUT(ret);    
1227     }
1228     
1229 out:
1230 
1231     UBF_LOG(log_debug, "%s - return %d", __func__, ret);
1232 
1233     if (NULL!=f)
1234     {
1235         NDRX_FCLOSE(f);
1236     }
1237 
1238     /* shall be normally set to NULL in the end */
1239     if (NULL!=v)
1240     {
1241         NDRX_FREE(v);
1242     }
1243 
1244     if (NULL!=fld)
1245     {
1246         NDRX_FREE(fld);
1247     }
1248 
1249     return ret;
1250 }
1251 
1252 /**
1253  * Load directory
1254  * We compare each file to be in the list of the files specified in env variable
1255  * if found then load it...
1256  * @param dir
1257  * @return 
1258  */
1259 expublic int ndrx_view_load_directory(char *dir)
1260 {
1261     int ret = EXSUCCEED;
1262     /* we must expand the env... so that file names would formatted as:
1263      * ;<fielname>;
1264      */
1265     char *env = getenv(CONF_VIEWFILES);
1266     char dup[PATH_MAX+1];
1267     char fname_chk[PATH_MAX+1];
1268     char full_fname[PATH_MAX+1];
1269     int n;
1270     struct dirent **namelist = NULL;
1271     
1272     if (NULL==env)
1273     {
1274         UBF_LOG(log_error, "Missing env [%s]", CONF_VIEWFILES);
1275         ndrx_Bset_error_fmt(BEUNIX, "Missing env [%s]", CONF_VIEWFILES);
1276         EXFAIL_OUT(ret);
1277     }
1278     
1279     if (strlen(env)+2 > PATH_MAX)
1280     {
1281         UBF_LOG(log_error, "Invalid [%s] -> too long, max: %d", 
1282                 CONF_VIEWFILES, PATH_MAX-2);
1283         
1284         ndrx_Bset_error_fmt(BEUNIX, "Invalid [%s] -> too long, max: %d", 
1285                 CONF_VIEWFILES, PATH_MAX-2);
1286         
1287         userlog("Invalid [%s] -> too long, max: %d", 
1288                 CONF_VIEWFILES, PATH_MAX-2);
1289         EXFAIL_OUT(ret);
1290     }
1291     
1292     snprintf(dup, sizeof(dup), ",%s,", env);
1293     
1294     ndrx_str_strip(dup, " \t");
1295    
1296     /* Open dir for scan */
1297     n = scandir(dir, &namelist, 0, alphasort);
1298     if (n < 0)
1299     {
1300         int err = errno;
1301         UBF_LOG(log_error, "Failed to scan view directory [%s]: %s", 
1302                dir, strerror(err));
1303        
1304         ndrx_Bset_error_fmt(BEUNIX, "Failed to scan view directory [%s]: %s", 
1305                dir, strerror(err));
1306        
1307         EXFAIL_OUT(ret);
1308     }
1309         
1310     while (n--)
1311     {
1312         if (0==strcmp(namelist[n]->d_name, ".") || 
1313             0==strcmp(namelist[n]->d_name, ".."))
1314         {
1315             NDRX_FREE(namelist[n]);
1316             continue;
1317         }
1318         
1319         /* Check the file name in list */
1320         snprintf(fname_chk, sizeof(fname_chk), ",%s,", namelist[n]->d_name);
1321         
1322         if (NULL!=strstr(dup, fname_chk))
1323         {
1324             snprintf(full_fname, sizeof(full_fname), "%s/%s", dir, namelist[n]->d_name);
1325             UBF_LOG(log_debug, "File name [%s] accepted for view object load. "
1326                     "full path: [%s]", 
1327                     namelist[n]->d_name, full_fname);
1328             
1329             if (EXSUCCEED!=ndrx_view_load_file(full_fname, EXTRUE))
1330             {
1331                 UBF_LOG(log_error, "Failed to load view object file: [%s]", full_fname);
1332                 EXFAIL_OUT(ret);
1333             }
1334             
1335             UBF_LOG(log_debug, "VIEW [%s] loaded OK.", namelist[n]->d_name);
1336             
1337         }
1338         
1339         NDRX_FREE(namelist[n]);
1340     }
1341 
1342     
1343 out:
1344                             
1345     if (NULL!=namelist)
1346     {
1347         while (n>=0)
1348         {
1349             NDRX_FREE(namelist[n]);
1350             n--;
1351         }
1352         NDRX_FREE(namelist);
1353         namelist = NULL;
1354     }
1355 
1356     return ret;
1357     
1358 }
1359 
1360 /**
1361  * init the views if needed.
1362  * @return EXSUCCEED/EXFAIL
1363  */
1364 expublic int ndrx_view_init(void)
1365 {
1366     int ret = EXSUCCEED;
1367     
1368     if (!M_views_loaded)
1369     {
1370         MUTEX_LOCK_V(M_views_init_lock);
1371         
1372         /* Check so that concurrent process did not load the tables already... */
1373         if (!M_views_loaded)
1374         {
1375             if (NULL==getenv(CONF_VIEWDIR) || NULL==getenv(CONF_VIEWFILES))
1376             {
1377                 UBF_LOG(log_warn, "%s or %s not defined -> Not loading view files...", 
1378                         CONF_VIEWDIR, CONF_VIEWFILES);
1379                 M_views_loaded=EXTRUE; /* Assume init done..., just not views will be found */
1380             }
1381             else
1382             {
1383                 ret = ndrx_view_load_directories();
1384             }
1385         }
1386         
1387         MUTEX_UNLOCK_V(M_views_init_lock);
1388         
1389     }
1390     
1391 out:
1392     return ret;
1393 }
1394 
1395 /**
1396  * Set view field option
1397  * Thread safe.
1398  * @param v resolved view object
1399  * @param f resolved view field object
1400  * @param option B_FTOS/B_STOF/B_OFF/B_BOTH
1401  * @return 
1402  */
1403 expublic int ndrx_Bvopt_int(ndrx_typedview_t *v, ndrx_typedview_field_t *f, int option)
1404 {
1405     int ret = EXSUCCEED;
1406     
1407     MUTEX_LOCK_V(M_view_change_lock);
1408     UBF_LOG(log_debug, "%s: Current flags: [%lx]", __func__, f->flags);
1409     switch (option)
1410     {
1411         case B_FTOS: 
1412             f->flags&=~NDRX_VIEW_FLAG_1WAYMAP_C2UBF_F;
1413             f->flags&=~NDRX_VIEW_FLAG_0WAYMAP_N;
1414             f->flags|=NDRX_VIEW_FLAG_1WAYMAP_UBF2C_S;
1415             break;
1416         case B_STOF:
1417             f->flags&=~NDRX_VIEW_FLAG_0WAYMAP_N;
1418             f->flags&=~NDRX_VIEW_FLAG_1WAYMAP_UBF2C_S;
1419             f->flags|=NDRX_VIEW_FLAG_1WAYMAP_C2UBF_F;
1420             break;
1421         case B_OFF:
1422             f->flags&=~NDRX_VIEW_FLAG_1WAYMAP_UBF2C_S;
1423             f->flags&=~NDRX_VIEW_FLAG_1WAYMAP_C2UBF_F;
1424             f->flags|=NDRX_VIEW_FLAG_0WAYMAP_N;
1425             break;
1426         case B_BOTH:
1427             f->flags&=~NDRX_VIEW_FLAG_0WAYMAP_N;
1428             f->flags|=NDRX_VIEW_FLAG_1WAYMAP_UBF2C_S;
1429             f->flags|=NDRX_VIEW_FLAG_1WAYMAP_C2UBF_F;
1430             break;
1431         default:
1432             ndrx_Bset_error_fmt(BEINVAL, "Invalid option for %s: %d", 
1433                     __func__, option);
1434             EXFAIL_OUT(ret);
1435             break;
1436     }
1437     
1438     UBF_LOG(log_debug, "%s: new flags: [%lx]", __func__, f->flags);
1439     
1440 out:
1441     MUTEX_UNLOCK_V(M_view_change_lock);
1442     return ret;
1443 }
1444 
1445 /**
1446  * Set view option..
1447  * @param cname field name
1448  * @param option option
1449  * @param view view name
1450  * @return EXSUCCEED/EXFAIL
1451  */
1452 expublic int ndrx_Bvopt(char *cname, int option, char *view) 
1453 {
1454     int ret = EXFALSE;
1455     ndrx_typedview_t *v = NULL;
1456     ndrx_typedview_field_t *f = NULL;
1457     
1458     if (NULL==(v = ndrx_view_get_view(view)))
1459     {
1460         ndrx_Bset_error_fmt(BBADVIEW, "View [%s] not found!", view);
1461         EXFAIL_OUT(ret);
1462     }
1463     
1464     if (NULL==(f = ndrx_view_get_field(v, cname)))
1465     {
1466         ndrx_Bset_error_fmt(BNOCNAME, "Field [%s] of view [%s] not found!", 
1467                 cname, v->vname);
1468         EXFAIL_OUT(ret);
1469     }
1470     
1471     if (EXFAIL==(ret=ndrx_Bvopt_int(v, f, option)))
1472     {
1473         /* should not get here.. */
1474         ndrx_Bset_error_fmt(BBADVIEW, "System error occurred.");
1475         goto out;
1476     }
1477     
1478 out:
1479     return ret;
1480 }
1481 
1482 
1483 
1484 /* vim: set ts=4 sw=4 et smartindent: */