queue_remove(q, c->who);
/* De-prepare the track. */
abandon(c->ev, q);
- /* If we removed a random track then add another one. */
- if(q->state == playing_random)
- add_random_track();
+ /* See about adding a new random track */
+ add_random_track(c->ev);
/* Prepare whatever the next head track is. */
if(qhead.next != &qhead)
prepare(c->ev, qhead.next);
static int c_get(struct conn *c,
char **vec,
int attribute((unused)) nvec) {
- const char *v;
+ const char *v, *track;
- if(vec[1][0] != '_' && (v = trackdb_get(vec[0], vec[1])))
+ if(!(track = trackdb_resolve(vec[0]))) {
+ sink_writes(ev_writer_sink(c->w), "550 cannot resolve track\n");
+ return 1;
+ }
+ if(vec[1][0] != '_' && (v = trackdb_get(track, vec[1])))
sink_printf(ev_writer_sink(c->w), "252 %s\n", quoteutf8(v));
else
sink_writes(ev_writer_sink(c->w), "555 not found\n");
static int c_set(struct conn *c,
char **vec,
int attribute((unused)) nvec) {
- if(vec[1][0] != '_' && !trackdb_set(vec[0], vec[1], vec[2]))
+ const char *track;
+
+ if(!(track = trackdb_resolve(vec[0]))) {
+ sink_writes(ev_writer_sink(c->w), "550 cannot resolve track\n");
+ return 1;
+ }
+ if(vec[1][0] != '_' && !trackdb_set(track, vec[1], vec[2]))
sink_writes(ev_writer_sink(c->w), "250 OK\n");
else
sink_writes(ev_writer_sink(c->w), "550 not found\n");
char **vec,
int attribute((unused)) nvec) {
struct kvp *k;
+ const char *track;
- k = trackdb_get_all(vec[0]);
+ if(!(track = trackdb_resolve(vec[0]))) {
+ sink_writes(ev_writer_sink(c->w), "550 cannot resolve track\n");
+ return 1;
+ }
+ k = trackdb_get_all(track);
sink_writes(ev_writer_sink(c->w), "253 prefs follow\n");
for(; k; k = k->next)
if(k->name[0] != '_') /* omit internal values */
static int c_exists(struct conn *c,
char **vec,
int attribute((unused)) nvec) {
+ /* trackdb_exists() does its own alias checking */
sink_printf(ev_writer_sink(c->w), "252 %s\n", noyes[trackdb_exists(vec[0])]);
return 1;
}
sink_writes(ev_writer_sink(c->w), "510 Prohibited\n");
return 1;
}
- if(mixer_control(&l, &r, set))
+ if(mixer_control(-1/*as configured*/, &l, &r, set))
sink_writes(ev_writer_sink(c->w), "550 error accessing mixer\n");
else {
sink_printf(ev_writer_sink(c->w), "252 %d %d\n", l, r);
static int c_part(struct conn *c,
char **vec,
int attribute((unused)) nvec) {
+ const char *track;
+
+ if(!(track = trackdb_resolve(vec[0]))) {
+ sink_writes(ev_writer_sink(c->w), "550 cannot resolve track\n");
+ return 1;
+ }
sink_printf(ev_writer_sink(c->w), "252 %s\n",
- quoteutf8(trackdb_getpart(vec[0], vec[1], vec[2])));
+ quoteutf8(trackdb_getpart(track, vec[1], vec[2])));
return 1;
}
int nvec) {
const char *rights;
+ if(!config->remote_userman && !(c->rights & RIGHT__LOCAL)) {
+ error(0, "S%x: remote adduser", c->tag);
+ sink_writes(ev_writer_sink(c->w), "550 Remote user management is disabled\n");
+ return 1;
+ }
if(nvec > 2) {
rights = vec[2];
if(parse_rights(vec[2], 0, 1)) {
int attribute((unused)) nvec) {
struct conn *d;
+ if(!config->remote_userman && !(c->rights & RIGHT__LOCAL)) {
+ error(0, "S%x: remote deluser", c->tag);
+ sink_writes(ev_writer_sink(c->w), "550 Remote user management is disabled\n");
+ return 1;
+ }
if(trackdb_deluser(vec[0])) {
sink_writes(ev_writer_sink(c->w), "550 Cannot delete user\n");
return 1;
int attribute((unused)) nvec) {
struct conn *d;
+ if(!config->remote_userman && !(c->rights & RIGHT__LOCAL)) {
+ error(0, "S%x: remote edituser", c->tag);
+ sink_writes(ev_writer_sink(c->w), "550 Remote user management is disabled\n");
+ return 1;
+ }
/* RIGHT_ADMIN can do anything; otherwise you can only set your own email
* address and password. */
if((c->rights & RIGHT_ADMIN)
/* Update rights for this user */
rights_type r;
- if(parse_rights(vec[1], &r, 1))
+ if(parse_rights(vec[2], &r, 1))
for(d = connections; d; d = d->next)
if(!strcmp(d->who, vec[0]))
d->rights = r;
struct kvp *k;
const char *value;
+ /* We allow remote querying of rights so that clients can figure out what
+ * they're allowed to do */
+ if(!config->remote_userman
+ && !(c->rights & RIGHT__LOCAL)
+ && strcmp(vec[1], "rights")) {
+ error(0, "S%x: remote userinfo %s %s", c->tag, vec[0], vec[1]);
+ sink_writes(ev_writer_sink(c->w), "550 Remote user management is disabled\n");
+ return 1;
+ }
/* RIGHT_ADMIN allows anything; otherwise you can only get your own email
- * address and righst list. */
+ * address and rights list. */
if((c->rights & RIGHT_ADMIN)
|| (!strcmp(c->who, vec[0])
&& (!strcmp(vec[1], "email")