1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-10 21:33:38 +00:00

Fixed on Linux, so db is opened exclusively, and fails/exits if it can't do it

Updated from SHA256 to SHA384
Added helper to see if db exist
Fixed deprecation problem on windows
Added an explicit unlock
Added fix, to prevent memory corruption if a db record is corrupt
This commit is contained in:
Bryan Roe
2019-01-11 13:34:22 -08:00
parent 372a20e841
commit 2363e36bcb

View File

@@ -119,14 +119,17 @@ ILibSimpleDataStore_RecordNode* ILibSimpleDataStore_ReadNextRecord(ILibSimpleDat
char data[4096]; char data[4096];
char result[SHA384HASHSIZE]; char result[SHA384HASHSIZE];
int i, bytesLeft; int i, bytesLeft;
ILibSimpleDataStore_RecordNode *node = (ILibSimpleDataStore_RecordNode*)(root->scratchPad ); ILibSimpleDataStore_RecordNode *node;
if (root == NULL) return NULL;
node = (ILibSimpleDataStore_RecordNode*)(root->scratchPad);
// If the current position is the end of the file, exit now. // If the current position is the end of the file, exit now.
if (ILibSimpleDataStore_GetPosition(root->dataFile) == root->fileSize) { return NULL; } if (ILibSimpleDataStore_GetPosition(root->dataFile) == root->fileSize) return NULL;
// Read sizeof(ILibSimpleDataStore_RecordNode) bytes to get record Size // Read sizeof(ILibSimpleDataStore_RecordNode) bytes to get record Size
i = (int)fread((void*)node, 1, sizeof(ILibSimpleDataStore_RecordNode), root->dataFile); i = (int)fread((void*)node, 1, sizeof(ILibSimpleDataStore_RecordNode), root->dataFile);
if (i < sizeof(ILibSimpleDataStore_RecordNode)) { return NULL; } if (i < sizeof(ILibSimpleDataStore_RecordNode)) return NULL;
// Correct the struct, valueHash stays the same // Correct the struct, valueHash stays the same
node->nodeSize = (int)ntohl(node->nodeSize); node->nodeSize = (int)ntohl(node->nodeSize);
@@ -134,9 +137,15 @@ ILibSimpleDataStore_RecordNode* ILibSimpleDataStore_ReadNextRecord(ILibSimpleDat
node->valueLength = (int)ntohl(node->valueLength); node->valueLength = (int)ntohl(node->valueLength);
node->valueOffset = ILibSimpleDataStore_GetPosition(root->dataFile) + (DS_Long)node->keyLen; node->valueOffset = ILibSimpleDataStore_GetPosition(root->dataFile) + (DS_Long)node->keyLen;
if (node->keyLen > (sizeof(ILibScratchPad) - sizeof(ILibSimpleDataStore_RecordNode)))
{
// Invalid record
return(NULL);
}
// Read the key name // Read the key name
i = (int)fread((char*)node + sizeof(ILibSimpleDataStore_RecordNode), 1, node->keyLen, root->dataFile); i = (int)fread((char*)node + sizeof(ILibSimpleDataStore_RecordNode), 1, node->keyLen, root->dataFile);
if (i != node->keyLen) { return NULL; } // Reading Key Failed if (i != node->keyLen) return NULL; // Reading Key Failed
// Validate Data, in 4k chunks at a time // Validate Data, in 4k chunks at a time
bytesLeft = node->valueLength; bytesLeft = node->valueLength;
@@ -154,9 +163,7 @@ ILibSimpleDataStore_RecordNode* ILibSimpleDataStore_ReadNextRecord(ILibSimpleDat
if (node->valueLength > 0) if (node->valueLength > 0)
{ {
// Check the hash // Check the hash
if (memcmp(node->valueHash, result, SHA384HASHSIZE) == 0) { if (memcmp(node->valueHash, result, SHA384HASHSIZE) == 0) { return node; } // Data is correct
return node; // Data is correct
}
return NULL; // Data is corrupt return NULL; // Data is corrupt
} }
return node; return node;
@@ -180,6 +187,7 @@ void ILibSimpleDataStore_RebuildKeyTable(ILibSimpleDataStore_Root *root)
ILibSimpleDataStore_RecordNode *node = NULL; ILibSimpleDataStore_RecordNode *node = NULL;
ILibSimpleDataStore_TableEntry *entry; ILibSimpleDataStore_TableEntry *entry;
if (root == NULL) return;
ILibHashtable_ClearEx(root->keyTable, ILibSimpleDataStore_TableClear_Sink, root); // Wipe the key table, we will rebulit it ILibHashtable_ClearEx(root->keyTable, ILibSimpleDataStore_TableClear_Sink, root); // Wipe the key table, we will rebulit it
fseek(root->dataFile, 0, SEEK_SET); // See the start of the file fseek(root->dataFile, 0, SEEK_SET); // See the start of the file
root->fileSize = -1; // Indicate we can't write to the data store root->fileSize = -1; // Indicate we can't write to the data store
@@ -265,9 +273,16 @@ __EXPORT_TYPE ILibSimpleDataStore ILibSimpleDataStore_CreateEx(char* filePath, i
__EXPORT_TYPE void ILibSimpleDataStore_Close(ILibSimpleDataStore dataStore) __EXPORT_TYPE void ILibSimpleDataStore_Close(ILibSimpleDataStore dataStore)
{ {
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore; ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
if (root == NULL) return;
ILibHashtable_DestroyEx(root->keyTable, ILibSimpleDataStore_TableClear_Sink, root); ILibHashtable_DestroyEx(root->keyTable, ILibSimpleDataStore_TableClear_Sink, root);
free(root->filePath); free(root->filePath);
#ifdef _POSIX
flock(fileno(root->dataFile), LOCK_UN);
#endif
fclose(root->dataFile); fclose(root->dataFile);
free(root); free(root);
} }
@@ -277,7 +292,10 @@ __EXPORT_TYPE int ILibSimpleDataStore_PutEx(ILibSimpleDataStore dataStore, char*
{ {
char hash[SHA384HASHSIZE]; char hash[SHA384HASHSIZE];
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore; ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
ILibSimpleDataStore_TableEntry *entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Get(root->keyTable, NULL, key, keyLen); ILibSimpleDataStore_TableEntry *entry;
if (root == NULL) return 0;
entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Get(root->keyTable, NULL, key, keyLen);
ILibSimpleDataStore_SHA384(value, valueLen, hash); // Hash the value ILibSimpleDataStore_SHA384(value, valueLen, hash); // Hash the value
// Create a new record for the key and value // Create a new record for the key and value
@@ -301,7 +319,10 @@ __EXPORT_TYPE int ILibSimpleDataStore_GetEx(ILibSimpleDataStore dataStore, char*
{ {
char hash[SHA384HASHSIZE]; char hash[SHA384HASHSIZE];
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore; ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
ILibSimpleDataStore_TableEntry *entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Get(root->keyTable, NULL, key, keyLen); ILibSimpleDataStore_TableEntry *entry;
if (root == NULL) return 0;
entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Get(root->keyTable, NULL, key, keyLen);
if (entry == NULL) return 0; // If there is no in-memory entry for this key, return zero now. if (entry == NULL) return 0; // If there is no in-memory entry for this key, return zero now.
if ((buffer != NULL) && (bufferLen >= entry->valueLength)) // If the buffer is not null and can hold the value, place the value in the buffer. if ((buffer != NULL) && (bufferLen >= entry->valueLength)) // If the buffer is not null and can hold the value, place the value in the buffer.
@@ -319,7 +340,10 @@ __EXPORT_TYPE int ILibSimpleDataStore_GetEx(ILibSimpleDataStore dataStore, char*
__EXPORT_TYPE char* ILibSimpleDataStore_GetHashEx(ILibSimpleDataStore dataStore, char* key, int keyLen) __EXPORT_TYPE char* ILibSimpleDataStore_GetHashEx(ILibSimpleDataStore dataStore, char* key, int keyLen)
{ {
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore; ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
ILibSimpleDataStore_TableEntry *entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Get(root->keyTable, NULL, key, keyLen); ILibSimpleDataStore_TableEntry *entry;
if (root == NULL) return NULL;
entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Get(root->keyTable, NULL, key, keyLen);
if (entry == NULL) return NULL; // If there is no in-memory entry for this key, return zero now. if (entry == NULL) return NULL; // If there is no in-memory entry for this key, return zero now.
return entry->valueHash; return entry->valueHash;
@@ -329,7 +353,10 @@ __EXPORT_TYPE char* ILibSimpleDataStore_GetHashEx(ILibSimpleDataStore dataStore,
__EXPORT_TYPE int ILibSimpleDataStore_DeleteEx(ILibSimpleDataStore dataStore, char* key, int keyLen) __EXPORT_TYPE int ILibSimpleDataStore_DeleteEx(ILibSimpleDataStore dataStore, char* key, int keyLen)
{ {
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore; ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
ILibSimpleDataStore_TableEntry *entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Remove(root->keyTable, NULL, key, keyLen); ILibSimpleDataStore_TableEntry *entry;
if (root == NULL) return 0;
entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Remove(root->keyTable, NULL, key, keyLen);
if (entry != NULL) { ILibSimpleDataStore_WriteRecord(root->dataFile, key, keyLen, NULL, 0, NULL); free(entry); return 1; } if (entry != NULL) { ILibSimpleDataStore_WriteRecord(root->dataFile, key, keyLen, NULL, 0, NULL); free(entry); return 1; }
return 0; return 0;
} }
@@ -338,6 +365,7 @@ __EXPORT_TYPE int ILibSimpleDataStore_DeleteEx(ILibSimpleDataStore dataStore, ch
__EXPORT_TYPE void ILibSimpleDataStore_Lock(ILibSimpleDataStore dataStore) __EXPORT_TYPE void ILibSimpleDataStore_Lock(ILibSimpleDataStore dataStore)
{ {
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore; ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
if (root == NULL) return;
ILibHashtable_Lock(root->keyTable); ILibHashtable_Lock(root->keyTable);
} }
@@ -345,6 +373,7 @@ __EXPORT_TYPE void ILibSimpleDataStore_Lock(ILibSimpleDataStore dataStore)
__EXPORT_TYPE void ILibSimpleDataStore_UnLock(ILibSimpleDataStore dataStore) __EXPORT_TYPE void ILibSimpleDataStore_UnLock(ILibSimpleDataStore dataStore)
{ {
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore; ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
if (root == NULL) return;
ILibHashtable_UnLock(root->keyTable); ILibHashtable_UnLock(root->keyTable);
} }
@@ -361,6 +390,7 @@ void ILibSimpleDataStore_Compact_EnumerateSink(ILibHashtable sender, void *Key1,
int totalBytesWritten = 0; int totalBytesWritten = 0;
int bytesWritten = 0; int bytesWritten = 0;
if (root == NULL) return;
if (root->error != 0) return; // There was an error, ABORT! if (root->error != 0) return; // There was an error, ABORT!
offset = ILibSimpleDataStore_WriteRecord(compacted, Key2, Key2Len, NULL, entry->valueLength, entry->valueHash); offset = ILibSimpleDataStore_WriteRecord(compacted, Key2, Key2Len, NULL, entry->valueLength, entry->valueHash);
@@ -410,7 +440,8 @@ __EXPORT_TYPE void ILibSimpleDataStore_EnumerateKeys(ILibSimpleDataStore dataSto
{ {
void* users[3]; void* users[3];
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore; ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
if (root == NULL) return;
users[0] = (void*)handler; users[0] = (void*)handler;
users[1] = (void*)dataStore; users[1] = (void*)dataStore;
users[2] = (void*)user; users[2] = (void*)user;
@@ -422,13 +453,16 @@ __EXPORT_TYPE void ILibSimpleDataStore_EnumerateKeys(ILibSimpleDataStore dataSto
__EXPORT_TYPE int ILibSimpleDataStore_Compact(ILibSimpleDataStore dataStore) __EXPORT_TYPE int ILibSimpleDataStore_Compact(ILibSimpleDataStore dataStore)
{ {
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore; ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
char* tmp = ILibString_Cat(root->filePath, -1, ".tmp", -1); // Create the name of the temporary data store char* tmp;
FILE* compacted; FILE* compacted;
void* state[2]; void* state[2];
int retVal = 0; int retVal = 0;
if (root == NULL) return 1; // Error
tmp = ILibString_Cat(root->filePath, -1, ".tmp", -1); // Create the name of the temporary data store
// Start by opening a temporary .tmp file. Will be used to write the compacted data store. // Start by opening a temporary .tmp file. Will be used to write the compacted data store.
if ((compacted = ILibSimpleDataStore_OpenFileEx(tmp, 1)) == NULL) { free(tmp); return 1; } if ((compacted = ILibSimpleDataStore_OpenFileEx(tmp, 1)) == NULL) { free(tmp); return 1; }
// Enumerate all keys and write them all into the temporary data store // Enumerate all keys and write them all into the temporary data store
state[0] = root; state[0] = root;