X-Git-Url: https://git.distorted.org.uk/~mdw/disorder/blobdiff_plain/2563dc1f46fad1640e2472151a9f1cf918f841b9..0beb320eeb18f9dd3d39999509ac8d4bff40f2ae:/lib/trackdb-playlists.c diff --git a/lib/trackdb-playlists.c b/lib/trackdb-playlists.c index 1492f8c..f9f8252 100644 --- a/lib/trackdb-playlists.c +++ b/lib/trackdb-playlists.c @@ -32,6 +32,7 @@ #include "log.h" #include "configuration.h" #include "vector.h" +#include "eventlog.h" static int trackdb_playlist_get_tid(const char *name, const char *who, @@ -81,7 +82,7 @@ int playlist_parse_name(const char *name, if(!valid_username(name)) return -1; owner = 0; - share = "public"; + share = "shared"; } if(ownerp) *ownerp = owner; @@ -100,7 +101,7 @@ static int playlist_may_read(const char *name, const char *share) { char *owner; - if(!playlist_parse_name(name, &owner, 0)) + if(playlist_parse_name(name, &owner, 0)) return 0; /* Anyone can read shared playlists */ if(!owner) @@ -125,7 +126,7 @@ static int playlist_may_write(const char *name, const char attribute((unused)) *share) { char *owner; - if(!playlist_parse_name(name, &owner, 0)) + if(playlist_parse_name(name, &owner, 0)) return 0; /* Anyone can modify shared playlists */ if(!owner) @@ -147,7 +148,7 @@ static int playlist_may_write(const char *name, * * Possible return values: * - @c 0 on success - * - @c DB_NOTFOUND if the playlist doesn't exist + * - @c ENOENT if the playlist doesn't exist * - @c EINVAL if the playlist name is invalid * - @c EACCES if the playlist cannot be read by @p who */ @@ -158,13 +159,16 @@ int trackdb_playlist_get(const char *name, char **sharep) { int e; - if(!playlist_parse_name(name, 0, 0)) { + if(playlist_parse_name(name, 0, 0)) { error(0, "invalid playlist name '%s'", name); return EINVAL; } WITH_TRANSACTION(trackdb_playlist_get_tid(name, who, tracksp, ntracksp, sharep, tid)); + /* Don't expose libdb error codes too much */ + if(e == DB_NOTFOUND) + e = ENOENT; return e; } @@ -226,6 +230,7 @@ static int trackdb_playlist_get_tid(const char *name, /** @brief Modify or create a playlist * @param name Playlist name + * @param who User modifying playlist * @param tracks List of tracks to set, or NULL to leave alone * @param ntracks Length of @p tracks * @param share Sharing status, or NULL to leave alone @@ -237,6 +242,10 @@ static int trackdb_playlist_get_tid(const char *name, * none, and the default sharing is private (if it is an owned one) or shared * (otherwise). * + * If neither @c tracks nor @c share are set then we only do an access check. + * The database is never modified (even to create the playlist) in this + * situation. + * * Possible return values: * - @c 0 on success * - @c EINVAL if the playlist name is invalid @@ -250,7 +259,7 @@ int trackdb_playlist_set(const char *name, int e; char *owner; - if(!playlist_parse_name(name, &owner, 0)) { + if(playlist_parse_name(name, &owner, 0)) { error(0, "invalid playlist name '%s'", name); return EINVAL; } @@ -286,6 +295,7 @@ static int trackdb_playlist_set_tid(const char *name, struct kvp *k; int e; const char *s; + const char *event = "playlist_modified"; if((e = trackdb_getdata(trackdb_playlistsdb, name, &k, tid)) && e != DB_NOTFOUND) @@ -304,6 +314,7 @@ static int trackdb_playlist_set_tid(const char *name, k = 0; kvp_set(&k, "count", 0); kvp_set(&k, "sharing", defshare); + event = "playlist_created"; } /* Check that the modification is allowed */ if(!(s = kvp_get(k, "sharing"))) { @@ -312,9 +323,12 @@ static int trackdb_playlist_set_tid(const char *name, } if(!playlist_may_write(name, who, s)) return EACCES; + /* If no change was requested then don't even create */ + if(!share && !tracks) + return 0; /* Set the new values */ if(share) - kvp_set(&k, "share", share); + kvp_set(&k, "sharing", share); if(tracks) { char b[16]; int oldcount, n; @@ -344,7 +358,11 @@ static int trackdb_playlist_set_tid(const char *name, kvp_set(&k, "count", b); } /* Store the resulting record */ - return trackdb_putdata(trackdb_playlistsdb, name, k, tid, 0); + e = trackdb_putdata(trackdb_playlistsdb, name, k, tid, 0); + /* Log the event */ + if(!e) + eventlog(event, name, kvp_get(k, "sharing"), (char *)0); + return e; } /** @brief Get a list of playlists @@ -376,13 +394,17 @@ static int trackdb_playlist_list_tid(const char *who, while(!(e = c->c_get(c, k, prepare_data(d), DB_NEXT))) { char *name = xstrndup(k->data, k->size), *owner; const char *share = kvp_get(kvp_urldecode(d->data, d->size), - "share"); + "sharing"); /* Extract owner; malformed names are skipped */ if(playlist_parse_name(name, &owner, 0)) { error(0, "invalid playlist name '%s' found in database", name); continue; } + if(!share) { + error(0, "playlist '%s' has no 'sharing' key", name); + continue; + } /* Always list public and shared playlists * Only list private ones to their owner * Don't list anything else @@ -393,6 +415,7 @@ static int trackdb_playlist_list_tid(const char *who, && owner && !strcmp(owner, who))) vector_append(v, name); } + trackdb_closecursor(c); switch(e) { case DB_NOTFOUND: break; @@ -418,19 +441,21 @@ static int trackdb_playlist_list_tid(const char *who, * - @c 0 on success * - @c EINVAL if the playlist name is invalid * - @c EACCES if the playlist cannot be modified by @p who - * - @c DB_NOTFOUND if the playlist doesn't exist + * - @c ENOENT if the playlist doesn't exist */ int trackdb_playlist_delete(const char *name, const char *who) { int e; char *owner; - if(!playlist_parse_name(name, &owner, 0)) { + if(playlist_parse_name(name, &owner, 0)) { error(0, "invalid playlist name '%s'", name); return EINVAL; } /* We've checked as much as we can for now, now go and attempt the change */ WITH_TRANSACTION(trackdb_playlist_delete_tid(name, who, tid)); + if(e == DB_NOTFOUND) + e = ENOENT; return e; } @@ -451,7 +476,10 @@ static int trackdb_playlist_delete_tid(const char *name, if(!playlist_may_write(name, who, s)) return EACCES; /* Delete the playlist */ - return trackdb_delkey(trackdb_playlistsdb, name, tid); + e = trackdb_delkey(trackdb_playlistsdb, name, tid); + if(!e) + eventlog("playlist_deleted", name, 0); + return e; } /*