diff options
author | Yorhel <git@yorhel.nl> | 2013-04-08 20:01:11 +0200 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2013-04-08 20:01:11 +0200 |
commit | 908571fd65e74837f8cd42b2164f2987849a9e68 (patch) | |
tree | 78041c07941ce2351df5fd7b1a5814a723b7474e | |
parent | f91b6435f9f5898dd2f20886507416935155b2c8 (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.c | 12 | ||||
-rw-r--r-- | src/hub/connection.c | 6 | ||||
-rw-r--r-- | src/hub/connection.h | 2 | ||||
-rw-r--r-- | src/hub/hub.c | 19 | ||||
-rw-r--r-- | src/hub/hub.h | 2 | ||||
-rw-r--r-- | src/hub/manager.c | 64 | ||||
-rw-r--r-- | src/hub/users.c | 11 | ||||
-rw-r--r-- | src/hub/users.h | 2 | ||||
-rw-r--r-- | src/util/base32.h | 5 |
9 files changed, 99 insertions, 24 deletions
@@ -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) { |