APPEND/PREPEND commands
[rxpd] / rxpd.c
diff --git a/rxpd.c b/rxpd.c
index 702e423..2fe7b77 100644 (file)
--- a/rxpd.c
+++ b/rxpd.c
@@ -609,18 +609,67 @@ rxpd_connection_cmd_CHECK (int fd, short event, void* ptr)
     }
 }
 
+
+
+static void
+rxpd_connection_APPEND_PREPEND_helper (int fd, short event, void* ptr, int do_append)
+{
+  struct rxpd_connection* self = (struct rxpd_connection*) ptr;
+
+  if (!event)
+    llist_init (&self->tmp_list);
+
+  if (event == EV_READ)
+    {
+      int again = -1;
+      char* line;
+
+      while (line = rxpd_buffer_readline (&self->in, ++again))
+        {
+          if (*line)
+            {
+              struct rxpd_rule* rule;
+              rule = rxpd_rule_new (line);
+              if (!rule)
+                abort();
+
+              llist_insert_tail (&self->tmp_list, &rule->node);
+            }
+          else goto finish;
+        }
+    }
+
+  if (rxpd_buffer_state (&self->in) == RXPD_OK)
+    rxpd_connection_schedule (self);
+  else
+    {
+      // TODO should also print error when any rule compilation failed
+      if (rxpd_buffer_state (&self->in) == RXPD_ERROR)
+        rxpd_buffer_printf (&self->out, "#ERROR:\n");
+      else
+        {
+        finish:
+          rxpd_buffer_printf (&self->out, "#OK:\n");
+        }
+
+      if (do_append)
+        llist_insertlist_prev (&self->file->rules, &self->tmp_list);
+      else
+        llist_insertlist_next (&self->file->rules, &self->tmp_list);
+      close (fd);
+    }
+}
+
 void
 rxpd_connection_cmd_APPEND (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]);
+  rxpd_connection_APPEND_PREPEND_helper (fd, event, ptr, 1);
 }
 
 void
 rxpd_connection_cmd_PREPEND (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]);
+  rxpd_connection_APPEND_PREPEND_helper (fd, event, ptr, 0);
 }
 
 void