if (*buf != '#')
{
int err;
- char* rxstart = strchr (buf, ':') + 1;
+ char* rxstart = strchr (buf, ':');
- err = regcomp (&self->rx, rxstart, REG_EXTENDED|REG_ICASE|REG_NOSUB);
-
- if (!err)
- {
- self->string = strdup (buf);
- if (!self->string) abort();
- }
+ if (!rxstart)
+ self->string = strdup ("#ERROR: Syntax error, line was neither a comment nor a rule");
else
{
- regfree (&self->rx);
- char ebuf[256];
- size_t len = regerror (err, NULL, ebuf, 256);
- self->string = malloc(len + strlen(buf) + 14);
- if (!self->string) abort();
- strcpy (self->string, "#ERROR ");
- strcat (self->string, ebuf);
- strcat (self->string, " in '");
- strcat (self->string, buf);
- strcat (self->string, "'");
+ err = regcomp (&self->rx, rxstart+1, REG_EXTENDED|REG_ICASE|REG_NOSUB);
+
+ if (!err)
+ {
+ self->string = strdup (buf);
+ if (!self->string) abort();
+ }
+ else
+ {
+ regfree (&self->rx);
+ char ebuf[256];
+ size_t len = regerror (err, NULL, ebuf, 256);
+ self->string = malloc(len + strlen(buf) + 14);
+ if (!self->string) abort();
+ strcpy (self->string, "#ERROR: ");
+ strcat (self->string, ebuf);
+ strcat (self->string, " in '");
+ strcat (self->string, buf);
+ strcat (self->string, "'");
+ }
}
}
else
if (!rule)
abort();
- printf("%s\n", rule->string);
+ printf("loaded rule '%s'\n", rule->string);
llist_insert_tail (&self->rules, &rule->node);
}
{
// rulename provided
self->file = (struct rxpd_file*) psplay_find (&self->base->files, &line[i->sz]);
+
if (!self->file)
{
+ // todo create policy?
self->file = rxpd_file_new (self->base, &line[i->sz]);
if (!self->file)
{
#define RXPD_CMD(cmd) \
case RXPD_CMD_##cmd: \
event_set (&self->ev, self->fd, EV_READ, rxpd_connection_cmd_##cmd, self); \
+ rxpd_connection_cmd_##cmd (fd, 0, ptr); \
break;
RXPD_COMMANDS
#undef RXPD_CMD
}
- rxpd_connection_schedule (self);
}
+
+
void
rxpd_connection_cmd_CHECK (int fd, short event, void* ptr)
{
struct rxpd_connection* self = (struct rxpd_connection*) ptr;
- LLIST_FOREACH (&self->file.rules, node)
-
- //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 (*line == '\0')
+ {
+ rxpd_buffer_printf (&self->out, "#OK:\n");
+ }
+ else
+ {
+ LLIST_FOREACH (&self->file->rules, n)
+ {
+ struct rxpd_rule* rule = (struct rxpd_rule*)n;
+ if (rule->string[0] != '#')
+ {
+ if (regexec (&rule->rx, line, 0, NULL, 0) == 0)
+ {
+ rxpd_buffer_printf (&self->out, "%s\n", rule->string);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ 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");
+ close (fd);
+ }
+}
+
+
+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;
- rxpd_connection_schedule (self);
+ 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
rxpd_connection_cmd_DUMP (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 (llist_is_empty (&self->file->rules))
+ rxpd_buffer_printf (&self->out, "#OK:\n");
+ else
+ {
+ LLIST_FOREACH (&self->file->rules, n)
+ {
+ struct rxpd_rule* rule = (struct rxpd_rule*)n;
+ rxpd_buffer_printf (&self->out, "%s\n", rule->string);
+ }
+ }
+
+ close (fd);
}
+
+static psplay_delete_t
+walk_LIST (PSplay node, const enum psplay_order_e which, int level, void* data)
+{
+ (void) level;
+ struct rxpd_file* file = (struct rxpd_file*) node;
+ struct rxpd_connection* conn = (struct rxpd_connection*) data;
+
+ if (which == PSPLAY_INORDER)
+ rxpd_buffer_printf (&conn->out, "%s\n", file->node.key);
+
+ return PSPLAY_CONT;
+}
+
+
void
rxpd_connection_cmd_LIST (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 (psplay_isempty_root (&self->base->files))
+ rxpd_buffer_printf (&self->out, "#OK:\n");
+ else
+ psplay_walk (&self->base->files, NULL, walk_LIST, 0, ptr);
+
+ close (fd);
}
void
rxpd_connection_cmd_SHUTDOWN (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]);
-}
+ // destroy all sockets
+ LLIST_WHILE_HEAD (&self->base->sockets_pending, n)
+ {
+ struct rxpd_socket* socket = (struct rxpd_socket*)n;
+ rxpd_socket_delete (socket);
+ }
+ LLIST_WHILE_HEAD (&self->base->sockets_active, n)
+ {
+ struct rxpd_socket* socket = (struct rxpd_socket*)n;
+ rxpd_socket_delete (socket);
+ }
+ rxpd_buffer_printf (&self->out, "#OK:\n");
+ close (fd);
+}