2c8668479c
to be able to deliver the client component onto distributions targeting desktops without having to deliver the server components. This commit is for the resulting client project.
687 lines
21 KiB
C
687 lines
21 KiB
C
/***********************************************************************
|
|
*
|
|
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; version 2.1
|
|
* of the License.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, Novell, Inc.
|
|
*
|
|
* To contact Novell about this file by physical or electronic mail,
|
|
* you may find current contact information at www.novell.com.
|
|
*
|
|
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
|
*
|
|
***********************************************************************/
|
|
|
|
|
|
//===[ Include files ]=====================================================
|
|
|
|
#include "internal.h"
|
|
|
|
//===[ Type definitions ]==================================================
|
|
|
|
//
|
|
// Config Key object
|
|
//
|
|
typedef struct _ConfigKey
|
|
{
|
|
LIST_ENTRY listEntry;
|
|
char *pKeyName;
|
|
int keyNameLen;
|
|
char *pValue;
|
|
int valueLen;
|
|
|
|
} ConfigKey, *pConfigKey;
|
|
|
|
//
|
|
// Config Interface instance data
|
|
//
|
|
typedef struct _ConfigIfInstance
|
|
{
|
|
LIST_ENTRY listEntry;
|
|
int refCount;
|
|
char *pConfigFolder;
|
|
int configFolderLen;
|
|
char *pConfigName;
|
|
int configNameLen;
|
|
LIST_ENTRY configKeyListHead;
|
|
ConfigIf configIf;
|
|
|
|
} ConfigIfInstance, *PConfigIfInstance;
|
|
|
|
//===[ Function prototypes ]===============================================
|
|
|
|
//===[ Global variables ]==================================================
|
|
|
|
// ConfigIf variables
|
|
static
|
|
LIST_ENTRY g_configIfListHead = {&g_configIfListHead, &g_configIfListHead};
|
|
|
|
static
|
|
int g_numConfigIfObjs = 0;
|
|
|
|
|
|
//++=======================================================================
|
|
static void
|
|
RemoveWhiteSpaceFromTheEnd(
|
|
IN const char *pInString)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Notes:
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
char *pLineEnd = (char*) pInString + strlen(pInString) - 1;
|
|
|
|
|
|
DbgTrace(3, "-RemoveWhiteSpaceFromTheEnd- Start\n", 0);
|
|
|
|
while (pLineEnd != pInString)
|
|
{
|
|
if (*pLineEnd == '\n'
|
|
|| *pLineEnd == ' '
|
|
|| *pLineEnd == '\t')
|
|
{
|
|
// Strike this character
|
|
*pLineEnd = '\0';
|
|
pLineEnd --;
|
|
}
|
|
else
|
|
{
|
|
// Found a non-white character
|
|
break;
|
|
}
|
|
}
|
|
|
|
DbgTrace(3, "-RemoveWhiteSpaceFromTheEnd- End\n", 0);
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
static char*
|
|
SkipWhiteSpace(
|
|
IN const char *pInString)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Notes:
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
char *pOutString = (char*) pInString;
|
|
|
|
DbgTrace(3, "-SkipWhiteSpace- Start\n", 0);
|
|
|
|
while (*pOutString != '\0')
|
|
{
|
|
if (*pOutString == '\n'
|
|
|| *pOutString == ' '
|
|
|| *pOutString == '\t')
|
|
{
|
|
// Skip this character
|
|
pOutString ++;
|
|
}
|
|
else
|
|
{
|
|
// Found a non-white character
|
|
break;
|
|
}
|
|
}
|
|
|
|
DbgTrace(3, "-SkipWhiteSpace- End\n", 0);
|
|
|
|
return pOutString;
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
static char*
|
|
SkipNonWhiteSpace(
|
|
IN const char *pInString)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Notes:
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
char *pOutString = (char*) pInString;
|
|
|
|
DbgTrace(3, "-SkipNonWhiteSpace- Start\n", 0);
|
|
|
|
while (*pOutString != '\0')
|
|
{
|
|
if (*pOutString == '\n'
|
|
|| *pOutString == ' '
|
|
|| *pOutString == '\t')
|
|
{
|
|
// Found a white character
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// Skip this character
|
|
pOutString ++;
|
|
}
|
|
}
|
|
|
|
DbgTrace(3, "-SkipNonWhiteSpace- End\n", 0);
|
|
|
|
return pOutString;
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
static void
|
|
LowerCaseString(
|
|
IN char *pDestString,
|
|
IN const char *pSrcString)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Abstract:
|
|
//
|
|
// Notes:
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
int i;
|
|
|
|
DbgTrace(3, "-LowerCaseString- Start\n", 0);
|
|
|
|
// Copy the string as lower case
|
|
for (i = 0; pSrcString[i] != '\0'; i++)
|
|
{
|
|
if (isalpha(pSrcString[i]))
|
|
pDestString[i] = tolower(pSrcString[i]);
|
|
else
|
|
pDestString[i] = pSrcString[i];
|
|
}
|
|
|
|
// Null terminate the destination string
|
|
pDestString[i] = '\0';
|
|
|
|
DbgTrace(3, "-LowerCaseString- End\n", 0);
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
int SSCS_CALL
|
|
ConfigIf_AddReference(
|
|
IN const void *pIfInstance)
|
|
//
|
|
// Arguments:
|
|
// pIfInstance -
|
|
// Pointer to interface object.
|
|
//
|
|
// Returns:
|
|
// Interface reference count.
|
|
//
|
|
// Description:
|
|
// Increases interface reference count.
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
int refCount;
|
|
ConfigIfInstance *pConfigIfInstance = CONTAINING_RECORD(pIfInstance, ConfigIfInstance, configIf);
|
|
|
|
DbgTrace(2, "-ConfigIf_AddReference- Start\n", 0);
|
|
|
|
// Increment the reference count on the object
|
|
pConfigIfInstance->refCount ++;
|
|
refCount = pConfigIfInstance->refCount;
|
|
|
|
DbgTrace(2, "-ConfigIf_AddReference- End, refCount = %08X\n", refCount);
|
|
|
|
return refCount;
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
void SSCS_CALL
|
|
ConfigIf_ReleaseReference(
|
|
IN const void *pIfInstance)
|
|
//
|
|
// Arguments:
|
|
// pIfInstance -
|
|
// Pointer to interface object.
|
|
//
|
|
// Returns:
|
|
// Nothing.
|
|
//
|
|
// Description:
|
|
// Decreases interface reference count. The interface is deallocated if
|
|
// the reference count becomes zero.
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
bool freeObj = false;
|
|
ConfigIfInstance *pConfigIfInstance = CONTAINING_RECORD(pIfInstance, ConfigIfInstance, configIf);
|
|
|
|
DbgTrace(2, "-ConfigIf_ReleaseReference- Start\n", 0);
|
|
|
|
// Decrement the reference count on the object and determine if it needs to
|
|
// be released.
|
|
pConfigIfInstance->refCount --;
|
|
if (pConfigIfInstance->refCount == 0)
|
|
{
|
|
// The object needs to be released, forget about it.
|
|
freeObj = true;
|
|
g_numConfigIfObjs --;
|
|
RemoveEntryList(&pConfigIfInstance->listEntry);
|
|
}
|
|
|
|
// Free object if necessary
|
|
if (freeObj)
|
|
{
|
|
// Free all of the config key objects associated with this configuration
|
|
// interface instance.
|
|
while (!IsListEmpty(&pConfigIfInstance->configKeyListHead))
|
|
{
|
|
LIST_ENTRY *pListEntry;
|
|
ConfigKey *pConfigKey;
|
|
|
|
// Get reference to entry at the head of the list
|
|
pListEntry = pConfigIfInstance->configKeyListHead.Flink;
|
|
pConfigKey = CONTAINING_RECORD(pListEntry, ConfigKey, listEntry);
|
|
|
|
// Free the buffers associated with the ConfigKey
|
|
free(pConfigKey->pKeyName);
|
|
free(pConfigKey->pValue);
|
|
|
|
// Remove the entry from the list
|
|
RemoveEntryList(&pConfigKey->listEntry);
|
|
|
|
// Finish freeing the ConfigKey
|
|
free(pConfigKey);
|
|
}
|
|
|
|
// Free the rest of the buffers associated with the interface instance data
|
|
free(pConfigIfInstance->pConfigFolder);
|
|
free(pConfigIfInstance->pConfigName);
|
|
free(pConfigIfInstance);
|
|
}
|
|
|
|
DbgTrace(2, "-ConfigIf_ReleaseReference- End\n", 0);
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
char* SSCS_CALL
|
|
ConfigIf_GetEntryValue(
|
|
IN const void *pIfInstance,
|
|
IN const char *pKeyName)
|
|
//
|
|
// Arguments:
|
|
// pIfInstance -
|
|
// Pointer to interface object.
|
|
//
|
|
// pKeyName -
|
|
// Pointer to NULL terminated string that contains the
|
|
// name of the key whose value is being requested.
|
|
//
|
|
// Returns:
|
|
// Pointer to NULL terminated string with value being requested or NULL.
|
|
//
|
|
// Description:
|
|
// Gets value associated with a key for the configuration object.
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
ConfigIfInstance *pConfigIfInstance = CONTAINING_RECORD(pIfInstance, ConfigIfInstance, configIf);
|
|
char *pValue = NULL;
|
|
LIST_ENTRY *pListEntry;
|
|
ConfigKey *pConfigKey;
|
|
int keyNameLen = (int) strlen(pKeyName);
|
|
char *pKeyNameLowercase;
|
|
|
|
DbgTrace(2, "-ConfigIf_GetEntryValue- Start\n", 0);
|
|
|
|
// Allocate enough space to hold lower case version of the key name
|
|
pKeyNameLowercase = (char*) malloc(keyNameLen + 1);
|
|
if (pKeyNameLowercase)
|
|
{
|
|
// Lower case the key name
|
|
LowerCaseString(pKeyNameLowercase, pKeyName);
|
|
|
|
// Try to find matching ConfigKey
|
|
pListEntry = pConfigIfInstance->configKeyListHead.Flink;
|
|
while (pListEntry != &pConfigIfInstance->configKeyListHead)
|
|
{
|
|
// Get pointer to the current entry
|
|
pConfigKey = CONTAINING_RECORD(pListEntry, ConfigKey, listEntry);
|
|
|
|
// Check if we have a match
|
|
if (pConfigKey->keyNameLen == keyNameLen
|
|
&& memcmp(pKeyNameLowercase, pConfigKey->pKeyName, keyNameLen) == 0)
|
|
{
|
|
// We found it, return its value.
|
|
pValue = (char*) malloc(pConfigKey->valueLen + 1);
|
|
if (pValue)
|
|
{
|
|
strcpy(pValue, pConfigKey->pValue);
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-ConfigIf_GetEntryValue- Buffer allocation failure\n", 0);
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Advance to the next entry
|
|
pListEntry = pListEntry->Flink;
|
|
}
|
|
|
|
// Free the lower case version of the key name
|
|
free(pKeyNameLowercase);
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-ConfigIf_GetEntryValue- Buffer allocation failure\n", 0);
|
|
}
|
|
|
|
DbgTrace(2, "-ConfigIf_GetEntryValue- End, pValue = %08X\n", (unsigned int) pValue);
|
|
|
|
return pValue;
|
|
}
|
|
|
|
|
|
|
|
//++=======================================================================
|
|
CasaStatus
|
|
GetConfigInterface(
|
|
IN const char *pConfigFolder,
|
|
IN const char *pConfigName,
|
|
INOUT ConfigIf **ppConfigIf)
|
|
//
|
|
// Arguments:
|
|
// pConfigFolder -
|
|
// Pointer to NULL terminated string that contains the name of
|
|
// the folder containing the configuration file.
|
|
//
|
|
// pConfigName -
|
|
// Pointer to NULL terminated string containing the name of the
|
|
// configuration entry.
|
|
//
|
|
// ppConfigIf -
|
|
// Pointer to variable that will receive pointer to ConfigIf
|
|
// instance.
|
|
//
|
|
// Returns:
|
|
// Casa Status
|
|
//
|
|
// Description:
|
|
// Get configuration interface to specified configuration entry.
|
|
//
|
|
// L2
|
|
//=======================================================================--
|
|
{
|
|
int configFolderLen = (int) strlen(pConfigFolder);
|
|
int configNameLen = (int)strlen(pConfigName);
|
|
ConfigIfInstance *pConfigIfInstance;
|
|
LIST_ENTRY *pListEntry;
|
|
CasaStatus retStatus = CasaStatusBuild(CASA_SEVERITY_INFORMATIONAL,
|
|
CASA_FACILITY_AUTHTOKEN,
|
|
CASA_STATUS_OBJECT_NOT_FOUND);
|
|
|
|
DbgTrace(2, "-GetConfigInterface- Start\n", 0);
|
|
|
|
// Check if we already have an entry in our list for the configuration
|
|
pListEntry = g_configIfListHead.Flink;
|
|
while (pListEntry != &g_configIfListHead)
|
|
{
|
|
// Get pointer to the current entry
|
|
pConfigIfInstance = CONTAINING_RECORD(pListEntry, ConfigIfInstance, listEntry);
|
|
|
|
// Check if we have a match
|
|
if (pConfigIfInstance->configFolderLen == configFolderLen
|
|
&& pConfigIfInstance->configNameLen == configNameLen
|
|
&& memcmp(pConfigFolder, pConfigIfInstance->pConfigFolder, configFolderLen) == 0
|
|
&& memcmp(pConfigName, pConfigIfInstance->pConfigName, configNameLen) == 0)
|
|
{
|
|
// We found it, return the ConfigIf associated with the instance data
|
|
// after incrementing its reference count.
|
|
pConfigIfInstance->refCount ++;
|
|
*ppConfigIf = &pConfigIfInstance->configIf;
|
|
|
|
// Success
|
|
retStatus = CASA_STATUS_SUCCESS;
|
|
break;
|
|
}
|
|
|
|
// Advance to the next entry
|
|
pListEntry = pListEntry->Flink;
|
|
}
|
|
|
|
// Proceed to create interface instance data for the configuration if none was found
|
|
if (retStatus != CASA_STATUS_SUCCESS)
|
|
{
|
|
char *pFilePath;
|
|
|
|
// Build a string containing the configuration file path
|
|
pFilePath = (char*) malloc(configFolderLen + 1 + configNameLen + sizeof(".conf"));
|
|
if (pFilePath)
|
|
{
|
|
FILE *pConfigFile;
|
|
|
|
strcpy(pFilePath, pConfigFolder);
|
|
strcat(pFilePath, pathCharString);
|
|
strcat(pFilePath, pConfigName);
|
|
strcat(pFilePath, ".conf");
|
|
|
|
// Open the configuration file for reading
|
|
pConfigFile = fopen(pFilePath, "r");
|
|
if (pConfigFile)
|
|
{
|
|
// Opened the file, create a ConfigIfInstance object for it.
|
|
pConfigIfInstance = (ConfigIfInstance*) malloc(sizeof(*pConfigIfInstance));
|
|
if (pConfigIfInstance)
|
|
{
|
|
// Initialize the list head within the instance data
|
|
InitializeListHead(&pConfigIfInstance->configKeyListHead);
|
|
|
|
// Initialize the ConfigIf within the instance data
|
|
pConfigIfInstance->configIf.addReference = ConfigIf_AddReference;
|
|
pConfigIfInstance->configIf.releaseReference = ConfigIf_ReleaseReference;
|
|
pConfigIfInstance->configIf.getEntryValue = ConfigIf_GetEntryValue;
|
|
|
|
// Save the ConfigFolder and ConfigName information within the instance data
|
|
pConfigIfInstance->pConfigFolder = (char*) malloc(configFolderLen + 1);
|
|
if (pConfigIfInstance->pConfigFolder)
|
|
{
|
|
strcpy(pConfigIfInstance->pConfigFolder, pConfigFolder);
|
|
pConfigIfInstance->configFolderLen = configFolderLen;
|
|
|
|
pConfigIfInstance->pConfigName = (char*) malloc(configNameLen + 1);
|
|
if (pConfigIfInstance->pConfigName)
|
|
{
|
|
strcpy(pConfigIfInstance->pConfigName, pConfigName);
|
|
pConfigIfInstance->configNameLen = configNameLen;
|
|
|
|
// Add the instance data into our list and bump up its reference count
|
|
// since we did that.
|
|
InsertTailList(&g_configIfListHead, &pConfigIfInstance->listEntry);
|
|
pConfigIfInstance->refCount = 1;
|
|
|
|
// At this point we want to return success to the caller even if we
|
|
// experience a read error.
|
|
retStatus = CASA_STATUS_SUCCESS;
|
|
|
|
// Return the ConfigIf associated with the instance data after
|
|
// incrementing its reference count.
|
|
pConfigIfInstance->refCount ++;
|
|
*ppConfigIf = &pConfigIfInstance->configIf;
|
|
|
|
// Now update the instance data with the information present in the file
|
|
if (fseek(pConfigFile, 0, SEEK_SET) == 0)
|
|
{
|
|
char line[512];
|
|
|
|
while (fgets(line, sizeof(line), pConfigFile) != NULL)
|
|
{
|
|
int lineLength;
|
|
|
|
RemoveWhiteSpaceFromTheEnd(line);
|
|
|
|
lineLength = (int) strlen(line);
|
|
if (lineLength != 0)
|
|
{
|
|
char *pKey;
|
|
char *pKeyEnd;
|
|
char *pValue;
|
|
ConfigKey *pConfigKey;
|
|
|
|
// Attempt to find the key
|
|
pKey = SkipWhiteSpace(line);
|
|
|
|
// Make sure that we are not dealing with an empty line or a comment
|
|
if (*pKey == '\0' || *pKey == '#')
|
|
continue;
|
|
|
|
// Go past the key
|
|
pKeyEnd = SkipNonWhiteSpace(pKey);
|
|
|
|
// Protect against a malformed line
|
|
if (*pKeyEnd == '\0')
|
|
{
|
|
DbgTrace(0, "-GetConfigInterface- Key found without value\n", 0);
|
|
continue;
|
|
}
|
|
|
|
// Attempt to find the value
|
|
pValue = SkipWhiteSpace(pKeyEnd);
|
|
|
|
// Protect against a malformed line
|
|
if (*pValue == '\0')
|
|
{
|
|
DbgTrace(0, "-GetConfigInterface- Key found without value\n", 0);
|
|
continue;
|
|
}
|
|
|
|
// Delineate the key
|
|
*pKeyEnd = '\0';
|
|
|
|
// Create a ConfigKey object for this key/value pair
|
|
pConfigKey = (ConfigKey*) malloc(sizeof(*pConfigKey));
|
|
if (pConfigKey)
|
|
{
|
|
pConfigKey->keyNameLen = (int) strlen(pKey);
|
|
pConfigKey->pKeyName = (char*) malloc(pConfigKey->keyNameLen + 1);
|
|
if (pConfigKey->pKeyName)
|
|
{
|
|
// Save the key name in lower case
|
|
LowerCaseString(pConfigKey->pKeyName, pKey);
|
|
|
|
pConfigKey->valueLen = (int) strlen(pValue);
|
|
pConfigKey->pValue = (char*) malloc(pConfigKey->valueLen + 1);
|
|
if (pConfigKey->pValue)
|
|
{
|
|
strcpy(pConfigKey->pValue, pValue);
|
|
|
|
// The entry is ready, now associate it with the instance data.
|
|
InsertTailList(&pConfigIfInstance->configKeyListHead, &pConfigKey->listEntry);
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-GetConfigInterface- Buffer allocation failure\n", 0);
|
|
free(pConfigKey->pKeyName);
|
|
free(pConfigKey);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-GetConfigInterface- Buffer allocation failure\n", 0);
|
|
free(pConfigKey);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-GetConfigInterface- Buffer allocation failure\n", 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-GetConfigInterface- File seek error, errno = %d\n", errno);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-GetConfigInterface- Buffer allocation failure\n", 0);
|
|
|
|
// Free the buffers associated with the instance data
|
|
free(pConfigIfInstance->pConfigFolder);
|
|
free(pConfigIfInstance);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-GetConfigInterface- Buffer allocation failure\n", 0);
|
|
|
|
// Free the buffer allocated for the instance data
|
|
free(pConfigIfInstance);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-GetConfigInterface- Buffer allocation failure\n", 0);
|
|
}
|
|
|
|
// Close the file
|
|
fclose(pConfigFile);
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-GetConfigInterface- Unable to open config file, errno = %d\n", errno);
|
|
DbgTrace(0, "-GetConfigInterface- Config file unable to open = %s\n", pFilePath);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DbgTrace(0, "-GetConfigInterface- Buffer allocation error\n", 0);
|
|
}
|
|
}
|
|
|
|
DbgTrace(2, "-GetConfigInterface- End, retStatus = %08X\n", retStatus);
|
|
|
|
return retStatus;
|
|
}
|
|
|
|
|
|
//++=======================================================================
|
|
//++=======================================================================
|
|
//++=======================================================================
|
|
|