#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 270 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().
00271 { 00272 static char fn[256]; 00273 int errors=0; 00274 int res; 00275 struct module *m; 00276 int flags=RTLD_NOW; 00277 #ifdef RTLD_GLOBAL 00278 char *val; 00279 #endif 00280 unsigned char *key; 00281 char tmp[80]; 00282 00283 if (strncasecmp(resource_name, "res_", 4)) { 00284 #ifdef RTLD_GLOBAL 00285 if (cfg) { 00286 if ((val = ast_variable_retrieve(cfg, "global", resource_name)) 00287 && ast_true(val)) 00288 flags |= RTLD_GLOBAL; 00289 } 00290 #endif 00291 } else { 00292 /* Resource modules are always loaded global and lazy */ 00293 #ifdef RTLD_GLOBAL 00294 flags = (RTLD_GLOBAL | RTLD_LAZY); 00295 #else 00296 flags = RTLD_LAZY; 00297 #endif 00298 } 00299 00300 if (ast_mutex_lock(&modlock)) 00301 ast_log(LOG_WARNING, "Failed to lock\n"); 00302 m = module_list; 00303 while(m) { 00304 if (!strcasecmp(m->resource, resource_name)) { 00305 ast_log(LOG_WARNING, "Module '%s' already exists\n", resource_name); 00306 ast_mutex_unlock(&modlock); 00307 return -1; 00308 } 00309 m = m->next; 00310 } 00311 m = malloc(sizeof(struct module)); 00312 if (!m) { 00313 ast_log(LOG_WARNING, "Out of memory\n"); 00314 ast_mutex_unlock(&modlock); 00315 return -1; 00316 } 00317 strncpy(m->resource, resource_name, sizeof(m->resource)-1); 00318 if (resource_name[0] == '/') { 00319 strncpy(fn, resource_name, sizeof(fn)-1); 00320 } else { 00321 snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_MODULE_DIR, resource_name); 00322 } 00323 m->lib = dlopen(fn, flags); 00324 if (!m->lib) { 00325 ast_log(LOG_WARNING, "%s\n", dlerror()); 00326 free(m); 00327 ast_mutex_unlock(&modlock); 00328 return -1; 00329 } 00330 m->load_module = dlsym(m->lib, "load_module"); 00331 if (m->load_module == NULL) 00332 m->load_module = dlsym(m->lib, "_load_module"); 00333 if (!m->load_module) { 00334 ast_log(LOG_WARNING, "No load_module in module %s\n", fn); 00335 errors++; 00336 } 00337 m->unload_module = dlsym(m->lib, "unload_module"); 00338 if (m->unload_module == NULL) 00339 m->unload_module = dlsym(m->lib, "_unload_module"); 00340 if (!m->unload_module) { 00341 ast_log(LOG_WARNING, "No unload_module in module %s\n", fn); 00342 errors++; 00343 } 00344 m->usecount = dlsym(m->lib, "usecount"); 00345 if (m->usecount == NULL) 00346 m->usecount = dlsym(m->lib, "_usecount"); 00347 if (!m->usecount) { 00348 ast_log(LOG_WARNING, "No usecount in module %s\n", fn); 00349 errors++; 00350 } 00351 m->description = dlsym(m->lib, "description"); 00352 if (m->description == NULL) 00353 m->description = dlsym(m->lib, "_description"); 00354 if (!m->description) { 00355 ast_log(LOG_WARNING, "No description in module %s\n", fn); 00356 errors++; 00357 } 00358 m->key = dlsym(m->lib, "key"); 00359 if (m->key == NULL) 00360 m->key = dlsym(m->lib, "_key"); 00361 if (!m->key) { 00362 ast_log(LOG_WARNING, "No key routine in module %s\n", fn); 00363 errors++; 00364 } 00365 00366 m->reload = dlsym(m->lib, "reload"); 00367 if (m->reload == NULL) 00368 m->reload = dlsym(m->lib, "_reload"); 00369 00370 if (!m->key || !(key = (unsigned char *) m->key())) { 00371 ast_log(LOG_WARNING, "Key routine returned NULL in module %s\n", fn); 00372 key = NULL; 00373 errors++; 00374 } 00375 if (key && verify_key(key)) { 00376 ast_log(LOG_WARNING, "Unexpected key returned by module %s\n", fn); 00377 errors++; 00378 } 00379 if (errors) { 00380 ast_log(LOG_WARNING, "%d error%s loading module %s, aborted\n", errors, (errors != 1) ? "s" : "", fn); 00381 dlclose(m->lib); 00382 free(m); 00383 ast_mutex_unlock(&modlock); 00384 return -1; 00385 } 00386 if (!fully_booted) { 00387 if (option_verbose) 00388 ast_verbose( " => (%s)\n", term_color(tmp, m->description(), COLOR_BROWN, COLOR_BLACK, sizeof(tmp))); 00389 if (option_console && !option_verbose) 00390 ast_verbose( "."); 00391 } else { 00392 if (option_verbose) 00393 ast_verbose(VERBOSE_PREFIX_1 "Loaded %s => (%s)\n", fn, m->description()); 00394 } 00395 00396 /* add module 'm' to end of module_list chain 00397 so reload commands will be issued in same order modules were loaded */ 00398 m->next = NULL; 00399 if (module_list == NULL) { 00400 /* empty list so far, add at front */ 00401 module_list = m; 00402 } 00403 else { 00404 struct module *i; 00405 /* find end of chain, and add there */ 00406 for (i = module_list; i->next; i = i->next) 00407 ; 00408 i->next = m; 00409 } 00410 00411 modlistver = rand(); 00412 ast_mutex_unlock(&modlock); 00413 if ((res = m->load_module())) { 00414 ast_log(LOG_WARNING, "%s: load_module failed, returning %d\n", m->resource, res); 00415 ast_unload_resource(resource_name, 0); 00416 return -1; 00417 } 00418 ast_update_use_count(); 00419 return 0; 00420 }
int ast_load_resource | ( | const char * | resource_name | ) |
Load a module.
resource_name | The filename of the module to load. |
Definition at line 422 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().
00423 { 00424 int o; 00425 struct ast_config *cfg = NULL; 00426 int res; 00427 00428 /* Keep the module file parsing silent */ 00429 o = option_verbose; 00430 option_verbose = 0; 00431 cfg = ast_config_load(AST_MODULE_CONFIG); 00432 option_verbose = o; 00433 res = __load_resource(resource_name, cfg); 00434 if (cfg) 00435 ast_config_destroy(cfg); 00436 return res; 00437 }
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 608 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().
00609 { 00610 struct loadupdate *tmp; 00611 /* XXX Should be more flexible here, taking > 1 verboser XXX */ 00612 if ((tmp = malloc(sizeof (struct loadupdate)))) { 00613 tmp->updater = v; 00614 if (ast_mutex_lock(&modlock)) 00615 ast_log(LOG_WARNING, "Failed to lock\n"); 00616 tmp->next = updaters; 00617 updaters = tmp; 00618 ast_mutex_unlock(&modlock); 00619 return 0; 00620 } 00621 return -1; 00622 }
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 624 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().
00625 { 00626 int res = -1; 00627 struct loadupdate *tmp, *tmpl=NULL; 00628 if (ast_mutex_lock(&modlock)) 00629 ast_log(LOG_WARNING, "Failed to lock\n"); 00630 tmp = updaters; 00631 while(tmp) { 00632 if (tmp->updater == v) { 00633 if (tmpl) 00634 tmpl->next = tmp->next; 00635 else 00636 updaters = tmp->next; 00637 break; 00638 } 00639 tmpl = tmp; 00640 tmp = tmp->next; 00641 } 00642 if (tmp) 00643 res = 0; 00644 ast_mutex_unlock(&modlock); 00645 return res; 00646 }
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 hup_handler().
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 if (!name || !strcasecmp(name, "extconfig")) { 00219 read_config_maps(); 00220 reloaded = 2; 00221 } 00222 if (!name || !strcasecmp(name, "manager")) { 00223 reload_manager(); 00224 reloaded = 2; 00225 } 00226 if (!name || !strcasecmp(name, "cdr")) { 00227 ast_cdr_engine_reload(); 00228 reloaded = 2; 00229 } 00230 if (!name || !strcasecmp(name, "enum")) { 00231 ast_enum_reload(); 00232 reloaded = 2; 00233 } 00234 if (!name || !strcasecmp(name, "rtp")) { 00235 ast_rtp_reload(); 00236 reloaded = 2; 00237 } 00238 if (!name || !strcasecmp(name, "dnsmgr")) { 00239 dnsmgr_reload(); 00240 reloaded = 2; 00241 } 00242 time(&ast_lastreloadtime); 00243 00244 ast_mutex_lock(&modlock); 00245 oldversion = modlistver; 00246 m = module_list; 00247 while(m) { 00248 if (!name || !strcasecmp(name, m->resource)) { 00249 if (reloaded < 1) 00250 reloaded = 1; 00251 reload = m->reload; 00252 ast_mutex_unlock(&modlock); 00253 if (reload) { 00254 reloaded = 2; 00255 if (option_verbose > 2) 00256 ast_verbose(VERBOSE_PREFIX_3 "Reloading module '%s' (%s)\n", m->resource, m->description()); 00257 reload(); 00258 } 00259 ast_mutex_lock(&modlock); 00260 if (oldversion != modlistver) 00261 break; 00262 } 00263 m = m->next; 00264 } 00265 ast_mutex_unlock(&modlock); 00266 ast_mutex_unlock(&reloadlock); 00267 return reloaded; 00268 }
AST_MUTEX_DEFINE_STATIC | ( | reloadlock | ) |
AST_MUTEX_DEFINE_STATIC | ( | modlock | ) |
static int ast_resource_exists | ( | char * | resource | ) | [static] |
Definition at line 439 of file loader.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, module_list, module::next, and module::resource.
00440 { 00441 struct module *m; 00442 if (ast_mutex_lock(&modlock)) 00443 ast_log(LOG_WARNING, "Failed to lock\n"); 00444 m = module_list; 00445 while(m) { 00446 if (!strcasecmp(resource, m->resource)) 00447 break; 00448 m = m->next; 00449 } 00450 ast_mutex_unlock(&modlock); 00451 if (m) 00452 return -1; 00453 else 00454 return 0; 00455 }
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 588 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().
00590 { 00591 struct module *m; 00592 int unlock = -1; 00593 int total_mod_loaded = 0; 00594 00595 if (ast_mutex_trylock(&modlock)) 00596 unlock = 0; 00597 m = module_list; 00598 while (m) { 00599 total_mod_loaded += modentry(m->resource, m->description(), m->usecount(), like); 00600 m = m->next; 00601 } 00602 if (unlock) 00603 ast_mutex_unlock(&modlock); 00604 00605 return total_mod_loaded; 00606 }
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 572 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().
00573 { 00574 /* Notify any module monitors that the use count for a 00575 resource has changed */ 00576 struct loadupdate *m; 00577 if (ast_mutex_lock(&modlock)) 00578 ast_log(LOG_WARNING, "Failed to lock\n"); 00579 m = updaters; 00580 while(m) { 00581 m->updater(); 00582 m = m->next; 00583 } 00584 ast_mutex_unlock(&modlock); 00585 00586 }
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 465 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().
00466 { 00467 struct ast_config *cfg; 00468 struct ast_variable *v; 00469 char tmp[80]; 00470 00471 if (option_verbose) { 00472 if (preload_only) 00473 ast_verbose("Asterisk Dynamic Loader loading preload modules:\n"); 00474 else 00475 ast_verbose("Asterisk Dynamic Loader Starting:\n"); 00476 } 00477 00478 cfg = ast_config_load(AST_MODULE_CONFIG); 00479 if (cfg) { 00480 int doload; 00481 00482 /* Load explicitly defined modules */ 00483 for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) { 00484 doload = 0; 00485 00486 if (preload_only) 00487 doload = !strcasecmp(v->name, "preload"); 00488 else 00489 doload = !strcasecmp(v->name, "load"); 00490 00491 if (doload) { 00492 if (option_debug && !option_verbose) 00493 ast_log(LOG_DEBUG, "Loading module %s\n", v->value); 00494 if (option_verbose) { 00495 ast_verbose(VERBOSE_PREFIX_1 "[%s]", term_color(tmp, v->value, COLOR_BRWHITE, 0, sizeof(tmp))); 00496 fflush(stdout); 00497 } 00498 if (__load_resource(v->value, cfg)) { 00499 ast_log(LOG_WARNING, "Loading module %s failed!\n", v->value); 00500 ast_config_destroy(cfg); 00501 return -1; 00502 } 00503 } 00504 } 00505 } 00506 00507 if (preload_only) { 00508 ast_config_destroy(cfg); 00509 return 0; 00510 } 00511 00512 if (!cfg || ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) { 00513 /* Load all modules */ 00514 DIR *mods; 00515 struct dirent *d; 00516 int x; 00517 00518 /* Loop through each order */ 00519 for (x=0; x<sizeof(loadorder) / sizeof(loadorder[0]); x++) { 00520 mods = opendir((char *)ast_config_AST_MODULE_DIR); 00521 if (mods) { 00522 while((d = readdir(mods))) { 00523 /* Must end in .so to load it. */ 00524 if ((strlen(d->d_name) > 3) && 00525 (!loadorder[x] || !strncasecmp(d->d_name, loadorder[x], strlen(loadorder[x]))) && 00526 !strcasecmp(d->d_name + strlen(d->d_name) - 3, ".so") && 00527 !ast_resource_exists(d->d_name)) { 00528 /* It's a shared library -- Just be sure we're allowed to load it -- kinda 00529 an inefficient way to do it, but oh well. */ 00530 if (cfg) { 00531 v = ast_variable_browse(cfg, "modules"); 00532 while(v) { 00533 if (!strcasecmp(v->name, "noload") && 00534 !strcasecmp(v->value, d->d_name)) 00535 break; 00536 v = v->next; 00537 } 00538 if (v) { 00539 if (option_verbose) { 00540 ast_verbose( VERBOSE_PREFIX_1 "[skipping %s]\n", d->d_name); 00541 fflush(stdout); 00542 } 00543 continue; 00544 } 00545 00546 } 00547 if (option_debug && !option_verbose) 00548 ast_log(LOG_DEBUG, "Loading module %s\n", d->d_name); 00549 if (option_verbose) { 00550 ast_verbose( VERBOSE_PREFIX_1 "[%s]", term_color(tmp, d->d_name, COLOR_BRWHITE, 0, sizeof(tmp))); 00551 fflush(stdout); 00552 } 00553 if (__load_resource(d->d_name, cfg)) { 00554 ast_log(LOG_WARNING, "Loading module %s failed!\n", d->d_name); 00555 if (cfg) 00556 ast_config_destroy(cfg); 00557 return -1; 00558 } 00559 } 00560 } 00561 closedir(mods); 00562 } else { 00563 if (!option_quiet) 00564 ast_log(LOG_WARNING, "Unable to open modules directory %s.\n", (char *)ast_config_AST_MODULE_DIR); 00565 } 00566 } 00567 } 00568 ast_config_destroy(cfg); 00569 return 0; 00570 }
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().