#include "eventlog.h"
#include "defs.h"
#include "cache.h"
+#include "unicode.h"
#ifndef NONCE_SIZE
# define NONCE_SIZE 16
void *u) {
struct conn *c = u;
- D(("server writer_error %d", errno_value));
- info("writer_error S%x %d", c->tag, errno_value);
+ D(("server writer_error S%x %d", c->tag, errno_value));
if(errno_value == 0) {
/* writer is done */
- error(errno_value, "S%x writer completed", c->tag); /* TODO */
+ D(("S%x writer completed", c->tag));
} else {
if(errno_value != EPIPE)
error(errno_value, "S%x write error on socket", c->tag);
if(c->r) {
- info("cancel reader");
+ D(("cancel reader"));
ev_reader_cancel(c->r);
c->r = 0;
}
- info("done cancel reader");
+ D(("done cancel reader"));
}
c->w = 0;
ev_report(ev);
void *u) {
struct conn *c = u;
- D(("server reader_error %d", errno_value));
- info("reader_error S%x %d", c->tag, errno_value);
+ D(("server reader_error S%x %d", c->tag, errno_value));
error(errno_value, "S%x read error on socket", c->tag);
if(c->w)
ev_writer_close(c->w);
* anything. */
if(q == qhead.next && playing)
prepare(c->ev, q);
- sink_writes(ev_writer_sink(c->w), "250 queued\n");
+ sink_printf(ev_writer_sink(c->w), "252 %s\n", q->id);
/* If the queue was empty but we are for some reason paused then
* unpause. */
if(!playing) resume_playing(0);
if(vec[1][0] != '_' && (v = trackdb_get(vec[0], vec[1])))
sink_printf(ev_writer_sink(c->w), "252 %s\n", v);
else
- sink_writes(ev_writer_sink(c->w), "550 not found\n");
+ sink_writes(ev_writer_sink(c->w), "555 not found\n");
return 1;
}
ev_reader_consume(reader, bytes);
if(eof) {
/* Oops, that's all for now */
- info("logging reader eof");
+ D(("logging reader eof"));
if(c->w) {
- info("close writer");
+ D(("close writer"));
ev_writer_close(c->w);
c->w = 0;
}
return 0;
}
-static void post_move_cleanup(void) {
- struct queue_entry *q;
-
- /* If we have caused any random tracks to not be at the end then we make them
- * no longer be random. */
- for(q = qhead.next; q != &qhead; q = q->next)
- if(q->state == playing_random && q->next != &qhead)
- q->state = playing_unplayed;
- /* That might mean we need to add a new random track. */
- add_random_track();
- queue_write();
-}
-
static int c_move(struct conn *c,
char **vec,
int attribute((unused)) nvec) {
return 1;
}
n = queue_move(q, atoi(vec[1]), c->who);
- post_move_cleanup();
sink_printf(ev_writer_sink(c->w), "252 %d\n", n);
/* If we've moved to the head of the queue then prepare the track. */
if(q == qhead.next)
return 1;
}
queue_moveafter(q, nvec, qs, c->who);
- post_move_cleanup();
sink_printf(ev_writer_sink(c->w), "250 Moved tracks\n");
/* If we've moved to the head of the queue then prepare the track. */
if(q == qhead.next)
static int c_set_global(struct conn *c,
char **vec,
int attribute((unused)) nvec) {
+ if(vec[0][0] == '_') {
+ sink_writes(ev_writer_sink(c->w), "550 cannot set internal global preferences\n");
+ return 1;
+ }
trackdb_set_global(vec[0], vec[1], c->who);
sink_printf(ev_writer_sink(c->w), "250 OK\n");
return 1;
if(s)
sink_printf(ev_writer_sink(c->w), "252 %s\n", s);
else
- sink_writes(ev_writer_sink(c->w), "550 not found\n");
+ sink_writes(ev_writer_sink(c->w), "555 not found\n");
return 1;
}
int nvec, n;
D(("server command %s", line));
+ /* We force everything into NFC as early as possible */
+ if(!(line = utf8_compose_canon(line, strlen(line), 0))) {
+ sink_writes(ev_writer_sink(c->w), "500 cannot normalize command\n");
+ return 1;
+ }
if(!(vec = split(line, &nvec, SPLIT_QUOTES, command_error, c))) {
sink_writes(ev_writer_sink(c->w), "500 cannot parse command\n");
return 1;
if(eof) {
if(bytes)
error(0, "S%x unterminated line", c->tag);
- info("normal reader close");
+ D(("normal reader close"));
c->r = 0;
if(c->w) {
- info("close associated writer");
+ D(("close associated writer"));
ev_writer_close(c->w);
c->w = 0;
}