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