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 #include <ndrx_config.h>
0039 #include <stdio.h>
0040 #include <stdlib.h>
0041 #include <time.h>
0042 #include <fcntl.h>
0043 
0044 #include <unistd.h>
0045 #include <stdarg.h>
0046 #include <ctype.h>
0047 #include <memory.h>
0048 #include <errno.h>
0049 #include <signal.h>
0050 #include <limits.h>
0051 #include <pthread.h>
0052 #include <string.h>
0053 
0054 #include <sys/time.h>                   /* purely for dbg_timer()       */
0055 #include <sys/stat.h>
0056 #include <ndrstandard.h>
0057 #include <ndebug.h>
0058 #include <nstdutil.h>
0059 #include <limits.h>
0060 #include <sys_unix.h>
0061 #include <cconfig.h>
0062 #include <nstd_int.h>
0063 #include "nstd_tls.h"
0064 #include "userlog.h"
0065 #include "utlist.h"
0066 #include <expluginbase.h>
0067 #include <sys_test.h>
0068 #include <lcfint.h>
0069 #include <exregex.h>
0070 
0071 
0072 
0073 #define BUFFER_CONTROL(dbg_p)\
0074     dbg_p->lines_written++;\
0075     if (dbg_p->lines_written >= dbg_p->buf_lines)\
0076     {\
0077         dbg_p->lines_written = 0;\
0078         fflush( ((ndrx_debug_file_sink_t*)dbg_p->dbg_f_ptr)->fp);\
0079     }
0080 
0081 #define BUFFERED_PRINT_LINE(dbg_p, line)\
0082     fputs(line, ((ndrx_debug_file_sink_t*)dbg_p->dbg_f_ptr)->fp);\
0083     fputs("\n", ((ndrx_debug_file_sink_t*)dbg_p->dbg_f_ptr)->fp);\
0084     BUFFER_CONTROL(dbg_p)
0085 
0086 
0087 #define DEFAULT_BUFFER_SIZE         50000
0088 
0089 
0090 
0091 
0092 #define DEBUG_INITIALIZER(CODE, MODULE, FLAGS)   \
0093 {\
0094     .level = 0,\
0095     .dbg_f_ptr = NULL,\
0096     .filename = "",\
0097     .filename_th_template="",\
0098     .pid = 0,\
0099     .buf_lines = 0,\
0100     .buffer_size = 0,\
0101     .lines_written = 0,\
0102     .module=MODULE,\
0103     .is_user=0,\
0104     .code=CODE,\
0105     .iflags="",\
0106     .is_threaded=0,\
0107     .threadnr=0,\
0108     .flags=FLAGS,\
0109     .memlog=NULL,\
0110     .hostnamecrc32=0x0,\
0111     .swait=NDRX_LOG_SWAIT_DEFAULT,\
0112     .version=0\
0113 }
0114 
0115 
0116 
0117 
0118 
0119 
0120 
0121 typedef struct
0122 {
0123     char *binname;  
0124     char *dbgstr;  
0125     EX_hash_handle hh; 
0126 
0127 } ndrx_debug_rebins_t;
0128 
0129 
0130 ndrx_debug_t G_ubf_debug = DEBUG_INITIALIZER(LOG_CODE_UBF, "UBF ", (LOG_FACILITY_UBF|LOG_FACILITY_PROCESS));
0131 ndrx_debug_t G_ndrx_debug = DEBUG_INITIALIZER(LOG_CODE_NDRX, "NDRX", (LOG_FACILITY_NDRX|LOG_FACILITY_PROCESS));
0132 ndrx_debug_t G_tp_debug = DEBUG_INITIALIZER(LOG_CODE_TP, "USER", (LOG_FACILITY_TP|LOG_FACILITY_PROCESS));
0133 
0134 ndrx_debug_t G_stdout_debug;
0135 
0136 volatile int G_ndrx_debug_first = EXTRUE;
0137 volatile unsigned M_thread_nr = 0;
0138 exprivate int __thread M_is_initlock_owner = 0; 
0139 exprivate MUTEX_LOCKDECL(M_dbglock);
0140 exprivate MUTEX_LOCKDECL(M_thread_nr_lock);
0141 exprivate MUTEX_LOCKDECL(M_memlog_lock);
0142 
0143 
0144 exprivate ndrx_debug_rebins_t *M_rebins = NULL; 
0145 
0146 
0147 
0148 
0149 
0150 expublic void ndrx_init_fail_banner(void)
0151 {
0152     
0153     fprintf(stderr, "********************************************************************************\n");
0154     fprintf(stderr, "**                         CONFIGURATION ERROR !                              **\n");
0155     fprintf(stderr, "**                         ... now worry                                      **\n");
0156     fprintf(stderr, "**                                                                            **\n");
0157     fprintf(stderr, "** Enduro/X Application server is not in proper environment or not configured **\n");
0158     fprintf(stderr, "**                                                                            **\n");
0159     fprintf(stderr, "** Possible causes:                                                           **\n");
0160     fprintf(stderr, "** - Classical environment variables are not loaded (see ex_env(5) man page)  **\n");
0161     fprintf(stderr, "** - Or Common-Config NDRX_CCONFIG env variable is not set                    **\n");
0162     fprintf(stderr, "** See \"Getting Started Tutorial\" in order to get system up-and-running       **\n");
0163     fprintf(stderr, "** More info can be found here http://www.endurox.org/dokuwiki                **\n");
0164     fprintf(stderr, "**                                                                            **\n");
0165     fprintf(stderr, "** Process is now terminating with failure                                    **\n");
0166     fprintf(stderr, "********************************************************************************\n");
0167     exit(EXFAIL);
0168 }
0169 
0170 
0171 
0172 
0173 
0174 exprivate void ndrx_dbg_reply_memlog(ndrx_debug_t *dbg)
0175 {
0176     ndrx_memlogger_t *line, *tmp;
0177     
0178     
0179 
0180 
0181     DL_FOREACH_SAFE(dbg->memlog, line, tmp)
0182     {
0183         
0184         if (line->level <= dbg->level)
0185         {
0186             BUFFERED_PRINT_LINE(dbg, line->line)
0187         }
0188         
0189         DL_DELETE(dbg->memlog, line);
0190         NDRX_FREE(line);
0191     }
0192 }
0193 
0194 
0195 
0196 
0197 expublic void ndrx_dbg_reply_memlog_all(void)
0198 {
0199     
0200 
0201     NDRX_DBG_INIT_ENTRY;
0202     MUTEX_LOCK_V(M_memlog_lock);
0203 
0204     if (NULL!=G_ubf_debug.memlog)
0205     {
0206         ndrx_dbg_reply_memlog(&G_ubf_debug);
0207     }
0208 
0209     if (NULL!=G_ndrx_debug.memlog)
0210     {
0211         ndrx_dbg_reply_memlog(&G_ndrx_debug);
0212     }
0213 
0214     if (NULL!=G_tp_debug.memlog)
0215     {
0216         ndrx_dbg_reply_memlog(&G_tp_debug);
0217     }
0218     MUTEX_UNLOCK_V(M_memlog_lock);
0219 }
0220 
0221 
0222 
0223 
0224 
0225 expublic int ndrx_dbg_intlock_isset(void)
0226 {
0227     return M_is_initlock_owner;
0228 }
0229 
0230 
0231 
0232 
0233 expublic void ndrx_dbg_intlock_set(void)
0234 {   
0235     M_is_initlock_owner++;
0236 }
0237 
0238 
0239 
0240 
0241 
0242 expublic void ndrx_dbg_intlock_unset(int *do_reply)
0243 {   
0244     M_is_initlock_owner--;
0245     
0246     if (M_is_initlock_owner < 0)
0247     {
0248         M_is_initlock_owner = 0;
0249     }
0250     
0251     
0252 
0253 
0254 
0255 
0256 
0257     if (0==M_is_initlock_owner)
0258     {  
0259         *do_reply=EXTRUE;
0260     }
0261 }
0262 
0263 
0264 
0265 
0266 
0267 expublic void ndrx_dbg_setthread(long threadnr)
0268 {
0269     NSTD_TLS_ENTRY;
0270     G_nstd_tls->M_threadnr = threadnr;
0271 }
0272 
0273 
0274 
0275 
0276 expublic void ndrx_dbg_lock(void)
0277 {
0278     MUTEX_LOCK_V(M_dbglock);
0279 }
0280 
0281 
0282 
0283 
0284 expublic void ndrx_dbg_unlock(void)
0285 {
0286     MUTEX_UNLOCK_V(M_dbglock);
0287 }
0288 
0289 
0290 
0291 
0292 expublic void ndrx_dbg_pid_update(void)
0293 {
0294     G_tp_debug.pid = G_ubf_debug.pid = G_ndrx_debug.pid = G_stdout_debug.pid = getpid();
0295 }
0296 
0297 
0298 
0299 
0300 
0301 
0302 
0303 exprivate ndrx_debug_t * get_debug_ptr(ndrx_debug_t *dbg_ptr)
0304 {
0305     static __thread int recursive = EXFALSE;
0306     long flags = 0;
0307     char new_file[PATH_MAX];
0308     
0309     if (NULL!=G_nstd_tls && !recursive)
0310     {
0311         if ( (LOG_THREADED_TEMPL & dbg_ptr->is_threaded) &&
0312                 (( 
0313                   ((dbg_ptr->flags & LOG_FACILITY_NDRX)
0314                         
0315                         && (flags = LOG_FACILITY_NDRX_THREAD)
0316                         && NULL==G_nstd_tls->threadlog_ndrx.dbg_f_ptr ) ||
0317                   ((dbg_ptr->flags & LOG_FACILITY_UBF) 
0318                         
0319                         && (flags = LOG_FACILITY_UBF_THREAD)
0320                         && NULL==G_nstd_tls->threadlog_ubf.dbg_f_ptr) ||
0321                   ((dbg_ptr->flags & LOG_FACILITY_TP)
0322                          
0323                         && (flags = LOG_FACILITY_TP_THREAD)
0324                         && NULL==G_nstd_tls->threadlog_tp.dbg_f_ptr )
0325                 ) || (G_nstd_tls->M_threadnr_logopen != G_nstd_tls->M_threadnr)
0326                 )
0327             )
0328         {
0329             
0330             snprintf(new_file, sizeof(new_file), dbg_ptr->filename_th_template, 
0331                     (unsigned)G_nstd_tls->M_threadnr);
0332             
0333             
0334             G_nstd_tls->M_threadnr_logopen = G_nstd_tls->M_threadnr;
0335             
0336             recursive = EXTRUE; 
0337             
0338             if (EXFAIL==tplogconfig(flags, 
0339                     dbg_ptr->level, NULL, dbg_ptr->module, new_file))
0340             {
0341                 userlog("Failed to configure thread based logger for thread %d file %s: %s",
0342                         G_nstd_tls->M_threadnr, new_file, Nstrerror(Nerror));
0343             }
0344             
0345             recursive = EXFALSE; 
0346             
0347         }
0348 
0349 
0350 
0351 
0352 #define SYNC_LEVELS(X, Y) if (X.version!=Y.version)\
0353                 {\
0354                     X.version = Y.version;\
0355                     X.level = Y.level;\
0356                 }
0357         
0358         if (NULL!=G_nstd_tls && !recursive)
0359         {
0360             if (dbg_ptr == &G_tp_debug && NULL!=G_nstd_tls->requestlog_tp.dbg_f_ptr)
0361             {
0362                 SYNC_LEVELS(G_nstd_tls->requestlog_tp, G_tp_debug);
0363                 return &G_nstd_tls->requestlog_tp;
0364             }
0365             else if (dbg_ptr == &G_tp_debug && NULL!=G_nstd_tls->threadlog_tp.dbg_f_ptr)
0366             {
0367                 SYNC_LEVELS(G_nstd_tls->threadlog_tp, G_tp_debug);
0368                 return &G_nstd_tls->threadlog_tp;
0369             }
0370             else if (dbg_ptr == &G_ndrx_debug && NULL!=G_nstd_tls->requestlog_ndrx.dbg_f_ptr)
0371             {
0372                 SYNC_LEVELS(G_nstd_tls->requestlog_ndrx, G_ndrx_debug);
0373                 return &G_nstd_tls->requestlog_ndrx;
0374             }
0375             else if (dbg_ptr == &G_ndrx_debug && NULL!=G_nstd_tls->threadlog_ndrx.dbg_f_ptr)
0376             {
0377                 SYNC_LEVELS(G_nstd_tls->threadlog_ndrx, G_ndrx_debug);
0378                 return &G_nstd_tls->threadlog_ndrx;
0379             }
0380             else if (dbg_ptr == &G_ubf_debug && NULL!=G_nstd_tls->requestlog_ubf.dbg_f_ptr)
0381             {
0382                 SYNC_LEVELS(G_nstd_tls->requestlog_ubf, G_ubf_debug);
0383                 return &G_nstd_tls->requestlog_ubf;
0384             }
0385             else if (dbg_ptr == &G_ubf_debug && NULL!=G_nstd_tls->threadlog_ubf.dbg_f_ptr)
0386             {
0387                 SYNC_LEVELS(G_nstd_tls->threadlog_ubf, G_ubf_debug);
0388                 return &G_nstd_tls->threadlog_ubf;
0389             }
0390         }
0391     }
0392     
0393     return dbg_ptr;
0394 }
0395 
0396 
0397 
0398 
0399 
0400 
0401 exprivate int ndrx_dbg_rebins_load(char *binlist)
0402 {
0403     int ret = EXSUCCEED;
0404     ndrx_stdcfgstr_t* parsed2=NULL, *el2;
0405     
0406     
0407 
0408 
0409     if (EXSUCCEED!=ndrx_stdcfgstr_parse(binlist, &parsed2))
0410     {
0411         userlog("Failed to parse rebins [%s]", binlist);
0412         EXFAIL_OUT(ret);
0413     }
0414 
0415     DL_FOREACH(parsed2, el2)
0416     {
0417         ndrx_debug_rebins_t *tmp=NULL;
0418 
0419         
0420 
0421 
0422         EXHASH_FIND_STR(M_rebins, el2->key, tmp);
0423         if (NULL==tmp)
0424         {
0425             ndrx_debug_rebins_t *tmp = NDRX_FPMALLOC(sizeof(ndrx_debug_rebins_t), 0);
0426             
0427             if (NULL==tmp)
0428             {
0429                 userlog("Failed to malloc ndrx_debug_rebins_t: %s", strerror(errno));
0430                 EXFAIL_OUT(ret);
0431             }
0432                 
0433             memset(tmp, 0, sizeof(*tmp));
0434 
0435             if (NULL==(tmp->binname = NDRX_STRDUP(el2->key)))
0436             {
0437                 userlog("Failed to malloc binname for rebins: %s", strerror(errno));
0438                 EXFAIL_OUT(ret);
0439             }
0440 
0441             
0442             EXHASH_ADD_KEYPTR(hh, M_rebins, tmp->binname, 
0443                     strlen(tmp->binname), tmp);
0444         }
0445     }
0446 out:
0447     
0448     if (NULL!=parsed2)
0449     {
0450         ndrx_stdcfgstr_free(parsed2);
0451     }
0452 
0453     return ret;
0454 }
0455 
0456 
0457 
0458 
0459 
0460 
0461 
0462 
0463 
0464 exprivate int ndrx_dbg_rebins_chkaddcfg(char *name, char *dbgstr)
0465 {
0466     int ret = EXSUCCEED;
0467     ndrx_debug_rebins_t *re_tmp=NULL;
0468     
0469     
0470 
0471 
0472     EXHASH_FIND_STR(M_rebins, name, re_tmp);
0473 
0474     if (NULL!=re_tmp)
0475     {
0476        
0477        re_tmp->dbgstr = NDRX_STRDUP(dbgstr);
0478 
0479        if (NULL==re_tmp->dbgstr)
0480        {
0481            userlog("Failed to strdup: %s", strerror(errno));
0482            EXFAIL_OUT(ret);
0483        }
0484     }
0485     
0486 out:
0487     return ret;
0488 }
0489 
0490 
0491 
0492 
0493 
0494 
0495 exprivate int ndrx_dbg_rebins_scancfg(ndrx_inicfg_section_keyval_t *conf)
0496 {
0497     int ret = EXSUCCEED;
0498     ndrx_inicfg_section_keyval_t *cc;
0499     ndrx_debug_rebins_t *el, *elt;
0500     
0501     EXHASH_ITER(hh, M_rebins, el, elt)
0502     {
0503         if (NULL!=(cc=ndrx_keyval_hash_get(conf, el->binname)))
0504         {
0505             el->dbgstr = NDRX_STRDUP(cc->val);
0506 
0507             if (NULL==el->dbgstr)
0508             {
0509                 userlog("Failed to strdup: %s", strerror(errno));
0510                 EXFAIL_OUT(ret);
0511             }
0512         }
0513     }
0514     
0515 out:
0516     return ret;
0517 }
0518 
0519 
0520 
0521 
0522 
0523 
0524 
0525 
0526 exprivate int ndrx_dbg_rebins_apply(char *name, char *tmpfname, size_t tmpfnamesz)
0527 {
0528     ndrx_debug_rebins_t *el, *elt;
0529     
0530     EXHASH_ITER(hh, M_rebins, el, elt)
0531     {
0532         int do_match;
0533         
0534         
0535         if (NULL!=el->dbgstr && EXSUCCEED==ndrx_init_parse_line(el->dbgstr, NULL,  
0536                 tmpfname, tmpfnamesz, &do_match, name))
0537         {
0538             if (EXTRUE==do_match)
0539             {
0540                 return EXTRUE;
0541             }
0542         }
0543     }
0544     
0545     return EXFALSE;
0546 }
0547 
0548 
0549 
0550 
0551 exprivate void ndrx_dbg_rebins_free(void)
0552 {
0553     ndrx_debug_rebins_t *el, *elt;
0554     
0555     EXHASH_ITER(hh, M_rebins, el, elt)
0556     {
0557         EXHASH_DEL(M_rebins, el);
0558         
0559         if (NULL!=el->binname)
0560         {
0561             NDRX_FREE(el->binname);
0562         }
0563         
0564         if (NULL!=el->dbgstr)
0565         {
0566             NDRX_FREE(el->dbgstr);
0567         }
0568         
0569         NDRX_FPFREE(el);
0570     }
0571 }
0572 
0573 
0574 
0575 
0576 
0577 
0578 
0579 
0580 
0581 
0582 
0583 
0584 
0585 
0586 
0587 expublic int ndrx_init_parse_line(const char *dbgstr, ndrx_debug_t *dbg_ptr, 
0588         char *tmpfname, size_t tmpfnamesz, int *do_match, char *match_nm)
0589 {
0590     int ret = EXSUCCEED;
0591     
0592     ndrx_stdcfgstr_t* parsed=NULL, *el;    
0593     ndrx_debug_t *tmp_ptr;
0594 
0595     
0596     if (EXSUCCEED!=ndrx_stdcfgstr_parse(dbgstr, &parsed))
0597     {
0598         userlog("Failed to parse debug string [%s]", dbgstr);
0599         EXFAIL_OUT(ret);
0600     }
0601     
0602     if (NULL!=do_match)
0603     {
0604         *do_match=EXFALSE;
0605         
0606         
0607         DL_FOREACH(parsed, el)
0608         {
0609             if (0==strcmp(el->key, "match"))
0610             {
0611                 if (NULL==el->value)
0612                 {
0613                     userlog("Invalid debug string [%s] missing value for key [%s]", 
0614                             dbgstr, el->key);
0615                 }
0616                 else if (EXSUCCEED==ndrx_regqexec(el->value, match_nm))
0617                 {
0618                     
0619                     *do_match=EXTRUE;
0620                     break;
0621                 }
0622                 
0623                 goto out;
0624             }
0625         }
0626     } 
0627 
0628     DL_FOREACH(parsed, el)
0629     {
0630         if (NULL==el->value)
0631         {
0632             userlog("Invalid debug string [%s] missing value for key [%s]", 
0633                     dbgstr, el->key);
0634         }
0635         else if (0==strcmp("ndrx", el->key))
0636         {
0637             int lev = atoi(el->value);
0638 
0639             if (NULL!=dbg_ptr)
0640             {
0641                 if ( (dbg_ptr->flags & LOG_FACILITY_NDRX) ||
0642                         (dbg_ptr->flags & LOG_FACILITY_NDRX_THREAD) ||
0643                         (dbg_ptr->flags & LOG_FACILITY_NDRX_REQUEST) )
0644                 {
0645                     dbg_ptr->level = lev;
0646                 }
0647             }
0648             else
0649             {
0650                 G_ndrx_debug.level = lev;
0651             }
0652         }
0653         else if (0==strcmp("ubf", el->key))
0654         {
0655             int lev = atoi(el->value);
0656 
0657             if (NULL!=dbg_ptr)
0658             {
0659                 if ( (dbg_ptr->flags & LOG_FACILITY_UBF) ||
0660                         (dbg_ptr->flags & LOG_FACILITY_UBF_THREAD) ||
0661                         (dbg_ptr->flags & LOG_FACILITY_UBF_REQUEST) )
0662                 {
0663                     dbg_ptr->level = lev;
0664                 }
0665             }
0666             else
0667             {
0668                 G_ubf_debug.level = lev;
0669             }
0670 
0671         }
0672         else if (0==strcmp("tp", el->key))
0673         {
0674             int lev = atoi(el->value);
0675 
0676             if (NULL!=dbg_ptr)
0677             {
0678                 if ( (dbg_ptr->flags & LOG_FACILITY_TP) ||
0679                         (dbg_ptr->flags & LOG_FACILITY_TP_THREAD) ||
0680                         (dbg_ptr->flags & LOG_FACILITY_TP_REQUEST) )
0681                 {
0682                     dbg_ptr->level = lev;
0683                 }
0684             }
0685             else
0686             {
0687                 G_tp_debug.level = lev;
0688             }
0689         }
0690         else if (0==strcmp("iflags", el->key))
0691         {
0692             
0693 
0694             
0695 
0696             NDRX_STRCPY_SAFE(G_ndrx_debug.iflags, el->value);
0697             NDRX_STRCPY_SAFE(G_ubf_debug.iflags, el->value);
0698             NDRX_STRCPY_SAFE(G_tp_debug.iflags, el->value);
0699         }
0700         else if (0==strcmp("lines", el->key))
0701         {
0702             int lines = atoi(el->value);
0703 
0704             if (lines < 0)
0705             {
0706                 lines = 0;
0707             }
0708 
0709             if (NULL!=dbg_ptr)
0710             {
0711                 dbg_ptr->buf_lines = lines;
0712             }
0713             else
0714             {
0715                 G_tp_debug.buf_lines = 
0716                         G_ndrx_debug.buf_lines = 
0717                         G_ubf_debug.buf_lines = lines;
0718             }
0719         }
0720         else if (0==strcmp("bufsz", el->key))
0721         {
0722             int bufsz = atoi(el->value);
0723 
0724             if (bufsz<=0)
0725             {
0726                 bufsz = DEFAULT_BUFFER_SIZE;
0727             }
0728 
0729             if (NULL!=dbg_ptr)
0730             {
0731                 dbg_ptr->buffer_size = bufsz;
0732             }
0733             else
0734             {
0735                 G_tp_debug.buffer_size = 
0736                         G_ndrx_debug.buffer_size = 
0737                         G_ubf_debug.buffer_size = bufsz;
0738             }
0739         }
0740         else if (0==strcmp("file", el->key))
0741         {
0742             NDRX_STRCPY_SAFE_DST(tmpfname, el->value, tmpfnamesz);
0743         } 
0744         else if (0==strcmp("threaded", el->key))
0745         {
0746             int val = 0;
0747 
0748             if (el->value[0] == 'Y' || el->value[0] == 'y')
0749             {
0750                 val = LOG_THREADED_TEMPL;
0751             }
0752             else if (el->value[0] == 'L' || el->value[0] == 'l')
0753             {
0754                 val = LOG_THREADED_LINEL;
0755             }
0756 
0757             if (NULL!=dbg_ptr)
0758             {
0759                 dbg_ptr->is_threaded = val;
0760             }
0761             else
0762             {
0763                 G_tp_debug.is_threaded = val;
0764                 G_ubf_debug.is_threaded = val;
0765                 G_ndrx_debug.is_threaded = val;
0766             }
0767         }
0768         else if (0==strcmp("mkdir", el->key))
0769         {
0770             int val = EXFALSE;
0771 
0772             if (el->value[0] == 'Y' || el->value[0] == 'y')
0773             {
0774                 val = EXTRUE;
0775             }
0776 
0777             if (NULL!=dbg_ptr)
0778             {
0779                 dbg_ptr->is_mkdir = val;
0780             }
0781             else
0782             {
0783                 G_tp_debug.is_mkdir = val;
0784                 G_ubf_debug.is_mkdir = val;
0785                 G_ndrx_debug.is_mkdir = val;
0786             }
0787         }
0788         else if (0==strcmp("rebins", el->key))
0789         {
0790             if (EXSUCCEED!=ndrx_dbg_rebins_load(el->value))
0791             {
0792                 EXFAIL_OUT(ret);
0793             }
0794         } 
0795     } 
0796 
0797     ndrx_str_env_subs_len(tmpfname, tmpfnamesz);
0798     
0799     if (NULL!=dbg_ptr)
0800     {
0801         tmp_ptr = dbg_ptr;
0802     }
0803     else
0804     {
0805         tmp_ptr = &G_ndrx_debug;
0806     }
0807 
0808     
0809 
0810 
0811     if ((tmp_ptr->is_threaded & LOG_THREADED_TEMPL) && EXEOS!=tmpfname[0])
0812     {
0813         int len;
0814         int len2;
0815         char *p;
0816         
0817         len2 = 3; 
0818         
0819         
0820 
0821 
0822         if (strchr(tmpfname, '%'))
0823         {
0824             
0825 
0826 
0827 
0828 
0829             ndrx_str_fmtesc(tmp_ptr->filename_th_template,
0830                     sizeof(tmp_ptr->filename_th_template), tmpfname);
0831         }
0832         else
0833         {
0834             NDRX_STRCPY_SAFE(tmp_ptr->filename_th_template, tmpfname);
0835         }
0836         
0837         len = strlen(tmp_ptr->filename_th_template);
0838         
0839         
0840         if (len+len2+1 <= tmpfnamesz)
0841         {
0842             
0843             if (NULL!=(p = strrchr(tmp_ptr->filename_th_template, '.')))
0844             {
0845                 
0846         
0847                 memmove(p+len2, p, strlen(p)+1);
0848                 NDRX_STRNCPY(p, ".%u", len2);
0849             }
0850             else
0851             {
0852                 
0853                 NDRX_STRCAT_S(tmp_ptr->filename_th_template, 
0854                         sizeof(tmp_ptr->filename_th_template), ".%u");
0855             }
0856             
0857             
0858             if (NULL==dbg_ptr)
0859             {
0860                 NDRX_STRCPY_SAFE(G_ubf_debug.filename_th_template, 
0861                         G_ndrx_debug.filename_th_template);
0862                 
0863                 NDRX_STRCPY_SAFE(G_tp_debug.filename_th_template, 
0864                         G_ndrx_debug.filename_th_template);
0865             }
0866         }
0867     }
0868 
0869 out:
0870     if (NULL!=parsed)
0871     {
0872         ndrx_stdcfgstr_free(parsed);
0873     }
0874     
0875     return ret;
0876 }
0877 
0878 
0879 
0880 
0881 
0882 
0883 
0884 
0885 
0886 
0887 expublic FILE *ndrx_dbg_fopen_mkdir(const char *filename, const char *mode,
0888         ndrx_debug_t *dbg_ptr, ndrx_debug_file_sink_t *fsink)
0889 {
0890     FILE *ret = NULL;
0891     int got_dir = EXFALSE;
0892     int fallbacks = 0;
0893     
0894     int is_mkdir;
0895     int buffer_size;
0896     
0897     ret = NDRX_FOPEN(filename, mode);
0898     
0899     
0900     
0901     if (NULL!=dbg_ptr)
0902     {
0903         is_mkdir = dbg_ptr->is_mkdir;
0904         buffer_size = dbg_ptr->buffer_size;
0905     }
0906     else
0907     {
0908         is_mkdir = fsink->org_is_mkdir;
0909         buffer_size = fsink->org_buffer_size;
0910     }
0911     
0912     if (!is_mkdir)
0913     {
0914         goto out;
0915     }
0916     
0917     
0918     if (NULL==ret && errno==ENOENT)
0919     {
0920         
0921         char tmp[PATH_MAX+1];
0922         char *p;
0923         
0924         NDRX_STRCPY_SAFE(tmp, filename);
0925         
0926         
0927 
0928 
0929         while (NULL!=(p=strrchr(tmp, '/')))
0930         {
0931             *p = EXEOS;
0932             
0933             
0934             if (EXSUCCEED!=mkdir(tmp, NDRX_DIR_PERM))
0935             {
0936                 if (ENOENT!=errno)
0937                 {
0938                     break;
0939                 }
0940             }
0941             else
0942             {
0943                 got_dir = EXTRUE;
0944                 break;
0945             }
0946             
0947             fallbacks++;
0948         }
0949         
0950         if (!got_dir)
0951         {
0952             goto out;
0953         }
0954         
0955         
0956 
0957 
0958 
0959         while (fallbacks > 0)
0960         {
0961             tmp[strlen(tmp)]='/';
0962             
0963             if (EXSUCCEED!=mkdir(tmp, NDRX_DIR_PERM))
0964             {
0965                 
0966                 goto out;
0967             }
0968             
0969             fallbacks--;
0970         }
0971         
0972         ret = NDRX_FOPEN(filename, "a");
0973     }
0974     
0975 out:
0976     
0977     if (NULL!=ret)
0978     {
0979         
0980         if (EXSUCCEED!=fcntl(fileno(ret), F_SETFD, FD_CLOEXEC))
0981         {
0982             userlog("WARNING: Failed to set FD_CLOEXEC: %s", strerror(errno));
0983         }
0984         
0985 
0986 
0987         setvbuf(ret, NULL, _IOFBF, buffer_size);
0988         
0989         
0990         if (NULL!=dbg_ptr && NULL!=fsink)
0991         {
0992             fsink->org_is_mkdir = dbg_ptr->is_mkdir;
0993             fsink->org_buffer_size = dbg_ptr->buffer_size;
0994         }        
0995     }
0996 
0997     return ret;
0998 }
0999 
1000 
1001 
1002 
1003 
1004 
1005 expublic void ndrx_init_debug(void)
1006 {
1007     char *cfg_file = getenv(CONF_NDRX_DEBUG_CONF);
1008     char *inline_setting = getenv(CONF_NDRX_DEBUG_STR);
1009     FILE *f;
1010     ndrx_inicfg_section_keyval_t *conf = NULL, *cc;
1011     ndrx_inicfg_t *cconfig = NULL;
1012     char hostname[PATH_MAX];
1013     char buf[PATH_MAX*2];
1014     char *tmp;
1015     char tmpname[PATH_MAX+1]={EXEOS};
1016     int lcf_status=EXFAIL;
1017     int do_reply=EXFALSE;
1018     int did_match = EXFALSE; 
1019     char *svname = getenv(CONF_NDRX_SVPROCNAME);
1020     
1021     ndrx_dbg_intlock_set();
1022     
1023     
1024 
1025 
1026 
1027 
1028 
1029     
1030     ndrx_dbg_pid_update();
1031     
1032     ndrx_sys_get_hostname(hostname, sizeof(hostname));
1033     
1034     
1035     
1036     G_tp_debug.hostnamecrc32 = G_ubf_debug.hostnamecrc32 = 
1037                 G_ndrx_debug.hostnamecrc32 = G_stdout_debug.hostnamecrc32 = 
1038                 ndrx_Crc32_ComputeBuf(0, hostname, strlen(hostname));
1039     
1040     cconfig = ndrx_get_G_cconfig();
1041     
1042     
1043 
1044 
1045     G_ndrx_debug.dbg_f_ptr = NULL;
1046     G_ubf_debug.dbg_f_ptr = NULL;
1047     G_tp_debug.dbg_f_ptr = NULL;
1048     G_stdout_debug.dbg_f_ptr = NULL;
1049     
1050     G_ndrx_debug.version = 0;
1051     G_ubf_debug.version = 0;
1052     G_tp_debug.version = 0;
1053     G_stdout_debug.version = 0;
1054     
1055     
1056 
1057 
1058 
1059 
1060 #ifdef EX_USE_SYSVQ
1061     G_ndrx_debug.is_threaded = LOG_THREADED_LINEL;
1062     G_ubf_debug.is_threaded = LOG_THREADED_LINEL;
1063     G_tp_debug.is_threaded = LOG_THREADED_LINEL;
1064     G_stdout_debug.is_threaded = LOG_THREADED_LINEL;
1065 #endif
1066     
1067     
1068     G_stdout_debug.buf_lines = 1;
1069     G_stdout_debug.buffer_size = 1;
1070     G_stdout_debug.level = log_debug;
1071     
1072     
1073     G_tp_debug.buffer_size = G_ubf_debug.buffer_size = G_ndrx_debug.buffer_size = 50000;
1074 
1075     G_tp_debug.buf_lines = G_ubf_debug.buf_lines = G_ndrx_debug.buf_lines = 1;
1076     G_ubf_debug.level = G_ndrx_debug.level = log_error;
1077     
1078     G_tp_debug.level = log_debug;
1079 
1080     if (NULL==cconfig)
1081     {
1082         if (NULL!=inline_setting)
1083         {
1084             ndrx_init_parse_line(inline_setting, NULL, tmpname, sizeof(tmpname),
1085                     NULL, NULL);
1086         }
1087         else if (NULL!=cfg_file && EXEOS==cfg_file[0])
1088         {
1089             
1090             G_tp_debug.level = G_ubf_debug.level = G_ndrx_debug.level = log_error;
1091         }
1092         else if (NULL!=cfg_file &&
1093                 NULL!=(f=fopen(cfg_file, "r")))
1094         {
1095 
1096             
1097             while (NULL!=fgets(buf, sizeof(buf), f))
1098             {
1099                 int offs;
1100                 
1101                 if ('#'==buf[0] || '\n'==buf[0])
1102                 {
1103                     
1104                     continue;
1105                 }
1106                 if (buf[strlen(buf)-1]=='\n')
1107                 {
1108                     buf[strlen(buf)-1]=EXEOS;
1109                 }
1110                 
1111                 offs = strcspn(buf, "\t ");
1112                 
1113                 
1114                 if (offs > 0)
1115                 {
1116                     *(buf + offs)=EXEOS;
1117                     
1118                     if (0==strcmp(buf, (char *)EX_PROGNAME) || 
1119                             NULL!=svname && 0==strcmp(buf, svname) ||
1120                             0==strcmp(buf, "*"))
1121                     {
1122                         ndrx_init_parse_line((buf+offs+1), NULL, 
1123                                 tmpname, sizeof(tmpname),
1124                                 NULL, NULL);
1125                         
1126                         
1127                         if (0!=strcmp(buf, "*"))
1128                         {
1129                             did_match=EXTRUE;
1130                             break;
1131                         }
1132                     }
1133                 
1134                     
1135                     if (M_rebins)
1136                     {
1137                         ndrx_dbg_rebins_chkaddcfg(buf, (buf+offs+1));
1138                     }
1139                 }
1140                 
1141             }
1142 
1143             fclose(f);
1144         }
1145         else if (NULL==f && NULL!=cfg_file)
1146         {
1147             fprintf(stderr, "Failed to to open [%s]: %d/%s\n", cfg_file,
1148                                 errno, strerror(errno));
1149         }
1150     }
1151     else
1152     {
1153         
1154         ndrx_cconfig_load(); 
1155         if (EXSUCCEED==ndrx_cconfig_get(NDRX_CONF_SECTION_DEBUG, &conf))
1156         {
1157             
1158             
1159             if (NULL!=inline_setting)
1160             {
1161                 ndrx_init_parse_line(inline_setting, NULL, tmpname, sizeof(tmpname),
1162                         NULL, NULL);
1163             }
1164             
1165             else 
1166             {
1167                 
1168                 if (NULL!=(cc=ndrx_keyval_hash_get(conf, "*")))
1169                 {
1170                     ndrx_init_parse_line(cc->val, NULL, tmpname, sizeof(tmpname),
1171                             NULL, NULL);
1172                 }
1173             
1174                 
1175 
1176 
1177 
1178                 if (
1179                     NULL!=svname && NULL!=(cc=ndrx_keyval_hash_get(conf, (char *)svname)) 
1180                     ||
1181                     NULL!=(cc=ndrx_keyval_hash_get(conf, (char *)EX_PROGNAME)) 
1182                     )
1183                 {
1184                     ndrx_init_parse_line(cc->val, NULL, tmpname, sizeof(tmpname),
1185                             NULL, NULL);
1186                     
1187                     did_match=EXTRUE;
1188                 }
1189                 
1190                 if (!did_match && M_rebins)
1191                 {
1192                     
1193                     ndrx_dbg_rebins_scancfg(conf);
1194                     
1195                 }
1196             } 
1197         } 
1198     } 
1199     
1200     
1201     
1202     if (!did_match && M_rebins)
1203     {
1204         
1205         if (NULL!=svname && EXTRUE==ndrx_dbg_rebins_apply(svname, tmpname, sizeof(tmpname)))
1206         {
1207             did_match = EXTRUE;
1208         }
1209         
1210         if (!did_match)
1211         {
1212             ndrx_dbg_rebins_apply((char *)EX_PROGNAME, tmpname, sizeof(tmpname));
1213         }
1214     }
1215     
1216     ndrx_dbg_rebins_free();
1217     M_rebins=NULL;
1218     
1219     
1220     if (EXEOS==tmpname[0])
1221     {
1222         
1223         tmp = getenv(CONF_NDRX_DFLTLOG);
1224         
1225         if (NULL!=tmp)
1226         {
1227             NDRX_STRCPY_SAFE(tmpname, tmp);
1228         }
1229     }
1230         
1231     if (EXEOS==tmpname[0])
1232     {
1233         NDRX_STRCPY_SAFE(tmpname, NDRX_LOG_OSSTDERR);
1234     }
1235     
1236     
1237     NDRX_STRCPY_SAFE(G_stdout_debug.filename, NDRX_LOG_OSSTDOUT);
1238     
1239     
1240     ndrx_debug_get_sink(tmpname, EXTRUE, &G_ndrx_debug, NULL);
1241     ndrx_debug_get_sink(tmpname, EXTRUE, &G_ubf_debug, NULL);
1242     ndrx_debug_get_sink(tmpname, EXTRUE, &G_tp_debug, NULL);
1243     ndrx_debug_get_sink(G_stdout_debug.filename, EXTRUE, 
1244             &G_stdout_debug, NULL);
1245 
1246     
1247 
1248     
1249 
1250 
1251 
1252 
1253 
1254 
1255     
1256     if (NULL!=conf)
1257     {
1258         
1259         ndrx_keyval_hash_free(conf);
1260     }
1261     
1262     
1263     
1264     ndrx_systest_init();
1265     
1266     
1267 
1268 
1269 
1270     lcf_status = ndrx_lcf_init();
1271     
1272     G_ndrx_debug_first = EXFALSE;
1273     
1274     ndrx_dbg_intlock_unset(&do_reply);
1275     
1276     
1277     if (do_reply)
1278     {
1279         ndrx_dbg_reply_memlog_all();
1280     }
1281     
1282     
1283     if (EXSUCCEED!=lcf_status)
1284     {
1285         
1286         NDRX_LOG(log_warn, "LCF startup failed -> LCF commands will not be processed");
1287     }
1288     
1289 }
1290 
1291 
1292 
1293 
1294 
1295 expublic ndrx_debug_t * debug_get_ndrx_ptr(void)
1296 {
1297     
1298     NDRX_DBG_INIT_ENTRY;
1299     
1300     return get_debug_ptr(&G_ndrx_debug);
1301 }
1302 
1303 
1304 
1305 
1306 
1307 expublic ndrx_debug_t * debug_get_tp_ptr(void)
1308 {
1309     
1310     NDRX_DBG_INIT_ENTRY;
1311     
1312     return get_debug_ptr(&G_tp_debug);
1313 }
1314 
1315 
1316 
1317 
1318 
1319 expublic ndrx_debug_t * debug_get_ubf_ptr(void)
1320 {   
1321     NDRX_DBG_INIT_ENTRY;
1322     
1323     return get_debug_ptr(&G_ubf_debug);
1324 }
1325 
1326 
1327 
1328 
1329 
1330 expublic int debug_get_ndrx_level(void)
1331 {
1332     NDRX_DBG_INIT_ENTRY;
1333     return G_ndrx_debug.level;
1334 }
1335 
1336 
1337 
1338 
1339 
1340 expublic int debug_get_ubf_level(void)
1341 {
1342     NDRX_DBG_INIT_ENTRY;
1343     return G_ubf_debug.level;
1344 }
1345 
1346 
1347 
1348 
1349 
1350 expublic int debug_get_tp_level(void)
1351 {
1352     NDRX_DBG_INIT_ENTRY;
1353     return G_tp_debug.level;
1354 }
1355 
1356 
1357 
1358 
1359 
1360 
1361 
1362 
1363 
1364 
1365 
1366 
1367 
1368 
1369 expublic void __ndrx_debug_dump_diff__(ndrx_debug_t *dbg_ptr, int lev, const char *file, 
1370         long line, const char *func, const char *comment, void *ptr, void *ptr2, long len)
1371 {
1372     
1373     int i;
1374     unsigned char buf[17];
1375     unsigned char buf2[17];
1376     unsigned char *cptr = (unsigned char*)ptr;
1377     unsigned char *cptr2 = (unsigned char*)ptr2;
1378     char print_line[256]={0};
1379     char print_line2[256]={0};
1380     
1381     
1382     dbg_ptr = get_debug_ptr(dbg_ptr);
1383     
1384     if (dbg_ptr->level < lev)
1385     {
1386         return; 
1387     }
1388         
1389     __ndrx_debug__(dbg_ptr, lev, file, line, func, "%s", comment);
1390     
1391     if (0==len)
1392     {
1393         __ndrx_debug__(dbg_ptr, lev, file, line, func, "Notice: Hex dump diff - "
1394                 "nothing to dump: len=%d ptr=%p ptr2=%p", len, ptr, ptr2);
1395         
1396         return; 
1397     }
1398     
1399     ndrx_debug_lock(dbg_ptr->dbg_f_ptr);
1400     
1401     for (i = 0; i < len; i++)
1402     {
1403         if ((i % 16) == 0)
1404         {
1405             if (i != 0)
1406             {
1407                 sprintf (print_line + strlen(print_line), "  %s", buf);
1408                 sprintf (print_line2 + strlen(print_line2), "  %s", buf2);
1409 
1410                 if (0!=strcmp(print_line, print_line2))
1411                 {
1412                     
1413                     fputs("<", ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1414                     fputs(print_line, ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1415                     fputs("\n", ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1416                     BUFFER_CONTROL(dbg_ptr);
1417                     
1418                     
1419                     fputs(">", ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1420                     fputs(print_line2, ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1421                     fputs("\n", ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1422                     BUFFER_CONTROL(dbg_ptr);
1423                 }
1424 
1425                 print_line[0] = 0;
1426                 print_line2[0] = 0;
1427             }
1428 
1429             sprintf (print_line + strlen(print_line), "  %04x ", i);
1430             sprintf (print_line2 + strlen(print_line2), "  %04x ", i);
1431         }
1432 
1433         sprintf (print_line + strlen(print_line), " %02x", cptr[i]);
1434         sprintf (print_line2 + strlen(print_line2), " %02x", cptr2[i]);
1435 
1436         if ((cptr[i] < 0x20) || (cptr[i] > 0x7e))
1437         {
1438             buf[i % 16] = '.';
1439         }
1440         else
1441         {
1442             buf[i % 16] = cptr[i];
1443         }
1444         buf[(i % 16) + 1] = '\0';
1445 
1446         if ((cptr2[i] < 0x20) || (cptr2[i] > 0x7e))
1447         {
1448             buf2[i % 16] = '.';
1449         }
1450         else
1451         {
1452             buf2[i % 16] = cptr2[i];
1453         }
1454         buf2[(i % 16) + 1] = '\0';
1455     }
1456 
1457     while ((i % 16) != 0)
1458     {
1459         sprintf (print_line + strlen(print_line), "   ");
1460         sprintf (print_line2 + strlen(print_line2), "   ");
1461         i++;
1462     }
1463 
1464     sprintf (print_line + strlen(print_line), "  %s", buf);
1465     sprintf (print_line2 + strlen(print_line2), "  %s", buf2);
1466 
1467     if (0!=strcmp(print_line, print_line2))
1468     {
1469         
1470         fputs("<", ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1471         fputs(print_line, ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1472         fputs("\n", ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1473         BUFFER_CONTROL(dbg_ptr);
1474 
1475         
1476         fputs(">", ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1477         fputs(print_line2, ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1478         fputs("\n", ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1479         BUFFER_CONTROL(dbg_ptr);
1480     }
1481     print_line[0] = 0;
1482     print_line2[0] = 0;
1483     
1484     ndrx_debug_unlock(dbg_ptr->dbg_f_ptr);
1485 }
1486 
1487 
1488 
1489 
1490 
1491 
1492 
1493 
1494 
1495 
1496 
1497 
1498 
1499 expublic void __ndrx_debug_dump__(ndrx_debug_t *dbg_ptr, int lev, const char *file, 
1500         long line, const char *func, const char *comment, void *ptr, long len)
1501 {
1502     int i;
1503     unsigned char buf[17];
1504     unsigned char *cptr = (unsigned char*)ptr;
1505     char print_line[256]={0};
1506     NSTD_TLS_ENTRY;
1507     
1508     
1509     dbg_ptr = get_debug_ptr(dbg_ptr);
1510     
1511     if (dbg_ptr->level < lev)
1512     {
1513         return; 
1514     }
1515     
1516     __ndrx_debug__(dbg_ptr, lev, file, line, func, "%s (nr bytes: %ld)", 
1517             comment, len);
1518     
1519     if (0==len)
1520     {
1521         __ndrx_debug__(dbg_ptr, lev, file, line, func, "Notice: Hex dump - "
1522                 "nothing to dump: len=%d ptr=%p", len, ptr);
1523         
1524         return; 
1525     }
1526 
1527     
1528     
1529     ndrx_debug_lock(dbg_ptr->dbg_f_ptr);
1530     
1531     for (i = 0; i < len; i++)
1532     {
1533         if ((i % 16) == 0)
1534         {
1535             if (i != 0)
1536             {
1537                 sprintf (print_line + strlen(print_line), "  %s", buf);
1538                 BUFFERED_PRINT_LINE(dbg_ptr, print_line);
1539                 print_line[0] = 0;
1540             }
1541 
1542             sprintf (print_line + strlen(print_line), "  %04x ", i);
1543         }
1544         sprintf (print_line + strlen(print_line), " %02x", cptr[i]);
1545 
1546         if ((cptr[i] < 0x20) || (cptr[i] > 0x7e))
1547         {
1548             buf[i % 16] = '.';
1549         }
1550         else
1551         {
1552             buf[i % 16] = cptr[i];
1553         }
1554         buf[(i % 16) + 1] = '\0';
1555     }
1556 
1557     while ((i % 16) != 0)
1558     {
1559         sprintf (print_line + strlen(print_line), "   ");
1560         i++;
1561     }
1562 
1563     
1564     sprintf (print_line + strlen(print_line), "  %s", buf);
1565     BUFFERED_PRINT_LINE(dbg_ptr, print_line);
1566     print_line[0] = 0;
1567     
1568     ndrx_debug_unlock(dbg_ptr->dbg_f_ptr);
1569     
1570 }
1571 
1572 
1573 
1574 
1575 
1576 
1577 
1578 
1579 
1580 
1581 
1582 
1583 expublic void __ndrx_debug__(ndrx_debug_t *dbg_ptr, int lev, const char *file, 
1584         long line, const char *func, const char *fmt, ...)
1585 {
1586     va_list ap;
1587     char line_start[128];
1588     long ldate, ltime, lusec;
1589     char *line_print;
1590     char *func_last;
1591     int len;
1592     long  thread_nr = 0;
1593     static __thread uint64_t ostid = 0;
1594     static __thread int first = EXTRUE;
1595     
1596     
1597     
1598     
1599     if (NULL!=G_nstd_tls)
1600     {
1601         thread_nr = G_nstd_tls->M_threadnr;
1602     }
1603     
1604     
1605     if (first)
1606     {
1607         ostid = ndrx_gettid();
1608         first = EXFALSE;
1609     }
1610     
1611     if (!M_is_initlock_owner)
1612     {
1613         dbg_ptr = get_debug_ptr(dbg_ptr);
1614 
1615         if (dbg_ptr->level < lev)
1616         {
1617             return; 
1618         }
1619     }
1620     
1621     if ((len=strlen(file)) > 8)
1622     {
1623         line_print = (char *)file+len-8;
1624     }
1625     else
1626     {
1627         line_print = (char *)file;
1628     }
1629     
1630     if ((len=strlen(func)) > 12)
1631     {
1632         func_last = (char *)func+len-12;
1633     }
1634     else
1635     {
1636         func_last = (char *)func;
1637     }
1638 
1639     ndrx_get_dt_local(&ldate, <ime, &lusec);
1640     
1641     snprintf(line_start, sizeof(line_start), 
1642         "%c:%s:%d:%08x:%05d:%08llx:%03ld:%08ld:%06ld%06d:%-12.12s:%-8.8s:%04ld:",
1643         dbg_ptr->code, dbg_ptr->module, lev, (unsigned int)dbg_ptr->hostnamecrc32, 
1644             (int)dbg_ptr->pid, (unsigned long long)(ostid), thread_nr, ldate, ltime, 
1645         (int)(lusec), func_last, line_print, line);
1646     
1647     
1648     
1649     if (!M_is_initlock_owner)
1650     {
1651         
1652         
1653         ndrx_debug_lock((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr);
1654         
1655         fputs(line_start, ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1656         va_start(ap, fmt);    
1657         (void) vfprintf(((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp, fmt, ap);
1658         va_end(ap);
1659         fputs("\n", ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1660         
1661         
1662         BUFFER_CONTROL(dbg_ptr);
1663         
1664         ndrx_debug_unlock(dbg_ptr->dbg_f_ptr);
1665     }
1666     else
1667     {
1668         ndrx_memlogger_t *memline = NDRX_MALLOC(sizeof(ndrx_memlogger_t));
1669         
1670         if (NULL==memline)
1671         {
1672             userlog("Failed to malloc mem debug line: %s - skipping log entry", 
1673                     strerror(errno));
1674         }
1675         else
1676         {
1677             int len;
1678             memline->line[0] = EXEOS;
1679             memline->level = lev; 
1680             
1681             NDRX_STRCPY_SAFE(memline->line, line_start);
1682             
1683             len = strlen(memline->line);
1684             
1685             va_start(ap, fmt);    
1686             (void) vsnprintf(memline->line+len, sizeof(memline->line)-len, fmt, ap);
1687             va_end(ap);
1688             
1689             
1690             
1691             MUTEX_LOCK_V(M_memlog_lock);
1692             DL_APPEND(dbg_ptr->memlog, memline);
1693             MUTEX_UNLOCK_V(M_memlog_lock);
1694             
1695         }
1696     }
1697 }
1698 
1699 
1700 
1701 
1702 
1703 
1704 
1705 
1706 expublic void ndrx_dbg_init(char *module, char *config_key)
1707 {
1708    NDRX_DBG_INIT_ENTRY;
1709 }
1710 
1711 
1712 
1713 
1714 
1715 
1716 
1717 
1718 
1719 expublic void *ndrx_malloc_dbg(size_t size, long line, const char *file, const char *func)
1720 {
1721     void *ret;
1722     int errnosv;
1723     
1724     ret=malloc(size);
1725     errnosv = errno;
1726     
1727     userlog("[%p] <= malloc(size=%d):%s %s:%ld", ret, size, func, file, line);
1728     
1729     errno = errnosv;
1730     
1731     return ret;
1732 }
1733 
1734 
1735 
1736 
1737 
1738 
1739 
1740 
1741 
1742 expublic void ndrx_free_dbg(void *ptr, long line, const char *file, const char *func)
1743 {
1744     userlog("[%p] => free(ptr=%p):%s %s:%ld", ptr, ptr, func, file, line);
1745     free(ptr);
1746 }
1747 
1748 
1749 
1750 
1751 
1752 
1753 
1754 
1755 
1756 expublic void *ndrx_calloc_dbg(size_t nmemb, size_t size, long line, const char *file, const char *func)
1757 {
1758     void *ret;
1759     int errnosv;
1760     
1761     ret=calloc(nmemb, size);
1762     errnosv = errno;
1763     userlog("[%p] <= calloc(nmemb=%d, size=%d):%s %s:%ld", ret, nmemb, 
1764             size, func, file, line);
1765     
1766     errno = errnosv;
1767     
1768     return ret;
1769 }
1770 
1771 
1772 
1773 
1774 
1775 
1776 
1777 
1778 
1779 expublic void *ndrx_realloc_dbg(void *ptr, size_t size, long line, const char *file, const char *func)
1780 {   
1781     void *ret;
1782     int errnosv;
1783     
1784     ret= realloc(ptr, size);
1785     
1786     errnosv = errno;
1787             
1788     userlog("[%p] <= realloc(ptr=[%p], size=%d):%s %s:%ld", ret, ptr, 
1789             size, func, file, line);
1790     
1791     errno = errnosv;
1792     return ret;
1793 }
1794 
1795 
1796 
1797 
1798 
1799 
1800 
1801 
1802 expublic FILE *ndrx_fopen_dbg(const char *path, const char *mode, 
1803         long line, const char *file, const char *func)
1804 {
1805     FILE *ret;
1806     int errnosv;
1807     
1808     ret = fopen(path, mode);
1809     errnosv = errno;
1810    
1811     userlog("[%p] <= fopen(path=%s, mode=%s):%s %s:%ld", ret,  path, mode,
1812             func, file, line);
1813     
1814     errno = errnosv;
1815     
1816     return ret;
1817 }
1818 
1819 
1820 
1821 
1822 
1823 
1824 
1825 expublic int ndrx_fclose_dbg(FILE *fp, long line, const char *file, const char *func)
1826 {
1827     int ret;
1828     int errnosv;
1829     
1830     ret = fclose(fp);
1831     
1832     errnosv = errno;
1833             
1834     userlog("[%p] => fclose(fp=%p) => %d:%s %s:%ld", fp, fp, ret, 
1835             func, file, line);
1836     
1837     errno = errnosv;
1838     
1839     return ret;
1840     
1841 }
1842 
1843 
1844 
1845 
1846 
1847 expublic char *ndrx_strdup_dbg(char *ptr, long line, const char *file, const char *func)
1848 {
1849     char *ret;
1850     int errnosv;
1851     
1852     ret=strdup(ptr);
1853     errnosv = errno;
1854     
1855     userlog("[%p] <= strdup(ptr=%p):%s %s:%ld", ret, ptr, func, file, line);
1856     
1857     errno = errnosv;
1858     
1859     return ret;
1860 }
1861 
1862