chiark / gitweb /
Send clients a rights-changed message when their rights change.
authorRichard Kettlewell <rjk@greenend.org.uk>
Sun, 15 Jun 2008 13:19:11 +0000 (14:19 +0100)
committerRichard Kettlewell <rjk@greenend.org.uk>
Sun, 15 Jun 2008 13:19:11 +0000 (14:19 +0100)
doc/disorder_protocol.5.in
lib/eclient.c
lib/eclient.h
server/server.c

index 367a68ab803a0128685c19abb11e92273a591bf4..85c16a25f7aaaff881f8f758da8a1e481b4b5915 100644 (file)
@@ -620,6 +620,9 @@ A track started playing.
 .B resume
 The current track was resumed.
 .TP
+.B rights-changed \fIRIGHTS\fR
+User's rights were changed.
+.TP
 .B scratched
 The current track was scratched.
 .PP
index e7395f35456f7a4ec3bdade11e06ef6792226df6..ad34a2154997e6dec160c522e4af4a542665dcb6 100644 (file)
@@ -184,6 +184,7 @@ static void logentry_user_add(disorder_eclient *c, int nvec, char **vec);
 static void logentry_user_confirm(disorder_eclient *c, int nvec, char **vec);
 static void logentry_user_delete(disorder_eclient *c, int nvec, char **vec);
 static void logentry_user_edit(disorder_eclient *c, int nvec, char **vec);
+static void logentry_rights_changed(disorder_eclient *c, int nvec, char **vec);
 
 /* Tables ********************************************************************/
 
@@ -209,6 +210,7 @@ static const struct logentry_handler logentry_handlers[] = {
   LE(recent_removed, 1, 1),
   LE(removed, 1, 2),
   LE(rescanned, 0, 0),
+  LE(rights_changed, 1, 1),
   LE(scratched, 2, 2),
   LE(state, 1, 1),
   LE(user_add, 1, 1),
@@ -1563,6 +1565,15 @@ static void logentry_user_edit(disorder_eclient *c,
     c->log_callbacks->user_edit(c->log_v, vec[0], vec[1]);
 }
 
+static void logentry_rights_changed(disorder_eclient *c,
+                                    int attribute((unused)) nvec, char **vec) {
+  if(c->log_callbacks->rights_changed) {
+    rights_type r;
+    if(parse_rights(vec[0], &r, 0/*report*/))
+      c->log_callbacks->rights_changed(c->log_v, r);
+  }
+}
+
 static const struct {
   unsigned long bit;
   const char *enable;
index 1d1b301428340f28943d62db8e93cc6ea4b66399..be5730cb5eb19367bf71f9ce361de320f0c1dacb 100644 (file)
@@ -24,6 +24,8 @@
 #ifndef ECLIENT_H
 #define ECLIENT_H
 
+#include "rights.h"
+
 /* Asynchronous client interface */
 
 /** @brief Handle type */
@@ -162,6 +164,9 @@ typedef struct disorder_eclient_log_callbacks {
 
   /** @brief Called when a user is edited (admins only) */
   void (*user_edit)(void *v, const char *user, const char *property);
+
+  /** @brief Called when your rights change */
+  void (*rights_changed)(void *v, rights_type new_rights);
 } disorder_eclient_log_callbacks;
 
 /* State bits */
index 46647b10aabb567e7d6224d4725f384aa232f940..1bfa29a05367fb4031c60f545567d07ea03a8458 100644 (file)
@@ -876,6 +876,7 @@ static void logclient(const char *msg, void *user) {
   if(!c->w || !c->r) {
     /* This connection has gone up in smoke for some reason */
     eventlog_remove(c->lo);
+    c->lo = 0;
     return;
   }
   /* user-* messages are restricted */
@@ -1244,10 +1245,21 @@ static int c_edituser(struct conn *c,
       /* Update rights for this user */
       rights_type r;
 
-      if(parse_rights(vec[2], &r, 1))
-       for(d = connections; d; d = d->next)
-         if(!strcmp(d->who, vec[0]))
+      if(!parse_rights(vec[2], &r, 1)) {
+        const char *new_rights = rights_string(r);
+       for(d = connections; d; d = d->next) {
+         if(!strcmp(d->who, vec[0])) {
+            /* Update rights */
            d->rights = r;
+            /* Notify any log connections */
+            if(d->lo)
+              sink_printf(ev_writer_sink(d->w),
+                          "%"PRIxMAX" rights-changed %s\n",
+                          (uintmax_t)time(0),
+                          new_rights);
+          }
+        }
+      }
     }
     sink_writes(ev_writer_sink(c->w), "250 OK\n");
   } else {
@@ -1762,6 +1774,7 @@ static int listen_callback(ev_source *ev,
   D(("server listen_callback fd %d (%s)", fd, l->name));
   nonblock(fd);
   cloexec(fd);
+  c->next = connections;
   c->tag = tags++;
   c->ev = ev;
   c->w = ev_writer_new(ev, fd, writer_error, c,
@@ -1773,6 +1786,7 @@ static int listen_callback(ev_source *ev,
   c->reader = reader_callback;
   c->l = l;
   c->rights = 0;
+  connections = c;
   gcry_randomize(c->nonce, sizeof c->nonce, GCRY_STRONG_RANDOM);
   sink_printf(ev_writer_sink(c->w), "231 %d %s %s\n",
              2,