diff options
Diffstat (limited to 'src/npassd')
-rw-r--r-- | src/npassd/collection.c | 81 | ||||
-rw-r--r-- | src/npassd/service.c | 46 |
2 files changed, 122 insertions, 5 deletions
diff --git a/src/npassd/collection.c b/src/npassd/collection.c index a190b79..4bf6ca7 100644 --- a/src/npassd/collection.c +++ b/src/npassd/collection.c @@ -18,8 +18,8 @@ static int collection_alloc(sd_bus *bus, struct collection **p, const char *root, const char *alias, const char *label, uint64_t created, uint64_t modified); -static int collection_db_read(sd_bus *bus, struct sqlite3 *db, - struct collection **p, const char *alias); +static int collection_db_root_read(sd_bus *bus, struct sqlite3 *db, + struct collection **p, const char *alias); static int collection_db_write(struct sqlite3 *db, struct collection *c); static int handle_create_item(__attribute__((unused)) sd_bus_message *msg, @@ -55,8 +55,8 @@ void collection_free(struct collection *c) free(c); } -static int collection_db_read(sd_bus *bus, struct sqlite3 *db, - struct collection **p, const char *root) +static int collection_db_root_read(sd_bus *bus, struct sqlite3 *db, + struct collection **p, const char *root) { const char *query, *alias, *label; uint64_t created, modified; @@ -96,6 +96,60 @@ static int collection_db_read(sd_bus *bus, struct sqlite3 *db, created = sqlite3_column_int64(stmt, 2); modified = sqlite3_column_int64(stmt, 3); + if (alias == NULL || label == NULL || created == 0 || modified == 0) { + print_err("%s", "Found null value in column"); + ret = -EINVAL; + goto out_stmt_finalize; + } + + ret = collection_alloc(bus, p, root, alias, label, created, modified); + +out_stmt_finalize: + sqlite3_finalize(stmt); + return ret; +} + +int collection_db_alias_read(sd_bus *bus, struct sqlite3 *db, + struct collection **p, const char *alias) +{ + const char *query, *root, *label; + uint64_t created, modified; + sqlite3_stmt *stmt; + int ret; + + query = "SELECT root, label, created, modified " + "FROM collections " + "WHERE collections.alias = ? "; + + ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL); + if (ret != SQLITE_OK) { + print_err("%s", "Failed to prepare sql"); + return -EPERM; + } + + ret = sqlite3_bind_text(stmt, 1, alias, -1, NULL); + if (ret != SQLITE_OK) { + print_err("%s", "Failed to bind sql"); + ret = -EPERM; + goto out_stmt_finalize; + } + + ret = sqlite3_step(stmt); + if (ret == SQLITE_DONE) { + ret = -ENOENT; + goto out_stmt_finalize; + } + if (ret != SQLITE_ROW) { + print_err("%s", "Failed to step sql"); + ret = -EPERM; + goto out_stmt_finalize; + } + + root = (char *)sqlite3_column_text(stmt, 0); + label = (char *)sqlite3_column_text(stmt, 1); + created = sqlite3_column_int64(stmt, 2); + modified = sqlite3_column_int64(stmt, 3); + if (root == NULL || label == NULL || created == 0 || modified == 0) { print_err("%s", "Found null value in column"); ret = -EINVAL; @@ -261,6 +315,23 @@ static int collection_alloc(sd_bus *bus, struct collection **p, return 0; } +int collection_alias_search(struct collection_dlist *collections, + const char *alias, struct collection **collection) +{ + struct collection *c; + int ret; + + LIST_FOREACH (c, collections, dlist) { + ret = strcmp(c->alias, alias); + if (ret == 0) { + *collection = c; + return 0; + } + } + + return -ENOENT; +} + int collection_root_make(const char *label, const char *alias, char **root) { int ret; @@ -286,7 +357,7 @@ int collection_new(sd_bus *bus, struct sqlite3 *db, struct collection **p, uint64_t epoch; int ret; - ret = collection_db_read(bus, db, p, root); + ret = collection_db_root_read(bus, db, p, root); if (ret != -ENOENT) return ret; diff --git a/src/npassd/service.c b/src/npassd/service.c index f69ac22..5996ddc 100644 --- a/src/npassd/service.c +++ b/src/npassd/service.c @@ -15,6 +15,8 @@ static int handle_search_items(sd_bus_message *msg, void *data, sd_bus_error *ret_error); static int handle_create_collection(sd_bus_message *msg, void *data, sd_bus_error *ret_error); +static int handle_read_alias(sd_bus_message *msg, void *data, + sd_bus_error *ret_error); static const sd_bus_vtable service_vtable[] = { SD_BUS_VTABLE_START(0), @@ -24,6 +26,8 @@ static const sd_bus_vtable service_vtable[] = { SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("CreateCollection", "a{sv}s", "oo", handle_create_collection, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ReadAlias", "s", "o", handle_read_alias, + SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_VTABLE_END, }; @@ -112,6 +116,48 @@ static int handle_create_collection(sd_bus_message *msg, void *data, return ret; } +static int handle_read_alias(sd_bus_message *msg, void *data, + __attribute__((unused)) sd_bus_error *ret_error) +{ + struct service *service = data; + struct collection *collection; + const char *alias; + int ret; + + ret = sd_bus_message_read(msg, "s", &alias); + if (ret < 0) { + print_err("%s", strerror(-ret)); + return ret; + } + + ret = collection_alias_search(&service->collections, alias, + &collection); + if (ret >= 0) { + ret = sd_bus_reply_method_return(msg, "o", collection->path); + if (ret < 0) + print_err("%s", strerror(-ret)); + return ret; + } + + ret = collection_db_alias_read(service->bus, service->db, &collection, + alias); + if (ret < 0) { + ret = sd_bus_reply_method_return(msg, "o", "/"); + if (ret < 0) + print_err("%s", strerror(-ret)); + return ret; + } + + ret = sd_bus_reply_method_return(msg, "o", collection->path); + if (ret < 0) { + print_err("%s", strerror(-ret)); + return ret; + } + + LIST_INSERT_HEAD(&service->collections, collection, dlist); + return ret; +} + static int handle_open_session(sd_bus_message *msg, void *data, sd_bus_error *ret_error) { |