#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.
|
Definition at line 54 of file loader.c. Referenced by __load_resource(), dlopen(), and loadModule(). |
|
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, modlistver, 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 }
|
|
Load a module.
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 }
|
|
Add a procedure to be 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 }
|
|
Remove a procedure to be run when modules are updated.
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 }
|
|
Match modules names for the Asterisk cli.
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 }
|
|
Reload asterisk modules.
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(), modlistver, 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 }
|
|
|
|
|
|
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 }
|
|
Unloads a module.
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, modlistver, module_list, module::next, module::resource, module::unload_module, and module::usecount. Referenced by __load_resource(), exit_now(), 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 }
|
|
Ask for a list of modules, descriptions, and use counts.
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 }
|
|
|
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 }
|
|
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. 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 }
|
|
Definition at line 84 of file loader.c. 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 }
|
|
Definition at line 109 of file loader.c. References expected_key, 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 }
|
|
Initial value: { 0x8e, 0x93, 0x22, 0x83, 0xf5, 0xc3, 0xc0, 0x75, 0xff, 0x8b, 0xa9, 0xbe, 0x7c, 0x43, 0x74, 0x63 } Definition at line 63 of file loader.c. Referenced by verify_key(). |
|
|
|
Definition at line 61 of file loader.c. Referenced by __load_resource(), ast_module_reload(), and ast_unload_resource(). |
|
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(). |
|
Referenced by ast_loader_register(), ast_loader_unregister(), and ast_update_use_count(). |