#include "log.h"
#include "configuration.h"
#include "vector.h"
+#include "eventlog.h"
+#include "validity.h"
static int trackdb_playlist_get_tid(const char *name,
const char *who,
const char *who,
DB_TXN *tid);
-/** @brief Parse a playlist name
- * @param name Playlist name
- * @param ownerp Where to put owner, or NULL
- * @param sharep Where to put default sharing, or NULL
- * @return 0 on success, -1 on error
- *
- * Playlists take the form USER.PLAYLIST or just PLAYLIST. The PLAYLIST part
- * is alphanumeric and nonempty. USER is a username (see valid_username()).
- */
-int playlist_parse_name(const char *name,
- char **ownerp,
- char **sharep) {
- const char *dot = strchr(name, '.'), *share;
- char *owner;
-
- if(dot) {
- /* Owned playlist */
- owner = xstrndup(name, dot - name);
- if(!valid_username(owner))
- return -1;
- if(!valid_username(dot + 1))
- return -1;
- share = "private";
- } else {
- /* Shared playlist */
- if(!valid_username(name))
- return -1;
- owner = 0;
- share = "public";
- }
- if(ownerp)
- *ownerp = owner;
- if(sharep)
- *sharep = xstrdup(share);
- return 0;
-}
-
/** @brief Check read access rights
* @param name Playlist name
* @param who Who wants to read
int e;
if(playlist_parse_name(name, 0, 0)) {
- error(0, "invalid playlist name '%s'", name);
+ disorder_error(0, "invalid playlist name '%s'", name);
return EINVAL;
}
WITH_TRANSACTION(trackdb_playlist_get_tid(name, who,
return e;
/* Get sharability */
if(!(s = kvp_get(k, "sharing"))) {
- error(0, "playlist '%s' has no 'sharing' key", name);
+ disorder_error(0, "playlist '%s' has no 'sharing' key", name);
s = "private";
}
/* Check the read is allowed */
*sharep = xstrdup(s);
/* Get track count */
if(!(s = kvp_get(k, "count"))) {
- error(0, "playlist '%s' has no 'count' key", name);
+ disorder_error(0, "playlist '%s' has no 'count' key", name);
s = "0";
}
ntracks = atoi(s);
if(ntracks < 0) {
- error(0, "playlist '%s' has negative count", name);
+ disorder_error(0, "playlist '%s' has negative count", name);
ntracks = 0;
}
/* Return track count */
for(int n = 0; n < ntracks; ++n) {
snprintf(b, sizeof b, "%d", n);
if(!(s = kvp_get(k, b))) {
- error(0, "playlist '%s' lacks track %d", name, n);
+ disorder_error(0, "playlist '%s' lacks track %d", name, n);
s = "unknown";
}
tracks[n] = xstrdup(s);
/** @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
char *owner;
if(playlist_parse_name(name, &owner, 0)) {
- error(0, "invalid playlist name '%s'", name);
+ disorder_error(0, "invalid playlist name '%s'", name);
return EINVAL;
}
/* Check valid share types */
/* Playlists with an owner must be public or private */
if(strcmp(share, "public")
&& strcmp(share, "private")) {
- error(0, "playlist '%s' must be public or private", name);
+ disorder_error(0, "playlist '%s' must be public or private", name);
return EINVAL;
}
} else {
/* Playlists with no owner must be shared */
if(strcmp(share, "shared")) {
- error(0, "playlist '%s' must be shared", name);
+ disorder_error(0, "playlist '%s' must be shared", name);
return EINVAL;
}
}
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)
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"))) {
- error(0, "playlist '%s' has no 'sharing' key", name);
+ disorder_error(0, "playlist '%s' has no 'sharing' key", name);
s = "private";
}
if(!playlist_may_write(name, who, s))
/* Sanity check track count */
if(ntracks < 0 || ntracks > config->playlist_max) {
- error(0, "invalid track count %d", ntracks);
+ disorder_error(0, "invalid track count %d", ntracks);
return EINVAL;
}
/* Set the tracks */
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
/* Extract owner; malformed names are skipped */
if(playlist_parse_name(name, &owner, 0)) {
- error(0, "invalid playlist name '%s' found in database", name);
+ disorder_error(0, "invalid playlist name '%s' found in database", name);
continue;
}
if(!share) {
- error(0, "playlist '%s' has no 'sharing' key", name);
+ disorder_error(0, "playlist '%s' has no 'sharing' key", name);
continue;
}
/* Always list public and shared playlists
case DB_LOCK_DEADLOCK:
return e;
default:
- fatal(0, "c->c_get: %s", db_strerror(e));
+ disorder_fatal(0, "c->c_get: %s", db_strerror(e));
}
vector_terminate(v);
if(playlistsp)
char *owner;
if(playlist_parse_name(name, &owner, 0)) {
- error(0, "invalid playlist name '%s'", name);
+ disorder_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 */
return e;
/* Check that modification is allowed */
if(!(s = kvp_get(k, "sharing"))) {
- error(0, "playlist '%s' has no 'sharing' key", name);
+ disorder_error(0, "playlist '%s' has no 'sharing' key", name);
s = "private";
}
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;
}
/*