1 /*
2  * (GNU Serveez 0.2.1) libserveez.h
3  *
4  * Copyright (C) 2011-2012, 2013 Thien-Thi Nguyen
5  * Copyright (C) 2000-2003  Stefan Jahn <stefan@lkcc.org>
6  * Copyright (C)      2002  Andreas Rottmann <a.rottmann@gmx.at>
7  * Copyright (C) 2000-2001  Raimund Jacob <raimi@lkcc.org>
8  * Copyright (C)      1999  Martin Grabmueller <mgrabmue@cs.tu-berlin.de>
9  *
10  * This is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 3, or (at your option)
13  * any later version.
14  *
15  * This software is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this package.  If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 #ifndef __LIBSERVEEZ_H__
25 #define __LIBSERVEEZ_H__ 1
26 
27 /* (svzconfig) */
28 /* Define to 1 if you have the <winsock2.h> header file.  */
29 /* #undef SVZ_HAVE_WINSOCK2_H */
30 
31 /* Define to 1 if you have the <arpa/inet.h> header file.  */
32 #define SVZ_HAVE_ARPA_INET_H 1
33 
34 /* Define to 1 if you have the <netinet/in.h> header file.  */
35 #define SVZ_HAVE_NETINET_IN_H 1
36 
37 /* Define to 'int' if <winsock2.h> does not define 'HANDLE'.  */
38 #define svz_t_handle int
39 
40 /* Define to 'int' if <winsock2.h> does not define 'SOCKET'.  */
41 #define svz_t_socket int
42 
43 /* Make CygWin / MinGW32 use large FD sets.  */
44 /* #undef FD_SETSIZE */
45 
46 /* Define for faster code generation.  */
47 /* #undef WIN32_LEAN_AND_MEAN */
48 
49 /* Define if you are using Windows Socket-API (not CYGWIN).  */
50 /* #undef Win32_Winsock */
51 
52 
53 /* (defines) */
54 
55 /* System headers: standard ones unconditional;
56    the rest only ‘#ifdef SVZ_HAVE_HEADER_H’ .. ‘#endif’.  */
57 
58 #include <stdio.h>
59 #include <stdlib.h>
60 #include <stdint.h>
61 
62 #ifdef SVZ_HAVE_WINSOCK2_H
63 #include <winsock2.h>
64 #endif
65 
66 #ifdef SVZ_HAVE_ARPA_INET_H
67 #include <arpa/inet.h>
68 #endif
69 
70 #ifdef SVZ_HAVE_NETINET_IN_H
71 #include <netinet/in.h>
72 #endif
73 
74 
75 /* ‘__BEGIN_DECLS’ should be used at the beginning of your declarations,
76    so that C++ compilers don't mangle their names.  Use ‘__END_DECLS’ at
77    the end of C declarations.  */
78 
79 #undef __BEGIN_DECLS
80 #undef __END_DECLS
81 #ifdef __cplusplus
82 # define __BEGIN_DECLS extern "C" {
83 # define __END_DECLS }
84 #else
85 # define __BEGIN_DECLS
86 # define __END_DECLS
87 #endif
88 
89 /* ‘SERVEEZ_API’ is a macro prepended to all function and data definitions
90    which should be exported or imported in the resulting dynamic link
91    library in the Win32 port.  */
92 
93 #if defined (__SERVEEZ_IMPORT__)
94 # define SERVEEZ_API __declspec (dllimport) extern
95 #elif defined (__SERVEEZ_EXPORT__) || defined (DLL_EXPORT)
96 # define SERVEEZ_API __declspec (dllexport) extern
97 #else
98 # define SERVEEZ_API extern
99 #endif
100 
101 
102 /* (address) */
103 
104 typedef struct svz_address svz_address_t;
105 
106 __BEGIN_DECLS
107 
108 SERVEEZ_API svz_address_t *svz_address_make (int family, const void *bits);
109 SERVEEZ_API int svz_address_family (const svz_address_t *addr);
110 SERVEEZ_API int svz_address_to (void *dest, const svz_address_t *addr);
111 SERVEEZ_API int svz_address_same (const svz_address_t *a,
112                                   const svz_address_t *b);
113 SERVEEZ_API const char *svz_pp_address (char *buf, size_t size,
114                                         const svz_address_t *addr);
115 SERVEEZ_API const char *svz_pp_addr_port (char *buf, size_t size,
116                                           const svz_address_t *addr,
117                                           in_port_t port);
118 SERVEEZ_API svz_address_t *svz_address_copy (const svz_address_t *addr);
119 
120 __END_DECLS
121 
122 
123 /* Idioms.  */
124 
125 /**
126  * Expand to a series of commands.  First, if @var{place} is
127  * non-@code{NULL}, then @code{svz_free} it.  Next, assign to
128  * @var{place} a new address object made by calling
129  * @code{svz_address_make} with @var{family} and @var{bits}.
130  */
131 #define SVZ_SET_ADDR(place,family,bits)  do             \
132     {                                                   \
133       if (place)                                        \
134         svz_free (place);                               \
135       place = svz_address_make (family, bits);          \
136     }                                                   \
137   while (0)
138 
139 /**
140  * Expand to a call to @code{svz_pp_address}, passing it
141  * @var{buf} and @code{sizeof @var{buf}}, in addition to @var{addr}.
142  */
143 #define SVZ_PP_ADDR(buf,addr)                   \
144   svz_pp_address (buf, sizeof buf, addr)
145 
146 /**
147  * Expand to a call to @code{svz_pp_addr_port}, passing it
148  * @var{buf} and @code{sizeof @var{buf}}, in addition to
149  * @var{addr} and @var{port}.
150  */
151 #define SVZ_PP_ADDR_PORT(buf,addr,port)                 \
152   svz_pp_addr_port (buf, sizeof buf, addr, port)
153 
154 
155 /* (boot) */
156 
157 /* Runtime parameters.  */
158 #define SVZ_RUNPARM_VERBOSITY    0
159 #define SVZ_RUNPARM_MAX_SOCKETS  1
160 
161 __BEGIN_DECLS
162 
163 SERVEEZ_API const char * const * svz_library_features (size_t *);
164 SERVEEZ_API void svz_boot (char const *);
165 SERVEEZ_API long svz_uptime (void);
166 SERVEEZ_API int svz_runparm (int, int);
167 SERVEEZ_API void svz_halt (void);
168 
169 __END_DECLS
170 
171 /**
172  * Return the value of runtime parameter @var{nick}.
173  */
174 #define SVZ_RUNPARM(nick)                       \
175   svz_runparm (-1, SVZ_RUNPARM_ ## nick)
176 
177 /**
178  * Set the runtime paramater @var{nick}
179  * to have value @var{val}, an integer.
180  */
181 #define SVZ_RUNPARM_X(nick,val)                 \
182   svz_runparm (SVZ_RUNPARM_ ## nick, (val))
183 
184 
185 /* (alloc) */
186 
187 __BEGIN_DECLS
188 
189 /* Function type definitions.  */
190 typedef void * (* svz_malloc_func_t) (size_t);
191 typedef void * (* svz_realloc_func_t) (void *, size_t);
192 typedef void (* svz_free_func_t) (void *);
193 
194 /* Global allocator functions.  */
195 SERVEEZ_API void svz_set_mm_funcs (svz_malloc_func_t,
196                                    svz_realloc_func_t,
197                                    svz_free_func_t);
198 
199 /* Internal allocator functions.  */
200 SERVEEZ_API void *svz_malloc (size_t);
201 SERVEEZ_API void *svz_calloc (size_t);
202 SERVEEZ_API void *svz_realloc (void *, size_t);
203 SERVEEZ_API void svz_free (void *);
204 SERVEEZ_API char *svz_strdup (const char *);
205 
206 
207 SERVEEZ_API void svz_get_curalloc (size_t *);
208 
209 __END_DECLS
210 
211 
212 /* (array) */
213 
214 typedef struct svz_array svz_array_t;
215 
216 __BEGIN_DECLS
217 
218 SERVEEZ_API svz_array_t *svz_array_create (size_t, svz_free_func_t);
219 SERVEEZ_API void svz_array_destroy (svz_array_t *);
220 SERVEEZ_API void *svz_array_get (svz_array_t *, size_t);
221 SERVEEZ_API void *svz_array_set (svz_array_t *, size_t, void *);
222 SERVEEZ_API void svz_array_add (svz_array_t *, void *);
223 SERVEEZ_API void *svz_array_del (svz_array_t *, size_t);
224 SERVEEZ_API size_t svz_array_size (svz_array_t *);
225 
226 __END_DECLS
227 
228 /**
229  * Expand into a @code{for}-statement header, for iterating over
230  * @var{array}.  On each cycle, @var{value} is assigned to successive
231  * elements of @var{array}, and @var{i} the element's position.
232  */
233 #define svz_array_foreach(array, value, i)                      \
234   for ((i) = 0, (value) = svz_array_get ((array), 0);           \
235        (array) && (i) < svz_array_size (array);                 \
236        ++(i), (value) = svz_array_get ((array), (i)))
237 
238 
239 /* (hash) */
240 
241 typedef struct svz_hash_entry svz_hash_entry_t;
242 typedef struct svz_hash_bucket svz_hash_bucket_t;
243 typedef struct svz_hash svz_hash_t;
244 
245 typedef void (svz_hash_do_t) (void *, void *, void *);
246 
247 __BEGIN_DECLS
248 
249 /*
250  * Basic hash table functions.
251  */
252 SERVEEZ_API svz_hash_t *svz_hash_create (size_t, svz_free_func_t);
253 SERVEEZ_API svz_hash_t *
254 svz_hash_configure (svz_hash_t *hash,
255                     size_t (* keylen) (const char *),
256                     unsigned long (* code) (const char *),
257                     int (* equals) (const char *, const char *));
258 SERVEEZ_API void svz_hash_destroy (svz_hash_t *);
259 SERVEEZ_API void *svz_hash_delete (svz_hash_t *, const char *);
260 SERVEEZ_API void *svz_hash_put (svz_hash_t *, const char *, void *);
261 SERVEEZ_API void *svz_hash_get (const svz_hash_t *, const char *);
262 SERVEEZ_API void svz_hash_foreach (svz_hash_do_t *, svz_hash_t *, void *);
263 SERVEEZ_API size_t svz_hash_size (const svz_hash_t *);
264 SERVEEZ_API char *svz_hash_contains (const svz_hash_t *, void *);
265 SERVEEZ_API int svz_hash_exists (const svz_hash_t *, char *);
266 
267 __END_DECLS
268 
269 
270 /* (util) */
271 
272 /*
273  * level of server's verbosity:
274  * 0 - only fatal error messages
275  * 1 - error messages
276  * 2 - warnings
277  * 3 - informational messages
278  * 4 - debugging output
279  * levels always imply numerically lesser levels
280  */
281 #define SVZ_LOG_FATAL     0
282 #define SVZ_LOG_ERROR     1
283 #define SVZ_LOG_WARNING   2
284 #define SVZ_LOG_NOTICE    3
285 #define SVZ_LOG_DEBUG     4
286 
287 __BEGIN_DECLS
288 
289 
290 SERVEEZ_API void svz_log (int, const char *, ...);
291 SERVEEZ_API void svz_log_setfile (FILE *);
292 SERVEEZ_API int svz_hexdump (FILE *, char *, int, char *, int, int);
293 SERVEEZ_API char *svz_itoa (unsigned int);
294 SERVEEZ_API unsigned int svz_atoi (char *);
295 SERVEEZ_API char *svz_getcwd (void);
296 SERVEEZ_API int svz_openfiles (int);
297 SERVEEZ_API char *svz_time (long);
298 SERVEEZ_API char *svz_tolower (char *);
299 SERVEEZ_API char *svz_sys_version (void);
300 
301 SERVEEZ_API int svz_socket_unavailable_error_p (void);
302 
303 SERVEEZ_API const char *svz_sys_strerror (void);
304 SERVEEZ_API void svz_log_sys_error (char const *, ...);
305 SERVEEZ_API void svz_log_net_error (char const *, ...);
306 
307 
308 SERVEEZ_API int svz_mingw_at_least_nt4_p (void);
309 
310 __END_DECLS
311 
312 
313 /* (socket) */
314 
315 /* Do not write more than this many bytes to a socket at once.  */
316 #define SVZ_SOCK_MAX_WRITE    1024
317 
318 
319 #define SVZ_SOFLG_INIT        0x00000000 /* Value for initializing.  */
320 #define SVZ_SOFLG_INBUF       0x00000001 /* Outbuf is allocated.  */
321 #define SVZ_SOFLG_OUTBUF      0x00000002 /* Inbuf is allocated.  */
322 #define SVZ_SOFLG_CONNECTED   0x00000004 /* Socket is connected.  */
323 #define SVZ_SOFLG_LISTENING   0x00000008 /* Socket is listening.  */
324 #define SVZ_SOFLG_KILLED      0x00000010 /* Socket will be shut down soon.  */
325 #define SVZ_SOFLG_NOFLOOD     0x00000020 /* Flood protection off.  */
326 #define SVZ_SOFLG_INITED      0x00000040 /* Socket was initialized.  */
327 #define SVZ_SOFLG_ENQUEUED    0x00000080 /* Socket is on socket queue.  */
328 #define SVZ_SOFLG_RECV_PIPE   0x00000100 /* Receiving pipe is active.  */
329 #define SVZ_SOFLG_SEND_PIPE   0x00000200 /* Sending pipe is active.  */
330 #define SVZ_SOFLG_FILE        0x00000400 /* Socket is no socket, but file.  */
331 #define SVZ_SOFLG_COSERVER    0x00000800 /* Socket is a coserver */
332 #define SVZ_SOFLG_SOCK        0x00001000 /* Socket is a plain socket.  */
333 /* Socket is no socket, but pipe.  */
334 #define SVZ_SOFLG_PIPE \
335   ( SVZ_SOFLG_RECV_PIPE | \
336     SVZ_SOFLG_SEND_PIPE )
337 #define SVZ_SOFLG_CONNECTING  0x00002000 /* Socket is still connecting */
338 #define SVZ_SOFLG_PRIORITY    0x00004000 /* Enqueue socket preferred.  */
339 #define SVZ_SOFLG_FIXED       0x00008000 /* Dedicated UDP connection.  */
340 #define SVZ_SOFLG_FINAL_WRITE 0x00010000 /* Disconnect as soon as send
341                                             queue is empty.  */
342 #define SVZ_SOFLG_READING     0x00020000 /* Pending read operation.  */
343 #define SVZ_SOFLG_WRITING     0x00040000 /* Pending write operation.  */
344 #define SVZ_SOFLG_FLUSH       0x00080000 /* Flush receive and send queue.  */
345 #define SVZ_SOFLG_NOSHUTDOWN  0x00100000 /* Disable shutdown.  */
346 #define SVZ_SOFLG_NOOVERFLOW  0x00200000 /* Disable receive buffer overflow.  */
347 
348 typedef struct svz_socket svz_socket_t;
349 
350 struct svz_socket
351 {
352   svz_socket_t *next;           /* Next socket in chain.  */
353   svz_socket_t *prev;           /* Previous socket in chain.  */
354 
355   int id;                       /* Unique ID for this socket.  */
356   int version;                  /* Socket version */
357   int parent_id;                /* A sockets parent ID.  */
358   int parent_version;           /* A sockets parent version.  */
359   int referrer_id;              /* Referring socket ID.  */
360   int referrer_version;         /* Referring socket version.  */
361 
362   int proto;                    /* Server/Protocol flag.  */
363   int flags;                    /* One of the SVZ_SOFLG_* flags above.  */
364   int userflags;                /* Can be used for protocol specific flags.  */
365   svz_t_socket sock_desc;       /* Socket descriptor.  */
366   int file_desc;                /* Used for files descriptors.  */
367   svz_t_handle pipe_desc[2];    /* Used for the pipes and coservers.  */
368   svz_t_handle pid;             /* Process id.  */
369 
370 #ifdef __MINGW32__
371   LPOVERLAPPED overlap[2];      /* Overlap info for WinNT.  */
372   int recv_pending;             /* Number of pending read bytes.  */
373   int send_pending;             /* Number of pending write bytes.  */
374 #endif /* not __MINGW32__ */
375 
376   char *recv_pipe;              /* File of the receive pipe.  */
377   char *send_pipe;              /* File of the send pipe.  */
378 
379   char *boundary;               /* Packet boundary.  */
380   int boundary_size;            /* Packet boundary length */
381 
382   /* The following items always MUST be in network byte order.  */
383   in_port_t remote_port;        /* Port number of remote end.  */
384   svz_address_t *remote_addr;   /* IP address of remote end.  */
385   in_port_t local_port;         /* Port number of local end.  */
386   svz_address_t *local_addr;    /* IP address of local end.  */
387 
388   char *send_buffer;            /* Buffer for outbound data.  */
389   char *recv_buffer;            /* Buffer for inbound data.  */
390   int send_buffer_size;         /* Size of SEND_BUFFER.  */
391   int recv_buffer_size;         /* Size of RECV_BUFFER.  */
392   int send_buffer_fill;         /* Valid bytes in SEND_BUFFER.  */
393   int recv_buffer_fill;         /* Valid bytes in RECV_BUFFER.  */
394 
395   uint16_t sequence;            /* Currently received sequence.  */
396   uint16_t send_seq;            /* Send stream sequence number.  */
397   uint16_t recv_seq;            /* Receive stream sequence number.  */
398   uint8_t itype;                /* ICMP message type.  */
399 
400   /*
401    * READ_SOCKET gets called whenever data is available on the socket.
402    * Normally, this is set to a default function which reads all available
403    * data from the socket and feeds it to CHECK_REQUEST, but specific
404    * sockets may need another policy.
405    */
406   int (* read_socket) (svz_socket_t *sock);
407 
408   /*
409    * READ_SOCKET_OOB is run when urgent data has been detected on the
410    * socket.  By default it reads a single byte, stores it in OOB and passes
411    * it to the CHECK_REQUEST_OOB callback.
412    */
413   int (* read_socket_oob) (svz_socket_t *sock);
414 
415   /*
416    * WRITE_SOCKET is called when data is is valid in the output buffer
417    * and the socket gets available for writing.  Normally, this simply
418    * writes as much data as possible to the socket and removes it from
419    * the buffer.
420    */
421   int (* write_socket) (svz_socket_t *sock);
422 
423   /*
424    * DISCONNECTED_SOCKET gets called whenever the socket is lost for
425    * some external reason.
426    */
427   int (* disconnected_socket) (svz_socket_t *sock);
428 
429   /*
430    * CONNECTED_SOCKET gets called whenever the socket is finally
431    * connected.
432    */
433   int (* connected_socket) (svz_socket_t *sock);
434 
435   /*
436    * KICKED_SOCKET gets called whenever the socket gets closed by us.
437    */
438   int (* kicked_socket) (svz_socket_t *sock, int reason);
439 
440   /*
441    * CHECK_REQUEST gets called whenever data was read from the socket.
442    * Its purpose is to check whether a complete request was read, and
443    * if it was, it should be handled and removed from the input buffer.
444    */
445   int (* check_request) (svz_socket_t *sock);
446 
447   /*
448    * CHECK_REQUEST_OOB is called when urgent data has been read from the
449    * socket.  The received byte is stored in OOB.
450    */
451   int (* check_request_oob) (svz_socket_t *sock);
452 
453   /*
454    * HANDLE_REQUEST gets called when the CHECK_REQUEST got
455    * a valid packet.
456    */
457   int (* handle_request) (svz_socket_t *sock, char *request, int len);
458 
459   /*
460    * CHILD_DIED is called when the PID stored in the socket structure
461    * equals the one signaled by the internal signal handler.
462    */
463   int (* child_died) (svz_socket_t *sock);
464 
465   /*
466    * Called if TRIGGER_COND returned non-zero.
467    */
468   int (* trigger_func) (svz_socket_t *sock);
469 
470   /*
471    * TRIGGER_COND is called once every server loop.  If it returns
472    * non-zero TRIGGER_FUNC is run.
473    */
474   int (* trigger_cond) (svz_socket_t *sock);
475 
476   /*
477    * IDLE_FUNC gets called from the periodic task scheduler.  Whenever
478    * IDLE_COUNTER (see below) is non-zero, it is decremented and
479    * IDLE_FUNC gets called when it drops to zero.  IDLE_FUNC can reset
480    * IDLE_COUNTER to some value and thus can re-schedule itself for a
481    * later task.
482    */
483   int (* idle_func) (svz_socket_t * sock);
484 
485   int idle_counter;             /* Counter for calls to IDLE_FUNC.  */
486 
487   long last_send;               /* Timestamp of last send to socket.  */
488   long last_recv;               /* Timestamp of last receive from socket */
489 
490   /* Note: These two are used only if flood protection is enabled.  */
491   int flood_points;             /* Accumulated flood points.  */
492   int flood_limit;              /* Limit of the above before kicking.  */
493 
494   /* Out-of-band data for TCP protocol.  This byte is used for both,
495      receiving and sending.  */
496   uint8_t oob;
497 
498   /* Set to non-zero @code{time} value if the the socket is temporarily
499      unavailable (EAGAIN).  This is why we use O_NONBLOCK socket descriptors.  */
500   int unavailable;
501 
502   /* Miscellaneous field.  Listener keeps array of server instances here.
503      This array is NULL terminated.  */
504   void *data;
505 
506   /* When the final protocol detection has been done this should get the
507      actual configuration hash.  */
508   void *cfg;
509 
510   /* Port configuration of a parent (listener).  */
511   void *port;
512 
513   /* Codec data pointers.  Yet another extension.  */
514   void *recv_codec;
515   void *send_codec;
516 };
517 
518 __BEGIN_DECLS
519 
520 typedef void (svz_sock_prefree_fn) (const svz_socket_t *);
521 SERVEEZ_API void svz_sock_prefree (int addsub, svz_sock_prefree_fn fn);
522 SERVEEZ_API int svz_sock_nconnections (void);
523 SERVEEZ_API int svz_sock_write (svz_socket_t *, char *, int);
524 SERVEEZ_API int svz_sock_printf (svz_socket_t *, const char *, ...);
525 SERVEEZ_API int svz_sock_resize_buffers (svz_socket_t *, int, int);
526 SERVEEZ_API int svz_sock_check_request (svz_socket_t *);
527 SERVEEZ_API int svz_wait_if_unavailable (svz_socket_t *, unsigned int);
528 SERVEEZ_API void svz_sock_reduce_recv (svz_socket_t *, int);
529 SERVEEZ_API void svz_sock_reduce_send (svz_socket_t *, int);
530 
531 __END_DECLS
532 
533 
534 /* (core) */
535 
536 /* protocol definitions */
537 #define SVZ_PROTO_TCP   0x00000001 /* tcp  - bidirectional, reliable */
538 #define SVZ_PROTO_UDP   0x00000002 /* udp  - multidirectional, unreliable */
539 #define SVZ_PROTO_PIPE  0x00000004 /* pipe - unidirectional, reliable */
540 #define SVZ_PROTO_ICMP  0x00000008 /* icmp - multidirectional, unreliable */
541 #define SVZ_PROTO_RAW   0x00000010 /* raw  - multidirectional, unreliable */
542 
543 /* Silence the "declared inside parameter list" warning.  */
544 struct stat;
545 
546 __BEGIN_DECLS
547 
548 SERVEEZ_API int svz_fd_cloexec (int);
549 SERVEEZ_API int svz_tcp_cork (svz_t_socket, int);
550 SERVEEZ_API int svz_tcp_nodelay (svz_t_socket, int, int *);
551 SERVEEZ_API int svz_closesocket (svz_t_socket);
552 SERVEEZ_API char *svz_inet_ntoa (in_addr_t);
553 SERVEEZ_API int svz_inet_aton (char *, struct sockaddr_in *);
554 SERVEEZ_API int svz_sendfile (int, int, off_t *, size_t);
555 SERVEEZ_API int svz_open (const char *, int, mode_t);
556 SERVEEZ_API int svz_close (int);
557 SERVEEZ_API int svz_fstat (int, struct stat *);
558 SERVEEZ_API FILE *svz_fopen (const char *, const char *);
559 SERVEEZ_API int svz_fclose (FILE *);
560 
561 
562 __END_DECLS
563 
564 
565 /* (pipe-socket) */
566 
567 #define SVZ_READ   0                    /* read pipe index */
568 #define SVZ_WRITE  1                    /* write pipe index */
569 
570 /*
571  * Definition of a named pipe.
572  */
573 typedef struct svz_pipe
574 {
575   char *name;        /* name of named pipe */
576   mode_t perm;       /* user and group permissions */
577   char *user;        /* user name */
578   uid_t uid;         /* user id (calculated from user name) */
579   gid_t pgid;        /* primary group id */
580   char *group;       /* group name */
581   gid_t gid;         /* group id (calculated from group name) */
582 }
583 svz_pipe_t;
584 
585 __BEGIN_DECLS
586 
587 SERVEEZ_API svz_socket_t *svz_pipe_create (svz_t_handle,
588                                            svz_t_handle);
589 SERVEEZ_API int svz_pipe_create_pair (svz_t_handle pipe_desc[2]);
590 SERVEEZ_API svz_socket_t *svz_pipe_connect (svz_pipe_t *,
591                                             svz_pipe_t *);
592 
593 SERVEEZ_API void svz_invalidate_handle (svz_t_handle *);
594 SERVEEZ_API int svz_invalid_handle_p (svz_t_handle);
595 SERVEEZ_API int svz_closehandle (svz_t_handle);
596 
597 __END_DECLS
598 
599 
600 /* (portcfg) */
601 
602 /* Port configuration items.  */
603 #define SVZ_PORTCFG_ANY   "any"
604 #define SVZ_PORTCFG_NOIP  "*"
605 
606 
607 /* Return values for port configuration comparisons.  */
608 #define SVZ_PORTCFG_NOMATCH  0x0001
609 #define SVZ_PORTCFG_EQUAL    0x0002
610 #define SVZ_PORTCFG_MATCH    0x0004
611 #define SVZ_PORTCFG_CONFLICT 0x0008
612 
613 /*
614  * Definition of a single port configuration reflecting either a network
615  * (TCP, UDP, ICMP or RAW) or filesystem configuration (PIPE).
616  */
617 typedef struct svz_portcfg
618 {
619   /* the symbolic name of this port configuration */
620   char *name;
621 
622   /* one of the PROTO_ flags defined in <core.h> */
623   int proto;
624 
625   /* one of PORTCFG_FLAG_ flags */
626   int flags;
627 
628   /* unified structure for each type of port */
629   union protocol_t
630   {
631     /* tcp port */
632     struct tcp_t
633     {
634       in_port_t port;          /* TCP/IP port */
635       char *ipaddr;            /* dotted decimal or "*" for any address */
636       struct sockaddr_in addr; /* converted from the above 2 values */
637       char *device;            /* network device */
638       int backlog;             /* backlog argument for ‘listen’ */
639     } tcp;
640 
641     /* udp port */
642     struct udp_t
643     {
644       in_port_t port;          /* UDP port */
645       char *ipaddr;            /* dotted decimal or "*" */
646       struct sockaddr_in addr; /* converted from the above 2 values */
647       char *device;            /* network device */
648     } udp;
649 
650     /* icmp port */
651     struct icmp_t
652     {
653       char *ipaddr;            /* dotted decimal or "*" */
654       struct sockaddr_in addr; /* converted from the above value */
655       char *device;            /* network device */
656       uint8_t type;            /* message type */
657     } icmp;
658 
659     /* raw ip port */
660     struct raw_t
661     {
662       char *ipaddr;            /* dotted decimal or "*" */
663       struct sockaddr_in addr; /* converted from the above value */
664       char *device;            /* network device */
665     } raw;
666 
667     /* pipe port */
668     struct pipe_t
669     {
670       svz_pipe_t recv;         /* pipe for sending data into serveez */
671       svz_pipe_t send;         /* pipe serveez sends responses out on */
672     } pipe;
673   }
674   protocol;
675 
676   /* maximum number of bytes for protocol identification */
677   int detection_fill;
678 
679   /* maximum seconds for protocol identification */
680   int detection_wait;
681 
682   /* initial buffer sizes */
683   int send_buffer_size;
684   int recv_buffer_size;
685 
686   /* allowed number of connects per second (hammer protection) */
687   int connect_freq;
688 
689   /* remembers connect frequency for each ip */
690   svz_hash_t *accepted;
691 
692   /* denied and allowed access list (ip based) */
693   svz_array_t *deny;
694   svz_array_t *allow;
695 }
696 svz_portcfg_t;
697 
698 /*
699  * Accessor definitions for each type of protocol.
700  */
701 #define SVZ_CFG_TCP(portcfg,x)     (portcfg->protocol.tcp.x)
702 #define SVZ_CFG_UDP(portcfg,x)     (portcfg->protocol.udp.x)
703 #define SVZ_CFG_ICMP(portcfg,x)    (portcfg->protocol.icmp.x)
704 #define SVZ_CFG_RAW(portcfg,x)     (portcfg->protocol.raw.x)
705 #define SVZ_CFG_PIPE(portcfg,x)    (portcfg->protocol.pipe.x)
706 
707 __BEGIN_DECLS
708 
709 SERVEEZ_API struct sockaddr_in *svz_portcfg_addr (svz_portcfg_t *);
710 SERVEEZ_API char *svz_portcfg_ipaddr (svz_portcfg_t *);
711 SERVEEZ_API char *svz_portcfg_device (svz_portcfg_t *);
712 SERVEEZ_API in_port_t svz_portcfg_port (svz_portcfg_t *);
713 
714 SERVEEZ_API svz_portcfg_t *svz_portcfg_create (void);
715 SERVEEZ_API int svz_portcfg_equal (svz_portcfg_t *, svz_portcfg_t *);
716 SERVEEZ_API svz_portcfg_t *svz_portcfg_add (char *, svz_portcfg_t *);
717 SERVEEZ_API svz_portcfg_t *svz_portcfg_get (char *);
718 SERVEEZ_API void svz_portcfg_destroy (svz_portcfg_t *);
719 SERVEEZ_API int svz_portcfg_mkaddr (svz_portcfg_t *);
720 SERVEEZ_API svz_portcfg_t *svz_portcfg_dup (svz_portcfg_t *);
721 
722 __END_DECLS
723 
724 
725 /* (cfg) */
726 
727 /*
728  * Each server can have a an array of key-value-pairs specific for it.
729  * Use macros at end of this file for setting up these.
730  */
731 typedef struct svz_key_value_pair
732 {
733   int type;        /* data type (string, integer, etc.) */
734   char *name;      /* variable name (symbol) */
735   int defaultable; /* set if this item is defaultable */
736   void *address;   /* memory address of the variable */
737 }
738 svz_key_value_pair_t;
739 
740 /*
741  * This structure defines callbacks for the (internal) server configuration
742  * function.  Each of these have the following arguments:
743  * instance: might be the name of the instance to configure
744  * arg:     an optional argument (e.g. scheme cell), supplied by user
745  * name:    the symbolic name of the configuration item
746  * target:  target address of the configuration item
747  * hasdef:  is there a default value
748  * def:     the default value for this configuration item
749  *
750  * The 'before' and 'after' callbacks are called just before and after
751  * other options are set.  The user is supposed to emit error messages since
752  * the library cannot guess what went wrong.
753  * Both callbacks have to return @code{SVZ_ITEM_OK} to allow the configure
754  * function to complete successfully.  No other callback is invoked when
755  * the 'before' callback fails.
756  *
757  * Default values and the @var{hasdef} flag are passed to callbacks for
758  * no sane reason.  You do not need to care about them if you set
759  * appropriate return values.  If you use them, however, everything that
760  * is a pointer needs to be copied.
761  */
762 
763 #define SVZ_ITEM_OK             0 /* okay, value set */
764 #define SVZ_ITEM_DEFAULT        1 /* use default, be silent if missing */
765 #define SVZ_ITEM_DEFAULT_ERRMSG 2 /* use default, croak if missing */
766 #define SVZ_ITEM_FAILED         3 /* error, error messages already emitted */
767 #define SVZ_ITEM_FAILED_ERRMSG  4 /* error, please report error */
768 
769 typedef struct
770 {
771   int (* before)   (char *instance, void *arg);
772   int (* integer)  (char *instance, void *arg, char *name,
773                     int *target, int hasdef, int def);
774   int (* boolean)  (char *instance, void *arg, char *name,
775                     int *target, int hasdef, int def);
776   int (* intarray) (char *instance, void *arg, char *name,
777                     svz_array_t **target, int hasdef, svz_array_t *def);
778   int (* string)   (char *instance, void *arg, char *name,
779                     char **target, int hasdef, char *def);
780   int (* strarray) (char *instance, void *arg, char *name,
781                     svz_array_t **target, int hasdef, svz_array_t *def);
782   int (* hash)     (char *instance, void *arg, char *name,
783                     svz_hash_t **target, int hasdef, svz_hash_t *def);
784   int (* portcfg)  (char *instance, void *arg, char *name,
785                     svz_portcfg_t **target, int hasdef, svz_portcfg_t *def);
786   int (* after)    (char *instance, void *arg);
787 }
788 svz_config_accessor_t;
789 
790 typedef struct
791 {
792   /* description of the configuration prototype */
793   char *description;
794   /* start of example structure */
795   void *start;
796   /* size of the above structure */
797   int size;
798   /* array of key-value-pairs of configuration items */
799   svz_key_value_pair_t *items;
800 }
801 svz_config_prototype_t;
802 
803 /* Constants for the @var{defaultable} argument.  */
804 #define SVZ_ITEM_DEFAULTABLE     1
805 #define SVZ_ITEM_NOTDEFAULTABLE  0
806 
807 /* Configuration item identifiers.  */
808 #define SVZ_ITEM_END      0
809 #define SVZ_ITEM_INT      1
810 #define SVZ_ITEM_INTARRAY 2
811 #define SVZ_ITEM_STR      3
812 #define SVZ_ITEM_STRARRAY 4
813 #define SVZ_ITEM_HASH     5
814 #define SVZ_ITEM_PORTCFG  6
815 #define SVZ_ITEM_BOOL     7
816 
817 /**
818  * Expand to a data structure that properly associates the example
819  * configuration @var{config} with the name @var{description} and its
820  * configuration items @var{prototypes}, for use within a server type
821  * definition.
822  */
823 #define SVZ_CONFIG_DEFINE(description, config, prototypes) \
824   { description, &(config), sizeof (config), (prototypes) }
825 
826 /*
827  * Returns a text representation of the given configuration item
828  * identifier @var{item}.
829  */
830 #define SVZ_ITEM_TEXT(item)                                  \
831   ((item) == SVZ_ITEM_INT) ? "integer" :                     \
832   ((item) == SVZ_ITEM_INTARRAY) ? "integer array" :          \
833   ((item) == SVZ_ITEM_STR) ? "string" :                      \
834   ((item) == SVZ_ITEM_STRARRAY) ? "string array" :           \
835   ((item) == SVZ_ITEM_HASH) ? "hash table" :                 \
836   ((item) == SVZ_ITEM_BOOL) ? "boolean" :                    \
837   ((item) == SVZ_ITEM_PORTCFG) ? "port configuration" : NULL
838 
839 /**
840  * Register a simple integer.  C-type: @code{int}.  The given @var{name}
841  * specifies the symbolic name of the integer and @var{item} the integer
842  * itself (not its address).  The @var{defaultable} argument can be either
843  * @code{SVZ_ITEM_DEFAULTABLE} or @code{SVZ_ITEM_NOTDEFAULTABLE}.
844  */
845 #define SVZ_REGISTER_INT(name, item, defaultable) \
846   { SVZ_ITEM_INT, (name), (defaultable), &(item) }
847 
848 /**
849  * Register an array of integers.  C-type: @code{svz_array_t *}.
850  */
851 #define SVZ_REGISTER_INTARRAY(name, item, defaultable) \
852   { SVZ_ITEM_INTARRAY, (name), (defaultable), &(item) }
853 
854 /**
855  * Register a boolean value.  C-type: @code{int}.
856  */
857 #define SVZ_REGISTER_BOOL(name, item, defaultable) \
858   { SVZ_ITEM_BOOL, (name), (defaultable), &(item) }
859 
860 /**
861  * Register a simple character string.  C-type: @code{char *}.
862  */
863 #define SVZ_REGISTER_STR(name, item, defaultable) \
864   { SVZ_ITEM_STR, (name), (defaultable), &(item) }
865 
866 /**
867  * Register a string array.  C-type: @code{svz_array_t *}.
868  */
869 #define SVZ_REGISTER_STRARRAY(name, item, defaultable) \
870   { SVZ_ITEM_STRARRAY, (name), (defaultable), &(item) }
871 
872 /**
873  * Register a hash table associating strings with strings only.  C-type:
874  * @code{svz_hash_t *}.
875  */
876 #define SVZ_REGISTER_HASH(name, item, defaultable) \
877   { SVZ_ITEM_HASH, (name), (defaultable), &(item) }
878 
879 /**
880  * Register a port configuration.  C-type: @code{svz_portcfg_t *}.
881  */
882 #define SVZ_REGISTER_PORTCFG(name, item, defaultable) \
883   { SVZ_ITEM_PORTCFG, (name), (defaultable), &(item) }
884 
885 /**
886  * Indicate the end of the list of configuration items.  It is
887  * the only mandatory item you need to specify in an example server type
888  * configuration.
889  */
890 #define SVZ_REGISTER_END() \
891   { SVZ_ITEM_END, NULL, SVZ_ITEM_DEFAULTABLE, NULL }
892 
893 #define SVZ_INTARRAY  0
894 #define SVZ_STRARRAY  1
895 #define SVZ_STRHASH   2
896 
897 __BEGIN_DECLS
898 
899 SERVEEZ_API void svz_config_free (svz_config_prototype_t *, void *);
900 SERVEEZ_API int svz_config_type_instantiate (char *, char *,
901                                              char *, void *,
902                                              svz_config_accessor_t *,
903                                              size_t, char *);
904 SERVEEZ_API void *svz_collect (int, size_t, void *);
905 
906 __END_DECLS
907 
908 #define __SVZ_COLLECT(nick,ctype,cvar)                                  \
909   svz_collect (SVZ_ ## nick, sizeof (cvar) / sizeof (ctype), cvar)
910 
911 /**
912  * Return an integer array @code{svz_array_t *}
913  * created from @code{int @var{cvar}[]}.
914  */
915 #define SVZ_COLLECT_INTARRAY(cvar)  __SVZ_COLLECT (INTARRAY, int, cvar)
916 
917 /**
918  * Return a string array @code{svz_array_t *}
919  * created from @code{char *@var{cvar}[]}.
920  */
921 #define SVZ_COLLECT_STRARRAY(cvar)  __SVZ_COLLECT (STRARRAY, char *, cvar)
922 
923 /**
924  * Return a string hash @code{svz_hash_t *}
925  * created from @code{char *@var{cvar}[]}.
926  */
927 #define SVZ_COLLECT_STRHASH(cvar)  __SVZ_COLLECT (STRHASH, char *, cvar)
928 
929 
930 /* (server) */
931 
932 typedef struct svz_servertype svz_servertype_t;
933 typedef struct svz_server svz_server_t;
934 
935 /*
936  * Each server instance gets such a structure.
937  */
938 struct svz_server
939 {
940   /* one of the PROTO_ flags defined in <core.h> */
941   int proto;
942   /* variable name in configuration language, used to identify it */
943   char *name;
944   /* server description */
945   char *description;
946   /* configuration structure for this instance */
947   void *cfg;
948   /* pointer to this server instances server type */
949   svz_servertype_t *type;
950   /* arbitrary data field */
951   void *data;
952 
953   /* init of instance */
954   int (* init) (svz_server_t *);
955   /* protocol detection */
956   int (* detect_proto) (svz_server_t *, svz_socket_t *);
957   /* what to do if detected */
958   int (* connect_socket) (svz_server_t *, svz_socket_t *);
959   /* finalize this instance */
960   int (* finalize) (svz_server_t *);
961   /* return client info */
962   char * (* info_client) (svz_server_t *, svz_socket_t *);
963   /* return server info */
964   char * (* info_server) (svz_server_t *);
965   /* server timer */
966   int (* notify) (svz_server_t *);
967   /* server reset callback */
968   int (* reset) (svz_server_t *);
969   /* packet processing */
970   int (* handle_request) (svz_socket_t *, char *, int);
971 };
972 
973 /*
974  * Every type (class) of server is completely defined by the following
975  * structure.
976  */
977 struct svz_servertype
978 {
979   /* full descriptive name */
980   char *description;
981   /* variable prefix (short name) as used in configuration */
982   char *prefix;
983 
984   /* run once per server definition */
985   int (* global_init) (svz_servertype_t *);
986   /* per server instance callback */
987   int (* init) (svz_server_t *);
988   /* protocol detection routine */
989   int (* detect_proto) (svz_server_t *, svz_socket_t *);
990   /* for accepting a client (tcp or pipe only) */
991   int (* connect_socket) (svz_server_t *, svz_socket_t *);
992   /* per instance */
993   int (* finalize) (svz_server_t *);
994   /* per server definition */
995   int (* global_finalize) (svz_servertype_t *);
996   /* return client info */
997   char * (* info_client) (svz_server_t *, svz_socket_t *);
998   /* return server info */
999   char * (* info_server) (svz_server_t *);
1000   /* server timer */
1001   int (* notify) (svz_server_t *);
1002   /* server reset */
1003   int (* reset) (svz_server_t *);
1004   /* packet processing */
1005   int (* handle_request) (svz_socket_t *, char *, int);
1006 
1007   /* configuration prototype */
1008   svz_config_prototype_t config_prototype;
1009 };
1010 
1011 
1012 typedef int (svz_servertype_do_t) (const svz_servertype_t *, void *);
1013 typedef void (svz_server_do_t) (svz_server_t *, void *);
1014 
1015 __BEGIN_DECLS
1016 
1017 SERVEEZ_API int svz_foreach_servertype (svz_servertype_do_t *, void *);
1018 SERVEEZ_API void svz_foreach_server (svz_server_do_t *, void *);
1019 SERVEEZ_API svz_server_t *svz_server_get (char *);
1020 SERVEEZ_API svz_server_t *svz_server_find (void *);
1021 SERVEEZ_API svz_array_t *svz_server_clients (svz_server_t *);
1022 SERVEEZ_API int svz_updn_all_servers (int);
1023 
1024 SERVEEZ_API void svz_servertype_add (svz_servertype_t *);
1025 SERVEEZ_API svz_servertype_t *svz_servertype_get (char *, int);
1026 SERVEEZ_API svz_servertype_t *svz_servertype_find (svz_server_t *);
1027 
1028 __END_DECLS
1029 
1030 
1031 /* (binding) */
1032 
1033 
1034 __BEGIN_DECLS
1035 
1036 SERVEEZ_API int svz_server_bind (svz_server_t *, svz_portcfg_t *);
1037 SERVEEZ_API svz_array_t *svz_server_portcfgs (svz_server_t *);
1038 SERVEEZ_API svz_array_t *svz_server_listeners (svz_server_t *);
1039 SERVEEZ_API svz_array_t *svz_sock_servers (svz_socket_t *);
1040 SERVEEZ_API int svz_binding_contains_server (svz_socket_t *,
1041                                              svz_server_t *);
1042 SERVEEZ_API size_t svz_pp_server_bindings (char *, size_t, svz_server_t *);
1043 
1044 __END_DECLS
1045 
1046 
1047 /* (tcp-socket) */
1048 
1049 __BEGIN_DECLS
1050 
1051 SERVEEZ_API svz_socket_t *svz_tcp_connect (svz_address_t *, in_port_t);
1052 SERVEEZ_API int svz_tcp_read_socket (svz_socket_t *);
1053 SERVEEZ_API int svz_tcp_send_oob (svz_socket_t *);
1054 
1055 __END_DECLS
1056 
1057 
1058 /* (udp-socket) */
1059 
1060 /* The maximum size of a UDP packet.  */
1061 #define SVZ_UDP_MSG_SIZE  (64 * 1024)
1062 
1063 /* Space for 4 messages.  */
1064 #define SVZ_UDP_BUF_SIZE  (4 * (SVZ_UDP_MSG_SIZE + 24))
1065 
1066 __BEGIN_DECLS
1067 
1068 SERVEEZ_API svz_socket_t *svz_udp_connect (svz_address_t *, in_port_t);
1069 SERVEEZ_API int svz_udp_write (svz_socket_t *, char *, int);
1070 
1071 __END_DECLS
1072 
1073 
1074 /* (icmp-socket) */
1075 
1076 /* Serveez-ICMP types and sub-codes.  */
1077 #define SVZ_ICMP_SERVEEZ        42
1078 #define SVZ_ICMP_SERVEEZ_DATA    0
1079 #define SVZ_ICMP_SERVEEZ_REQ     1
1080 #define SVZ_ICMP_SERVEEZ_ACK     2
1081 #define SVZ_ICMP_SERVEEZ_CLOSE   3
1082 #define SVZ_ICMP_SERVEEZ_CONNECT 4
1083 
1084 __BEGIN_DECLS
1085 
1086 SERVEEZ_API svz_socket_t *svz_icmp_connect (svz_address_t *, in_port_t, uint8_t);
1087 SERVEEZ_API int svz_icmp_send_control (svz_socket_t *, uint8_t);
1088 SERVEEZ_API int svz_icmp_write (svz_socket_t *, char *, int);
1089 
1090 __END_DECLS
1091 
1092 
1093 /* (server-core) */
1094 
1095 
1096 
1097 typedef int (svz_socket_do_t) (svz_socket_t *, void *);
1098 
1099 __BEGIN_DECLS
1100 
1101 SERVEEZ_API int svz_foreach_socket (svz_socket_do_t *, void *);
1102 SERVEEZ_API svz_socket_t *svz_sock_find (int, int);
1103 SERVEEZ_API int svz_sock_schedule_for_shutdown (svz_socket_t *);
1104 SERVEEZ_API int svz_sock_enqueue (svz_socket_t *);
1105 SERVEEZ_API void svz_sock_setparent (svz_socket_t *, svz_socket_t *);
1106 SERVEEZ_API svz_socket_t *svz_sock_getparent (svz_socket_t *);
1107 SERVEEZ_API void svz_sock_setreferrer (svz_socket_t *, svz_socket_t *);
1108 SERVEEZ_API svz_socket_t *svz_sock_getreferrer (svz_socket_t *);
1109 SERVEEZ_API svz_portcfg_t *svz_sock_portcfg (svz_socket_t *);
1110 
1111 SERVEEZ_API int svz_shutting_down_p (void);
1112 SERVEEZ_API void svz_loop_pre (void);
1113 SERVEEZ_API void svz_loop_post (void);
1114 SERVEEZ_API void svz_loop (void);
1115 SERVEEZ_API void svz_loop_one (void);
1116 
1117 __END_DECLS
1118 
1119 
1120 /* (coserver/coserver) */
1121 
1122 /*
1123  * Every invoked internal coserver has got such a structure.
1124  * It contains all the data it needs to run properly.
1125  */
1126 typedef struct
1127 {
1128 #ifdef __MINGW32__
1129 
1130   /* Win32 specific part.  */
1131   CRITICAL_SECTION sync;        /* critical section handle */
1132   HANDLE thread;                /* the thread handle for access */
1133   DWORD tid;                    /* internal thread id */
1134 
1135 #else /* not __MINGW32__ */
1136 
1137   /* Unix specific part.  */
1138   int pid;                      /* process id */
1139 
1140 #endif /* not __MINGW32__ */
1141 
1142   char * (* callback) (char *); /* callback routine, blocking...  */
1143   svz_socket_t *sock;           /* socket structure for this coserver */
1144   int type;                     /* coserver type id */
1145   int busy;                     /* is this thread currently busy?  */
1146 }
1147 svz_coserver_t;
1148 
1149 
1150 /*
1151  * This structure holds a socket's ‘.id’ and ‘.version’ information,
1152  * created by ‘svz_make_sock_iv’ to be later fed (by the callback) to
1153  * ‘svz_sock_find’.  The callback should ‘svz_free’ it afterwards.
1154  */
1155 typedef struct
1156 {
1157   int id;
1158   int version;
1159 }
1160 svz_sock_iv_t;
1161 
1162 /*
1163  * The callback structure is used to finally execute some code
1164  * which should be called whenever one of the coservers produces
1165  * any data for the server.
1166  */
1167 typedef int (* svz_coserver_handle_result_t) (char *, void *);
1168 
1169 typedef struct
1170 {
1171   svz_coserver_handle_result_t handle_result; /* any code callback */
1172   void *closure;                              /* opaque to libserveez */
1173 }
1174 svz_coserver_callback_t;
1175 
1176 /*
1177  * Types of internal servers you can start as threads or processes.
1178  * coserver-TODO:
1179  * add your coserver identification here and increase SVZ_MAX_COSERVER_TYPES
1180  */
1181 #define SVZ_COSERVER_REVERSE_DNS 0 /* reverse DNS lookup ID */
1182 #define SVZ_COSERVER_IDENT       1 /* identification ID */
1183 #define SVZ_COSERVER_DNS         2 /* DNS lookup ID */
1184 #define SVZ_MAX_COSERVER_TYPES   3 /* number of different coservers */
1185 
1186 typedef int (svz_coserver_do_t) (const svz_coserver_t *, void *);
1187 
1188 __BEGIN_DECLS
1189 
1190 SERVEEZ_API svz_sock_iv_t *svz_make_sock_iv (svz_socket_t *);
1191 SERVEEZ_API int svz_foreach_coserver (svz_coserver_do_t *, void *);
1192 SERVEEZ_API void svz_coserver_check (void);
1193 SERVEEZ_API int svz_updn_all_coservers (int);
1194 SERVEEZ_API void svz_coserver_destroy (int);
1195 SERVEEZ_API svz_coserver_t *svz_coserver_create (int);
1196 SERVEEZ_API const char *svz_coserver_type_name (const svz_coserver_t *);
1197 
1198 /*
1199  * These are the three wrappers for our existing coservers.
1200  */
1201 SERVEEZ_API void svz_coserver_rdns_invoke (svz_address_t *,
1202                                            svz_coserver_handle_result_t,
1203                                            void *);
1204 
1205 SERVEEZ_API void svz_coserver_dns_invoke (char *,
1206                                           svz_coserver_handle_result_t,
1207                                           void *);
1208 
1209 SERVEEZ_API void svz_coserver_ident_invoke (svz_socket_t *,
1210                                             svz_coserver_handle_result_t,
1211                                             void *);
1212 
1213 __END_DECLS
1214 
1215 
1216 /* (interface) */
1217 
1218 /*
1219  * Structure for collecting IP interfaces.
1220  */
1221 typedef struct svz_interface
1222 {
1223   size_t index;         /* interface index */
1224   char *description;    /* interface description */
1225   svz_address_t *addr;  /* address */
1226   int detected;         /* interface flag */
1227 }
1228 svz_interface_t;
1229 
1230 typedef int (svz_interface_do_t) (const svz_interface_t *, void *);
1231 
1232 __BEGIN_DECLS
1233 
1234 SERVEEZ_API int svz_foreach_interface (svz_interface_do_t *, void *);
1235 SERVEEZ_API int svz_interface_add (size_t, char *, int, const void *, int);
1236 
1237 __END_DECLS
1238 
1239 
1240 /* (dynload) */
1241 
1242 __BEGIN_DECLS
1243 
1244 SERVEEZ_API void svz_dynload_path_set (svz_array_t *);
1245 SERVEEZ_API svz_array_t *svz_dynload_path_get (void);
1246 
1247 __END_DECLS
1248 
1249 
1250 /* (passthrough) */
1251 
1252 /* Structure containing a system independent environment.  */
1253 typedef struct
1254 {
1255   int size;     /* Number of environment entries.  */
1256   char **entry; /* Environment entries in the format "VAR=VALUE".  */
1257   char *block;  /* Temporary environment block.  */
1258 }
1259 svz_envblock_t;
1260 
1261 /* Definitions for the @var{user} argument of @code{svz_sock_process}.  */
1262 #define SVZ_PROCESS_NONE  ((char *) 0L)
1263 #define SVZ_PROCESS_OWNER ((char *) ~0L)
1264 
1265 __BEGIN_DECLS
1266 
1267 SERVEEZ_API int svz_sock_process (svz_socket_t *, char *, char *,
1268                                   char **, svz_envblock_t *, int,
1269                                   char *);
1270 #ifdef __MINGW32__
1271 SERVEEZ_API int svz_mingw_child_dead_p (char *, svz_t_handle *);
1272 #endif
1273 SERVEEZ_API int svz_most_recent_dead_child_p (svz_t_handle);
1274 SERVEEZ_API void svz_envblock_setup (void);
1275 SERVEEZ_API svz_envblock_t *svz_envblock_create (void);
1276 SERVEEZ_API int svz_envblock_default (svz_envblock_t *);
1277 SERVEEZ_API int svz_envblock_add (svz_envblock_t *, char *, ...);
1278 SERVEEZ_API void svz_envblock_destroy (svz_envblock_t *);
1279 SERVEEZ_API void * svz_envblock_get (svz_envblock_t *);
1280 
1281 __END_DECLS
1282 
1283 
1284 /* (codec/codec) */
1285 
1286 /* Modes of operation.  */
1287 #define SVZ_CODEC_INIT   0x0001
1288 #define SVZ_CODEC_FLUSH  0x0002
1289 #define SVZ_CODEC_RESET  0x0004
1290 #define SVZ_CODEC_FINISH 0x0008
1291 #define SVZ_CODEC_CODE   0x0010
1292 
1293 /* Return values of the codec callbacks.  */
1294 #define SVZ_CODEC_OK       0x0001
1295 #define SVZ_CODEC_FINISHED 0x0002
1296 #define SVZ_CODEC_ERROR    0x0004
1297 #define SVZ_CODEC_MORE_OUT 0x0008
1298 #define SVZ_CODEC_MORE_IN  0x0010
1299 
1300 /* Internal state of a codec.  */
1301 #define SVZ_CODEC_NONE  0x0000
1302 #define SVZ_CODEC_READY 0x0001
1303 
1304 /* Codec types.  */
1305 #define SVZ_CODEC_ENCODER 0x0001
1306 #define SVZ_CODEC_DECODER 0x0002
1307 
1308 typedef struct svz_codec svz_codec_t;
1309 typedef struct svz_codec_data svz_codec_data_t;
1310 
1311 /*
1312  * General codec data structure for both encoding and encoding calls.
1313  */
1314 struct svz_codec_data
1315 {
1316   /* Current codec class.  */
1317   svz_codec_t *codec;
1318 
1319   /* Operation flags.  */
1320   int flag;
1321 
1322   /* Current state flags.  */
1323   int state;
1324 
1325   /* Input buffer description.  */
1326   char *in_buffer;
1327   int in_fill;
1328   int in_size;
1329 
1330   /* Output buffer description.  */
1331   char *out_buffer;
1332   int out_fill;
1333   int out_size;
1334 
1335   /* Configuration field (passed to each codec callback).  Could be
1336      used as compression level, algorithm, etc. indicator.  */
1337   void *config;
1338 
1339   /* Arbitrary data field.  Can be used by codec for internal data.  */
1340   void *data;
1341 
1342   /* Saved @code{check_request} callback.  Used by receiving codecs.  */
1343   int (* check_request) (svz_socket_t *sock);
1344 
1345   /* Saved @code{write_socket} callback.  Used by sending codecs.  */
1346   int (* write_socket) (svz_socket_t *sock);
1347 
1348   /* Saved @code{disconnected_socket} callback.  Used by both.  */
1349   int (* disconnected_socket) (svz_socket_t *sock);
1350 };
1351 
1352 /*
1353  * Description of a codec class.
1354  */
1355 struct svz_codec
1356 {
1357   /* Name of the codec.  Should be short descriptive name.  */
1358   char *description;
1359 
1360   /* Codec type.  */
1361   int type;
1362 
1363   /* Initializer.  */
1364   int (* init) (svz_codec_data_t *);
1365 
1366   /* Finalizer.  */
1367   int (* finalize) (svz_codec_data_t *);
1368 
1369   /* Encoding / decoding routine.  */
1370   int (* code) (svz_codec_data_t *);
1371 
1372   /* Last error description.  */
1373   char * (* error) (svz_codec_data_t *);
1374 
1375   /* Overall ratio request.  */
1376   int (* ratio) (svz_codec_data_t *, size_t *, size_t *);
1377 
1378   /* Magic detection sequence.  */
1379   char *detection;
1380 
1381   /* Length of the above detection sequence.  */
1382   int detection_size;
1383 };
1384 
1385 typedef int (svz_codec_do_t) (const svz_codec_t *, void *);
1386 
1387 __BEGIN_DECLS
1388 
1389 SERVEEZ_API int svz_foreach_codec (svz_codec_do_t *, void *);
1390 SERVEEZ_API svz_codec_t * svz_codec_get (char *, int);
1391 SERVEEZ_API int svz_codec_register (svz_codec_t *);
1392 SERVEEZ_API int svz_codec_unregister (svz_codec_t *);
1393 SERVEEZ_API int svz_codec_sock_receive_setup (svz_socket_t *,
1394                                               svz_codec_t *);
1395 SERVEEZ_API int svz_codec_sock_receive (svz_socket_t *);
1396 SERVEEZ_API int svz_codec_sock_send_setup (svz_socket_t *,
1397                                            svz_codec_t *);
1398 SERVEEZ_API int svz_codec_sock_send (svz_socket_t *);
1399 SERVEEZ_API int svz_codec_sock_disconnect (svz_socket_t *);
1400 SERVEEZ_API void svz_codec_ratio (svz_codec_t *,
1401                                   svz_codec_data_t *);
1402 SERVEEZ_API svz_codec_t * svz_codec_sock_detect (svz_socket_t *);
1403 
1404 __END_DECLS
1405 
1406 
1407 #endif /* not __LIBSERVEEZ_H__ */
1408 
1409 /* (GNU Serveez 0.2.1) libserveez.h ends here */
1410