command REPLACE
authorChristian Thaeter <ct@pipapo.org>
Mon, 8 Oct 2007 18:01:43 +0000 (20:01 +0200)
committerChristian Thaeter <ct@pipapo.org>
Mon, 8 Oct 2007 18:01:43 +0000 (20:01 +0200)
rxpd.c

diff --git a/rxpd.c b/rxpd.c
index a1afb7e..5bb75e2 100644 (file)
--- a/rxpd.c
+++ b/rxpd.c
@@ -708,7 +708,7 @@ rxpd_connection_cmd_REMOVE (int fd, short event, void* ptr)
   else if (!self->file)
     {
       rxpd_buffer_printf (&self->out, "#ERROR: no such file\n");
-      close (fd);
+      rxpd_connection_delete (self);
       return;
     }
 
@@ -718,15 +718,85 @@ rxpd_connection_cmd_REMOVE (int fd, short event, void* ptr)
     {
       if (rxpd_buffer_state (&self->in) == RXPD_ERROR)
         rxpd_buffer_printf (&self->out, "#ERROR:\n");
-      close (fd);
+      rxpd_connection_delete (self);
     }
 }
 
+
+static int
+rxpd_connection_do_REPLACE (struct rxpd_connection* self)
+{
+  struct rxpd_rule* rule;
+
+  LLIST_FOREACH (&self->file->rules, n)
+    {
+      rule = (struct rxpd_rule*)n;
+      if (strcmp (rule->string, self->tmp_str) == 0)
+        goto found;
+    }
+  return 0;
+ found:
+  llist_insertlist_next (&rule->node, &self->tmp_list);
+  rxpd_rule_delete (rule);
+  free (self->tmp_str);
+  self->tmp_str = NULL;
+  return 1;
+}
+
 void
 rxpd_connection_cmd_REPLACE (int fd, short event, void* ptr)
 {
   struct rxpd_connection* self = (struct rxpd_connection*) ptr;
-  rxpd_buffer_printf (&self->out, "#ERROR: unimplemented command %s\n", &__func__[20]);
+
+  if (event == EV_READ)
+    {
+      int again = -1;
+      char* line;
+      while (line = rxpd_buffer_readline (&self->in, ++again))
+        {
+          if (self->tmp_str)
+            {
+              if (*line)
+                {
+                  struct rxpd_rule* rule;
+                  rule = rxpd_rule_new (line);
+                  if (!rule)
+                    abort();
+
+                  llist_insert_tail (&self->tmp_list, &rule->node);
+                }
+              /* TODO handle empty lines? */
+            }
+          else
+            {
+              self->tmp_str = strdup (line);
+              if (!self->tmp_str) abort();
+            }
+        }
+    }
+  else if (!self->file)
+    {
+      rxpd_buffer_printf (&self->out, "#ERROR: no such file\n");
+      rxpd_connection_delete (self);
+      return;
+    }
+
+  if (rxpd_buffer_state (&self->in) == RXPD_OK)
+    rxpd_connection_schedule (self);
+  else
+    {
+      if (rxpd_buffer_state (&self->in) == RXPD_ERROR)
+        rxpd_buffer_printf (&self->out, "#ERROR:\n");
+      else
+        {
+          if (rxpd_connection_do_REPLACE (self))
+            rxpd_buffer_printf (&self->out, "#OK:\n");
+          else
+            rxpd_buffer_printf (&self->out, "#ERROR: rule matching '%s'\n", self->tmp_str);
+        }
+
+      rxpd_connection_delete (self);
+    }
 }
 
 void