mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
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<EFBFBD>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);
|
|||
|
}
|
|||
|
|