version 1.16, 2007/09/12 21:30:58
|
version 1.19, 2008/12/02 09:00:42
|
|
|
//%2006//////////////////////////////////////////////////////////////////////// |
//%LICENSE//////////////////////////////////////////////////////////////// |
// | // |
// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development |
// Licensed to The Open Group (TOG) under one or more contributor license |
// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. |
// agreements. Refer to the OpenPegasusNOTICE.txt file distributed with |
// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.; |
// this work for additional information regarding copyright ownership. |
// IBM Corp.; EMC Corporation, The Open Group. |
// Each contributor licenses this file to you under the OpenPegasus Open |
// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.; |
// Source License; you may not use this file except in compliance with the |
// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. |
// License. |
// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; |
|
// EMC Corporation; VERITAS Software Corporation; The Open Group. |
|
// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.; |
|
// EMC Corporation; Symantec Corporation; The Open Group. |
|
// | // |
// Permission is hereby granted, free of charge, to any person obtaining a copy |
// Permission is hereby granted, free of charge, to any person obtaining a |
// of this software and associated documentation files (the "Software"), to |
// copy of this software and associated documentation files (the "Software"), |
// deal in the Software without restriction, including without limitation the |
// to deal in the Software without restriction, including without limitation |
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
// the rights to use, copy, modify, merge, publish, distribute, sublicense, |
// sell copies of the Software, and to permit persons to whom the Software is |
// and/or sell copies of the Software, and to permit persons to whom the |
// furnished to do so, subject to the following conditions: |
// Software is furnished to do so, subject to the following conditions: |
// | // |
// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN |
// The above copyright notice and this permission notice shall be included |
// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED |
// in all copies or substantial portions of the Software. |
// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT |
|
// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR |
|
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
|
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
// | // |
//============================================================================== |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
|
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
|
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
|
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
|
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
// |
|
////////////////////////////////////////////////////////////////////////// |
// | // |
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
#include <Pegasus/Common/Config.h> |
|
#include <Pegasus/Common/Constants.h> |
|
#include <Pegasus/Common/Logger.h> |
|
#include <Pegasus/Common/AuditLogger.h> | #include <Pegasus/Common/AuditLogger.h> |
| |
#ifdef PEGASUS_OS_DARWIN |
#if defined(PEGASUS_OS_ZOS) |
# include <crt_externs.h> |
// SMF is a z/OS operating system specific facility. |
#endif |
// It is not recommended to port it to other platforms. |
|
# include "AuditLoggerToSMF.cpp" |
#ifndef PEGASUS_OS_TYPE_WINDOWS |
|
# include <unistd.h> |
|
#endif |
|
|
|
#ifdef PEGASUS_OS_VMS |
|
# include <unixlib.h> |
|
#endif |
|
|
|
#include <stdlib.h> |
|
|
|
#ifdef PEGASUS_ENABLE_AUDIT_LOGGER |
|
|
|
PEGASUS_USING_STD; |
|
|
|
PEGASUS_NAMESPACE_BEGIN |
|
|
|
static const String providerModuleStatus [] = { |
|
"Unknown", "Other", "OK", "Degraded", |
|
"Stressed", "Predictive Failure", "Error", "Non-Recoverable Error", |
|
"Starting", "Stopping", "Stopped", "In Service", "No Contact", |
|
"Lost Communication"}; |
|
|
|
Boolean AuditLogger::_auditLogFlag = false; |
|
|
|
AuditLogger::PEGASUS_AUDITLOGINITIALIZE_CALLBACK_T |
|
AuditLogger::_auditLogInitializeCallback = 0; |
|
|
|
AuditLogger::PEGASUS_AUDITLOG_CALLBACK_T AuditLogger::_writeAuditMessageToFile = |
|
AuditLogger::_writeAuditMessage; |
|
|
|
void AuditLogger::logCurrentConfig( |
|
const Array<String> & propertyNames, |
|
const Array<String> & propertyValues) |
|
{ |
|
for (Uint32 i = 0; i < propertyNames.size(); i++) |
|
{ |
|
String propertyStr = propertyNames[i] + "=" + propertyValues[i]; |
|
|
|
MessageLoaderParms msgParms("Common.AuditLogger.CURRENT_CONFIG", |
|
"cimserver configuration $0", propertyStr); |
|
|
|
_writeAuditMessageToFile(TYPE_CONFIGURATION, |
|
SUBTYPE_CURRENT_CONFIGURATION, |
|
EVENT_START_UP, Logger::INFORMATION, msgParms); |
|
} |
|
} |
|
|
|
void AuditLogger::logCurrentRegProvider( |
|
const Array < CIMInstance > & instances) |
|
{ |
|
String moduleName; |
|
Array<Uint16> moduleStatus; |
|
String statusValue; |
|
Uint32 pos; |
|
|
|
// get all the registered provider module names and status |
|
for (Uint32 i = 0; i <instances.size(); i++) |
|
{ |
|
instances[i].getProperty(instances[i].findProperty( |
|
_PROPERTY_PROVIDERMODULE_NAME)).getValue().get(moduleName); |
|
|
|
pos = instances[i].findProperty(_PROPERTY_OPERATIONALSTATUS); |
|
|
|
if (pos == PEG_NOT_FOUND) |
|
{ |
|
moduleStatus.append(0); |
|
} |
|
else |
|
{ |
|
CIMValue theValue = instances[i].getProperty(pos).getValue(); |
|
|
|
if (theValue.isNull()) |
|
{ |
|
moduleStatus.append(0); |
|
} |
|
else |
|
{ |
|
theValue.get(moduleStatus); |
|
} |
|
} |
|
|
|
statusValue = _getModuleStatusValue(moduleStatus); |
|
|
|
MessageLoaderParms msgParms( |
|
"Common.AuditLogger.CURRENT_PROVIDER_REGISTRATION", |
|
"Provider module \"$0\" has status \"$1\".", |
|
moduleName, statusValue); |
|
|
|
_writeAuditMessageToFile(TYPE_CONFIGURATION, |
|
SUBTYPE_CURRENT_PROVIDER_REGISTRATION, |
|
EVENT_START_UP, Logger::INFORMATION, msgParms); |
|
} |
|
} |
|
|
|
void AuditLogger::logCurrentEnvironmentVar() |
|
{ |
|
#ifdef PEGASUS_OS_DARWIN |
|
char** envp = *_NSGetEnviron(); |
|
#else | #else |
char** envp = environ; |
# include "AuditLoggerToLog.cpp" |
#endif | #endif |
| |
Uint32 i = 0; |
|
|
|
while (envp[i]) |
|
{ |
|
MessageLoaderParms msgParms("Common.AuditLogger.CURRENT_ENV", |
|
"cimserver environment variable: $0", envp[i]); |
|
|
|
_writeAuditMessageToFile(TYPE_CONFIGURATION, |
|
SUBTYPE_CURRENT_ENVIRONMENT_VARIABLES, |
|
EVENT_START_UP, Logger::INFORMATION, msgParms); |
|
|
|
i++; |
|
} |
|
} |
|
|
|
void AuditLogger::logSetConfigProperty( |
|
const String & userName, |
|
const String & propertyName, |
|
const String & prePropertyValue, |
|
const String & newPropertyValue, |
|
Boolean isPlanned) |
|
{ |
|
if (isPlanned) |
|
{ |
|
MessageLoaderParms msgParms( |
|
"Common.AuditLogger.SET_PLANNED_CONFIG_PROPERTY", |
|
"The planned value of property \"$0\" is modified from " |
|
"value \"$1\" to value \"$2\" by user \"$3\".", |
|
propertyName, prePropertyValue, newPropertyValue, userName); |
|
|
|
_writeAuditMessageToFile(TYPE_CONFIGURATION, |
|
SUBTYPE_CONFIGURATION_CHANGE, |
|
EVENT_UPDATE, Logger::INFORMATION, msgParms); |
|
} |
|
else |
|
{ |
|
MessageLoaderParms msgParms( |
|
"Common.AuditLogger.SET_CURRENT_CONFIG_PROPERTY", |
|
"The current value of property \"$0\" is modified from " |
|
"value \"$1\" to value \"$2\" by user \"$3\".", |
|
propertyName, prePropertyValue, newPropertyValue, userName); |
|
|
|
_writeAuditMessageToFile(TYPE_CONFIGURATION, |
|
SUBTYPE_CONFIGURATION_CHANGE, |
|
EVENT_UPDATE, Logger::INFORMATION, msgParms); |
|
} |
|
} |
|
|
|
void AuditLogger::logUpdateClassOperation( |
|
const char* cimMethodName, |
|
AuditEvent eventType, |
|
const String& userName, |
|
const String& ipAddr, |
|
const CIMNamespaceName& nameSpace, |
|
const CIMName& className, |
|
CIMStatusCode statusCode) |
|
{ |
|
MessageLoaderParms msgParms( |
|
"Common.AuditLogger.OPERATION_UPDATE_CLASS", |
|
"A CIM $0 operation on class \"$1\" in namespace \"$2\" by user " |
|
"\"$3\" connected from system \"$4\" resulted in status \"$5\".", |
|
cimMethodName, |
|
className.getString(), |
|
nameSpace.getString(), |
|
userName, |
|
ipAddr, |
|
cimStatusCodeToString(statusCode)); |
|
|
|
_writeAuditMessageToFile(TYPE_CIMOPERATION, SUBTYPE_SCHEMA_OPERATION, |
|
eventType, Logger::INFORMATION, msgParms); |
|
} |
|
|
|
void AuditLogger::logUpdateQualifierOperation( |
|
const char* cimMethodName, |
|
AuditEvent eventType, |
|
const String& userName, |
|
const String& ipAddr, |
|
const CIMNamespaceName& nameSpace, |
|
const CIMName& className, |
|
CIMStatusCode statusCode) |
|
{ |
|
MessageLoaderParms msgParms( |
|
"Common.AuditLogger.OPERATION_UPDATE_QUALIFIER", |
|
"A CIM $0 operation on qualifier \"$1\" in namespace \"$2\" by user " |
|
"\"$3\" connected from system \"$4\" resulted in status \"$5\".", |
|
cimMethodName, |
|
className.getString(), |
|
nameSpace.getString(), |
|
userName, |
|
ipAddr, |
|
cimStatusCodeToString(statusCode)); |
|
|
|
_writeAuditMessageToFile(TYPE_CIMOPERATION, SUBTYPE_SCHEMA_OPERATION, |
|
eventType, Logger::INFORMATION, msgParms); |
|
} |
|
|
|
void AuditLogger::logUpdateInstanceOperation( |
|
const char* cimMethodName, |
|
AuditEvent eventType, |
|
const String& userName, |
|
const String& ipAddr, |
|
const CIMNamespaceName& nameSpace, |
|
const CIMObjectPath& instanceName, |
|
const String& moduleName, |
|
const String& providerName, |
|
CIMStatusCode statusCode) |
|
{ |
|
if (providerName != String::EMPTY) |
|
{ |
|
MessageLoaderParms msgParms( |
|
"Common.AuditLogger.OPERATION_UPDATE_INSTANCE_WITH_PROVIDER", |
|
"A CIM $0 operation on instance \"$1\" in namespace \"$2\" by " |
|
"user \"$3\" connected from system \"$4\" resulted in " |
|
"status \"$5\". " |
|
"The provider for this operation is \"$6\" in module \"$7\".", |
|
cimMethodName, |
|
CIMObjectPath("", CIMNamespaceName(), instanceName.getClassName(), |
|
instanceName.getKeyBindings()).toString(), |
|
nameSpace.getString(), |
|
userName, |
|
ipAddr, |
|
cimStatusCodeToString(statusCode), |
|
providerName, |
|
moduleName); |
|
|
|
_writeAuditMessageToFile(TYPE_CIMOPERATION, SUBTYPE_INSTANCE_OPERATION, |
|
eventType, Logger::INFORMATION, msgParms); |
|
} |
|
else |
|
{ |
|
MessageLoaderParms msgParms( |
|
"Common.AuditLogger.OPERATION_UPDATE_INSTANCE", |
|
"A CIM $0 operation on instance \"$1\" in namespace \"$2\" by " |
|
"user \"$3\" connected from system \"$4\" resulted in " |
|
"status \"$5\". ", |
|
cimMethodName, |
|
CIMObjectPath("", CIMNamespaceName(), instanceName.getClassName(), |
|
instanceName.getKeyBindings()).toString(), |
|
nameSpace.getString(), |
|
userName, |
|
ipAddr, |
|
cimStatusCodeToString(statusCode)); |
|
|
|
_writeAuditMessageToFile(TYPE_CIMOPERATION, SUBTYPE_INSTANCE_OPERATION, |
|
eventType, Logger::INFORMATION, msgParms); |
|
} |
|
} |
|
|
|
void AuditLogger::logInvokeMethodOperation( |
|
const String& userName, |
|
const String& ipAddr, |
|
const CIMNamespaceName& nameSpace, |
|
const CIMObjectPath& objectName, |
|
const CIMName& methodName, |
|
const String& moduleName, |
|
const String& providerName, |
|
CIMStatusCode statusCode) |
|
{ |
|
if (providerName != String::EMPTY) |
|
{ |
|
MessageLoaderParms msgParms( |
|
"Common.AuditLogger.OPERATION_INVOKE_METHOD_WITH_PROVIDER", |
|
"A CIM InvokeMethod operation on method \"$0\" of object \"$1\" " |
|
"in namespace \"$2\" by user \"$3\" connected from system " |
|
"\"$4\" resulted in status \"$5\". The provider for this " |
|
"operation is \"$6\" in module \"$7\".", |
|
methodName.getString(), |
|
CIMObjectPath("", CIMNamespaceName(), objectName.getClassName(), |
|
objectName.getKeyBindings()).toString(), |
|
nameSpace.getString(), |
|
userName, |
|
ipAddr, |
|
cimStatusCodeToString(statusCode), |
|
providerName, |
|
moduleName); |
|
|
|
_writeAuditMessageToFile(TYPE_CIMOPERATION, SUBTYPE_INSTANCE_OPERATION, |
|
EVENT_INVOKE, Logger::INFORMATION, msgParms); |
|
} |
|
else |
|
{ |
|
MessageLoaderParms msgParms( |
|
"Common.AuditLogger.OPERATION_INVOKE_METHOD", |
|
"A CIM InvokeMethod operation on method \"$0\" of object \"$1\" " |
|
"in namespace \"$2\" by user \"$3\" connected from system " |
|
"\"$4\" resulted in status \"$5\".", |
|
methodName.getString(), |
|
CIMObjectPath("", CIMNamespaceName(), objectName.getClassName(), |
|
objectName.getKeyBindings()).toString(), |
|
nameSpace.getString(), |
|
userName, |
|
ipAddr, |
|
cimStatusCodeToString(statusCode)); |
|
|
|
_writeAuditMessageToFile(TYPE_CIMOPERATION, SUBTYPE_INSTANCE_OPERATION, |
|
EVENT_INVOKE, Logger::INFORMATION, msgParms); |
|
} |
|
} |
|
|
|
void AuditLogger::logUpdateProvModuleStatus( |
|
const String & moduleName, |
|
const Array<Uint16> currentModuleStatus, |
|
const Array<Uint16> newModuleStatus) |
|
{ |
|
String currentModuleStatusValue = |
|
_getModuleStatusValue(currentModuleStatus); |
|
|
|
String newModuleStatusValue = _getModuleStatusValue(newModuleStatus); |
|
|
|
MessageLoaderParms msgParms( |
|
"Common.AuditLogger.UPDATE_PROVIDER_MODULE_STATUS", |
|
"The operational status of module \"$0\" has changed from \"$1\"" |
|
" to \"$2\".", |
|
moduleName, currentModuleStatusValue, newModuleStatusValue); |
|
|
|
_writeAuditMessageToFile(TYPE_CONFIGURATION, |
|
SUBTYPE_PROVIDER_MODULE_STATUS_CHANGE, |
|
EVENT_UPDATE, Logger::INFORMATION, msgParms); |
|
} |
|
|
|
void AuditLogger::logLocalAuthentication( |
|
const String& userName, |
|
Boolean successful) |
|
{ |
|
MessageLoaderParms msgParms( |
|
"Common.AuditLogger.LOCAL_AUTHENTICATION", |
|
"Local authentication attempt: " |
|
"successful = $0, user = $1. ", |
|
CIMValue(successful).toString(), |
|
userName); |
|
|
|
_writeAuditMessageToFile( |
|
TYPE_AUTHENTICATION, |
|
SUBTYPE_LOCAL_AUTHENTICATION, |
|
successful ? EVENT_AUTH_SUCCESS : EVENT_AUTH_FAILURE, |
|
successful ? Logger::INFORMATION : Logger::WARNING, |
|
msgParms); |
|
} |
|
|
|
void AuditLogger::logBasicAuthentication( |
|
const String& userName, |
|
const String& ipAddr, |
|
Boolean successful) |
|
{ |
|
MessageLoaderParms msgParms( |
|
"Common.AuditLogger.BASIC_AUTHENTICATION", |
|
"Basic authentication attempt: " |
|
"successful = $0, user = $1, IP address = $2.", |
|
CIMValue(successful).toString(), |
|
userName, |
|
ipAddr); |
|
|
|
_writeAuditMessageToFile( TYPE_AUTHENTICATION, |
|
SUBTYPE_BASIC_AUTHENTICATION, |
|
successful ? EVENT_AUTH_SUCCESS : EVENT_AUTH_FAILURE, |
|
successful ? Logger::INFORMATION: Logger::WARNING, |
|
msgParms); |
|
} |
|
|
|
void AuditLogger::logCertificateBasedAuthentication( |
|
const String& issuerName, |
|
const String& subjectName, |
|
const String& serialNumber, |
|
const String& ipAddr, |
|
Boolean successful) |
|
{ |
|
MessageLoaderParms msgParms( |
|
"Common.AuditLogger.CERTIFICATE_BASED_AUTHENTICATION", |
|
"Certificate based authentication attempt: " |
|
"successful = $0, issuer = $1, subject = $2, serialNumber = $3, " |
|
"IP address = $4.", |
|
CIMValue(successful).toString(), |
|
issuerName, |
|
subjectName, |
|
serialNumber, |
|
ipAddr); |
|
|
|
_writeAuditMessageToFile(TYPE_AUTHENTICATION, |
|
SUBTYPE_CERTIFICATE_BASED_AUTHENTICATION, |
|
successful ? EVENT_AUTH_SUCCESS : EVENT_AUTH_FAILURE, |
|
successful ? Logger::INFORMATION: Logger::WARNING, |
|
msgParms); |
|
} |
|
|
|
void AuditLogger::logCertificateBasedUserValidation( |
|
const String& userName, |
|
const String& issuerName, |
|
const String& subjectName, |
|
const String& serialNumber, |
|
const String& ipAddr, |
|
Boolean successful) |
|
{ |
|
MessageLoaderParms msgParms( |
|
"Common.AuditLogger.CERTIFICATE_BASED_USER_VALIDATION", |
|
"Certificate based user validation attempt: " |
|
"successful = $0, userName = $1, issuer = $2, subject = $3, " |
|
"serialNumber = $4, IP address = $5.", |
|
CIMValue(successful).toString(), |
|
userName, |
|
issuerName, |
|
subjectName, |
|
serialNumber, |
|
ipAddr); |
|
|
|
_writeAuditMessageToFile( TYPE_AUTHORIZATION, |
|
SUBTYPE_CERTIFICATE_BASED_USER_VALIDATION, |
|
successful ? EVENT_AUTH_SUCCESS : EVENT_AUTH_FAILURE, |
|
successful ? Logger::INFORMATION: Logger::WARNING, |
|
msgParms); |
|
} |
|
|
|
void AuditLogger::setInitializeCallback( |
|
PEGASUS_AUDITLOGINITIALIZE_CALLBACK_T auditLogInitializeCallback) |
|
{ |
|
_auditLogInitializeCallback = auditLogInitializeCallback; |
|
} |
|
|
|
void AuditLogger::setEnabled(Boolean enabled) |
|
{ |
|
// Only write the enable/disable messages if we are set up to handle them |
|
if (_auditLogInitializeCallback != 0) |
|
{ |
|
if (enabled) |
|
{ |
|
if (!_auditLogFlag) |
|
{ |
|
_auditLogInitializeCallback(); |
|
|
|
MessageLoaderParms msgParms( |
|
"Common.AuditLogger.ENABLE_AUDIT_LOG", |
|
"Audit logging is enabled."); |
|
|
|
_writeAuditMessageToFile(TYPE_CONFIGURATION, |
|
SUBTYPE_CONFIGURATION_CHANGE, |
|
EVENT_UPDATE, Logger::INFORMATION, msgParms); |
|
} |
|
} |
|
else |
|
{ |
|
if (_auditLogFlag) |
|
{ |
|
MessageLoaderParms msgParms( |
|
"Common.AuditLogger.DISABLE_AUDIT_LOG", |
|
"Audit logging is disabled."); |
|
|
|
_writeAuditMessageToFile(TYPE_CONFIGURATION, |
|
SUBTYPE_CONFIGURATION_CHANGE, |
|
EVENT_UPDATE, Logger::INFORMATION, msgParms); |
|
} |
|
} |
|
} |
|
|
|
_auditLogFlag = enabled; |
|
} |
|
|
|
void AuditLogger::writeAuditLogToFileCallback( |
|
PEGASUS_AUDITLOG_CALLBACK_T writeAuditLogToFileCallback) |
|
{ |
|
_writeAuditMessageToFile = writeAuditLogToFileCallback; |
|
} |
|
|
|
void AuditLogger::_writeAuditMessage( |
|
AuditType auditType, |
|
AuditSubType auditSubType, |
|
AuditEvent auditEvent, |
|
Uint32 logLevel, |
|
MessageLoaderParms & msgParms) |
|
{ |
|
String localizedMsg = MessageLoader::getMessage(msgParms); |
|
|
|
String identifier = "cimserver audit"; |
|
|
|
Logger::put(Logger::AUDIT_LOG, identifier, logLevel, localizedMsg); |
|
} |
|
|
|
String AuditLogger::_getModuleStatusValue( |
|
const Array<Uint16> moduleStatus) |
|
{ |
|
String moduleStatusValue, statusValue; |
|
Uint32 moduleStatusSize = moduleStatus.size(); |
|
|
|
for (Uint32 j=0; j < moduleStatusSize; j++) |
|
{ |
|
statusValue = providerModuleStatus[moduleStatus[j]]; |
|
moduleStatusValue.append(statusValue); |
|
|
|
if (j < moduleStatusSize - 1) |
|
{ |
|
moduleStatusValue.append(","); |
|
} |
|
} |
|
|
|
return moduleStatusValue; |
|
} |
|
|
|
PEGASUS_NAMESPACE_END |
|
|
|
#endif |
|