mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
DirtySDK (EA's Dirty Sockets library) will be used for the LiveAPI implementation, and depends on: EABase, EAThread.
707 lines
22 KiB
C
707 lines
22 KiB
C
/*H********************************************************************************/
|
||
/*!
|
||
\File testerprofile.c
|
||
|
||
\Description
|
||
Maintain user profiles for the tester application.
|
||
|
||
\Notes
|
||
A profile is selected, created, or deleted after client GUI start
|
||
and before anything else happens. Currently, the following items
|
||
will be stored in a tester2 profile: command history, network startup,
|
||
and lobby parameters. Profiles will be stored in a single file on the
|
||
client’s disk, the elements of the profile encoded into tagfields.
|
||
|
||
\Copyright
|
||
Copyright (c) 2005 Electronic Arts Inc.
|
||
|
||
\Version 03/18/2005 (jfrank) First Version
|
||
*/
|
||
/********************************************************************************H*/
|
||
|
||
/*** Include files ****************************************************************/
|
||
|
||
#include <string.h>
|
||
#include <stdlib.h>
|
||
#include <stdio.h>
|
||
#include "DirtySDK/dirtysock.h"
|
||
#include "DirtySDK/util/jsonformat.h"
|
||
#include "DirtySDK/util/jsonparse.h"
|
||
#include "libsample/zmem.h"
|
||
#include "libsample/zlib.h"
|
||
#include "libsample/zfile.h"
|
||
#include "testerprofile.h"
|
||
#include "testerregistry.h"
|
||
|
||
/*** Defines **********************************************************************/
|
||
|
||
/*** Type Definitions *************************************************************/
|
||
|
||
// module state
|
||
struct TesterProfileT
|
||
{
|
||
TesterProfileEntryT Profiles[TESTERPROFILE_NUMPROFILES_DEFAULT]; //!< profile entry list
|
||
uint32_t uProfileTail; //!< tail index for the profile list
|
||
char strFilename[TESTERPROFILE_PROFILEFILENAME_SIZEDEFAULT]; //!< filename for the profile file
|
||
};
|
||
|
||
/*** Variables ********************************************************************/
|
||
|
||
/*** Private Functions ************************************************************/
|
||
|
||
|
||
/*F********************************************************************************/
|
||
/*!
|
||
\Function _TesterProfileGenerateHistoryFilename
|
||
|
||
\Description
|
||
Use an entry's name to generate a history file name
|
||
|
||
\Input *pState - module state
|
||
|
||
\Output int32_t - error codes, 0 if success
|
||
|
||
\Version 03/29/2005 (jfrank)
|
||
*/
|
||
/********************************************************************************F*/
|
||
static void _TesterProfileGenerateHistoryFilename(TesterProfileEntryT *pEntry)
|
||
{
|
||
int32_t iNumChars, iChecksum;
|
||
const char strFileSuffix[] = ".history.txt";
|
||
char strChecksum[16];
|
||
char cReplace;
|
||
|
||
|
||
// check for errors
|
||
if(pEntry == NULL)
|
||
return;
|
||
|
||
// create the history filename
|
||
iChecksum=0;
|
||
ds_memclr(strChecksum, sizeof(strChecksum));
|
||
ds_memclr(pEntry->strHistoryFile, sizeof(pEntry->strHistoryFile));
|
||
for(iNumChars = 0;
|
||
(iNumChars < (signed)sizeof(pEntry->strProfileName)) && (pEntry->strProfileName[iNumChars] != 0);
|
||
iNumChars++)
|
||
{
|
||
cReplace = pEntry->strProfileName[iNumChars];
|
||
iChecksum += (int32_t)cReplace;
|
||
if( ((cReplace >= '0') && (cReplace <= '9')) ||
|
||
((cReplace >= 'a') && (cReplace <= 'z')) ||
|
||
((cReplace >= 'A') && (cReplace <= 'Z')) ||
|
||
((cReplace >= '0') && (cReplace <= '9')) )
|
||
{
|
||
// character OK
|
||
}
|
||
else
|
||
{
|
||
cReplace = '_';
|
||
}
|
||
pEntry->strHistoryFile[iNumChars] = cReplace;
|
||
}
|
||
sprintf(strChecksum, "%d", iChecksum);
|
||
strncat(pEntry->strHistoryFile, strChecksum, sizeof(pEntry->strHistoryFile) - strlen(pEntry->strHistoryFile) - 1);
|
||
strncat(pEntry->strHistoryFile, strFileSuffix, sizeof(pEntry->strHistoryFile) - strlen(pEntry->strHistoryFile) - 1);
|
||
}
|
||
|
||
|
||
/*F********************************************************************************/
|
||
/*!
|
||
\Function _TesterProfileKillAllEntries
|
||
|
||
\Description
|
||
Delete all the profile entries in the profile list
|
||
|
||
\Input *pState - module state to delete all the entries from
|
||
|
||
\Output None
|
||
|
||
\Version 03/29/2005 (jfrank)
|
||
*/
|
||
/********************************************************************************F*/
|
||
static void _TesterProfileKillAllEntries(TesterProfileT *pState)
|
||
{
|
||
pState->uProfileTail = 0;
|
||
ds_memclr(pState->Profiles, sizeof(pState->Profiles));
|
||
}
|
||
|
||
/*F********************************************************************************/
|
||
/*!
|
||
\Function _TesterProfileParseLine
|
||
|
||
\Description
|
||
Take an incoming tagfield and create a profile structure from it
|
||
|
||
\Input *pData - incoming data buffer
|
||
\Input *pEntry - profile entry structure to put the data into
|
||
|
||
\Output None
|
||
|
||
\Version 03/29/2005 (jfrank)
|
||
*/
|
||
/********************************************************************************F*/
|
||
static void _TesterProfileParseLine(char *pData, TesterProfileEntryT *pEntry)
|
||
{
|
||
uint16_t aJson[512];
|
||
|
||
// check error conditions
|
||
if((pData == NULL) || (pEntry == NULL))
|
||
return;
|
||
|
||
// wipe the supplied structure
|
||
ds_memclr(pEntry, sizeof(*pEntry));
|
||
|
||
JsonParse(aJson, sizeof(aJson)/sizeof(*aJson), pData, -1);
|
||
|
||
// populate with data
|
||
JsonGetString(JsonFind(aJson, TESTERPROFILE_PROFILENAME_TAGVALUE), pEntry->strProfileName, sizeof(pEntry->strProfileName), TESTERPROFILE_PROFILENAME_VALUEDEFAULT);
|
||
JsonGetString(JsonFind(aJson, TESTERPROFILE_CONTROLDIR_TAGVALUE), pEntry->strControlDirectory, sizeof(pEntry->strControlDirectory), TESTERPROFILE_CONTROLDIR_VALUEDEFAULT);
|
||
JsonGetString(JsonFind(aJson, TESTERPROFILE_COMMANDLINE_TAGVALUE), pEntry->strCommandLine, sizeof(pEntry->strCommandLine), TESTERPROFILE_COMMANDLINE_VALUEDEFAULT);
|
||
JsonGetString(JsonFind(aJson, TESTERPROFILE_LOGDIRECTORY_TAGVALUE), pEntry->strLogDirectory, sizeof(pEntry->strLogDirectory), TESTERPROFILE_LOGDIRECTORY_VALUEDEFAULT);
|
||
JsonGetString(JsonFind(aJson, TESTERPROFILE_HOSTNAME_TAGVALUE), pEntry->strHostname, sizeof(pEntry->strHostname), TESTERPROFILE_HOSTNAME_VALUEDEFAULT);
|
||
JsonGetString(JsonFind(aJson, TESTERPROFILE_HISTORYFILE_TAGVALUE), pEntry->strHistoryFile, sizeof(pEntry->strHistoryFile), TESTERPROFILE_HISTORYFILE_VALUEDEFAULT);
|
||
pEntry->uLogEnable = (uint8_t)JsonGetInteger(JsonFind(aJson, TESTERPROFILE_LOGENABLE_TAGVALUE), TESTERPROFILE_LOGENABLE_VALUEDEFAULT);
|
||
pEntry->uNetworkStartup = (uint8_t)JsonGetInteger(JsonFind(aJson, TESTERPROFILE_NETWORKSTART_TAGVALUE), TESTERPROFILE_NETWORKSTART_VALUEDEFAULT);
|
||
pEntry->uDefault = (uint8_t)JsonGetInteger(JsonFind(aJson, TESTERPROFILE_DEFAULTPROFILE_TAGVALUE), 0);
|
||
|
||
// create a history file name
|
||
_TesterProfileGenerateHistoryFilename(pEntry);
|
||
}
|
||
|
||
/*F********************************************************************************/
|
||
/*!
|
||
\Function _TesterProfileParseFile
|
||
|
||
\Description
|
||
Take incoming data (from a file) and parse into profile structures
|
||
|
||
\Notes
|
||
This function is destructive and will modify the contents at pData.
|
||
|
||
\Input *pState - module state
|
||
\Input *pData - incoming data buffer
|
||
\Input iSize - amount of data in the buffer
|
||
|
||
\Output None
|
||
|
||
\Version 03/18/2005 (jfrank)
|
||
*/
|
||
/********************************************************************************F*/
|
||
static void _TesterProfileParseFile(TesterProfileT *pState, char *pData)
|
||
{
|
||
const char strSep[] = {"\r\n"};
|
||
char *pDataPtr;
|
||
|
||
// wipe out the previous list in case it exists
|
||
_TesterProfileKillAllEntries(pState);
|
||
|
||
// walk the pData buffer and parse each incoming line
|
||
pDataPtr = (char *)strtok(pData, strSep);
|
||
while(pDataPtr)
|
||
{
|
||
// get an entry based on the line
|
||
_TesterProfileParseLine(pDataPtr, &pState->Profiles[pState->uProfileTail]);
|
||
pDataPtr = (char *)strtok(NULL, strSep);
|
||
pState->uProfileTail++;
|
||
}
|
||
}
|
||
|
||
|
||
/*F********************************************************************************/
|
||
/*!
|
||
\Function _TesterProfileReadFile
|
||
|
||
\Description
|
||
Read a file containing profiles and store it in the profile list.
|
||
|
||
\Input *pState - module state
|
||
|
||
\Output int32_t - error codes, 0 if success
|
||
|
||
\Version 03/29/2005 (jfrank)
|
||
*/
|
||
/********************************************************************************F*/
|
||
static int32_t _TesterProfileReadFile(TesterProfileT *pState)
|
||
{
|
||
char *pProfileString;
|
||
int32_t iFileSize;
|
||
|
||
// load the file in
|
||
pProfileString = ZFileLoad(pState->strFilename, &iFileSize, 0);
|
||
if(pProfileString == NULL)
|
||
{
|
||
ZPrintf("testerprofile: TesterProfileConnect error opening file [%s]\n", pState->strFilename);
|
||
return(TESTERPROFILE_ERROR_FILEOPEN);
|
||
}
|
||
|
||
// parse the file out
|
||
_TesterProfileParseFile(pState, pProfileString);
|
||
|
||
// don't forget to dump the memory when done
|
||
ZMemFree(pProfileString);
|
||
|
||
// quit
|
||
return(TESTERPROFILE_ERROR_NONE);
|
||
}
|
||
|
||
|
||
/*** Public functions *************************************************************/
|
||
|
||
/*F********************************************************************************/
|
||
/*!
|
||
\Function TesterProfileCreate
|
||
|
||
\Description
|
||
Create a tester profile manager.
|
||
|
||
\Input None
|
||
|
||
\Output TesterProfileT * - allocated module state pointer
|
||
|
||
\Version 03/18/2005 (jfrank)
|
||
*/
|
||
/********************************************************************************F*/
|
||
TesterProfileT *TesterProfileCreate(void)
|
||
{
|
||
TesterProfileT *pState = (TesterProfileT *)ZMemAlloc(sizeof(TesterProfileT));
|
||
ds_memclr(pState, sizeof(TesterProfileT));
|
||
TesterRegistrySetPointer("PROFILE", pState);
|
||
return(pState);
|
||
}
|
||
|
||
|
||
/*F********************************************************************************/
|
||
/*!
|
||
\Function TesterProfileConnect
|
||
|
||
\Description
|
||
Connect the profile manager to a set of profiles in a file.
|
||
|
||
\Input *pState - module state
|
||
\Input *pFilename - filename to try to read
|
||
|
||
\Output int32_t - error codes, 0 if success
|
||
|
||
\Version 03/18/2005 (jfrank)
|
||
*/
|
||
/********************************************************************************F*/
|
||
int32_t TesterProfileConnect(TesterProfileT *pState, const char *pFilename)
|
||
{
|
||
|
||
// check for error conditions
|
||
if (pState == NULL)
|
||
return(TESTERPROFILE_ERROR_NULLPOINTER);
|
||
if (pFilename == NULL)
|
||
return(TESTERPROFILE_ERROR_INVALIDFILENAME);
|
||
if (pState->strFilename[0] != 0)
|
||
return(TESTERPROFILE_ERROR_FILEALREADYOPEN);
|
||
|
||
// copy the filename in
|
||
ds_strnzcpy(pState->strFilename, pFilename, sizeof(pState->strFilename));
|
||
|
||
// read the contents of the requested file
|
||
_TesterProfileReadFile(pState);
|
||
|
||
// done
|
||
return(TESTERPROFILE_ERROR_NONE);
|
||
}
|
||
|
||
|
||
/*F********************************************************************************/
|
||
/*!
|
||
\Function TesterProfileAdd
|
||
|
||
\Description
|
||
Add a profile to the list
|
||
|
||
\Input *pState - module state
|
||
\Input *pEntry - profile entry to add
|
||
|
||
\Output int32_t - 0 for success, error code otherwise
|
||
|
||
\Version 03/18/2005 (jfrank)
|
||
*/
|
||
/********************************************************************************F*/
|
||
int32_t TesterProfileAdd(TesterProfileT *pState, TesterProfileEntryT *pEntry)
|
||
{
|
||
TesterProfileEntryT *pTarget = NULL;
|
||
uint32_t uLoop, uNameLen, uStoredNameLen;
|
||
char *pStoredProfileName;
|
||
|
||
// check for errors
|
||
if((pState == NULL) || (pEntry == NULL))
|
||
{
|
||
return(TESTERPROFILE_ERROR_NULLPOINTER);
|
||
}
|
||
|
||
// make sure we have a valid history filename
|
||
_TesterProfileGenerateHistoryFilename(pEntry);
|
||
|
||
// walk the list and look for a place to put it
|
||
// watch for a matching profile name as well
|
||
uNameLen = (uint32_t)strlen(pEntry->strProfileName);
|
||
for(uLoop = 0; (uLoop < pState->uProfileTail) && (pTarget == NULL); uLoop++)
|
||
{
|
||
pStoredProfileName = pState->Profiles[uLoop].strProfileName;
|
||
uStoredNameLen = (uint32_t)strlen(pStoredProfileName);
|
||
// if it matches, we have a target
|
||
if((uStoredNameLen == uNameLen) &&
|
||
(strcmp(pStoredProfileName, pEntry->strProfileName) == 0))
|
||
{
|
||
pTarget = &pState->Profiles[uLoop];
|
||
}
|
||
}
|
||
|
||
// if we don't have a match, see if we can make some room at the end
|
||
if(pTarget == NULL)
|
||
{
|
||
// no match - see if we have room
|
||
if(pState->uProfileTail < TESTERPROFILE_NUMPROFILES_DEFAULT)
|
||
{
|
||
pTarget = &pState->Profiles[pState->uProfileTail];
|
||
pState->uProfileTail++;
|
||
}
|
||
}
|
||
|
||
// copy all the parameters in if we found a spot
|
||
if(pTarget != NULL)
|
||
{
|
||
ds_memcpy(pTarget, pEntry, sizeof(TesterProfileEntryT));
|
||
}
|
||
|
||
return(TESTERPROFILE_ERROR_NONE);
|
||
}
|
||
|
||
/*F********************************************************************************/
|
||
/*!
|
||
\Function TesterProfileDelete
|
||
|
||
\Description
|
||
Remove a profile from the list
|
||
|
||
\Input *pState - module state
|
||
\Input *pName - profile to nuke
|
||
|
||
\Output int32_t - 0 for success, error code otherwise
|
||
|
||
\Version 03/18/2005 (jfrank)
|
||
*/
|
||
/********************************************************************************F*/
|
||
int32_t TesterProfileDelete(TesterProfileT *pState, const char *pName)
|
||
{
|
||
uint32_t uLoop, uNameLen, uStoredNameLen;
|
||
char *pStoredProfileName;
|
||
|
||
// check for errors
|
||
if((pState == NULL) || (pName == NULL))
|
||
return(TESTERPROFILE_ERROR_NULLPOINTER);
|
||
|
||
// nuke the entry in question
|
||
uNameLen = (uint32_t)strlen(pName);
|
||
for(uLoop = 0; uLoop < pState->uProfileTail; uLoop++)
|
||
{
|
||
// if it matches, we have a target
|
||
pStoredProfileName = (pState->Profiles[uLoop]).strProfileName;
|
||
uStoredNameLen = (uint32_t)strlen(pStoredProfileName);
|
||
if((uStoredNameLen == uNameLen) &&
|
||
(strcmp(pStoredProfileName, pName) == 0))
|
||
{
|
||
// nuke the entry so we won't save it
|
||
ds_memclr(&pState->Profiles[uLoop],sizeof(TesterProfileEntryT));
|
||
}
|
||
}
|
||
|
||
// now force a save (save won't dump a NULL entry)
|
||
TesterProfileSave(pState);
|
||
// and re-read the file
|
||
_TesterProfileReadFile(pState);
|
||
|
||
return(TESTERPROFILE_ERROR_NONE);
|
||
}
|
||
|
||
|
||
/*F********************************************************************************/
|
||
/*!
|
||
\Function TesterProfileSetDefaultName
|
||
|
||
\Description
|
||
Set a particular profile as the default profile
|
||
|
||
\Input *pState - module state
|
||
\Input *pProfileName - profile to set as default
|
||
|
||
\Output int32_t - 0 for success, error code otherwise
|
||
|
||
\Version 03/28/2005 (jfrank)
|
||
*/
|
||
/********************************************************************************F*/
|
||
int32_t TesterProfileSetDefaultName(TesterProfileT *pState, const char *pProfileName)
|
||
{
|
||
uint32_t uStoredNameLen, uNameLen;
|
||
char *pStoredProfileName;
|
||
uint32_t uLoop;
|
||
|
||
// check for errors first
|
||
if((pState == NULL) || (pProfileName == NULL))
|
||
return(TESTERPROFILE_ERROR_NULLPOINTER);
|
||
|
||
uNameLen = (uint32_t)strlen(pProfileName);
|
||
for(uLoop = 0; uLoop < TESTERPROFILE_NUMPROFILES_DEFAULT; uLoop++)
|
||
{
|
||
pState->Profiles[uLoop].uDefault = 0;
|
||
pStoredProfileName = pState->Profiles[uLoop].strProfileName;
|
||
uStoredNameLen = (uint32_t)strlen(pStoredProfileName);
|
||
if((uNameLen == uStoredNameLen) &&
|
||
(strcmp(pProfileName, pStoredProfileName) == 0))
|
||
{
|
||
pState->Profiles[uLoop].uDefault = 1;
|
||
}
|
||
}
|
||
|
||
// no error
|
||
return(TESTERPROFILE_ERROR_NONE);
|
||
}
|
||
|
||
|
||
/*F********************************************************************************/
|
||
/*!
|
||
\Function TesterProfileGetDefaultIndex
|
||
|
||
\Description
|
||
Return the index of the default profile
|
||
|
||
\Input *pState - module state
|
||
|
||
\Output int32_t - index of default profile, 0 if no default
|
||
|
||
\Version 03/28/2005 (jfrank)
|
||
*/
|
||
/********************************************************************************F*/
|
||
int32_t TesterProfileGetDefaultIndex(TesterProfileT *pState)
|
||
{
|
||
uint32_t uLoop;
|
||
int32_t iIndex = TESTERPROFILE_ERROR_NOSUCHENTRY;
|
||
|
||
if(pState == NULL)
|
||
return(TESTERPROFILE_ERROR_NULLPOINTER);
|
||
|
||
// loop while less than total number and not a default entry
|
||
for(uLoop = 0; uLoop < TESTERPROFILE_NUMPROFILES_DEFAULT; uLoop++)
|
||
{
|
||
if(pState->Profiles[uLoop].uDefault != 0)
|
||
iIndex = uLoop;
|
||
}
|
||
return(iIndex);
|
||
}
|
||
|
||
|
||
/*F********************************************************************************/
|
||
/*!
|
||
\Function TesterProfileSave
|
||
|
||
\Description
|
||
Save all profiles to disk.
|
||
|
||
\Notes
|
||
Called automatically on disconnect - no need to call this function
|
||
unless special functionality is desired. Will not save NULL entries.
|
||
|
||
\Input *pState - module state
|
||
|
||
\Output int32_t - 0 for success, error code otherwise
|
||
|
||
\Version 03/18/2005 (jfrank)
|
||
*/
|
||
/********************************************************************************F*/
|
||
int32_t TesterProfileSave(TesterProfileT *pState)
|
||
{
|
||
char strProfile[1024];
|
||
ZFileT iFilePointer;
|
||
int32_t iEntryNum;
|
||
|
||
// open the file for create (no append)
|
||
iFilePointer = ZFileOpen(pState->strFilename, ZFILE_OPENFLAG_CREATE | ZFILE_OPENFLAG_WRONLY);
|
||
if (iFilePointer < 0)
|
||
{
|
||
return(TESTERPROFILE_ERROR_FILEOPEN);
|
||
}
|
||
|
||
// loop through all entries and write the valid ones out
|
||
for (iEntryNum = 0; iEntryNum < TESTERPROFILE_NUMPROFILES_DEFAULT; iEntryNum++)
|
||
{
|
||
// will return an error if the entry is NULL or nuked
|
||
if (TesterProfileGetJson(pState, iEntryNum, strProfile, sizeof(strProfile)) >= 0)
|
||
{
|
||
// write it to the file
|
||
ZFileWrite(iFilePointer, (void *)strProfile, (int32_t)strlen(strProfile));
|
||
}
|
||
}
|
||
|
||
// close the file
|
||
ZFileClose(iFilePointer);
|
||
|
||
// done
|
||
return(TESTERPROFILE_ERROR_NONE);
|
||
}
|
||
|
||
|
||
/*F********************************************************************************/
|
||
/*!
|
||
\Function TesterProfileGet
|
||
|
||
\Description
|
||
Return a specific profile index into a tagfield string buffer.
|
||
|
||
\Input *pState - module state
|
||
\Input iIndex - 0-based index of the profile to get
|
||
\Input *pDest - destination buffer
|
||
|
||
\Output int32_t - index number of retreived entry (>=0) , error code otherwise
|
||
|
||
\Version 03/29/2005 (jfrank)
|
||
*/
|
||
/********************************************************************************F*/
|
||
int32_t TesterProfileGet(TesterProfileT *pState, int32_t iIndex, TesterProfileEntryT *pDest)
|
||
{
|
||
TesterProfileEntryT *pEntry;
|
||
|
||
// see if we want the default entry
|
||
if (iIndex == -1)
|
||
iIndex = TesterProfileGetDefaultIndex(pState);
|
||
|
||
// check for error conditions
|
||
if ((pState == NULL) || (pDest == NULL))
|
||
return(TESTERPROFILE_ERROR_NULLPOINTER);
|
||
else if (iIndex < -1)
|
||
return(TESTERPROFILE_ERROR_NOSUCHENTRY);
|
||
|
||
// set the entry pointer
|
||
pEntry = &pState->Profiles[iIndex];
|
||
|
||
// if the entry has been nuked, don't do anything
|
||
if(pEntry->strProfileName[0] == 0)
|
||
return(TESTERPROFILE_ERROR_NOSUCHENTRY);
|
||
|
||
// copy the data in
|
||
ds_memcpy(pDest, pEntry, sizeof(TesterProfileEntryT));
|
||
|
||
// done
|
||
return(iIndex);
|
||
}
|
||
|
||
|
||
/*F********************************************************************************/
|
||
/*!
|
||
\Function TesterProfileGetJson
|
||
|
||
\Description
|
||
Return a specific profile index into a json string buffer.
|
||
|
||
\Input *pState - module state
|
||
\Input iIndex - 0-based index of the profile to get
|
||
\Input *pDest - destination buffer
|
||
\Input iSize - size of the destination buffer
|
||
|
||
\Output int32_t - index number of retreived entry (>=0) , error code otherwise
|
||
|
||
\Version 03/29/2005 (jfrank)
|
||
*/
|
||
/********************************************************************************F*/
|
||
int32_t TesterProfileGetJson(TesterProfileT *pState, int32_t iIndex, char *pDest, int32_t iSize)
|
||
{
|
||
TesterProfileEntryT Entry;
|
||
int32_t iResult;
|
||
|
||
if (pState == NULL)
|
||
return(TESTERPROFILE_ERROR_NULLPOINTER);
|
||
|
||
iResult = TesterProfileGet(pState, iIndex, &Entry);
|
||
if (iResult < 0)
|
||
return(iResult);
|
||
|
||
// otherwise dump the json into the buffer
|
||
JsonInit(pDest, iSize, 0);
|
||
JsonAddStr(pDest, TESTERPROFILE_PROFILENAME_TAGVALUE, Entry.strProfileName);
|
||
JsonAddStr(pDest, TESTERPROFILE_HOSTNAME_TAGVALUE, Entry.strHostname);
|
||
JsonAddStr(pDest, TESTERPROFILE_CONTROLDIR_TAGVALUE, Entry.strControlDirectory);
|
||
JsonAddStr(pDest, TESTERPROFILE_COMMANDLINE_TAGVALUE, Entry.strCommandLine);
|
||
JsonAddStr(pDest, TESTERPROFILE_LOGDIRECTORY_TAGVALUE, Entry.strLogDirectory);
|
||
JsonAddStr(pDest, TESTERPROFILE_HISTORYFILE_TAGVALUE, Entry.strHistoryFile);
|
||
JsonAddInt(pDest, TESTERPROFILE_LOGENABLE_TAGVALUE, Entry.uLogEnable);
|
||
JsonAddInt(pDest, TESTERPROFILE_NETWORKSTART_TAGVALUE, Entry.uNetworkStartup);
|
||
JsonAddInt(pDest, TESTERPROFILE_DEFAULTPROFILE_TAGVALUE, Entry.uDefault);
|
||
pDest = JsonFinish(pDest);
|
||
|
||
// done
|
||
return(iIndex);
|
||
}
|
||
|
||
|
||
/*F********************************************************************************/
|
||
/*!
|
||
\Function TesterProfileDisconnect
|
||
|
||
\Description
|
||
Disconnect from a set of profiles and save the current profiles.
|
||
|
||
\Input *pState - module state
|
||
|
||
\Output int32_t - result of trying to save the profiles (TesterProfileSave())
|
||
|
||
\Version 03/18/2005 (jfrank)
|
||
*/
|
||
/********************************************************************************F*/
|
||
int32_t TesterProfileDisconnect(TesterProfileT *pState)
|
||
{
|
||
int32_t iResult;
|
||
|
||
// check for valid state - not really an error
|
||
if (pState == NULL)
|
||
return(TESTERPROFILE_ERROR_NONE);
|
||
// check to see if we're already disconnected
|
||
if (pState->strFilename[0] == 0)
|
||
return(TESTERPROFILE_ERROR_NONE);
|
||
|
||
// make a best effort at saving the file
|
||
iResult = TesterProfileSave(pState);
|
||
if (iResult)
|
||
{
|
||
ZPrintf("testerprofile: TesterProfileDisconnect: error saving file [%s]\n",
|
||
pState->strFilename);
|
||
}
|
||
|
||
// kill all the entries in the profile list
|
||
_TesterProfileKillAllEntries(pState);
|
||
|
||
// wipe out the filename to signify we've disconnected
|
||
ds_memclr(pState->strFilename, sizeof(pState->strFilename));
|
||
|
||
// return the fclose error code
|
||
return(iResult);
|
||
}
|
||
|
||
/*F********************************************************************************/
|
||
/*!
|
||
\Function TesterProfileDestroy
|
||
|
||
\Description
|
||
Destroy and allocated tester profile object.
|
||
|
||
\Input *pState - module state
|
||
|
||
\Output None
|
||
|
||
\Version 03/18/2005 (jfrank)
|
||
*/
|
||
/********************************************************************************F*/
|
||
void TesterProfileDestroy(TesterProfileT *pState)
|
||
{
|
||
if(pState)
|
||
{
|
||
TesterProfileDisconnect(pState);
|
||
ZMemFree(pState);
|
||
}
|
||
TesterRegistrySetPointer("PROFILE", NULL);
|
||
}
|
||
|