X-Git-Url: https://git.distorted.org.uk/~mdw/disorder/blobdiff_plain/f0feb22e80bfe438c16d212a7cc8be6d2282b6ac..eb5dc014179415a0e5476e986519ac96c36221f9:/lib/trackdb.c diff --git a/lib/trackdb.c b/lib/trackdb.c index d3e6e40..2aed9a4 100644 --- a/lib/trackdb.c +++ b/lib/trackdb.c @@ -49,6 +49,7 @@ #include "kvp.h" #include "log.h" #include "vector.h" +#include "rights.h" #include "trackdb.h" #include "configuration.h" #include "syscalls.h" @@ -73,7 +74,6 @@ static const char *getpart(const char *track, const char *part, const struct kvp *p, int *used_db); -static int trackdb_alltags_tid(DB_TXN *tid, char ***taglistp); static char **trackdb_new_tid(int *ntracksp, int maxtracks, DB_TXN *tid); @@ -1520,42 +1520,39 @@ fail: /* return the list of tags */ char **trackdb_alltags(void) { - DB_TXN *tid; - int err; - char **taglist; + int e; + struct vector v[1]; - for(;;) { - tid = trackdb_begin_transaction(); - err = trackdb_alltags_tid(tid, &taglist); - if(!err) break; - trackdb_abort_transaction(tid); - } - trackdb_commit_transaction(tid); - return taglist; + WITH_TRANSACTION(trackdb_listkeys(trackdb_tagsdb, v, tid)); + return v->vec; } -static int trackdb_alltags_tid(DB_TXN *tid, char ***taglistp) { - struct vector v; - DBC *c; +/** @brief List all the keys in @p db + * @param db Database + * @param v Vector to store keys in + * @param tid Transaction ID + * @return 0 or DB_LOCK_DEADLOCK + */ +int trackdb_listkeys(DB *db, struct vector *v, DB_TXN *tid) { + int e; DBT k, d; - int err; + DBC *const c = trackdb_opencursor(db, tid); - vector_init(&v); - c = trackdb_opencursor(trackdb_tagsdb, tid); + v->nvec = 0; memset(&k, 0, sizeof k); - while(!(err = c->c_get(c, &k, prepare_data(&d), DB_NEXT_NODUP))) - vector_append(&v, xstrndup(k.data, k.size)); - switch(err) { + while(!(e = c->c_get(c, &k, prepare_data(&d), DB_NEXT_NODUP))) + vector_append(v, xstrndup(k.data, k.size)); + switch(e) { case DB_NOTFOUND: break; case DB_LOCK_DEADLOCK: - return err; + return e; default: - fatal(0, "c->c_get: %s", db_strerror(err)); + fatal(0, "c->c_get: %s", db_strerror(e)); } - if((err = trackdb_closecursor(c))) return err; - vector_terminate(&v); - *taglistp = v.vec; + if((e = trackdb_closecursor(c))) + return e; + vector_terminate(v); return 0; } @@ -2423,69 +2420,6 @@ static int trusted(const char *user) { return n < config->trust.n; } -static const struct { - rights_type bit; - const char *name; -} rights_names[] = { - { RIGHT_READ, "read" }, - { RIGHT_PLAY, "play" }, - { RIGHT_MOVE_ANY, "move any" }, - { RIGHT_MOVE_MINE, "move mine" }, - { RIGHT_MOVE_RANDOM, "move random" }, - { RIGHT_REMOVE_ANY, "remove any" }, - { RIGHT_REMOVE_MINE, "remove mine" }, - { RIGHT_REMOVE_RANDOM, "remove random" }, - { RIGHT_SCRATCH_ANY, "scratch any" }, - { RIGHT_SCRATCH_MINE, "scratch mine" }, - { RIGHT_SCRATCH_RANDOM, "scratch random" }, - { RIGHT_VOLUME, "volume" }, - { RIGHT_ADMIN, "admin" }, - { RIGHT_RESCAN, "rescan" }, - { RIGHT_REGISTER, "register" }, - { RIGHT_USERINFO, "userinfo" }, - { RIGHT_PREFS, "prefs" }, - { RIGHT_GLOBAL_PREFS, "global prefs" } -}; -#define NRIGHTS (sizeof rights_names / sizeof *rights_names) - -/** @brief Convert a rights word to a string */ -static char *rights_string(rights_type r) { - struct dynstr d[1]; - size_t n; - - dynstr_init(d); - for(n = 0; n < NRIGHTS; ++n) { - if(r & rights_names[n].bit) { - if(d->nvec) - dynstr_append(d, ','); - dynstr_append_string(d, rights_names[n].name); - } - } - dynstr_terminate(d); - return d->vec; -} - -/** @brief Compute default rights for a new user */ -rights_type default_rights(void) { - /* TODO get rights from config. This is probably in the wrong place but it - * will do for now... */ - rights_type r = RIGHTS__MASK & ~(RIGHT_ADMIN|RIGHT_REGISTER - |RIGHT_MOVE__MASK - |RIGHT_SCRATCH__MASK - |RIGHT_REMOVE__MASK); - if(config->restrictions & RESTRICT_SCRATCH) - r |= RIGHT_SCRATCH_MINE|RIGHT_SCRATCH_RANDOM; - else - r |= RIGHT_SCRATCH_ANY; - if(!(config->restrictions & RESTRICT_MOVE)) - r |= RIGHT_MOVE_ANY; - if(config->restrictions & RESTRICT_REMOVE) - r |= RIGHT_REMOVE_MINE; - else - r |= RIGHT_REMOVE_ANY; - return r; -} - /** @brief Add a user */ static int create_user(const char *user, const char *password, @@ -2685,13 +2619,48 @@ int trackdb_edituserinfo(const char *user, const char *key, const char *value) { int e; + if(!strcmp(key, "rights")) { + if(!value) { + error(0, "cannot remove 'rights' key from user '%s'", user); + return -1; + } + if(parse_rights(value, 0)) { + error(0, "invalid rights string"); + return -1; + } + } else if(!strcmp(key, "email")) { + if(!strchr(value, '@')) { + error(0, "invalid email address '%s' for user '%s'", user, value); + return -1; + } + } else if(!strcmp(key, "created")) { + error(0, "cannot change creation date for user '%s'", user); + return -1; + } else if(strcmp(key, "password") + && !strcmp(key, "confirmation")) { + error(0, "unknown user info key '%s' for user '%s'", key, user); + return -1; + } WITH_TRANSACTION(trackdb_edituserinfo_tid(user, key, value, tid)); - if(e) + if(e) { + error(0, "unknown user '%s'", user); return -1; - else + } else return 0; } +/** @brief List all users + * @return NULL-terminated list of users + */ +char **trackdb_listusers(void) { + int e; + struct vector v[1]; + + vector_init(v); + WITH_TRANSACTION(trackdb_listkeys(trackdb_usersdb, v, tid)); + return v->vec; +} + /* Local Variables: c-basic-offset:2