#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/options.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/term.h"
#include "asterisk/manager.h"
#include "asterisk/cdr.h"
#include "asterisk/enum.h"
#include "asterisk/rtp.h"
#include "asterisk/lock.h"
#include <dlfcn.h>
#include "asterisk/md5.h"
Include dependency graph for loader.c:

Go to the source code of this file.
Data Structures | |
| struct | loadupdate |
| struct | module |
Defines | |
| #define | RTLD_NOW 0 |
Functions | |
| static int | __load_resource (const char *resource_name, const struct ast_config *cfg) |
| int | ast_load_resource (const char *resource_name) |
| Load a module. | |
| int | ast_loader_register (int(*v)(void)) |
| Add a procedure to be run when modules have been updated. | |
| int | ast_loader_unregister (int(*v)(void)) |
| Remove a procedure to be run when modules are updated. | |
| char * | ast_module_helper (char *line, char *word, int pos, int state, int rpos, int needsreload) |
| Match modules names for the Asterisk cli. | |
| int | ast_module_reload (const char *name) |
| Reload asterisk modules. | |
| AST_MUTEX_DEFINE_STATIC (reloadlock) | |
| AST_MUTEX_DEFINE_STATIC (modlock) | |
| static int | ast_resource_exists (char *resource) |
| int | ast_unload_resource (const char *resource_name, int force) |
| Unloads a module. | |
| int | ast_update_module_list (int(*modentry)(const char *module, const char *description, int usecnt, const char *like), const char *like) |
| Ask for a list of modules, descriptions, and use counts. | |
| void | ast_update_use_count (void) |
| Notify when usecount has been changed. | |
| static int | key_matches (unsigned char *key1, unsigned char *key2) |
| int | load_modules (const int preload_only) |
| static int | printdigest (unsigned char *d) |
| static int | verify_key (unsigned char *key) |
Variables | |
| static unsigned char | expected_key [] |
| static const char * | loadorder [] |
| static int | modlistver = 0 |
| static struct module * | module_list = NULL |
| static struct loadupdate * | updaters |
Definition in file loader.c.
| #define RTLD_NOW 0 |
Definition at line 54 of file loader.c.
Referenced by __load_resource(), dlopen(), and loadModule().
| static int __load_resource | ( | const char * | resource_name, | |
| const struct ast_config * | cfg | |||
| ) | [static] |
Definition at line 271 of file loader.c.
References ast_config_AST_MODULE_DIR, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_true(), ast_unload_resource(), ast_update_use_count(), ast_variable_retrieve(), ast_verbose(), cfg, COLOR_BLACK, COLOR_BROWN, module::description, dlclose(), dlerror(), dlopen(), dlsym(), free, fully_booted, module::key, key(), module::lib, module::load_module, LOG_WARNING, malloc, module_list, module::next, option_console, option_verbose, module::reload, module::resource, RTLD_GLOBAL, RTLD_LAZY, RTLD_NOW, term_color(), module::unload_module, module::usecount, VERBOSE_PREFIX_1, and verify_key().
Referenced by ast_load_resource(), and load_modules().
00272 { 00273 static char fn[256]; 00274 int errors=0; 00275 int res; 00276 struct module *m; 00277 int flags=RTLD_NOW; 00278 #ifdef RTLD_GLOBAL 00279 char *val; 00280 #endif 00281 unsigned char *key; 00282 char tmp[80]; 00283 00284 if (strncasecmp(resource_name, "res_", 4)) { 00285 #ifdef RTLD_GLOBAL 00286 if (cfg) { 00287 if ((val = ast_variable_retrieve(cfg, "global", resource_name)) 00288 && ast_true(val)) 00289 flags |= RTLD_GLOBAL; 00290 } 00291 #endif 00292 } else { 00293 /* Resource modules are always loaded global and lazy */ 00294 #ifdef RTLD_GLOBAL 00295 flags = (RTLD_GLOBAL | RTLD_LAZY); 00296 #else 00297 flags = RTLD_LAZY; 00298 #endif 00299 } 00300 00301 if (ast_mutex_lock(&modlock)) 00302 ast_log(LOG_WARNING, "Failed to lock\n"); 00303 m = module_list; 00304 while(m) { 00305 if (!strcasecmp(m->resource, resource_name)) { 00306 ast_log(LOG_WARNING, "Module '%s' already exists\n", resource_name); 00307 ast_mutex_unlock(&modlock); 00308 return -1; 00309 } 00310 m = m->next; 00311 } 00312 m = malloc(sizeof(struct module)); 00313 if (!m) { 00314 ast_log(LOG_WARNING, "Out of memory\n"); 00315 ast_mutex_unlock(&modlock); 00316 return -1; 00317 } 00318 strncpy(m->resource, resource_name, sizeof(m->resource)-1); 00319 if (resource_name[0] == '/') { 00320 strncpy(fn, resource_name, sizeof(fn)-1); 00321 } else { 00322 snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_MODULE_DIR, resource_name); 00323 } 00324 m->lib = dlopen(fn, flags); 00325 if (!m->lib) { 00326 ast_log(LOG_WARNING, "%s\n", dlerror()); 00327 free(m); 00328 ast_mutex_unlock(&modlock); 00329 return -1; 00330 } 00331 m->load_module = dlsym(m->lib, "load_module"); 00332 if (m->load_module == NULL) 00333 m->load_module = dlsym(m->lib, "_load_module"); 00334 if (!m->load_module) { 00335 ast_log(LOG_WARNING, "No load_module in module %s\n", fn); 00336 errors++; 00337 } 00338 m->unload_module = dlsym(m->lib, "unload_module"); 00339 if (m->unload_module == NULL) 00340 m->unload_module = dlsym(m->lib, "_unload_module"); 00341 if (!m->unload_module) { 00342 ast_log(LOG_WARNING, "No unload_module in module %s\n", fn); 00343 errors++; 00344 } 00345 m->usecount = dlsym(m->lib, "usecount"); 00346 if (m->usecount == NULL) 00347 m->usecount = dlsym(m->lib, "_usecount"); 00348 if (!m->usecount) { 00349 ast_log(LOG_WARNING, "No usecount in module %s\n", fn); 00350 errors++; 00351 } 00352 m->description = dlsym(m->lib, "description"); 00353 if (m->description == NULL) 00354 m->description = dlsym(m->lib, "_description"); 00355 if (!m->description) { 00356 ast_log(LOG_WARNING, "No description in module %s\n", fn); 00357 errors++; 00358 } 00359 m->key = dlsym(m->lib, "key"); 00360 if (m->key == NULL) 00361 m->key = dlsym(m->lib, "_key"); 00362 if (!m->key) { 00363 ast_log(LOG_WARNING, "No key routine in module %s\n", fn); 00364 errors++; 00365 } 00366 00367 m->reload = dlsym(m->lib, "reload"); 00368 if (m->reload == NULL) 00369 m->reload = dlsym(m->lib, "_reload"); 00370 00371 if (!m->key || !(key = (unsigned char *) m->key())) { 00372 ast_log(LOG_WARNING, "Key routine returned NULL in module %s\n", fn); 00373 key = NULL; 00374 errors++; 00375 } 00376 if (key && verify_key(key)) { 00377 ast_log(LOG_WARNING, "Unexpected key returned by module %s\n", fn); 00378 errors++; 00379 } 00380 if (errors) { 00381 ast_log(LOG_WARNING, "%d error%s loading module %s, aborted\n", errors, (errors != 1) ? "s" : "", fn); 00382 dlclose(m->lib); 00383 free(m); 00384 ast_mutex_unlock(&modlock); 00385 return -1; 00386 } 00387 if (!fully_booted) { 00388 if (option_verbose) 00389 ast_verbose( " => (%s)\n", term_color(tmp, m->description(), COLOR_BROWN, COLOR_BLACK, sizeof(tmp))); 00390 if (option_console && !option_verbose) 00391 ast_verbose( "."); 00392 } else { 00393 if (option_verbose) 00394 ast_verbose(VERBOSE_PREFIX_1 "Loaded %s => (%s)\n", fn, m->description()); 00395 } 00396 00397 /* add module 'm' to end of module_list chain 00398 so reload commands will be issued in same order modules were loaded */ 00399 m->next = NULL; 00400 if (module_list == NULL) { 00401 /* empty list so far, add at front */ 00402 module_list = m; 00403 } 00404 else { 00405 struct module *i; 00406 /* find end of chain, and add there */ 00407 for (i = module_list; i->next; i = i->next) 00408 ; 00409 i->next = m; 00410 } 00411 00412 modlistver = rand(); 00413 ast_mutex_unlock(&modlock); 00414 if ((res = m->load_module())) { 00415 ast_log(LOG_WARNING, "%s: load_module failed, returning %d\n", m->resource, res); 00416 ast_unload_resource(resource_name, 0); 00417 return -1; 00418 } 00419 ast_update_use_count(); 00420 return 0; 00421 }
| int ast_load_resource | ( | const char * | resource_name | ) |
Load a module.
| resource_name | The filename of the module to load. |
Definition at line 423 of file loader.c.
References __load_resource(), ast_config_destroy(), ast_config_load(), AST_MODULE_CONFIG, cfg, and option_verbose.
Referenced by file_ok_sel(), handle_load(), load_module(), and reload_module().
00424 { 00425 int o; 00426 struct ast_config *cfg = NULL; 00427 int res; 00428 00429 /* Keep the module file parsing silent */ 00430 o = option_verbose; 00431 option_verbose = 0; 00432 cfg = ast_config_load(AST_MODULE_CONFIG); 00433 option_verbose = o; 00434 res = __load_resource(resource_name, cfg); 00435 if (cfg) 00436 ast_config_destroy(cfg); 00437 return res; 00438 }
| int ast_loader_register | ( | int(*)(void) | updater | ) |
Add a procedure to be run when modules have been updated.
| updater | The function to run when modules have been updated. |
Definition at line 609 of file loader.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, malloc, loadupdate::next, loadupdate::updater, and updaters.
Referenced by show_console().
00610 { 00611 struct loadupdate *tmp; 00612 /* XXX Should be more flexible here, taking > 1 verboser XXX */ 00613 if ((tmp = malloc(sizeof (struct loadupdate)))) { 00614 tmp->updater = v; 00615 if (ast_mutex_lock(&modlock)) 00616 ast_log(LOG_WARNING, "Failed to lock\n"); 00617 tmp->next = updaters; 00618 updaters = tmp; 00619 ast_mutex_unlock(&modlock); 00620 return 0; 00621 } 00622 return -1; 00623 }
| int ast_loader_unregister | ( | int(*)(void) | updater | ) |
Remove a procedure to be run when modules are updated.
| updater | The updater function to unregister. |
Definition at line 625 of file loader.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, loadupdate::next, loadupdate::updater, and updaters.
Referenced by exit_now().
00626 { 00627 int res = -1; 00628 struct loadupdate *tmp, *tmpl=NULL; 00629 if (ast_mutex_lock(&modlock)) 00630 ast_log(LOG_WARNING, "Failed to lock\n"); 00631 tmp = updaters; 00632 while(tmp) { 00633 if (tmp->updater == v) { 00634 if (tmpl) 00635 tmpl->next = tmp->next; 00636 else 00637 updaters = tmp->next; 00638 break; 00639 } 00640 tmpl = tmp; 00641 tmp = tmp->next; 00642 } 00643 if (tmp) 00644 res = 0; 00645 ast_mutex_unlock(&modlock); 00646 return res; 00647 }
| char* ast_module_helper | ( | char * | line, | |
| char * | word, | |||
| int | pos, | |||
| int | state, | |||
| int | rpos, | |||
| int | needsreload | |||
| ) |
Match modules names for the Asterisk cli.
| line | Unused by this function, but this should be the line we are matching. | |
| word | The partial name to match. | |
| pos | The position the word we are completing is in. | |
| state | The possible match to return. | |
| rpos | The position we should be matching. This should be the same as pos. | |
| needsreload | This should be 1 if we need to reload this module and 0 otherwise. This function will only return modules that are reloadble if this is 1. |
Definition at line 166 of file loader.c.
References ast_mutex_lock(), ast_mutex_unlock(), module_list, module::next, module::reload, module::resource, and strdup.
Referenced by complete_mod_2(), and complete_mod_4().
00167 { 00168 struct module *m; 00169 int which=0; 00170 char *ret; 00171 00172 if (pos != rpos) 00173 return NULL; 00174 ast_mutex_lock(&modlock); 00175 m = module_list; 00176 while(m) { 00177 if (!strncasecmp(word, m->resource, strlen(word)) && (m->reload || !needsreload)) { 00178 if (++which > state) 00179 break; 00180 } 00181 m = m->next; 00182 } 00183 if (m) { 00184 ret = strdup(m->resource); 00185 } else { 00186 ret = NULL; 00187 if (!strncasecmp(word, "extconfig", strlen(word))) { 00188 if (++which > state) 00189 ret = strdup("extconfig"); 00190 } else if (!strncasecmp(word, "manager", strlen(word))) { 00191 if (++which > state) 00192 ret = strdup("manager"); 00193 } else if (!strncasecmp(word, "enum", strlen(word))) { 00194 if (++which > state) 00195 ret = strdup("enum"); 00196 } else if (!strncasecmp(word, "rtp", strlen(word))) { 00197 if (++which > state) 00198 ret = strdup("rtp"); 00199 } 00200 00201 } 00202 ast_mutex_unlock(&modlock); 00203 return ret; 00204 }
| int ast_module_reload | ( | const char * | name | ) |
Reload asterisk modules.
| name | the name of the module to reload |
Definition at line 206 of file loader.c.
References ast_cdr_engine_reload(), ast_enum_reload(), ast_lastreloadtime, ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_rtp_reload(), ast_verbose(), module::description, dnsmgr_reload(), module_list, module::next, option_verbose, read_config_maps(), reload(), module::reload, reload_manager(), module::resource, and VERBOSE_PREFIX_3.
Referenced by handle_reload(), and monitor_sig_flags().
00207 { 00208 struct module *m; 00209 int reloaded = 0; 00210 int oldversion; 00211 int (*reload)(void); 00212 /* We'll do the logger and manager the favor of calling its reload here first */ 00213 00214 if (ast_mutex_trylock(&reloadlock)) { 00215 ast_verbose("The previous reload command didn't finish yet\n"); 00216 return -1; 00217 } 00218 time(&ast_lastreloadtime); 00219 00220 if (!name || !strcasecmp(name, "extconfig")) { 00221 read_config_maps(); 00222 reloaded = 2; 00223 } 00224 if (!name || !strcasecmp(name, "manager")) { 00225 reload_manager(); 00226 reloaded = 2; 00227 } 00228 if (!name || !strcasecmp(name, "cdr")) { 00229 ast_cdr_engine_reload(); 00230 reloaded = 2; 00231 } 00232 if (!name || !strcasecmp(name, "enum")) { 00233 ast_enum_reload(); 00234 reloaded = 2; 00235 } 00236 if (!name || !strcasecmp(name, "rtp")) { 00237 ast_rtp_reload(); 00238 reloaded = 2; 00239 } 00240 if (!name || !strcasecmp(name, "dnsmgr")) { 00241 dnsmgr_reload(); 00242 reloaded = 2; 00243 } 00244 00245 ast_mutex_lock(&modlock); 00246 oldversion = modlistver; 00247 m = module_list; 00248 while(m) { 00249 if (!name || !strcasecmp(name, m->resource)) { 00250 if (reloaded < 1) 00251 reloaded = 1; 00252 reload = m->reload; 00253 ast_mutex_unlock(&modlock); 00254 if (reload) { 00255 reloaded = 2; 00256 if (option_verbose > 2) 00257 ast_verbose(VERBOSE_PREFIX_3 "Reloading module '%s' (%s)\n", m->resource, m->description()); 00258 reload(); 00259 } 00260 ast_mutex_lock(&modlock); 00261 if (oldversion != modlistver) 00262 break; 00263 } 00264 m = m->next; 00265 } 00266 ast_mutex_unlock(&modlock); 00267 ast_mutex_unlock(&reloadlock); 00268 return reloaded; 00269 }
| AST_MUTEX_DEFINE_STATIC | ( | reloadlock | ) |
| AST_MUTEX_DEFINE_STATIC | ( | modlock | ) |
| static int ast_resource_exists | ( | char * | resource | ) | [static] |
Definition at line 440 of file loader.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, module_list, module::next, and module::resource.
00441 { 00442 struct module *m; 00443 if (ast_mutex_lock(&modlock)) 00444 ast_log(LOG_WARNING, "Failed to lock\n"); 00445 m = module_list; 00446 while(m) { 00447 if (!strcasecmp(resource, m->resource)) 00448 break; 00449 m = m->next; 00450 } 00451 ast_mutex_unlock(&modlock); 00452 if (m) 00453 return -1; 00454 else 00455 return 0; 00456 }
| int ast_unload_resource | ( | const char * | resource_name, | |
| int | force | |||
| ) |
Unloads a module.
| resource_name | The name of the module to unload. | |
| force | The force flag. This should be set using one of the AST_FORCE* flags. |
Definition at line 122 of file loader.c.
References AST_FORCE_FIRM, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_update_use_count(), dlclose(), free, module::lib, LOG_WARNING, module_list, module::next, module::resource, module::unload_module, and module::usecount.
Referenced by __load_resource(), exit_now(), handle_unload(), reload_module(), and remove_module().
00123 { 00124 struct module *m, *ml = NULL; 00125 int res = -1; 00126 if (ast_mutex_lock(&modlock)) 00127 ast_log(LOG_WARNING, "Failed to lock\n"); 00128 m = module_list; 00129 while(m) { 00130 if (!strcasecmp(m->resource, resource_name)) { 00131 if ((res = m->usecount()) > 0) { 00132 if (force) 00133 ast_log(LOG_WARNING, "Warning: Forcing removal of module %s with use count %d\n", resource_name, res); 00134 else { 00135 ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name, res); 00136 ast_mutex_unlock(&modlock); 00137 return -1; 00138 } 00139 } 00140 res = m->unload_module(); 00141 if (res) { 00142 ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name); 00143 if (force <= AST_FORCE_FIRM) { 00144 ast_mutex_unlock(&modlock); 00145 return -1; 00146 } else 00147 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n"); 00148 } 00149 if (ml) 00150 ml->next = m->next; 00151 else 00152 module_list = m->next; 00153 dlclose(m->lib); 00154 free(m); 00155 break; 00156 } 00157 ml = m; 00158 m = m->next; 00159 } 00160 modlistver = rand(); 00161 ast_mutex_unlock(&modlock); 00162 ast_update_use_count(); 00163 return res; 00164 }
| int ast_update_module_list | ( | int(*)(const char *module, const char *description, int usecnt, const char *like) | modentry, | |
| const char * | like | |||
| ) |
Ask for a list of modules, descriptions, and use counts.
| modentry | A callback to an updater function. | |
| like | For each of the modules loaded, modentry will be executed with the resource, description, and usecount values of each particular module. |
Definition at line 589 of file loader.c.
References ast_mutex_trylock(), ast_mutex_unlock(), module::description, module_list, module::next, module::resource, and module::usecount.
Referenced by handle_modlist(), and mod_update().
00591 { 00592 struct module *m; 00593 int unlock = -1; 00594 int total_mod_loaded = 0; 00595 00596 if (ast_mutex_trylock(&modlock)) 00597 unlock = 0; 00598 m = module_list; 00599 while (m) { 00600 total_mod_loaded += modentry(m->resource, m->description(), m->usecount(), like); 00601 m = m->next; 00602 } 00603 if (unlock) 00604 ast_mutex_unlock(&modlock); 00605 00606 return total_mod_loaded; 00607 }
| void ast_update_use_count | ( | void | ) |
Notify when usecount has been changed.
This function calulates use counts and notifies anyone trying to keep track of them. It should be called whenever your module's usecount changes.
Definition at line 573 of file loader.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, loadupdate::next, loadupdate::updater, and updaters.
Referenced by __load_resource(), __oh323_new(), adpcm_destroy(), adpcmtolin_new(), agent_new(), alaw_destroy(), alawtolin_new(), alawtoulaw_new(), alsa_new(), aopen_decusecnt(), aopen_incusecnt(), ast_iax2_new(), ast_modem_new(), ast_unload_resource(), au_close(), au_open(), au_rewrite(), bestdata_decusecnt(), bestdata_incusecnt(), exit_now(), features_new(), g723_close(), g723_destroy(), g723_open(), g723_rewrite(), g723tolin_new(), g726_16_open(), g726_16_rewrite(), g726_24_open(), g726_24_rewrite(), g726_32_open(), g726_32_rewrite(), g726_40_open(), g726_40_rewrite(), g726_close(), g726_destroy(), g726tolin_new(), g729_close(), g729_open(), g729_rewrite(), gsm_close(), gsm_open(), gsm_rewrite(), h263_close(), h263_open(), h263_rewrite(), i4l_decusecnt(), i4l_incusecnt(), iax2_predestroy(), ilbc_close(), ilbc_open(), ilbc_rewrite(), lintoadpcm_new(), lintoalaw_new(), lintog723_new(), lintog726_new(), lintoulaw_new(), load_module(), local_new(), mgcp_hangup(), mgcp_new(), modem_hangup(), nbs_new(), ogg_vorbis_close(), ogg_vorbis_open(), ogg_vorbis_rewrite(), oh323_hangup(), oh323_request(), oss_new(), pcm_close(), pcm_open(), pcm_rewrite(), phone_check_exception(), phone_hangup(), phone_new(), sip_hangup(), sip_new(), sip_request_call(), sipsock_read(), skinny_new(), slinear_close(), slinear_open(), slinear_rewrite(), ulaw_destroy(), ulawtoalaw_new(), ulawtolin_new(), vox_close(), vox_open(), vox_rewrite(), vpb_hangup(), vpb_new(), wav_close(), wav_open(), wav_rewrite(), zt_hangup(), and zt_new().
00574 { 00575 /* Notify any module monitors that the use count for a 00576 resource has changed */ 00577 struct loadupdate *m; 00578 if (ast_mutex_lock(&modlock)) 00579 ast_log(LOG_WARNING, "Failed to lock\n"); 00580 m = updaters; 00581 while(m) { 00582 m->updater(); 00583 m = m->next; 00584 } 00585 ast_mutex_unlock(&modlock); 00586 00587 }
| static int key_matches | ( | unsigned char * | key1, | |
| unsigned char * | key2 | |||
| ) | [static] |
Definition at line 99 of file loader.c.
References match().
Referenced by verify_key().
00100 { 00101 int match = 1; 00102 int x; 00103 for (x=0; x<16; x++) { 00104 match &= (key1[x] == key2[x]); 00105 } 00106 return match; 00107 }
| int load_modules | ( | const int | preload_only | ) |
Definition at line 466 of file loader.c.
References __load_resource(), ast_config_destroy(), ast_config_load(), ast_log(), AST_MODULE_CONFIG, ast_variable_browse(), ast_verbose(), cfg, COLOR_BRWHITE, LOG_DEBUG, LOG_WARNING, ast_variable::name, ast_variable::next, option_debug, option_verbose, term_color(), ast_variable::value, and VERBOSE_PREFIX_1.
Referenced by main().
00467 { 00468 struct ast_config *cfg; 00469 struct ast_variable *v; 00470 char tmp[80]; 00471 00472 if (option_verbose) { 00473 if (preload_only) 00474 ast_verbose("Asterisk Dynamic Loader loading preload modules:\n"); 00475 else 00476 ast_verbose("Asterisk Dynamic Loader Starting:\n"); 00477 } 00478 00479 cfg = ast_config_load(AST_MODULE_CONFIG); 00480 if (cfg) { 00481 int doload; 00482 00483 /* Load explicitly defined modules */ 00484 for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) { 00485 doload = 0; 00486 00487 if (preload_only) 00488 doload = !strcasecmp(v->name, "preload"); 00489 else 00490 doload = !strcasecmp(v->name, "load"); 00491 00492 if (doload) { 00493 if (option_debug && !option_verbose) 00494 ast_log(LOG_DEBUG, "Loading module %s\n", v->value); 00495 if (option_verbose) { 00496 ast_verbose(VERBOSE_PREFIX_1 "[%s]", term_color(tmp, v->value, COLOR_BRWHITE, 0, sizeof(tmp))); 00497 fflush(stdout); 00498 } 00499 if (__load_resource(v->value, cfg)) { 00500 ast_log(LOG_WARNING, "Loading module %s failed!\n", v->value); 00501 ast_config_destroy(cfg); 00502 return -1; 00503 } 00504 } 00505 } 00506 } 00507 00508 if (preload_only) { 00509 ast_config_destroy(cfg); 00510 return 0; 00511 } 00512 00513 if (!cfg || ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) { 00514 /* Load all modules */ 00515 DIR *mods; 00516 struct dirent *d; 00517 int x; 00518 00519 /* Loop through each order */ 00520 for (x=0; x<sizeof(loadorder) / sizeof(loadorder[0]); x++) { 00521 mods = opendir((char *)ast_config_AST_MODULE_DIR); 00522 if (mods) { 00523 while((d = readdir(mods))) { 00524 /* Must end in .so to load it. */ 00525 if ((strlen(d->d_name) > 3) && 00526 (!loadorder[x] || !strncasecmp(d->d_name, loadorder[x], strlen(loadorder[x]))) && 00527 !strcasecmp(d->d_name + strlen(d->d_name) - 3, ".so") && 00528 !ast_resource_exists(d->d_name)) { 00529 /* It's a shared library -- Just be sure we're allowed to load it -- kinda 00530 an inefficient way to do it, but oh well. */ 00531 if (cfg) { 00532 v = ast_variable_browse(cfg, "modules"); 00533 while(v) { 00534 if (!strcasecmp(v->name, "noload") && 00535 !strcasecmp(v->value, d->d_name)) 00536 break; 00537 v = v->next; 00538 } 00539 if (v) { 00540 if (option_verbose) { 00541 ast_verbose( VERBOSE_PREFIX_1 "[skipping %s]\n", d->d_name); 00542 fflush(stdout); 00543 } 00544 continue; 00545 } 00546 00547 } 00548 if (option_debug && !option_verbose) 00549 ast_log(LOG_DEBUG, "Loading module %s\n", d->d_name); 00550 if (option_verbose) { 00551 ast_verbose( VERBOSE_PREFIX_1 "[%s]", term_color(tmp, d->d_name, COLOR_BRWHITE, 0, sizeof(tmp))); 00552 fflush(stdout); 00553 } 00554 if (__load_resource(d->d_name, cfg)) { 00555 ast_log(LOG_WARNING, "Loading module %s failed!\n", d->d_name); 00556 if (cfg) 00557 ast_config_destroy(cfg); 00558 return -1; 00559 } 00560 } 00561 } 00562 closedir(mods); 00563 } else { 00564 if (!option_quiet) 00565 ast_log(LOG_WARNING, "Unable to open modules directory %s.\n", (char *)ast_config_AST_MODULE_DIR); 00566 } 00567 } 00568 } 00569 ast_config_destroy(cfg); 00570 return 0; 00571 }
| static int printdigest | ( | unsigned char * | d | ) | [static] |
Definition at line 84 of file loader.c.
References ast_log(), and LOG_DEBUG.
Referenced by verify_key().
00085 { 00086 int x; 00087 char buf[256]; 00088 char buf2[16]; 00089 snprintf(buf, sizeof(buf), "Unexpected signature:"); 00090 for (x=0; x<16; x++) { 00091 snprintf(buf2, sizeof(buf2), " %02x", *(d++)); 00092 strcat(buf, buf2); 00093 } 00094 strcat(buf, "\n"); 00095 ast_log(LOG_DEBUG, "%s", buf); 00096 return 0; 00097 }
| static int verify_key | ( | unsigned char * | key | ) | [static] |
Definition at line 109 of file loader.c.
References key_matches(), MD5Final(), MD5Init(), MD5Update(), and printdigest().
Referenced by __load_resource().
00110 { 00111 struct MD5Context c; 00112 unsigned char digest[16]; 00113 MD5Init(&c); 00114 MD5Update(&c, key, strlen((char *)key)); 00115 MD5Final(digest, &c); 00116 if (key_matches(expected_key, digest)) 00117 return 0; 00118 printdigest(digest); 00119 return -1; 00120 }
unsigned char expected_key[] [static] |
int modlistver = 0 [static] |
struct module* module_list = NULL [static] |
Definition at line 60 of file loader.c.
Referenced by __load_resource(), ast_module_helper(), ast_module_reload(), ast_resource_exists(), ast_unload_resource(), and ast_update_module_list().
struct loadupdate * updaters [static] |
Referenced by ast_loader_register(), ast_loader_unregister(), and ast_update_use_count().
1.5.1