/*
* This file is part of DisOrder.
- * Copyright (C) 2004, 2005, 2006 Richard Kettlewell
+ * Copyright (C) 2004, 2005, 2006, 2007 Richard Kettlewell
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "server.h"
#include "syscalls.h"
#include "queue.h"
+#include "server-queue.h"
#include "play.h"
#include "log.h"
#include "mem.h"
D(("server reader_error %d %d", fd, errno_value));
error(errno, "S%x read error on socket", c->tag);
ev_writer_cancel(c->w);
+ ev_report(ev);
+ info("closing fd %d", fd);
xclose(fd);
return 0;
}
static void post_move_cleanup(void) {
struct queue_entry *q;
- /* If we have caused the random track to not be at the end then we make it no
- * longer be random. */
+ /* 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;
return 1;
}
+static int c_new(struct conn *c,
+ char **vec,
+ int nvec) {
+ char **tracks = trackdb_new(0, nvec > 0 ? atoi(vec[0]) : INT_MAX);
+
+ sink_printf(ev_writer_sink(c->w), "253 New track list follows\n");
+ while(*tracks) {
+ sink_printf(ev_writer_sink(c->w), "%s%s\n",
+ **tracks == '.' ? "." : "", *tracks);
+ ++tracks;
+ }
+ sink_writes(ev_writer_sink(c->w), ".\n");
+ return 1; /* completed */
+
+}
+
+static int c_rtp_address(struct conn *c,
+ char attribute((unused)) **vec,
+ int attribute((unused)) nvec) {
+ if(config->speaker_backend == BACKEND_NETWORK) {
+ sink_printf(ev_writer_sink(c->w), "252 %s %s\n",
+ quoteutf8(config->broadcast.s[0]),
+ quoteutf8(config->broadcast.s[1]));
+ } else
+ sink_writes(ev_writer_sink(c->w), "550 No RTP\n");
+ return 1;
+}
+
#define C_AUTH 0001 /* must be authenticated */
#define C_TRUSTED 0002 /* must be trusted user */
{ "log", 0, 0, c_log, C_AUTH },
{ "move", 2, 2, c_move, C_AUTH },
{ "moveafter", 1, INT_MAX, c_moveafter, C_AUTH },
+ { "new", 0, 1, c_new, C_AUTH },
{ "nop", 0, 0, c_nop, C_AUTH },
{ "part", 3, 3, c_part, C_AUTH },
{ "pause", 0, 0, c_pause, C_AUTH },
{ "rescan", 0, 0, c_rescan, C_AUTH|C_TRUSTED },
{ "resolve", 1, 1, c_resolve, C_AUTH },
{ "resume", 0, 0, c_resume, C_AUTH },
+ { "rtp-address", 0, 0, c_rtp_address, C_AUTH },
{ "scratch", 0, 1, c_scratch, C_AUTH },
{ "search", 1, 1, c_search, C_AUTH },
{ "set", 3, 3, c_set, C_AUTH, },
cloexec(fd);
c->tag = tags++;
c->ev = ev;
- c->w = ev_writer_new(ev, fd, writer_error, c);
- c->r = ev_reader_new(ev, fd, redirect_reader_callback, reader_error, c);
+ c->w = ev_writer_new(ev, fd, writer_error, c,
+ "client writer");
+ c->r = ev_reader_new(ev, fd, redirect_reader_callback, reader_error, c,
+ "client reader");
c->fd = fd;
c->reader = reader_callback;
c->l = l;
cloexec(fd);
l->name = name;
l->pf = pf;
- if(ev_listen(ev, fd, listen_callback, l)) exit(EXIT_FAILURE);
+ if(ev_listen(ev, fd, listen_callback, l, "server listener"))
+ exit(EXIT_FAILURE);
return fd;
}