chiark / gitweb /
server shouldn't crash on client disconnect!
[disorder] / server / server.c
1 /*
2  * This file is part of DisOrder.
3  * Copyright (C) 2004, 2005, 2006, 2007 Richard Kettlewell
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18  * USA
19  */
20
21 #include <config.h>
22 #include "types.h"
23
24 #include <pwd.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <sys/time.h>
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <gcrypt.h>
34 #include <stddef.h>
35 #include <time.h>
36 #include <limits.h>
37 #include <pcre.h>
38 #include <netdb.h>
39 #include <netinet/in.h>
40
41 #include "event.h"
42 #include "server.h"
43 #include "syscalls.h"
44 #include "queue.h"
45 #include "server-queue.h"
46 #include "play.h"
47 #include "log.h"
48 #include "mem.h"
49 #include "state.h"
50 #include "charset.h"
51 #include "split.h"
52 #include "configuration.h"
53 #include "hex.h"
54 #include "trackdb.h"
55 #include "table.h"
56 #include "kvp.h"
57 #include "mixer.h"
58 #include "sink.h"
59 #include "authhash.h"
60 #include "plugin.h"
61 #include "printf.h"
62 #include "trackname.h"
63 #include "eventlog.h"
64 #include "defs.h"
65 #include "cache.h"
66
67 #ifndef NONCE_SIZE
68 # define NONCE_SIZE 16
69 #endif
70
71 int volume_left, volume_right;          /* last known volume */
72
73 /** @brief Accept all well-formed login attempts
74  *
75  * Used in debugging.
76  */
77 int wideopen;
78
79 struct listener {
80   const char *name;
81   int pf;
82 };
83
84 struct conn {
85   ev_reader *r;
86   ev_writer *w;
87   int fd;
88   unsigned tag;
89   char *who;
90   ev_source *ev;
91   unsigned char nonce[NONCE_SIZE];
92   ev_reader_callback *reader;
93   struct eventlog_output *lo;
94   const struct listener *l;
95 };
96
97 static int reader_callback(ev_source *ev,
98                            ev_reader *reader,
99                            void *ptr,
100                            size_t bytes,
101                            int eof,
102                            void *u);
103
104 static const char *noyes[] = { "no", "yes" };
105
106 static int writer_error(ev_source attribute((unused)) *ev,
107                         int errno_value,
108                         void *u) {
109   struct conn *c = u;
110
111   D(("server writer_error %d", errno_value));
112   info("writer_error S%x %d", c->tag, errno_value);
113   if(errno_value == 0) {
114     /* writer is done */
115     error(errno_value, "S%x writer completed", c->tag); /* TODO */
116   } else {
117     if(errno_value != EPIPE)
118       error(errno_value, "S%x write error on socket", c->tag);
119     info("cancel reader");
120     ev_reader_cancel(c->r);
121     info("done cancel reader");
122   }
123   ev_report(ev);
124   return 0;
125 }
126
127 static int reader_error(ev_source attribute((unused)) *ev,
128                         int errno_value,
129                         void *u) {
130   struct conn *c = u;
131
132   D(("server reader_error %d", errno_value));
133   info("reader_error S%x %d", c->tag, errno_value);
134   error(errno_value, "S%x read error on socket", c->tag);
135   ev_writer_close(c->w);
136   ev_report(ev);
137   return 0;
138 }
139
140 /* return true if we are talking to a trusted user */
141 static int trusted(struct conn *c) {
142   int n;
143   
144   for(n = 0; (n < config->trust.n
145               && strcmp(config->trust.s[n], c->who)); ++n)
146     ;
147   return n < config->trust.n;
148 }
149
150 static int c_disable(struct conn *c, char **vec, int nvec) {
151   if(nvec == 0)
152     disable_playing(c->who);
153   else if(nvec == 1 && !strcmp(vec[0], "now"))
154     disable_playing(c->who);
155   else {
156     sink_writes(ev_writer_sink(c->w), "550 invalid argument\n");
157     return 1;                   /* completed */
158   }
159   sink_writes(ev_writer_sink(c->w), "250 OK\n");
160   return 1;                     /* completed */
161 }
162
163 static int c_enable(struct conn *c,
164                     char attribute((unused)) **vec,
165                     int attribute((unused)) nvec) {
166   enable_playing(c->who, c->ev);
167   /* Enable implicitly unpauses if there is nothing playing */
168   if(paused && !playing) resume_playing(c->who);
169   sink_writes(ev_writer_sink(c->w), "250 OK\n");
170   return 1;                     /* completed */
171 }
172
173 static int c_enabled(struct conn *c,
174                      char attribute((unused)) **vec,
175                      int attribute((unused)) nvec) {
176   sink_printf(ev_writer_sink(c->w), "252 %s\n", noyes[playing_is_enabled()]);
177   return 1;                     /* completed */
178 }
179
180 static int c_play(struct conn *c, char **vec,
181                   int attribute((unused)) nvec) {
182   const char *track;
183   struct queue_entry *q;
184   
185   if(!trackdb_exists(vec[0])) {
186     sink_writes(ev_writer_sink(c->w), "550 track is not in database\n");
187     return 1;
188   }
189   if(!(track = trackdb_resolve(vec[0]))) {
190     sink_writes(ev_writer_sink(c->w), "550 cannot resolve track\n");
191     return 1;
192   }
193   q = queue_add(track, c->who, WHERE_BEFORE_RANDOM);
194   queue_write();
195   /* If we added the first track, and something is playing, then prepare the
196    * new track.  If nothing is playing then we don't bother as it wouldn't gain
197    * anything. */
198   if(q == qhead.next && playing)
199     prepare(c->ev, q);
200   sink_writes(ev_writer_sink(c->w), "250 queued\n");
201   /* If the queue was empty but we are for some reason paused then
202    * unpause. */
203   if(!playing) resume_playing(0);
204   play(c->ev);
205   return 1;                     /* completed */
206 }
207
208 static int c_remove(struct conn *c, char **vec,
209                     int attribute((unused)) nvec) {
210   struct queue_entry *q;
211
212   if(!(q = queue_find(vec[0]))) {
213     sink_writes(ev_writer_sink(c->w), "550 no such track on the queue\n");
214     return 1;
215   }
216   if(config->restrictions & RESTRICT_REMOVE) {
217     /* can only remove tracks that you submitted */
218     if(!q->submitter || strcmp(q->submitter, c->who)) {
219       sink_writes(ev_writer_sink(c->w), "550 you didn't submit that track!\n");
220       return 1;
221     }
222   }
223   queue_remove(q, c->who);
224   /* De-prepare the track. */
225   abandon(c->ev, q);
226   /* If we removed the random track then add another one. */
227   if(q->state == playing_random)
228     add_random_track();
229   /* Prepare whatever the next head track is. */
230   if(qhead.next != &qhead)
231     prepare(c->ev, qhead.next);
232   queue_write();
233   sink_writes(ev_writer_sink(c->w), "250 removed\n");
234   return 1;                     /* completed */
235 }
236
237 static int c_scratch(struct conn *c,
238                      char **vec,
239                      int nvec) {
240   if(!playing) {
241     sink_writes(ev_writer_sink(c->w), "250 nothing is playing\n");
242     return 1;                   /* completed */
243   }
244   if(config->restrictions & RESTRICT_SCRATCH) {
245     /* can only scratch tracks you submitted and randomly selected ones */
246     if(playing->submitter && strcmp(playing->submitter, c->who)) {
247       sink_writes(ev_writer_sink(c->w), "550 you didn't submit that track!\n");
248       return 1;
249     }
250   }
251   scratch(c->who, nvec == 1 ? vec[0] : 0);
252   /* If you scratch an unpaused track then it is automatically unpaused */
253   resume_playing(0);
254   sink_writes(ev_writer_sink(c->w), "250 scratched\n");
255   return 1;                     /* completed */
256 }
257
258 static int c_pause(struct conn *c,
259                    char attribute((unused)) **vec,
260                    int attribute((unused)) nvec) {
261   if(!playing) {
262     sink_writes(ev_writer_sink(c->w), "250 nothing is playing\n");
263     return 1;                   /* completed */
264   }
265   if(paused) {
266     sink_writes(ev_writer_sink(c->w), "250 already paused\n");
267     return 1;                   /* completed */
268   }
269   if(pause_playing(c->who) < 0)
270     sink_writes(ev_writer_sink(c->w), "550 cannot pause this track\n");
271   else
272     sink_writes(ev_writer_sink(c->w), "250 paused\n");
273   return 1;
274 }
275
276 static int c_resume(struct conn *c,
277                    char attribute((unused)) **vec,
278                    int attribute((unused)) nvec) {
279   if(!paused) {
280     sink_writes(ev_writer_sink(c->w), "250 not paused\n");
281     return 1;                   /* completed */
282   }
283   resume_playing(c->who);
284   sink_writes(ev_writer_sink(c->w), "250 paused\n");
285   return 1;
286 }
287
288 static int c_shutdown(struct conn *c,
289                       char attribute((unused)) **vec,
290                       int attribute((unused)) nvec) {
291   info("S%x shut down by %s", c->tag, c->who);
292   sink_writes(ev_writer_sink(c->w), "250 shutting down\n");
293   ev_writer_flush(c->w);
294   quit(c->ev);
295 }
296
297 static int c_reconfigure(struct conn *c,
298                          char attribute((unused)) **vec,
299                          int attribute((unused)) nvec) {
300   info("S%x reconfigure by %s", c->tag, c->who);
301   if(reconfigure(c->ev, 1))
302     sink_writes(ev_writer_sink(c->w), "550 error reading new config\n");
303   else
304     sink_writes(ev_writer_sink(c->w), "250 installed new config\n");
305   return 1;                             /* completed */
306 }
307
308 static int c_rescan(struct conn *c,
309                     char attribute((unused)) **vec,
310                     int attribute((unused)) nvec) {
311   info("S%x rescan by %s", c->tag, c->who);
312   trackdb_rescan(c->ev);
313   sink_writes(ev_writer_sink(c->w), "250 initiated rescan\n");
314   return 1;                             /* completed */
315 }
316
317 static int c_version(struct conn *c,
318                      char attribute((unused)) **vec,
319                      int attribute((unused)) nvec) {
320   /* VERSION had better only use the basic character set */
321   sink_printf(ev_writer_sink(c->w), "251 %s\n", disorder_version_string);
322   return 1;                     /* completed */
323 }
324
325 static int c_playing(struct conn *c,
326                      char attribute((unused)) **vec,
327                      int attribute((unused)) nvec) {
328   if(playing) {
329     queue_fix_sofar(playing);
330     playing->expected = 0;
331     sink_printf(ev_writer_sink(c->w), "252 %s\n", queue_marshall(playing));
332   } else
333     sink_printf(ev_writer_sink(c->w), "259 nothing playing\n");
334   return 1;                             /* completed */
335 }
336
337 static int c_become(struct conn *c,
338                   char **vec,
339                   int attribute((unused)) nvec) {
340   c->who = vec[0];
341   sink_writes(ev_writer_sink(c->w), "230 OK\n");
342   return 1;
343 }
344
345 static int c_user(struct conn *c,
346                   char **vec,
347                   int attribute((unused)) nvec) {
348   int n;
349   const char *res;
350   union {
351     struct sockaddr sa;
352     struct sockaddr_in in;
353     struct sockaddr_in6 in6;
354   } u;
355   socklen_t l;
356   char host[1024];
357
358   if(c->who) {
359     sink_writes(ev_writer_sink(c->w), "530 already authenticated\n");
360     return 1;
361   }
362   /* get connection data */
363   l = sizeof u;
364   if(getpeername(c->fd, &u.sa, &l) < 0) {
365     error(errno, "S%x error calling getpeername", c->tag);
366     sink_writes(ev_writer_sink(c->w), "530 authentication failure\n");
367     return 1;
368   }
369   if(c->l->pf != PF_UNIX) {
370     if((n = getnameinfo(&u.sa, l,
371                         host, sizeof host, 0, 0, NI_NUMERICHOST))) {
372       error(0, "S%x error calling getnameinfo: %s", c->tag, gai_strerror(n));
373       sink_writes(ev_writer_sink(c->w), "530 authentication failure\n");
374       return 1;
375     }
376   } else
377     strcpy(host, "local");
378   /* find the user */
379   for(n = 0; n < config->allow.n
380         && strcmp(config->allow.s[n].s[0], vec[0]); ++n)
381     ;
382   /* if it's a real user check whether the response is right */
383   if(n >= config->allow.n) {
384     info("S%x unknown user '%s' from %s", c->tag, vec[0], host);
385     sink_writes(ev_writer_sink(c->w), "530 authentication failed\n");
386     return 1;
387   }
388   res = authhash(c->nonce, sizeof c->nonce, config->allow.s[n].s[1],
389                  config->authorization_algorithm);
390   if(wideopen || (res && !strcmp(res, vec[1]))) {
391     c->who = vec[0];
392     /* currently we only bother logging remote connections */
393     if(c->l->pf != PF_UNIX)
394       info("S%x %s connected from %s", c->tag, vec[0], host);
395     sink_writes(ev_writer_sink(c->w), "230 OK\n");
396     return 1;
397   }
398   /* oops, response was wrong */
399   info("S%x authentication failure for %s from %s", c->tag, vec[0], host);
400   sink_writes(ev_writer_sink(c->w), "530 authentication failed\n");
401   return 1;
402 }
403
404 static int c_recent(struct conn *c,
405                     char attribute((unused)) **vec,
406                     int attribute((unused)) nvec) {
407   const struct queue_entry *q;
408
409   sink_writes(ev_writer_sink(c->w), "253 Tracks follow\n");
410   for(q = phead.next; q != &phead; q = q->next)
411     sink_printf(ev_writer_sink(c->w), " %s\n", queue_marshall(q));
412   sink_writes(ev_writer_sink(c->w), ".\n");
413   return 1;                             /* completed */
414 }
415
416 static int c_queue(struct conn *c,
417                    char attribute((unused)) **vec,
418                    int attribute((unused)) nvec) {
419   struct queue_entry *q;
420   time_t when = 0;
421   const char *l;
422   long length;
423
424   sink_writes(ev_writer_sink(c->w), "253 Tracks follow\n");
425   if(playing_is_enabled() && !paused) {
426     if(playing) {
427       queue_fix_sofar(playing);
428       if((l = trackdb_get(playing->track, "_length"))
429          && (length = atol(l))) {
430         time(&when);
431         when += length - playing->sofar + config->gap;
432       }
433     } else
434       /* Nothing is playing but playing is enabled, so whatever is
435        * first in the queue can be expected to start immediately. */
436       time(&when);
437   }
438   for(q = qhead.next; q != &qhead; q = q->next) {
439     /* fill in estimated start time */
440     q->expected = when;
441     sink_printf(ev_writer_sink(c->w), " %s\n", queue_marshall(q));
442     /* update for next track */
443     if(when) {
444       if((l = trackdb_get(q->track, "_length"))
445          && (length = atol(l)))
446         when += length + config->gap;
447       else
448         when = 0;
449     }
450   }
451   sink_writes(ev_writer_sink(c->w), ".\n");
452   return 1;                             /* completed */
453 }
454
455 static int output_list(struct conn *c, char **vec) {
456   while(*vec)
457     sink_printf(ev_writer_sink(c->w), "%s\n", *vec++);
458   sink_writes(ev_writer_sink(c->w), ".\n");
459   return 1;
460 }
461
462 static int files_dirs(struct conn *c,
463                       char **vec,
464                       int nvec,
465                       enum trackdb_listable what) {
466   const char *dir, *re, *errstr;
467   int erroffset;
468   pcre *rec;
469   char **fvec, *key;
470   
471   switch(nvec) {
472   case 0: dir = 0; re = 0; break;
473   case 1: dir = vec[0]; re = 0; break;
474   case 2: dir = vec[0]; re = vec[1]; break;
475   default: abort();
476   }
477   /* A bit of a bodge to make sure the args don't trample on cache keys */
478   if(dir && strchr(dir, '\n')) {
479     sink_writes(ev_writer_sink(c->w), "550 invalid directory name\n");
480     return 1;
481   }
482   if(re && strchr(re, '\n')) {
483     sink_writes(ev_writer_sink(c->w), "550 invalid regexp\n");
484     return 1;
485   }
486   /* We bother eliminating "" because the web interface is relatively
487    * likely to send it */
488   if(re && *re) {
489     byte_xasprintf(&key, "%d\n%s\n%s", (int)what, dir ? dir : "", re);
490     fvec = (char **)cache_get(&cache_files_type, key);
491     if(fvec) {
492       /* Got a cache hit, don't store the answer in the cache */
493       key = 0;
494       ++cache_files_hits;
495       rec = 0;                          /* quieten compiler */
496     } else {
497       /* Cache miss, we'll do the lookup and key != 0 so we'll store the answer
498        * in the cache. */
499       if(!(rec = pcre_compile(re, PCRE_CASELESS|PCRE_UTF8,
500                               &errstr, &erroffset, 0))) {
501         sink_printf(ev_writer_sink(c->w), "550 Error compiling regexp: %s\n",
502                     errstr);
503         return 1;
504       }
505       /* It only counts as a miss if the regexp was valid. */
506       ++cache_files_misses;
507     }
508   } else {
509     /* No regexp, don't bother caching the result */
510     rec = 0;
511     key = 0;
512     fvec = 0;
513   }
514   if(!fvec) {
515     /* No cache hit (either because a miss, or because we did not look) so do
516      * the lookup */
517     if(dir && *dir)
518       fvec = trackdb_list(dir, 0, what, rec);
519     else
520       fvec = trackdb_list(0, 0, what, rec);
521   }
522   if(key)
523     /* Put the answer in the cache */
524     cache_put(&cache_files_type, key, fvec);
525   sink_writes(ev_writer_sink(c->w), "253 Listing follow\n");
526   return output_list(c, fvec);
527 }
528
529 static int c_files(struct conn *c,
530                   char **vec,
531                   int nvec) {
532   return files_dirs(c, vec, nvec, trackdb_files);
533 }
534
535 static int c_dirs(struct conn *c,
536                   char **vec,
537                   int nvec) {
538   return files_dirs(c, vec, nvec, trackdb_directories);
539 }
540
541 static int c_allfiles(struct conn *c,
542                       char **vec,
543                       int nvec) {
544   return files_dirs(c, vec, nvec, trackdb_directories|trackdb_files);
545 }
546
547 static int c_get(struct conn *c,
548                  char **vec,
549                  int attribute((unused)) nvec) {
550   const char *v;
551
552   if(vec[1][0] != '_' && (v = trackdb_get(vec[0], vec[1])))
553     sink_printf(ev_writer_sink(c->w), "252 %s\n", v);
554   else
555     sink_writes(ev_writer_sink(c->w), "550 not found\n");
556   return 1;
557 }
558
559 static int c_length(struct conn *c,
560                  char **vec,
561                  int attribute((unused)) nvec) {
562   const char *track, *v;
563
564   if(!(track = trackdb_resolve(vec[0]))) {
565     sink_writes(ev_writer_sink(c->w), "550 cannot resolve track\n");
566     return 1;
567   }
568   if((v = trackdb_get(track, "_length")))
569     sink_printf(ev_writer_sink(c->w), "252 %s\n", v);
570   else
571     sink_writes(ev_writer_sink(c->w), "550 not found\n");
572   return 1;
573 }
574
575 static int c_set(struct conn *c,
576                  char **vec,
577                  int attribute((unused)) nvec) {
578   if(vec[1][0] != '_' && !trackdb_set(vec[0], vec[1], vec[2]))
579     sink_writes(ev_writer_sink(c->w), "250 OK\n");
580   else
581     sink_writes(ev_writer_sink(c->w), "550 not found\n");
582   return 1;
583 }
584
585 static int c_prefs(struct conn *c,
586                    char **vec,
587                    int attribute((unused)) nvec) {
588   struct kvp *k;
589
590   k = trackdb_get_all(vec[0]);
591   sink_writes(ev_writer_sink(c->w), "253 prefs follow\n");
592   for(; k; k = k->next)
593     if(k->name[0] != '_')               /* omit internal values */
594       sink_printf(ev_writer_sink(c->w),
595                   " %s %s\n", quoteutf8(k->name), quoteutf8(k->value));
596   sink_writes(ev_writer_sink(c->w), ".\n");
597   return 1;
598 }
599
600 static int c_exists(struct conn *c,
601                     char **vec,
602                     int attribute((unused)) nvec) {
603   sink_printf(ev_writer_sink(c->w), "252 %s\n", noyes[trackdb_exists(vec[0])]);
604   return 1;
605 }
606
607 static void search_parse_error(const char *msg, void *u) {
608   *(const char **)u = msg;
609 }
610
611 static int c_search(struct conn *c,
612                           char **vec,
613                           int attribute((unused)) nvec) {
614   char **terms, **results;
615   int nterms, nresults, n;
616   const char *e = "unknown error";
617
618   /* This is a bit of a bodge.  Initially it's there to make the eclient
619    * interface a bit more convenient to add searching to, but it has the more
620    * compelling advantage that if everything uses it, then interpretation of
621    * user-supplied search strings will be the same everywhere. */
622   if(!(terms = split(vec[0], &nterms, SPLIT_QUOTES, search_parse_error, &e))) {
623     sink_printf(ev_writer_sink(c->w), "550 %s\n", e);
624   } else {
625     results = trackdb_search(terms, nterms, &nresults);
626     sink_printf(ev_writer_sink(c->w), "253 %d matches\n", nresults);
627     for(n = 0; n < nresults; ++n)
628       sink_printf(ev_writer_sink(c->w), "%s\n", results[n]);
629     sink_writes(ev_writer_sink(c->w), ".\n");
630   }
631   return 1;
632 }
633
634 static int c_random_enable(struct conn *c,
635                            char attribute((unused)) **vec,
636                            int attribute((unused)) nvec) {
637   enable_random(c->who, c->ev);
638   /* Enable implicitly unpauses if there is nothing playing */
639   if(paused && !playing) resume_playing(c->who);
640   sink_writes(ev_writer_sink(c->w), "250 OK\n");
641   return 1;                     /* completed */
642 }
643
644 static int c_random_disable(struct conn *c,
645                             char attribute((unused)) **vec,
646                             int attribute((unused)) nvec) {
647   disable_random(c->who);
648   sink_writes(ev_writer_sink(c->w), "250 OK\n");
649   return 1;                     /* completed */
650 }
651
652 static int c_random_enabled(struct conn *c,
653                             char attribute((unused)) **vec,
654                             int attribute((unused)) nvec) {
655   sink_printf(ev_writer_sink(c->w), "252 %s\n", noyes[random_is_enabled()]);
656   return 1;                     /* completed */
657 }
658
659 static void got_stats(char *stats, void *u) {
660   struct conn *const c = u;
661
662   sink_printf(ev_writer_sink(c->w), "253 stats\n%s\n.\n", stats);
663   /* Now we can start processing commands again */
664   ev_reader_enable(c->r);
665 }
666
667 static int c_stats(struct conn *c,
668                    char attribute((unused)) **vec,
669                    int attribute((unused)) nvec) {
670   trackdb_stats_subprocess(c->ev, got_stats, c);
671   return 0;                             /* not yet complete */
672 }
673
674 static int c_volume(struct conn *c,
675                     char **vec,
676                     int nvec) {
677   int l, r, set;
678   char lb[32], rb[32];
679
680   switch(nvec) {
681   case 0:
682     set = 0;
683     break;
684   case 1:
685     l = r = atoi(vec[0]);
686     set = 1;
687     break;
688   case 2:
689     l = atoi(vec[0]);
690     r = atoi(vec[1]);
691     set = 1;
692     break;
693   default:
694     abort();
695   }
696   if(mixer_control(&l, &r, set))
697     sink_writes(ev_writer_sink(c->w), "550 error accessing mixer\n");
698   else {
699     sink_printf(ev_writer_sink(c->w), "252 %d %d\n", l, r);
700     if(l != volume_left || r != volume_right) {
701       volume_left = l;
702       volume_right = r;
703       snprintf(lb, sizeof lb, "%d", l);
704       snprintf(rb, sizeof rb, "%d", r);
705       eventlog("volume", lb, rb, (char *)0);
706     }
707   }
708   return 1;
709 }
710
711 /* we are logging, and some data is available to read */
712 static int logging_reader_callback(ev_source *ev,
713                                    ev_reader *reader,
714                                    void *ptr,
715                                    size_t bytes,
716                                    int eof,
717                                    void *u) {
718   struct conn *c = u;
719
720   /* don't log to this conn any more */
721   eventlog_remove(c->lo);
722   if(c->w) {
723     /* Terminate the log output, but only if the writer hasn't been killed off
724      * from a failure on some earlier write */
725     sink_writes(ev_writer_sink(c->w), ".\n");
726   }
727   /* restore the reader callback */
728   c->reader = reader_callback;
729   /* ...and exit via it */
730   return c->reader(ev, reader, ptr, bytes, eof, u);
731 }
732
733 static void logclient(const char *msg, void *user) {
734   struct conn *c = user;
735
736   if(!c->w || !c->r) {
737     /* This connection has gone up in smoke for some reason */
738     eventlog_remove(c->lo);
739     return;
740   }
741   sink_printf(ev_writer_sink(c->w), "%"PRIxMAX" %s\n",
742               (uintmax_t)time(0), msg);
743 }
744
745 static int c_log(struct conn *c,
746                  char attribute((unused)) **vec,
747                  int attribute((unused)) nvec) {
748   time_t now;
749
750   sink_writes(ev_writer_sink(c->w), "254 OK\n");
751   /* pump out initial state */
752   time(&now);
753   sink_printf(ev_writer_sink(c->w), "%"PRIxMAX" state %s\n",
754               (uintmax_t)now, 
755               playing_is_enabled() ? "enable_play" : "disable_play");
756   sink_printf(ev_writer_sink(c->w), "%"PRIxMAX" state %s\n",
757               (uintmax_t)now, 
758               random_is_enabled() ? "enable_random" : "disable_random");
759   sink_printf(ev_writer_sink(c->w), "%"PRIxMAX" state %s\n",
760               (uintmax_t)now, 
761               paused ? "pause" : "resume");
762   if(playing)
763     sink_printf(ev_writer_sink(c->w), "%"PRIxMAX" state playing\n",
764                 (uintmax_t)now);
765   /* Initial volume */
766   sink_printf(ev_writer_sink(c->w), "%"PRIxMAX" volume %d %d\n",
767               (uintmax_t)now, volume_left, volume_right);
768   c->lo = xmalloc(sizeof *c->lo);
769   c->lo->fn = logclient;
770   c->lo->user = c;
771   eventlog_add(c->lo);
772   c->reader = logging_reader_callback;
773   return 0;
774 }
775
776 static void post_move_cleanup(void) {
777   struct queue_entry *q;
778
779   /* If we have caused any random tracks to not be at the end then we make them
780    * no longer be random. */
781   for(q = qhead.next; q != &qhead; q = q->next)
782     if(q->state == playing_random && q->next != &qhead)
783       q->state = playing_unplayed;
784   /* That might mean we need to add a new random track. */
785   add_random_track();
786   queue_write();
787 }
788
789 static int c_move(struct conn *c,
790                   char **vec,
791                   int attribute((unused)) nvec) {
792   struct queue_entry *q;
793   int n;
794
795   if(config->restrictions & RESTRICT_MOVE) {
796     if(!trusted(c)) {
797       sink_writes(ev_writer_sink(c->w),
798                   "550 only trusted users can move tracks\n");
799       return 1;
800     }
801   }
802   if(!(q = queue_find(vec[0]))) {
803     sink_writes(ev_writer_sink(c->w), "550 no such track on the queue\n");
804     return 1;
805   }
806   n = queue_move(q, atoi(vec[1]), c->who);
807   post_move_cleanup();
808   sink_printf(ev_writer_sink(c->w), "252 %d\n", n);
809   /* If we've moved to the head of the queue then prepare the track. */
810   if(q == qhead.next)
811     prepare(c->ev, q);
812   return 1;
813 }
814
815 static int c_moveafter(struct conn *c,
816                        char **vec,
817                        int attribute((unused)) nvec) {
818   struct queue_entry *q, **qs;
819   int n;
820
821   if(config->restrictions & RESTRICT_MOVE) {
822     if(!trusted(c)) {
823       sink_writes(ev_writer_sink(c->w),
824                   "550 only trusted users can move tracks\n");
825       return 1;
826     }
827   }
828   if(vec[0][0]) {
829     if(!(q = queue_find(vec[0]))) {
830       sink_writes(ev_writer_sink(c->w), "550 no such track on the queue\n");
831       return 1;
832     }
833   } else
834     q = 0;
835   ++vec;
836   --nvec;
837   qs = xcalloc(nvec, sizeof *qs);
838   for(n = 0; n < nvec; ++n)
839     if(!(qs[n] = queue_find(vec[n]))) {
840       sink_writes(ev_writer_sink(c->w), "550 no such track on the queue\n");
841       return 1;
842     }
843   queue_moveafter(q, nvec, qs, c->who);
844   post_move_cleanup();
845   sink_printf(ev_writer_sink(c->w), "250 Moved tracks\n");
846   /* If we've moved to the head of the queue then prepare the track. */
847   if(q == qhead.next)
848     prepare(c->ev, q);
849   return 1;
850 }
851
852 static int c_part(struct conn *c,
853                   char **vec,
854                   int attribute((unused)) nvec) {
855   sink_printf(ev_writer_sink(c->w), "252 %s\n",
856               trackdb_getpart(vec[0], vec[1], vec[2]));
857   return 1;
858 }
859
860 static int c_resolve(struct conn *c,
861                      char **vec,
862                      int attribute((unused)) nvec) {
863   const char *track;
864
865   if(!(track = trackdb_resolve(vec[0]))) {
866     sink_writes(ev_writer_sink(c->w), "550 cannot resolve track\n");
867     return 1;
868   }
869   sink_printf(ev_writer_sink(c->w), "252 %s\n", track);
870   return 1;
871 }
872
873 static int c_tags(struct conn *c,
874                   char attribute((unused)) **vec,
875                   int attribute((unused)) nvec) {
876   char **tags = trackdb_alltags();
877   
878   sink_printf(ev_writer_sink(c->w), "253 Tag list follows\n");
879   while(*tags) {
880     sink_printf(ev_writer_sink(c->w), "%s%s\n",
881                 **tags == '.' ? "." : "", *tags);
882     ++tags;
883   }
884   sink_writes(ev_writer_sink(c->w), ".\n");
885   return 1;                             /* completed */
886
887 }
888
889 static int c_set_global(struct conn *c,
890                         char **vec,
891                         int attribute((unused)) nvec) {
892   trackdb_set_global(vec[0], vec[1], c->who);
893   sink_printf(ev_writer_sink(c->w), "250 OK\n");
894   return 1;
895 }
896
897 static int c_get_global(struct conn *c,
898                         char **vec,
899                         int attribute((unused)) nvec) {
900   const char *s = trackdb_get_global(vec[0]);
901
902   if(s)
903     sink_printf(ev_writer_sink(c->w), "252 %s\n", s);
904   else
905     sink_writes(ev_writer_sink(c->w), "550 not found\n");
906   return 1;
907 }
908
909 static int c_nop(struct conn *c,
910                  char attribute((unused)) **vec,
911                  int attribute((unused)) nvec) {
912   sink_printf(ev_writer_sink(c->w), "250 Quack\n");
913   return 1;
914 }
915
916 static int c_new(struct conn *c,
917                  char **vec,
918                  int nvec) {
919   char **tracks = trackdb_new(0, nvec > 0 ? atoi(vec[0]) : INT_MAX);
920
921   sink_printf(ev_writer_sink(c->w), "253 New track list follows\n");
922   while(*tracks) {
923     sink_printf(ev_writer_sink(c->w), "%s%s\n",
924                 **tracks == '.' ? "." : "", *tracks);
925     ++tracks;
926   }
927   sink_writes(ev_writer_sink(c->w), ".\n");
928   return 1;                             /* completed */
929
930 }
931
932 static int c_rtp_address(struct conn *c,
933                          char attribute((unused)) **vec,
934                          int attribute((unused)) nvec) {
935   if(config->speaker_backend == BACKEND_NETWORK) {
936     sink_printf(ev_writer_sink(c->w), "252 %s %s\n",
937                 quoteutf8(config->broadcast.s[0]),
938                 quoteutf8(config->broadcast.s[1]));
939   } else
940     sink_writes(ev_writer_sink(c->w), "550 No RTP\n");
941   return 1;
942 }
943  
944 #define C_AUTH          0001            /* must be authenticated */
945 #define C_TRUSTED       0002            /* must be trusted user */
946
947 static const struct command {
948   const char *name;
949   int minargs, maxargs;
950   int (*fn)(struct conn *, char **, int);
951   unsigned flags;
952 } commands[] = {
953   { "allfiles",       0, 2,       c_allfiles,       C_AUTH },
954   { "become",         1, 1,       c_become,         C_AUTH|C_TRUSTED },
955   { "dirs",           0, 2,       c_dirs,           C_AUTH },
956   { "disable",        0, 1,       c_disable,        C_AUTH },
957   { "enable",         0, 0,       c_enable,         C_AUTH },
958   { "enabled",        0, 0,       c_enabled,        C_AUTH },
959   { "exists",         1, 1,       c_exists,         C_AUTH },
960   { "files",          0, 2,       c_files,          C_AUTH },
961   { "get",            2, 2,       c_get,            C_AUTH },
962   { "get-global",     1, 1,       c_get_global,     C_AUTH },
963   { "length",         1, 1,       c_length,         C_AUTH },
964   { "log",            0, 0,       c_log,            C_AUTH },
965   { "move",           2, 2,       c_move,           C_AUTH },
966   { "moveafter",      1, INT_MAX, c_moveafter,      C_AUTH },
967   { "new",            0, 1,       c_new,            C_AUTH },
968   { "nop",            0, 0,       c_nop,            C_AUTH },
969   { "part",           3, 3,       c_part,           C_AUTH },
970   { "pause",          0, 0,       c_pause,          C_AUTH },
971   { "play",           1, 1,       c_play,           C_AUTH },
972   { "playing",        0, 0,       c_playing,        C_AUTH },
973   { "prefs",          1, 1,       c_prefs,          C_AUTH },
974   { "queue",          0, 0,       c_queue,          C_AUTH },
975   { "random-disable", 0, 0,       c_random_disable, C_AUTH },
976   { "random-enable",  0, 0,       c_random_enable,  C_AUTH },
977   { "random-enabled", 0, 0,       c_random_enabled, C_AUTH },
978   { "recent",         0, 0,       c_recent,         C_AUTH },
979   { "reconfigure",    0, 0,       c_reconfigure,    C_AUTH|C_TRUSTED },
980   { "remove",         1, 1,       c_remove,         C_AUTH },
981   { "rescan",         0, 0,       c_rescan,         C_AUTH|C_TRUSTED },
982   { "resolve",        1, 1,       c_resolve,        C_AUTH },
983   { "resume",         0, 0,       c_resume,         C_AUTH },
984   { "rtp-address",    0, 0,       c_rtp_address,    C_AUTH },
985   { "scratch",        0, 1,       c_scratch,        C_AUTH },
986   { "search",         1, 1,       c_search,         C_AUTH },
987   { "set",            3, 3,       c_set,            C_AUTH, },
988   { "set-global",     2, 2,       c_set_global,     C_AUTH },
989   { "shutdown",       0, 0,       c_shutdown,       C_AUTH|C_TRUSTED },
990   { "stats",          0, 0,       c_stats,          C_AUTH },
991   { "tags",           0, 0,       c_tags,           C_AUTH },
992   { "unset",          2, 2,       c_set,            C_AUTH },
993   { "unset-global",   1, 1,       c_set_global,      C_AUTH },
994   { "user",           2, 2,       c_user,           0 },
995   { "version",        0, 0,       c_version,        C_AUTH },
996   { "volume",         0, 2,       c_volume,         C_AUTH }
997 };
998
999 static void command_error(const char *msg, void *u) {
1000   struct conn *c = u;
1001
1002   sink_printf(ev_writer_sink(c->w), "500 parse error: %s\n", msg);
1003 }
1004
1005 /* process a command.  Return 1 if complete, 0 if incomplete. */
1006 static int command(struct conn *c, char *line) {
1007   char **vec;
1008   int nvec, n;
1009
1010   D(("server command %s", line));
1011   if(!(vec = split(line, &nvec, SPLIT_QUOTES, command_error, c))) {
1012     sink_writes(ev_writer_sink(c->w), "500 cannot parse command\n");
1013     return 1;
1014   }
1015   if(nvec == 0) {
1016     sink_writes(ev_writer_sink(c->w), "500 do what?\n");
1017     return 1;
1018   }
1019   if((n = TABLE_FIND(commands, struct command, name, vec[0])) < 0)
1020     sink_writes(ev_writer_sink(c->w), "500 unknown command\n");
1021   else {
1022     if((commands[n].flags & C_AUTH) && !c->who) {
1023       sink_writes(ev_writer_sink(c->w), "530 not authenticated\n");
1024       return 1;
1025     }
1026     if((commands[n].flags & C_TRUSTED) && !trusted(c)) {
1027       sink_writes(ev_writer_sink(c->w), "530 insufficient privilege\n");
1028       return 1;
1029     }
1030     ++vec;
1031     --nvec;
1032     if(nvec < commands[n].minargs) {
1033       sink_writes(ev_writer_sink(c->w), "500 missing argument(s)\n");
1034       return 1;
1035     }
1036     if(nvec > commands[n].maxargs) {
1037       sink_writes(ev_writer_sink(c->w), "500 too many arguments\n");
1038       return 1;
1039     }
1040     return commands[n].fn(c, vec, nvec);
1041   }
1042   return 1;                     /* completed */
1043 }
1044
1045 /* redirect to the right reader callback for our current state */
1046 static int redirect_reader_callback(ev_source *ev,
1047                                     ev_reader *reader,
1048                                     void *ptr,
1049                                     size_t bytes,
1050                                     int eof,
1051                                     void *u) {
1052   struct conn *c = u;
1053
1054   return c->reader(ev, reader, ptr, bytes, eof, u);
1055 }
1056
1057 /* the main command reader */
1058 static int reader_callback(ev_source attribute((unused)) *ev,
1059                            ev_reader *reader,
1060                            void *ptr,
1061                            size_t bytes,
1062                            int eof,
1063                            void *u) {
1064   struct conn *c = u;
1065   char *eol;
1066   int complete;
1067
1068   D(("server reader_callback"));
1069   while((eol = memchr(ptr, '\n', bytes))) {
1070     *eol++ = 0;
1071     ev_reader_consume(reader, eol - (char *)ptr);
1072     complete = command(c, ptr);
1073     bytes -= (eol - (char *)ptr);
1074     ptr = eol;
1075     if(!complete) {
1076       /* the command had better have set a new reader callback */
1077       if(bytes || eof)
1078         /* there are further bytes to read, or we are at eof; arrange for the
1079          * command's reader callback to handle them */
1080         return ev_reader_incomplete(reader);
1081       /* nothing's going on right now */
1082       return 0;
1083     }
1084     /* command completed, we can go around and handle the next one */
1085   }
1086   if(eof) {
1087     if(bytes)
1088       error(0, "S%x unterminated line", c->tag);
1089     return ev_writer_close(c->w);
1090   }
1091   return 0;
1092 }
1093
1094 static int listen_callback(ev_source *ev,
1095                            int fd,
1096                            const struct sockaddr attribute((unused)) *remote,
1097                            socklen_t attribute((unused)) rlen,
1098                            void *u) {
1099   const struct listener *l = u;
1100   struct conn *c = xmalloc(sizeof *c);
1101   static unsigned tags;
1102
1103   D(("server listen_callback fd %d (%s)", fd, l->name));
1104   nonblock(fd);
1105   cloexec(fd);
1106   c->tag = tags++;
1107   c->ev = ev;
1108   c->w = ev_writer_new(ev, fd, writer_error, c,
1109                        "client writer");
1110   c->r = ev_reader_new(ev, fd, redirect_reader_callback, reader_error, c,
1111                        "client reader");
1112   ev_tie(c->r, c->w);
1113   c->fd = fd;
1114   c->reader = reader_callback;
1115   c->l = l;
1116   gcry_randomize(c->nonce, sizeof c->nonce, GCRY_STRONG_RANDOM);
1117   if(!strcmp(config->authorization_algorithm, "sha1")
1118      || !strcmp(config->authorization_algorithm, "SHA1")) {
1119     sink_printf(ev_writer_sink(c->w), "231 %s\n",
1120                 hex(c->nonce, sizeof c->nonce));
1121   } else {
1122     sink_printf(ev_writer_sink(c->w), "231 %s %s\n",
1123                 config->authorization_algorithm,
1124                 hex(c->nonce, sizeof c->nonce));
1125   }
1126   return 0;
1127 }
1128
1129 int server_start(ev_source *ev, int pf,
1130                  size_t socklen, const struct sockaddr *sa,
1131                  const char *name) {
1132   int fd;
1133   struct listener *l = xmalloc(sizeof *l);
1134   static const int one = 1;
1135
1136   D(("server_init socket %s", name));
1137   fd = xsocket(pf, SOCK_STREAM, 0);
1138   xsetsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
1139   if(bind(fd, sa, socklen) < 0) {
1140     error(errno, "error binding to %s", name);
1141     return -1;
1142   }
1143   xlisten(fd, 128);
1144   nonblock(fd);
1145   cloexec(fd);
1146   l->name = name;
1147   l->pf = pf;
1148   if(ev_listen(ev, fd, listen_callback, l, "server listener"))
1149     exit(EXIT_FAILURE);
1150   return fd;
1151 }
1152
1153 int server_stop(ev_source *ev, int fd) {
1154   xclose(fd);
1155   return ev_listen_cancel(ev, fd);
1156 }
1157
1158 /*
1159 Local Variables:
1160 c-basic-offset:2
1161 comment-column:40
1162 fill-column:79
1163 End:
1164 */