diff --git a/configure.ac b/configure.ac
index 2dd0c51..e9f0375 100644
--- a/configure.ac
+++ b/configure.ac
@@ -65,5 +65,7 @@ AC_CONFIG_FILES([Makefile
src/stream/Makefile
src/tree/Makefile
src/application/Makefile
+ src/storage/Makefile
+ src/user/Makefile
tests/Makefile])
AC_OUTPUT
diff --git a/include/storage.h b/include/storage.h
new file mode 100644
index 0000000..c2fcb8b
--- /dev/null
+++ b/include/storage.h
@@ -0,0 +1,43 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2012 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef __STORAGE_H__
+#define __STORAGE_H__
+
+#include
+#include
+
+#include "class.h"
+
+
+CLASS(Storage) {
+ GDBM_FILE gdbm;
+ char * db_name;
+};
+
+void storagePut(Storage, char *, size_t, char *, size_t);
+void storageGet(Storage, char *, size_t, char **, size_t *);
+
+#endif // __STORAGE_H__
+
+// vim: set ts=4 sw=4:
+
diff --git a/include/user.h b/include/user.h
new file mode 100644
index 0000000..8aa7c62
--- /dev/null
+++ b/include/user.h
@@ -0,0 +1,51 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2012 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef __USER_H__
+#define __USER_H__
+
+#include
+
+#include "class.h"
+#include "storage.h"
+
+
+CLASS(User) {
+ char * email;
+ char * firstname;
+ char * surname;
+
+ size_t * nemail;
+ size_t * nfirstname;
+ size_t * nsurname;
+};
+
+User userLoad(User, Storage);
+void userSave(User, Storage);
+
+// void userSerialize(User, void **, size_t *);
+// void userDeserialize(User, void *, size_t);
+
+#endif // __USER_H__
+
+// vim: set ts=4 sw=4:
+
diff --git a/src/Makefile.am b/src/Makefile.am
index 9d06867..771d173 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,6 +12,8 @@ UTILS = utils/hash.c \
utils/mime_type.c
LIBS = ./application/libapplication.a \
+ ./user/libuser.a \
+ ./storage/libstorage.a \
./http/libhttp.a \
./auth/libauth.a \
./cbuf/libcbuf.a \
@@ -32,8 +34,9 @@ bin_PROGRAMS = taskrambler
taskrambler_SOURCES = taskrambler.c $(IFACE) $(UTILS)
taskrambler_CFLAGS = $(CFLAGS) -Wall -DPWD=\"$(PWD)\" -I ../include/# $(COVERAGE_CFLAGS)
-taskrambler_LDADD = $(LIBS) -lrt -lssl -lldap
+taskrambler_LDADD = $(LIBS) -lrt -lssl -lldap -lgdbm
#taskrambler_LDFLAGS = $(COVERAGE_LDFLAGS)
SUBDIRS = asset auth cbuf class hash queue http \
- logger server session socket stream tree application
+ logger server session socket stream tree application \
+ storage user
diff --git a/src/storage/Makefile.am b/src/storage/Makefile.am
new file mode 100644
index 0000000..3e6aeb0
--- /dev/null
+++ b/src/storage/Makefile.am
@@ -0,0 +1,7 @@
+ACLOCAL_AMFLAGS = -I m4
+AUTOMAKE_OPTIONS = subdir-objects
+
+noinst_LIBRARIES = libstorage.a
+
+libstorage_a_SOURCES = storage.c get.c put.c
+libstorage_a_CFLAGS = $(CFLAGS) -Wall -I ../../include/
diff --git a/src/storage/get.c b/src/storage/get.c
new file mode 100644
index 0000000..1e4274b
--- /dev/null
+++ b/src/storage/get.c
@@ -0,0 +1,53 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2012 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+
+#include "storage.h"
+#include "class.h"
+
+#include "utils/memory.h"
+
+void
+storageGet(
+ Storage this,
+ char * _key, size_t nkey,
+ char ** data, size_t * ndata)
+{
+ datum key = {_key, nkey};
+ datum value;
+
+ value = gdbm_fetch(this->gdbm, key);
+
+ if (NULL != value.dptr) {
+ *ndata = value.dsize;
+ *data = memMalloc(value.dsize);
+ memcpy(*data, value.dptr, value.dsize);
+
+ free(value.dptr);
+ }
+}
+
+// vim: set ts=4 sw=4:
diff --git a/src/storage/put.c b/src/storage/put.c
new file mode 100644
index 0000000..f6d8079
--- /dev/null
+++ b/src/storage/put.c
@@ -0,0 +1,41 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2012 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+
+#include "storage.h"
+#include "class.h"
+
+#include "utils/memory.h"
+
+void
+storagePut(Storage this, char * _key, size_t nkey, char * data, size_t ndata)
+{
+ datum key = {_key, nkey};
+ datum value = {data, ndata};
+
+ gdbm_store(this->gdbm, key, value, GDBM_REPLACE);
+}
+
+// vim: set ts=4 sw=4:
diff --git a/src/storage/storage.c b/src/storage/storage.c
new file mode 100644
index 0000000..c275793
--- /dev/null
+++ b/src/storage/storage.c
@@ -0,0 +1,69 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2012 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+
+#include "storage.h"
+#include "class.h"
+
+#include "utils/memory.h"
+
+static
+int
+storageCtor(void * _this, va_list * params)
+{
+ Storage this = _this;
+ char * db_name = va_arg(* params, void *);
+
+ this->db_name = memMalloc(strlen(db_name) + 1);
+ strcpy(this->db_name, db_name);
+
+ this->gdbm = gdbm_open(
+ this->db_name,
+ 0,
+ GDBM_WRCREAT,
+ S_IRUSR | S_IWUSR,
+ NULL);
+
+ if (NULL == this->gdbm) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static
+void
+storageDtor(void * _this)
+{
+ Storage this = _this;
+
+ if (NULL != this->db_name) MEM_FREE(this->db_name);
+ if (NULL != this->gdbm) gdbm_close(this->gdbm);
+}
+
+INIT_IFACE(Class, storageCtor, storageDtor, NULL);
+CREATE_CLASS(Storage, NULL, IFACE(Class));
+
+// vim: set ts=4 sw=4:
diff --git a/src/user/Makefile.am b/src/user/Makefile.am
new file mode 100644
index 0000000..e3cd065
--- /dev/null
+++ b/src/user/Makefile.am
@@ -0,0 +1,7 @@
+ACLOCAL_AMFLAGS = -I m4
+AUTOMAKE_OPTIONS = subdir-objects
+
+noinst_LIBRARIES = libuser.a
+
+libuser_a_SOURCES = user.c load.c save.c
+libuser_a_CFLAGS = $(CFLAGS) -Wall -I ../../include/
diff --git a/src/user/load.c b/src/user/load.c
new file mode 100644
index 0000000..ed6547f
--- /dev/null
+++ b/src/user/load.c
@@ -0,0 +1,64 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2012 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+
+#include "user.h"
+#include "storage.h"
+#include "class.h"
+
+#include "utils/memory.h"
+
+
+User
+userLoad(User this, Storage storage)
+{
+ char * storage_data;
+ size_t nstorage_data;
+
+ size_t * user_data_sizes;
+
+ storageGet(
+ storage,
+ this->email, *this->nemail,
+ &storage_data, &nstorage_data);
+
+ if (NULL == storage_data) {
+ return NULL;
+ }
+
+ user_data_sizes =
+ (size_t *)(storage_data + nstorage_data - 3 * sizeof(size_t));
+
+ this->nemail = user_data_sizes;
+ this->nfirstname = user_data_sizes + 1;
+ this->nsurname = user_data_sizes + 2;
+
+ this->email = storage_data;
+ this->firstname = this->email + *this->nemail + 1;
+ this->surname = this->firstname + *this->nfirstname + 1;
+
+ return this;
+}
+
+// vim: set ts=4 sw=4:
diff --git a/src/user/save.c b/src/user/save.c
new file mode 100644
index 0000000..17e546f
--- /dev/null
+++ b/src/user/save.c
@@ -0,0 +1,48 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2012 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+
+#include "user.h"
+#include "storage.h"
+#include "class.h"
+
+#include "utils/memory.h"
+
+
+void
+userSave(User this, Storage storage)
+{
+ size_t storage_size =
+ *this->nemail + 1 +
+ *this->nfirstname + 1 +
+ *this->nsurname + 1 +
+ 3 * sizeof(size_t);
+
+ storagePut(
+ storage,
+ this->email, *this->nemail,
+ this->email, storage_size);
+}
+
+// vim: set ts=4 sw=4:
diff --git a/src/user/user.c b/src/user/user.c
new file mode 100644
index 0000000..1dac923
--- /dev/null
+++ b/src/user/user.c
@@ -0,0 +1,90 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2012 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "user.h"
+#include "storage.h"
+#include "class.h"
+
+#include "utils/memory.h"
+
+
+static
+int
+userCtor(void * _this, va_list * params)
+{
+ User this = _this;
+
+ char * email = va_arg(* params, char *);
+
+ if (NULL != email) {
+ size_t nemail = va_arg(* params, size_t);
+ char * firstname = va_arg(* params, char *);
+ size_t nfirstname = va_arg(* params, size_t);
+ char * surname = va_arg(* params, char *);
+ size_t nsurname = va_arg(* params, size_t);
+
+ size_t storage_size =
+ nemail + 1 +
+ nfirstname + 1 +
+ nsurname + 1 +
+ 3 * sizeof(size_t);
+
+ this->email = memMalloc(storage_size);
+ memcpy(this->email, email, nemail);
+ this->email[nemail] = '\0';
+
+ this->firstname = this->email + nemail + 1;
+ memcpy(this->firstname, firstname, nfirstname);
+ this->firstname[nfirstname] = '\0';
+
+ this->surname = this->firstname + nfirstname + 1;
+ memcpy(this->surname, surname, nsurname);
+ this->surname[nsurname] = '\0';
+
+ this->nemail = (size_t *)(this->surname + nsurname + 1);
+ *this->nemail = nemail;
+
+ this->nfirstname = this->nemail + 1;
+ *this->nfirstname = nfirstname;
+
+ this->nsurname = this->nfirstname + 1;
+ *this->nsurname = nsurname;
+ }
+
+ return 0;
+}
+
+static
+void
+userDtor(void * _this)
+{
+ User this = _this;
+
+ if (NULL != this->email) {
+ MEM_FREE(this->email);
+ }
+}
+
+INIT_IFACE(Class, userCtor, userDtor, NULL);
+CREATE_CLASS(User, NULL, IFACE(Class));
+
+// vim: set ts=4 sw=4:
diff --git a/src/usertest.c b/src/usertest.c
new file mode 100644
index 0000000..089ff3d
--- /dev/null
+++ b/src/usertest.c
@@ -0,0 +1,59 @@
+#include
+#include
+#include
+#include
+#include
+
+#include "class.h"
+#include "commons.h"
+#include "user.h"
+#include "storage.h"
+
+#include "utils/memory.h"
+
+int
+main(int argc, char * argv[])
+{
+ Storage users = new(Storage, CSTRA("./users.db"));
+ User user;
+ User georg;
+ //User steffi;
+ size_t nuser;
+
+ if (NULL == users) {
+ fprintf(stderr, "%s\n", gdbm_strerror(gdbm_errno));
+ fprintf(stderr, "%s\n", strerror(errno));
+ return 1;
+ }
+
+ georg = new(User,
+ CSTRA("georg@steffers.org"),
+ CSTRA("Georg"),
+ CSTRA("Hopp"));
+
+ userSave(georg, users);
+ delete(georg);
+
+ user = new(User, NULL);
+ user->email = "georg@steffers.org";
+ nuser = sizeof("georg@steffers.org") - 1;
+ user->nemail = &nuser;
+
+ if (NULL == userLoad(user, users)) {
+ fprintf(stderr, "can't find user");
+ } else {
+ puts("found user:");
+ puts(user->email);
+ puts(user->firstname);
+ puts(user->surname);
+ }
+
+ delete(user);
+ delete(users);
+
+ memCleanup();
+
+ return 0;
+}
+
+// vim: set et ts=4 sw=4: