/[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.8 - (show annotations)
Fri Feb 14 06:14:29 2003 UTC (21 years, 1 month ago) by andreou
Branch: MAIN
Changes since 1.7: +6 -1 lines
File MIME type: text/plain
Now uses RTLD_LAZY if RTLD_NOW is not implemented (like in OpenBSD).

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.7 2003/01/22 07:51:50 nmav 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 #warning OS does not implement RTLD_NOW, using RTLD_LAZY; it's probably safe.
110 #define RTLD_NOW RTLD_LAZY
111 #endif /* not RTLD_NOW */
112 handle = dlopen( module, RTLD_NOW);
113 if ( handle==NULL) {
114 fprintf(stderr, "Could not load module '%s'. Dlopen failed: %s\n", module, dlerror());
115 exit(1);
116 }
117 old->dl_handle = handle;
118
119
120 sym_prefix_len = strlen( sym_prefix);
121 if (sym_prefix_len + 20 > sizeof(symbol)) {
122 DIE("Symbol prefix is too long.");
123 }
124
125 /* Resolve shutdown */
126 strcpy( symbol, sym_prefix);
127 strcat( symbol, "_hic_shutdown");
128
129 old->shutdown = dlsym( handle, symbol);
130 if ( old->shutdown == NULL) {
131 fprintf(stderr, "Could not resolve %s_hic_shutdown symbol", sym_prefix);
132 exit(1);
133 }
134
135 /* Resolve init */
136 strcpy( symbol, sym_prefix);
137 strcat( symbol, "_hic_init");
138
139 old->init = dlsym( handle, symbol);
140 if ( old->init == NULL) {
141 fprintf(stderr, "Could not resolve %s_hic_init symbol", sym_prefix);
142 exit(1);
143 }
144 old->init(); /* Run the initialization stuff */
145
146 /* Resolve request */
147 strcpy( symbol, sym_prefix);
148 strcat( symbol, "_hic_request");
149
150 old->request = dlsym( handle, symbol);
151 if ( old->request == NULL) {
152 fprintf(stderr, "Could not resolve %s_hic_request symbol", sym_prefix);
153 exit(1);
154 }
155
156 module_hashtable[hash] = old;
157
158 return;
159 #endif
160 }
161
162
163 /* add_hic_action
164 *
165 * Like add_hic_module() but associates the file type with a
166 * specific action (executable to run with)
167 */
168
169 void add_hic_action(const char *action, const char* file_type)
170 {
171 int hash;
172 hic_module_st* old, *start;
173
174 /* sanity checking */
175 if (action == NULL || file_type == NULL) {
176 DIE("NULL values sent to add_hic_action");
177 }
178
179 hash = get_hic_module_hash_value( file_type);
180 start = old = module_hashtable[hash];
181
182 if ( old != NULL) {
183 /* find next empty */
184 do {
185 hash = (hash + 1) % MODULE_HASHTABLE_SIZE;
186
187 old = module_hashtable[hash];
188
189 if (start == old) {
190 DIE("Module hashtable is full.");
191 }
192
193 } while( old != NULL);
194 }
195
196 /* old was found, and is empty. */
197
198 old = malloc( sizeof(hic_module_st));
199 if (old==NULL) {
200 DIE("malloc() failed.");
201 }
202
203 old->sym_prefix = NULL;
204
205 old->content_type = strdup( file_type);
206 if (old->content_type == NULL) {
207 DIE("strdup() failed.");
208 }
209
210 old->content_type_len = strlen( file_type);
211
212 old->action = strdup( action);
213 if ( old->action == NULL) {
214 DIE("strdup() failed.");
215 }
216
217 old->dl_handle = NULL;
218 old->shutdown = NULL;
219 old->init = NULL;
220 old->request = NULL;
221
222 module_hashtable[hash] = old;
223
224 return;
225 }
226
227 /*
228 * Name: find_hic_appr_module
229 *
230 * Description: Locates the appropriate HIC module for the given file.
231 * Actually ones needs this to get the dlsymed() functions.
232 *
233 * Returns:
234 *
235 * a pointer to a hic_module_st structure or NULL if not found
236 */
237
238 hic_module_st *find_hic_appr_module(const char *content_type, int content_type_len)
239 {
240 int i, hash;
241
242 if (content_type == NULL) return NULL;
243 if (content_type_len == 0) content_type_len = strlen( content_type);
244
245 hash = get_hic_module_hash_value( content_type);
246 for (i=hash;i<MODULE_HASHTABLE_SIZE;i++) {
247 if (module_hashtable[i] == NULL) break;
248
249 if ( content_type_len != module_hashtable[i]->content_type_len) continue;
250
251 if (memcmp( content_type, module_hashtable[i]->content_type,
252 content_type_len) == 0) {
253 /* FOUND! */
254 return module_hashtable[i];
255 }
256 }
257
258 return NULL;
259
260 }
261
262
263 /*
264 * Empties the hic modules table, deallocating any allocated memory.
265 */
266
267 void dump_hic_modules(void)
268 {
269 int i;
270
271 for (i = 0; i < MODULE_HASHTABLE_SIZE; ++i) { /* these limits OK? */
272 if (!module_hashtable[i]) continue;
273
274 #ifdef ENABLE_HIC
275 free( module_hashtable[i]->sym_prefix);
276 free( module_hashtable[i]->content_type);
277
278 if (module_hashtable[i]->shutdown)
279 module_hashtable[i]->shutdown(); /* Run the deinitialization stuff */
280
281 if (module_hashtable[i]->dl_handle)
282 dlclose( module_hashtable[i]->dl_handle);
283 #endif
284
285 free( module_hashtable[i]->action);
286
287 free( module_hashtable[i]);
288 module_hashtable[i] = NULL;
289 }
290 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26