1 #ifndef HANDLER_H
  2 #define HANDLER_H
  3 
  4 #include <stdlib.h>
  5 #include "queue.h"
  6 
  7 enum {
  8         HANDLER_FAILURE         = -1,
  9         
 10         HANDLER_SUCCESS         =  0,
 11 
 12         HANDLER_AGAIN           =  1,
 13         
 14         HANDLER_WRITE_DATA      =  2,
 15         
 16         HANDLER_STOP            =  3,
 17 };
 18 
 19 enum {
 20         /* rewrite uri (mod_alias) or full content change (Redirect, EACCESS)
 21          * before the real file is stat()'d || after the request header was
 22          * successfully parsed */
 23         HANDLER_TYPE_REWRITE,
 24 
 25         /* content generation handlers (default file open, ssi) */
 26         HANDLER_TYPE_CONTENT,
 27 
 28         HANDLER_TYPE_ACCESSLOG,
 29         
 30         /* error handler */
 31         HANDLER_TYPE_ERROR,
 32 };
 33 
 34 typedef struct handler          handler_t;
 35 typedef struct handler_base     handler_base_t;
 36 
 37 TAILQ_HEAD(handler_list, handler);
 38 
 39 struct handler_base {
 40         struct config_base      *config;
 41         struct handler_list     handler;
 42 };
 43         
 44 struct handler {
 45         /* in which base-list  this handler is stored */
 46         
 47         struct handler_base                     *base;
 48         
 49         /* symbols for exec() etc. */
 50         const struct handler_definition         *def;
 51         
 52         /* dlopen(); only not NULL at parent handler */
 53         void                                    *library;
 54         
 55         /* NULL if its the parent, otherwise .. the parent handler */
 56         struct handler                          *parent;
 57 
 58         /* the used reference counter.
 59          * if it tends to 0 then handler_free really unloads/frees.
 60          *
 61          * destroy(data_local) is always called because this is ''per handler''
 62          * destroy(data_global) is called when the parent handler is unloaded
 63          * 
 64          */
 65         size_t                                  reference;
 66         
 67         /* local genereted data, will be free'd on handler_free() */
 68         void                                    *data_local;
 69         
 70         /* global genereted data, useable be all child handlers */
 71         void                                    *data_global;
 72 
 73         struct http_request                     *request;
 74         
 75         TAILQ_ENTRY(handler)                    list;
 76 };
 77 
 78 void handler_base_init    (handler_base_t *base, struct config_base *config);
 79 
 80 void handler_base_destroy (handler_base_t *base);
 81 
 82 int handler_base_init_handlers (handler_base_t *base);
 83 
 84 int handler_base_dup (handler_base_t *dst, const handler_base_t *src);
 85 
 86 int handler_base_remove_handlers (handler_base_t *base, int type);
 87         
 88 int handler_base_prepend_handler (handler_base_t *base,
 89                                   const handler_t *src_handler);
 90 
 91 int handler_base_append_handler (handler_base_t *base,
 92                                   const handler_t *src_handler);
 93 
 94 handler_t * handler_load (handler_base_t *base, const char *name,
 95                           const char *filename);
 96 handler_t * handler_dup  (const handler_t *src);
 97 int         handler_free (handler_t *handler);
 98 
 99 
100 
101 /*
102  *
103  * some (funny?) macros to make handler execution easier 
104  *
105  */
106 
107 #define HANDLER_CALL_EXIST(_handler,_func)              \
108         ( NULL != (_handler)->def->sym_ ## _func )
109 
110 #define HANDLER_CALL(_handler,_func)                    \
111         ( (_handler)->def->sym_ ## _func ( (_handler) ) )
112 
113 #define HANDLER_CALL_MAYBE(_handler,_func)                              \
114         ( HANDLER_CALL_EXIST(_handler,_func)                            \
115                 ?                                                       \
116                 (_handler)->def->sym_ ## _func ( (_handler) )           \
117                 :                                                       \
118                 HANDLER_SUCCESS                                         \
119         )
120 
121 
122 /*
123  *
124  * definition stuff
125  *
126  *
127  *
128  * dont call handler->def->sym_free(_global), its called in handler_free()
129  *
130  */
131 
132 struct handler_definition {
133         const char      *name;
134         int             type;
135 
136         /* setup is called after loading the module. */
137         int             (*sym_setup)            (handler_t *);
138         
139         /* init_global is called after all modules and
140          * the whole configuration file are loaded.
141          * it should be used to init handler related data structures */
142         int             (*sym_init_global)      (handler_t *);
143         
144         /* free_global is called if the whole handler is unloaded */
145         int             (*sym_free_global)      (handler_t *);
146         
147         /* init is called before exec whould be called */
148         int             (*sym_init)             (handler_t *);
149         
150         /* exec is called until it returns an error or success */
151         int             (*sym_exec)             (handler_t *);
152 
153         /* free is called if the current handler is done */
154         int             (*sym_free)             (handler_t *);
155 };
156 
157 
158 #define DECLARE_HANDLER_BEGIN(_name,_type)                      \
159         const struct handler_definition handler_ ## _name = {   \
160                 .type  = HANDLER_TYPE_ ## _type,                \
161                 .name  = #_name,
162 
163 #define DECLARE_HANDLER_END                                     \
164         };
165 
166 #define DECLARE_HANDLER_FUNCTION(_name,_func)                   \
167         int handler_ ## _name ## _ ## _func (handler_t *handler)
168 
169 #define DECLARE_HANDLER_SYMBOL(_name,_func)                     \
170         sym_ ## _func = handler_ ## _name ## _ ## _func
171 
172 #define DECLARE_HANDLER_NULL(_name,_func)                       \
173         sym_ ## _func = NULL
174 
175 #endif /* HANDLER_H */


syntax highlighted by Code2HTML, v. 0.9.1