![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
loader.c File Reference
Kevin P. Fleming <kpfleming@digium.com>
Luigi Rizzo <rizzo@icir.org>
Definition in file loader.c.
#include "asterisk.h"
#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include "asterisk/linkedlists.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/http.h"
#include "asterisk/lock.h"
#include <dlfcn.h>
#include "asterisk/md5.h"
#include "asterisk/utils.h"
Include dependency graph for loader.c:

Go to the source code of this file.
Data Structures | |
| struct | ast_module |
| struct | ast_module_user |
| struct | load_order_entry |
| struct | loadupdate |
| struct | reload_classes |
Defines | |
| #define | RTLD_NOW 0 |
Enumerations | |
| enum | flags { FLAG_RUNNING = (1 << 1), FLAG_DECLINED = (1 << 2) } |
Functions | |
| ast_module_user * | __ast_module_user_add (struct ast_module *mod, struct ast_channel *chan) |
| void | __ast_module_user_hangup_all (struct ast_module *mod) |
| void | __ast_module_user_remove (struct ast_module *mod, struct ast_module_user *u) |
| static struct load_order_entry * | add_to_load_order (const char *resource, struct load_order *load_order) |
| AST_LIST_HEAD (module_user_list, ast_module_user) | |
| AST_LIST_HEAD_NOLOCK (load_order, load_order_entry) | |
| static | AST_LIST_HEAD_STATIC (updaters, loadupdate) |
| static | AST_LIST_HEAD_STATIC (module_list, ast_module) |
| 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. | |
| int | ast_module_check (char *name) |
| Check if module with the name given is loaded. | |
| char * | ast_module_helper (const char *line, const char *word, int pos, int state, int rpos, int needsreload) |
| Match modules names for the Asterisk cli. | |
| ast_module * | ast_module_ref (struct ast_module *mod) |
| void | ast_module_register (const struct ast_module_info *info) |
| int | ast_module_reload (const char *name) |
| Reload asterisk modules. | |
| void | ast_module_unref (struct ast_module *mod) |
| void | ast_module_unregister (const struct ast_module_info *info) |
| AST_MUTEX_DEFINE_STATIC (reloadlock) | |
| int | ast_unload_resource (const char *resource_name, enum ast_module_unload_mode force) |
| Unload 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 struct ast_module * | find_resource (const char *resource, int do_lock) |
| static unsigned int | inspect_module (const struct ast_module *mod) |
| static int | key_matches (const unsigned char *key1, const unsigned char *key2) |
| int | load_modules (unsigned int preload_only) |
| static enum ast_module_load_result | load_resource (const char *resource_name, unsigned int global_symbols_only) |
| static int | printdigest (const unsigned char *d) |
| static int | resource_name_match (const char *name1_in, const char *name2_in) |
| static int | verify_key (const unsigned char *key) |
Variables | |
| static unsigned int | embedding = 1 |
| static unsigned char | expected_key [] |
| ast_module * | resource_being_loaded |
|
|
Definition at line 65 of file loader.c. Referenced by dlopen(), and loadModule(). |
|
|
Definition at line 83 of file loader.c. 00083 { 00084 FLAG_RUNNING = (1 << 1), /* module successfully initialized */ 00085 FLAG_DECLINED = (1 << 2), /* module declined to initialize */ 00086 };
|
|
||||||||||||
|
Definition at line 179 of file loader.c. References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_update_use_count(), ast_module_user::chan, ast_module::usecount, and ast_module::users. 00181 { 00182 struct ast_module_user *u = ast_calloc(1, sizeof(*u)); 00183 00184 if (!u) 00185 return NULL; 00186 00187 u->chan = chan; 00188 00189 AST_LIST_LOCK(&mod->users); 00190 AST_LIST_INSERT_HEAD(&mod->users, u, entry); 00191 AST_LIST_UNLOCK(&mod->users); 00192 00193 ast_atomic_fetchadd_int(&mod->usecount, +1); 00194 00195 ast_update_use_count(); 00196 00197 return u; 00198 }
|
|
|
Definition at line 211 of file loader.c. References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_update_use_count(), ast_module_user::chan, free, ast_module::usecount, and ast_module::users. Referenced by ast_unload_resource(). 00212 { 00213 struct ast_module_user *u; 00214 00215 AST_LIST_LOCK(&mod->users); 00216 while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) { 00217 ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD); 00218 ast_atomic_fetchadd_int(&mod->usecount, -1); 00219 free(u); 00220 } 00221 AST_LIST_UNLOCK(&mod->users); 00222 00223 ast_update_use_count(); 00224 }
|
|
||||||||||||
|
Definition at line 200 of file loader.c. References AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_update_use_count(), free, ast_module::usecount, and ast_module::users. 00201 { 00202 AST_LIST_LOCK(&mod->users); 00203 AST_LIST_REMOVE(&mod->users, u, entry); 00204 AST_LIST_UNLOCK(&mod->users); 00205 ast_atomic_fetchadd_int(&mod->usecount, -1); 00206 free(u); 00207 00208 ast_update_use_count(); 00209 }
|
|
||||||||||||
|
Definition at line 678 of file loader.c. References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_strdup, load_order_entry::resource, and resource_name_match(). Referenced by load_modules(). 00679 { 00680 struct load_order_entry *order; 00681 00682 AST_LIST_TRAVERSE(load_order, order, entry) { 00683 if (!resource_name_match(order->resource, resource)) 00684 return NULL; 00685 } 00686 00687 if (!(order = ast_calloc(1, sizeof(*order)))) 00688 return NULL; 00689 00690 order->resource = ast_strdup(resource); 00691 AST_LIST_INSERT_TAIL(load_order, order, entry); 00692 00693 return order; 00694 }
|
|
||||||||||||
|
|
|
||||||||||||
|
|
|
||||||||||||
|
|
|
||||||||||||
|
|
|
|
Load a module.
Definition at line 662 of file loader.c. References AST_LIST_LOCK, AST_LIST_UNLOCK, and load_resource(). Referenced by file_ok_sel(), handle_load(), and reload_module(). 00663 { 00664 AST_LIST_LOCK(&module_list); 00665 load_resource(resource_name, 0); 00666 AST_LIST_UNLOCK(&module_list); 00667 00668 return 0; 00669 }
|
|
|
Add a procedure to be run when modules have been updated.
Definition at line 888 of file loader.c. References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, and ast_malloc. Referenced by show_console(). 00889 { 00890 struct loadupdate *tmp; 00891 00892 if (!(tmp = ast_malloc(sizeof(*tmp)))) 00893 return -1; 00894 00895 tmp->updater = v; 00896 AST_LIST_LOCK(&module_list); 00897 AST_LIST_INSERT_HEAD(&updaters, tmp, entry); 00898 AST_LIST_UNLOCK(&module_list); 00899 00900 return 0; 00901 }
|
|
|
Remove a procedure to be run when modules are updated.
Definition at line 903 of file loader.c. References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, and loadupdate::updater. Referenced by exit_now(). 00904 { 00905 struct loadupdate *cur; 00906 00907 AST_LIST_LOCK(&module_list); 00908 AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) { 00909 if (cur->updater == v) { 00910 AST_LIST_REMOVE_CURRENT(&updaters, entry); 00911 break; 00912 } 00913 } 00914 AST_LIST_TRAVERSE_SAFE_END; 00915 AST_LIST_UNLOCK(&module_list); 00916 00917 return cur ? 0 : -1; 00918 }
|
|
|
Check if module with the name given is loaded.
Definition at line 875 of file loader.c. References ast_strlen_zero(), and find_resource(). 00876 { 00877 struct ast_module *cur; 00878 00879 if (ast_strlen_zero(name)) 00880 return 0; /* FALSE */ 00881 00882 cur = find_resource(name, 1); 00883 00884 return (cur != NULL); 00885 }
|
|
||||||||||||||||||||||||||||
|
Match modules names for the Asterisk cli.
Definition at line 489 of file loader.c. References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_module::info, name, ast_module_info::reload, and strdup. Referenced by handle_modlist(), handle_reload(), and handle_unload(). 00490 { 00491 struct ast_module *cur; 00492 int i, which=0, l = strlen(word); 00493 char *ret = NULL; 00494 00495 if (pos != rpos) 00496 return NULL; 00497 00498 AST_LIST_LOCK(&module_list); 00499 AST_LIST_TRAVERSE(&module_list, cur, entry) { 00500 if (!strncasecmp(word, cur->resource, l) && 00501 (cur->info->reload || !needsreload) && 00502 ++which > state) { 00503 ret = strdup(cur->resource); 00504 break; 00505 } 00506 } 00507 AST_LIST_UNLOCK(&module_list); 00508 00509 if (!ret) { 00510 for (i=0; !ret && reload_classes[i].name; i++) { 00511 if (!strncasecmp(word, reload_classes[i].name, l) && ++which > state) 00512 ret = strdup(reload_classes[i].name); 00513 } 00514 } 00515 00516 return ret; 00517 }
|
|
|
Definition at line 920 of file loader.c. References ast_update_use_count(), and ast_module::usecount. Referenced by __oh323_new(), alsa_new(), ast_iax2_new(), cli_audio_convert(), complete_orig(), fn_wrapper(), gtalk_new(), handle_orig(), mgcp_new(), oss_new(), phone_check_exception(), phone_new(), sip_new(), and skinny_new(). 00921 { 00922 ast_atomic_fetchadd_int(&mod->usecount, +1); 00923 ast_update_use_count(); 00924 00925 return mod; 00926 }
|
|
|
Definition at line 117 of file loader.c. References ast_calloc, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, embedding, ast_module::info, ast_module_info::name, resource_being_loaded, ast_module_info::self, and ast_module::users. 00118 { 00119 struct ast_module *mod; 00120 00121 if (embedding) { 00122 if (!(mod = ast_calloc(1, sizeof(*mod) + strlen(info->name) + 1))) 00123 return; 00124 strcpy(mod->resource, info->name); 00125 } else { 00126 mod = resource_being_loaded; 00127 } 00128 00129 mod->info = info; 00130 AST_LIST_HEAD_INIT(&mod->users); 00131 00132 /* during startup, before the loader has been initialized, 00133 there are no threads, so there is no need to take the lock 00134 on this list to manipulate it. it is also possible that it 00135 might be unsafe to use the list lock at that point... so 00136 let's avoid it altogether 00137 */ 00138 if (!embedding) 00139 AST_LIST_LOCK(&module_list); 00140 00141 /* it is paramount that the new entry be placed at the tail of 00142 the list, otherwise the code that uses dlopen() to load 00143 dynamic modules won't be able to find out if the module it 00144 just opened was registered or failed to load 00145 */ 00146 AST_LIST_INSERT_TAIL(&module_list, mod, entry); 00147 00148 if (!embedding) 00149 AST_LIST_UNLOCK(&module_list); 00150 00151 /* give the module a copy of its own handle, for later use in registrations and the like */ 00152 *((struct ast_module **) &(info->self)) = mod; 00153 }
|
|
|
Reload asterisk modules.
Definition at line 519 of file loader.c. References ast_mutex_trylock(), and ast_verbose(). Referenced by action_updateconfig(), and handle_reload(). 00520 { 00521 struct ast_module *cur; 00522 int res = 0; /* return value. 0 = not found, others, see below */ 00523 int i; 00524 00525 if (ast_mutex_trylock(&reloadlock)) { 00526 ast_verbose("The previous reload command didn't finish yet\n"); 00527 return -1; /* reload already in progress */ 00528 } 00529 00530 /* Call "predefined" reload here first */ 00531 for (i = 0; reload_classes[i].name; i++) { 00532 if (!name || !strcasecmp(name, reload_classes[i].name)) { 00533 reload_classes[i].reload_fn(); /* XXX should check error ? */ 00534 res = 2; /* found and reloaded */ 00535 } 00536 } 00537 ast_lastreloadtime = time(NULL); 00538 00539 if (name && res) 00540 return res; 00541 00542 AST_LIST_LOCK(&module_list); 00543 AST_LIST_TRAVERSE(&module_list, cur, entry) { 00544 const struct ast_module_info *info = cur->info; 00545 00546 if (name && resource_name_match(name, cur->resource)) 00547 continue; 00548 00549 if (!ast_test_flag(cur, FLAG_RUNNING | FLAG_DECLINED)) 00550 continue; 00551 00552 if (!info->reload) { /* cannot be reloaded */ 00553 if (res < 1) /* store result if possible */ 00554 res = 1; /* 1 = no reload() method */ 00555 continue; 00556 } 00557 00558 res = 2; 00559 if (option_verbose > 2) 00560 ast_verbose(VERBOSE_PREFIX_3 "Reloading module '%s' (%s)\n", cur->resource, info->description); 00561 info->reload(); 00562 } 00563 AST_LIST_UNLOCK(&module_list); 00564 00565 ast_mutex_unlock(&reloadlock); 00566 00567 return res; 00568 }
|
|
|
Definition at line 928 of file loader.c. References ast_update_use_count(), and ast_module::usecount. Referenced by alsa_hangup(), ast_closestream(), ast_smdi_interface_destroy(), cli_audio_convert(), complete_orig(), destroy(), gtalk_hangup(), handle_orig(), iax2_predestroy(), mgcp_hangup(), oh323_hangup(), oss_hangup(), phone_check_exception(), phone_hangup(), sip_hangup(), and zt_hangup(). 00929 { 00930 ast_atomic_fetchadd_int(&mod->usecount, -1); 00931 ast_update_use_count(); 00932 }
|
|
|
Definition at line 155 of file loader.c. References AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, free, ast_module::info, and ast_module::users. 00156 { 00157 struct ast_module *mod = NULL; 00158 00159 /* it is assumed that the users list in the module structure 00160 will already be empty, or we cannot have gotten to this 00161 point 00162 */ 00163 AST_LIST_LOCK(&module_list); 00164 AST_LIST_TRAVERSE_SAFE_BEGIN(&module_list, mod, entry) { 00165 if (mod->info == info) { 00166 AST_LIST_REMOVE_CURRENT(&module_list, entry); 00167 break; 00168 } 00169 } 00170 AST_LIST_TRAVERSE_SAFE_END; 00171 AST_LIST_UNLOCK(&module_list); 00172 00173 if (mod) { 00174 AST_LIST_HEAD_DESTROY(&mod->users); 00175 free(mod); 00176 } 00177 }
|
|
|
|
|
||||||||||||
|
Unload a module.
Definition at line 433 of file loader.c. References __ast_module_user_hangup_all(), ast_clear_flag, AST_FORCE_FIRM, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_test_flag, ast_update_use_count(), error(), find_resource(), FLAG_DECLINED, FLAG_RUNNING, and ast_module::usecount. Referenced by exit_now(), handle_unload(), reload_module(), and remove_module(). 00434 { 00435 struct ast_module *mod; 00436 int res = -1; 00437 int error = 0; 00438 00439 AST_LIST_LOCK(&module_list); 00440 00441 if (!(mod = find_resource(resource_name, 0))) { 00442 AST_LIST_UNLOCK(&module_list); 00443 return 0; 00444 } 00445 00446 if (!ast_test_flag(mod, FLAG_RUNNING | FLAG_DECLINED)) 00447 error = 1; 00448 00449 if (!error && (mod->usecount > 0)) { 00450 if (force) 00451 ast_log(LOG_WARNING, "Warning: Forcing removal of module '%s' with use count %d\n", 00452 resource_name, mod->usecount); 00453 else { 00454 ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name, 00455 mod->usecount); 00456 error = 1; 00457 } 00458 } 00459 00460 if (!error) { 00461 __ast_module_user_hangup_all(mod); 00462 res = mod->info->unload(); 00463 00464 if (res) { 00465 ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name); 00466 if (force <= AST_FORCE_FIRM) 00467 error = 1; 00468 else 00469 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n"); 00470 } 00471 } 00472 00473 if (!error) 00474 ast_clear_flag(mod, FLAG_RUNNING | FLAG_DECLINED); 00475 00476 AST_LIST_UNLOCK(&module_list); 00477 00478 #if LOADABLE_MODULES 00479 if (!error) 00480 unload_dynamic_module(mod); 00481 #endif 00482 00483 if (!error) 00484 ast_update_use_count(); 00485 00486 return res; 00487 }
|
|
||||||||||||
|
Ask for a list of modules, descriptions, and use counts.
Definition at line 854 of file loader.c. References AST_LIST_TRAVERSE, AST_LIST_TRYLOCK, AST_LIST_UNLOCK, ast_module_info::description, ast_module::info, and ast_module::usecount. Referenced by handle_modlist(), and mod_update(). 00856 { 00857 struct ast_module *cur; 00858 int unlock = -1; 00859 int total_mod_loaded = 0; 00860 00861 if (AST_LIST_TRYLOCK(&module_list)) 00862 unlock = 0; 00863 00864 AST_LIST_TRAVERSE(&module_list, cur, entry) { 00865 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, like); 00866 } 00867 00868 if (unlock) 00869 AST_LIST_UNLOCK(&module_list); 00870 00871 return total_mod_loaded; 00872 }
|
|
|
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 842 of file loader.c. References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and loadupdate::updater. Referenced by __ast_module_user_add(), __ast_module_user_hangup_all(), __ast_module_user_remove(), ast_module_ref(), ast_module_unref(), ast_unload_resource(), exit_now(), load_module(), load_resource(), oh323_request(), process_sip_queue(), and sip_request_call(). 00843 { 00844 /* Notify any module monitors that the use count for a 00845 resource has changed */ 00846 struct loadupdate *m; 00847 00848 AST_LIST_LOCK(&module_list); 00849 AST_LIST_TRAVERSE(&updaters, m, entry) 00850 m->updater(); 00851 AST_LIST_UNLOCK(&module_list); 00852 }
|
|
||||||||||||
|
Definition at line 306 of file loader.c. References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and resource_name_match(). Referenced by ast_module_check(), ast_unload_resource(), and load_resource(). 00307 { 00308 struct ast_module *cur; 00309 00310 if (do_lock) 00311 AST_LIST_LOCK(&module_list); 00312 00313 AST_LIST_TRAVERSE(&module_list, cur, entry) { 00314 if (!resource_name_match(resource, cur->resource)) 00315 break; 00316 } 00317 00318 if (do_lock) 00319 AST_LIST_UNLOCK(&module_list); 00320 00321 return cur; 00322 }
|
|
|
Definition at line 570 of file loader.c. References ast_log(), ast_module_info::description, ast_module::info, ast_module_info::key, and verify_key(). Referenced by load_resource(). 00571 { 00572 if (!mod->info->description) { 00573 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource); 00574 return 1; 00575 } 00576 00577 if (!mod->info->key) { 00578 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource); 00579 return 1; 00580 } 00581 00582 if (verify_key((unsigned char *) mod->info->key)) { 00583 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource); 00584 return 1; 00585 } 00586 00587 return 0; 00588 }
|
|
||||||||||||
|
Definition at line 259 of file loader.c. Referenced by verify_key(). 00260 { 00261 int x; 00262 00263 for (x = 0; x < 16; x++) { 00264 if (key1[x] != key2[x]) 00265 return 0; 00266 } 00267 00268 return 1; 00269 }
|
|
|
Provided by loader.c Definition at line 696 of file loader.c. References add_to_load_order(), ast_config_load(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_TRAVERSE, ast_log(), AST_MODULE_CONFIG, ast_variable_browse(), ast_verbose(), embedding, LOG_DEBUG, ast_variable::name, ast_variable::next, option_debug, option_verbose, and ast_variable::value. 00697 { 00698 struct ast_config *cfg; 00699 struct ast_module *mod; 00700 struct load_order_entry *order; 00701 struct ast_variable *v; 00702 unsigned int load_count; 00703 struct load_order load_order; 00704 int res = 0; 00705 #if LOADABLE_MODULES 00706 struct dirent *dirent; 00707 DIR *dir; 00708 #endif 00709 00710 /* all embedded modules have registered themselves by now */ 00711 embedding = 0; 00712 00713 if (option_verbose) 00714 ast_verbose("Asterisk Dynamic Loader Starting:\n"); 00715 00716 AST_LIST_TRAVERSE(&module_list, mod, entry) { 00717 if (option_debug > 1) 00718 ast_log(LOG_DEBUG, "Embedded module found: %s\n", mod->resource); 00719 } 00720 00721 if (!(cfg = ast_config_load(AST_MODULE_CONFIG))) { 00722 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG); 00723 return 0; 00724 } 00725 00726 AST_LIST_HEAD_INIT_NOLOCK(&load_order); 00727 00728 /* first, find all the modules we have been explicitly requested to load */ 00729 for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) { 00730 if (!strcasecmp(v->name, preload_only ? "preload" : "load")) 00731 add_to_load_order(v->value, &load_order); 00732 } 00733 00734 /* check if 'autoload' is on */ 00735 if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) { 00736 /* if so, first add all the embedded modules to the load order */ 00737 AST_LIST_TRAVERSE(&module_list, mod, entry) 00738 order = add_to_load_order(mod->resource, &load_order); 00739 00740 #if LOADABLE_MODULES 00741 /* if we are allowed to load dynamic modules, scan the directory for 00742 for all available modules and add them as well */ 00743 if ((dir = opendir(ast_config_AST_MODULE_DIR))) { 00744 while ((dirent = readdir(dir))) { 00745 int ld = strlen(dirent->d_name); 00746 00747 /* Must end in .so to load it. */ 00748 00749 if (ld < 4) 00750 continue; 00751 00752 if (strcasecmp(dirent->d_name + ld - 3, ".so")) 00753 continue; 00754 00755 add_to_load_order(dirent->d_name, &load_order); 00756 00757 } 00758 00759 closedir(dir); 00760 } else { 00761 if (!ast_opt_quiet) 00762 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n", 00763 ast_config_AST_MODULE_DIR); 00764 } 00765 #endif 00766 } 00767 00768 /* now scan the config for any modules we are prohibited from loading and 00769 remove them from the load order */ 00770 for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) { 00771 if (strcasecmp(v->name, "noload")) 00772 continue; 00773 00774 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) { 00775 if (!resource_name_match(order->resource, v->value)) { 00776 AST_LIST_REMOVE_CURRENT(&load_order, entry); 00777 free(order->resource); 00778 free(order); 00779 } 00780 } 00781 AST_LIST_TRAVERSE_SAFE_END; 00782 } 00783 00784 /* we are done with the config now, all the information we need is in the 00785 load_order list */ 00786 ast_config_destroy(cfg); 00787 00788 load_count = 0; 00789 AST_LIST_TRAVERSE(&load_order, order, entry) 00790 load_count++; 00791 00792 if (load_count) 00793 ast_log(LOG_NOTICE, "%d modules will be loaded.\n", load_count); 00794 00795 /* first, load only modules that provide global symbols */ 00796 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) { 00797 switch (load_resource(order->resource, 1)) { 00798 case AST_MODULE_LOAD_SUCCESS: 00799 case AST_MODULE_LOAD_DECLINE: 00800 AST_LIST_REMOVE_CURRENT(&load_order, entry); 00801 free(order->resource); 00802 free(order); 00803 break; 00804 case AST_MODULE_LOAD_FAILURE: 00805 res = -1; 00806 goto done; 00807 case AST_MODULE_LOAD_SKIP: 00808 /* try again later */ 00809 break; 00810 } 00811 } 00812 AST_LIST_TRAVERSE_SAFE_END; 00813 00814 /* now load everything else */ 00815 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) { 00816 switch (load_resource(order->resource, 0)) { 00817 case AST_MODULE_LOAD_SUCCESS: 00818 case AST_MODULE_LOAD_DECLINE: 00819 AST_LIST_REMOVE_CURRENT(&load_order, entry); 00820 free(order->resource); 00821 free(order); 00822 break; 00823 case AST_MODULE_LOAD_FAILURE: 00824 res = -1; 00825 goto done; 00826 case AST_MODULE_LOAD_SKIP: 00827 /* should not happen */ 00828 break; 00829 } 00830 } 00831 AST_LIST_TRAVERSE_SAFE_END; 00832 00833 done: 00834 while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) { 00835 free(order->resource); 00836 free(order); 00837 } 00838 00839 return res; 00840 }
|
|
||||||||||||
|
Definition at line 590 of file loader.c. References ast_clear_flag, ast_fully_booted, ast_log(), AST_MODFLAG_GLOBAL_SYMBOLS, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SKIP, AST_MODULE_LOAD_SUCCESS, ast_opt_console, ast_set_flag, ast_test_flag, ast_update_use_count(), ast_verbose(), COLOR_BLACK, COLOR_BROWN, ast_module_info::description, find_resource(), FLAG_DECLINED, FLAG_RUNNING, ast_module::info, inspect_module(), ast_module_info::load, option_verbose, term_color(), and VERBOSE_PREFIX_1. Referenced by ast_load_resource(). 00591 { 00592 struct ast_module *mod; 00593 enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS; 00594 char tmp[256]; 00595 00596 if ((mod = find_resource(resource_name, 0))) { 00597 if (ast_test_flag(mod, FLAG_RUNNING)) { 00598 ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name); 00599 return AST_MODULE_LOAD_DECLINE; 00600 } 00601 if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS)) 00602 return AST_MODULE_LOAD_SKIP; 00603 } else { 00604 #if LOADABLE_MODULES 00605 if (!(mod = load_dynamic_module(resource_name, global_symbols_only))) { 00606 /* don't generate a warning message during load_modules() */ 00607 if (!global_symbols_only) { 00608 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); 00609 return AST_MODULE_LOAD_DECLINE; 00610 } else { 00611 return AST_MODULE_LOAD_SKIP; 00612 } 00613 } 00614 #else 00615 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); 00616 return AST_MODULE_LOAD_DECLINE; 00617 #endif 00618 } 00619 00620 if (inspect_module(mod)) { 00621 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); 00622 #if LOADABLE_MODULES 00623 unload_dynamic_module(mod); 00624 #endif 00625 return AST_MODULE_LOAD_DECLINE; 00626 } 00627 00628 ast_clear_flag(mod, FLAG_DECLINED); 00629 00630 if (mod->info->load) 00631 res = mod->info->load(); 00632 00633 switch (res) { 00634 case AST_MODULE_LOAD_SUCCESS: 00635 if (!ast_fully_booted) { 00636 if (option_verbose) 00637 ast_verbose("%s => (%s)\n", resource_name, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp))); 00638 if (ast_opt_console && !option_verbose) 00639 ast_verbose( "."); 00640 } else { 00641 if (option_verbose) 00642 ast_verbose(VERBOSE_PREFIX_1 "Loaded %s => (%s)\n", resource_name, mod->info->description); 00643 } 00644 00645 ast_set_flag(mod, FLAG_RUNNING); 00646 00647 ast_update_use_count(); 00648 break; 00649 case AST_MODULE_LOAD_DECLINE: 00650 ast_set_flag(mod, FLAG_DECLINED); 00651 break; 00652 case AST_MODULE_LOAD_FAILURE: 00653 break; 00654 case AST_MODULE_LOAD_SKIP: 00655 /* modules should never return this value */ 00656 break; 00657 } 00658 00659 return res; 00660 }
|
|
|
Definition at line 245 of file loader.c. References ast_log(), LOG_DEBUG, and option_debug. Referenced by verify_key(). 00246 { 00247 int x, pos; 00248 char buf[256]; /* large enough so we don't have to worry */ 00249 00250 for (pos = 0, x = 0; x < 16; x++) 00251 pos += sprintf(buf + pos, " %02x", *d++); 00252 00253 if (option_debug) 00254 ast_log(LOG_DEBUG, "Unexpected signature:%s\n", buf); 00255 00256 return 0; 00257 }
|
|
||||||||||||
|
Definition at line 288 of file loader.c. References ast_strdupa. Referenced by add_to_load_order(), and find_resource(). 00289 { 00290 char *name1 = (char *) name1_in; 00291 char *name2 = (char *) name2_in; 00292 00293 /* trim off any .so extensions */ 00294 if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) { 00295 name1 = ast_strdupa(name1); 00296 name1[strlen(name1) - 3] = '\0'; 00297 } 00298 if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) { 00299 name2 = ast_strdupa(name2); 00300 name2[strlen(name2) - 3] = '\0'; 00301 } 00302 00303 return strcasecmp(name1, name2); 00304 }
|
|
|
Definition at line 271 of file loader.c. References expected_key, key_matches(), MD5Final(), MD5Init(), MD5Update(), and printdigest(). Referenced by inspect_module(). 00272 { 00273 struct MD5Context c; 00274 unsigned char digest[16]; 00275 00276 MD5Init(&c); 00277 MD5Update(&c, key, strlen((char *)key)); 00278 MD5Final(digest, &c); 00279 00280 if (key_matches(expected_key, digest)) 00281 return 0; 00282 00283 printdigest(digest); 00284 00285 return -1; 00286 }
|
|
|
Definition at line 79 of file loader.c. Referenced by ast_module_register(), and load_modules(). |
|
|
Initial value:
{ 0x87, 0x76, 0x79, 0x35, 0x23, 0xea, 0x3a, 0xd3,
0x25, 0x2a, 0xbb, 0x35, 0x87, 0xe4, 0x22, 0x24 }
Definition at line 75 of file loader.c. Referenced by verify_key(). |
|
|
Definition at line 113 of file loader.c. Referenced by ast_module_register(). |