xbot/src/db.c

284 lines
6.8 KiB
C
Executable File

#include "util.h"
#include "irc.h"
#include "db.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int db_write(struct db_table *db, char *fname)
{
FILE *fp;
int i;
char *fullpath;
if ((fp = fopen(fname, "wb")) == NULL)
{
return -1;
}
db->db_magic = DB_MAGIC;
db->db_ver = DB_VER;
// get the full path to the db file
#ifdef _WIN32
fullpath = _fullpath(NULL, fname, 0);
#else
fullpath = realpath(fname, NULL);
#endif
printf("Writing db to file: %s\n", fullpath);
// write the header
fwrite(db, sizeof(struct db_table), 1, fp);
// write the hashes
fwrite(db->hashes, sizeof(struct db_hash), db->count, fp);
// write the keys and values
for (i = 0; i < db->count; i++)
{
fwrite(db->hashes[i].key, sizeof(char), db->hashes[i].key_len, fp);
fwrite(db->hashes[i].value, sizeof(char), db->hashes[i].value_len, fp);
}
fclose(fp);
return 0;
}
struct db_table *db_read(char *fname)
{
FILE *fp;
struct db_table *db;
int tmp;
if ((fp = fopen(fname, "rb")) == NULL)
{
return NULL;
}
db = (struct db_table *)malloc(sizeof(struct db_table));
fread(db, sizeof(struct db_table), 1, fp);
// check the magic value
if (db->db_magic != DB_MAGIC)
{
printf("Error: %s incompatible or unknown db file format: Bad Magic\n", fname);
return NULL;
}
// check the version
if (db->db_ver != DB_VER)
{
printf("Error: %s incompatible or unknown db file format: Incompatible Version\n", fname);
return NULL;
}
tmp = db->count != 0 ? db->count : sizeof(struct db_hash);
db->hashes = (struct db_hash *)malloc(sizeof(struct db_hash) * tmp);
fread(db->hashes, sizeof(struct db_hash), db->count, fp);
// read the keys and values
for (tmp = 0; tmp < db->count; tmp++)
{
db->hashes[tmp].key = (char *)malloc(sizeof(char) * db->hashes[tmp].key_len);
db->hashes[tmp].value = (char *)malloc(sizeof(char) * db->hashes[tmp].value_len);
fread(db->hashes[tmp].key, sizeof(char), db->hashes[tmp].key_len, fp);
fread(db->hashes[tmp].value, sizeof(char), db->hashes[tmp].value_len, fp);
}
fclose(fp);
return db;
}
int db_set_hash(struct db_table *db, char *key, void *value)
{
int i;
// check if the key already exists and update it
for (i = 0; i < db->count; i++)
{
if (strcmp(db->hashes[i].key, key) == 0)
{
if (db->hashes[i].type == DB_TYPE_CHAR)
{
free(db->hashes[i].value);
}
db->hashes[i].value = value;
return 0;
}
}
db->hashes[db->count].key_len = strlen(key) + 1;
db->hashes[db->count].key = (char *)malloc(sizeof(char) * db->hashes[db->count].key_len);
memset(db->hashes[db->count].key, 0, sizeof(char) * db->hashes[db->count].key_len);
strlcpy(db->hashes[db->count].key, key, sizeof(char) * db->hashes[db->count].key_len);
db->hashes[db->count].value = value;
db->count++;
return 0;
}
int db_set_hash_char(struct db_table *db, char *key, char *value)
{
// check if the key already exists and update it
int i;
for (i = 0; i < db->count; i++)
{
if (strcmp(db->hashes[i].key, key) == 0)
{
if (db->hashes[i].type == DB_TYPE_CHAR)
{
free(db->hashes[i].value);
}
db->hashes[i].type = DB_TYPE_CHAR;
db->hashes[i].value_len = strlen(value) + 1;
db->hashes[i].value = (char *)malloc(sizeof(char) * db->hashes[i].value_len);
memset(db->hashes[i].value, 0, sizeof(char) * db->hashes[i].value_len);
strlcpy(db->hashes[i].value, value, sizeof(char) * db->hashes[i].value_len);
return 0;
}
}
db->hashes = (struct db_hash *)realloc(db->hashes, sizeof(struct db_hash) * (db->count + 1));
// zero out reallocated memory
memset(&db->hashes[db->count], 0, sizeof(struct db_hash));
db->hashes[db->count].type = DB_TYPE_CHAR;
db->hashes[db->count].value_len = strlen(value) + 1;
db->hashes[db->count].value = (char *)malloc(sizeof(char) * db->hashes[db->count].value_len);
memset(db->hashes[db->count].value, 0, sizeof(char) * db->hashes[db->count].value_len);
strlcpy(db->hashes[db->count].value, value, sizeof(char) * db->hashes[db->count].value_len);
return db_set_hash(db, key, db->hashes[db->count].value);
}
int db_set_hash_int(struct db_table *db, char *key, int value)
{
db->hashes = (struct db_hash *)realloc(db->hashes, sizeof(struct db_hash) * (db->count + 1));
// zero out reallocated memory
memset(&db->hashes[db->count], 0, sizeof(struct db_hash));
db->hashes[db->count].type = DB_TYPE_INT;
db->hashes[db->count].value_len = sizeof(int);
db->hashes[db->count].value = (int *)malloc(sizeof(int));
memcpy(db->hashes[db->count].value, &value, sizeof(int));
return db_set_hash(db, key, db->hashes[db->count].value);
}
int db_set_hash_float(struct db_table *db, char *key, float value)
{
db->hashes = (struct db_hash *)realloc(db->hashes, sizeof(struct db_hash) * (db->count + 1));
// zero out reallocated memory
memset(&db->hashes[db->count], 0, sizeof(struct db_hash));
db->hashes[db->count].type = DB_TYPE_FLOAT;
db->hashes[db->count].value_len = sizeof(float);
db->hashes[db->count].value = (float *)malloc(sizeof(float));
memcpy(db->hashes[db->count].value, &value, sizeof(float));
return db_set_hash(db, key, db->hashes[db->count].value);
}
int db_del_hash(struct db_table *db, char *key)
{
int i;
for (i = 0; i < db->count; i++)
{
if (strcmp(db->hashes[i].key, key) == 0)
{
free(db->hashes[i].key);
free(db->hashes[i].value);
memmove(&db->hashes[i], &db->hashes[i + 1], sizeof(struct db_hash) * (db->count - i));
db->count--;
return 0;
}
}
return -1;
}
void *db_get_hash(struct db_table *db, char *key)
{
int i;
for (i = 0; i < db->count; i++)
{
if (strcmp(db->hashes[i].key, key) == 0)
{
return db->hashes[i].value;
}
}
return NULL;
}
int db_get_hash_type(struct db_table *db, char *key)
{
int i;
for (i = 0; i < db->count; i++)
{
if (strcmp(db->hashes[i].key, key) == 0)
{
return db->hashes[i].type;
}
}
return -1;
}
char *db_get_hash_char(struct db_table *db, char *key)
{
return (char *)db_get_hash(db, key);
}
int db_get_hash_int(struct db_table *db, char *key)
{
int value;
memcpy(&value, db_get_hash(db, key), sizeof(int));
return value;
}
float db_get_hash_float(struct db_table *db, char *key)
{
float value;
memcpy(&value, db_get_hash(db, key), sizeof(float));
return value;
}