chiark / gitweb /
Implement most of the playlist commands in the server. playlist-set
[disorder] / server / server.c
1 /*
2  * This file is part of DisOrder.
3  * Copyright (C) 2004-2008 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 "disorder-server.h"
22
23 #ifndef NONCE_SIZE
24 # define NONCE_SIZE 16
25 #endif
26
27 #ifndef CONFIRM_SIZE
28 # define CONFIRM_SIZE 10
29 #endif
30
31 int volume_left, volume_right;          /* last known volume */
32
33 /** @brief Accept all well-formed login attempts
34  *
35  * Used in debugging.
36  */
37 int wideopen;
38
39 struct listener {
40   const char *name;
41   int pf;
42 };
43
44 /** @brief One client connection */
45 struct conn {
46   /** @brief Read commands from here */
47   ev_reader *r;
48   /** @brief Send responses to here */
49   ev_writer *w;
50   /** @brief Underlying file descriptor */
51   int fd;
52   /** @brief Unique identifier for connection used in log messages */
53   unsigned tag;
54   /** @brief Login name or NULL */
55   char *who;
56   /** @brief Event loop */
57   ev_source *ev;
58   /** @brief Nonce chosen for this connection */
59   unsigned char nonce[NONCE_SIZE];
60   /** @brief Current reader callback
61    *
62    * We change this depending on whether we're servicing the @b log command
63    */
64   ev_reader_callback *reader;
65   /** @brief Event log output sending to this connection */
66   struct eventlog_output *lo;
67   /** @brief Parent listener */
68   const struct listener *l;
69   /** @brief Login cookie or NULL */
70   char *cookie;
71   /** @brief Connection rights */
72   rights_type rights;
73   /** @brief Next connection */
74   struct conn *next;
75   /** @brief True if pending rescan had 'wait' set */
76   int rescan_wait;
77   /** @brief Playlist that this connection locks */
78   const char *locked_playlist;
79   /** @brief When that playlist was locked */
80   time_t locked_when;
81 };
82
83 /** @brief Linked list of connections */
84 static struct conn *connections;
85
86 static int reader_callback(ev_source *ev,
87                            ev_reader *reader,
88                            void *ptr,
89                            size_t bytes,
90                            int eof,
91                            void *u);
92
93 static const char *noyes[] = { "no", "yes" };
94
95 /** @brief Remove a connection from the connection list */
96 static void remove_connection(struct conn *c) {
97   struct conn **cc;
98
99   for(cc = &connections; *cc && *cc != c; cc = &(*cc)->next)
100     ;
101   if(*cc)
102     *cc = c->next;
103 }
104
105 /** @brief Called when a connection's writer fails or is shut down
106  *
107  * If the connection still has a raeder that is cancelled.
108  */
109 static int writer_error(ev_source attribute((unused)) *ev,
110                         int errno_value,
111                         void *u) {
112   struct conn *c = u;
113
114   D(("server writer_error S%x %d", c->tag, errno_value));
115   if(errno_value == 0) {
116     /* writer is done */
117     D(("S%x writer completed", c->tag));
118   } else {
119     if(errno_value != EPIPE)
120       error(errno_value, "S%x write error on socket", c->tag);
121     if(c->r) {
122       D(("cancel reader"));
123       ev_reader_cancel(c->r);
124       c->r = 0;
125     }
126     D(("done cancel reader"));
127   }
128   c->w = 0;
129   ev_report(ev);
130   remove_connection(c);
131   return 0;
132 }
133
134 /** @brief Called when a conncetion's reader fails or is shut down
135  *
136  * If connection still has a writer then it is closed.
137  */
138 static int reader_error(ev_source attribute((unused)) *ev,
139                         int errno_value,
140                         void *u) {
141   struct conn *c = u;
142
143   D(("server reader_error S%x %d", c->tag, errno_value));
144   error(errno_value, "S%x read error on socket", c->tag);
145   if(c->w)
146     ev_writer_close(c->w);
147   c->w = 0;
148   c->r = 0;
149   ev_report(ev);
150   remove_connection(c);
151   return 0;
152 }
153
154 static int c_disable(struct conn *c, char **vec, int nvec) {
155   if(nvec == 0)
156     disable_playing(c->who);
157   else if(nvec == 1 && !strcmp(vec[0], "now"))
158     disable_playing(c->who);
159   else {
160     sink_writes(ev_writer_sink(c->w), "550 invalid argument\n");
161     return 1;                   /* completed */
162   }
163   sink_writes(ev_writer_sink(c->w), "250 OK\n");
164   return 1;                     /* completed */
165 }
166
167 static int c_enable(struct conn *c,
168                     char attribute((unused)) **vec,
169                     int attribute((unused)) nvec) {
170   enable_playing(c->who, c->ev);
171   /* Enable implicitly unpauses if there is nothing playing */
172   if(paused && !playing) resume_playing(c->who);
173   sink_writes(ev_writer_sink(c->w), "250 OK\n");
174   return 1;                     /* completed */
175 }
176
177 static int c_enabled(struct conn *c,
178                      char attribute((unused)) **vec,
179                      int attribute((unused)) nvec) {
180   sink_printf(ev_writer_sink(c->w), "252 %s\n", noyes[playing_is_enabled()]);
181   return 1;                     /* completed */
182 }
183
184 static int c_play(struct conn *c, char **vec,
185                   int attribute((unused)) nvec) {
186   const char *track;
187   struct queue_entry *q;
188   
189   if(!trackdb_exists(vec[0])) {
190     sink_writes(ev_writer_sink(c->w), "550 track is not in database\n");
191     return 1;
192   }
193   if(!(track = trackdb_resolve(vec[0]))) {
194     sink_writes(ev_writer_sink(c->w), "550 cannot resolve track\n");
195     return 1;
196   }
197   q = queue_add(track, c->who, WHERE_BEFORE_RANDOM);
198   queue_write();
199   /* If we added the first track, and something is playing, then prepare the
200    * new track.  If nothing is playing then we don't bother as it wouldn't gain
201    * anything. */
202   if(q == qhead.next && playing)
203     prepare(c->ev, q);
204   sink_printf(ev_writer_sink(c->w), "252 %s\n", q->id);
205   /* If the queue was empty but we are for some reason paused then
206    * unpause. */
207   if(!playing) resume_playing(0);
208   play(c->ev);
209   return 1;                     /* completed */
210 }
211
212 static int c_remove(struct conn *c, char **vec,
213                     int attribute((unused)) nvec) {
214   struct queue_entry *q;
215
216   if(!(q = queue_find(vec[0]))) {
217     sink_writes(ev_writer_sink(c->w), "550 no such track on the queue\n");
218     return 1;
219   }
220   if(!right_removable(c->rights, c->who, q)) {
221     error(0, "%s attempted remove but lacks required rights", c->who);
222     sink_writes(ev_writer_sink(c->w),
223                 "510 Not authorized to remove that track\n");
224     return 1;
225   }
226   queue_remove(q, c->who);
227   /* De-prepare the track. */
228   abandon(c->ev, q);
229   /* See about adding a new random track */
230   add_random_track(c->ev);
231   /* Prepare whatever the next head track is. */
232   if(qhead.next != &qhead)
233     prepare(c->ev, qhead.next);
234   queue_write();
235   sink_writes(ev_writer_sink(c->w), "250 removed\n");
236   return 1;                     /* completed */
237 }
238
239 static int c_scratch(struct conn *c,
240                      char **vec,
241                      int nvec) {
242   if(!playing) {
243     sink_writes(ev_writer_sink(c->w), "250 nothing is playing\n");
244     return 1;                   /* completed */
245   }
246   /* TODO there is a bug here: if we specify an ID but it's not the currently
247    * playing track then you will get 550 if you weren't authorized to scratch
248    * the currently playing track. */
249   if(!right_scratchable(c->rights, c->who, playing)) {
250     error(0, "%s attempted scratch but lacks required rights", c->who);
251     sink_writes(ev_writer_sink(c->w),
252                 "510 Not authorized to scratch that track\n");
253     return 1;
254   }
255   scratch(c->who, nvec == 1 ? vec[0] : 0);
256   /* If you scratch an unpaused track then it is automatically unpaused */
257   resume_playing(0);
258   sink_writes(ev_writer_sink(c->w), "250 scratched\n");
259   return 1;                     /* completed */
260 }
261
262 static int c_pause(struct conn *c,
263                    char attribute((unused)) **vec,
264                    int attribute((unused)) nvec) {
265   if(!playing) {
266     sink_writes(ev_writer_sink(c->w), "250 nothing is playing\n");
267     return 1;                   /* completed */
268   }
269   if(paused) {
270     sink_writes(ev_writer_sink(c->w), "250 already paused\n");
271     return 1;                   /* completed */
272   }
273   if(pause_playing(c->who) < 0)
274     sink_writes(ev_writer_sink(c->w), "550 cannot pause this track\n");
275   else
276     sink_writes(ev_writer_sink(c->w), "250 paused\n");
277   return 1;
278 }
279
280 static int c_resume(struct conn *c,
281                    char attribute((unused)) **vec,
282                    int attribute((unused)) nvec) {
283   if(!paused) {
284     sink_writes(ev_writer_sink(c->w), "250 not paused\n");
285     return 1;                   /* completed */
286   }
287   resume_playing(c->who);
288   sink_writes(ev_writer_sink(c->w), "250 paused\n");
289   return 1;
290 }
291
292 static int c_shutdown(struct conn *c,
293                       char attribute((unused)) **vec,
294                       int attribute((unused)) nvec) {
295   info("S%x shut down by %s", c->tag, c->who);
296   sink_writes(ev_writer_sink(c->w), "250 shutting down\n");
297   ev_writer_flush(c->w);
298   quit(c->ev);
299 }
300
301 static int c_reconfigure(struct conn *c,
302                          char attribute((unused)) **vec,
303                          int attribute((unused)) nvec) {
304   info("S%x reconfigure by %s", c->tag, c->who);
305   if(reconfigure(c->ev, 1))
306     sink_writes(ev_writer_sink(c->w), "550 error reading new config\n");
307   else
308     sink_writes(ev_writer_sink(c->w), "250 installed new config\n");
309   return 1;                             /* completed */
310 }
311
312 static void finished_rescan(void *ru) {
313   struct conn *const c = ru;
314
315   sink_writes(ev_writer_sink(c->w), "250 rescan completed\n");
316   /* Turn this connection back on */
317   ev_reader_enable(c->r);
318 }
319
320 static void start_fresh_rescan(void *ru) {
321   struct conn *const c = ru;
322
323   if(trackdb_rescan_underway()) {
324     /* Some other waiter beat us to it.  However in this case we're happy to
325      * piggyback; the requirement is that a new rescan be started, not that it
326      * was _our_ rescan. */
327     if(c->rescan_wait) {
328       /* We block until the rescan completes */
329       trackdb_add_rescanned(finished_rescan, c);
330     } else {
331       /* We report that the new rescan has started */
332       sink_writes(ev_writer_sink(c->w), "250 rescan initiated\n");
333       /* Turn this connection back on */
334       ev_reader_enable(c->r);
335     }
336   } else {
337     /* We are the first connection to get a callback so we must start a
338      * rescan. */
339     if(c->rescan_wait) {
340       /* We want to block until the new rescan completes */
341       trackdb_rescan(c->ev, 1/*check*/, finished_rescan, c);
342     } else {
343       /* We can report back immediately */
344       trackdb_rescan(c->ev, 1/*check*/, 0, 0);
345       sink_writes(ev_writer_sink(c->w), "250 rescan initiated\n");
346       /* Turn this connection back on */
347       ev_reader_enable(c->r);
348     }
349   }
350 }
351
352 static int c_rescan(struct conn *c,
353                     char **vec,
354                     int nvec) {
355   int flag_wait = 0, flag_fresh = 0, n;
356
357   /* Parse flags */
358   for(n = 0; n < nvec; ++n) {
359     if(!strcmp(vec[n], "wait"))
360       flag_wait = 1;                    /* wait for rescan to complete */
361 #if 0
362     /* Currently disabled because untested (and hard to test). */
363     else if(!strcmp(vec[n], "fresh"))
364       flag_fresh = 1;                   /* don't piggyback underway rescan */
365 #endif
366     else {
367       sink_writes(ev_writer_sink(c->w), "550 unknown flag\n");
368       return 1;                         /* completed */
369     }
370   }
371   /* Report what was requested */
372   info("S%x rescan by %s (%s %s)", c->tag, c->who,
373        flag_wait ? "wait" : "",
374        flag_fresh ? "fresh" : "");
375   if(trackdb_rescan_underway()) {
376     if(flag_fresh) {
377       /* We want a fresh rescan but there is already one underway.  Arrange a
378        * callback when it completes and then set off a new one. */
379       c->rescan_wait = flag_wait;
380       trackdb_add_rescanned(start_fresh_rescan, c);
381       if(flag_wait)
382         return 0;
383       else {
384         sink_writes(ev_writer_sink(c->w), "250 rescan queued\n");
385         return 1;
386       }
387     } else {
388       /* There's a rescan underway, and it's acceptable to piggyback on it */
389       if(flag_wait) {
390         /* We want to block until completion. */
391         trackdb_add_rescanned(finished_rescan, c);
392         return 0;
393       } else {
394         /* We don't want to block.  So we just report that things are in
395          * hand. */
396         sink_writes(ev_writer_sink(c->w), "250 rescan already underway\n");
397         return 1;
398       }
399     }
400   } else {
401     /* No rescan is underway.  fresh is therefore irrelevant. */
402     if(flag_wait) {
403       /* We want to block until completion */
404       trackdb_rescan(c->ev, 1/*check*/, finished_rescan, c);
405       return 0;
406     } else {
407       /* We don't want to block. */
408       trackdb_rescan(c->ev, 1/*check*/, 0, 0);
409       sink_writes(ev_writer_sink(c->w), "250 rescan initiated\n");
410       return 1;                         /* completed */
411     }
412   }
413 }
414
415 static int c_version(struct conn *c,
416                      char attribute((unused)) **vec,
417                      int attribute((unused)) nvec) {
418   /* VERSION had better only use the basic character set */
419   sink_printf(ev_writer_sink(c->w), "251 %s\n", disorder_short_version_string);
420   return 1;                     /* completed */
421 }
422
423 static int c_playing(struct conn *c,
424                      char attribute((unused)) **vec,
425                      int attribute((unused)) nvec) {
426   if(playing) {
427     queue_fix_sofar(playing);
428     playing->expected = 0;
429     sink_printf(ev_writer_sink(c->w), "252 %s\n", queue_marshall(playing));
430   } else
431     sink_printf(ev_writer_sink(c->w), "259 nothing playing\n");
432   return 1;                             /* completed */
433 }
434
435 static const char *connection_host(struct conn *c) {
436   union {
437     struct sockaddr sa;
438     struct sockaddr_in in;
439     struct sockaddr_in6 in6;
440   } u;
441   socklen_t l;
442   int n;
443   char host[1024];
444
445   /* get connection data */
446   l = sizeof u;
447   if(getpeername(c->fd, &u.sa, &l) < 0) {
448     error(errno, "S%x error calling getpeername", c->tag);
449     return 0;
450   }
451   if(c->l->pf != PF_UNIX) {
452     if((n = getnameinfo(&u.sa, l,
453                         host, sizeof host, 0, 0, NI_NUMERICHOST))) {
454       error(0, "S%x error calling getnameinfo: %s", c->tag, gai_strerror(n));
455       return 0;
456     }
457     return xstrdup(host);
458   } else
459     return "local";
460 }
461
462 static int c_user(struct conn *c,
463                   char **vec,
464                   int attribute((unused)) nvec) {
465   struct kvp *k;
466   const char *res, *host, *password;
467   rights_type rights;
468
469   if(c->who) {
470     sink_writes(ev_writer_sink(c->w), "530 already authenticated\n");
471     return 1;
472   }
473   /* get connection data */
474   if(!(host = connection_host(c))) {
475     sink_writes(ev_writer_sink(c->w), "530 authentication failure\n");
476     return 1;
477   }
478   /* find the user */
479   k = trackdb_getuserinfo(vec[0]);
480   /* reject nonexistent users */
481   if(!k) {
482     error(0, "S%x unknown user '%s' from %s", c->tag, vec[0], host);
483     sink_writes(ev_writer_sink(c->w), "530 authentication failed\n");
484     return 1;
485   }
486   /* reject unconfirmed users */
487   if(kvp_get(k, "confirmation")) {
488     error(0, "S%x unconfirmed user '%s' from %s", c->tag, vec[0], host);
489     sink_writes(ev_writer_sink(c->w), "530 authentication failed\n");
490     return 1;
491   }
492   password = kvp_get(k, "password");
493   if(!password) password = "";
494   if(parse_rights(kvp_get(k, "rights"), &rights, 1)) {
495     error(0, "error parsing rights for %s", vec[0]);
496     sink_writes(ev_writer_sink(c->w), "530 authentication failed\n");
497     return 1;
498   }
499   /* check whether the response is right */
500   res = authhash(c->nonce, sizeof c->nonce, password,
501                  config->authorization_algorithm);
502   if(wideopen || (res && !strcmp(res, vec[1]))) {
503     c->who = vec[0];
504     c->rights = rights;
505     /* currently we only bother logging remote connections */
506     if(strcmp(host, "local"))
507       info("S%x %s connected from %s", c->tag, vec[0], host);
508     else
509       c->rights |= RIGHT__LOCAL;
510     sink_writes(ev_writer_sink(c->w), "230 OK\n");
511     return 1;
512   }
513   /* oops, response was wrong */
514   info("S%x authentication failure for %s from %s", c->tag, vec[0], host);
515   sink_writes(ev_writer_sink(c->w), "530 authentication failed\n");
516   return 1;
517 }
518
519 static int c_recent(struct conn *c,
520                     char attribute((unused)) **vec,
521                     int attribute((unused)) nvec) {
522   const struct queue_entry *q;
523
524   sink_writes(ev_writer_sink(c->w), "253 Tracks follow\n");
525   for(q = phead.next; q != &phead; q = q->next)
526     sink_printf(ev_writer_sink(c->w), " %s\n", queue_marshall(q));
527   sink_writes(ev_writer_sink(c->w), ".\n");
528   return 1;                             /* completed */
529 }
530
531 static int c_queue(struct conn *c,
532                    char attribute((unused)) **vec,
533                    int attribute((unused)) nvec) {
534   struct queue_entry *q;
535   time_t when = 0;
536   const char *l;
537   long length;
538
539   sink_writes(ev_writer_sink(c->w), "253 Tracks follow\n");
540   if(playing_is_enabled() && !paused) {
541     if(playing) {
542       queue_fix_sofar(playing);
543       if((l = trackdb_get(playing->track, "_length"))
544          && (length = atol(l))) {
545         time(&when);
546         when += length - playing->sofar + config->gap;
547       }
548     } else
549       /* Nothing is playing but playing is enabled, so whatever is
550        * first in the queue can be expected to start immediately. */
551       time(&when);
552   }
553   for(q = qhead.next; q != &qhead; q = q->next) {
554     /* fill in estimated start time */
555     q->expected = when;
556     sink_printf(ev_writer_sink(c->w), " %s\n", queue_marshall(q));
557     /* update for next track */
558     if(when) {
559       if((l = trackdb_get(q->track, "_length"))
560          && (length = atol(l)))
561         when += length + config->gap;
562       else
563         when = 0;
564     }
565   }
566   sink_writes(ev_writer_sink(c->w), ".\n");
567   return 1;                             /* completed */
568 }
569
570 static int output_list(struct conn *c, char **vec) {
571   while(*vec)
572     sink_printf(ev_writer_sink(c->w), "%s\n", *vec++);
573   sink_writes(ev_writer_sink(c->w), ".\n");
574   return 1;
575 }
576
577 static int files_dirs(struct conn *c,
578                       char **vec,
579                       int nvec,
580                       enum trackdb_listable what) {
581   const char *dir, *re, *errstr;
582   int erroffset;
583   pcre *rec;
584   char **fvec, *key;
585   
586   switch(nvec) {
587   case 0: dir = 0; re = 0; break;
588   case 1: dir = vec[0]; re = 0; break;
589   case 2: dir = vec[0]; re = vec[1]; break;
590   default: abort();
591   }
592   /* A bit of a bodge to make sure the args don't trample on cache keys */
593   if(dir && strchr(dir, '\n')) {
594     sink_writes(ev_writer_sink(c->w), "550 invalid directory name\n");
595     return 1;
596   }
597   if(re && strchr(re, '\n')) {
598     sink_writes(ev_writer_sink(c->w), "550 invalid regexp\n");
599     return 1;
600   }
601   /* We bother eliminating "" because the web interface is relatively
602    * likely to send it */
603   if(re && *re) {
604     byte_xasprintf(&key, "%d\n%s\n%s", (int)what, dir ? dir : "", re);
605     fvec = (char **)cache_get(&cache_files_type, key);
606     if(fvec) {
607       /* Got a cache hit, don't store the answer in the cache */
608       key = 0;
609       ++cache_files_hits;
610       rec = 0;                          /* quieten compiler */
611     } else {
612       /* Cache miss, we'll do the lookup and key != 0 so we'll store the answer
613        * in the cache. */
614       if(!(rec = pcre_compile(re, PCRE_CASELESS|PCRE_UTF8,
615                               &errstr, &erroffset, 0))) {
616         sink_printf(ev_writer_sink(c->w), "550 Error compiling regexp: %s\n",
617                     errstr);
618         return 1;
619       }
620       /* It only counts as a miss if the regexp was valid. */
621       ++cache_files_misses;
622     }
623   } else {
624     /* No regexp, don't bother caching the result */
625     rec = 0;
626     key = 0;
627     fvec = 0;
628   }
629   if(!fvec) {
630     /* No cache hit (either because a miss, or because we did not look) so do
631      * the lookup */
632     if(dir && *dir)
633       fvec = trackdb_list(dir, 0, what, rec);
634     else
635       fvec = trackdb_list(0, 0, what, rec);
636   }
637   if(key)
638     /* Put the answer in the cache */
639     cache_put(&cache_files_type, key, fvec);
640   sink_writes(ev_writer_sink(c->w), "253 Listing follow\n");
641   return output_list(c, fvec);
642 }
643
644 static int c_files(struct conn *c,
645                   char **vec,
646                   int nvec) {
647   return files_dirs(c, vec, nvec, trackdb_files);
648 }
649
650 static int c_dirs(struct conn *c,
651                   char **vec,
652                   int nvec) {
653   return files_dirs(c, vec, nvec, trackdb_directories);
654 }
655
656 static int c_allfiles(struct conn *c,
657                       char **vec,
658                       int nvec) {
659   return files_dirs(c, vec, nvec, trackdb_directories|trackdb_files);
660 }
661
662 static int c_get(struct conn *c,
663                  char **vec,
664                  int attribute((unused)) nvec) {
665   const char *v, *track;
666
667   if(!(track = trackdb_resolve(vec[0]))) {
668     sink_writes(ev_writer_sink(c->w), "550 cannot resolve track\n");
669     return 1;
670   }
671   if(vec[1][0] != '_' && (v = trackdb_get(track, vec[1])))
672     sink_printf(ev_writer_sink(c->w), "252 %s\n", quoteutf8(v));
673   else
674     sink_writes(ev_writer_sink(c->w), "555 not found\n");
675   return 1;
676 }
677
678 static int c_length(struct conn *c,
679                  char **vec,
680                  int attribute((unused)) nvec) {
681   const char *track, *v;
682
683   if(!(track = trackdb_resolve(vec[0]))) {
684     sink_writes(ev_writer_sink(c->w), "550 cannot resolve track\n");
685     return 1;
686   }
687   if((v = trackdb_get(track, "_length")))
688     sink_printf(ev_writer_sink(c->w), "252 %s\n", quoteutf8(v));
689   else
690     sink_writes(ev_writer_sink(c->w), "550 not found\n");
691   return 1;
692 }
693
694 static int c_set(struct conn *c,
695                  char **vec,
696                  int attribute((unused)) nvec) {
697   const char *track;
698
699   if(!(track = trackdb_resolve(vec[0]))) {
700     sink_writes(ev_writer_sink(c->w), "550 cannot resolve track\n");
701     return 1;
702   }
703   if(vec[1][0] != '_' && !trackdb_set(track, vec[1], vec[2]))
704     sink_writes(ev_writer_sink(c->w), "250 OK\n");
705   else
706     sink_writes(ev_writer_sink(c->w), "550 not found\n");
707   return 1;
708 }
709
710 static int c_prefs(struct conn *c,
711                    char **vec,
712                    int attribute((unused)) nvec) {
713   struct kvp *k;
714   const char *track;
715
716   if(!(track = trackdb_resolve(vec[0]))) {
717     sink_writes(ev_writer_sink(c->w), "550 cannot resolve track\n");
718     return 1;
719   }
720   k = trackdb_get_all(track);
721   sink_writes(ev_writer_sink(c->w), "253 prefs follow\n");
722   for(; k; k = k->next)
723     if(k->name[0] != '_')               /* omit internal values */
724       sink_printf(ev_writer_sink(c->w),
725                   " %s %s\n", quoteutf8(k->name), quoteutf8(k->value));
726   sink_writes(ev_writer_sink(c->w), ".\n");
727   return 1;
728 }
729
730 static int c_exists(struct conn *c,
731                     char **vec,
732                     int attribute((unused)) nvec) {
733   /* trackdb_exists() does its own alias checking */
734   sink_printf(ev_writer_sink(c->w), "252 %s\n", noyes[trackdb_exists(vec[0])]);
735   return 1;
736 }
737
738 static void search_parse_error(const char *msg, void *u) {
739   *(const char **)u = msg;
740 }
741
742 static int c_search(struct conn *c,
743                           char **vec,
744                           int attribute((unused)) nvec) {
745   char **terms, **results;
746   int nterms, nresults, n;
747   const char *e = "unknown error";
748
749   /* This is a bit of a bodge.  Initially it's there to make the eclient
750    * interface a bit more convenient to add searching to, but it has the more
751    * compelling advantage that if everything uses it, then interpretation of
752    * user-supplied search strings will be the same everywhere. */
753   if(!(terms = split(vec[0], &nterms, SPLIT_QUOTES, search_parse_error, &e))) {
754     sink_printf(ev_writer_sink(c->w), "550 %s\n", e);
755   } else {
756     results = trackdb_search(terms, nterms, &nresults);
757     sink_printf(ev_writer_sink(c->w), "253 %d matches\n", nresults);
758     for(n = 0; n < nresults; ++n)
759       sink_printf(ev_writer_sink(c->w), "%s\n", results[n]);
760     sink_writes(ev_writer_sink(c->w), ".\n");
761   }
762   return 1;
763 }
764
765 static int c_random_enable(struct conn *c,
766                            char attribute((unused)) **vec,
767                            int attribute((unused)) nvec) {
768   enable_random(c->who, c->ev);
769   /* Enable implicitly unpauses if there is nothing playing */
770   if(paused && !playing) resume_playing(c->who);
771   sink_writes(ev_writer_sink(c->w), "250 OK\n");
772   return 1;                     /* completed */
773 }
774
775 static int c_random_disable(struct conn *c,
776                             char attribute((unused)) **vec,
777                             int attribute((unused)) nvec) {
778   disable_random(c->who);
779   sink_writes(ev_writer_sink(c->w), "250 OK\n");
780   return 1;                     /* completed */
781 }
782
783 static int c_random_enabled(struct conn *c,
784                             char attribute((unused)) **vec,
785                             int attribute((unused)) nvec) {
786   sink_printf(ev_writer_sink(c->w), "252 %s\n", noyes[random_is_enabled()]);
787   return 1;                     /* completed */
788 }
789
790 static void got_stats(char *stats, void *u) {
791   struct conn *const c = u;
792
793   sink_printf(ev_writer_sink(c->w), "253 stats\n%s\n.\n", stats);
794   /* Now we can start processing commands again */
795   ev_reader_enable(c->r);
796 }
797
798 static int c_stats(struct conn *c,
799                    char attribute((unused)) **vec,
800                    int attribute((unused)) nvec) {
801   trackdb_stats_subprocess(c->ev, got_stats, c);
802   return 0;                             /* not yet complete */
803 }
804
805 static int c_volume(struct conn *c,
806                     char **vec,
807                     int nvec) {
808   int l, r, set;
809   char lb[32], rb[32];
810   rights_type rights;
811
812   switch(nvec) {
813   case 0:
814     set = 0;
815     break;
816   case 1:
817     l = r = atoi(vec[0]);
818     set = 1;
819     break;
820   case 2:
821     l = atoi(vec[0]);
822     r = atoi(vec[1]);
823     set = 1;
824     break;
825   default:
826     abort();
827   }
828   rights = set ? RIGHT_VOLUME : RIGHT_READ;
829   if(!(c->rights & rights)) {
830     error(0, "%s attempted to set volume but lacks required rights", c->who);
831     sink_writes(ev_writer_sink(c->w), "510 Prohibited\n");
832     return 1;
833   }
834   if(mixer_control(-1/*as configured*/, &l, &r, set))
835     sink_writes(ev_writer_sink(c->w), "550 error accessing mixer\n");
836   else {
837     sink_printf(ev_writer_sink(c->w), "252 %d %d\n", l, r);
838     if(l != volume_left || r != volume_right) {
839       volume_left = l;
840       volume_right = r;
841       snprintf(lb, sizeof lb, "%d", l);
842       snprintf(rb, sizeof rb, "%d", r);
843       eventlog("volume", lb, rb, (char *)0);
844     }
845   }
846   return 1;
847 }
848
849 /** @brief Called when data arrives on a log connection
850  *
851  * We just discard all such data.  The client may occasionally send data as a
852  * keepalive.
853  */
854 static int logging_reader_callback(ev_source attribute((unused)) *ev,
855                                    ev_reader *reader,
856                                    void attribute((unused)) *ptr,
857                                    size_t bytes,
858                                    int attribute((unused)) eof,
859                                    void attribute((unused)) *u) {
860   struct conn *c = u;
861
862   ev_reader_consume(reader, bytes);
863   if(eof) {
864     /* Oops, that's all for now */
865     D(("logging reader eof"));
866     if(c->w) {
867       D(("close writer"));
868       ev_writer_close(c->w);
869       c->w = 0;
870     }
871     c->r = 0;
872     remove_connection(c);
873   }
874   return 0;
875 }
876
877 static void logclient(const char *msg, void *user) {
878   struct conn *c = user;
879
880   if(!c->w || !c->r) {
881     /* This connection has gone up in smoke for some reason */
882     eventlog_remove(c->lo);
883     c->lo = 0;
884     return;
885   }
886   /* user_* messages are restricted */
887   if(!strncmp(msg, "user_", 5)) {
888     /* They are only sent to admin users */
889     if(!(c->rights & RIGHT_ADMIN))
890       return;
891     /* They are not sent over TCP connections unless remote user-management is
892      * enabled */
893     if(!config->remote_userman && !(c->rights & RIGHT__LOCAL))
894       return;
895   }
896   sink_printf(ev_writer_sink(c->w), "%"PRIxMAX" %s\n",
897               (uintmax_t)time(0), msg);
898 }
899
900 static int c_log(struct conn *c,
901                  char attribute((unused)) **vec,
902                  int attribute((unused)) nvec) {
903   time_t now;
904
905   sink_writes(ev_writer_sink(c->w), "254 OK\n");
906   /* pump out initial state */
907   time(&now);
908   sink_printf(ev_writer_sink(c->w), "%"PRIxMAX" state %s\n",
909               (uintmax_t)now, 
910               playing_is_enabled() ? "enable_play" : "disable_play");
911   sink_printf(ev_writer_sink(c->w), "%"PRIxMAX" state %s\n",
912               (uintmax_t)now, 
913               random_is_enabled() ? "enable_random" : "disable_random");
914   sink_printf(ev_writer_sink(c->w), "%"PRIxMAX" state %s\n",
915               (uintmax_t)now, 
916               paused ? "pause" : "resume");
917   if(playing)
918     sink_printf(ev_writer_sink(c->w), "%"PRIxMAX" state playing\n",
919                 (uintmax_t)now);
920   /* Initial volume */
921   sink_printf(ev_writer_sink(c->w), "%"PRIxMAX" volume %d %d\n",
922               (uintmax_t)now, volume_left, volume_right);
923   c->lo = xmalloc(sizeof *c->lo);
924   c->lo->fn = logclient;
925   c->lo->user = c;
926   eventlog_add(c->lo);
927   c->reader = logging_reader_callback;
928   return 0;
929 }
930
931 /** @brief Test whether a move is allowed
932  * @param c Connection
933  * @param qs List of IDs on queue
934  * @param nqs Number of IDs
935  * @return 0 if move is prohibited, non-0 if it is allowed
936  */
937 static int has_move_rights(struct conn *c, struct queue_entry **qs, int nqs) {
938   for(; nqs > 0; ++qs, --nqs) {
939     struct queue_entry *const q = *qs;
940
941     if(!right_movable(c->rights, c->who, q))
942       return 0;
943   }
944   return 1;
945 }
946
947 static int c_move(struct conn *c,
948                   char **vec,
949                   int attribute((unused)) nvec) {
950   struct queue_entry *q;
951   int n;
952
953   if(!(q = queue_find(vec[0]))) {
954     sink_writes(ev_writer_sink(c->w), "550 no such track on the queue\n");
955     return 1;
956   }
957   if(!has_move_rights(c, &q, 1)) {
958     error(0, "%s attempted move but lacks required rights", c->who);
959     sink_writes(ev_writer_sink(c->w),
960                 "510 Not authorized to move that track\n");
961     return 1;
962   }
963   n = queue_move(q, atoi(vec[1]), c->who);
964   sink_printf(ev_writer_sink(c->w), "252 %d\n", n);
965   /* If we've moved to the head of the queue then prepare the track. */
966   if(q == qhead.next)
967     prepare(c->ev, q);
968   return 1;
969 }
970
971 static int c_moveafter(struct conn *c,
972                        char **vec,
973                        int attribute((unused)) nvec) {
974   struct queue_entry *q, **qs;
975   int n;
976
977   if(vec[0][0]) {
978     if(!(q = queue_find(vec[0]))) {
979       sink_writes(ev_writer_sink(c->w), "550 no such track on the queue\n");
980       return 1;
981     }
982   } else
983     q = 0;
984   ++vec;
985   --nvec;
986   qs = xcalloc(nvec, sizeof *qs);
987   for(n = 0; n < nvec; ++n)
988     if(!(qs[n] = queue_find(vec[n]))) {
989       sink_writes(ev_writer_sink(c->w), "550 no such track on the queue\n");
990       return 1;
991     }
992   if(!has_move_rights(c, qs, nvec)) {
993     error(0, "%s attempted moveafter but lacks required rights", c->who);
994     sink_writes(ev_writer_sink(c->w),
995                 "510 Not authorized to move those tracks\n");
996     return 1;
997   }
998   queue_moveafter(q, nvec, qs, c->who);
999   sink_printf(ev_writer_sink(c->w), "250 Moved tracks\n");
1000   /* If we've moved to the head of the queue then prepare the track. */
1001   if(q == qhead.next)
1002     prepare(c->ev, q);
1003   return 1;
1004 }
1005
1006 static int c_part(struct conn *c,
1007                   char **vec,
1008                   int attribute((unused)) nvec) {
1009   const char *track;
1010
1011   if(!(track = trackdb_resolve(vec[0]))) {
1012     sink_writes(ev_writer_sink(c->w), "550 cannot resolve track\n");
1013     return 1;
1014   }
1015   sink_printf(ev_writer_sink(c->w), "252 %s\n",
1016               quoteutf8(trackdb_getpart(track, vec[1], vec[2])));
1017   return 1;
1018 }
1019
1020 static int c_resolve(struct conn *c,
1021                      char **vec,
1022                      int attribute((unused)) nvec) {
1023   const char *track;
1024
1025   if(!(track = trackdb_resolve(vec[0]))) {
1026     sink_writes(ev_writer_sink(c->w), "550 cannot resolve track\n");
1027     return 1;
1028   }
1029   sink_printf(ev_writer_sink(c->w), "252 %s\n", quoteutf8(track));
1030   return 1;
1031 }
1032
1033 static int list_response(struct conn *c,
1034                          const char *reply,
1035                          char **list) {
1036   sink_printf(ev_writer_sink(c->w), "253 %s\n", reply);
1037   while(*list) {
1038     sink_printf(ev_writer_sink(c->w), "%s%s\n",
1039                 **list == '.' ? "." : "", *list);
1040     ++list;
1041   }
1042   sink_writes(ev_writer_sink(c->w), ".\n");
1043   return 1;                             /* completed */
1044 }
1045
1046 static int c_tags(struct conn *c,
1047                   char attribute((unused)) **vec,
1048                   int attribute((unused)) nvec) {
1049   return list_response(c, "Tag list follows", trackdb_alltags());
1050 }
1051
1052 static int c_set_global(struct conn *c,
1053                         char **vec,
1054                         int attribute((unused)) nvec) {
1055   if(vec[0][0] == '_') {
1056     sink_writes(ev_writer_sink(c->w), "550 cannot set internal global preferences\n");
1057     return 1;
1058   }
1059   trackdb_set_global(vec[0], vec[1], c->who);
1060   sink_printf(ev_writer_sink(c->w), "250 OK\n");
1061   return 1;
1062 }
1063
1064 static int c_get_global(struct conn *c,
1065                         char **vec,
1066                         int attribute((unused)) nvec) {
1067   const char *s = trackdb_get_global(vec[0]);
1068
1069   if(s)
1070     sink_printf(ev_writer_sink(c->w), "252 %s\n", quoteutf8(s));
1071   else
1072     sink_writes(ev_writer_sink(c->w), "555 not found\n");
1073   return 1;
1074 }
1075
1076 static int c_nop(struct conn *c,
1077                  char attribute((unused)) **vec,
1078                  int attribute((unused)) nvec) {
1079   sink_printf(ev_writer_sink(c->w), "250 Quack\n");
1080   return 1;
1081 }
1082
1083 static int c_new(struct conn *c,
1084                  char **vec,
1085                  int nvec) {
1086   int max, n;
1087   char **tracks;
1088
1089   if(nvec > 0)
1090     max = atoi(vec[0]);
1091   else
1092     max = INT_MAX;
1093   if(max <= 0 || max > config->new_max)
1094     max = config->new_max;
1095   tracks = trackdb_new(0, max);
1096   sink_printf(ev_writer_sink(c->w), "253 New track list follows\n");
1097   n = 0;
1098   while(*tracks) {
1099     sink_printf(ev_writer_sink(c->w), "%s%s\n",
1100                 **tracks == '.' ? "." : "", *tracks);
1101     ++tracks;
1102   }
1103   sink_writes(ev_writer_sink(c->w), ".\n");
1104   return 1;                             /* completed */
1105
1106 }
1107
1108 static int c_rtp_address(struct conn *c,
1109                          char attribute((unused)) **vec,
1110                          int attribute((unused)) nvec) {
1111   if(config->api == BACKEND_NETWORK) {
1112     sink_printf(ev_writer_sink(c->w), "252 %s %s\n",
1113                 quoteutf8(config->broadcast.s[0]),
1114                 quoteutf8(config->broadcast.s[1]));
1115   } else
1116     sink_writes(ev_writer_sink(c->w), "550 No RTP\n");
1117   return 1;
1118 }
1119
1120 static int c_cookie(struct conn *c,
1121                     char **vec,
1122                     int attribute((unused)) nvec) {
1123   const char *host;
1124   char *user;
1125   rights_type rights;
1126
1127   /* Can't log in twice on the same connection */
1128   if(c->who) {
1129     sink_writes(ev_writer_sink(c->w), "530 already authenticated\n");
1130     return 1;
1131   }
1132   /* Get some kind of peer identifcation */
1133   if(!(host = connection_host(c))) {
1134     sink_writes(ev_writer_sink(c->w), "530 authentication failure\n");
1135     return 1;
1136   }
1137   /* Check the cookie */
1138   user = verify_cookie(vec[0], &rights);
1139   if(!user) {
1140     sink_writes(ev_writer_sink(c->w), "530 authentication failure\n");
1141     return 1;
1142   }
1143   /* Log in */
1144   c->who = user;
1145   c->cookie = vec[0];
1146   c->rights = rights;
1147   if(strcmp(host, "local"))
1148     info("S%x %s connected with cookie from %s", c->tag, user, host);
1149   else
1150     c->rights |= RIGHT__LOCAL;
1151   /* Response contains username so client knows who they are acting as */
1152   sink_printf(ev_writer_sink(c->w), "232 %s\n", quoteutf8(user));
1153   return 1;
1154 }
1155
1156 static int c_make_cookie(struct conn *c,
1157                          char attribute((unused)) **vec,
1158                          int attribute((unused)) nvec) {
1159   const char *cookie = make_cookie(c->who);
1160
1161   if(cookie)
1162     sink_printf(ev_writer_sink(c->w), "252 %s\n", quoteutf8(cookie));
1163   else
1164     sink_writes(ev_writer_sink(c->w), "550 Cannot create cookie\n");
1165   return 1;
1166 }
1167
1168 static int c_revoke(struct conn *c,
1169                     char attribute((unused)) **vec,
1170                     int attribute((unused)) nvec) {
1171   if(c->cookie) {
1172     revoke_cookie(c->cookie);
1173     sink_writes(ev_writer_sink(c->w), "250 OK\n");
1174   } else
1175     sink_writes(ev_writer_sink(c->w), "550 Did not log in with cookie\n");
1176   return 1;
1177 }
1178
1179 static int c_adduser(struct conn *c,
1180                      char **vec,
1181                      int nvec) {
1182   const char *rights;
1183
1184   if(!config->remote_userman && !(c->rights & RIGHT__LOCAL)) {
1185     error(0, "S%x: remote adduser", c->tag);
1186     sink_writes(ev_writer_sink(c->w), "550 Remote user management is disabled\n");
1187     return 1;
1188   }
1189   if(nvec > 2) {
1190     rights = vec[2];
1191     if(parse_rights(vec[2], 0, 1)) {
1192       sink_writes(ev_writer_sink(c->w), "550 Invalid rights list\n");
1193       return -1;
1194     }
1195   } else
1196     rights = config->default_rights;
1197   if(trackdb_adduser(vec[0], vec[1], rights,
1198                      0/*email*/, 0/*confirmation*/))
1199     sink_writes(ev_writer_sink(c->w), "550 Cannot create user\n");
1200   else
1201     sink_writes(ev_writer_sink(c->w), "250 User created\n");
1202   return 1;
1203 }
1204
1205 static int c_deluser(struct conn *c,
1206                      char **vec,
1207                      int attribute((unused)) nvec) {
1208   struct conn *d;
1209
1210   if(!config->remote_userman && !(c->rights & RIGHT__LOCAL)) {
1211     error(0, "S%x: remote deluser", c->tag);
1212     sink_writes(ev_writer_sink(c->w), "550 Remote user management is disabled\n");
1213     return 1;
1214   }
1215   if(trackdb_deluser(vec[0])) {
1216     sink_writes(ev_writer_sink(c->w), "550 Cannot delete user\n");
1217     return 1;
1218   }
1219   /* Zap connections belonging to deleted user */
1220   for(d = connections; d; d = d->next)
1221     if(!strcmp(d->who, vec[0]))
1222       d->rights = 0;
1223   sink_writes(ev_writer_sink(c->w), "250 User deleted\n");
1224   return 1;
1225 }
1226
1227 static int c_edituser(struct conn *c,
1228                       char **vec,
1229                       int attribute((unused)) nvec) {
1230   struct conn *d;
1231
1232   if(!config->remote_userman && !(c->rights & RIGHT__LOCAL)) {
1233     error(0, "S%x: remote edituser", c->tag);
1234     sink_writes(ev_writer_sink(c->w), "550 Remote user management is disabled\n");
1235     return 1;
1236   }
1237   /* RIGHT_ADMIN can do anything; otherwise you can only set your own email
1238    * address and password. */
1239   if((c->rights & RIGHT_ADMIN)
1240      || (!strcmp(c->who, vec[0])
1241          && (!strcmp(vec[1], "email")
1242              || !strcmp(vec[1], "password")))) {
1243     if(trackdb_edituserinfo(vec[0], vec[1], vec[2])) {
1244       sink_writes(ev_writer_sink(c->w), "550 Failed to change setting\n");
1245       return 1;
1246     }
1247     if(!strcmp(vec[1], "password")) {
1248       /* Zap all connections for this user after a password change */
1249       for(d = connections; d; d = d->next)
1250         if(!strcmp(d->who, vec[0]))
1251           d->rights = 0;
1252     } else if(!strcmp(vec[1], "rights")) {
1253       /* Update rights for this user */
1254       rights_type r;
1255
1256       if(!parse_rights(vec[2], &r, 1)) {
1257         const char *new_rights = rights_string(r);
1258         for(d = connections; d; d = d->next) {
1259           if(!strcmp(d->who, vec[0])) {
1260             /* Update rights */
1261             d->rights = r;
1262             /* Notify any log connections */
1263             if(d->lo)
1264               sink_printf(ev_writer_sink(d->w),
1265                           "%"PRIxMAX" rights_changed %s\n",
1266                           (uintmax_t)time(0),
1267                           quoteutf8(new_rights));
1268           }
1269         }
1270       }
1271     }
1272     sink_writes(ev_writer_sink(c->w), "250 OK\n");
1273   } else {
1274     error(0, "%s attempted edituser but lacks required rights", c->who);
1275     sink_writes(ev_writer_sink(c->w), "510 Restricted to administrators\n");
1276   }
1277   return 1;
1278 }
1279
1280 static int c_userinfo(struct conn *c,
1281                       char attribute((unused)) **vec,
1282                       int attribute((unused)) nvec) {
1283   struct kvp *k;
1284   const char *value;
1285
1286   /* We allow remote querying of rights so that clients can figure out what
1287    * they're allowed to do */
1288   if(!config->remote_userman
1289      && !(c->rights & RIGHT__LOCAL)
1290      && strcmp(vec[1], "rights")) {
1291     error(0, "S%x: remote userinfo %s %s", c->tag, vec[0], vec[1]);
1292     sink_writes(ev_writer_sink(c->w), "550 Remote user management is disabled\n");
1293     return 1;
1294   }
1295   /* RIGHT_ADMIN allows anything; otherwise you can only get your own email
1296    * address and rights list. */
1297   if((c->rights & RIGHT_ADMIN)
1298      || (!strcmp(c->who, vec[0])
1299          && (!strcmp(vec[1], "email")
1300              || !strcmp(vec[1], "rights")))) {
1301     if((k = trackdb_getuserinfo(vec[0])))
1302       if((value = kvp_get(k, vec[1])))
1303         sink_printf(ev_writer_sink(c->w), "252 %s\n", quoteutf8(value));
1304       else
1305         sink_writes(ev_writer_sink(c->w), "555 Not set\n");
1306     else
1307       sink_writes(ev_writer_sink(c->w), "550 No such user\n");
1308   } else {
1309     error(0, "%s attempted userinfo but lacks required rights", c->who);
1310     sink_writes(ev_writer_sink(c->w), "510 Restricted to administrators\n");
1311   }
1312   return 1;
1313 }
1314
1315 static int c_users(struct conn *c,
1316                    char attribute((unused)) **vec,
1317                    int attribute((unused)) nvec) {
1318   return list_response(c, "User list follows", trackdb_listusers());
1319 }
1320
1321 /** @brief Base64 mapping table for confirmation strings
1322  *
1323  * This is used with generic_to_base64() and generic_base64().  We cannot use
1324  * the MIME table as that contains '+' and '=' which get quoted when
1325  * URL-encoding.  (The CGI still does the URL encoding but it is desirable to
1326  * avoid it being necessary.)
1327  */
1328 static const char confirm_base64_table[] =
1329   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/.*";
1330
1331 static int c_register(struct conn *c,
1332                       char **vec,
1333                       int attribute((unused)) nvec) {
1334   char *buf, *cs;
1335   size_t bufsize;
1336   int offset;
1337
1338   /* The confirmation string is base64(username;nonce) */
1339   bufsize = strlen(vec[0]) + CONFIRM_SIZE + 2;
1340   buf = xmalloc_noptr(bufsize);
1341   offset = byte_snprintf(buf, bufsize, "%s;", vec[0]);
1342   gcry_randomize(buf + offset, CONFIRM_SIZE, GCRY_STRONG_RANDOM);
1343   cs = generic_to_base64((uint8_t *)buf, offset + CONFIRM_SIZE,
1344                          confirm_base64_table);
1345   if(trackdb_adduser(vec[0], vec[1], config->default_rights, vec[2], cs))
1346     sink_writes(ev_writer_sink(c->w), "550 Cannot create user\n");
1347   else
1348     sink_printf(ev_writer_sink(c->w), "252 %s\n", quoteutf8(cs));
1349   return 1;
1350 }
1351
1352 static int c_confirm(struct conn *c,
1353                      char **vec,
1354                      int attribute((unused)) nvec) {
1355   size_t nuser;
1356   char *user, *sep;
1357   rights_type rights;
1358   const char *host;
1359
1360   /* Get some kind of peer identifcation */
1361   if(!(host = connection_host(c))) {
1362     sink_writes(ev_writer_sink(c->w), "530 Authentication failure\n");
1363     return 1;
1364   }
1365   if(!(user = generic_base64(vec[0], &nuser, confirm_base64_table))
1366      || !(sep = memchr(user, ';', nuser))) {
1367     sink_writes(ev_writer_sink(c->w), "550 Malformed confirmation string\n");
1368     return 1;
1369   }
1370   *sep = 0;
1371   if(trackdb_confirm(user, vec[0], &rights))
1372     sink_writes(ev_writer_sink(c->w), "550 Incorrect confirmation string\n");
1373   else {
1374     c->who = user;
1375     c->cookie = 0;
1376     c->rights = rights;
1377     if(strcmp(host, "local"))
1378       info("S%x %s confirmed from %s", c->tag, user, host);
1379     else
1380       c->rights |= RIGHT__LOCAL;
1381     /* Response contains username so client knows who they are acting as */
1382     sink_printf(ev_writer_sink(c->w), "232 %s\n", quoteutf8(user));
1383   }
1384   return 1;
1385 }
1386
1387 static int sent_reminder(ev_source attribute((unused)) *ev,
1388                          pid_t attribute((unused)) pid,
1389                          int status,
1390                          const struct rusage attribute((unused)) *rusage,
1391                          void *u) {
1392   struct conn *const c = u;
1393
1394   /* Tell the client what went down */ 
1395   if(!status) {
1396     sink_writes(ev_writer_sink(c->w), "250 OK\n");
1397   } else {
1398     error(0, "reminder subprocess %s", wstat(status));
1399     sink_writes(ev_writer_sink(c->w), "550 Cannot send a reminder email\n");
1400   }
1401   /* Re-enable this connection */
1402   ev_reader_enable(c->r);
1403   return 0;
1404 }
1405
1406 static int c_reminder(struct conn *c,
1407                       char **vec,
1408                       int attribute((unused)) nvec) {
1409   struct kvp *k;
1410   const char *password, *email, *text, *encoding, *charset, *content_type;
1411   const time_t *last;
1412   time_t now;
1413   pid_t pid;
1414   
1415   static hash *last_reminder;
1416
1417   if(!config->mail_sender) {
1418     error(0, "cannot send password reminders because mail_sender not set");
1419     sink_writes(ev_writer_sink(c->w), "550 Cannot send a reminder email\n");
1420     return 1;
1421   }
1422   if(!(k = trackdb_getuserinfo(vec[0]))) {
1423     error(0, "reminder for user '%s' who does not exist", vec[0]);
1424     sink_writes(ev_writer_sink(c->w), "550 Cannot send a reminder email\n");
1425     return 1;
1426   }
1427   if(!(email = kvp_get(k, "email"))
1428      || !email_valid(email)) {
1429     error(0, "user '%s' has no valid email address", vec[0]);
1430     sink_writes(ev_writer_sink(c->w), "550 Cannot send a reminder email\n");
1431     return 1;
1432   }
1433   if(!(password = kvp_get(k, "password"))
1434      || !*password) {
1435     error(0, "user '%s' has no password", vec[0]);
1436     sink_writes(ev_writer_sink(c->w), "550 Cannot send a reminder email\n");
1437     return 1;
1438   }
1439   /* Rate-limit reminders.  This hash is bounded in size by the number of
1440    * users.  If this is actually a problem for anyone then we can periodically
1441    * clean it. */
1442   if(!last_reminder)
1443     last_reminder = hash_new(sizeof (time_t));
1444   last = hash_find(last_reminder, vec[0]);
1445   time(&now);
1446   if(last && now < *last + config->reminder_interval) {
1447     error(0, "sent a password reminder to '%s' too recently", vec[0]);
1448     sink_writes(ev_writer_sink(c->w), "550 Cannot send a reminder email\n");
1449     return 1;
1450   }
1451   /* Send the reminder */
1452   /* TODO this should be templatized and to some extent merged with
1453    * the code in act_register() */
1454   byte_xasprintf((char **)&text,
1455 "Someone requested that you be sent a reminder of your DisOrder password.\n"
1456 "Your password is:\n"
1457 "\n"
1458 "  %s\n", password);
1459   if(!(text = mime_encode_text(text, &charset, &encoding)))
1460     fatal(0, "cannot encode email");
1461   byte_xasprintf((char **)&content_type, "text/plain;charset=%s",
1462                  quote822(charset, 0));
1463   pid = sendmail_subprocess("", config->mail_sender, email,
1464                             "DisOrder password reminder",
1465                             encoding, content_type, text);
1466   if(pid < 0) {
1467     sink_writes(ev_writer_sink(c->w), "550 Cannot send a reminder email\n");
1468     return 1;
1469   }
1470   hash_add(last_reminder, vec[0], &now, HASH_INSERT_OR_REPLACE);
1471   info("sending a passsword reminder to user '%s'", vec[0]);
1472   /* We can only continue when the subprocess finishes */
1473   ev_child(c->ev, pid, 0, sent_reminder, c);
1474   return 0;
1475 }
1476
1477 static int c_schedule_list(struct conn *c,
1478                            char attribute((unused)) **vec,
1479                            int attribute((unused)) nvec) {
1480   char **ids = schedule_list(0);
1481   sink_writes(ev_writer_sink(c->w), "253 ID list follows\n");
1482   while(*ids)
1483     sink_printf(ev_writer_sink(c->w), "%s\n", *ids++);
1484   sink_writes(ev_writer_sink(c->w), ".\n");
1485   return 1;                             /* completed */
1486 }
1487
1488 static int c_schedule_get(struct conn *c,
1489                           char **vec,
1490                           int attribute((unused)) nvec) {
1491   struct kvp *actiondata = schedule_get(vec[0]), *k;
1492
1493   if(!actiondata) {
1494     sink_writes(ev_writer_sink(c->w), "555 No such event\n");
1495     return 1;                           /* completed */
1496   }
1497   /* Scheduled events are public information.  Anyone with RIGHT_READ can see
1498    * them. */
1499   sink_writes(ev_writer_sink(c->w), "253 Event information follows\n");
1500   for(k = actiondata; k; k = k->next)
1501     sink_printf(ev_writer_sink(c->w), " %s %s\n",
1502                 quoteutf8(k->name),  quoteutf8(k->value));
1503   sink_writes(ev_writer_sink(c->w), ".\n");
1504   return 1;                             /* completed */
1505 }
1506
1507 static int c_schedule_del(struct conn *c,
1508                           char **vec,
1509                           int attribute((unused)) nvec) {
1510   struct kvp *actiondata = schedule_get(vec[0]);
1511
1512   if(!actiondata) {
1513     sink_writes(ev_writer_sink(c->w), "555 No such event\n");
1514     return 1;                           /* completed */
1515   }
1516   /* If you have admin rights you can delete anything.  If you don't then you
1517    * can only delete your own scheduled events. */
1518   if(!(c->rights & RIGHT_ADMIN)) {
1519     const char *who = kvp_get(actiondata, "who");
1520
1521     if(!who || !c->who || strcmp(who, c->who)) {
1522       sink_writes(ev_writer_sink(c->w), "551 Not authorized\n");
1523       return 1;                         /* completed */
1524     }
1525   }
1526   if(schedule_del(vec[0]))
1527     sink_writes(ev_writer_sink(c->w), "550 Could not delete scheduled event\n");
1528   else
1529     sink_writes(ev_writer_sink(c->w), "250 Deleted\n");
1530   return 1;                             /* completed */
1531 }
1532
1533 static int c_schedule_add(struct conn *c,
1534                           char **vec,
1535                           int nvec) {
1536   struct kvp *actiondata = 0;
1537   const char *id;
1538
1539   /* Standard fields */
1540   kvp_set(&actiondata, "who", c->who);
1541   kvp_set(&actiondata, "when", vec[0]);
1542   kvp_set(&actiondata, "priority", vec[1]);
1543   kvp_set(&actiondata, "action", vec[2]);
1544   /* Action-dependent fields */
1545   if(!strcmp(vec[2], "play")) {
1546     if(nvec != 4) {
1547       sink_writes(ev_writer_sink(c->w), "550 Wrong number of arguments\n");
1548       return 1;
1549     }
1550     if(!trackdb_exists(vec[3])) {
1551       sink_writes(ev_writer_sink(c->w), "550 Track is not in database\n");
1552       return 1;
1553     }
1554     kvp_set(&actiondata, "track", vec[3]);
1555   } else if(!strcmp(vec[2], "set-global")) {
1556     if(nvec < 4 || nvec > 5) {
1557       sink_writes(ev_writer_sink(c->w), "550 Wrong number of arguments\n");
1558       return 1;
1559     }
1560     kvp_set(&actiondata, "key", vec[3]);
1561     if(nvec > 4)
1562       kvp_set(&actiondata, "value", vec[4]);
1563   } else {
1564     sink_writes(ev_writer_sink(c->w), "550 Unknown action\n");
1565     return 1;
1566   }
1567   /* schedule_add() checks user rights */
1568   id = schedule_add(c->ev, actiondata);
1569   if(!id)
1570     sink_writes(ev_writer_sink(c->w), "550 Cannot add scheduled event\n");
1571   else
1572     sink_printf(ev_writer_sink(c->w), "252 %s\n", id);
1573   return 1;
1574 }
1575
1576 static int playlist_response(struct conn *c,
1577                              int err) {
1578   switch(err) {
1579   case 0:
1580     assert(!"cannot cope with success");
1581   case EACCES:
1582     sink_writes(ev_writer_sink(c->w), "550 Access denied\n");
1583     break;
1584   case EINVAL:
1585     sink_writes(ev_writer_sink(c->w), "550 Invalid playlist name\n");
1586     break;
1587   case ENOENT:
1588     sink_writes(ev_writer_sink(c->w), "555 No such playlist\n");
1589     break;
1590   default:
1591     sink_writes(ev_writer_sink(c->w), "550 Error accessing playlist\n");
1592     break;
1593   }
1594   return 1;
1595 }
1596
1597 static int c_playlist_get(struct conn *c,
1598                           char **vec,
1599                           int attribute((unused)) nvec) {
1600   char **tracks;
1601   int err;
1602
1603   if(!(err = trackdb_playlist_get(vec[0], c->who, &tracks, 0, 0)))
1604     return list_response(c, "Playlist contents follows", tracks);
1605   else
1606     return playlist_response(c, err);
1607 }
1608
1609 static int c_playlist_set(struct conn *c,
1610                           char **vec,
1611                           int attribute((unused)) nvec) {
1612   /* TODO */
1613 }
1614
1615 static int c_playlist_get_share(struct conn *c,
1616                                 char **vec,
1617                                 int attribute((unused)) nvec) {
1618   char *share;
1619   int err;
1620
1621   if(!(err = trackdb_playlist_get(vec[0], c->who, 0, 0, &share))) {
1622     sink_printf(ev_writer_sink(c->w), "252 %s", quoteutf8(share));
1623     return 1;
1624   } else
1625     return playlist_response(c, err);
1626 }
1627
1628 static int c_playlist_set_share(struct conn *c,
1629                                 char **vec,
1630                                 int attribute((unused)) nvec) {
1631   int err;
1632
1633   if(!(err = trackdb_playlist_set(vec[0], c->who, 0, 0, vec[1]))) {
1634     sink_printf(ev_writer_sink(c->w), "250 OK");
1635     return 1;
1636   } else
1637     return playlist_response(c, err);
1638 }
1639
1640 static int c_playlists(struct conn *c,
1641                        char attribute((unused)) **vec,
1642                        int attribute((unused)) nvec) {
1643   char **p;
1644
1645   trackdb_playlist_list(c->who, &p, 0);
1646   return list_response(c, "List of playlists follows", p);
1647 }
1648
1649 static int c_playlist_delete(struct conn *c,
1650                              char **vec,
1651                              int attribute((unused)) nvec) {
1652   int err;
1653   
1654   if(!(err = trackdb_playlist_delete(vec[0], c->who))) {
1655     sink_writes(ev_writer_sink(c->w), "250 OK");
1656     return 1;
1657   } else
1658     return playlist_response(c, err);
1659 }
1660
1661 static int c_playlist_lock(struct conn *c,
1662                            char **vec,
1663                            int attribute((unused)) nvec) {
1664   int err;
1665   struct conn *cc;
1666
1667   /* Check we're allowed to modify this playlist */
1668   if((err = trackdb_playlist_set(vec[0], c->who, 0, 0, 0)))
1669     return playlist_response(c, err);
1670   /* If we hold a lock don't allow a new one */
1671   if(c->locked_playlist) {
1672     sink_writes(ev_writer_sink(c->w), "550 Already holding a lock\n");
1673     return 1;
1674   }
1675   /* See if some other connection locks the same playlist */
1676   for(cc = connections; cc; cc = cc->next)
1677     if(cc->locked_playlist && !strcmp(cc->locked_playlist, vec[0]))
1678       break;
1679   if(cc) {
1680     /* TODO: implement config->playlist_lock_timeout */
1681     sink_writes(ev_writer_sink(c->w), "550 Already locked\n");
1682     return 1;
1683   }
1684   c->locked_playlist = xstrdup(vec[0]);
1685   time(&c->locked_when);
1686   sink_writes(ev_writer_sink(c->w), "250 Acquired lock\n");
1687   return 1;
1688 }
1689
1690 static int c_playlist_unlock(struct conn *c,
1691                              char **vec,
1692                              int attribute((unused)) nvec) {
1693   if(!c->locked_playlist) {
1694     sink_writes(ev_writer_sink(c->w), "550 Not holding a lock\n");
1695     return 1;
1696   }
1697   c->locked_playlist = 0;
1698   sink_writes(ev_writer_sink(c->w), "250 Released lock\n");
1699   return 1;
1700 }
1701
1702 static const struct command {
1703   /** @brief Command name */
1704   const char *name;
1705
1706   /** @brief Minimum number of arguments */
1707   int minargs;
1708
1709   /** @brief Maximum number of arguments */
1710   int maxargs;
1711
1712   /** @brief Function to process command */
1713   int (*fn)(struct conn *, char **, int);
1714
1715   /** @brief Rights required to execute command
1716    *
1717    * 0 means that the command can be issued without logging in.  If multiple
1718    * bits are listed here any of those rights will do.
1719    */
1720   rights_type rights;
1721 } commands[] = {
1722   { "adduser",        2, 3,       c_adduser,        RIGHT_ADMIN|RIGHT__LOCAL },
1723   { "allfiles",       0, 2,       c_allfiles,       RIGHT_READ },
1724   { "confirm",        1, 1,       c_confirm,        0 },
1725   { "cookie",         1, 1,       c_cookie,         0 },
1726   { "deluser",        1, 1,       c_deluser,        RIGHT_ADMIN|RIGHT__LOCAL },
1727   { "dirs",           0, 2,       c_dirs,           RIGHT_READ },
1728   { "disable",        0, 1,       c_disable,        RIGHT_GLOBAL_PREFS },
1729   { "edituser",       3, 3,       c_edituser,       RIGHT_ADMIN|RIGHT_USERINFO },
1730   { "enable",         0, 0,       c_enable,         RIGHT_GLOBAL_PREFS },
1731   { "enabled",        0, 0,       c_enabled,        RIGHT_READ },
1732   { "exists",         1, 1,       c_exists,         RIGHT_READ },
1733   { "files",          0, 2,       c_files,          RIGHT_READ },
1734   { "get",            2, 2,       c_get,            RIGHT_READ },
1735   { "get-global",     1, 1,       c_get_global,     RIGHT_READ },
1736   { "length",         1, 1,       c_length,         RIGHT_READ },
1737   { "log",            0, 0,       c_log,            RIGHT_READ },
1738   { "make-cookie",    0, 0,       c_make_cookie,    RIGHT_READ },
1739   { "move",           2, 2,       c_move,           RIGHT_MOVE__MASK },
1740   { "moveafter",      1, INT_MAX, c_moveafter,      RIGHT_MOVE__MASK },
1741   { "new",            0, 1,       c_new,            RIGHT_READ },
1742   { "nop",            0, 0,       c_nop,            0 },
1743   { "part",           3, 3,       c_part,           RIGHT_READ },
1744   { "pause",          0, 0,       c_pause,          RIGHT_PAUSE },
1745   { "play",           1, 1,       c_play,           RIGHT_PLAY },
1746   { "playing",        0, 0,       c_playing,        RIGHT_READ },
1747   { "playlist-delete",    1, 1,   c_playlist_delete,    RIGHT_PLAY },
1748   { "playlist-get",       1, 1,   c_playlist_get,       RIGHT_PLAY },
1749   { "playlist-get-share", 1, 1,   c_playlist_get_share, RIGHT_PLAY },
1750   { "playlist-lock",      1, 1,   c_playlist_lock,      RIGHT_PLAY },
1751   { "playlist-set",       1, 1,   c_playlist_set,       RIGHT_PLAY },
1752   { "playlist-set-share", 2, 2,   c_playlist_set_share, RIGHT_PLAY },
1753   { "playlist-unlock",    0, 0,   c_playlist_unlock,    RIGHT_PLAY },
1754   { "playlists",          0, 0,   c_playlists,          RIGHT_PLAY },
1755   { "prefs",          1, 1,       c_prefs,          RIGHT_READ },
1756   { "queue",          0, 0,       c_queue,          RIGHT_READ },
1757   { "random-disable", 0, 0,       c_random_disable, RIGHT_GLOBAL_PREFS },
1758   { "random-enable",  0, 0,       c_random_enable,  RIGHT_GLOBAL_PREFS },
1759   { "random-enabled", 0, 0,       c_random_enabled, RIGHT_READ },
1760   { "recent",         0, 0,       c_recent,         RIGHT_READ },
1761   { "reconfigure",    0, 0,       c_reconfigure,    RIGHT_ADMIN },
1762   { "register",       3, 3,       c_register,       RIGHT_REGISTER|RIGHT__LOCAL },
1763   { "reminder",       1, 1,       c_reminder,       RIGHT__LOCAL },
1764   { "remove",         1, 1,       c_remove,         RIGHT_REMOVE__MASK },
1765   { "rescan",         0, INT_MAX, c_rescan,         RIGHT_RESCAN },
1766   { "resolve",        1, 1,       c_resolve,        RIGHT_READ },
1767   { "resume",         0, 0,       c_resume,         RIGHT_PAUSE },
1768   { "revoke",         0, 0,       c_revoke,         RIGHT_READ },
1769   { "rtp-address",    0, 0,       c_rtp_address,    0 },
1770   { "schedule-add",   3, INT_MAX, c_schedule_add,   RIGHT_READ },
1771   { "schedule-del",   1, 1,       c_schedule_del,   RIGHT_READ },
1772   { "schedule-get",   1, 1,       c_schedule_get,   RIGHT_READ },
1773   { "schedule-list",  0, 0,       c_schedule_list,  RIGHT_READ },
1774   { "scratch",        0, 1,       c_scratch,        RIGHT_SCRATCH__MASK },
1775   { "search",         1, 1,       c_search,         RIGHT_READ },
1776   { "set",            3, 3,       c_set,            RIGHT_PREFS, },
1777   { "set-global",     2, 2,       c_set_global,     RIGHT_GLOBAL_PREFS },
1778   { "shutdown",       0, 0,       c_shutdown,       RIGHT_ADMIN },
1779   { "stats",          0, 0,       c_stats,          RIGHT_READ },
1780   { "tags",           0, 0,       c_tags,           RIGHT_READ },
1781   { "unset",          2, 2,       c_set,            RIGHT_PREFS },
1782   { "unset-global",   1, 1,       c_set_global,     RIGHT_GLOBAL_PREFS },
1783   { "user",           2, 2,       c_user,           0 },
1784   { "userinfo",       2, 2,       c_userinfo,       RIGHT_READ },
1785   { "users",          0, 0,       c_users,          RIGHT_READ },
1786   { "version",        0, 0,       c_version,        RIGHT_READ },
1787   { "volume",         0, 2,       c_volume,         RIGHT_READ|RIGHT_VOLUME }
1788 };
1789
1790 static void command_error(const char *msg, void *u) {
1791   struct conn *c = u;
1792
1793   sink_printf(ev_writer_sink(c->w), "500 parse error: %s\n", msg);
1794 }
1795
1796 /* process a command.  Return 1 if complete, 0 if incomplete. */
1797 static int command(struct conn *c, char *line) {
1798   char **vec;
1799   int nvec, n;
1800
1801   D(("server command %s", line));
1802   /* We force everything into NFC as early as possible */
1803   if(!(line = utf8_compose_canon(line, strlen(line), 0))) {
1804     sink_writes(ev_writer_sink(c->w), "500 cannot normalize command\n");
1805     return 1;
1806   }
1807   if(!(vec = split(line, &nvec, SPLIT_QUOTES, command_error, c))) {
1808     sink_writes(ev_writer_sink(c->w), "500 cannot parse command\n");
1809     return 1;
1810   }
1811   if(nvec == 0) {
1812     sink_writes(ev_writer_sink(c->w), "500 do what?\n");
1813     return 1;
1814   }
1815   if((n = TABLE_FIND(commands, name, vec[0])) < 0)
1816     sink_writes(ev_writer_sink(c->w), "500 unknown command\n");
1817   else {
1818     if(commands[n].rights
1819        && !(c->rights & commands[n].rights)) {
1820       error(0, "%s attempted %s but lacks required rights", c->who ? c->who : "NULL",
1821             commands[n].name);
1822       sink_writes(ev_writer_sink(c->w), "510 Prohibited\n");
1823       return 1;
1824     }
1825     ++vec;
1826     --nvec;
1827     if(nvec < commands[n].minargs) {
1828       sink_writes(ev_writer_sink(c->w), "500 missing argument(s)\n");
1829       return 1;
1830     }
1831     if(nvec > commands[n].maxargs) {
1832       sink_writes(ev_writer_sink(c->w), "500 too many arguments\n");
1833       return 1;
1834     }
1835     return commands[n].fn(c, vec, nvec);
1836   }
1837   return 1;                     /* completed */
1838 }
1839
1840 /* redirect to the right reader callback for our current state */
1841 static int redirect_reader_callback(ev_source *ev,
1842                                     ev_reader *reader,
1843                                     void *ptr,
1844                                     size_t bytes,
1845                                     int eof,
1846                                     void *u) {
1847   struct conn *c = u;
1848
1849   return c->reader(ev, reader, ptr, bytes, eof, u);
1850 }
1851
1852 /* the main command reader */
1853 static int reader_callback(ev_source attribute((unused)) *ev,
1854                            ev_reader *reader,
1855                            void *ptr,
1856                            size_t bytes,
1857                            int eof,
1858                            void *u) {
1859   struct conn *c = u;
1860   char *eol;
1861   int complete;
1862
1863   D(("server reader_callback"));
1864   while((eol = memchr(ptr, '\n', bytes))) {
1865     *eol++ = 0;
1866     ev_reader_consume(reader, eol - (char *)ptr);
1867     complete = command(c, ptr);
1868     bytes -= (eol - (char *)ptr);
1869     ptr = eol;
1870     if(!complete) {
1871       /* the command had better have set a new reader callback */
1872       if(bytes || eof)
1873         /* there are further bytes to read, or we are at eof; arrange for the
1874          * command's reader callback to handle them */
1875         return ev_reader_incomplete(reader);
1876       /* nothing's going on right now */
1877       return 0;
1878     }
1879     /* command completed, we can go around and handle the next one */
1880   }
1881   if(eof) {
1882     if(bytes)
1883       error(0, "S%x unterminated line", c->tag);
1884     D(("normal reader close"));
1885     c->r = 0;
1886     if(c->w) {
1887       D(("close associated writer"));
1888       ev_writer_close(c->w);
1889       c->w = 0;
1890     }
1891     remove_connection(c);
1892   }
1893   return 0;
1894 }
1895
1896 static int listen_callback(ev_source *ev,
1897                            int fd,
1898                            const struct sockaddr attribute((unused)) *remote,
1899                            socklen_t attribute((unused)) rlen,
1900                            void *u) {
1901   const struct listener *l = u;
1902   struct conn *c = xmalloc(sizeof *c);
1903   static unsigned tags;
1904
1905   D(("server listen_callback fd %d (%s)", fd, l->name));
1906   nonblock(fd);
1907   cloexec(fd);
1908   c->next = connections;
1909   c->tag = tags++;
1910   c->ev = ev;
1911   c->w = ev_writer_new(ev, fd, writer_error, c,
1912                        "client writer");
1913   c->r = ev_reader_new(ev, fd, redirect_reader_callback, reader_error, c,
1914                        "client reader");
1915   ev_tie(c->r, c->w);
1916   c->fd = fd;
1917   c->reader = reader_callback;
1918   c->l = l;
1919   c->rights = 0;
1920   connections = c;
1921   gcry_randomize(c->nonce, sizeof c->nonce, GCRY_STRONG_RANDOM);
1922   sink_printf(ev_writer_sink(c->w), "231 %d %s %s\n",
1923               2,
1924               config->authorization_algorithm,
1925               hex(c->nonce, sizeof c->nonce));
1926   return 0;
1927 }
1928
1929 int server_start(ev_source *ev, int pf,
1930                  size_t socklen, const struct sockaddr *sa,
1931                  const char *name) {
1932   int fd;
1933   struct listener *l = xmalloc(sizeof *l);
1934   static const int one = 1;
1935
1936   D(("server_init socket %s", name));
1937   fd = xsocket(pf, SOCK_STREAM, 0);
1938   xsetsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
1939   if(bind(fd, sa, socklen) < 0) {
1940     error(errno, "error binding to %s", name);
1941     return -1;
1942   }
1943   xlisten(fd, 128);
1944   nonblock(fd);
1945   cloexec(fd);
1946   l->name = name;
1947   l->pf = pf;
1948   if(ev_listen(ev, fd, listen_callback, l, "server listener"))
1949     exit(EXIT_FAILURE);
1950   return fd;
1951 }
1952
1953 int server_stop(ev_source *ev, int fd) {
1954   xclose(fd);
1955   return ev_listen_cancel(ev, fd);
1956 }
1957
1958 /*
1959 Local Variables:
1960 c-basic-offset:2
1961 comment-column:40
1962 fill-column:79
1963 End:
1964 */