2 rxpd_connection_cmd.c - regex policy daemon
5 2007, Christian Thaeter <ct@pipapo.org>
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 rxpd_connection_cmd_CHECK (int fd, short event, void* ptr)
28 struct rxpd_connection* self = (struct rxpd_connection*) ptr;
34 while ((line = rxpd_buffer_readline (&self->in, ++again)))
38 rxpd_buffer_printf (&self->out, "#OK:\n");
42 LLIST_FOREACH (&self->file->rules, n)
44 struct rxpd_rule* rule = (struct rxpd_rule*)n;
45 if (rule->string[0] != '#')
47 if (regexec (&rule->rx, line, 0, NULL, 0) == 0)
49 rxpd_buffer_printf (&self->out, "%s\n", rule->string);
59 rxpd_buffer_printf (&self->out, "#ERROR: no such file\n");
60 rxpd_connection_delete (self);
64 if (rxpd_buffer_state (&self->in) == RXPD_OK)
65 rxpd_connection_schedule (self);
68 if (rxpd_buffer_state (&self->in) == RXPD_ERROR)
69 rxpd_buffer_printf (&self->out, "#ERROR:\n");
70 rxpd_connection_delete (self);
77 rxpd_connection_APPEND_PREPEND_helper (short event, void* ptr, int do_append)
79 struct rxpd_connection* self = (struct rxpd_connection*) ptr;
86 while ((line = rxpd_buffer_readline (&self->in, ++again)))
90 struct rxpd_rule* rule;
91 rule = rxpd_rule_new (line);
95 llist_insert_tail (&self->tmp_list, &rule->node);
97 else goto finish; /* move along, look elsewhere! This goto is not harmful and saves some code. */
100 else if (!event && !self->file)
102 rxpd_buffer_printf (&self->out, "#ERROR: no such file\n");
103 rxpd_connection_delete (self);
107 if (rxpd_buffer_state (&self->in) == RXPD_OK)
108 rxpd_connection_schedule (self);
111 // TODO should also print error when any rule compilation failed, use tmp_str to save case?
112 if (rxpd_buffer_state (&self->in) == RXPD_ERROR)
113 rxpd_buffer_printf (&self->out, "#ERROR:\n");
117 rxpd_buffer_printf (&self->out, "#OK:\n");
121 llist_insertlist_prev (&self->file->rules, &self->tmp_list);
123 llist_insertlist_next (&self->file->rules, &self->tmp_list);
124 rxpd_connection_delete (self);
129 rxpd_connection_cmd_APPEND (int fd, short event, void* ptr)
132 rxpd_connection_APPEND_PREPEND_helper (event, ptr, 1);
136 rxpd_connection_cmd_PREPEND (int fd, short event, void* ptr)
139 rxpd_connection_APPEND_PREPEND_helper (event, ptr, 0);
144 rxpd_connection_cmd_REMOVE (int fd, short event, void* ptr)
147 struct rxpd_connection* self = (struct rxpd_connection*) ptr;
149 if (event == EV_READ)
153 while ((line = rxpd_buffer_readline (&self->in, ++again)))
155 LLIST_FOREACH (&self->file->rules, n)
157 struct rxpd_rule* rule = (struct rxpd_rule*)n;
158 if (strcmp (rule->string, line) == 0)
160 LList tmp = llist_prev (n);
161 rxpd_rule_delete (rule);
163 rxpd_buffer_printf (&self->out, "#OK:\n");
167 rxpd_buffer_printf (&self->out, "#ERROR: line not found\n");
172 else if (!self->file)
174 rxpd_buffer_printf (&self->out, "#ERROR: no such file\n");
175 rxpd_connection_delete (self);
179 if (rxpd_buffer_state (&self->in) == RXPD_OK)
180 rxpd_connection_schedule (self);
183 if (rxpd_buffer_state (&self->in) == RXPD_ERROR)
184 rxpd_buffer_printf (&self->out, "#ERROR:\n");
185 rxpd_connection_delete (self);
191 rxpd_connection_do_REPLACE (struct rxpd_connection* self)
193 struct rxpd_rule* rule;
195 LLIST_FOREACH (&self->file->rules, n)
197 rule = (struct rxpd_rule*)n;
198 if (strcmp (rule->string, self->tmp_str) == 0)
203 llist_insertlist_next (&rule->node, &self->tmp_list);
204 rxpd_rule_delete (rule);
205 free (self->tmp_str);
206 self->tmp_str = NULL;
211 rxpd_connection_cmd_REPLACE (int fd, short event, void* ptr)
214 struct rxpd_connection* self = (struct rxpd_connection*) ptr;
216 if (event == EV_READ)
220 while ((line = rxpd_buffer_readline (&self->in, ++again)))
226 struct rxpd_rule* rule;
227 rule = rxpd_rule_new (line);
231 llist_insert_tail (&self->tmp_list, &rule->node);
233 /* TODO handle empty lines? */
236 self->tmp_str = rxpd_strdup (line);
239 else if (!self->file)
241 rxpd_buffer_printf (&self->out, "#ERROR: no such file\n");
242 rxpd_connection_delete (self);
246 if (rxpd_buffer_state (&self->in) == RXPD_OK)
247 rxpd_connection_schedule (self);
250 if (rxpd_buffer_state (&self->in) == RXPD_ERROR)
251 rxpd_buffer_printf (&self->out, "#ERROR:\n");
254 if (rxpd_connection_do_REPLACE (self))
255 rxpd_buffer_printf (&self->out, "#OK:\n");
257 rxpd_buffer_printf (&self->out, "#ERROR: rule matching '%s'\n", self->tmp_str);
260 rxpd_connection_delete (self);
265 rxpd_connection_cmd_LOAD (int fd, short event, void* ptr)
268 struct rxpd_connection* self = (struct rxpd_connection*) ptr;
274 if (rxpd_file_load (self->file))
276 rxpd_buffer_printf (&self->out, "#OK:\n");
280 rxpd_buffer_printf (&self->out, "#ERROR: loading file '%s'\n", (const char*)self->file->node.key);
284 rxpd_buffer_printf (&self->out, "#ERROR: no such file\n");
285 rxpd_connection_delete (self);
290 rxpd_connection_cmd_SAVE (int fd, short event, void* ptr)
293 struct rxpd_connection* self = (struct rxpd_connection*) ptr;
299 if (rxpd_file_save (self->file))
301 rxpd_buffer_printf (&self->out, "#OK:\n");
305 rxpd_buffer_printf (&self->out, "#ERROR: saving file '%s'\n", (const char*)self->file->node.key);
309 rxpd_buffer_printf (&self->out, "#ERROR: no such file\n");
310 rxpd_connection_delete (self);
315 rxpd_connection_cmd_DUMP (int fd, short event, void* ptr)
318 struct rxpd_connection* self = (struct rxpd_connection*) ptr;
320 if (!event && !self->file)
322 rxpd_buffer_printf (&self->out, "#ERROR: no such file\n");
323 rxpd_connection_delete (self);
327 if (llist_is_empty (&self->file->rules))
328 rxpd_buffer_printf (&self->out, "#OK:\n");
331 LLIST_FOREACH (&self->file->rules, n)
333 struct rxpd_rule* rule = (struct rxpd_rule*)n;
334 rxpd_buffer_printf (&self->out, "%s\n", rule->string);
338 rxpd_connection_delete (self);
342 static psplay_delete_t
343 walk_LIST (PSplay node, const enum psplay_order_e which, int level, void* data)
346 struct rxpd_file* file = (struct rxpd_file*) node;
347 struct rxpd_connection* conn = (struct rxpd_connection*) data;
349 if (which == PSPLAY_INORDER)
350 rxpd_buffer_printf (&conn->out, "%s\n", file->node.key);
357 rxpd_connection_cmd_LIST (int fd, short event, void* ptr)
361 struct rxpd_connection* self = (struct rxpd_connection*) ptr;
362 struct rxpd_base* base = self->socket->base;
364 if (psplay_isempty_root (&base->files))
365 rxpd_buffer_printf (&self->out, "#OK:\n");
367 psplay_walk (&base->files, NULL, walk_LIST, 0, ptr);
369 rxpd_connection_delete (self);
373 rxpd_connection_cmd_SHUTDOWN (int fd, short event, void* ptr)
377 struct rxpd_connection* self = (struct rxpd_connection*) ptr;
378 struct rxpd_base* base = self->socket->base;
379 // destroy all sockets
380 LLIST_WHILE_HEAD (&base->sockets, n)
382 struct rxpd_socket* socket = (struct rxpd_socket*)n;
383 rxpd_socket_delete (socket);
385 rxpd_buffer_printf (&self->out, "#OK:\n");
386 rxpd_connection_delete (self);
391 rxpd_connection_cmd_VERSION (int fd, short event, void* ptr)
395 struct rxpd_connection* self = (struct rxpd_connection*) ptr;
396 rxpd_buffer_printf (&self->out, PACKAGE_STRING "\n#\n"
398 "# 2007, Christian Thaeter <ct@pipapo.org>\n#\n"
399 "# This is free software. You may redistribute copies of it under the terms of\n"
400 "# the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.\n"
401 "# There is NO WARRANTY, to the extent permitted by law.\n#\n"
402 "# http://www.pipapo.org/pipawiki/RegexPolicyDaemon\n");
403 rxpd_connection_delete (self);
407 rxpd_connection_cmd_HELP (int fd, short event, void* ptr)
411 struct rxpd_connection* self = (struct rxpd_connection*) ptr;
412 //struct rxpd_base* base = self->socket->base;
413 rxpd_buffer_printf (&self->out, "# Available commands:\n\n");
414 #define RXPD_CMD(cmd, help) rxpd_buffer_printf (&self->out, "%s %s.\n", #cmd, help);
417 rxpd_buffer_printf (&self->out, "\n# general syntax is: 'COMMAND:listname\\n..data..'\n");
418 rxpd_connection_delete (self);
422 rxpd_connection_cmd_EXPIRE (int fd, short event, void* ptr)
426 struct rxpd_connection* self = (struct rxpd_connection*) ptr;
427 //struct rxpd_base* base = self->socket->base;
428 rxpd_die ("Unimplemented\n");
433 rxpd_connection_cmd_ (int fd, short event, void* ptr)
437 struct rxpd_connection* self = (struct rxpd_connection*) ptr;
438 struct rxpd_base* base = self->socket->base;
439 rxpd_die ("Unimplemented\n");