mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-20 02:03:15 +00:00
1. Fixed size checks
2. Added checks for db write errors, and added readonly mode failover, with an error event
This commit is contained in:
@@ -637,7 +637,7 @@ void UDPSocket_OnData(ILibAsyncUDPSocket_SocketModule socketModule, char* buffer
|
|||||||
|
|
||||||
// Check if this is a Mesh Server discovery packet and it is for our server
|
// Check if this is a Mesh Server discovery packet and it is for our server
|
||||||
// It will have this form: "MeshCentral2|f5a50091028fe2c122434cbcbd2709a7ec10369295e5a0e43db8853a413d89df|wss://~:443/agent.ashx"
|
// It will have this form: "MeshCentral2|f5a50091028fe2c122434cbcbd2709a7ec10369295e5a0e43db8853a413d89df|wss://~:443/agent.ashx"
|
||||||
if ((packetLen > 78) && (memcmp(packet, "MeshCentral2|", 13) == 0) && ((ILibSimpleDataStore_Get(agentHost->masterDb, "ServerID", ILibScratchPad2, sizeof(ILibScratchPad2))) == 97) && (memcmp(ILibScratchPad2, packet + 13, 96) == 0)) {
|
if ((packetLen > 109) && (memcmp(packet, "MeshCentral2|", 13) == 0) && ((ILibSimpleDataStore_Get(agentHost->masterDb, "ServerID", ILibScratchPad2, sizeof(ILibScratchPad2))) == 97) && (memcmp(ILibScratchPad2, packet + 13, 96) == 0)) {
|
||||||
// We have a match, set the server URL correctly.
|
// We have a match, set the server URL correctly.
|
||||||
if (agentHost->multicastServerUrl != NULL) { free(agentHost->multicastServerUrl); agentHost->multicastServerUrl = NULL; }
|
if (agentHost->multicastServerUrl != NULL) { free(agentHost->multicastServerUrl); agentHost->multicastServerUrl = NULL; }
|
||||||
|
|
||||||
@@ -765,7 +765,7 @@ duk_ret_t ILibDuktape_MeshAgent_GenerateCertificate(duk_context *ctx)
|
|||||||
ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Agent_GuardPost, ILibRemoteLogging_Flags_VerbosityLevel_1, "...Generating JS TLS Certificate");
|
ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Agent_GuardPost, ILibRemoteLogging_Flags_VerbosityLevel_1, "...Generating JS TLS Certificate");
|
||||||
#endif
|
#endif
|
||||||
SSL_TRACE1("ILibDuktape_MeshAgent_GenerateCertificate()");
|
SSL_TRACE1("ILibDuktape_MeshAgent_GenerateCertificate()");
|
||||||
len = util_mkCert(NULL, &(cert), 3072, 10000, "localhost", CERTIFICATE_TLS_CLIENT, NULL);
|
if (util_mkCert(NULL, &(cert), 3072, 10000, "localhost", CERTIFICATE_TLS_CLIENT, NULL) == 0) { return(ILibDuktape_Error(ctx, "Error Generating Certificate")); }
|
||||||
len = util_to_p12(cert, passphrase, &data);
|
len = util_to_p12(cert, passphrase, &data);
|
||||||
|
|
||||||
duk_push_fixed_buffer(ctx, len);
|
duk_push_fixed_buffer(ctx, len);
|
||||||
@@ -1800,6 +1800,7 @@ void ILibDuktape_MeshAgent_PUSH(duk_context *ctx, void *chain)
|
|||||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "Connected");
|
ILibDuktape_EventEmitter_CreateEventEx(emitter, "Connected");
|
||||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "Command");
|
ILibDuktape_EventEmitter_CreateEventEx(emitter, "Command");
|
||||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "DesktopSessionChanged");
|
ILibDuktape_EventEmitter_CreateEventEx(emitter, "DesktopSessionChanged");
|
||||||
|
ILibDuktape_EventEmitter_CreateEventEx(emitter, "DBError");
|
||||||
ILibDuktape_EventEmitter_AddHook(emitter, "Connected", ILibDuktape_MeshAgent_ConnectedHook);
|
ILibDuktape_EventEmitter_AddHook(emitter, "Connected", ILibDuktape_MeshAgent_ConnectedHook);
|
||||||
|
|
||||||
ILibDuktape_CreateEventWithGetter(ctx, "ServerInfo", ILibDuktape_MeshAgent_ServerInfo);
|
ILibDuktape_CreateEventWithGetter(ctx, "ServerInfo", ILibDuktape_MeshAgent_ServerInfo);
|
||||||
@@ -2192,29 +2193,6 @@ int agent_VerifyMeshCertificates(MeshAgentHostContainer *agent)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void WritePipeResponse(AGENT_RECORD_TYPE recordType, JS_ENGINE_CONTEXT engineContext, char *payload, int payloadLength)
|
|
||||||
{
|
|
||||||
#ifdef WIN32
|
|
||||||
int tmpLen;
|
|
||||||
#endif
|
|
||||||
AGENT_RECORD_HEADER *header = (AGENT_RECORD_HEADER*)ILibScratchPad2;
|
|
||||||
header->RecordType = recordType;
|
|
||||||
header->RecordLength = sizeof(AGENT_RECORD_HEADER) + payloadLength;
|
|
||||||
memcpy_s(header->Context, sizeof(JS_ENGINE_CONTEXT), engineContext, sizeof(JS_ENGINE_CONTEXT));
|
|
||||||
if (payloadLength > 0)
|
|
||||||
{
|
|
||||||
memcpy_s(header->Payload, sizeof(ILibScratchPad2) - sizeof(AGENT_RECORD_HEADER), payload, payloadLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
WriteFile(GetStdHandle(STD_ERROR_HANDLE), header, header->RecordLength, &tmpLen, NULL);
|
|
||||||
#else
|
|
||||||
ignore_result(write(STDERR_FILENO, header, header->RecordLength));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
duk_context* ScriptEngine_Stop(MeshAgentHostContainer *agent, char *contextGUID)
|
duk_context* ScriptEngine_Stop(MeshAgentHostContainer *agent, char *contextGUID)
|
||||||
{
|
{
|
||||||
SCRIPT_ENGINE_SETTINGS *settings = ILibDuktape_ScriptContainer_GetSettings(agent->meshCoreCtx);
|
SCRIPT_ENGINE_SETTINGS *settings = ILibDuktape_ScriptContainer_GetSettings(agent->meshCoreCtx);
|
||||||
@@ -3802,7 +3780,7 @@ int importSettings(MeshAgentHostContainer *agent, char* fileName)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ntohs(((unsigned short*)val)[0]) == HEX_IDENTIFIER)
|
if (valLen > 2 && ntohs(((unsigned short*)val)[0]) == HEX_IDENTIFIER)
|
||||||
{
|
{
|
||||||
// HEX value
|
// HEX value
|
||||||
ILibSimpleDataStore_PutEx(agent->masterDb, key, keyLen, ILibScratchPad2, util_hexToBuf(val + 2, valLen - 2, ILibScratchPad2));
|
ILibSimpleDataStore_PutEx(agent->masterDb, key, keyLen, ILibScratchPad2, util_hexToBuf(val + 2, valLen - 2, ILibScratchPad2));
|
||||||
@@ -4030,6 +4008,19 @@ BOOL MeshAgent_PidWaiter(void *chain, HANDLE h, ILibWaitHandle_ErrorStatus statu
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void MeshAgent_DB_WriteError(ILibSimpleDataStore sender, void *user)
|
||||||
|
{
|
||||||
|
MeshAgentHostContainer *agent = (MeshAgentHostContainer*)user;
|
||||||
|
if (agent->meshCoreCtx != NULL)
|
||||||
|
{
|
||||||
|
ILibDuktape_MeshAgent_PUSH(agent->meshCoreCtx, agent->chain); // [mesh]
|
||||||
|
duk_prepare_method_call(agent->meshCoreCtx, -1, "emit"); // [mesh][emit][this]
|
||||||
|
duk_remove(agent->meshCoreCtx, -3); // [emit][this]
|
||||||
|
duk_push_string(agent->meshCoreCtx, "DBError"); // [emit][this][DBError]
|
||||||
|
duk_pcall_method(agent->meshCoreCtx, 1); duk_pop(agent->meshCoreCtx); // ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **param, int parseCommands)
|
int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **param, int parseCommands)
|
||||||
{
|
{
|
||||||
int resetNodeId = 0;
|
int resetNodeId = 0;
|
||||||
@@ -4259,17 +4250,18 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
|
|||||||
agentHost->httpClientManager = ILibCreateWebClient(3, agentHost->chain);
|
agentHost->httpClientManager = ILibCreateWebClient(3, agentHost->chain);
|
||||||
|
|
||||||
|
|
||||||
#ifdef _REMOTELOGGINGSERVER
|
|
||||||
if (agentHost->masterDb != NULL)
|
if (agentHost->masterDb != NULL)
|
||||||
{
|
{
|
||||||
|
ILibSimpleDataStore_ConfigWriteErrorHandler(agentHost->masterDb, MeshAgent_DB_WriteError, agentHost);
|
||||||
|
#ifdef _REMOTELOGGINGSERVER
|
||||||
int len;
|
int len;
|
||||||
if ((len = ILibSimpleDataStore_Get(agentHost->masterDb, "enableILibRemoteLogging", ILibScratchPad, sizeof(ILibScratchPad))) != 0)
|
if ((len = ILibSimpleDataStore_Get(agentHost->masterDb, "enableILibRemoteLogging", ILibScratchPad, sizeof(ILibScratchPad))) != 0)
|
||||||
{
|
{
|
||||||
ILibScratchPad[len] = 0;
|
ILibScratchPad[len] = 0;
|
||||||
ILibStartDefaultLoggerEx(agentHost->chain, (unsigned short)atoi(ILibScratchPad), MeshAgent_MakeAbsolutePath(agentHost->exePath, ".wlg"));
|
ILibStartDefaultLoggerEx(agentHost->chain, (unsigned short)atoi(ILibScratchPad), MeshAgent_MakeAbsolutePath(agentHost->exePath, ".wlg"));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ILibRemoteLogging_printf(ILibChainGetLogger(agentHost->chain), ILibRemoteLogging_Modules_Microstack_Generic, ILibRemoteLogging_Flags_VerbosityLevel_1, "agentcore: argv[0] = %s", param[0]);
|
ILibRemoteLogging_printf(ILibChainGetLogger(agentHost->chain), ILibRemoteLogging_Modules_Microstack_Generic, ILibRemoteLogging_Flags_VerbosityLevel_1, "agentcore: argv[0] = %s", param[0]);
|
||||||
@@ -4558,7 +4550,7 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
|
|||||||
if (pid < 0) { exit(EXIT_FAILURE); }
|
if (pid < 0) { exit(EXIT_FAILURE); }
|
||||||
else if (pid > 0)
|
else if (pid > 0)
|
||||||
{
|
{
|
||||||
len = snprintf(str, 15, "%d\r\n", pid);
|
len = sprintf_s(str, 15, "%d\r\n", pid);
|
||||||
|
|
||||||
fd = fopen("/var/run/meshagent.pid", "w");
|
fd = fopen("/var/run/meshagent.pid", "w");
|
||||||
if (fd == NULL) fd = fopen(".meshagent.pid", "w");
|
if (fd == NULL) fd = fopen(".meshagent.pid", "w");
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ typedef struct ILibSimpleDataStore_Root
|
|||||||
ILibSimpleDataStore_SizeWarningHandler warningSink;
|
ILibSimpleDataStore_SizeWarningHandler warningSink;
|
||||||
void* warningSinkUser;
|
void* warningSinkUser;
|
||||||
int error;
|
int error;
|
||||||
|
ILibSimpleDataStore_WriteErrorHandler ErrorHandler;
|
||||||
|
void *ErrorHandlerUser;
|
||||||
} ILibSimpleDataStore_Root;
|
} ILibSimpleDataStore_Root;
|
||||||
|
|
||||||
/* File Format
|
/* File Format
|
||||||
@@ -343,18 +345,39 @@ uint64_t ILibSimpleDataStore_WriteRecord(FILE *f, char* key, int keyLen, char* v
|
|||||||
char headerBytes[sizeof(ILibSimpleDataStore_RecordHeader_NG)];
|
char headerBytes[sizeof(ILibSimpleDataStore_RecordHeader_NG)];
|
||||||
ILibSimpleDataStore_RecordHeader_NG *header = (ILibSimpleDataStore_RecordHeader_NG*)headerBytes;
|
ILibSimpleDataStore_RecordHeader_NG *header = (ILibSimpleDataStore_RecordHeader_NG*)headerBytes;
|
||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
|
uint64_t curlen;
|
||||||
|
uint64_t written = 0;
|
||||||
|
|
||||||
fseek(f, 0, SEEK_END);
|
fseek(f, 0, SEEK_END);
|
||||||
|
curlen = ILibSimpleDataStore_GetPosition(f);
|
||||||
|
|
||||||
header->nodeSize = htonl(sizeof(ILibSimpleDataStore_RecordHeader_NG) + keyLen + valueLen);
|
header->nodeSize = htonl(sizeof(ILibSimpleDataStore_RecordHeader_NG) + keyLen + valueLen);
|
||||||
header->keyLen = htonl(keyLen);
|
header->keyLen = htonl(keyLen);
|
||||||
header->valueLength = htonl(valueLen);
|
header->valueLength = htonl(valueLen);
|
||||||
if (hash != NULL) { memcpy_s(header->hash, sizeof(header->hash), hash, SHA384HASHSIZE); } else { memset(header->hash, 0, SHA384HASHSIZE); }
|
if (hash != NULL) { memcpy_s(header->hash, sizeof(header->hash), hash, SHA384HASHSIZE); } else { memset(header->hash, 0, SHA384HASHSIZE); }
|
||||||
|
|
||||||
if (fwrite(headerBytes, 1, sizeof(ILibSimpleDataStore_RecordHeader_NG), f)) {}
|
written += (uint64_t)fwrite(headerBytes, 1, sizeof(ILibSimpleDataStore_RecordHeader_NG), f);
|
||||||
if (fwrite(key, 1, keyLen, f)) {}
|
written += (uint64_t)fwrite(key, 1, keyLen, f);
|
||||||
offset = ILibSimpleDataStore_GetPosition(f);
|
offset = ILibSimpleDataStore_GetPosition(f);
|
||||||
if (value != NULL) { if (fwrite(value, 1, valueLen, f)) {} }
|
if (value != NULL) { written += (uint64_t)fwrite(value, 1, valueLen, f); }
|
||||||
fflush(f);
|
fflush(f);
|
||||||
|
|
||||||
|
if (written < (sizeof(ILibSimpleDataStore_RecordHeader_NG) + keyLen + (value!=NULL?valueLen:0)))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Unable to write all data, probably because insufficient disc space,
|
||||||
|
// so we're going to undo the last write, so we don't corrupt the db,
|
||||||
|
//
|
||||||
|
#ifdef WIN32
|
||||||
|
LARGE_INTEGER i;
|
||||||
|
i.QuadPart = curlen;
|
||||||
|
SetFilePointerEx((HANDLE)_get_osfhandle(_fileno(f)), i, NULL, FILE_BEGIN);
|
||||||
|
SetEndOfFile((HANDLE)_get_osfhandle(_fileno(f)));
|
||||||
|
#else
|
||||||
|
ftruncate(fileno(f), curlen);
|
||||||
|
#endif
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -710,11 +733,14 @@ __EXPORT_TYPE void ILibSimpleDataStore_Close(ILibSimpleDataStore dataStore)
|
|||||||
// Store a key/value pair in the data store
|
// Store a key/value pair in the data store
|
||||||
__EXPORT_TYPE int ILibSimpleDataStore_PutEx2(ILibSimpleDataStore dataStore, char* key, int keyLen, char* value, int valueLen, char *vhash)
|
__EXPORT_TYPE int ILibSimpleDataStore_PutEx2(ILibSimpleDataStore dataStore, char* key, int keyLen, char* value, int valueLen, char *vhash)
|
||||||
{
|
{
|
||||||
|
int allocated = 0;
|
||||||
int ret;
|
int ret;
|
||||||
char hash[SHA384HASHSIZE];
|
char hash[SHA384HASHSIZE];
|
||||||
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
||||||
ILibSimpleDataStore_TableEntry *entry;
|
ILibSimpleDataStore_TableEntry *entry;
|
||||||
|
char *origkey = key;
|
||||||
|
int origkeylen = keyLen;
|
||||||
|
|
||||||
if (root == NULL) { return 0; }
|
if (root == NULL) { return 0; }
|
||||||
if (root->dataFile == NULL)
|
if (root->dataFile == NULL)
|
||||||
{
|
{
|
||||||
@@ -749,6 +775,7 @@ __EXPORT_TYPE int ILibSimpleDataStore_PutEx2(ILibSimpleDataStore dataStore, char
|
|||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
{
|
{
|
||||||
entry = (ILibSimpleDataStore_TableEntry*)ILibMemory_Allocate(sizeof(ILibSimpleDataStore_TableEntry), 0, NULL, NULL);
|
entry = (ILibSimpleDataStore_TableEntry*)ILibMemory_Allocate(sizeof(ILibSimpleDataStore_TableEntry), 0, NULL, NULL);
|
||||||
|
allocated = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -761,6 +788,19 @@ __EXPORT_TYPE int ILibSimpleDataStore_PutEx2(ILibSimpleDataStore dataStore, char
|
|||||||
entry->valueOffset = ILibSimpleDataStore_WriteRecord(root->dataFile, key, keyLen, value, valueLen, entry->valueHash); // Write the key and value
|
entry->valueOffset = ILibSimpleDataStore_WriteRecord(root->dataFile, key, keyLen, value, valueLen, entry->valueHash); // Write the key and value
|
||||||
root->fileSize = ILibSimpleDataStore_GetPosition(root->dataFile); // Update the size of the data store;
|
root->fileSize = ILibSimpleDataStore_GetPosition(root->dataFile); // Update the size of the data store;
|
||||||
|
|
||||||
|
if (entry->valueOffset == 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Write Error, switch to readonly mode,
|
||||||
|
// and re-write this record into the cache
|
||||||
|
//
|
||||||
|
if (allocated) { free(entry); }
|
||||||
|
ILibSimpleDataStore_CachedEx(root, origkey, origkeylen, value, valueLen, vhash);
|
||||||
|
ILibSimpleDataStore_ReOpenReadOnly(root, NULL);
|
||||||
|
if (root->ErrorHandler != NULL) { root->ErrorHandler(root, root->ErrorHandlerUser); }
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
// Add the record to the data store
|
// Add the record to the data store
|
||||||
ret = ILibHashtable_Put(root->keyTable, NULL, key, keyLen, entry) == NULL ? 0 : 1;
|
ret = ILibHashtable_Put(root->keyTable, NULL, key, keyLen, entry) == NULL ? 0 : 1;
|
||||||
if (root->warningSize > 0 && root->fileSize > root->warningSize && root->warningSink != NULL)
|
if (root->warningSize > 0 && root->fileSize > root->warningSize && root->warningSink != NULL)
|
||||||
@@ -918,7 +958,6 @@ __EXPORT_TYPE char* ILibSimpleDataStore_GetHashEx(ILibSimpleDataStore dataStore,
|
|||||||
if (centry == NULL)
|
if (centry == NULL)
|
||||||
{
|
{
|
||||||
// Let's check if this is a compressed record entry
|
// Let's check if this is a compressed record entry
|
||||||
size_t tmplen = 0;
|
|
||||||
char *tmpkey = (char*)ILibMemory_SmartAllocate(keyLen + sizeof(uint32_t));
|
char *tmpkey = (char*)ILibMemory_SmartAllocate(keyLen + sizeof(uint32_t));
|
||||||
memcpy_s(tmpkey, ILibMemory_Size(tmpkey), key, keyLen);
|
memcpy_s(tmpkey, ILibMemory_Size(tmpkey), key, keyLen);
|
||||||
((uint32_t*)(tmpkey + keyLen))[0] = crc32c(0, (unsigned char*)key, keyLen);
|
((uint32_t*)(tmpkey + keyLen))[0] = crc32c(0, (unsigned char*)key, keyLen);
|
||||||
@@ -971,7 +1010,10 @@ __EXPORT_TYPE int ILibSimpleDataStore_DeleteEx(ILibSimpleDataStore dataStore, ch
|
|||||||
entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Remove(root->keyTable, NULL, tmpkey, (int)ILibMemory_Size(tmpkey));
|
entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Remove(root->keyTable, NULL, tmpkey, (int)ILibMemory_Size(tmpkey));
|
||||||
if (entry != NULL)
|
if (entry != NULL)
|
||||||
{
|
{
|
||||||
ILibSimpleDataStore_WriteRecord(root->dataFile, tmpkey, (int)ILibMemory_Size(tmpkey), NULL, 0, NULL);
|
if (ILibSimpleDataStore_WriteRecord(root->dataFile, tmpkey, (int)ILibMemory_Size(tmpkey), NULL, 0, NULL) == 0)
|
||||||
|
{
|
||||||
|
if (root->ErrorHandler != NULL) { root->ErrorHandler(root, root->ErrorHandlerUser); }
|
||||||
|
}
|
||||||
free(entry);
|
free(entry);
|
||||||
ILibMemory_Free(tmpkey);
|
ILibMemory_Free(tmpkey);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -980,7 +1022,10 @@ __EXPORT_TYPE int ILibSimpleDataStore_DeleteEx(ILibSimpleDataStore dataStore, ch
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ILibSimpleDataStore_WriteRecord(root->dataFile, key, keyLen, NULL, 0, NULL);
|
if (ILibSimpleDataStore_WriteRecord(root->dataFile, key, keyLen, NULL, 0, NULL) == 0)
|
||||||
|
{
|
||||||
|
if (root->ErrorHandler != NULL) { root->ErrorHandler(root, root->ErrorHandlerUser); }
|
||||||
|
}
|
||||||
free(entry);
|
free(entry);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -1027,6 +1072,7 @@ void ILibSimpleDataStore_Compact_EnumerateSink(ILibHashtable sender, void *Key1,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
offset = ILibSimpleDataStore_WriteRecord(compacted, Key2, Key2Len, NULL, entry->valueLength, entry->valueHash);
|
offset = ILibSimpleDataStore_WriteRecord(compacted, Key2, Key2Len, NULL, entry->valueLength, entry->valueHash);
|
||||||
|
if (offset == 0) { root->error = 1; return; }
|
||||||
while (bytesLeft > 0)
|
while (bytesLeft > 0)
|
||||||
{
|
{
|
||||||
if (ILibSimpleDataStore_SeekPosition(root->dataFile, entry->valueOffset + totalBytesWritten, SEEK_SET) == 0)
|
if (ILibSimpleDataStore_SeekPosition(root->dataFile, entry->valueOffset + totalBytesWritten, SEEK_SET) == 0)
|
||||||
@@ -1090,6 +1136,12 @@ __EXPORT_TYPE void ILibSimpleDataStore_EnumerateKeys(ILibSimpleDataStore dataSto
|
|||||||
|
|
||||||
if (handler != NULL) { ILibHashtable_Enumerate(root->keyTable, ILibSimpleDataStore_EnumerateKeysSink, users); }
|
if (handler != NULL) { ILibHashtable_Enumerate(root->keyTable, ILibSimpleDataStore_EnumerateKeysSink, users); }
|
||||||
}
|
}
|
||||||
|
void ILibSimpleDataStore_ConfigWriteErrorHandler(ILibSimpleDataStore dataStore, ILibSimpleDataStore_WriteErrorHandler handler, void *user)
|
||||||
|
{
|
||||||
|
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
||||||
|
root->ErrorHandler = handler;
|
||||||
|
root->ErrorHandlerUser = user;
|
||||||
|
}
|
||||||
__EXPORT_TYPE void ILibSimpleDataStore_ConfigSizeLimit(ILibSimpleDataStore dataStore, uint64_t sizeLimit, ILibSimpleDataStore_SizeWarningHandler handler, void *user)
|
__EXPORT_TYPE void ILibSimpleDataStore_ConfigSizeLimit(ILibSimpleDataStore dataStore, uint64_t sizeLimit, ILibSimpleDataStore_SizeWarningHandler handler, void *user)
|
||||||
{
|
{
|
||||||
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ const extern int ILibMemory_SimpleDataStore_CONTAINERSIZE;
|
|||||||
|
|
||||||
typedef void(*ILibSimpleDataStore_KeyEnumerationHandler)(ILibSimpleDataStore sender, char* Key, int KeyLen, void *user);
|
typedef void(*ILibSimpleDataStore_KeyEnumerationHandler)(ILibSimpleDataStore sender, char* Key, int KeyLen, void *user);
|
||||||
typedef void(*ILibSimpleDataStore_SizeWarningHandler)(ILibSimpleDataStore sender, uint64_t size, void *user);
|
typedef void(*ILibSimpleDataStore_SizeWarningHandler)(ILibSimpleDataStore sender, uint64_t size, void *user);
|
||||||
|
typedef void(*ILibSimpleDataStore_WriteErrorHandler)(ILibSimpleDataStore sender, void *user);
|
||||||
|
|
||||||
// Create the data store.
|
// Create the data store.
|
||||||
__EXPORT_TYPE ILibSimpleDataStore ILibSimpleDataStore_CreateEx2(char* filePath, int userExtraMemorySize, int readonly);
|
__EXPORT_TYPE ILibSimpleDataStore ILibSimpleDataStore_CreateEx2(char* filePath, int userExtraMemorySize, int readonly);
|
||||||
@@ -60,6 +61,7 @@ __EXPORT_TYPE int ILibSimpleDataStore_Cached_GetJSON(ILibSimpleDataStore dataSto
|
|||||||
__EXPORT_TYPE int ILibSimpleDataStore_Cached_GetJSONEx(ILibSimpleDataStore dataStore, char *buffer, int bufferLen);
|
__EXPORT_TYPE int ILibSimpleDataStore_Cached_GetJSONEx(ILibSimpleDataStore dataStore, char *buffer, int bufferLen);
|
||||||
__EXPORT_TYPE void ILibSimpleDataStore_ConfigCompact(ILibSimpleDataStore dataStore, uint64_t minimumDirtySize);
|
__EXPORT_TYPE void ILibSimpleDataStore_ConfigCompact(ILibSimpleDataStore dataStore, uint64_t minimumDirtySize);
|
||||||
__EXPORT_TYPE void ILibSimpleDataStore_ConfigSizeLimit(ILibSimpleDataStore dataStore, uint64_t sizeLimit, ILibSimpleDataStore_SizeWarningHandler handler, void *user);
|
__EXPORT_TYPE void ILibSimpleDataStore_ConfigSizeLimit(ILibSimpleDataStore dataStore, uint64_t sizeLimit, ILibSimpleDataStore_SizeWarningHandler handler, void *user);
|
||||||
|
void ILibSimpleDataStore_ConfigWriteErrorHandler(ILibSimpleDataStore dataStore, ILibSimpleDataStore_WriteErrorHandler handler, void *user);
|
||||||
|
|
||||||
__EXPORT_TYPE int ILibSimpleDataStore_PutEx2(ILibSimpleDataStore dataStore, char* key, int keyLen, char* value, int valueLen, char *hash);
|
__EXPORT_TYPE int ILibSimpleDataStore_PutEx2(ILibSimpleDataStore dataStore, char* key, int keyLen, char* value, int valueLen, char *hash);
|
||||||
#define ILibSimpleDataStore_Put(dataStore, key, value) ILibSimpleDataStore_PutEx(dataStore, key, (int)strnlen_s(key, ILibSimpleDataStore_MaxKeyLength), value, (int)strnlen_s(value, ILibSimpleDataStore_MaxUnspecifiedValueLen))
|
#define ILibSimpleDataStore_Put(dataStore, key, value) ILibSimpleDataStore_PutEx(dataStore, key, (int)strnlen_s(key, ILibSimpleDataStore_MaxKeyLength), value, (int)strnlen_s(value, ILibSimpleDataStore_MaxUnspecifiedValueLen))
|
||||||
|
|||||||
Reference in New Issue
Block a user