chiark / gitweb /
clients/playrtp.c: Don't crash if an interface has a null address.
[disorder] / clients / playrtp.c
index 89e458e48504c471f327b0171b81bfe1099b91c9..372bfcf63c83373d078011019b89665463e4e2a0 100644 (file)
@@ -243,6 +243,7 @@ static void *control_thread(void attribute((unused)) *arg) {
   char *line;
   socklen_t salen;
   FILE *fp;
+  int vl, vr;
 
   assert(control_socket);
   unlink(control_socket);
@@ -276,9 +277,21 @@ static void *control_thread(void attribute((unused)) *arg) {
       if(!strcmp(line, "stop")) {
         disorder_info("stopped via %s", control_socket);
         exit(0);                          /* terminate immediately */
-      }
-      if(!strcmp(line, "query"))
+      } else if(!strcmp(line, "query"))
         fprintf(fp, "running");
+      else if(!strcmp(line, "getvol")) {
+        if(backend->get_volume) backend->get_volume(&vl, &vr);
+        else vl = vr = 0;
+        fprintf(fp, "%d %d\n", vl, vr);
+      } else if(!strncmp(line, "setvol ", 7)) {
+        if(!backend->set_volume)
+          vl = vr = 0;
+        else if(sscanf(line + 7, "%d %d", &vl, &vr) == 2)
+          backend->set_volume(&vl, &vr);
+        else
+          backend->get_volume(&vl, &vr);
+        fprintf(fp, "%d %d\n", vl, vr);
+      }
       xfree(line);
     }
     if(fclose(fp) < 0)
@@ -487,7 +500,7 @@ struct packet *playrtp_next_packet(void) {
 }
 
 /* display usage message and terminate */
-static void help(void) {
+static void attribute((noreturn)) help(void) {
   xprintf("Usage:\n"
          "  disorder-playrtp [OPTIONS] [[ADDRESS] PORT]\n"
          "Options:\n"
@@ -647,10 +660,12 @@ static int compare_flags(const struct ifaddrs *a,
   unsigned aup = aflags & IFF_UP, bup = bflags & IFF_UP;
   if(aup != bup)
     return aup > bup ? 1 : -1;
+#if IFF_DYNAMIC
   /* Static addresses are better than dynamic */
   unsigned adynamic = aflags & IFF_DYNAMIC, bdynamic = bflags & IFF_DYNAMIC;
   if(adynamic != bdynamic)
     return adynamic < bdynamic ? 1 : -1;
+#endif
   unsigned aloopback = aflags & IFF_LOOPBACK, bloopback = bflags & IFF_LOOPBACK;
   /* Static addresses are better than dynamic */
   if(aloopback != bloopback)
@@ -780,6 +795,12 @@ int main(int argc, char **argv) {
   struct sockaddr *addr;
   socklen_t addr_len;
   if(!strcmp(sl.s[0], "-")) {
+    /* We'll need a connection to request the incoming stream, so open one if
+     * we don't have one already */
+    if(!c) {
+      if(!(c = disorder_new(1))) exit(EXIT_FAILURE);
+      if(disorder_connect(c)) exit(EXIT_FAILURE);
+    }
     /* Pick address family to match known-working connectivity to the server */
     int family = disorder_client_af(c);
     /* Get a list of interfaces */
@@ -788,6 +809,7 @@ int main(int argc, char **argv) {
       disorder_fatal(errno, "error calling getifaddrs");
     /* Try to pick a good one */
     for(; ifa; ifa = ifa->ifa_next) {
+      if(!ifa->ifa_addr) continue;
       if(bestifa == NULL
          || compare_interfaces(ifa, bestifa, family) > 0)
         bestifa = ifa;
@@ -951,7 +973,9 @@ int main(int argc, char **argv) {
   uaudio_set_format(44100/*Hz*/, 2/*channels*/,
                     16/*bits/channel*/, 1/*signed*/);
   uaudio_set("application", "disorder-playrtp");
+  backend->configure();
   backend->start(playrtp_callback, NULL);
+  if(backend->open_mixer) backend->open_mixer();
   /* We receive and convert audio data in a background thread */
   if((err = pthread_create(&ltid, 0, listen_thread, 0)))
     disorder_fatal(err, "pthread_create listen_thread");