DELETE command
[rxpd] / src / rxpd_connection_cmd.c
index 86262e6..9008ec2 100644 (file)
@@ -314,6 +314,23 @@ rxpd_connection_cmd_SAVE (int fd, short event, void* ptr)
     }
 }
 
+void
+rxpd_connection_cmd_DELETE (int fd, short event, void* ptr)
+{
+  (void) fd;
+  struct rxpd_connection* self = (struct rxpd_connection*) ptr;
+
+  if (!event)
+    {
+      if (self->file)
+        {
+          rxpd_file_delete (self->file);
+          rxpd_buffer_printf (&self->out, "#OK:\n");
+        }
+      rxpd_connection_delete (self);
+    }
+}
+
 void
 rxpd_connection_cmd_DUMP (int fd, short event, void* ptr)
 {
@@ -430,10 +447,52 @@ void
 rxpd_connection_cmd_EXPIRE (int fd, short event, void* ptr)
 {
   (void) fd;
-  (void) event;
   struct rxpd_connection* self = (struct rxpd_connection*) ptr;
-  //struct rxpd_base* base = self->socket->base;
-  rxpd_die ("Unimplemented\n");
+  struct rxpd_base* base = self->socket->base;
+
+  if (event == EV_READ)
+    {
+      int again = -1;
+      char* line;
+      while ((line = rxpd_buffer_readline (&self->in, ++again)))
+        {
+          if (*line)
+            {
+              time_t since = time (NULL) - atoi (line);
+              rxpd_log (base, LOG_INFO, "expire all entries in '%s' since %ld\n",
+                        (const char*) self->file->node.key, since);
+
+              LLIST_FOREACH (&self->file->rules, n)
+                {
+                  struct rxpd_rule* rule = (struct rxpd_rule*)n;
+                  if (rule->atime != -1 && rule->atime < since)
+                    {
+                      n = llist_prev (n);
+                      rxpd_log (base, LOG_DEBUG, "expiring %ld:%s\n", rule->atime, rule->string);
+                      rxpd_buffer_printf (&self->out, "#OK: expiring '%s'\n", rule->string);
+                      rxpd_rule_delete (rule);
+                    }
+                }
+            }
+          else
+            rxpd_buffer_printf (&self->out, "#OK:\n");
+        }
+    }
+  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");
+      rxpd_connection_delete (self);
+    }
 }
 
 /* Template