chiark / gitweb /
Switch to GPL v3
[disorder] / lib / eclient.c
index e7395f35456f7a4ec3bdade11e06ef6792226df6..19d8d7c04b3393bc07f8ec184fa78cd6fc9d55fd 100644 (file)
@@ -2,20 +2,18 @@
  * This file is part of DisOrder.
  * Copyright (C) 2006-2008 Richard Kettlewell
  *
- * This program is free software; you can redistribute it and/or modify
+ * 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
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 /** @file lib/eclient.c
  * @brief Client code for event-driven programs
@@ -144,6 +142,9 @@ struct disorder_eclient {
 
   /** @brief Protocol version */
   int protocol;
+
+  /** @brief True if enabled */
+  int enabled;
 };
 
 /* Forward declarations ******************************************************/
@@ -184,6 +185,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 +211,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),
@@ -232,6 +235,7 @@ disorder_eclient *disorder_eclient_new(const disorder_eclient_callbacks *cb,
   c->callbacks = cb;
   c->u = u;
   c->opstail = &c->ops;
+  c->enabled = 1;
   vector_init(&c->vec);
   dynstr_init(&c->input);
   dynstr_init(&c->output);
@@ -269,6 +273,16 @@ void disorder_eclient_close(disorder_eclient *c) {
     c->log_callbacks->state(c->log_v, c->statebits);
 }
 
+/** @brief Permit new connection activity */
+void disorder_eclient_enable_connect(disorder_eclient *c) {
+  c->enabled = 1;
+}
+
+/** @brief Suppress new connection activity */
+void disorder_eclient_disable_connect(disorder_eclient *c) {
+  c->enabled = 0;
+}
+
 /** @brief Return current state */
 unsigned long disorder_eclient_state(const disorder_eclient *c) {
   return c->statebits | (c->state > state_connected ? DISORDER_CONNECTED : 0);
@@ -338,9 +352,12 @@ void disorder_eclient_polled(disorder_eclient *c, unsigned mode) {
     /* If there is no password yet then we cannot connect */
     if(!config->password) {
       comms_error(c, "no password is configured");
+      c->enabled = 0;
       return;
     }
-    start_connect(c);
+    /* Only try to connect if enabled */
+    if(c->enabled)
+      start_connect(c);
     /* might now be state_disconnected (on error), state_connecting (slow
      * connect) or state_connected (fast connect).  If state_disconnected then
      * we just rely on a periodic callback from the event loop sometime. */
@@ -471,7 +488,7 @@ static int start_connect(disorder_eclient *c) {
   socklen_t len;
 
   D(("start_connect"));
-  if((len = find_server(&sa, &c->ident)) == (socklen_t)-1)
+  if((len = find_server(config, &sa, &c->ident)) == (socklen_t)-1)
     return comms_error(c, "cannot look up server"); /* TODO better error */
   if(c->fd != -1) {
     xclose(c->fd);
@@ -595,6 +612,7 @@ static void authuser_opcallback(disorder_eclient *c,
   if(c->rc / 100 != 2) {
     /* Wrong password or something.  We cannot proceed. */
     protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
+    c->enabled = 0;
     disorder_eclient_close(c);
     return;
   }
@@ -1447,12 +1465,18 @@ static void logline(disorder_eclient *c, const char *line) {
     return;
   }
   /* TODO: do something with the time */
+  //fprintf(stderr, "log key: %s\n", vec[1]);
   n = TABLE_FIND(logentry_handlers, name, vec[1]);
-  if(n < 0) return;                     /* probably a future command */
+  if(n < 0) {
+    //fprintf(stderr, "...not found\n");
+    return;                     /* probably a future command */
+  }
   vec += 2;
   nvec -= 2;
-  if(nvec < logentry_handlers[n].min || nvec > logentry_handlers[n].max)
+  if(nvec < logentry_handlers[n].min || nvec > logentry_handlers[n].max) {
+    //fprintf(stderr, "...wrong # args\n");
     return;
+  }
   logentry_handlers[n].handler(c, nvec, vec);
 }
 
@@ -1563,6 +1587,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;