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