#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"
Go to the source code of this file.
Data Structures | |
struct | ast_module |
struct | ast_module_user |
struct | load_order |
struct | load_order_entry |
struct | loadupdate |
struct | module_list |
struct | module_user_list |
struct | reload_classes |
struct | reload_queue |
struct | reload_queue_item |
struct | updaters |
Defines | |
#define | RTLD_NOW 0 |
Enumerations | |
enum | module_load_pass { LOAD_FIRST, LOAD_GLOBAL_SYMBOLS, LOAD_ALL, LOAD_DONE } |
Load modules in this order. More... | |
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) |
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 (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_shutdown (void) |
Run the unload() callback for all loaded modules. | |
void | ast_module_unref (struct ast_module *mod) |
void | ast_module_unregister (const struct ast_module_info *info) |
void | ast_process_pending_reloads (void) |
Process reload requests received during startup. | |
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) |
static struct ast_module * | load_dynamic_module (const char *resource_in, enum module_load_pass load_pass) |
int | load_modules (unsigned int preload_only) |
static enum ast_module_load_result | load_resource (const char *resource_name, enum module_load_pass load_pass) |
static int | printdigest (const unsigned char *d) |
static void | queue_reload_request (const char *module) |
static int | resource_name_match (const char *name1_in, const char *name2_in) |
static int | translate_module_name (char *oldname, char *newname) |
static void | unload_dynamic_module (struct ast_module *mod) |
static int | verify_key (const unsigned char *key) |
Variables | |
static char | buildopt_sum [33] = AST_BUILDOPT_SUM |
static int | do_full_reload = 0 |
static unsigned int | embedding = 1 |
static unsigned char | expected_key [] |
static ast_mutex_t | reloadlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
ast_module * | resource_being_loaded |
Kevin P. Fleming <kpfleming@digium.com>
Luigi Rizzo <rizzo@icir.org>
Definition in file loader.c.
#define RTLD_NOW 0 |
enum module_load_pass |
Load modules in this order.
LOAD_FIRST | AST_MODFLAG_LOAD_FIRST. |
LOAD_GLOBAL_SYMBOLS | AST_MODFLAG_GLOBAL_SYMBOLS. |
LOAD_ALL | everything that is left |
LOAD_DONE | Must remain at the end. |
Definition at line 121 of file loader.c.
00121 { 00122 /*! \brief AST_MODFLAG_LOAD_FIRST */ 00123 LOAD_FIRST, 00124 /*! \brief AST_MODFLAG_GLOBAL_SYMBOLS */ 00125 LOAD_GLOBAL_SYMBOLS, 00126 /*! \brief everything that is left */ 00127 LOAD_ALL, 00128 00129 /*! \brief Must remain at the end. */ 00130 LOAD_DONE, 00131 };
struct ast_module_user* __ast_module_user_add | ( | struct ast_module * | mod, | |
struct ast_channel * | chan | |||
) |
Definition at line 197 of file loader.c.
References ast_atomic_fetchadd_int(), ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_update_use_count(), ast_module_user::chan, ast_module_user::entry, ast_module::usecount, and ast_module::users.
00199 { 00200 struct ast_module_user *u = ast_calloc(1, sizeof(*u)); 00201 00202 if (!u) 00203 return NULL; 00204 00205 u->chan = chan; 00206 00207 AST_LIST_LOCK(&mod->users); 00208 AST_LIST_INSERT_HEAD(&mod->users, u, entry); 00209 AST_LIST_UNLOCK(&mod->users); 00210 00211 ast_atomic_fetchadd_int(&mod->usecount, +1); 00212 00213 ast_update_use_count(); 00214 00215 return u; 00216 }
void __ast_module_user_hangup_all | ( | struct ast_module * | mod | ) |
Definition at line 229 of file loader.c.
References ast_atomic_fetchadd_int(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_update_use_count(), ast_module_user::chan, ast_module_user::entry, free, ast_module::usecount, and ast_module::users.
Referenced by ast_unload_resource().
00230 { 00231 struct ast_module_user *u; 00232 00233 AST_LIST_LOCK(&mod->users); 00234 while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) { 00235 ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD); 00236 ast_atomic_fetchadd_int(&mod->usecount, -1); 00237 free(u); 00238 } 00239 AST_LIST_UNLOCK(&mod->users); 00240 00241 ast_update_use_count(); 00242 }
void __ast_module_user_remove | ( | struct ast_module * | mod, | |
struct ast_module_user * | u | |||
) |
Definition at line 218 of file loader.c.
References ast_atomic_fetchadd_int(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_update_use_count(), ast_module_user::entry, free, ast_module::usecount, and ast_module::users.
00219 { 00220 AST_LIST_LOCK(&mod->users); 00221 AST_LIST_REMOVE(&mod->users, u, entry); 00222 AST_LIST_UNLOCK(&mod->users); 00223 ast_atomic_fetchadd_int(&mod->usecount, -1); 00224 free(u); 00225 00226 ast_update_use_count(); 00227 }
static struct load_order_entry* add_to_load_order | ( | const char * | resource, | |
struct load_order * | load_order | |||
) | [static] |
Definition at line 853 of file loader.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_strdup, ast_module_user::entry, load_order_entry::resource, and resource_name_match().
Referenced by load_modules().
00854 { 00855 struct load_order_entry *order; 00856 00857 AST_LIST_TRAVERSE(load_order, order, entry) { 00858 if (!resource_name_match(order->resource, resource)) 00859 return NULL; 00860 } 00861 00862 if (!(order = ast_calloc(1, sizeof(*order)))) 00863 return NULL; 00864 00865 order->resource = ast_strdup(resource); 00866 AST_LIST_INSERT_TAIL(load_order, order, entry); 00867 00868 return order; 00869 }
int ast_load_resource | ( | const char * | resource_name | ) |
Load a module.
resource_name | The name of the module to load. |
Definition at line 837 of file loader.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, LOAD_ALL, and load_resource().
Referenced by file_ok_sel(), handle_load(), handle_load_deprecated(), and reload().
00838 { 00839 AST_LIST_LOCK(&module_list); 00840 load_resource(resource_name, LOAD_ALL); 00841 AST_LIST_UNLOCK(&module_list); 00842 00843 return 0; 00844 }
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 1073 of file loader.c.
References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_malloc, and ast_module_user::entry.
Referenced by show_console().
01074 { 01075 struct loadupdate *tmp; 01076 01077 if (!(tmp = ast_malloc(sizeof(*tmp)))) 01078 return -1; 01079 01080 tmp->updater = v; 01081 AST_LIST_LOCK(&updaters); 01082 AST_LIST_INSERT_HEAD(&updaters, tmp, entry); 01083 AST_LIST_UNLOCK(&updaters); 01084 01085 return 0; 01086 }
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 1088 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, ast_module_user::entry, and loadupdate::updater.
Referenced by exit_now().
01089 { 01090 struct loadupdate *cur; 01091 01092 AST_LIST_LOCK(&updaters); 01093 AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) { 01094 if (cur->updater == v) { 01095 AST_LIST_REMOVE_CURRENT(&updaters, entry); 01096 break; 01097 } 01098 } 01099 AST_LIST_TRAVERSE_SAFE_END; 01100 AST_LIST_UNLOCK(&updaters); 01101 01102 return cur ? 0 : -1; 01103 }
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.
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 557 of file loader.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_module_user::entry, ast_module::info, name, ast_module_info::reload, ast_module::resource, and strdup.
Referenced by complete_mod_2(), complete_mod_2_nr(), complete_mod_3(), complete_mod_3_nr(), complete_mod_4(), and load_module().
00558 { 00559 struct ast_module *cur; 00560 int i, which=0, l = strlen(word); 00561 char *ret = NULL; 00562 00563 if (pos != rpos) 00564 return NULL; 00565 00566 AST_LIST_LOCK(&module_list); 00567 AST_LIST_TRAVERSE(&module_list, cur, entry) { 00568 if (!strncasecmp(word, cur->resource, l) && 00569 (cur->info->reload || !needsreload) && 00570 ++which > state) { 00571 ret = strdup(cur->resource); 00572 break; 00573 } 00574 } 00575 AST_LIST_UNLOCK(&module_list); 00576 00577 if (!ret) { 00578 for (i=0; !ret && reload_classes[i].name; i++) { 00579 if (!strncasecmp(word, reload_classes[i].name, l) && ++which > state) 00580 ret = strdup(reload_classes[i].name); 00581 } 00582 } 00583 00584 return ret; 00585 }
struct ast_module* ast_module_ref | ( | struct ast_module * | mod | ) |
Definition at line 1105 of file loader.c.
References ast_atomic_fetchadd_int(), ast_update_use_count(), and ast_module::usecount.
Referenced by __oh323_new(), alsa_new(), ast_iax2_new(), cli_audio_convert(), cli_audio_convert_deprecated(), complete_orig(), dahdi_new(), features_new(), fn_wrapper(), gtalk_new(), handle_orig(), mgcp_new(), newpvt(), oss_new(), phone_check_exception(), phone_new(), sip_new(), and skinny_new().
01106 { 01107 ast_atomic_fetchadd_int(&mod->usecount, +1); 01108 ast_update_use_count(); 01109 01110 return mod; 01111 }
void ast_module_register | ( | const struct ast_module_info * | info | ) |
Definition at line 135 of file loader.c.
References ast_calloc, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, embedding, ast_module_user::entry, ast_module::info, ast_module_info::name, resource_being_loaded, ast_module_info::self, and ast_module::users.
00136 { 00137 struct ast_module *mod; 00138 00139 if (embedding) { 00140 if (!(mod = ast_calloc(1, sizeof(*mod) + strlen(info->name) + 1))) 00141 return; 00142 strcpy(mod->resource, info->name); 00143 } else { 00144 mod = resource_being_loaded; 00145 } 00146 00147 mod->info = info; 00148 AST_LIST_HEAD_INIT(&mod->users); 00149 00150 /* during startup, before the loader has been initialized, 00151 there are no threads, so there is no need to take the lock 00152 on this list to manipulate it. it is also possible that it 00153 might be unsafe to use the list lock at that point... so 00154 let's avoid it altogether 00155 */ 00156 if (!embedding) 00157 AST_LIST_LOCK(&module_list); 00158 00159 /* it is paramount that the new entry be placed at the tail of 00160 the list, otherwise the code that uses dlopen() to load 00161 dynamic modules won't be able to find out if the module it 00162 just opened was registered or failed to load 00163 */ 00164 AST_LIST_INSERT_TAIL(&module_list, mod, entry); 00165 00166 if (!embedding) 00167 AST_LIST_UNLOCK(&module_list); 00168 00169 /* give the module a copy of its own handle, for later use in registrations and the like */ 00170 *((struct ast_module **) &(info->self)) = mod; 00171 }
int ast_module_reload | ( | const char * | name | ) |
Reload asterisk modules.
name | the name of the module to reload |
Definition at line 652 of file loader.c.
References ast_fully_booted, ast_lastreloadtime, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_verbose(), ast_module::declined, ast_module_info::description, ast_module_user::entry, ast_module::flags, ast_module::info, LOG_NOTICE, option_verbose, queue_reload_request(), ast_module_info::reload, ast_module::resource, resource_name_match(), ast_module::running, and VERBOSE_PREFIX_3.
Referenced by action_updateconfig(), ast_process_pending_reloads(), handle_reload(), handle_reload_deprecated(), and monitor_sig_flags().
00653 { 00654 struct ast_module *cur; 00655 int res = 0; /* return value. 0 = not found, others, see below */ 00656 int i; 00657 00658 /* If we aren't fully booted, we just pretend we reloaded but we queue this 00659 up to run once we are booted up. */ 00660 if (!ast_fully_booted) { 00661 queue_reload_request(name); 00662 return 0; 00663 } 00664 00665 if (ast_mutex_trylock(&reloadlock)) { 00666 ast_verbose("The previous reload command didn't finish yet\n"); 00667 return -1; /* reload already in progress */ 00668 } 00669 ast_lastreloadtime = time(NULL); 00670 00671 /* Call "predefined" reload here first */ 00672 for (i = 0; reload_classes[i].name; i++) { 00673 if (!name || !strcasecmp(name, reload_classes[i].name)) { 00674 reload_classes[i].reload_fn(); /* XXX should check error ? */ 00675 res = 2; /* found and reloaded */ 00676 } 00677 } 00678 00679 if (name && res) { 00680 ast_mutex_unlock(&reloadlock); 00681 return res; 00682 } 00683 00684 AST_LIST_LOCK(&module_list); 00685 AST_LIST_TRAVERSE(&module_list, cur, entry) { 00686 const struct ast_module_info *info = cur->info; 00687 00688 if (name && resource_name_match(name, cur->resource)) 00689 continue; 00690 00691 if (!cur->flags.running || cur->flags.declined) { 00692 if (!name) 00693 continue; 00694 ast_log(LOG_NOTICE, "The module '%s' was not properly initialized. " 00695 "Before reloading the module, you must run \"module load %s\" " 00696 "and fix whatever is preventing the module from being initialized.\n", 00697 name, name); 00698 res = 2; /* Don't report that the module was not found */ 00699 break; 00700 } 00701 00702 if (!info->reload) { /* cannot be reloaded */ 00703 if (res < 1) /* store result if possible */ 00704 res = 1; /* 1 = no reload() method */ 00705 continue; 00706 } 00707 00708 res = 2; 00709 if (option_verbose > 2) 00710 ast_verbose(VERBOSE_PREFIX_3 "Reloading module '%s' (%s)\n", cur->resource, info->description); 00711 info->reload(); 00712 } 00713 AST_LIST_UNLOCK(&module_list); 00714 00715 ast_mutex_unlock(&reloadlock); 00716 00717 return res; 00718 }
void ast_module_shutdown | ( | void | ) |
Run the unload() callback for all loaded modules.
This function should be called when Asterisk is shutting down gracefully.
If we go through the entire list without changing anything, ignore the usecounts and unload, then exit.
Definition at line 456 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, ast_module::declined, ast_module_user::entry, ast_module::flags, free, ast_module::info, ast_module::running, ast_module_info::unload, ast_module::usecount, and ast_module::users.
Referenced by quit_handler().
00457 { 00458 struct ast_module *mod; 00459 int somethingchanged = 1, final = 0; 00460 00461 AST_LIST_LOCK(&module_list); 00462 00463 /*!\note Some resources, like timers, are started up dynamically, and thus 00464 * may be still in use, even if all channels are dead. We must therefore 00465 * check the usecount before asking modules to unload. */ 00466 do { 00467 if (!somethingchanged) { 00468 /*!\note If we go through the entire list without changing 00469 * anything, ignore the usecounts and unload, then exit. */ 00470 final = 1; 00471 } 00472 00473 /* Reset flag before traversing the list */ 00474 somethingchanged = 0; 00475 00476 AST_LIST_TRAVERSE_SAFE_BEGIN(&module_list, mod, entry) { 00477 if (!final && mod->usecount) { 00478 continue; 00479 } 00480 AST_LIST_REMOVE_CURRENT(&module_list, entry); 00481 if (mod->flags.running && !mod->flags.declined && mod->info->unload) { 00482 mod->info->unload(); 00483 } 00484 AST_LIST_HEAD_DESTROY(&mod->users); 00485 free(mod); 00486 somethingchanged = 1; 00487 } 00488 AST_LIST_TRAVERSE_SAFE_END; 00489 } while (somethingchanged && !final); 00490 00491 AST_LIST_UNLOCK(&module_list); 00492 }
void ast_module_unref | ( | struct ast_module * | mod | ) |
Definition at line 1113 of file loader.c.
References ast_atomic_fetchadd_int(), ast_update_use_count(), and ast_module::usecount.
Referenced by alsa_hangup(), ast_smdi_interface_destroy(), cli_audio_convert(), cli_audio_convert_deprecated(), complete_orig(), dahdi_destroy_channel_bynum(), dahdi_hangup(), destroy(), filestream_destructor(), gtalk_hangup(), handle_orig(), iax2_predestroy(), mgcp_hangup(), oh323_hangup(), oss_hangup(), phone_check_exception(), phone_hangup(), and sip_hangup().
01114 { 01115 ast_atomic_fetchadd_int(&mod->usecount, -1); 01116 ast_update_use_count(); 01117 }
void ast_module_unregister | ( | const struct ast_module_info * | info | ) |
Definition at line 173 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, ast_module_user::entry, free, ast_module::info, and ast_module::users.
00174 { 00175 struct ast_module *mod = NULL; 00176 00177 /* it is assumed that the users list in the module structure 00178 will already be empty, or we cannot have gotten to this 00179 point 00180 */ 00181 AST_LIST_LOCK(&module_list); 00182 AST_LIST_TRAVERSE_SAFE_BEGIN(&module_list, mod, entry) { 00183 if (mod->info == info) { 00184 AST_LIST_REMOVE_CURRENT(&module_list, entry); 00185 break; 00186 } 00187 } 00188 AST_LIST_TRAVERSE_SAFE_END; 00189 AST_LIST_UNLOCK(&module_list); 00190 00191 if (mod) { 00192 AST_LIST_HEAD_DESTROY(&mod->users); 00193 free(mod); 00194 } 00195 }
void ast_process_pending_reloads | ( | void | ) |
Process reload requests received during startup.
This function requests that the loader execute the pending reload requests that were queued during server startup.
Definition at line 587 of file loader.c.
References ast_free, ast_fully_booted, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_log(), ast_module_reload(), do_full_reload, ast_module_user::entry, LOG_NOTICE, and reload_queue_item::module.
Referenced by main().
00588 { 00589 struct reload_queue_item *item; 00590 00591 if (!ast_fully_booted) { 00592 return; 00593 } 00594 00595 AST_LIST_LOCK(&reload_queue); 00596 00597 if (do_full_reload) { 00598 do_full_reload = 0; 00599 AST_LIST_UNLOCK(&reload_queue); 00600 ast_log(LOG_NOTICE, "Executing deferred reload request.\n"); 00601 ast_module_reload(NULL); 00602 return; 00603 } 00604 00605 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) { 00606 ast_log(LOG_NOTICE, "Executing deferred reload request for module '%s'.\n", item->module); 00607 ast_module_reload(item->module); 00608 ast_free(item); 00609 } 00610 00611 AST_LIST_UNLOCK(&reload_queue); 00612 }
int ast_unload_resource | ( | const char * | resource_name, | |
enum | ast_module_unload_mode | |||
) |
Unload a module.
resource_name | The name of the module to unload. | |
ast_module_unload_mode | The force flag. This should be set using one of the AST_FORCE flags. |
Definition at line 494 of file loader.c.
References __ast_module_user_hangup_all(), AST_FORCE_FIRM, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_update_use_count(), ast_module::declined, find_resource(), ast_module::flags, ast_module::lib, LOG_WARNING, ast_module::running, unload_dynamic_module(), and ast_module::usecount.
Referenced by exit_now(), handle_unload(), handle_unload_deprecated(), reload(), and remove_module().
00495 { 00496 struct ast_module *mod; 00497 int res = -1; 00498 int error = 0; 00499 00500 AST_LIST_LOCK(&module_list); 00501 00502 if (!(mod = find_resource(resource_name, 0))) { 00503 AST_LIST_UNLOCK(&module_list); 00504 return 0; 00505 } 00506 00507 if (!mod->flags.running || mod->flags.declined) { 00508 ast_log(LOG_WARNING, "Unload failed, '%s' is not loaded.\n", resource_name); 00509 error = 1; 00510 } 00511 00512 if (!mod->lib) { 00513 ast_log(LOG_WARNING, "Unloading embedded modules is not supported.\n"); 00514 error = 1; 00515 } 00516 00517 if (!error && (mod->usecount > 0)) { 00518 if (force) 00519 ast_log(LOG_WARNING, "Warning: Forcing removal of module '%s' with use count %d\n", 00520 resource_name, mod->usecount); 00521 else { 00522 ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name, 00523 mod->usecount); 00524 error = 1; 00525 } 00526 } 00527 00528 if (!error) { 00529 __ast_module_user_hangup_all(mod); 00530 res = mod->info->unload(); 00531 00532 if (res) { 00533 ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name); 00534 if (force <= AST_FORCE_FIRM) 00535 error = 1; 00536 else 00537 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n"); 00538 } 00539 } 00540 00541 if (!error) 00542 mod->flags.running = mod->flags.declined = 0; 00543 00544 AST_LIST_UNLOCK(&module_list); 00545 00546 #ifdef LOADABLE_MODULES 00547 if (!error) 00548 unload_dynamic_module(mod); 00549 #endif 00550 00551 if (!error) 00552 ast_update_use_count(); 00553 00554 return res; 00555 }
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 1053 of file loader.c.
References AST_LIST_TRAVERSE, AST_LIST_TRYLOCK, AST_LIST_UNLOCK, ast_module_info::description, ast_module_user::entry, ast_module::info, ast_module::resource, and ast_module::usecount.
Referenced by handle_modlist(), and mod_update().
01055 { 01056 struct ast_module *cur; 01057 int unlock = -1; 01058 int total_mod_loaded = 0; 01059 01060 if (AST_LIST_TRYLOCK(&module_list)) 01061 unlock = 0; 01062 01063 AST_LIST_TRAVERSE(&module_list, cur, entry) { 01064 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, like); 01065 } 01066 01067 if (unlock) 01068 AST_LIST_UNLOCK(&module_list); 01069 01070 return total_mod_loaded; 01071 }
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 1041 of file loader.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_module_user::entry, and loadupdate::updater.
Referenced by __ast_module_user_add(), __ast_module_user_hangup_all(), __ast_module_user_remove(), agent_new(), ast_module_ref(), ast_module_unref(), ast_unload_resource(), exit_now(), load_module(), load_resource(), oh323_request(), sip_request_call(), and sipsock_read().
01042 { 01043 /* Notify any module monitors that the use count for a 01044 resource has changed */ 01045 struct loadupdate *m; 01046 01047 AST_LIST_LOCK(&updaters); 01048 AST_LIST_TRAVERSE(&updaters, m, entry) 01049 m->updater(); 01050 AST_LIST_UNLOCK(&updaters); 01051 }
static struct ast_module* find_resource | ( | const char * | resource, | |
int | do_lock | |||
) | [static] |
Definition at line 325 of file loader.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_module_user::entry, ast_module::resource, and resource_name_match().
Referenced by ast_unload_resource(), and load_resource().
00326 { 00327 struct ast_module *cur; 00328 00329 if (do_lock) 00330 AST_LIST_LOCK(&module_list); 00331 00332 AST_LIST_TRAVERSE(&module_list, cur, entry) { 00333 if (!resource_name_match(resource, cur->resource)) 00334 break; 00335 } 00336 00337 if (do_lock) 00338 AST_LIST_UNLOCK(&module_list); 00339 00340 return cur; 00341 }
static unsigned int inspect_module | ( | const struct ast_module * | mod | ) | [static] |
Definition at line 720 of file loader.c.
References ast_log(), AST_MODFLAG_BUILDSUM, ast_strlen_zero(), ast_test_flag, buildopt_sum, ast_module_info::buildopt_sum, ast_module_info::description, ast_module::info, ast_module_info::key, LOG_WARNING, ast_module::resource, and verify_key().
Referenced by load_resource().
00721 { 00722 if (!mod->info->description) { 00723 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource); 00724 return 1; 00725 } 00726 00727 if (!mod->info->key) { 00728 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource); 00729 return 1; 00730 } 00731 00732 if (verify_key((unsigned char *) mod->info->key)) { 00733 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource); 00734 return 1; 00735 } 00736 00737 if (!ast_test_flag(mod->info, AST_MODFLAG_BUILDSUM)) { 00738 ast_log(LOG_WARNING, "Module '%s' was not compiled against a recent version of Asterisk and may cause instability.\n", mod->resource); 00739 } else if (!ast_strlen_zero(mod->info->buildopt_sum) && 00740 strcmp(buildopt_sum, mod->info->buildopt_sum)) { 00741 ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource); 00742 ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource); 00743 return 1; 00744 } 00745 00746 return 0; 00747 }
static int key_matches | ( | const unsigned char * | key1, | |
const unsigned char * | key2 | |||
) | [static] |
Definition at line 278 of file loader.c.
Referenced by verify_key().
00279 { 00280 int x; 00281 00282 for (x = 0; x < 16; x++) { 00283 if (key1[x] != key2[x]) 00284 return 0; 00285 } 00286 00287 return 1; 00288 }
static struct ast_module* load_dynamic_module | ( | const char * | resource_in, | |
enum module_load_pass | load_pass | |||
) | [static] |
Definition at line 356 of file loader.c.
References ast_calloc, ast_config_AST_MODULE_DIR, AST_LIST_LAST, ast_log(), AST_MODFLAG_GLOBAL_SYMBOLS, AST_MODFLAG_LOAD_FIRST, ast_test_flag, free, ast_module::info, ast_module::lib, LOAD_ALL, LOAD_DONE, LOAD_FIRST, LOAD_GLOBAL_SYMBOLS, LOG_ERROR, LOG_WARNING, resource_being_loaded, and RTLD_NOW.
Referenced by load_resource().
00357 { 00358 char fn[256]; 00359 void *lib; 00360 struct ast_module *mod; 00361 char *resource = (char *) resource_in; 00362 unsigned int wants_global = 0, not_yet = 0; 00363 00364 if (strcasecmp(resource + strlen(resource) - 3, ".so")) { 00365 resource = alloca(strlen(resource_in) + 3); 00366 strcpy(resource, resource_in); 00367 strcat(resource, ".so"); 00368 } 00369 00370 snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_MODULE_DIR, resource); 00371 00372 /* make a first load of the module in 'quiet' mode... don't try to resolve 00373 any symbols, and don't export any symbols. this will allow us to peek into 00374 the module's info block (if available) to see what flags it has set */ 00375 00376 if (!(resource_being_loaded = ast_calloc(1, sizeof(*resource_being_loaded) + strlen(resource) + 1))) 00377 return NULL; 00378 00379 strcpy(resource_being_loaded->resource, resource); 00380 00381 /* libopenh323 is buggy and segfaults on dlclose() when opened with 00382 * RTLD_LAZY. Workaround this until it gets fixed */ 00383 if (!strcasecmp(resource, "chan_h323.so") || 00384 !strcasecmp(resource, "chan_oh323.so")) 00385 lib = dlopen(fn, RTLD_NOW | RTLD_LOCAL); 00386 00387 if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_LOCAL))) { 00388 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror()); 00389 free(resource_being_loaded); 00390 return NULL; 00391 } 00392 00393 /* the dlopen() succeeded, let's find out if the module 00394 registered itself */ 00395 /* note that this will only work properly as long as 00396 ast_module_register() (which is called by the module's 00397 constructor) places the new module at the tail of the 00398 module_list 00399 */ 00400 if (resource_being_loaded != (mod = AST_LIST_LAST(&module_list))) { 00401 ast_log(LOG_WARNING, "Module '%s' did not register itself during load\n", resource_in); 00402 /* no, it did not, so close it and return */ 00403 while (!dlclose(lib)); 00404 /* note that the module's destructor will call ast_module_unregister(), 00405 which will free the structure we allocated in resource_being_loaded */ 00406 return NULL; 00407 } 00408 00409 wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS); 00410 switch (load_pass) { 00411 case LOAD_FIRST: 00412 not_yet = !ast_test_flag(mod->info, AST_MODFLAG_LOAD_FIRST); 00413 break; 00414 case LOAD_GLOBAL_SYMBOLS: 00415 not_yet = !wants_global; 00416 break; 00417 case LOAD_ALL: 00418 break; 00419 case LOAD_DONE: 00420 ast_log(LOG_ERROR, "Satan just bought a snowblower! (This should never happen, btw.)\n"); 00421 break; 00422 } 00423 00424 if (not_yet) { 00425 while (!dlclose(lib)); 00426 return NULL; 00427 } 00428 00429 while (!dlclose(lib)); 00430 resource_being_loaded = NULL; 00431 00432 /* start the load process again */ 00433 00434 if (!(resource_being_loaded = ast_calloc(1, sizeof(*resource_being_loaded) + strlen(resource) + 1))) 00435 return NULL; 00436 00437 strcpy(resource_being_loaded->resource, resource); 00438 00439 if (!(lib = dlopen(fn, wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) { 00440 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror()); 00441 free(resource_being_loaded); 00442 return NULL; 00443 } 00444 00445 /* since the module was successfully opened, and it registered itself 00446 the previous time we did that, we're going to assume it worked this 00447 time too :) */ 00448 00449 AST_LIST_LAST(&module_list)->lib = lib; 00450 resource_being_loaded = NULL; 00451 00452 return AST_LIST_LAST(&module_list); 00453 }
int load_modules | ( | unsigned | int | ) |
Provided by loader.c
Definition at line 888 of file loader.c.
References add_to_load_order(), ast_config_load(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_LOCK, ast_log(), AST_MODULE_CONFIG, ast_variable_browse(), ast_verbose(), embedding, LOG_WARNING, ast_variable::name, ast_variable::next, option_verbose, translate_module_name(), and ast_variable::value.
Referenced by main().
00889 { 00890 struct ast_config *cfg; 00891 struct ast_module *mod; 00892 struct load_order_entry *order; 00893 struct ast_variable *v; 00894 unsigned int load_count; 00895 struct load_order load_order; 00896 int res = 0; 00897 int load_pass; 00898 00899 int translate_status; 00900 char newname[18]; /* although this would normally be 80, max length in translate_module_name is 18 */ 00901 #ifdef LOADABLE_MODULES 00902 struct dirent *dirent; 00903 DIR *dir; 00904 #endif 00905 00906 /* all embedded modules have registered themselves by now */ 00907 embedding = 0; 00908 00909 if (option_verbose) 00910 ast_verbose("Asterisk Dynamic Loader Starting:\n"); 00911 00912 AST_LIST_HEAD_INIT_NOLOCK(&load_order); 00913 00914 AST_LIST_LOCK(&module_list); 00915 00916 if (!(cfg = ast_config_load(AST_MODULE_CONFIG))) { 00917 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG); 00918 goto done; 00919 } 00920 00921 /* first, find all the modules we have been explicitly requested to load */ 00922 for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) { 00923 if (!strcasecmp(v->name, preload_only ? "preload" : "load")) { 00924 translate_status = translate_module_name(v->value, newname); 00925 if (!translate_status) 00926 ast_log(LOG_WARNING, "Use of old module name %s is deprecated, please use %s instead.\n", v->value, newname); 00927 add_to_load_order(translate_status ? v->value : newname, &load_order); 00928 } 00929 } 00930 00931 /* check if 'autoload' is on */ 00932 if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) { 00933 /* if so, first add all the embedded modules that are not already running to the load order */ 00934 AST_LIST_TRAVERSE(&module_list, mod, entry) { 00935 /* if it's not embedded, skip it */ 00936 if (mod->lib) 00937 continue; 00938 00939 if (mod->flags.running) 00940 continue; 00941 00942 order = add_to_load_order(mod->resource, &load_order); 00943 } 00944 00945 #ifdef LOADABLE_MODULES 00946 /* if we are allowed to load dynamic modules, scan the directory for 00947 for all available modules and add them as well */ 00948 if ((dir = opendir(ast_config_AST_MODULE_DIR))) { 00949 while ((dirent = readdir(dir))) { 00950 int ld = strlen(dirent->d_name); 00951 00952 /* Must end in .so to load it. */ 00953 00954 if (ld < 4) 00955 continue; 00956 00957 if (strcasecmp(dirent->d_name + ld - 3, ".so")) 00958 continue; 00959 00960 /* if there is already a module by this name in the module_list, 00961 skip this file */ 00962 if (find_resource(dirent->d_name, 0)) 00963 continue; 00964 00965 add_to_load_order(dirent->d_name, &load_order); 00966 } 00967 00968 closedir(dir); 00969 } else { 00970 if (!ast_opt_quiet) 00971 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n", 00972 ast_config_AST_MODULE_DIR); 00973 } 00974 #endif 00975 } 00976 00977 /* now scan the config for any modules we are prohibited from loading and 00978 remove them from the load order */ 00979 for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) { 00980 if (strcasecmp(v->name, "noload")) 00981 continue; 00982 00983 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) { 00984 translate_status = translate_module_name(v->value, newname); 00985 if (!resource_name_match(order->resource, translate_status ? v->value : newname)) { 00986 if (!translate_status) 00987 ast_log(LOG_WARNING, "Use of old module name %s is deprecated, please use %s instead.\n", v->value, newname); 00988 AST_LIST_REMOVE_CURRENT(&load_order, entry); 00989 free(order->resource); 00990 free(order); 00991 } 00992 } 00993 AST_LIST_TRAVERSE_SAFE_END; 00994 } 00995 00996 /* we are done with the config now, all the information we need is in the 00997 load_order list */ 00998 ast_config_destroy(cfg); 00999 01000 load_count = 0; 01001 AST_LIST_TRAVERSE(&load_order, order, entry) 01002 load_count++; 01003 01004 if (load_count) 01005 ast_log(LOG_NOTICE, "%d modules will be loaded.\n", load_count); 01006 01007 for (load_pass = 0; load_pass < LOAD_DONE; load_pass++) { 01008 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) { 01009 switch (load_resource(order->resource, load_pass)) { 01010 case AST_MODULE_LOAD_SUCCESS: 01011 case AST_MODULE_LOAD_DECLINE: 01012 AST_LIST_REMOVE_CURRENT(&load_order, entry); 01013 free(order->resource); 01014 free(order); 01015 break; 01016 case AST_MODULE_LOAD_FAILURE: 01017 res = -1; 01018 goto done; 01019 case AST_MODULE_LOAD_SKIP: 01020 /* 01021 * Try again later. This result is received when a module is 01022 * deferred because it is not a part of the current pass. 01023 */ 01024 break; 01025 } 01026 } 01027 AST_LIST_TRAVERSE_SAFE_END; 01028 } 01029 01030 done: 01031 while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) { 01032 free(order->resource); 01033 free(order); 01034 } 01035 01036 AST_LIST_UNLOCK(&module_list); 01037 01038 return res; 01039 }
static enum ast_module_load_result load_resource | ( | const char * | resource_name, | |
enum module_load_pass | load_pass | |||
) | [static] |
Definition at line 749 of file loader.c.
References ast_fully_booted, ast_log(), AST_MODFLAG_GLOBAL_SYMBOLS, AST_MODFLAG_LOAD_FIRST, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SKIP, AST_MODULE_LOAD_SUCCESS, ast_opt_console, ast_test_flag, ast_update_use_count(), ast_verbose(), COLOR_BLACK, COLOR_BROWN, ast_module::declined, ast_module_info::description, find_resource(), ast_module::flags, ast_module::info, inspect_module(), ast_module_info::load, LOAD_ALL, LOAD_DONE, load_dynamic_module(), LOAD_FIRST, LOAD_GLOBAL_SYMBOLS, LOG_ERROR, LOG_WARNING, option_verbose, ast_module::running, term_color(), unload_dynamic_module(), and VERBOSE_PREFIX_1.
Referenced by ast_load_resource().
00750 { 00751 struct ast_module *mod; 00752 enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS; 00753 char tmp[256]; 00754 00755 if ((mod = find_resource(resource_name, 0))) { 00756 if (mod->flags.running) { 00757 ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name); 00758 return AST_MODULE_LOAD_DECLINE; 00759 } 00760 00761 switch (load_pass) { 00762 case LOAD_FIRST: 00763 if (!ast_test_flag(mod->info, AST_MODFLAG_LOAD_FIRST)) { 00764 return AST_MODULE_LOAD_SKIP; 00765 } 00766 break; 00767 case LOAD_GLOBAL_SYMBOLS: 00768 if (!ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS)) { 00769 return AST_MODULE_LOAD_SKIP; 00770 } 00771 break; 00772 case LOAD_ALL: 00773 break; 00774 case LOAD_DONE: 00775 ast_log(LOG_ERROR, "This should never happen, -EFLAMES!\n"); 00776 break; 00777 } 00778 } else { 00779 #ifdef LOADABLE_MODULES 00780 if (!(mod = load_dynamic_module(resource_name, load_pass))) { 00781 /* don't generate a warning message during load_modules() */ 00782 if (load_pass == LOAD_ALL) { 00783 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); 00784 return AST_MODULE_LOAD_DECLINE; 00785 } else { 00786 return AST_MODULE_LOAD_SKIP; 00787 } 00788 } 00789 #else 00790 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); 00791 return AST_MODULE_LOAD_DECLINE; 00792 #endif 00793 } 00794 00795 if (inspect_module(mod)) { 00796 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); 00797 #ifdef LOADABLE_MODULES 00798 unload_dynamic_module(mod); 00799 #endif 00800 return AST_MODULE_LOAD_DECLINE; 00801 } 00802 00803 mod->flags.declined = 0; 00804 00805 if (mod->info->load) 00806 res = mod->info->load(); 00807 00808 switch (res) { 00809 case AST_MODULE_LOAD_SUCCESS: 00810 if (!ast_fully_booted) { 00811 if (option_verbose) 00812 ast_verbose("%s => (%s)\n", resource_name, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp))); 00813 if (ast_opt_console && !option_verbose) 00814 ast_verbose( "."); 00815 } else { 00816 if (option_verbose) 00817 ast_verbose(VERBOSE_PREFIX_1 "Loaded %s => (%s)\n", resource_name, mod->info->description); 00818 } 00819 00820 mod->flags.running = 1; 00821 00822 ast_update_use_count(); 00823 break; 00824 case AST_MODULE_LOAD_DECLINE: 00825 mod->flags.declined = 1; 00826 break; 00827 case AST_MODULE_LOAD_FAILURE: 00828 break; 00829 case AST_MODULE_LOAD_SKIP: 00830 /* modules should never return this value */ 00831 break; 00832 } 00833 00834 return res; 00835 }
static int printdigest | ( | const unsigned char * | d | ) | [static] |
Definition at line 265 of file loader.c.
References ast_log(), and LOG_DEBUG.
Referenced by verify_key().
00266 { 00267 int x, pos; 00268 char buf[256]; /* large enough so we don't have to worry */ 00269 00270 for (pos = 0, x = 0; x < 16; x++) 00271 pos += sprintf(buf + pos, " %02x", *d++); 00272 00273 ast_log(LOG_DEBUG, "Unexpected signature:%s\n", buf); 00274 00275 return 0; 00276 }
static void queue_reload_request | ( | const char * | module | ) | [static] |
Definition at line 614 of file loader.c.
References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), do_full_reload, ast_module_user::entry, LOG_ERROR, and reload_queue_item::module.
Referenced by ast_module_reload().
00615 { 00616 struct reload_queue_item *item; 00617 00618 AST_LIST_LOCK(&reload_queue); 00619 00620 if (do_full_reload) { 00621 AST_LIST_UNLOCK(&reload_queue); 00622 return; 00623 } 00624 00625 if (ast_strlen_zero(module)) { 00626 /* A full reload request (when module is NULL) wipes out any previous 00627 reload requests and causes the queue to ignore future ones */ 00628 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) { 00629 ast_free(item); 00630 } 00631 do_full_reload = 1; 00632 } else { 00633 /* No reason to add the same module twice */ 00634 AST_LIST_TRAVERSE(&reload_queue, item, entry) { 00635 if (!strcasecmp(item->module, module)) { 00636 AST_LIST_UNLOCK(&reload_queue); 00637 return; 00638 } 00639 } 00640 item = ast_calloc(1, sizeof(*item) + strlen(module) + 1); 00641 if (!item) { 00642 ast_log(LOG_ERROR, "Failed to allocate reload queue item.\n"); 00643 AST_LIST_UNLOCK(&reload_queue); 00644 return; 00645 } 00646 strcpy(item->module, module); 00647 AST_LIST_INSERT_TAIL(&reload_queue, item, entry); 00648 } 00649 AST_LIST_UNLOCK(&reload_queue); 00650 }
static int resource_name_match | ( | const char * | name1_in, | |
const char * | name2_in | |||
) | [static] |
Definition at line 307 of file loader.c.
References ast_strdupa.
Referenced by add_to_load_order(), ast_module_reload(), and find_resource().
00308 { 00309 char *name1 = (char *) name1_in; 00310 char *name2 = (char *) name2_in; 00311 00312 /* trim off any .so extensions */ 00313 if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) { 00314 name1 = ast_strdupa(name1); 00315 name1[strlen(name1) - 3] = '\0'; 00316 } 00317 if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) { 00318 name2 = ast_strdupa(name2); 00319 name2[strlen(name2) - 3] = '\0'; 00320 } 00321 00322 return strcasecmp(name1, name2); 00323 }
static int translate_module_name | ( | char * | oldname, | |
char * | newname | |||
) | [static] |
Definition at line 871 of file loader.c.
References ast_copy_string().
Referenced by load_modules().
00872 { 00873 if (!strcasecmp(oldname, "app_zapbarge.so")) 00874 ast_copy_string(newname, "app_dahdibarge.so", 18); 00875 else if(!strcasecmp(oldname, "app_zapras.so")) 00876 ast_copy_string(newname, "app_dahdiras.so", 16); 00877 else if(!strcasecmp(oldname, "app_zapscan.so")) 00878 ast_copy_string(newname, "app_dahdiscan.so", 17); 00879 else if(!strcasecmp(oldname, "codec_zap.so")) 00880 ast_copy_string(newname, "codec_dahdi.so", 16); 00881 else 00882 return -1; /* no use for newname, oldname is fine */ 00883 00884 return 0; 00885 }
static void unload_dynamic_module | ( | struct ast_module * | mod | ) | [static] |
Definition at line 344 of file loader.c.
References ast_module::lib.
Referenced by ast_unload_resource(), and load_resource().
00345 { 00346 void *lib = mod->lib; 00347 00348 /* WARNING: the structure pointed to by mod is going to 00349 disappear when this operation succeeds, so we can't 00350 dereference it */ 00351 00352 if (lib) 00353 while (!dlclose(lib)); 00354 }
static int verify_key | ( | const unsigned char * | key | ) | [static] |
Definition at line 290 of file loader.c.
References expected_key, key_matches(), MD5Final(), MD5Init(), MD5Update(), and printdigest().
Referenced by inspect_module().
00291 { 00292 struct MD5Context c; 00293 unsigned char digest[16]; 00294 00295 MD5Init(&c); 00296 MD5Update(&c, key, strlen((char *)key)); 00297 MD5Final(digest, &c); 00298 00299 if (key_matches(expected_key, digest)) 00300 return 0; 00301 00302 printdigest(digest); 00303 00304 return -1; 00305 }
char buildopt_sum[33] = AST_BUILDOPT_SUM [static] |
int do_full_reload = 0 [static] |
Definition at line 110 of file loader.c.
Referenced by ast_process_pending_reloads(), and queue_reload_request().
unsigned int embedding = 1 [static] |
unsigned char expected_key[] [static] |
Initial value:
{ 0x87, 0x76, 0x79, 0x35, 0x23, 0xea, 0x3a, 0xd3, 0x25, 0x2a, 0xbb, 0x35, 0x87, 0xe4, 0x22, 0x24 }
Definition at line 71 of file loader.c.
Referenced by verify_key().
ast_mutex_t reloadlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
struct ast_module* resource_being_loaded |
Definition at line 118 of file loader.c.
Referenced by ast_module_register(), and load_dynamic_module().