aboutsummaryrefslogtreecommitdiff
path: root/src/userdb.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2016-01-25 16:10:46 -0500
committerFranklin Wei <git@fwei.tk>2016-01-25 16:10:46 -0500
commita1acf425cfb00a41c7862c915eb024207658c814 (patch)
treefcee7cf8a1c204b779ab50a3545e8671012d7643 /src/userdb.c
parentd351bb34ba256d6fbf0869485bcf75ec46646e74 (diff)
downloadnetcosm-a1acf425cfb00a41c7862c915eb024207658c814.zip
netcosm-a1acf425cfb00a41c7862c915eb024207658c814.tar.gz
netcosm-a1acf425cfb00a41c7862c915eb024207658c814.tar.bz2
netcosm-a1acf425cfb00a41c7862c915eb024207658c814.tar.xz
inventory works
Diffstat (limited to 'src/userdb.c')
-rw-r--r--src/userdb.c94
1 files changed, 65 insertions, 29 deletions
diff --git a/src/userdb.c b/src/userdb.c
index 3a7ebbc..e107a6c 100644
--- a/src/userdb.c
+++ b/src/userdb.c
@@ -26,51 +26,58 @@
static void *map = NULL;
static char *db_file = NULL;
+static void free_userdata(void *ptr)
+{
+ struct userdata_t *data = ptr;
+ hash_free(data->objects);
+ free(data);
+}
+
/*
- * the user DB is stored on disk as an ASCII database
+ * the user DB is stored on disk as an binary flat file
*
* this is then loaded into fixed-sized hash map at init
- * TODO: implement with B-tree
+ * TODO: re-implement with B-tree
*/
void userdb_init(const char *file)
{
db_file = strdup(file);
- /* FILE* for getline() */
- FILE *f = fopen(file, "r");
+ int fd = open(file, O_RDONLY);
map = hash_init(256, hash_djb, compare_strings);
- hash_setfreedata_cb(map, free);
+ hash_setfreedata_cb(map, free_userdata);
- char *format;
- asprintf(&format, "%%%d[a-z0-9 ]:%%%d[A-Z]:%%%ds:%%d:%%ld\n",
- MAX_NAME_LEN, SALT_LEN, AUTH_HASHLEN * 2);
-
- if(f)
+ /* 0 is a valid fd */
+ if(fd >= 0)
{
while(1)
{
struct userdata_t *data = calloc(1, sizeof(*data));
- int ret = fscanf(f, format,
- data->username,
- data->salt,
- data->passhash,
- &data->priv,
- &data->last_login);
+ if(read(fd, data, sizeof(*data)) != sizeof(*data))
+ break;
- if(ret != 5)
- {
- free(data);
+ size_t n_objects;
+ if(read(fd, &n_objects, sizeof(n_objects)) != sizeof(n_objects))
break;
+
+ data->objects = hash_init(MIN(8, n_objects),
+ hash_djb,
+ compare_strings);
+
+ debugf("READING %d OBJECTS INTO INVENTORY\n", n_objects);
+
+ for(unsigned i = 0; i < n_objects; ++i)
+ {
+ struct object_t *obj = obj_read(fd);
+ hash_insert(data->objects, obj->name, obj);
}
hash_insert(map, data->username, data);
}
- fclose(f);
+ close(fd);
}
-
- free(format);
}
void userdb_write(const char *file)
@@ -83,12 +90,34 @@ void userdb_write(const char *file)
ptr = NULL;
if(!user)
break;
- dprintf(fd, "%s:%*s:%*s:%d:%ld\n",
- user->username,
- SALT_LEN, user->salt,
- AUTH_HASHLEN*2, user->passhash,
- user->priv,
- user->last_login);
+
+ write(fd, user, sizeof(*user));
+
+ size_t n_objects;
+ if(user->objects)
+ n_objects = hash_size(user->objects);
+ else
+ n_objects = 0;
+
+ write(fd, &n_objects, sizeof(n_objects));
+
+ debugf("WRITING %d OBJECTS\n", n_objects);
+
+ /* write objects */
+
+ if(n_objects)
+ {
+ void *objptr = user->objects, *objsave;
+ while(1)
+ {
+ struct object_t *obj = hash_iterate(objptr, &objsave, NULL);
+ if(!obj)
+ break;
+ objptr = NULL;
+ debugf("WRITING OBJECT %s\n", obj->name);
+ obj_write(fd, obj);
+ }
+ }
}
close(fd);
}
@@ -114,6 +143,13 @@ struct userdata_t *userdb_add(struct userdata_t *data)
struct userdata_t *new = calloc(1, sizeof(*new)); /* only in C! */
memcpy(new, data, sizeof(*new));
+ /* don't overwrite their inventory */
+ struct userdata_t *old = userdb_lookup(new->username);
+ if(old && old->objects)
+ new->objects = hash_dup(old->objects);
+ else
+ new->objects = hash_init(8, hash_djb, compare_strings);
+
struct userdata_t *ret;
if((ret = hash_insert(map, new->username, new))) /* already exists */
@@ -129,7 +165,7 @@ struct userdata_t *userdb_add(struct userdata_t *data)
void userdb_shutdown(void)
{
- if(map && db_file)
+ if(map && db_file && !are_child)
userdb_write(db_file);
if(map)
{