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