/** * @file: $RCSfile: logcfgx.c,v $ * @brief: $IEC 61850 Protocol * * @version: $Revision: 1.1 $ * @date: $Date: 2018/11/24 06:54:50 $ * @author: $Author: lizhongming $ * @state: $State: Exp $ * * @latest: $Id: logcfgx.c,v 1.1 2018/11/24 06:54:50 lizhongming Exp $ * */ /************************************************************************/ /* SISCO SOFTWARE MODULE HEADER *****************************************/ /************************************************************************/ /* (c) Copyright Systems Integration Specialists Company, Inc., */ /* 2000 - 2005, All Rights Reserved */ /* */ /* MODULE NAME : logcfgx.c */ /* PRODUCT(S) : */ /* */ /* MODULE DESCRIPTION : This module processes each value parsed in */ /* the logcfg.xml file . The logcfg.xml file */ /* assigns Log File Attributes and */ /* Miscellaneous Control Flags as well as */ /* Memory Use Logging and various Log Masks */ /* to enable specific logging required. */ /* */ /* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */ /* */ /* MODIFICATION LOG : */ /* Date Who Rev Comments */ /* -------- --- ------ -------------------------------------------- */ /* 08/10/05 MDE 13 Added logCfgRemoveAllMaskGroups */ /* 06/21/05 EJV 12 Deleted obsolete logcfgx function. */ /* 05/23/05 EJV 11 Moved xxxLogMaskMapCtrl to respective C files.*/ /* Del m_track_prev_free (not used anymore). */ /* Force user to use logcfgx_ex insted of logcfgx*/ /* 04/25/05 MDE 10 Added MMS_LOG_CLIENT & MMS_LOG_SERVER */ /* 03/31/05 MDE 09 Put suicacse.h back, for MAP30_ACSE */ /* 03/28/05 JRB 08 Del suicacse header. */ /* 02/10/05 MDE 07 Changed MILOG_ to MI_LOG_ */ /* 02/10/05 MDE 06 Added new DATATYPE's */ /* 01/27/05 MDE 05 DEBUG_SISCO #ifdefs, LINUX warning cleanup */ /* 01/20/05 MDE 04 Lot's more work ... */ /* 12/10/04 ASK 03 Added Slog IPC params, added */ /* case _LOGCFG_DATATYPE_UINT32_MASK */ /* Modify params to use 'R'everse data type */ /* Update copyright year */ /* 11/16/04 MDE 02 Fixed to compile with MAP30_ACSE */ /* 10/12/04 MDE 01 Complete rewrite to work with SX changes, */ /* make extendable */ /************************************************************************/ #include "glbtypes.h" #include "sysincs.h" #include "mem_chk.h" #include "gen_list.h" #include "str_util.h" #include "slog.h" #include "sx_defs.h" #include "sx_log.h" /************************************************************************/ /* For debug version, use a static pointer to avoid duplication of */ /* __FILE__ strings. */ #if defined(DEBUG_SISCO) SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__; #endif /************************************************************************/ LOGCFG_VALUE_GROUP *logCfgLogMaskGroupList; static LOGCFGX_TAG_VAL *_tagValList; /************************************************************************/ #if defined(DEBUG_SISCO) static LOG_CTRL tmp_sLogCtrl; ST_UINT logcfg_debug_sel; /* Log type strings */ SD_CONST ST_CHAR *SD_CONST _logcfg_log_err_logstr = "LOGCFG_ERR"; SD_CONST ST_CHAR *SD_CONST _logcfg_log_nerr_logstr = "LOGCFG_NERR"; SD_CONST ST_CHAR *SD_CONST _logcfg_log_flow_logstr = "LOGCFG_FLOW"; LOGCFGX_VALUE_MAP logcfgMaskMaps[] = { {"LOGCFG_ERR", LOGCFG_ERR, &logcfg_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, "Error"}, {"LOGCFG_NERR", LOGCFG_NERR, &logcfg_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, "Notice"}, {"LOGCFG_FLOW", LOGCFG_FLOW, &logcfg_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, "Flow"} }; LOGCFG_VALUE_GROUP logcfgMaskMapCtrl = { {NULL,NULL}, "LOGCFG", sizeof(logcfgMaskMaps)/sizeof(LOGCFGX_VALUE_MAP), logcfgMaskMaps }; /************************************************************************/ /************************************************************************/ LOGCFGX_VALUE_MAP logCfgLogMaskMaps[] = { /* SLOG Control */ {"LogFileEnable", LOG_FILE_EN, &tmp_sLogCtrl.logCtrl, _LOGCFG_DATATYPE_UINT32_MASK}, {"DestroyOldFile", FIL_CTRL_NO_APPEND, &tmp_sLogCtrl.fc.ctrl, _LOGCFG_DATATYPE_UINT_MASK}, {"Setbuf", FIL_CTRL_SETBUF_EN, &tmp_sLogCtrl.fc.ctrl, _LOGCFG_DATATYPE_UINT_MASK}, {"MsgHeader", FIL_CTRL_MSG_HDR_EN, &tmp_sLogCtrl.fc.ctrl, _LOGCFG_DATATYPE_UINT_MASK}, {"Wipe", FIL_CTRL_WIPE_EN, &tmp_sLogCtrl.fc.ctrl, _LOGCFG_DATATYPE_UINT_MASK}, {"Wrap", FIL_CTRL_WRAP_EN, &tmp_sLogCtrl.fc.ctrl, _LOGCFG_DATATYPE_UINT_MASK}, {"HardFlush", FIL_CTRL_HARD_FLUSH, &tmp_sLogCtrl.fc.ctrl, _LOGCFG_DATATYPE_UINT_MASK}, {"LogMemoryEnable", LOG_MEM_EN, &tmp_sLogCtrl.logCtrl, _LOGCFG_DATATYPE_UINT32_MASK}, {"MemoryFileDump", MEM_CTRL_AUTODUMP_EN, &tmp_sLogCtrl.mc.ctrl, _LOGCFG_DATATYPE_UINT_MASK}, {"LogIpcListenEnable", LOG_IPC_LISTEN_EN, &tmp_sLogCtrl.logCtrl, _LOGCFG_DATATYPE_UINT32_MASK}, {"LogIpcCallEnable", LOG_IPC_CALL_EN, &tmp_sLogCtrl.logCtrl, _LOGCFG_DATATYPE_UINT32_MASK}, {"LogIpcSmartMode", LOG_IPC_SMART, &tmp_sLogCtrl.logCtrl, _LOGCFG_DATATYPE_UINT32_MASK}, {"HeaderCr", LOG_NO_HEADER_CR, &tmp_sLogCtrl.logCtrl, _LOGCFG_DATATYPE_RUINT32_MASK}, {"HeaderFilename", LOG_FILENAME_SUPPRESS, &tmp_sLogCtrl.logCtrl, _LOGCFG_DATATYPE_RUINT32_MASK}, {"HeaderLogType", LOG_LOGTYPE_SUPPRESS, &tmp_sLogCtrl.logCtrl, _LOGCFG_DATATYPE_RUINT32_MASK}, {"LogFileSize", 0, &tmp_sLogCtrl.fc.maxSize, _LOGCFG_DATATYPE_ULONG}, {"LogFileName", 0, &tmp_sLogCtrl.fc.fileName, _LOGCFG_DATATYPE_FILENAME}, {"LogMemoryItems", 0, &tmp_sLogCtrl.mc.maxItems, _LOGCFG_DATATYPE_ULONG}, {"MemoryFileName", 0, &tmp_sLogCtrl.mc.dumpFileName, _LOGCFG_DATATYPE_FILENAME}, {"LogIpcAppId", 0, &tmp_sLogCtrl.ipc.appId, _LOGCFG_DATATYPE_STRING}, {"LogIpcListenPort", 0, &tmp_sLogCtrl.ipc.port, _LOGCFG_DATATYPE_UINT16}, {"LogIpcNumListenPorts", 0, &tmp_sLogCtrl.ipc.portCnt, _LOGCFG_DATATYPE_UINT16}, {"LogIpcMaxListenConn", 0, &tmp_sLogCtrl.ipc.maxConns, _LOGCFG_DATATYPE_UINT}, {"LogIpcCallingPort", 0, &tmp_sLogCtrl.ipc.callingPort, _LOGCFG_DATATYPE_UINT16}, {"LogIpcCallingIp", 0, &tmp_sLogCtrl.ipc.callingIp, _LOGCFG_DATATYPE_STRING}, {"LogIpcMaxQueCount", 0, &tmp_sLogCtrl.ipc.maxQueCnt, _LOGCFG_DATATYPE_UINT}, }; LOGCFG_VALUE_GROUP logCfgLogCtrlMapCtrl = { {NULL,NULL}, "", sizeof(logCfgLogMaskMaps)/sizeof(LOGCFGX_VALUE_MAP), logCfgLogMaskMaps }; #endif /* defined(DEBUG_SISCO) */ /************************************************************************/ /************************************************************************/ static ST_RET _logcfg_data_start (SX_DEC_CTRL *sxDecCtrl, ST_CHAR *tag); static ST_RET _logcfg_data_end (SX_DEC_CTRL *sxDecCtrl, ST_CHAR *tag); /************************************************************************/ /* logCfgAddMaskGroup */ /************************************************************************/ ST_VOID logCfgAddMaskGroup (LOGCFG_VALUE_GROUP *logMaskGroup) { if (list_find_node (logCfgLogMaskGroupList, logMaskGroup) != SD_SUCCESS) list_add_last (&logCfgLogMaskGroupList, logMaskGroup); } /************************************************************************/ /* logCfgRemoveMaskGroup */ /************************************************************************/ ST_VOID logCfgRemoveMaskGroup (LOGCFG_VALUE_GROUP *logMaskGroup) { if (list_find_node (logCfgLogMaskGroupList, logMaskGroup) == SD_SUCCESS) list_unlink (&logCfgLogMaskGroupList, logMaskGroup); } /************************************************************************/ /* logCfgRemoveAllMaskGroups */ /************************************************************************/ ST_VOID logCfgRemoveAllMaskGroups () { logCfgLogMaskGroupList = NULL; } /************************************************************************/ /* logCfgFindTagVal */ /************************************************************************/ LOGCFGX_TAG_VAL *logCfgFindTagVal (ST_CHAR *tag) { LOGCFGX_TAG_VAL *tagVal; tagVal = _tagValList; while (tagVal != NULL) { if (!strcmp (tag, tagVal->tag)) return (tagVal); tagVal =(LOGCFGX_TAG_VAL*) list_get_next (_tagValList, tagVal); } return (NULL); } /************************************************************************/ /* logCfgClearTagVals */ /************************************************************************/ ST_VOID logCfgClearTagVals () { LOGCFGX_TAG_VAL *tagVal; while (_tagValList) { tagVal = (LOGCFGX_TAG_VAL *) list_unlink (&_tagValList, _tagValList); if (tagVal->dataType == _LOGCFG_DATATYPE_STRING || tagVal->dataType == _LOGCFG_DATATYPE_FILENAME) { chk_free (tagVal->u.str); } chk_free (tagVal); } } /************************************************************************/ /************************************************************************/ /* logcfgx_ex */ /* User must call logCfgAddMaskGroup for each group of log masks to be */ /* configured BEFORE calling this function to parse the file. */ /************************************************************************/ typedef struct { LOG_CTRL *destLogCtrl; ST_INT state; ST_CHAR *logFileName; ST_CHAR *fileNamePrefix; ST_BOOLEAN masksOnly; ST_BOOLEAN saveTagVals; } LOGCFGX_CTRL; ST_RET logcfgx_ex (LOG_CTRL *destLogCtrl, ST_CHAR *logFileName, ST_CHAR *fileNamePrefix, ST_BOOLEAN masksOnly, ST_BOOLEAN saveTagVals) { LOGCFGX_CTRL logCfgxCtrl; ST_UINT sx_debug_sel_save; ST_RET rc; #if defined(DEBUG_SISCO) ST_CHAR *savedFileName; #endif logCfgxCtrl.destLogCtrl = destLogCtrl; logCfgxCtrl.logFileName = logFileName; logCfgxCtrl.fileNamePrefix = fileNamePrefix; logCfgxCtrl.masksOnly = masksOnly; logCfgxCtrl.saveTagVals = saveTagVals; #if defined(DEBUG_SISCO) logcfg_debug_sel |= LOGCFG_ERR; logcfg_debug_sel |= LOGCFG_NERR; sx_debug_sel |= SX_LOG_ERR; sx_debug_sel |= SX_LOG_NERR; if (masksOnly) logCfgRemoveMaskGroup (&logCfgLogCtrlMapCtrl); else logCfgAddMaskGroup (&logCfgLogCtrlMapCtrl); /* Always allow LOGCFG & SX logging ... */ logCfgAddMaskGroup (&logcfgMaskMapCtrl); logCfgAddMaskGroup (&sxLogMaskMapCtrl); savedFileName = sLogCtrl->fc.fileName; /* Copy original "sLogCtrl" to temporary struct which may be modified */ /* by the configuration. */ /* This prevents logging control changes while there may be logging. */ memcpy (&tmp_sLogCtrl, sLogCtrl, sizeof (LOG_CTRL)); #endif rc = sx_parseEx_mt (logFileName, 0, NULL, &logCfgxCtrl, _logcfg_data_start, _logcfg_data_end); if (rc != SD_SUCCESS) { /* Config failed: Do not modify "sLogCtrl". */ /* Turn on cfg logging and parse file again. */ sx_debug_sel_save = sx_debug_sel; sx_debug_sel |= SX_LOG_DEC | SX_LOG_ENC | SX_LOG_FLOW | SX_LOG_DEBUG; LOGCFG_ERR0 ("ERROR Parsing Logging Configuration File: Trying again w/debug on ... "); rc = sx_parseEx_mt (logFileName, 0,NULL,&logCfgxCtrl, _logcfg_data_start, _logcfg_data_end); sx_debug_sel = sx_debug_sel_save; } else /* rc == SD_SUCCESS */ { LOGCFG_FLOW0 ("Logging configuration complete"); } return (rc); } /************************************************************************/ /************************************************************************/ /* _logcfg_data_start */ /************************************************************************/ #define LOGCFGX_STATE_NONE 0 #define LOGCFGX_STATE_UNKNOWN 1 #define LOGCFGX_STATE_LOGCTRL 2 #define LOGCFGX_STATE_LOGMASKS 3 static ST_RET _logcfg_data_start (SX_DEC_CTRL *sxDecCtrl, ST_CHAR *tag) { LOGCFGX_CTRL *logCfgxCtrl; logCfgxCtrl =(LOGCFGX_CTRL*) sxDecCtrl->usr; if (!strcmp (tag, "LogControl")) logCfgxCtrl->state = LOGCFGX_STATE_LOGCTRL; else if (!strcmp (tag, "LogMasks")) logCfgxCtrl->state = LOGCFGX_STATE_LOGMASKS; return (SD_SUCCESS); } /************************************************************************/ /* _logcfg_data_end */ /************************************************************************/ static ST_RET _logcfg_data_end (SX_DEC_CTRL *sxDecCtrl, ST_CHAR *tag) { LOGCFGX_CTRL *logCfgxCtrl; LOGCFG_VALUE_GROUP *slogMaskGroup; LOG_CTRL *destLogCtrl; LOGCFGX_TAG_VAL *tagVal; SX_DEC_ELEMENT_INFO *sxDecElInfo; ST_VOID (*logCfgCallbackFun) (SX_DEC_CTRL *sxDecCtrl, ST_CHAR *tag, LOGCFGX_VALUE_MAP *valMap); ST_CHAR *cp; ST_CHAR *str; ST_BOOLEAN *bp; ST_BOOLEAN b; ST_INT i; ST_INT strLen; ST_RET rc; ST_UINT *up; ST_UINT32 *u32p; ST_UINT16 *u16p; ST_ULONG *ulp; ST_CHAR **cpp; ST_DOUBLE *dp; #if defined(DEBUG_SISCO) ST_CHAR *oldFileName; ST_BOOLEAN logFileChanged; #endif ST_BOOLEAN found; ST_CHAR *p; logCfgxCtrl =(LOGCFGX_CTRL*) sxDecCtrl->usr; if (!strcmp (tag, "LogMasks")) { logCfgxCtrl->state = LOGCFGX_STATE_NONE; return (SD_SUCCESS); } destLogCtrl = logCfgxCtrl->destLogCtrl; sxDecElInfo = &sxDecCtrl->sxDecElInfo; if (!strcmp (tag, "LogControl")) { #if defined(DEBUG_SISCO) logFileChanged = SD_FALSE; if (logCfgxCtrl->masksOnly == SD_FALSE) { /* If the log file name has changed and the log file is open, */ /* close the log file and clear state. */ if (destLogCtrl->fc.state & FIL_STATE_OPEN) { oldFileName = destLogCtrl->fc.fileName; #ifdef _WIN32 /* Filenames NOT case sensitive on Windows */ if (_stricmp (tmp_sLogCtrl.fc.fileName, oldFileName) != 0) #else if (strcmp (tmp_sLogCtrl.fc.fileName, oldFileName) != 0) #endif { /* NEW log file name different from OLD. */ fclose (destLogCtrl->fc.fp); /* close it */ destLogCtrl->fc.state &= ~(FIL_STATE_OPEN); /* clear state */ logFileChanged = SD_TRUE; } } if (tmp_sLogCtrl.fc.ctrl & FIL_CTRL_MSG_HDR_EN) tmp_sLogCtrl.mc.ctrl |= MEM_CTRL_MSG_HDR_EN; else tmp_sLogCtrl.mc.ctrl &= ~MEM_CTRL_MSG_HDR_EN; destLogCtrl->logCtrl = tmp_sLogCtrl.logCtrl; destLogCtrl->fc.ctrl = tmp_sLogCtrl.fc.ctrl; destLogCtrl->fc.fileName = tmp_sLogCtrl.fc.fileName; destLogCtrl->fc.maxSize = tmp_sLogCtrl.fc.maxSize; destLogCtrl->mc.ctrl = tmp_sLogCtrl.mc.ctrl; destLogCtrl->mc.dumpFileName = tmp_sLogCtrl.mc.dumpFileName; destLogCtrl->mc.maxItems = tmp_sLogCtrl.mc.maxItems; destLogCtrl->ipc.appId = tmp_sLogCtrl.ipc.appId; destLogCtrl->ipc.port = tmp_sLogCtrl.ipc.port; destLogCtrl->ipc.portCnt = tmp_sLogCtrl.ipc.portCnt; destLogCtrl->ipc.maxConns = tmp_sLogCtrl.ipc.maxConns; destLogCtrl->ipc.callingIp = tmp_sLogCtrl.ipc.callingIp; destLogCtrl->ipc.callingPort = tmp_sLogCtrl.ipc.callingPort; destLogCtrl->ipc.maxQueCnt = tmp_sLogCtrl.ipc.maxQueCnt; } LOGCFG_FLOW2 ("LogCfg loading file %s, prefix %s", logCfgxCtrl->logFileName, logCfgxCtrl->fileNamePrefix); if (logFileChanged) { _slog (destLogCtrl,_logcfg_log_flow_logstr, thisFileName,__LINE__, "See the file '%s' for messages logged before or during Logging config", oldFileName); } #endif logCfgxCtrl->state = LOGCFGX_STATE_NONE; return (SD_SUCCESS); } /* Get the pointer to the contents */ strLen = 0; rc = sx_get_string_ptr (sxDecCtrl, &str, &strLen); if (rc != SD_SUCCESS) return (rc); /* OK, this might be an Log Mask or other value of interest */ /* If we are to save this in a list, start here */ if (logCfgxCtrl->saveTagVals && logCfgxCtrl->state == LOGCFGX_STATE_LOGMASKS) { tagVal = logCfgFindTagVal (tag); if (tagVal) { list_unlink (&_tagValList, tagVal); if (tagVal->dataType == _LOGCFG_DATATYPE_STRING || tagVal->dataType == _LOGCFG_DATATYPE_FILENAME) { chk_free (tagVal->u.str); } chk_free (tagVal); } tagVal = (LOGCFGX_TAG_VAL*)chk_calloc (1, sizeof (LOGCFGX_TAG_VAL) + strlen (tag) + 1); p = (ST_CHAR *) (tagVal + 1); tagVal->tag = p; strcpy (p, tag); list_add_last (&_tagValList, tagVal); } else tagVal = NULL; /* Now see if we can find it ... */ found = SD_FALSE; slogMaskGroup = logCfgLogMaskGroupList; while (slogMaskGroup) { for (i = 0; i < slogMaskGroup->numMaskMap; ++i) { if (!strcmp (tag, slogMaskGroup->maskMapTbl[i].tag)) { found = SD_TRUE; if (tagVal != NULL) tagVal->dataType = slogMaskGroup->maskMapTbl[i].dataType; switch (slogMaskGroup->maskMapTbl[i].dataType) { case _LOGCFG_DATATYPE_UINT_MASK: up =(ST_UINT*) slogMaskGroup->maskMapTbl[i].addr; sx_get_string_OnOff_bool (sxDecCtrl, &b, SX_ERR_CONVERT); if (b) *up |= slogMaskGroup->maskMapTbl[i].mask; /* Set the bit */ else *up &= ~slogMaskGroup->maskMapTbl[i].mask; /* Clear the bit */ LOGCFG_CFLOW2 ("Setting log mask %-16s %s", tag, b ? "ON" : "OFF"); if (tagVal != NULL) tagVal->u.b = b; break; case _LOGCFG_DATATYPE_UINT32_MASK: u32p =(ST_UINT32 *) slogMaskGroup->maskMapTbl[i].addr; sx_get_string_OnOff_bool (sxDecCtrl, &b, SX_ERR_CONVERT); if (b) *u32p |= slogMaskGroup->maskMapTbl[i].mask; /* Set the bit */ else *u32p &= ~slogMaskGroup->maskMapTbl[i].mask; /* Clear the bit */ LOGCFG_CFLOW2 ("Setting log mask %-16s %s", tag, b ? "ON" : "OFF"); if (tagVal != NULL) tagVal->u.b = b; break; /* 'R'everse mask settings */ case _LOGCFG_DATATYPE_RUINT32_MASK: up =(ST_UINT *) slogMaskGroup->maskMapTbl[i].addr; sx_get_string_OnOff_bool (sxDecCtrl, &b, SX_ERR_CONVERT); if (b) *up &= ~slogMaskGroup->maskMapTbl[i].mask; /* Clear the bit */ else *up |= slogMaskGroup->maskMapTbl[i].mask; /* Set the bit */ LOGCFG_CFLOW2 ("Setting log mask %-16s %s", tag, b ? "ON" : "OFF"); if (tagVal != NULL) tagVal->u.b = b; break; case _LOGCFG_DATATYPE_BOOLEAN: bp = (ST_BOOLEAN *) slogMaskGroup->maskMapTbl[i].addr; sx_get_string_OnOff_bool (sxDecCtrl, bp, SX_ERR_CONVERT); LOGCFG_CFLOW2 ("Setting boolean %-16s %s", tag, *bp ? "ON" : "OFF"); if (tagVal != NULL) tagVal->u.b = *bp; break; case _LOGCFG_DATATYPE_INT: case _LOGCFG_DATATYPE_UINT: up =(ST_UINT *) slogMaskGroup->maskMapTbl[i].addr; sx_get_uint (sxDecCtrl, up); LOGCFG_CFLOW2 ("Setting %16s to %d", tag, (int) *up); if (tagVal != NULL) tagVal->u.uInt = *up; break; case _LOGCFG_DATATYPE_LONG: case _LOGCFG_DATATYPE_ULONG: ulp =(ST_ULONG *) slogMaskGroup->maskMapTbl[i].addr; sx_get_ulong (sxDecCtrl, ulp); LOGCFG_CFLOW2 ("Setting %16s to %ld", tag, (long int) *ulp); if (tagVal != NULL) tagVal->u.uLong = *ulp; break; case _LOGCFG_DATATYPE_INT16: case _LOGCFG_DATATYPE_UINT16: u16p =(ST_UINT16*) slogMaskGroup->maskMapTbl[i].addr; sx_get_uint16 (sxDecCtrl, u16p); LOGCFG_CFLOW2 ("Setting %16s to %d", tag, (int) *u16p); if (tagVal != NULL) tagVal->u.uInt16 = *u16p; break; case _LOGCFG_DATATYPE_INT32: case _LOGCFG_DATATYPE_UINT32: u32p = (ST_UINT32 *)slogMaskGroup->maskMapTbl[i].addr; sx_get_ulong (sxDecCtrl, u32p); LOGCFG_CFLOW2 ("Setting %16s to %d", tag, (int) *u32p); if (tagVal != NULL) tagVal->u.uInt32 = *u32p; break; case _LOGCFG_DATATYPE_DOUBLE: dp =(ST_DOUBLE *) slogMaskGroup->maskMapTbl[i].addr; sx_get_double (sxDecCtrl, dp); LOGCFG_CFLOW2 ("Setting %16s to %.4f", tag, *dp); if (tagVal != NULL) tagVal->u.uInt32 = *u32p; break; case _LOGCFG_DATATYPE_STRING: cpp =(ST_CHAR **) slogMaskGroup->maskMapTbl[i].addr; sx_get_alloc_string (sxDecCtrl, cpp); LOGCFG_CFLOW2 ("Setting %16s to '%s'", tag, *cpp); if (tagVal != NULL) tagVal->u.str = *cpp; break; case _LOGCFG_DATATYPE_STRINGBUF: cp =(ST_CHAR *) slogMaskGroup->maskMapTbl[i].addr; strLen = 0; sx_get_string_ptr (sxDecCtrl, &str, &strLen); LOGCFG_CFLOW2 ("Setting %16s to '%s'", tag, str); cp =(ST_CHAR *) slogMaskGroup->maskMapTbl[i].addr; strncpy_safe (cp, str, slogMaskGroup->maskMapTbl[i].mask); if (tagVal != NULL) tagVal->u.str = cp; break; case _LOGCFG_DATATYPE_FILENAME: cpp = (ST_CHAR **)slogMaskGroup->maskMapTbl[i].addr; /* The user might want a prefix for this file name */ strLen = 0; sx_get_string_ptr (sxDecCtrl, &str, &strLen); if (logCfgxCtrl->fileNamePrefix) strLen += strlen (logCfgxCtrl->fileNamePrefix); p =(ST_CHAR *) chk_malloc (strLen+1); *cpp = p; if (logCfgxCtrl->fileNamePrefix) strcpy (p, logCfgxCtrl->fileNamePrefix); else *p = 0; strcat (p, str); LOGCFG_CFLOW2 ("Setting %-16s to '%s'", tag, p); if (tagVal != NULL) tagVal->u.str = p; break; case _LOGCFG_DATATYPE_CALLBACK: logCfgCallbackFun = (ST_VOID(*)(SX_DEC_CTRL*,ST_CHAR*,LOGCFGX_VALUE_MAP*)) slogMaskGroup->maskMapTbl[i].addr; if (logCfgCallbackFun != NULL) (*logCfgCallbackFun) (sxDecCtrl, tag, &slogMaskGroup->maskMapTbl[i]); break; } break; } } slogMaskGroup =(LOGCFG_VALUE_GROUP*) list_get_next (logCfgLogMaskGroupList, slogMaskGroup); } /* If we did not find it but are supposed to get it's value anyway ... */ if (tagVal != NULL && found == SD_FALSE) { strLen = 0; sx_get_string_ptr (sxDecCtrl, &str, &strLen); if (!stricmp (str, "On")) { LOGCFG_CFLOW1 ("Setting log mask %-16s ON", tag); tagVal->u.b = SD_TRUE; tagVal->dataType = _LOGCFG_DATATYPE_BOOLEAN; } else if (!stricmp (str, "Off")) { LOGCFG_CFLOW1 ("Setting log mask %-16s OFF", tag); tagVal->u.b = SD_FALSE; tagVal->dataType = _LOGCFG_DATATYPE_BOOLEAN; } else { tagVal->u.str = chk_strdup (p);; tagVal->dataType = _LOGCFG_DATATYPE_STRING; } } return (SD_SUCCESS); }