chiark / gitweb /
DisOrder 3.0
[disorder] / lib / eclient.c
index 0037fb5d362d352449bbb34cb5ff3105eb2fda2c..98f60a899d917fd5d1ed4c843b071285f54754f5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This file is part of DisOrder.
- * Copyright (C) 2006, 2007 Richard Kettlewell
+ * Copyright (C) 2006-2008 Richard Kettlewell
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -146,6 +146,9 @@ struct disorder_eclient {
    * time to time so that we detect broken connections reasonably quickly.  The
    * server just ignores these bytes.
    */
+
+  /** @brief Protocol version */
+  int protocol;
 };
 
 /* Forward declarations ******************************************************/
@@ -539,16 +542,32 @@ static void authbanner_opcallback(disorder_eclient *c,
     disorder_eclient_close(c);
     return;
   }
-  if(nrvec != 3) {
+  switch(nrvec) {
+  case 1:
+    protocol = "1";
+    algorithm = "sha1";
+    challenge = *rvec++;
+    break;
+  case 2:
+    protocol = "1";
+    algorithm = *rvec++;
+    challenge = *rvec++;
+    break;
+  case 3:
+    protocol = *rvec++;
+    algorithm = *rvec++;
+    challenge = *rvec++;
+    break;
+  default:
     protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
     disorder_eclient_close(c);
+    return;
   }
-  protocol = *rvec++;
-  algorithm = *rvec++;
-  challenge = *rvec++;
-  if(strcmp(protocol, "2")) {
+  c->protocol = atoi(protocol);
+  if(c->protocol < 1 || c->protocol > 2) {
     protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
     disorder_eclient_close(c);
+    return;
   }
   nonce = unhex(challenge, &nonce_len);
   res = authhash(nonce, nonce_len, config->password, algorithm);
@@ -824,12 +843,16 @@ static void string_response_opcallback(disorder_eclient *c,
   D(("string_response_callback"));
   if(c->rc / 100 == 2) {
     if(op->completed) {
-      char **rr = split(c->line + 4, 0, SPLIT_QUOTES, 0, 0);
-
-      if(rr && *rr)
-        ((disorder_eclient_string_response *)op->completed)(op->v, *rr);
-      else
-        protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
+      if(c->protocol >= 2) {
+        char **rr = split(c->line + 4, 0, SPLIT_QUOTES, 0, 0);
+        
+        if(rr && *rr)
+          ((disorder_eclient_string_response *)op->completed)(op->v, *rr);
+        else
+          protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
+      } else
+        ((disorder_eclient_string_response *)op->completed)(op->v,
+                                                            c->line + 4);
     }
   } else
     protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
@@ -1265,6 +1288,7 @@ int disorder_eclient_log(disorder_eclient *c,
     c->log_callbacks->state(c->log_v, c->statebits);
   stash_command(c, 0/*queuejump*/, log_opcallback, 0/*completed*/, v,
                 "log", (char *)0);
+  disorder_eclient_polled(c, 0);
   return 0;
 }
 
@@ -1309,33 +1333,33 @@ static void logline(disorder_eclient *c, const char *line) {
 
 static void logentry_completed(disorder_eclient *c,
                                int attribute((unused)) nvec, char **vec) {
-  if(!c->log_callbacks->completed) return;
   c->statebits &= ~DISORDER_PLAYING;
-  c->log_callbacks->completed(c->log_v, vec[0]);
+  if(c->log_callbacks->completed)
+    c->log_callbacks->completed(c->log_v, vec[0]);
   if(c->log_callbacks->state)
     c->log_callbacks->state(c->log_v, c->statebits | DISORDER_CONNECTED);
 }
 
 static void logentry_failed(disorder_eclient *c,
                             int attribute((unused)) nvec, char **vec) {
-  if(!c->log_callbacks->failed)return;
   c->statebits &= ~DISORDER_PLAYING;
-  c->log_callbacks->failed(c->log_v, vec[0], vec[1]);
+  if(c->log_callbacks->failed)
+    c->log_callbacks->failed(c->log_v, vec[0], vec[1]);
   if(c->log_callbacks->state)
     c->log_callbacks->state(c->log_v, c->statebits | DISORDER_CONNECTED);
 }
 
 static void logentry_moved(disorder_eclient *c,
                            int attribute((unused)) nvec, char **vec) {
-  if(!c->log_callbacks->moved) return;
-  c->log_callbacks->moved(c->log_v, vec[0]);
+  if(c->log_callbacks->moved)
+    c->log_callbacks->moved(c->log_v, vec[0]);
 }
 
 static void logentry_playing(disorder_eclient *c,
                              int attribute((unused)) nvec, char **vec) {
-  if(!c->log_callbacks->playing) return;
   c->statebits |= DISORDER_PLAYING;
-  c->log_callbacks->playing(c->log_v, vec[0], vec[1]);
+  if(c->log_callbacks->playing)
+    c->log_callbacks->playing(c->log_v, vec[0], vec[1]);
   if(c->log_callbacks->state)
     c->log_callbacks->state(c->log_v, c->statebits | DISORDER_CONNECTED);
 }
@@ -1344,7 +1368,7 @@ static void logentry_queue(disorder_eclient *c,
                            int attribute((unused)) nvec, char **vec) {
   struct queue_entry *q;
 
-  if(!c->log_callbacks->completed) return;
+  if(!c->log_callbacks->queue) return;
   q = xmalloc(sizeof *q);
   if(queue_unmarshall_vec(q, nvec, vec, eclient_queue_error, c))
     return;                             /* bogus */
@@ -1364,28 +1388,28 @@ static void logentry_recent_added(disorder_eclient *c,
 
 static void logentry_recent_removed(disorder_eclient *c,
                                     int attribute((unused)) nvec, char **vec) {
-  if(!c->log_callbacks->recent_removed) return;
-  c->log_callbacks->recent_removed(c->log_v, vec[0]);
+  if(c->log_callbacks->recent_removed)
+    c->log_callbacks->recent_removed(c->log_v, vec[0]);
 }
 
 static void logentry_removed(disorder_eclient *c,
                              int attribute((unused)) nvec, char **vec) {
-  if(!c->log_callbacks->removed) return;
-  c->log_callbacks->removed(c->log_v, vec[0], vec[1]);
+  if(c->log_callbacks->removed)
+    c->log_callbacks->removed(c->log_v, vec[0], vec[1]);
 }
 
 static void logentry_rescanned(disorder_eclient *c,
                                int attribute((unused)) nvec,
                                char attribute((unused)) **vec) {
-  if(!c->log_callbacks->rescanned) return;
-  c->log_callbacks->rescanned(c->log_v);
+  if(c->log_callbacks->rescanned)
+    c->log_callbacks->rescanned(c->log_v);
 }
 
 static void logentry_scratched(disorder_eclient *c,
                                int attribute((unused)) nvec, char **vec) {
-  if(!c->log_callbacks->scratched) return;
   c->statebits &= ~DISORDER_PLAYING;
-  c->log_callbacks->scratched(c->log_v, vec[0], vec[1]);
+  if(c->log_callbacks->scratched)
+    c->log_callbacks->scratched(c->log_v, vec[0], vec[1]);
   if(c->log_callbacks->state)
     c->log_callbacks->state(c->log_v, c->statebits | DISORDER_CONNECTED);
 }
@@ -1416,8 +1440,8 @@ static void logentry_state(disorder_eclient *c,
       c->statebits &= ~statestrings[n].bit;
       break;
     }
-  if(!c->log_callbacks->state) return;
-  c->log_callbacks->state(c->log_v, c->statebits | DISORDER_CONNECTED);
+  if(c->log_callbacks->state) 
+    c->log_callbacks->state(c->log_v, c->statebits | DISORDER_CONNECTED);
 }
 
 static void logentry_volume(disorder_eclient *c,