summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2013-04-08 20:01:11 +0200
committerYorhel <git@yorhel.nl>2013-04-08 20:01:11 +0200
commit908571fd65e74837f8cd42b2164f2987849a9e68 (patch)
tree78041c07941ce2351df5fd7b1a5814a723b7474e
parentf91b6435f9f5898dd2f20886507416935155b2c8 (diff)
db: Add hub_vars table + hub: Load hub list and info from the DB
Currently fairly useless, since no hub information is ever *saved* to the database. I'll get to that tomorrow.
-rw-r--r--src/db.c12
-rw-r--r--src/hub/connection.c6
-rw-r--r--src/hub/connection.h2
-rw-r--r--src/hub/hub.c19
-rw-r--r--src/hub/hub.h2
-rw-r--r--src/hub/manager.c64
-rw-r--r--src/hub/users.c11
-rw-r--r--src/hub/users.h2
-rw-r--r--src/util/base32.h5
9 files changed, 99 insertions, 24 deletions
diff --git a/src/db.c b/src/db.c
index a5a3f1d..accfe51 100644
--- a/src/db.c
+++ b/src/db.c
@@ -31,8 +31,8 @@ static sqlasync_wakeup_t *db_wakeup;
static ev_async db_async;
-#define SQLVER 1 /* Current SQLite user_version value */
-#define SQLVERSTR "1" /* Decimal string version of the above (can't use bind parameters in PRAGMA queries) */
+#define SQLVER 2 /* Current SQLite user_version value */
+#define SQLVERSTR "2" /* Decimal string version of the above (can't use bind parameters in PRAGMA queries) */
/* Queries to execute to convert from one version to another. */
@@ -42,6 +42,14 @@ static struct { int fromver, tover; const char *sql; } schema[] = {
"name TEXT NOT NULL PRIMARY KEY,"
"value TEXT NOT NULL"
")"
+ },
+ { 0, 1,
+ "CREATE TABLE hub_vars ("
+ "hub INTEGER NOT NULL,"
+ "name TEXT NOT NULL,"
+ "value TEXT NOT NULL,"
+ "PRIMARY KEY(hub, name)"
+ ")"
}
};
diff --git a/src/hub/connection.c b/src/hub/connection.c
index 2dbe505..bcacc14 100644
--- a/src/hub/connection.c
+++ b/src/hub/connection.c
@@ -366,12 +366,12 @@ static void set_ReconnectTimeout(hub_t *h, DBusMessage *msg, uint16_t timeout) {
}
-void hub_conn_init(hub_t *h) {
+void hub_conn_init(hub_t *h, const char *addr, uint16_t timeout) {
static dbo_hubc_vtable_t(hub_t) vt = dbo_hubc_funcs();
h->c.props.ConnectState = HUBC_IDLE;
- h->c.props.ConnectAddress = strdup("");
+ h->c.props.ConnectAddress = strdup(addr);
h->c.props.ResolvedAddress = strdup("");
- h->c.props.ReconnectTimeout = 60;
+ h->c.props.ReconnectTimeout = timeout;
h->c.props.KeyprintSHA256 = strdup("");
ev_timer_init(&h->c.timer, hub_conn_timer, h->c.props.ReconnectTimeout, 0);
diff --git a/src/hub/connection.h b/src/hub/connection.h
index 32b3565..3cacaec 100644
--- a/src/hub/connection.h
+++ b/src/hub/connection.h
@@ -55,7 +55,7 @@ typedef struct {
* directly move to IDLE or TIMER. */
void hub_conn_disconnect(hub_t *h, hub_conn_flags_t flags, const char *reason, const char *message);
-void hub_conn_init(hub_t *h);
+void hub_conn_init(hub_t *h, const char *addr, uint16_t timeout);
void hub_conn_destroy(hub_t *h);
diff --git a/src/hub/hub.c b/src/hub/hub.c
index af94b21..597d504 100644
--- a/src/hub/hub.c
+++ b/src/hub/hub.c
@@ -179,18 +179,23 @@ void hub_hub_disconnected(hub_t *h) {
-void hub_hub_init(hub_t *h) {
+void hub_hub_init(hub_t *h, const char *nick, const char *desc, const char *mail, uint32_t conn, const char *encoding) {
static dbo_hub_vtable_t(hub_t) vt = dbo_hub_funcs();
- h->h.props.MyNick = malloc(20);
- snprintf(h->h.props.MyNick, 19, "Mr.%05d", rand() % 100000);
+ if(nick)
+ h->h.props.MyNick = strdup(nick);
+ else {
+ h->h.props.MyNick = malloc(20);
+ snprintf(h->h.props.MyNick, 19, "Mr.%05d", rand() % 100000);
+ /* TODO: Save nick */
+ }
- h->h.props.MyDescription = strdup("");
- h->h.props.MyEmail = strdup("");
- h->h.props.MyConnection = 0;
+ h->h.props.MyDescription = strdup(desc);
+ h->h.props.MyEmail = strdup(mail);
+ h->h.props.MyConnection = conn;
h->h.props.MyPassword = strdup("");
- h->h.props.HubEncoding = strdup("UTF-8");
+ h->h.props.HubEncoding = strdup(encoding);
h->h.props.HubName = strdup("");
h->h.props.HubDescription = strdup("");
diff --git a/src/hub/hub.h b/src/hub/hub.h
index 41e18dc..2a9680c 100644
--- a/src/hub/hub.h
+++ b/src/hub/hub.h
@@ -71,7 +71,7 @@ void hub_hub_seterror(hub_t *h, hub_conn_flags_t disconnectflags, const char *er
void hub_hub_connected(hub_t *h);
void hub_hub_disconnected(hub_t *h);
-void hub_hub_init(hub_t *h);
+void hub_hub_init(hub_t *h, const char *nick, const char *desc, const char *mail, uint32_t conn, const char *encoding);
void hub_hub_destroy(hub_t *h);
#endif
diff --git a/src/hub/manager.c b/src/hub/manager.c
index 7de02e0..2fa34c5 100644
--- a/src/hub/manager.c
+++ b/src/hub/manager.c
@@ -78,23 +78,51 @@ static int hub_newid() {
+#define LOADVALUES\
+ V(1, ConnectAddress)\
+ V(2, ReconnectTimeout)\
+ V(3, MyNick)\
+ V(4, MyDescription)\
+ V(5, MyEmail)\
+ V(6, MyConnection)\
+ V(7, HubEncoding)\
+ V(8, UserIDSalt)
+
/* Create a hub object and register it with dbo */
-static void hub_create(int id) {
+static void hub_create(int id, sqlasync_result_t *r) {
char path[50];
assert(snprintf(path, sizeof(path), HUB_BASE_PATH"/%d", id) < (int)sizeof(path));
yinfo("Creating hub object: %d", id);
+#define V(i, n) sqlasync_value_t n = r ? r->col[i] : sqlasync_null();
+ LOADVALUES
+#undef V
+
hub_t *h = calloc(1, sizeof(hub_t));
h->id = id;
h->type = HUBM_HNONE;
h->proto = hub_adc;
dbo_register(&h->dbo, path);
- hub_conn_init(h);
- hub_hub_init(h);
- hub_users_init(h);
+
+#define INTVAL(v, min, max, def) (v.type == SQLITE_INTEGER && v.val.i64 >= min && v.val.i64 <= max ? v.val.i64 : def)
+
+ hub_conn_init(h,
+ ConnectAddress.type == SQLITE_TEXT ? ConnectAddress.val.ptr : "",
+ INTVAL(ReconnectTimeout, 0, UINT16_MAX, 60)
+ );
+ hub_hub_init(h,
+ MyNick.type == SQLITE_TEXT ? MyNick.val.ptr : "",
+ MyDescription.type == SQLITE_TEXT ? MyDescription.val.ptr : "",
+ MyEmail.type == SQLITE_TEXT ? MyEmail.val.ptr : "",
+ INTVAL(MyConnection, 0, UINT32_MAX, 0),
+ HubEncoding.type == SQLITE_TEXT ? HubEncoding.val.ptr : ""
+ );
+ hub_users_init(h, UserIDSalt.type == SQLITE_TEXT && isbase32_32(UserIDSalt.val.ptr) ? UserIDSalt.val.ptr : NULL);
hub_chat_init(h);
+#undef INTVAL
+
hub_insert(h);
}
@@ -113,7 +141,7 @@ static void hub_destroy(hub_t *h) {
static void Create(obj_t *o, DBusMessage *msg) {
int id = hub_newid();
- hub_create(id);
+ hub_create(id, NULL);
dbo_hubm_Create_reply(msg, id);
dbo_hubm_Created_signal(o, id);
}
@@ -195,6 +223,30 @@ uint16_t hub_manager_hreg() { return manager.props.RegHubs; }
uint16_t hub_manager_hop() { return manager.props.OpHubs; }
+static void hub_manager_load() {
+ /* Get everything we need with a single query. It looks kinda awkward, but
+ * the column trick makes processing easier.
+ * The UserIDSalt variable is used to obtain a listing of all available hub
+ * IDs. This variable is present for each hub, after all. */
+ sqlasync_queue_t *q = sqlasync_sql(db_sql, sqlasync_queue_sync(), SQLASYNC_STATIC,
+ "SELECT hub"
+#define V(i, n) ", (SELECT l.value FROM hub_vars l WHERE l.hub = g.hub AND l.name = \""#n"\") "
+ LOADVALUES
+#undef V
+ "FROM hub_vars g "
+ "WHERE name = \"UserIDSalt\"", 0);
+
+ sqlasync_result_t *r;
+ while((r = db_get(q, "getting hub config")) && r->result == SQLITE_ROW) {
+ if(r->col[0].type == SQLITE_INTEGER && r->col[0].val.i64 > 0 && r->col[0].val.i64 < INT_MAX/2)
+ hub_create(r->col[0].val.i64, r);
+ sqlasync_result_free(r);
+ }
+ sqlasync_result_free(r);
+ sqlasync_queue_destroy(q);
+}
+
+
void hub_manager_create() {
static dbo_hubm_vtable_t(obj_t) vt = dbo_hubm_funcs();
@@ -202,6 +254,8 @@ void hub_manager_create() {
dbo_register(&manager.dbo, MANAGER_PATH);
dbo_add_itf(&manager.dbo, dbo_hubm_interface, &vt, &manager.props);
+
+ hub_manager_load();
}
diff --git a/src/hub/users.c b/src/hub/users.c
index c98ce76..2887c6c 100644
--- a/src/hub/users.c
+++ b/src/hub/users.c
@@ -504,7 +504,7 @@ void hub_users_disconnected(hub_t *h) {
}
-void hub_users_init(hub_t *h) {
+void hub_users_init(hub_t *h, const char *salt) {
static dbo_hubu_vtable_t(hub_t) vt = dbo_hubu_funcs();
h->u.delmark = true;
@@ -512,9 +512,12 @@ void hub_users_init(hub_t *h) {
h->u.list = kh_init(userlist);
h->u.sids = kh_init(ulistsid);
- /* TODO: This salt should be the same across runs, in order to guarantee
- * stable user IDs. */
- crypt_rnd(h->u.idsalt, sizeof(h->u.idsalt));
+ if(salt)
+ base32_decode(salt, h->u.idsalt, sizeof(h->u.idsalt));
+ else {
+ crypt_rnd(h->u.idsalt, sizeof(h->u.idsalt));
+ /* TODO: Save the salt in the database */
+ }
ev_timer_init(&h->u.sweep, hub_users_sweep, SWEEP_TIMEOUT, SWEEP_TIMEOUT);
h->u.sweep.data = h;
diff --git a/src/hub/users.h b/src/hub/users.h
index 67cccc0..e41c582 100644
--- a/src/hub/users.h
+++ b/src/hub/users.h
@@ -161,7 +161,7 @@ void hub_users_listcomplete(hub_t *h);
void hub_users_disconnected(hub_t *h);
-void hub_users_init(hub_t *h);
+void hub_users_init(hub_t *h, const char *salt);
void hub_users_shutdown(hub_t *h);
void hub_users_destroy(hub_t *h);
diff --git a/src/util/base32.h b/src/util/base32.h
index 123404a..1c33c82 100644
--- a/src/util/base32.h
+++ b/src/util/base32.h
@@ -40,6 +40,11 @@ static inline bool isbase32_24(const char *s) {
}
+static inline bool isbase32_32(const char *s) {
+ return isbase32(s) && strlen(s) == 52 && s[51] >= 'A' && s[51] <= 'Q';
+}
+
+
/* Given the length of a base32-encoded string, calculate the length of its
* binary version */
static inline int base32_binlength(int l) {