#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 = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, 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 837 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().
00838 { 00839 struct load_order_entry *order; 00840 00841 AST_LIST_TRAVERSE(load_order, order, entry) { 00842 if (!resource_name_match(order->resource, resource)) 00843 return NULL; 00844 } 00845 00846 if (!(order = ast_calloc(1, sizeof(*order)))) 00847 return NULL; 00848 00849 order->resource = ast_strdup(resource); 00850 AST_LIST_INSERT_TAIL(load_order, order, entry); 00851 00852 return order; 00853 }
int ast_load_resource | ( | const char * | resource_name | ) |
Load a module.
resource_name | The name of the module to load. |
Definition at line 821 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().
00822 { 00823 AST_LIST_LOCK(&module_list); 00824 load_resource(resource_name, LOAD_ALL); 00825 AST_LIST_UNLOCK(&module_list); 00826 00827 return 0; 00828 }
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 1057 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().
01058 { 01059 struct loadupdate *tmp; 01060 01061 if (!(tmp = ast_malloc(sizeof(*tmp)))) 01062 return -1; 01063 01064 tmp->updater = v; 01065 AST_LIST_LOCK(&updaters); 01066 AST_LIST_INSERT_HEAD(&updaters, tmp, entry); 01067 AST_LIST_UNLOCK(&updaters); 01068 01069 return 0; 01070 }
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 1072 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().
01073 { 01074 struct loadupdate *cur; 01075 01076 AST_LIST_LOCK(&updaters); 01077 AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) { 01078 if (cur->updater == v) { 01079 AST_LIST_REMOVE_CURRENT(&updaters, entry); 01080 break; 01081 } 01082 } 01083 AST_LIST_TRAVERSE_SAFE_END; 01084 AST_LIST_UNLOCK(&updaters); 01085 01086 return cur ? 0 : -1; 01087 }
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 541 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_3(), complete_mod_3_nr(), complete_mod_4(), and load_module().
00542 { 00543 struct ast_module *cur; 00544 int i, which=0, l = strlen(word); 00545 char *ret = NULL; 00546 00547 if (pos != rpos) 00548 return NULL; 00549 00550 AST_LIST_LOCK(&module_list); 00551 AST_LIST_TRAVERSE(&module_list, cur, entry) { 00552 if (!strncasecmp(word, cur->resource, l) && 00553 (cur->info->reload || !needsreload) && 00554 ++which > state) { 00555 ret = strdup(cur->resource); 00556 break; 00557 } 00558 } 00559 AST_LIST_UNLOCK(&module_list); 00560 00561 if (!ret) { 00562 for (i=0; !ret && reload_classes[i].name; i++) { 00563 if (!strncasecmp(word, reload_classes[i].name, l) && ++which > state) 00564 ret = strdup(reload_classes[i].name); 00565 } 00566 } 00567 00568 return ret; 00569 }
struct ast_module* ast_module_ref | ( | struct ast_module * | mod | ) |
Definition at line 1089 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().
01090 { 01091 ast_atomic_fetchadd_int(&mod->usecount, +1); 01092 ast_update_use_count(); 01093 01094 return mod; 01095 }
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 636 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().
00637 { 00638 struct ast_module *cur; 00639 int res = 0; /* return value. 0 = not found, others, see below */ 00640 int i; 00641 00642 /* If we aren't fully booted, we just pretend we reloaded but we queue this 00643 up to run once we are booted up. */ 00644 if (!ast_fully_booted) { 00645 queue_reload_request(name); 00646 return 0; 00647 } 00648 00649 if (ast_mutex_trylock(&reloadlock)) { 00650 ast_verbose("The previous reload command didn't finish yet\n"); 00651 return -1; /* reload already in progress */ 00652 } 00653 ast_lastreloadtime = time(NULL); 00654 00655 /* Call "predefined" reload here first */ 00656 for (i = 0; reload_classes[i].name; i++) { 00657 if (!name || !strcasecmp(name, reload_classes[i].name)) { 00658 reload_classes[i].reload_fn(); /* XXX should check error ? */ 00659 res = 2; /* found and reloaded */ 00660 } 00661 } 00662 00663 if (name && res) { 00664 ast_mutex_unlock(&reloadlock); 00665 return res; 00666 } 00667 00668 AST_LIST_LOCK(&module_list); 00669 AST_LIST_TRAVERSE(&module_list, cur, entry) { 00670 const struct ast_module_info *info = cur->info; 00671 00672 if (name && resource_name_match(name, cur->resource)) 00673 continue; 00674 00675 if (!cur->flags.running || cur->flags.declined) { 00676 if (!name) 00677 continue; 00678 ast_log(LOG_NOTICE, "The module '%s' was not properly initialized. " 00679 "Before reloading the module, you must run \"module load %s\" " 00680 "and fix whatever is preventing the module from being initialized.\n", 00681 name, name); 00682 res = 2; /* Don't report that the module was not found */ 00683 break; 00684 } 00685 00686 if (!info->reload) { /* cannot be reloaded */ 00687 if (res < 1) /* store result if possible */ 00688 res = 1; /* 1 = no reload() method */ 00689 continue; 00690 } 00691 00692 res = 2; 00693 if (option_verbose > 2) 00694 ast_verbose(VERBOSE_PREFIX_3 "Reloading module '%s' (%s)\n", cur->resource, info->description); 00695 info->reload(); 00696 } 00697 AST_LIST_UNLOCK(&module_list); 00698 00699 ast_mutex_unlock(&reloadlock); 00700 00701 return res; 00702 }
void ast_module_shutdown | ( | void | ) |
Run the unload() callback for all loaded modules.
This function should be called when Asterisk is shutting down gracefully.
Definition at line 455 of file loader.c.
References AST_LIST_HEAD_DESTROY, AST_LIST_HEAD_NOLOCK_STATIC, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_module_user::entry, free, ast_module::info, ast_module_info::unload, and ast_module::users.
Referenced by quit_handler().
00456 { 00457 struct ast_module *mod; 00458 AST_LIST_HEAD_NOLOCK_STATIC(local_module_list, ast_module); 00459 00460 /* We have to call the unload() callbacks in reverse order that the modules 00461 * exist in the module list so it is the reverse order of how they were 00462 * loaded. */ 00463 00464 AST_LIST_LOCK(&module_list); 00465 while ((mod = AST_LIST_REMOVE_HEAD(&module_list, entry))) 00466 AST_LIST_INSERT_HEAD(&local_module_list, mod, entry); 00467 AST_LIST_UNLOCK(&module_list); 00468 00469 while ((mod = AST_LIST_REMOVE_HEAD(&local_module_list, entry))) { 00470 if (mod->info->unload) 00471 mod->info->unload(); 00472 /* Since this should only be called when shutting down "gracefully", 00473 * all channels should be down before we get to this point, meaning 00474 * there will be no module users left. */ 00475 AST_LIST_HEAD_DESTROY(&mod->users); 00476 free(mod); 00477 } 00478 }
void ast_module_unref | ( | struct ast_module * | mod | ) |
Definition at line 1097 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().
01098 { 01099 ast_atomic_fetchadd_int(&mod->usecount, -1); 01100 ast_update_use_count(); 01101 }
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 571 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().
00572 { 00573 struct reload_queue_item *item; 00574 00575 if (!ast_fully_booted) { 00576 return; 00577 } 00578 00579 AST_LIST_LOCK(&reload_queue); 00580 00581 if (do_full_reload) { 00582 do_full_reload = 0; 00583 AST_LIST_UNLOCK(&reload_queue); 00584 ast_log(LOG_NOTICE, "Executing deferred reload request.\n"); 00585 ast_module_reload(NULL); 00586 return; 00587 } 00588 00589 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) { 00590 ast_log(LOG_NOTICE, "Executing deferred reload request for module '%s'.\n", item->module); 00591 ast_module_reload(item->module); 00592 ast_free(item); 00593 } 00594 00595 AST_LIST_UNLOCK(&reload_queue); 00596 }
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 480 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().
00481 { 00482 struct ast_module *mod; 00483 int res = -1; 00484 int error = 0; 00485 00486 AST_LIST_LOCK(&module_list); 00487 00488 if (!(mod = find_resource(resource_name, 0))) { 00489 AST_LIST_UNLOCK(&module_list); 00490 return 0; 00491 } 00492 00493 if (!(mod->flags.running || mod->flags.declined)) 00494 error = 1; 00495 00496 if (!mod->lib) { 00497 ast_log(LOG_WARNING, "Unloading embedded modules is not supported.\n"); 00498 error = 1; 00499 } 00500 00501 if (!error && (mod->usecount > 0)) { 00502 if (force) 00503 ast_log(LOG_WARNING, "Warning: Forcing removal of module '%s' with use count %d\n", 00504 resource_name, mod->usecount); 00505 else { 00506 ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name, 00507 mod->usecount); 00508 error = 1; 00509 } 00510 } 00511 00512 if (!error) { 00513 __ast_module_user_hangup_all(mod); 00514 res = mod->info->unload(); 00515 00516 if (res) { 00517 ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name); 00518 if (force <= AST_FORCE_FIRM) 00519 error = 1; 00520 else 00521 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n"); 00522 } 00523 } 00524 00525 if (!error) 00526 mod->flags.running = mod->flags.declined = 0; 00527 00528 AST_LIST_UNLOCK(&module_list); 00529 00530 #ifdef LOADABLE_MODULES 00531 if (!error) 00532 unload_dynamic_module(mod); 00533 #endif 00534 00535 if (!error) 00536 ast_update_use_count(); 00537 00538 return res; 00539 }
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 1037 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().
01039 { 01040 struct ast_module *cur; 01041 int unlock = -1; 01042 int total_mod_loaded = 0; 01043 01044 if (AST_LIST_TRYLOCK(&module_list)) 01045 unlock = 0; 01046 01047 AST_LIST_TRAVERSE(&module_list, cur, entry) { 01048 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, like); 01049 } 01050 01051 if (unlock) 01052 AST_LIST_UNLOCK(&module_list); 01053 01054 return total_mod_loaded; 01055 }
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 1025 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().
01026 { 01027 /* Notify any module monitors that the use count for a 01028 resource has changed */ 01029 struct loadupdate *m; 01030 01031 AST_LIST_LOCK(&updaters); 01032 AST_LIST_TRAVERSE(&updaters, m, entry) 01033 m->updater(); 01034 AST_LIST_UNLOCK(&updaters); 01035 }
static struct ast_module* find_resource | ( | const char * | resource, | |
int | do_lock | |||
) | [static] |
Definition at line 324 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().
00325 { 00326 struct ast_module *cur; 00327 00328 if (do_lock) 00329 AST_LIST_LOCK(&module_list); 00330 00331 AST_LIST_TRAVERSE(&module_list, cur, entry) { 00332 if (!resource_name_match(resource, cur->resource)) 00333 break; 00334 } 00335 00336 if (do_lock) 00337 AST_LIST_UNLOCK(&module_list); 00338 00339 return cur; 00340 }
static unsigned int inspect_module | ( | const struct ast_module * | mod | ) | [static] |
Definition at line 704 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().
00705 { 00706 if (!mod->info->description) { 00707 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource); 00708 return 1; 00709 } 00710 00711 if (!mod->info->key) { 00712 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource); 00713 return 1; 00714 } 00715 00716 if (verify_key((unsigned char *) mod->info->key)) { 00717 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource); 00718 return 1; 00719 } 00720 00721 if (!ast_test_flag(mod->info, AST_MODFLAG_BUILDSUM)) { 00722 ast_log(LOG_WARNING, "Module '%s' was not compiled against a recent version of Asterisk and may cause instability.\n", mod->resource); 00723 } else if (!ast_strlen_zero(mod->info->buildopt_sum) && 00724 strcmp(buildopt_sum, mod->info->buildopt_sum)) { 00725 ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource); 00726 ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource); 00727 return 1; 00728 } 00729 00730 return 0; 00731 }
static int key_matches | ( | const unsigned char * | key1, | |
const unsigned char * | key2 | |||
) | [static] |
Definition at line 277 of file loader.c.
Referenced by verify_key().
00278 { 00279 int x; 00280 00281 for (x = 0; x < 16; x++) { 00282 if (key1[x] != key2[x]) 00283 return 0; 00284 } 00285 00286 return 1; 00287 }
static struct ast_module* load_dynamic_module | ( | const char * | resource_in, | |
enum module_load_pass | load_pass | |||
) | [static] |
Definition at line 355 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().
00356 { 00357 char fn[256]; 00358 void *lib; 00359 struct ast_module *mod; 00360 char *resource = (char *) resource_in; 00361 unsigned int wants_global = 0, not_yet = 0; 00362 00363 if (strcasecmp(resource + strlen(resource) - 3, ".so")) { 00364 resource = alloca(strlen(resource_in) + 3); 00365 strcpy(resource, resource_in); 00366 strcat(resource, ".so"); 00367 } 00368 00369 snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_MODULE_DIR, resource); 00370 00371 /* make a first load of the module in 'quiet' mode... don't try to resolve 00372 any symbols, and don't export any symbols. this will allow us to peek into 00373 the module's info block (if available) to see what flags it has set */ 00374 00375 if (!(resource_being_loaded = ast_calloc(1, sizeof(*resource_being_loaded) + strlen(resource) + 1))) 00376 return NULL; 00377 00378 strcpy(resource_being_loaded->resource, resource); 00379 00380 /* libopenh323 is buggy and segfaults on dlclose() when opened with 00381 * RTLD_LAZY. Workaround this until it gets fixed */ 00382 if (!strcasecmp(resource, "chan_h323.so") || 00383 !strcasecmp(resource, "chan_oh323.so")) 00384 lib = dlopen(fn, RTLD_NOW | RTLD_LOCAL); 00385 00386 if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_LOCAL))) { 00387 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror()); 00388 free(resource_being_loaded); 00389 return NULL; 00390 } 00391 00392 /* the dlopen() succeeded, let's find out if the module 00393 registered itself */ 00394 /* note that this will only work properly as long as 00395 ast_module_register() (which is called by the module's 00396 constructor) places the new module at the tail of the 00397 module_list 00398 */ 00399 if (resource_being_loaded != (mod = AST_LIST_LAST(&module_list))) { 00400 ast_log(LOG_WARNING, "Module '%s' did not register itself during load\n", resource_in); 00401 /* no, it did not, so close it and return */ 00402 while (!dlclose(lib)); 00403 /* note that the module's destructor will call ast_module_unregister(), 00404 which will free the structure we allocated in resource_being_loaded */ 00405 return NULL; 00406 } 00407 00408 switch (load_pass) { 00409 case LOAD_FIRST: 00410 not_yet = !ast_test_flag(mod->info, AST_MODFLAG_LOAD_FIRST); 00411 break; 00412 case LOAD_GLOBAL_SYMBOLS: 00413 wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS); 00414 not_yet = !wants_global; 00415 break; 00416 case LOAD_ALL: 00417 break; 00418 case LOAD_DONE: 00419 ast_log(LOG_ERROR, "Satan just bought a snowblower! (This should never happen, btw.)\n"); 00420 break; 00421 } 00422 00423 if (not_yet) { 00424 while (!dlclose(lib)); 00425 return NULL; 00426 } 00427 00428 while (!dlclose(lib)); 00429 resource_being_loaded = NULL; 00430 00431 /* start the load process again */ 00432 00433 if (!(resource_being_loaded = ast_calloc(1, sizeof(*resource_being_loaded) + strlen(resource) + 1))) 00434 return NULL; 00435 00436 strcpy(resource_being_loaded->resource, resource); 00437 00438 if (!(lib = dlopen(fn, wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) { 00439 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror()); 00440 free(resource_being_loaded); 00441 return NULL; 00442 } 00443 00444 /* since the module was successfully opened, and it registered itself 00445 the previous time we did that, we're going to assume it worked this 00446 time too :) */ 00447 00448 AST_LIST_LAST(&module_list)->lib = lib; 00449 resource_being_loaded = NULL; 00450 00451 return AST_LIST_LAST(&module_list); 00452 }
int load_modules | ( | unsigned | int | ) |
Provided by loader.c
Definition at line 872 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().
00873 { 00874 struct ast_config *cfg; 00875 struct ast_module *mod; 00876 struct load_order_entry *order; 00877 struct ast_variable *v; 00878 unsigned int load_count; 00879 struct load_order load_order; 00880 int res = 0; 00881 int load_pass; 00882 00883 int translate_status; 00884 char newname[18]; /* although this would normally be 80, max length in translate_module_name is 18 */ 00885 #ifdef LOADABLE_MODULES 00886 struct dirent *dirent; 00887 DIR *dir; 00888 #endif 00889 00890 /* all embedded modules have registered themselves by now */ 00891 embedding = 0; 00892 00893 if (option_verbose) 00894 ast_verbose("Asterisk Dynamic Loader Starting:\n"); 00895 00896 AST_LIST_HEAD_INIT_NOLOCK(&load_order); 00897 00898 AST_LIST_LOCK(&module_list); 00899 00900 if (!(cfg = ast_config_load(AST_MODULE_CONFIG))) { 00901 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG); 00902 goto done; 00903 } 00904 00905 /* first, find all the modules we have been explicitly requested to load */ 00906 for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) { 00907 if (!strcasecmp(v->name, preload_only ? "preload" : "load")) { 00908 translate_status = translate_module_name(v->value, newname); 00909 if (!translate_status) 00910 ast_log(LOG_WARNING, "Use of old module name %s is deprecated, please use %s instead.\n", v->value, newname); 00911 add_to_load_order(translate_status ? v->value : newname, &load_order); 00912 } 00913 } 00914 00915 /* check if 'autoload' is on */ 00916 if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) { 00917 /* if so, first add all the embedded modules that are not already running to the load order */ 00918 AST_LIST_TRAVERSE(&module_list, mod, entry) { 00919 /* if it's not embedded, skip it */ 00920 if (mod->lib) 00921 continue; 00922 00923 if (mod->flags.running) 00924 continue; 00925 00926 order = add_to_load_order(mod->resource, &load_order); 00927 } 00928 00929 #ifdef LOADABLE_MODULES 00930 /* if we are allowed to load dynamic modules, scan the directory for 00931 for all available modules and add them as well */ 00932 if ((dir = opendir(ast_config_AST_MODULE_DIR))) { 00933 while ((dirent = readdir(dir))) { 00934 int ld = strlen(dirent->d_name); 00935 00936 /* Must end in .so to load it. */ 00937 00938 if (ld < 4) 00939 continue; 00940 00941 if (strcasecmp(dirent->d_name + ld - 3, ".so")) 00942 continue; 00943 00944 /* if there is already a module by this name in the module_list, 00945 skip this file */ 00946 if (find_resource(dirent->d_name, 0)) 00947 continue; 00948 00949 add_to_load_order(dirent->d_name, &load_order); 00950 } 00951 00952 closedir(dir); 00953 } else { 00954 if (!ast_opt_quiet) 00955 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n", 00956 ast_config_AST_MODULE_DIR); 00957 } 00958 #endif 00959 } 00960 00961 /* now scan the config for any modules we are prohibited from loading and 00962 remove them from the load order */ 00963 for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) { 00964 if (strcasecmp(v->name, "noload")) 00965 continue; 00966 00967 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) { 00968 translate_status = translate_module_name(v->value, newname); 00969 if (!resource_name_match(order->resource, translate_status ? v->value : newname)) { 00970 if (!translate_status) 00971 ast_log(LOG_WARNING, "Use of old module name %s is deprecated, please use %s instead.\n", v->value, newname); 00972 AST_LIST_REMOVE_CURRENT(&load_order, entry); 00973 free(order->resource); 00974 free(order); 00975 } 00976 } 00977 AST_LIST_TRAVERSE_SAFE_END; 00978 } 00979 00980 /* we are done with the config now, all the information we need is in the 00981 load_order list */ 00982 ast_config_destroy(cfg); 00983 00984 load_count = 0; 00985 AST_LIST_TRAVERSE(&load_order, order, entry) 00986 load_count++; 00987 00988 if (load_count) 00989 ast_log(LOG_NOTICE, "%d modules will be loaded.\n", load_count); 00990 00991 for (load_pass = 0; load_pass < LOAD_DONE; load_pass++) { 00992 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) { 00993 switch (load_resource(order->resource, load_pass)) { 00994 case AST_MODULE_LOAD_SUCCESS: 00995 case AST_MODULE_LOAD_DECLINE: 00996 AST_LIST_REMOVE_CURRENT(&load_order, entry); 00997 free(order->resource); 00998 free(order); 00999 break; 01000 case AST_MODULE_LOAD_FAILURE: 01001 res = -1; 01002 goto done; 01003 case AST_MODULE_LOAD_SKIP: 01004 /* 01005 * Try again later. This result is received when a module is 01006 * deferred because it is not a part of the current pass. 01007 */ 01008 break; 01009 } 01010 } 01011 AST_LIST_TRAVERSE_SAFE_END; 01012 } 01013 01014 done: 01015 while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) { 01016 free(order->resource); 01017 free(order); 01018 } 01019 01020 AST_LIST_UNLOCK(&module_list); 01021 01022 return res; 01023 }
static enum ast_module_load_result load_resource | ( | const char * | resource_name, | |
enum module_load_pass | load_pass | |||
) | [static] |
Definition at line 733 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().
00734 { 00735 struct ast_module *mod; 00736 enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS; 00737 char tmp[256]; 00738 00739 if ((mod = find_resource(resource_name, 0))) { 00740 if (mod->flags.running) { 00741 ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name); 00742 return AST_MODULE_LOAD_DECLINE; 00743 } 00744 00745 switch (load_pass) { 00746 case LOAD_FIRST: 00747 if (!ast_test_flag(mod->info, AST_MODFLAG_LOAD_FIRST)) { 00748 return AST_MODULE_LOAD_SKIP; 00749 } 00750 break; 00751 case LOAD_GLOBAL_SYMBOLS: 00752 if (!ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS)) { 00753 return AST_MODULE_LOAD_SKIP; 00754 } 00755 break; 00756 case LOAD_ALL: 00757 break; 00758 case LOAD_DONE: 00759 ast_log(LOG_ERROR, "This should never happen, -EFLAMES!\n"); 00760 break; 00761 } 00762 } else { 00763 #ifdef LOADABLE_MODULES 00764 if (!(mod = load_dynamic_module(resource_name, load_pass))) { 00765 /* don't generate a warning message during load_modules() */ 00766 if (load_pass == LOAD_ALL) { 00767 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); 00768 return AST_MODULE_LOAD_DECLINE; 00769 } else { 00770 return AST_MODULE_LOAD_SKIP; 00771 } 00772 } 00773 #else 00774 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); 00775 return AST_MODULE_LOAD_DECLINE; 00776 #endif 00777 } 00778 00779 if (inspect_module(mod)) { 00780 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); 00781 #ifdef LOADABLE_MODULES 00782 unload_dynamic_module(mod); 00783 #endif 00784 return AST_MODULE_LOAD_DECLINE; 00785 } 00786 00787 mod->flags.declined = 0; 00788 00789 if (mod->info->load) 00790 res = mod->info->load(); 00791 00792 switch (res) { 00793 case AST_MODULE_LOAD_SUCCESS: 00794 if (!ast_fully_booted) { 00795 if (option_verbose) 00796 ast_verbose("%s => (%s)\n", resource_name, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp))); 00797 if (ast_opt_console && !option_verbose) 00798 ast_verbose( "."); 00799 } else { 00800 if (option_verbose) 00801 ast_verbose(VERBOSE_PREFIX_1 "Loaded %s => (%s)\n", resource_name, mod->info->description); 00802 } 00803 00804 mod->flags.running = 1; 00805 00806 ast_update_use_count(); 00807 break; 00808 case AST_MODULE_LOAD_DECLINE: 00809 mod->flags.declined = 1; 00810 break; 00811 case AST_MODULE_LOAD_FAILURE: 00812 break; 00813 case AST_MODULE_LOAD_SKIP: 00814 /* modules should never return this value */ 00815 break; 00816 } 00817 00818 return res; 00819 }
static int printdigest | ( | const unsigned char * | d | ) | [static] |
Definition at line 264 of file loader.c.
References ast_log(), and LOG_DEBUG.
Referenced by verify_key().
00265 { 00266 int x, pos; 00267 char buf[256]; /* large enough so we don't have to worry */ 00268 00269 for (pos = 0, x = 0; x < 16; x++) 00270 pos += sprintf(buf + pos, " %02x", *d++); 00271 00272 ast_log(LOG_DEBUG, "Unexpected signature:%s\n", buf); 00273 00274 return 0; 00275 }
static void queue_reload_request | ( | const char * | module | ) | [static] |
Definition at line 598 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().
00599 { 00600 struct reload_queue_item *item; 00601 00602 AST_LIST_LOCK(&reload_queue); 00603 00604 if (do_full_reload) { 00605 AST_LIST_UNLOCK(&reload_queue); 00606 return; 00607 } 00608 00609 if (ast_strlen_zero(module)) { 00610 /* A full reload request (when module is NULL) wipes out any previous 00611 reload requests and causes the queue to ignore future ones */ 00612 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) { 00613 ast_free(item); 00614 } 00615 do_full_reload = 1; 00616 } else { 00617 /* No reason to add the same module twice */ 00618 AST_LIST_TRAVERSE(&reload_queue, item, entry) { 00619 if (!strcasecmp(item->module, module)) { 00620 AST_LIST_UNLOCK(&reload_queue); 00621 return; 00622 } 00623 } 00624 item = ast_calloc(1, sizeof(*item) + strlen(module) + 1); 00625 if (!item) { 00626 ast_log(LOG_ERROR, "Failed to allocate reload queue item.\n"); 00627 AST_LIST_UNLOCK(&reload_queue); 00628 return; 00629 } 00630 strcpy(item->module, module); 00631 AST_LIST_INSERT_TAIL(&reload_queue, item, entry); 00632 } 00633 AST_LIST_UNLOCK(&reload_queue); 00634 }
static int resource_name_match | ( | const char * | name1_in, | |
const char * | name2_in | |||
) | [static] |
Definition at line 306 of file loader.c.
References ast_strdupa.
Referenced by add_to_load_order(), ast_module_reload(), and find_resource().
00307 { 00308 char *name1 = (char *) name1_in; 00309 char *name2 = (char *) name2_in; 00310 00311 /* trim off any .so extensions */ 00312 if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) { 00313 name1 = ast_strdupa(name1); 00314 name1[strlen(name1) - 3] = '\0'; 00315 } 00316 if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) { 00317 name2 = ast_strdupa(name2); 00318 name2[strlen(name2) - 3] = '\0'; 00319 } 00320 00321 return strcasecmp(name1, name2); 00322 }
static int translate_module_name | ( | char * | oldname, | |
char * | newname | |||
) | [static] |
Definition at line 855 of file loader.c.
References ast_copy_string().
Referenced by load_modules().
00856 { 00857 if (!strcasecmp(oldname, "app_zapbarge.so")) 00858 ast_copy_string(newname, "app_dahdibarge.so", 18); 00859 else if(!strcasecmp(oldname, "app_zapras.so")) 00860 ast_copy_string(newname, "app_dahdiras.so", 16); 00861 else if(!strcasecmp(oldname, "app_zapscan.so")) 00862 ast_copy_string(newname, "app_dahdiscan.so", 17); 00863 else if(!strcasecmp(oldname, "codec_zap.so")) 00864 ast_copy_string(newname, "codec_dahdi.so", 16); 00865 else 00866 return -1; /* no use for newname, oldname is fine */ 00867 00868 return 0; 00869 }
static void unload_dynamic_module | ( | struct ast_module * | mod | ) | [static] |
Definition at line 343 of file loader.c.
References ast_module::lib.
Referenced by ast_unload_resource(), and load_resource().
00344 { 00345 void *lib = mod->lib; 00346 00347 /* WARNING: the structure pointed to by mod is going to 00348 disappear when this operation succeeds, so we can't 00349 dereference it */ 00350 00351 if (lib) 00352 while (!dlclose(lib)); 00353 }
static int verify_key | ( | const unsigned char * | key | ) | [static] |
Definition at line 289 of file loader.c.
References expected_key, key_matches(), MD5Final(), MD5Init(), MD5Update(), and printdigest().
Referenced by inspect_module().
00290 { 00291 struct MD5Context c; 00292 unsigned char digest[16]; 00293 00294 MD5Init(&c); 00295 MD5Update(&c, key, strlen((char *)key)); 00296 MD5Final(digest, &c); 00297 00298 if (key_matches(expected_key, digest)) 00299 return 0; 00300 00301 printdigest(digest); 00302 00303 return -1; 00304 }
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 = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, 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().