f26d346a7b1406a9f3a15a87ee738559fb661763
[rxpd] / src / rxpd.h
1 /*
2     rxpd.h - regex policy daemon
3
4   Copyright (C)
5     2007,               Christian Thaeter <ct@pipapo.org>
6
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.
11
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.
16
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.
20 */
21 #ifndef RXPD_H
22 #define RXPD_H
23
24 #include "llist.h"
25 #include "psplay.h"
26
27 #include <errno.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <stdarg.h>
31 #include <unistd.h>
32 #include <regex.h>
33 #include <syslog.h>
34 #include <sys/stat.h>
35 #include <sys/time.h>
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #include <arpa/inet.h>
40 #include <event.h>
41 #include <pth.h>
42 #include <time.h>
43 #include <netdb.h>
44
45 #define RXPD_COMMANDS                                           \
46   RXPD_CMD(CHECK,       "data against regular expressions")     \
47   RXPD_CMD(APPEND,      "new rules to a list")                  \
48   RXPD_CMD(PREPEND,     "new rules in front of a list")         \
49   RXPD_CMD(REMOVE,      "rules from a list")                    \
50   RXPD_CMD(REPLACE,     "a rule in a list with new rules")      \
51   RXPD_CMD(DELETE,      "a list from memory")                   \
52   RXPD_CMD(LOAD,        "a list from disk")                     \
53   RXPD_CMD(SAVE,        "a list to disk")                       \
54   RXPD_CMD(FETCH,       "a list from a remote server")          \
55   RXPD_CMD(UPDATE,      "atimes from other lists")              \
56   RXPD_CMD(EXPIRE,      "aged rules from a list")               \
57   RXPD_CMD(DUMP,        "rules in a list")                      \
58   RXPD_CMD(LIST,        "all existing lists")                   \
59   RXPD_CMD(VERSION,     "of this rxpd is "PACKAGE_VERSION)      \
60   RXPD_CMD(HELP,        "is what you see right now")            \
61   RXPD_CMD(SHUTDOWN,    "the daemon")
62
63 #define RXPD_CMD(cmd, _) RXPD_CMD_##cmd,
64 enum rxpd_cmd_e {RXPD_COMMANDS};
65 #undef RXPD_CMD
66
67 /*
68  * characters which are absolutely not allowed in rule filenames
69  * for finer control use policies, note that this are arbitary
70  * decisions also reserving some chars for later extension
71  */
72 #define RXPD_FILE_ILG_CHARS "@&?<>|/: \t\n\r*?\\"
73
74 /*
75  * Call a cooperative pth_yield every this much expensive interations
76  * not implemented yet
77  * A higher number favors throughput, lower number improves latency
78  */
79 #define RXPD_YIELD_EVERY 500
80
81 struct rxpd_base;
82 struct rxpd_file;
83 struct rxpd_rule;
84 struct rxpd_socket;
85 struct rxpd_buffer;
86 struct rxpd_connection;
87
88 struct rxpd_base
89 {
90   char* basedir;
91
92   int verbosity;
93   int regflags;
94   int daemonize;
95
96   struct rxpd_file* policy;
97
98   // TODO
99   //FILE* -l log      log hits to logfile
100
101   psplayroot files;
102   llist sockets;
103 };
104
105 struct rxpd_base*
106 rxpd_init (void);
107
108 void
109 rxpd_destroy (void);
110
111 void
112 rxpd_log (struct rxpd_base*, int level, const char* fmt, ...);
113
114 void
115 rxpd_fail (struct rxpd_base*, const char* fmt, ...);
116
117 void
118 rxpd_die (const char* fmt, ...);
119
120 void*
121 rxpd_malloc (size_t size);
122
123 char*
124 rxpd_strdup (const char* str);
125
126 struct rxpd_base*
127 rxpd_set_basedir (struct rxpd_base*, const char* basedir);
128
129 //
130 struct rxpd_rule
131 {
132   llist node;
133   char* string;
134   time_t atime;
135   regex_t rx;
136 };
137
138 struct rxpd_rule*
139 rxpd_rule_new (const char* buf);
140
141 struct rxpd_rule*
142 rxpd_rule_copy (const struct rxpd_rule* src);
143
144 void
145 rxpd_rule_delete (struct rxpd_rule* self);
146
147
148
149 //
150 struct rxpd_file
151 {
152   psplay node;          // key points to basename part of filename
153   const char* filename; // full filename
154   //TODO later     struct stat last_stat;
155   struct rxpd_base* base;
156   pth_rwlock_t lock;
157   llist rules;
158 };
159
160 struct rxpd_file*
161 rxpd_file_new (struct rxpd_base* base, const char* filename);
162
163 void
164 rxpd_file_delete (struct rxpd_file* file);
165
166 struct rxpd_file*
167 rxpd_file_rules_delete (struct rxpd_file* self);
168
169 int
170 rxpd_file_load (struct rxpd_file* self);
171
172 int
173 rxpd_file_save (struct rxpd_file* self);
174
175 struct rxpd_file*
176 rxpd_file_dump (struct rxpd_file* self, struct rxpd_buffer* out);
177
178 int
179 rxpd_file_cmp (const void* A, const void* B);
180
181
182 //
183
184 struct rxpd_socket
185 {
186   llist node;
187   int fd;
188   struct event ev;
189   struct rxpd_base* base;
190   pth_t accepter;
191   int (*rxpd_socket_addr)(struct rxpd_connection* conn, char* dst, const char* pfx, size_t size);
192 };
193
194
195 struct rxpd_socket*
196 rxpd_socket_new_tcp4 (struct rxpd_base* base, const char* addr, unsigned short port);
197
198 int
199 rxpd_socket_tcp4addr (struct rxpd_connection* conn, char* dst, const char* pfx, size_t size);
200
201 //TODO
202 //struct rxpd_socket*
203 //rxpd_socket_new_unix (struct rxpd_base* base, const char* name);
204
205 void
206 rxpd_socket_delete (struct rxpd_socket* self);
207
208 void *
209 rxpd_socket_accept (void* ptr);
210
211 struct rxpd_socket*
212 rxpd_socket_spawn (struct rxpd_socket* self);
213
214 struct rxpd_socket*
215 rxpd_socket_join (struct rxpd_socket* self);
216
217 struct rxpd_socket*
218 rxpd_socket_cancel (struct rxpd_socket* self);
219
220 //
221
222 enum rxpd_buffer_state_e
223   {
224     RXPD_OK,            // operational
225     RXPD_EOF,           // connection closed
226     RXPD_ERROR          // some other error
227   };
228
229 struct rxpd_buffer
230 {
231   int fd;
232   enum rxpd_buffer_state_e state;
233   char* eol;
234   char* eob;
235   char buffer[4096];
236 };
237
238 struct rxpd_buffer*
239 rxpd_buffer_init (struct rxpd_buffer* self, int fd);
240
241 char*
242 rxpd_buffer_readline (struct rxpd_buffer* self);
243
244 int
245 rxpd_buffer_printf (struct rxpd_buffer* self, const char* fmt, ...);
246
247 inline static enum rxpd_buffer_state_e
248 rxpd_buffer_state (struct rxpd_buffer* self)
249 {
250   return self->state;
251 }
252
253
254 //
255 struct rxpd_connection
256 {
257   int fd;
258   pth_t connecter;
259   struct rxpd_file* file;
260   struct rxpd_socket* socket;
261   char* tmp_str;
262   llist tmp_list;
263
264   struct rxpd_buffer in;
265   struct rxpd_buffer out;
266 };
267
268
269 struct rxpd_connection*
270 rxpd_connection_new (struct rxpd_socket* socket, int fd);
271
272 void
273 rxpd_connection_delete (struct rxpd_connection* self);
274
275 struct rxpd_connection*
276 rxpd_connection_spawn (struct rxpd_connection* self);
277
278 int
279 rxpd_connection_readline (struct rxpd_connection* self);
280
281 int
282 rxpd_connection_check_policy (struct rxpd_connection* self, char* line);
283
284 void*
285 rxpd_connection_parse_cmd (void* ptr);
286
287 /* generate prototypes for each defined command */
288 #define RXPD_CMD(cmd, _) void rxpd_connection_cmd_##cmd (struct rxpd_connection* self);
289 RXPD_COMMANDS
290 #undef RXPD_CMD
291
292
293 #endif