char gdbReadHeader(GDatabase *db) { char version[2]; char buffer[DB_HEADER_DATA_SIZE]; int counter; if (db == NULL || db->fp == NULL) return 0; fseek(db->fp, 0, SEEK_SET); if (fread(buffer, DB_HEADER_DATA_SIZE, 1, db->fp) != 1) { pmError(PM_ERROR_FATAL, _("GNUpdate DB: Truncated database.\n")); return 0; } /* Check the magic string. */ if (strncmp(buffer + DB_OFFSET_MAGIC, DB_MAGIC, 8)) { pmError(PM_ERROR_FATAL, _("GNUpdate DB: Invalid database signature.\n")); return 0; } counter = 8; version[0] = gdbGet8(buffer, &counter); version[1] = gdbGet8(buffer, &counter); if (version[0] != DB_MAJOR_VER || version[1] != DB_MINOR_VER) { pmError(PM_ERROR_FATAL, _("GNUpdate DB: Unsupported database version %d.%d\n"), version[0], version[1]); return 0; } db->type = gdbGet8(buffer, &counter); if (db->type != GDB_INDEX_FILE && db->type != GDB_DATA_FILE) { pmError(PM_ERROR_FATAL, _("GNUpdate DB: Unsupported database type.\n")); return 0; } return 1; }
void * btreeReadHeader(GdbBlock *block, const char *buffer, void *extra) { BTree *tree; int counter = 0; MEM_CHECK(tree = (BTree *)malloc(sizeof(BTree))); memset(tree, 0, sizeof(BTree)); tree->block = block; tree->order = gdbGet8(buffer, &counter); tree->size = gdbGet32(buffer, &counter); tree->root = gdbGet32(buffer, &counter); tree->leftLeaf = gdbGet32(buffer, &counter); tree->minLeaf = (tree->order / 2); tree->minInt = ((tree->order + 1) / 2) - 1; return tree; }
GdbBlock * gdbReadBlockHeader(GDatabase *db, offset_t offset, blocktype_t blockType) { GdbBlock *block; char header[GDB_BLOCK_HEADER_SIZE]; int counter = 0; blocktype_t typeIndex; if (db == NULL || !GDB_VALID_OFFSET(offset) || (blockType != GDB_BLOCK_ANY && !GDB_VALID_BLOCK_TYPE(blockType))) { return NULL; } /* See if the block is cached. */ if ((block = gdbCacheGetBlock(db, offset)) != NULL) { if (blockType == GDB_BLOCK_ANY || blockType == block->type) return block; else return NULL; } /* Seek to the offset of the block. */ fseek(db->fp, offset, SEEK_SET); if (fread(header, GDB_BLOCK_HEADER_SIZE, 1, db->fp) != 1) { return NULL; } /* Allocate memory for the block. */ MEM_CHECK(block = (GdbBlock *)malloc(sizeof(GdbBlock))); memset(block, 0, sizeof(GdbBlock)); block->db = db; /* Store the info from the header. */ block->type = gdbGet8(header, &counter); /* Make sure the type is valid. */ if (!GDB_VALID_BLOCK_TYPE(block->type) || (blockType != GDB_BLOCK_ANY && blockType != block->type)) { free(block); return NULL; } typeIndex = block->type - 1; block->offset = offset; block->multiple = blockTypeInfo[typeIndex].multiple; block->dataSize = gdbGet32(header, &counter); block->flags = gdbGet16(header, &counter); block->next = gdbGet32(header, &counter); block->listNext = gdbGet32(header, &counter); GDB_CLEAR_DIRTY(block); gdbCacheAddBlock(block->db, block); return block; }
/*comment: read BTree Node out of buffer*/ void * btreeReadNodeBlock(GdbBlock *block, const uint8_t *buffer, void *extra) { BTreeNode *node; uint8_t i; uint32_t counter = 0; node = (BTreeNode *)btreeCreateNodeBlock(block, extra); //comment: tree and block of the node were set in btreeCreateNodeBlock //node->tree = (BTree *)extra; //node->block = block; node->keyCount = gdbGet8(buffer, &counter); for (i = 0; i < node->tree->order; i++) { node->children[i] = gdbGetOffset(buffer, &counter); } for (i = 0; i < node->tree->order - 1; i++) { node->keySizes[i] = gdbGet16(buffer, &counter); } for (i = 0; i < node->tree->order - 1; i++) { if (node->keySizes[i] > 0) { MEM_CHECK(node->keys[i] = keyNew(node->keySizes[i], LOC_BTREE_0158)); memcpy(node->keys[i], buffer + counter, node->keySizes[i]); counter += node->keySizes[i]; } } #if (SWITCH_ON == COMPRESS_MODE) if (node->keyCount >= 2) { uint8_t **newKeys; uint16_t *newKeySizes; __uncompressNode(node, &newKeys, &newKeySizes); /* Free up the compressed keys. */ for (i = 0; i < node->keyCount; i++) { if (node->keys[i] != NULL) { keyFree(node->keys[i], LOC_BTREE_0159); } } SAFE_FREE(node->keys, LOC_BTREE_0160); SAFE_FREE(node->keySizes, LOC_BTREE_0161); /* Move over the new arrays. */ node->keys = newKeys; node->keySizes = newKeySizes; } #endif/*(SWITCH_ON == COMPRESS_MODE)*/ return node; }
uint8_t gdbReadHeader(GDatabase *db) { uint8_t version[2]; uint8_t buffer[DB_HEADER_DATA_SIZE]; uint32_t counter; if (db == NULL || db->idxRawFile == NULL) { return 0; } rawFileSeek(db->idxRawFile, 0, SEEK_SET); if (rawFileRead(db->idxRawFile, 0, buffer, DB_HEADER_DATA_SIZE, 1, LOC_DB_0009) != 1) { sys_log(LOGSTDOUT, "error:gdbReadHeader: Truncated database.\n"); return 0; } if(0)/*debug*/ { int idx; sys_log(LOGSTDOUT, "[DEBUG]gdbReadHeader: header: "); for(idx = 0; idx < DB_HEADER_DATA_SIZE; idx ++) { sys_log(LOGSTDOUT, "%02x ", *(buffer + idx)); } sys_log(LOGSTDOUT, "\n"); } /* Check the magic string. */ if (0 != __safe_strncmp(buffer + DB_OFFSET_MAGIC, (const uint8_t *)DB_MAGIC, 8, LOC_DB_0010)) { sys_log(LOGSTDOUT, "error:gdbReadHeader: Invalid database signature.\n"); return 0; } counter = 8; version[0] = gdbGet8(buffer, &counter); version[1] = gdbGet8(buffer, &counter); if (version[0] != DB_MAJOR_VER || version[1] != DB_MINOR_VER) { sys_log(LOGSTDOUT, "error:gdbReadHeader: Unsupported database version %d.%d\n", version[0], version[1]); return 0; } db->type = gdbGet8(buffer, &counter); if (GDB_INDEX_FILE != db->type && GDB_DATA_FILE != db->type) { sys_log(LOGSTDOUT, "error:gdbReadHeader: Unsupported database type.\n"); return 0; } return 1; }