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.
24 struct rxpd_connection*
25 rxpd_connection_cmd_CHECK (struct rxpd_connection* self)
29 while ((line = rxpd_buffer_readline (&self->in)))
33 rxpd_buffer_printf (&self->out, "#OK:\n");
37 LLIST_FOREACH (&self->file->rules, n)
39 struct rxpd_rule* rule = (struct rxpd_rule*)n;
40 if (rule->string[0] != '#')
42 if (regexec (&rule->rx, line, 0, NULL, 0) == 0)
44 if (rule->atime != (time_t) -1)
47 rxpd_buffer_printf (&self->out, "%s\n", rule->string);
57 rxpd_buffer_printf (&self->out, "#ERROR: no such file\n");
58 rxpd_connection_delete (self);
61 if (rxpd_buffer_state (&self->in) == RXPD_OK)
62 rxpd_connection_schedule (self);
65 if (rxpd_buffer_state (&self->in) == RXPD_ERROR)
66 rxpd_buffer_printf (&self->out, "#ERROR:\n");
67 rxpd_connection_delete (self);
77 rxpd_connection_APPEND_PREPEND_helper (struct rxpd_connection* self)
81 while ((line = rxpd_buffer_readline (&self->in)))
85 struct rxpd_rule* rule;
86 rule = rxpd_rule_new (line);
90 llist_insert_tail (&self->tmp_list, &rule->node);
92 // else goto finish; /* move along, look elsewhere! This goto is not harmful and saves some code. */
96 else if (!event && !self->file)
98 rxpd_buffer_printf (&self->out, "#ERROR: no such file\n");
99 rxpd_connection_delete (self);
103 if (rxpd_buffer_state (&self->in) == RXPD_OK)
104 rxpd_connection_schedule (self);
107 // TODO should also print error when any rule compilation failed, use tmp_str to save case?
108 if (rxpd_buffer_state (&self->in) == RXPD_ERROR)
109 rxpd_buffer_printf (&self->out, "#ERROR:\n");
113 rxpd_buffer_printf (&self->out, "#OK:\n");
116 rxpd_connection_delete (self);
121 struct rxpd_connection*
122 rxpd_connection_cmd_APPEND (struct rxpd_connection* self)
124 rxpd_connection_APPEND_PREPEND_helper (self);
125 llist_insertlist_prev (&self->file->rules, &self->tmp_list);
129 struct rxpd_connection*
130 rxpd_connection_cmd_PREPEND (struct rxpd_connection* self)
132 rxpd_connection_APPEND_PREPEND_helper (self);
133 llist_insertlist_next (&self->file->rules, &self->tmp_list);
138 struct rxpd_connection*
139 rxpd_connection_cmd_REMOVE (struct rxpd_connection* self)
142 while ((line = rxpd_buffer_readline (&self->in)))
144 LLIST_FOREACH (&self->file->rules, n)
146 struct rxpd_rule* rule = (struct rxpd_rule*)n;
147 if (strcmp (rule->string, line) == 0)
149 LList tmp = llist_prev (n);
150 rxpd_rule_delete (rule);
152 rxpd_buffer_printf (&self->out, "#OK:\n");
156 rxpd_buffer_printf (&self->out, "#ERROR: line not found\n");
162 else if (!self->file)
164 rxpd_buffer_printf (&self->out, "#ERROR: no such file\n");
165 rxpd_connection_delete (self);
169 if (rxpd_buffer_state (&self->in) == RXPD_OK)
170 rxpd_connection_schedule (self);
173 if (rxpd_buffer_state (&self->in) == RXPD_ERROR)
174 rxpd_buffer_printf (&self->out, "#ERROR:\n");
175 rxpd_connection_delete (self);
183 rxpd_connection_do_REPLACE (struct rxpd_connection* self)
185 struct rxpd_rule* rule;
187 LLIST_FOREACH (&self->file->rules, n)
189 rule = (struct rxpd_rule*)n;
190 if (strcmp (rule->string, self->tmp_str) == 0)
195 llist_insertlist_next (&rule->node, &self->tmp_list);
196 rxpd_rule_delete (rule);
197 free (self->tmp_str);
198 self->tmp_str = NULL;
202 struct rxpd_connection*
203 rxpd_connection_cmd_REPLACE (struct rxpd_connection* self)
206 while ((line = rxpd_buffer_readline (&self->in)))
212 struct rxpd_rule* rule;
213 rule = rxpd_rule_new (line);
217 llist_insert_tail (&self->tmp_list, &rule->node);
219 /* TODO handle empty lines? */
222 self->tmp_str = rxpd_strdup (line);
226 else if (!self->file)
228 rxpd_buffer_printf (&self->out, "#ERROR: no such file\n");
229 rxpd_connection_delete (self);
233 if (rxpd_buffer_state (&self->in) == RXPD_OK)
234 rxpd_connection_schedule (self);
237 if (rxpd_buffer_state (&self->in) == RXPD_ERROR)
238 rxpd_buffer_printf (&self->out, "#ERROR:\n");
243 rxpd_connection_delete (self);
246 if (rxpd_connection_do_REPLACE (self))
247 rxpd_buffer_printf (&self->out, "#OK:\n");
249 rxpd_buffer_printf (&self->out, "#ERROR: rule matching '%s'\n", self->tmp_str);
253 struct rxpd_connection*
254 rxpd_connection_cmd_LOAD (struct rxpd_connection* self)
258 if (rxpd_file_load (self->file))
260 rxpd_buffer_printf (&self->out, "#OK:\n");
264 rxpd_buffer_printf (&self->out, "#ERROR: loading file '%s'\n", (const char*)self->file->node.key);
268 rxpd_buffer_printf (&self->out, "#ERROR: no such file\n");
272 struct rxpd_connection*
273 rxpd_connection_cmd_SAVE (struct rxpd_connection* self)
277 if (rxpd_file_save (self->file))
279 rxpd_buffer_printf (&self->out, "#OK:\n");
283 rxpd_buffer_printf (&self->out, "#ERROR: saving file '%s'\n", (const char*)self->file->node.key);
287 rxpd_buffer_printf (&self->out, "#ERROR: no such file\n");
291 struct rxpd_connection*
292 rxpd_connection_cmd_DELETE (struct rxpd_connection* self)
296 rxpd_file_delete (self->file);
297 rxpd_buffer_printf (&self->out, "#OK:\n");
302 struct rxpd_connection*
303 rxpd_connection_cmd_FETCH (struct rxpd_connection* self)
305 struct rxpd_base* base = self->socket->base;
308 line = rxpd_buffer_readline (&self->in);
311 rxpd_file_rules_delete (self->file);
313 char* list = strrchr (line, '/');
314 // TODO error handling
316 rxpd_die ("syntax error");
321 char* port = strrchr (line, ':');
322 // TODO error handling / unix domain sockets
324 rxpd_die ("syntax error");
329 struct addrinfo* addrs = NULL;
332 aierr = getaddrinfo (line, port, NULL, &addrs);
334 rxpd_log (base, LOG_INFO, "fetching list '%s' from '%s(%s)' at port '%s' to '%s'\n",
337 inet_ntoa (((struct sockaddr_in*)addrs->ai_addr)->sin_addr),
339 self->file->node.key);
342 rxpd_die ("resolv error %s\n", gai_strerror (aierr));
346 // add recieving event
348 freeaddrinfo (addrs);
353 else if (!self->file)
355 rxpd_buffer_printf (&self->out, "#ERROR: no such file\n");
356 rxpd_connection_delete (self);
360 if (!event && rxpd_buffer_state (&self->in) == RXPD_OK)
361 rxpd_connection_schedule (self);
366 struct rxpd_connection*
367 rxpd_connection_cmd_DUMP (struct rxpd_connection* self)
370 if (!event && !self->file)
372 rxpd_buffer_printf (&self->out, "#ERROR: no such file\n");
373 rxpd_connection_delete (self);
378 if (llist_is_empty (&self->file->rules))
379 rxpd_buffer_printf (&self->out, "#OK:\n");
382 LLIST_FOREACH (&self->file->rules, n)
384 struct rxpd_rule* rule = (struct rxpd_rule*)n;
385 if (rule->atime != (time_t)-1)
386 rxpd_buffer_printf (&self->out, "%ld:%s\n", rule->atime, rule->string);
387 else if (*rule->string != '#')
388 rxpd_buffer_printf (&self->out, ":%s\n", rule->string);
390 rxpd_buffer_printf (&self->out, "%s\n", rule->string);
397 static psplay_delete_t
398 walk_LIST (PSplay node, const enum psplay_order_e which, int level, void* data)
401 struct rxpd_file* file = (struct rxpd_file*) node;
402 struct rxpd_connection* conn = (struct rxpd_connection*) data;
404 if (which == PSPLAY_INORDER)
405 rxpd_buffer_printf (&conn->out, "%s\n", file->node.key);
411 struct rxpd_connection*
412 rxpd_connection_cmd_LIST (struct rxpd_connection* self)
414 struct rxpd_base* base = self->socket->base;
416 if (psplay_isempty_root (&base->files))
417 rxpd_buffer_printf (&self->out, "#OK:\n");
419 psplay_walk (&base->files, NULL, walk_LIST, 0, self);
423 struct rxpd_connection*
424 rxpd_connection_cmd_SHUTDOWN (struct rxpd_connection* self)
426 //struct rxpd_base* base = self->socket->base;
427 // destroy all sockets
429 LLIST_WHILE_HEAD (&base->sockets, n)
431 struct rxpd_socket* socket = (struct rxpd_socket*)n;
432 rxpd_socket_delete (socket);
434 rxpd_buffer_printf (&self->out, "#OK:\n");
440 struct rxpd_connection*
441 rxpd_connection_cmd_VERSION (struct rxpd_connection* self)
443 rxpd_buffer_printf (&self->out, PACKAGE_STRING "\n#\n"
445 "# 2007, Christian Thaeter <ct@pipapo.org>\n#\n"
446 "# This is free software. You may redistribute copies of it under the terms of\n"
447 "# the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.\n"
448 "# There is NO WARRANTY, to the extent permitted by law.\n#\n"
449 "# http://www.pipapo.org/pipawiki/RegexPolicyDaemon\n");
453 struct rxpd_connection*
454 rxpd_connection_cmd_HELP (struct rxpd_connection* self)
456 //struct rxpd_base* base = self->socket->base;
457 rxpd_buffer_printf (&self->out, "# Available commands:\n#\n");
458 #define RXPD_CMD(cmd, help) rxpd_buffer_printf (&self->out, "# %s %s.\n", #cmd, help);
461 rxpd_buffer_printf (&self->out, "#\n# general syntax is: 'COMMAND:listname\\n..data..'\n");
465 struct rxpd_connection*
466 rxpd_connection_cmd_EXPIRE (struct rxpd_connection* self)
468 struct rxpd_base* base = self->socket->base;
471 while ((line = rxpd_buffer_readline (&self->in)))
475 time_t since = time (NULL) - atoi (line);
476 rxpd_log (base, LOG_INFO, "expire all entries in '%s' since %ld\n",
477 (const char*) self->file->node.key, since);
479 LLIST_FOREACH (&self->file->rules, n)
481 struct rxpd_rule* rule = (struct rxpd_rule*)n;
482 if (rule->atime != -1 && rule->atime < since)
485 rxpd_log (base, LOG_DEBUG, "expiring %ld:%s\n", rule->atime, rule->string);
486 rxpd_buffer_printf (&self->out, "#OK: expiring '%s'\n", rule->string);
487 rxpd_rule_delete (rule);
492 rxpd_buffer_printf (&self->out, "#OK:\n");
498 else if (!self->file)
500 rxpd_buffer_printf (&self->out, "#ERROR: no such file\n");
501 rxpd_connection_delete (self);
505 if (rxpd_buffer_state (&self->in) == RXPD_OK)
506 rxpd_connection_schedule (self);
509 if (rxpd_buffer_state (&self->in) == RXPD_ERROR)
510 rxpd_buffer_printf (&self->out, "#ERROR:\n");
511 rxpd_connection_delete (self);
518 struct rxpd_connection*
519 rxpd_connection_cmd_ (struct rxpd_connection* ptr)
523 struct rxpd_connection* self = (struct rxpd_connection*) ptr;
524 struct rxpd_base* base = self->socket->base;
525 rxpd_die ("Unimplemented\n");