Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Common config server
0003  *
0004  * @file cconfsv.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 <stdio.h>
0035 #include <stdlib.h>
0036 #include <string.h>
0037 #include <errno.h>
0038 #include <regex.h>
0039 #include <utlist.h>
0040 
0041 #include <ndebug.h>
0042 #include <atmi.h>
0043 #include <atmi_int.h>
0044 #include <typed_buf.h>
0045 #include <ndrstandard.h>
0046 #include <ubf.h>
0047 #include <Exfields.h>
0048 #include <atmi_shm.h>
0049 
0050 #include "cconfsv.h"
0051 #include "userlog.h"
0052 #include <cconfig.h>
0053 #include <inicfg.h>
0054 #include <nerror.h>
0055 #include <ubfutil.h>
0056 /*---------------------------Externs------------------------------------*/
0057 /*---------------------------Macros-------------------------------------*/
0058 /*---------------------------Enums--------------------------------------*/
0059 /*---------------------------Typedefs-----------------------------------*/
0060 
0061 /**
0062  * Lookup config
0063  */
0064 struct cconf_req
0065 {
0066     char **resources; /* files to lookup, if NULL, then default Enduro/X */
0067     char *lookup_sections; /* section to get */
0068     
0069     char **sectionmask; /* list of section startings to return the values for */
0070     
0071     char cmd;
0072 };
0073 typedef struct cconf_req cconf_req_t;
0074 /*---------------------------Globals------------------------------------*/
0075 /*---------------------------Statics------------------------------------*/
0076 exprivate ndrx_inicfg_t *M_config = NULL;
0077 /*---------------------------Prototypes---------------------------------*/
0078 
0079 /**
0080  * Set the error response
0081  * @param p_ub
0082  * @param code
0083  * @param msg
0084  * @return 
0085  */
0086 exprivate void set_error(UBFH *p_ub, short code, char *msg)
0087 {
0088     Bchg(p_ub, EX_NERROR_CODE, 0, (char *)&code, 0);
0089     Bchg(p_ub, EX_NERROR_MSG, 0, (char *)msg, 0);
0090 }
0091 
0092 /**
0093  * Free data allocated by load_data();
0094  * @param req
0095  */
0096 exprivate void free_data(cconf_req_t *req)
0097 {
0098     int i;
0099     
0100     if (NULL!=req->resources)
0101     {
0102         i = 0;
0103         while (NULL!=req->resources[i])
0104         {
0105             NDRX_FREE(req->resources[i]);
0106             i++;
0107         }
0108         
0109         NDRX_FREE(req->resources);
0110     }
0111     
0112     i = 0;
0113     if (NULL!=req->sectionmask)
0114     {
0115         while (NULL!=req->sectionmask[i])
0116         {
0117             NDRX_FREE(req->sectionmask[i]);
0118             i++;
0119         }
0120         NDRX_FREE(req->sectionmask);
0121     }
0122     
0123     if (NULL!=req->lookup_sections)
0124     {
0125         NDRX_FREE(req->lookup_sections);
0126     }
0127 }
0128 
0129 /**
0130  * Load the request data
0131  * @param p_svc
0132  */
0133 exprivate int load_data(UBFH *p_ub, cconf_req_t *req)
0134 {
0135     int ret = EXSUCCEED;
0136     int i;
0137     int nr_resources = Boccur(p_ub, EX_CC_RESOURCE);
0138     int nr_section_masks = Boccur(p_ub, EX_CC_SECTIONMASK);
0139     char fn[] = "load_data";
0140     
0141     NDRX_LOG(log_debug, "load_data called, resources: %d", nr_resources);
0142     
0143     if (EXSUCCEED!=Bget(p_ub, EX_CC_CMD, 0, &(req->cmd), 0L))
0144     {
0145         req->cmd = NDRX_CCONFIG_CMD_GET;
0146     }
0147     
0148     if (nr_resources>0)
0149     {
0150         req->resources = NDRX_CALLOC(nr_resources+1, sizeof(char *));
0151         if (NULL==req->resources)
0152         {
0153             NDRX_LOG(log_error, "Failed to allocate resources: %s", strerror(errno));
0154             set_error(p_ub, NEMALLOC, "malloc failed for resources");
0155             EXFAIL_OUT(ret);
0156         }
0157         
0158         for (i=0; i<nr_resources; i++)
0159         {
0160             if (NULL==(req->resources[i] = Bgetalloc(p_ub, EX_CC_RESOURCE, i, NULL)))
0161             {
0162                 NDRX_LOG(log_error, "Failed to get EX_CC_RESOURCE[%d]: %s", i, 
0163                         Bstrerror(Berror));
0164                 set_error(p_ub, NESYSTEM, Bstrerror(Berror));
0165                 EXFAIL_OUT(ret);
0166             }
0167         }
0168         NDRX_LOG(log_debug, "Resources loaded ok...");    
0169     }
0170     
0171     if (nr_section_masks>0)
0172     {
0173         req->sectionmask = NDRX_CALLOC(nr_section_masks+1, sizeof(char *));
0174         if (NULL==req->sectionmask)
0175         {
0176             NDRX_LOG(log_error, "Failed to allocate section_masks: %s", strerror(errno));
0177             set_error(p_ub, NEMALLOC, "malloc failed for section_masks");
0178             EXFAIL_OUT(ret);
0179         }
0180         
0181         for (i=0; i<nr_section_masks; i++)
0182         {
0183             if (NULL==(req->sectionmask[i] = Bgetalloc(p_ub, EX_CC_SECTIONMASK, i, NULL)))
0184             {
0185                 NDRX_LOG(log_error, "Failed to get EX_CC_SECTIONMASK[%d]: %s", i, 
0186                         Bstrerror(Berror));
0187                 set_error(p_ub, NESYSTEM, Bstrerror(Berror));
0188                 EXFAIL_OUT(ret);
0189             }
0190         }
0191         NDRX_LOG(log_debug, "Section masks loaded ok...");    
0192     }
0193     
0194     /* Load EX_CC_SECTIONMASK if have */
0195     
0196     if (Bpres(p_ub, EX_CC_LOOKUPSECTION, 0))
0197     {
0198         if (NULL==(req->lookup_sections = Bgetalloc(p_ub, EX_CC_LOOKUPSECTION, 0, NULL)))
0199         {
0200             NDRX_LOG(log_error, "Failed to get EX_CC_LOOKUPSECTION: %s", 
0201                         Bstrerror(Berror));
0202             set_error(p_ub, NESYSTEM, Bstrerror(Berror));
0203             EXFAIL_OUT(ret);
0204         }
0205     }
0206     
0207     NDRX_LOG(log_info, "Request data parsed ok");
0208     
0209     
0210 out:
0211 
0212     NDRX_LOG(log_info, "%s returns  %d", fn, ret);
0213 
0214     return ret;
0215 }
0216 
0217 /**
0218  * Get the config.
0219  * @param p_ub
0220  * @param req
0221  * @return 
0222  */
0223 exprivate int config_get(UBFH *p_ub, cconf_req_t *req)
0224 {
0225     char msg[256];
0226     int ret = EXSUCCEED;
0227     int nr_mand = Boccur(p_ub, EX_CC_MANDATORY);
0228     int nr_formats1 = Boccur(p_ub, EX_CC_FORMAT_KEY);
0229     int nr_formats2 = Boccur(p_ub, EX_CC_FORMAT_FORMAT);
0230     int i;
0231     char *p = NULL;
0232     char *key = NULL;
0233     char *format = NULL;
0234     char *format2 = NULL;
0235     char *p2;
0236     char fmt_code;
0237     int min_len;
0238     int max_len;
0239     int len;
0240     float f;
0241     ndrx_inicfg_section_keyval_t *out = NULL, 
0242             *iter = NULL, 
0243             *iter_tmp = NULL, 
0244             *hash_key = NULL;
0245     
0246     if (nr_formats1!=nr_formats2)
0247     {
0248         NDRX_LOG(log_error, "Invalid format field count: "
0249                 "EX_CC_FORMAT_FIELD = %d but EX_CC_FORMAT_FORMAT = %d",
0250                 nr_formats1, nr_formats2);
0251         set_error(p_ub, NEINVAL, "Invalid EX_CC_FORMAT_FIELD, EX_CC_FORMAT_FORMAT "
0252                 "count, must match.");
0253         EXFAIL_OUT(ret);
0254     }
0255     
0256     /* add any resources */
0257     if (EXSUCCEED!=ndrx_inicfg_get_subsect(M_config, 
0258         req->resources, req->lookup_sections, &out))
0259     {
0260         NDRX_LOG(log_error, "Failed to lookup for [%s]: %s", 
0261                 req->lookup_sections, Nstrerror(Nerror));
0262         set_error(p_ub, NEINVAL, Nstrerror(Nerror));
0263         EXFAIL_OUT(ret);
0264     }
0265     
0266     
0267     /* check mandatory fields */
0268     for (i=0; i<nr_mand; i++)
0269     {
0270         if (NULL!=p)
0271         {
0272             NDRX_FREE(p);
0273         }
0274         
0275         if (NULL!=(p = Bgetalloc(p_ub, EX_CC_MANDATORY, i, NULL)))
0276         {
0277             if (NULL==ndrx_keyval_hash_get(out, p))
0278             {
0279                 snprintf(msg, sizeof(msg), "%s", p);
0280                 set_error(p_ub, NEMANDATORY, msg);
0281                 NDRX_LOG(log_error, "Mandatory key is missing: [%s] in config result", p);
0282                 EXFAIL_OUT(ret);
0283             }
0284         }
0285         else
0286         {
0287             NDRX_LOG(log_error, "Bgetalloc error: %s", Nstrerror(Nerror));
0288             set_error(p_ub, NESYSTEM, Bstrerror(Berror));
0289             EXFAIL_OUT(ret);
0290         }
0291     }
0292     
0293     
0294     /* check for formats */
0295     for (i=0; i<nr_formats1; i++)
0296     {
0297         if (NULL!=key)
0298         {
0299             NDRX_FREE(key);
0300         }
0301         
0302         if (NULL!=format)
0303         {
0304             NDRX_FREE(format);
0305         }
0306         
0307         if (NULL!=format2)
0308         {
0309             NDRX_FREE(format2);
0310         }
0311         
0312         min_len = 0;
0313         max_len = 0;
0314         
0315         if (NULL!=(key = Bgetalloc(p_ub, EX_CC_FORMAT_KEY, i, NULL)) &&
0316                 NULL!=(format = Bgetalloc(p_ub, EX_CC_FORMAT_FORMAT, i, NULL)))
0317         {
0318             fmt_code = format[0];
0319             
0320             if (NULL==(format2 = strdup(format)))
0321             {
0322                 set_error(p_ub, NEMALLOC, strerror(errno));
0323                 NDRX_LOG(log_error, "Failed to strdup format");
0324                 EXFAIL_OUT(ret);
0325             }
0326             
0327             if ('t'!=fmt_code)
0328             {
0329                 /* search for dots */
0330                 p2 = strchr(format, '.');
0331                 
0332                 /* ok there is not MIN */
0333                 if (NULL==p2)
0334                 {
0335                     snprintf(msg, sizeof(msg), "Invalid format code: [%s]", format2);
0336                     set_error(p_ub, NEINVAL, msg);
0337                     NDRX_LOG(log_error, "%s", msg);
0338                     EXFAIL_OUT(ret);
0339                 } 
0340                 else if (p2==(format+1))
0341                 {
0342                     /* In this case next symbol is dot thus no length */
0343                     min_len = 0;
0344                 }
0345                 else
0346                 {
0347                     /* have some len */
0348                     *p2 = EXEOS;
0349                     min_len = atoi(format+1);
0350                 }
0351                 p2++;
0352                 
0353                 /* get out the max */
0354                 if (EXEOS==*p2)
0355                 {
0356                     /* So the first dot was finished with EOS, it is invalid format */
0357                     snprintf(msg, sizeof(msg), "Invalid format code: [%s]", format2);
0358                     set_error(p_ub, NEINVAL, msg);
0359                     NDRX_LOG(log_error, "%s", msg);
0360                     EXFAIL_OUT(ret);
0361                 } 
0362                 else if (NULL==(p2=strrchr(p2, '.')))
0363                 {
0364                     snprintf(msg, sizeof(msg), "Invalid format code: [%s], "
0365                             "missing second dot", format2);
0366                     set_error(p_ub, NEINVAL, msg);
0367                     NDRX_LOG(log_error, "%s", msg);
0368                     EXFAIL_OUT(ret);
0369                 }
0370                 
0371                 p2++;
0372                 
0373                 if (EXEOS==*p2)
0374                 {
0375                     snprintf(msg, sizeof(msg), "Invalid format code: [%s], "
0376                             "missing max len", format2);
0377                     set_error(p_ub, NEINVAL, msg);
0378                     NDRX_LOG(log_error, "%s", msg);
0379                     EXFAIL_OUT(ret);
0380                 }
0381                 
0382                 max_len = atoi(p2);
0383                 
0384                 NDRX_LOG(log_debug, "constructed check: type [%c] min_len [%d] max_len [%d]",
0385                         fmt_code, min_len, max_len);
0386             }
0387             
0388             /* get the field it self */
0389             if (NULL==(hash_key=ndrx_keyval_hash_get(out, key)))
0390             {
0391                 NDRX_LOG(log_debug, "cannot check format for key [%s] - field missing",
0392                             key);
0393                 continue; /* mandatory checks will verify it for existance if needed */
0394             }
0395             
0396             switch (fmt_code)
0397             {
0398                 case 't':
0399                     /* check for boolean */
0400                     if (!('Y' == hash_key->val[0] ||
0401                             'y' == hash_key->val[0] ||
0402                             'T' == hash_key->val[0] ||
0403                             't' == hash_key->val[0] ||
0404                             'N' == hash_key->val[0] ||
0405                             'n' == hash_key->val[0] ||
0406                             'F' == hash_key->val[0] ||
0407                             'f' == hash_key->val[0] ||
0408                             '1' == hash_key->val[0] ||
0409                             '0' == hash_key->val[0]))
0410                     {
0411                         /* invalid value... */
0412                         set_error(p_ub, NEFORMAT, hash_key->key);
0413                         
0414                         NDRX_LOG(log_error, "Format error for key: [%s] (section %s) [%s]", 
0415                                 hash_key->key, hash_key->section, hash_key->val);
0416                         EXFAIL_OUT(ret);
0417                     }
0418                     break;
0419                     
0420                 case 'i':
0421                     if (!ndrx_isint(hash_key->val))
0422                     {
0423                         /* invalid value... */
0424                         set_error(p_ub, NEFORMAT, hash_key->key);
0425                         
0426                         NDRX_LOG(log_error, "Invalid integer: [%s] (section %s) [%s]", 
0427                                 hash_key->key, hash_key->section, hash_key->val);
0428                         EXFAIL_OUT(ret);
0429                     }
0430                 case 'n':
0431                     /* do no break, we want length tests for all of the types... */
0432                     if(sscanf(hash_key->val, "%f", &f) == 0)  //It's a float.
0433                     {
0434                         set_error(p_ub, NEFORMAT, hash_key->key);
0435                         
0436                         NDRX_LOG(log_error, "Invalid floating point value: [%s]"
0437                                 " (section %s) [%s]", 
0438                                 hash_key->key, hash_key->section, hash_key->val);
0439                         EXFAIL_OUT(ret);
0440                     }
0441                 case 's':
0442                     /* if is string, just check the len */
0443                     len = strlen(hash_key->val);
0444                     if (len < min_len || len>max_len)
0445                     {
0446                         set_error(p_ub, NEFORMAT, hash_key->key);
0447                         
0448                         NDRX_LOG(log_error, "Format error for key: [%s] (section %s) "
0449                                 "len: %d min_len: %d max_len: %d", 
0450                                 hash_key->key, hash_key->section, len,
0451                                 min_len, max_len);
0452                         EXFAIL_OUT(ret);
0453                     }
0454                     break;
0455                     
0456                 default:
0457                     /* unsupported check.. */
0458                     snprintf(msg, sizeof(msg), "Invalid check: [%c]", fmt_code);
0459                     set_error(p_ub, NEINVAL, msg);
0460                     NDRX_LOG(log_error, "%s", msg);
0461                     EXFAIL_OUT(ret);
0462                     break;
0463             }
0464         }
0465         else
0466         {
0467             NDRX_LOG(log_error, "Bgetalloc error: %s", Nstrerror(Nerror));
0468             set_error(p_ub, NESYSTEM, Bstrerror(Berror));
0469             EXFAIL_OUT(ret);
0470         }
0471                 
0472     }
0473     
0474     /* load stuff to buffer */ 
0475     EXHASH_ITER(hh, out, iter, iter_tmp)
0476     {
0477         if (EXSUCCEED!=Badd(p_ub, EX_CC_SECTION, iter->section, 0L))
0478         {
0479             NDRX_LOG(log_error, "Failed to set EX_CC_SECTION (section: %s): %s", 
0480                         iter->section, Nstrerror(Nerror));
0481             set_error(p_ub, NEINVAL, Bstrerror(Berror));
0482             EXFAIL_OUT(ret);
0483         }
0484         
0485         if (EXSUCCEED!=Badd(p_ub, EX_CC_KEY, iter->key, 0L))
0486         {
0487             NDRX_LOG(log_error, "Failed to set EX_CC_KEY (key: %s): %s", 
0488                         iter->key, Nstrerror(Nerror));
0489             set_error(p_ub, NEINVAL, Bstrerror(Berror));
0490             EXFAIL_OUT(ret);
0491         }
0492         
0493         if (EXSUCCEED!=Badd(p_ub, EX_CC_VALUE, iter->val, 0L))
0494         {
0495             NDRX_LOG(log_error, "Failed to set EX_CC_VALUE (val: %s): %s", 
0496                         iter->val, Nstrerror(Nerror));
0497             set_error(p_ub, NEINVAL, Bstrerror(Berror));
0498             EXFAIL_OUT(ret);
0499         }
0500     }
0501     
0502 out:
0503     if (NULL!=p)
0504     {
0505         NDRX_FREE(p);
0506     }
0507 
0508     if (NULL!=out)
0509     {
0510         ndrx_keyval_hash_free(out);
0511     }
0512 
0513     if (NULL!=key)
0514     {
0515         NDRX_FREE(key);
0516     }
0517 
0518     if (NULL!=format)
0519     {
0520         NDRX_FREE(format);
0521     }
0522 
0523     if (NULL!=format2)
0524     {
0525         NDRX_FREE(format2);
0526     }
0527 
0528     return ret;
0529 }
0530 
0531 /**
0532  * list th config (this runs in conversational mode)
0533  * @param p_ub
0534  * @param req
0535  * @return 
0536  */
0537 exprivate int config_list(UBFH *p_ub, cconf_req_t *req, int cd)
0538 {
0539     int ret = EXSUCCEED;
0540     ndrx_inicfg_section_t *sections=NULL, *iter=NULL, *iter_tmp=NULL;
0541     ndrx_inicfg_section_keyval_t *key_iter = NULL, *key_iter_tmp = NULL;
0542     long revent;
0543     BFLDID rm_list[] =  {   
0544         EX_CC_SECTION, 
0545         EX_CC_KEY, 
0546         EX_CC_VALUE, 
0547         BBADFLDID
0548     };
0549     
0550     if (EXSUCCEED!=ndrx_inicfg_iterate(M_config, req->resources, 
0551             req->sectionmask, &sections))
0552     {
0553         NDRX_LOG(log_error, "Failed to iterate sections: %s", Nstrerror(Nerror));
0554         set_error(p_ub, NESYSTEM, Nstrerror(Nerror));
0555         EXFAIL_OUT(ret);
0556     }
0557     
0558     EXHASH_ITER(hh, sections, iter, iter_tmp)
0559     {
0560         NDRX_LOG(log_info, "iter: section [%s]", iter->section);
0561         
0562         /* Remove all  EX_CC_SECTION/ EX_CC_KEY/ EX_CC_VALUE from buffer
0563          * so that we list fresh data for each section.
0564          */
0565         if (EXSUCCEED!=Bdelete(p_ub, rm_list))
0566         {
0567             if (Berror!=BNOTPRES)
0568             {
0569                 NDRX_LOG(log_error, "Buffer cleanup failed: %s", Bstrerror(Berror));
0570                 set_error(p_ub, NESYSTEM, Bstrerror(Berror));
0571                 EXFAIL_OUT(ret);
0572             }
0573         }
0574         
0575         EXHASH_ITER(hh, sections->values, key_iter, key_iter_tmp)
0576         {
0577             if (EXSUCCEED!=Badd(p_ub, EX_CC_SECTION, key_iter->section, 0L))
0578             {
0579                 NDRX_LOG(log_error, "Failed to set EX_CC_SECTION (section: %s): %s", 
0580                             key_iter->section, Nstrerror(Nerror));
0581                 set_error(p_ub, NEINVAL, Bstrerror(Berror));
0582                 EXFAIL_OUT(ret);
0583             }
0584 
0585             if (EXSUCCEED!=Badd(p_ub, EX_CC_KEY, key_iter->key, 0L))
0586             {
0587                 NDRX_LOG(log_error, "Failed to set EX_CC_KEY (key: %s): %s", 
0588                             key_iter->key, Nstrerror(Nerror));
0589                 set_error(p_ub, NEINVAL, Bstrerror(Berror));
0590                 EXFAIL_OUT(ret);
0591             }
0592 
0593             if (EXSUCCEED!=Badd(p_ub, EX_CC_VALUE, key_iter->val, 0L))
0594             {
0595                 NDRX_LOG(log_error, "Failed to set EX_CC_VALUE (val: %s): %s", 
0596                             key_iter->val, Nstrerror(Nerror));
0597                 set_error(p_ub, NEINVAL, Bstrerror(Berror));
0598                 EXFAIL_OUT(ret);
0599             }
0600         }
0601         
0602         ndrx_debug_dump_UBF(log_debug, "CCONF listing section", p_ub);
0603         
0604         /* send the stuff way... */
0605         if (EXFAIL == tpsend(cd,
0606                     (char *)p_ub,
0607                     0L,
0608                     0,
0609                     &revent))
0610         {
0611             NDRX_LOG(log_error, "Send data failed [%s] %ld",
0612                                 tpstrerror(tperrno), revent);
0613             set_error(p_ub, NESYSTEM, tpstrerror(tperrno));
0614             EXFAIL_OUT(ret);
0615                 
0616         }
0617         else
0618         {
0619             NDRX_LOG(log_debug,"sent ok");
0620         }
0621 
0622     }
0623     
0624     /* Remove any response (so that we finish cleanly) */
0625     if (EXSUCCEED!=Bdelete(p_ub, rm_list))
0626     {
0627         if (Berror!=BNOTPRES)
0628         {
0629             NDRX_LOG(log_error, "Buffer cleanup failed: %s", Bstrerror(Berror));
0630             set_error(p_ub, NESYSTEM, Bstrerror(Berror));
0631             EXFAIL_OUT(ret);
0632         }
0633     }
0634     
0635 
0636 out:
0637                     
0638     if (NULL!=sections)
0639     {
0640         ndrx_inicfg_sections_free(sections);
0641     }
0642 
0643     return ret;
0644 }
0645 
0646 /**
0647  * Common config server
0648  * 
0649  * @param p_svc
0650  */
0651 void CCONF (TPSVCINFO *p_svc)
0652 {
0653     int ret=EXSUCCEED;
0654     UBFH *p_ub = (UBFH *)p_svc->data;
0655     cconf_req_t req;
0656     char tmp[256];
0657     int i;
0658     /* Common config command */
0659     
0660     /*
0661      * Allocate extra 32KB for config storage.
0662      */
0663     if (NULL==(p_ub = (UBFH *)tprealloc ((char *)p_ub, Bsizeof (p_ub) + 32000)))
0664     {
0665         userlog("buffer realloc failed!");
0666         NDRX_LOG(log_error, "tprealloc failed");
0667         EXFAIL_OUT(ret);
0668     }
0669     
0670     ndrx_debug_dump_UBF(log_debug, "CCONF request buffer", p_ub);
0671     
0672     
0673     memset(&req, 0, sizeof(req));
0674     
0675     if (EXSUCCEED!=load_data(p_ub, &req))
0676     {
0677         NDRX_LOG(log_error, "Request data failed to parse");
0678         EXFAIL_OUT(ret);
0679     }
0680     
0681     /* Add any resources */
0682     NDRX_LOG(log_debug, "Loading any resources (if new)");
0683     if (NULL!=req.resources && NULL!=req.resources[0])
0684     {
0685         i=0;
0686         while (NULL!=req.resources[i])
0687         {
0688             NDRX_LOG(log_debug, "Loading [%s]", req.resources[i]);
0689             /* any section please */
0690             if (EXSUCCEED!=ndrx_inicfg_add(M_config, req.resources[i], NULL))
0691             {
0692                 NDRX_LOG(log_error, "Failed to add resource [%s]: %s", 
0693                         req.resources[i], Nstrerror(Nerror));
0694                 set_error(p_ub, NEINVALINI, Nstrerror(Nerror));
0695                 EXFAIL_OUT(ret);
0696             }
0697             i++;
0698         }
0699     }
0700 
0701     /* refresh config - all sections please */
0702     NDRX_LOG(log_debug, "Refreshing configs...");
0703     if (EXSUCCEED!=ndrx_inicfg_reload(M_config, NULL))
0704     {
0705         NDRX_LOG(log_error, "Refresh failed: %s", Nstrerror(Nerror));
0706         set_error(p_ub, NESYSTEM, Nstrerror(Nerror));
0707         
0708     }
0709     
0710     NDRX_LOG(log_info, "Ready for lookup");
0711     
0712     switch (req.cmd)
0713     {
0714         case NDRX_CCONFIG_CMD_GET:
0715             if (EXSUCCEED!=config_get(p_ub, &req))
0716             {
0717                 NDRX_LOG(log_error, "config_get failed!");
0718                 EXFAIL_OUT(ret);
0719             }
0720             break;
0721         case NDRX_CCONFIG_CMD_LIST:
0722             
0723             if (EXSUCCEED!=config_list(p_ub, &req, p_svc->cd))
0724             {
0725                 NDRX_LOG(log_error, "config_list failed!");
0726                 EXFAIL_OUT(ret);
0727             }
0728             break;
0729         default:
0730             NDRX_LOG(log_error, "Unsupported config command: %c", req.cmd);
0731             snprintf(tmp, sizeof(tmp), "Unsupported config command: %c", req.cmd);
0732             set_error(p_ub, NEINVAL, tmp);
0733             break;
0734     }
0735     
0736 out:
0737     free_data(&req);
0738 
0739     ndrx_debug_dump_UBF(log_debug, "CCONF response buffer", p_ub);
0740 
0741     tpreturn(  ret==EXSUCCEED?TPSUCCESS:TPFAIL,
0742                 0,
0743                 (char *)p_ub,
0744                 0L,
0745                 0L);
0746 }
0747 
0748 /*
0749  * Do initialization
0750  */
0751 int NDRX_INTEGRA(tpsvrinit)(int argc, char **argv)
0752 {
0753     int ret=EXSUCCEED;
0754 
0755     NDRX_LOG(log_debug, "tpsvrinit called");
0756     
0757     if (EXSUCCEED!=ndrx_cconfig_load_general(&M_config))
0758     {
0759         NDRX_LOG(log_error, "Failed to general config (Enduro/X config)!");
0760         EXFAIL_OUT(ret);
0761     }
0762     
0763     if (!M_config)
0764     {
0765         NDRX_LOG(log_error, "CCONFIG must be set in order to run cconfsrv");
0766         EXFAIL_OUT(ret);   
0767     }
0768     
0769     if (EXSUCCEED!=tpadvertise(NDRX_SVC_CCONF, CCONF))
0770     {
0771         NDRX_LOG(log_error, "Failed to initialize CCONF!");
0772         EXFAIL_OUT(ret);
0773     }
0774     
0775     
0776 out:
0777     return ret;
0778 }
0779 
0780 /**
0781  * Finish off the processing
0782  */
0783 void NDRX_INTEGRA(tpsvrdone) (void)
0784 {
0785     if (NULL!=M_config)
0786     {
0787         ndrx_inicfg_free(M_config);
0788     }
0789 }
0790 
0791 /* vim: set ts=4 sw=4 et smartindent: */