/[hydra]/hydra/src/hic_modules.c
ViewVC logotype

Contents of /hydra/src/hic_modules.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (show annotations)
Tue Feb 18 18:35:27 2003 UTC (21 years, 1 month ago) by nmav
Branch: MAIN
CVS Tags: hydra_0_1_7, hydra_0_1_6, hydra_0_1_4
Changes since 1.9: +2 -2 lines
File MIME type: text/plain
changes in order to compile.

1 /*
2 * Hydra, an http server
3 * Copyright (C) 2002 Nikos Mavroyanopoulos <nmav@gnutls.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 1, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 */
20
21 /* $Id: hic_modules.c,v 1.9 2003/02/14 08:58:11 andreou Exp $ */
22
23 /* This file includes support for dynamically loaded HIC modules
24 * All modules added to module_table[] will be dlopen()ed at startup.
25 *
26 * Also hic symbols will be resolved.
27 */
28
29 #include "boa.h"
30
31 #ifdef ENABLE_HIC
32 # include <dlfcn.h>
33 #endif
34
35 /* A dynamic module, must provide three functions:
36 * void _php_hic_shutdown(void);
37 * void _php_hic_init(void);
38 * off_t _php_hic_request(hic_stuff *hc);
39 *
40 * This is from php.
41 */
42
43
44 static hic_module_st* module_hashtable[MODULE_HASHTABLE_SIZE];
45
46 /*
47 * Name: add_module
48 *
49 * Description: add an module entry
50 */
51
52 void add_hic_module(const char *module, const char* sym_prefix, const char* content_type)
53 {
54 #ifndef ENABLE_HIC
55 fprintf(stderr, "Cannot open '%s' since dynamic module opening, is not supported, "
56 "or HIC has been disabled.\n", module);
57 #else
58 char symbol[128];
59 int hash;
60 hic_module_st* old, *start;
61
62 int sym_prefix_len;
63 void * handle;
64
65 /* sanity checking */
66 if (module == NULL || sym_prefix == NULL || content_type == NULL) {
67 DIE("NULL values sent to add_module");
68 }
69
70 hash = get_hic_module_hash_value( content_type);
71 start = old = module_hashtable[hash];
72
73 if ( old != NULL) {
74 /* find next empty */
75 do {
76 hash = (hash + 1) % MODULE_HASHTABLE_SIZE;
77
78 old = module_hashtable[hash];
79
80 if (start == old) {
81 DIE("Module hashtable is full.");
82 }
83
84 } while( old != NULL);
85 }
86
87 /* old was found, and is empty. */
88
89 old = malloc( sizeof(hic_module_st));
90 if (old==NULL) {
91 DIE("malloc() failed.");
92 }
93
94 old->sym_prefix = strdup( sym_prefix);
95 if (old->sym_prefix == NULL) {
96 DIE("strdup() failed.");
97 }
98
99 old->content_type = strdup( content_type);
100 if (old->content_type == NULL) {
101 DIE("strdup() failed.");
102 }
103
104 old->content_type_len = strlen( content_type);
105
106
107 /* Handle OSs that only implement RTLD_LAZY. */
108 #ifndef RTLD_NOW
109 #ifdef __GNUC__
110 #warning "OS does not implement RTLD_NOW, using RTLD_LAZY; it's probably safe."
111 #endif /* __GNUC__ */
112 #define RTLD_NOW RTLD_LAZY
113 #endif /* not RTLD_NOW */
114 handle = dlopen( module, RTLD_NOW);
115 if ( handle==NULL) {
116 fprintf(stderr, "Could not load module '%s'. Dlopen failed: %s\n", module, dlerror());
117 exit(1);
118 }
119 old->dl_handle = handle;
120
121
122 sym_prefix_len = strlen( sym_prefix);
123 if (sym_prefix_len + 20 > sizeof(symbol)) {
124 DIE("Symbol prefix is too long.");
125 }
126
127 /* Resolve shutdown */
128 strcpy( symbol, sym_prefix);
129 strcat( symbol, "_hic_shutdown");
130
131 old->shutdown = dlsym( handle, symbol);
132 if ( old->shutdown == NULL) {
133 fprintf(stderr, "Could not resolve %s_hic_shutdown symbol", sym_prefix);
134 exit(1);
135 }
136
137 /* Resolve init */
138 strcpy( symbol, sym_prefix);
139 strcat( symbol, "_hic_init");
140
141 old->init = dlsym( handle, symbol);
142 if ( old->init == NULL) {
143 fprintf(stderr, "Could not resolve %s_hic_init symbol", sym_prefix);
144 exit(1);
145 }
146 old->init(); /* Run the initialization stuff */
147
148 /* Resolve request */
149 strcpy( symbol, sym_prefix);
150 strcat( symbol, "_hic_request");
151
152 old->request = dlsym( handle, symbol);
153 if ( old->request == NULL) {
154 fprintf(stderr, "Could not resolve %s_hic_request symbol", sym_prefix);
155 exit(1);
156 }
157
158 module_hashtable[hash] = old;
159
160 return;
161 #endif
162 }
163
164
165 /* add_hic_action
166 *
167 * Like add_hic_module() but associates the file type with a
168 * specific action (executable to run with)
169 */
170
171 void add_hic_action(const char *action, const char* file_type)
172 {
173 int hash;
174 hic_module_st* old, *start;
175
176 /* sanity checking */
177 if (action == NULL || file_type == NULL) {
178 DIE("NULL values sent to add_hic_action");
179 }
180
181 hash = get_hic_module_hash_value( file_type);
182 start = old = module_hashtable[hash];
183
184 if ( old != NULL) {
185 /* find next empty */
186 do {
187 hash = (hash + 1) % MODULE_HASHTABLE_SIZE;
188
189 old = module_hashtable[hash];
190
191 if (start == old) {
192 DIE("Module hashtable is full.");
193 }
194
195 } while( old != NULL);
196 }
197
198 /* old was found, and is empty. */
199
200 old = malloc( sizeof(hic_module_st));
201 if (old==NULL) {
202 DIE("malloc() failed.");
203 }
204
205 old->sym_prefix = NULL;
206
207 old->content_type = strdup( file_type);
208 if (old->content_type == NULL) {
209 DIE("strdup() failed.");
210 }
211
212 old->content_type_len = strlen( file_type);
213
214 old->action = strdup( action);
215 if ( old->action == NULL) {
216 DIE("strdup() failed.");
217 }
218
219 old->dl_handle = NULL;
220 old->shutdown = NULL;
221 old->init = NULL;
222 old->request = NULL;
223
224 module_hashtable[hash] = old;
225
226 return;
227 }
228
229 /*
230 * Name: find_hic_appr_module
231 *
232 * Description: Locates the appropriate HIC module for the given file.
233 * Actually ones needs this to get the dlsymed() functions.
234 *
235 * Returns:
236 *
237 * a pointer to a hic_module_st structure or NULL if not found
238 */
239
240 hic_module_st *find_hic_appr_module(const char *content_type, int content_type_len)
241 {
242 int i, hash;
243
244 if (content_type == NULL) return NULL;
245 if (content_type_len == 0) content_type_len = strlen( content_type);
246
247 hash = get_hic_module_hash_value( content_type);
248 for (i=hash;i<MODULE_HASHTABLE_SIZE;i++) {
249 if (module_hashtable[i] == NULL) break;
250
251 if ( content_type_len != module_hashtable[i]->content_type_len) continue;
252
253 if (memcmp( content_type, module_hashtable[i]->content_type,
254 content_type_len) == 0) {
255 /* FOUND! */
256 return module_hashtable[i];
257 }
258 }
259
260 return NULL;
261
262 }
263
264
265 /*
266 * Empties the hic modules table, deallocating any allocated memory.
267 */
268
269 void dump_hic_modules(void)
270 {
271 int i;
272
273 for (i = 0; i < MODULE_HASHTABLE_SIZE; ++i) { /* these limits OK? */
274 if (!module_hashtable[i]) continue;
275
276 #ifdef ENABLE_HIC
277 free( module_hashtable[i]->sym_prefix);
278 free( module_hashtable[i]->content_type);
279
280 if (module_hashtable[i]->shutdown)
281 module_hashtable[i]->shutdown(); /* Run the deinitialization stuff */
282
283 if (module_hashtable[i]->dl_handle)
284 dlclose( module_hashtable[i]->dl_handle);
285 #endif
286
287 free( module_hashtable[i]->action);
288
289 free( module_hashtable[i]);
290 module_hashtable[i] = NULL;
291 }
292 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26