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

Annotation of /hydra/src/hic_modules.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (hide annotations)
Wed Jan 22 07:51:50 2003 UTC (21 years, 3 months ago) by nmav
Branch: MAIN
Changes since 1.6: +78 -6 lines
File MIME type: text/plain
merged changes from 0.1.x branch.

1 nmav 1.1 /*
2 nmav 1.4 * Hydra, an http server
3 nmav 1.1 * 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 nmav 1.7 /* $Id: hic_modules.c,v 1.6.2.3 2003/01/19 10:15:22 nmav Exp $ */
22 nmav 1.1
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 nmav 1.3 static hic_module_st* module_hashtable[MODULE_HASHTABLE_SIZE];
45 nmav 1.1
46     /*
47     * Name: add_module
48     *
49     * Description: add an module entry
50     */
51    
52 nmav 1.2 void add_hic_module(const char *module, const char* sym_prefix, const char* content_type)
53 nmav 1.1 {
54     #ifndef ENABLE_HIC
55 nmav 1.6 fprintf(stderr, "Cannot open '%s' since dynamic module opening, is not supported, "
56     "or HIC has been disabled.\n", module);
57 nmav 1.1 #else
58     char symbol[128];
59 nmav 1.2 int hash;
60     hic_module_st* old, *start;
61 nmav 1.1
62     int sym_prefix_len;
63     void * handle;
64    
65     /* sanity checking */
66 nmav 1.2 if (module == NULL || sym_prefix == NULL || content_type == NULL) {
67 nmav 1.1 DIE("NULL values sent to add_module");
68     }
69    
70 nmav 1.2 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 nmav 1.3 hash = (hash + 1) % MODULE_HASHTABLE_SIZE;
77 nmav 1.2
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 nmav 1.1 }
93    
94 nmav 1.2 old->sym_prefix = strdup( sym_prefix);
95     if (old->sym_prefix == NULL) {
96     DIE("strdup() failed.");
97 nmav 1.1 }
98    
99 nmav 1.2 old->content_type = strdup( content_type);
100     if (old->content_type == NULL) {
101 nmav 1.1 DIE("strdup() failed.");
102     }
103    
104 nmav 1.2 old->content_type_len = strlen( content_type);
105    
106    
107     handle = dlopen( module, RTLD_NOW);
108     if ( handle==NULL) {
109 nmav 1.7 fprintf(stderr, "Could not load module '%s'. Dlopen failed: %s\n", module, dlerror());
110 nmav 1.2 exit(1);
111 nmav 1.1 }
112 nmav 1.2 old->dl_handle = handle;
113 nmav 1.1
114    
115     sym_prefix_len = strlen( sym_prefix);
116     if (sym_prefix_len + 20 > sizeof(symbol)) {
117     DIE("Symbol prefix is too long.");
118     }
119    
120     /* Resolve shutdown */
121     strcpy( symbol, sym_prefix);
122     strcat( symbol, "_hic_shutdown");
123    
124 nmav 1.2 old->shutdown = dlsym( handle, symbol);
125     if ( old->shutdown == NULL) {
126 nmav 1.1 fprintf(stderr, "Could not resolve %s_hic_shutdown symbol", sym_prefix);
127     exit(1);
128     }
129    
130     /* Resolve init */
131     strcpy( symbol, sym_prefix);
132     strcat( symbol, "_hic_init");
133    
134 nmav 1.2 old->init = dlsym( handle, symbol);
135     if ( old->init == NULL) {
136 nmav 1.1 fprintf(stderr, "Could not resolve %s_hic_init symbol", sym_prefix);
137     exit(1);
138     }
139 nmav 1.2 old->init(); /* Run the initialization stuff */
140 nmav 1.1
141     /* Resolve request */
142     strcpy( symbol, sym_prefix);
143     strcat( symbol, "_hic_request");
144    
145 nmav 1.2 old->request = dlsym( handle, symbol);
146     if ( old->request == NULL) {
147 nmav 1.1 fprintf(stderr, "Could not resolve %s_hic_request symbol", sym_prefix);
148     exit(1);
149     }
150    
151 nmav 1.2 module_hashtable[hash] = old;
152    
153 nmav 1.1 return;
154     #endif
155     }
156    
157 nmav 1.7
158     /* add_hic_action
159     *
160     * Like add_hic_module() but associates the file type with a
161     * specific action (executable to run with)
162     */
163    
164     void add_hic_action(const char *action, const char* file_type)
165     {
166     int hash;
167     hic_module_st* old, *start;
168    
169     /* sanity checking */
170     if (action == NULL || file_type == NULL) {
171     DIE("NULL values sent to add_hic_action");
172     }
173    
174     hash = get_hic_module_hash_value( file_type);
175     start = old = module_hashtable[hash];
176    
177     if ( old != NULL) {
178     /* find next empty */
179     do {
180     hash = (hash + 1) % MODULE_HASHTABLE_SIZE;
181    
182     old = module_hashtable[hash];
183    
184     if (start == old) {
185     DIE("Module hashtable is full.");
186     }
187    
188     } while( old != NULL);
189     }
190    
191     /* old was found, and is empty. */
192    
193     old = malloc( sizeof(hic_module_st));
194     if (old==NULL) {
195     DIE("malloc() failed.");
196     }
197    
198     old->sym_prefix = NULL;
199    
200     old->content_type = strdup( file_type);
201     if (old->content_type == NULL) {
202     DIE("strdup() failed.");
203     }
204    
205     old->content_type_len = strlen( file_type);
206    
207     old->action = strdup( action);
208     if ( old->action == NULL) {
209     DIE("strdup() failed.");
210     }
211    
212     old->dl_handle = NULL;
213     old->shutdown = NULL;
214     old->init = NULL;
215     old->request = NULL;
216    
217     module_hashtable[hash] = old;
218    
219     return;
220     }
221    
222 nmav 1.1 /*
223 nmav 1.2 * Name: find_hic_appr_module
224 nmav 1.1 *
225     * Description: Locates the appropriate HIC module for the given file.
226     * Actually ones needs this to get the dlsymed() functions.
227     *
228     * Returns:
229     *
230     * a pointer to a hic_module_st structure or NULL if not found
231     */
232    
233 nmav 1.2 hic_module_st *find_hic_appr_module(const char *content_type, int content_type_len)
234 nmav 1.1 {
235 nmav 1.2 int i, hash;
236 nmav 1.1
237 nmav 1.2 if (content_type == NULL) return NULL;
238     if (content_type_len == 0) content_type_len = strlen( content_type);
239 nmav 1.1
240 nmav 1.2 hash = get_hic_module_hash_value( content_type);
241 nmav 1.3 for (i=hash;i<MODULE_HASHTABLE_SIZE;i++) {
242 nmav 1.2 if (module_hashtable[i] == NULL) break;
243 nmav 1.1
244 nmav 1.2 if ( content_type_len != module_hashtable[i]->content_type_len) continue;
245 nmav 1.1
246 nmav 1.2 if (memcmp( content_type, module_hashtable[i]->content_type,
247     content_type_len) == 0) {
248 nmav 1.1 /* FOUND! */
249 nmav 1.2 return module_hashtable[i];
250 nmav 1.1 }
251     }
252    
253     return NULL;
254    
255     }
256    
257    
258     /*
259     * Empties the hic modules table, deallocating any allocated memory.
260     */
261    
262     void dump_hic_modules(void)
263     {
264     int i;
265    
266 nmav 1.3 for (i = 0; i < MODULE_HASHTABLE_SIZE; ++i) { /* these limits OK? */
267 nmav 1.5 if (!module_hashtable[i]) continue;
268    
269 nmav 1.7 #ifdef ENABLE_HIC
270 nmav 1.2 free( module_hashtable[i]->sym_prefix);
271     free( module_hashtable[i]->content_type);
272 nmav 1.7
273     if (module_hashtable[i]->shutdown)
274     module_hashtable[i]->shutdown(); /* Run the deinitialization stuff */
275    
276     if (module_hashtable[i]->dl_handle)
277     dlclose( module_hashtable[i]->dl_handle);
278     #endif
279    
280     free( module_hashtable[i]->action);
281    
282 nmav 1.2 free( module_hashtable[i]);
283     module_hashtable[i] = NULL;
284 nmav 1.1 }
285     }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26