Module Loader. More...
#include "asterisk.h"#include "asterisk/_private.h"#include "asterisk/paths.h"#include <dirent.h>#include "asterisk/linkedlists.h"#include "asterisk/module.h"#include "asterisk/config.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 "asterisk/features.h"#include "asterisk/dsp.h"#include "asterisk/udptl.h"#include "asterisk/heap.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_entry |
| struct | loadupdate |
| struct | reload_classes |
| struct | reload_queue_item |
Defines | |
| #define | RTLD_LOCAL 0 |
| #define | RTLD_NOW 0 |
Functions | |
| struct 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 (reload_queue, reload_queue_item) |
| 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 (const char *name) |
| Check if module exists. | |
| 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. | |
| struct 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) |
| AST_MUTEX_DEFINE_STATIC (reloadlock) | |
| 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) |
| int | load_modules (unsigned int preload_only) |
| static enum ast_module_load_result | load_resource (const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap) |
| static int | load_resource_list (struct load_order *load_order, unsigned int global_symbols, int *mod_count) |
| static int | mod_load_cmp (void *a, void *b) |
| 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 enum ast_module_load_result | start_resource (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 struct module_list | embedded_module_list |
| static unsigned int | embedding = 1 |
| static unsigned char | expected_key [] |
| struct ast_module * | resource_being_loaded |
Module Loader.
Definition in file loader.c.
| struct ast_module_user* __ast_module_user_add | ( | struct ast_module * | mod, | |
| struct ast_channel * | chan | |||
| ) | [read] |
Definition at line 195 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::usecount, and ast_module::users.
Referenced by ast_func_read(), ast_func_write(), and pbx_exec().
00197 { 00198 struct ast_module_user *u = ast_calloc(1, sizeof(*u)); 00199 00200 if (!u) 00201 return NULL; 00202 00203 u->chan = chan; 00204 00205 AST_LIST_LOCK(&mod->users); 00206 AST_LIST_INSERT_HEAD(&mod->users, u, entry); 00207 AST_LIST_UNLOCK(&mod->users); 00208 00209 ast_atomic_fetchadd_int(&mod->usecount, +1); 00210 00211 ast_update_use_count(); 00212 00213 return u; 00214 }
| void __ast_module_user_hangup_all | ( | struct ast_module * | mod | ) |
Definition at line 227 of file loader.c.
References ast_atomic_fetchadd_int(), ast_free, 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::usecount, and ast_module::users.
Referenced by ast_unload_resource().
00228 { 00229 struct ast_module_user *u; 00230 00231 AST_LIST_LOCK(&mod->users); 00232 while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) { 00233 ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD); 00234 ast_atomic_fetchadd_int(&mod->usecount, -1); 00235 ast_free(u); 00236 } 00237 AST_LIST_UNLOCK(&mod->users); 00238 00239 ast_update_use_count(); 00240 }
| void __ast_module_user_remove | ( | struct ast_module * | mod, | |
| struct ast_module_user * | u | |||
| ) |
Definition at line 216 of file loader.c.
References ast_atomic_fetchadd_int(), ast_free, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_update_use_count(), ast_module::usecount, and ast_module::users.
Referenced by ast_func_read(), ast_func_write(), and pbx_exec().
00217 { 00218 AST_LIST_LOCK(&mod->users); 00219 AST_LIST_REMOVE(&mod->users, u, entry); 00220 AST_LIST_UNLOCK(&mod->users); 00221 ast_atomic_fetchadd_int(&mod->usecount, -1); 00222 ast_free(u); 00223 00224 ast_update_use_count(); 00225 }
| static struct load_order_entry* add_to_load_order | ( | const char * | resource, | |
| struct load_order * | load_order | |||
| ) | [static, read] |
Definition at line 834 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().
00835 { 00836 struct load_order_entry *order; 00837 00838 AST_LIST_TRAVERSE(load_order, order, entry) { 00839 if (!resource_name_match(order->resource, resource)) 00840 return NULL; 00841 } 00842 00843 if (!(order = ast_calloc(1, sizeof(*order)))) 00844 return NULL; 00845 00846 order->resource = ast_strdup(resource); 00847 AST_LIST_INSERT_TAIL(load_order, order, entry); 00848 00849 return order; 00850 }
| AST_LIST_HEAD | ( | module_user_list | , | |
| ast_module_user | ||||
| ) |
| AST_LIST_HEAD_NOLOCK | ( | load_order | , | |
| load_order_entry | ||||
| ) |
| static AST_LIST_HEAD_STATIC | ( | reload_queue | , | |
| reload_queue_item | ||||
| ) | [static] |
| static AST_LIST_HEAD_STATIC | ( | updaters | , | |
| loadupdate | ||||
| ) | [static] |
| static AST_LIST_HEAD_STATIC | ( | module_list | , | |
| ast_module | ||||
| ) | [static] |
| int ast_load_resource | ( | const char * | resource_name | ) |
Load a module.
| resource_name | The name of the module to load. |
This function is run by the PBX to load the modules. It performs all loading and initialization tasks. Basically, to load a module, just give it the name of the module and it will do the rest.
Definition at line 817 of file loader.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, and load_resource().
Referenced by file_ok_sel(), handle_load(), load_module(), manager_moduleload(), and reload().
00818 { 00819 int res; 00820 AST_LIST_LOCK(&module_list); 00821 res = load_resource(resource_name, 0, NULL); 00822 AST_LIST_UNLOCK(&module_list); 00823 00824 return res; 00825 }
| 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. |
This function adds the given function to a linked list of functions to be run when the modules are updated.
| 0 | on success | |
| -1 | on failure. |
Definition at line 1116 of file loader.c.
References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_malloc, and loadupdate::updater.
Referenced by show_console().
01117 { 01118 struct loadupdate *tmp; 01119 01120 if (!(tmp = ast_malloc(sizeof(*tmp)))) 01121 return -1; 01122 01123 tmp->updater = v; 01124 AST_LIST_LOCK(&updaters); 01125 AST_LIST_INSERT_HEAD(&updaters, tmp, entry); 01126 AST_LIST_UNLOCK(&updaters); 01127 01128 return 0; 01129 }
| int ast_loader_unregister | ( | int(*)(void) | updater | ) |
Remove a procedure to be run when modules are updated.
| updater | The updater function to unregister. |
This removes the given function from the updater list.
| 0 | on success | |
| -1 | on failure. |
Definition at line 1131 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().
01132 { 01133 struct loadupdate *cur; 01134 01135 AST_LIST_LOCK(&updaters); 01136 AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) { 01137 if (cur->updater == v) { 01138 AST_LIST_REMOVE_CURRENT(entry); 01139 break; 01140 } 01141 } 01142 AST_LIST_TRAVERSE_SAFE_END; 01143 AST_LIST_UNLOCK(&updaters); 01144 01145 return cur ? 0 : -1; 01146 }
| int ast_module_check | ( | const char * | name | ) |
Check if module exists.
Check if module with the name given is loaded.
Definition at line 1103 of file loader.c.
References ast_strlen_zero(), and find_resource().
Referenced by ifmodule_read(), load_module(), manager_modulecheck(), and unload_module().
01104 { 01105 struct ast_module *cur; 01106 01107 if (ast_strlen_zero(name)) 01108 return 0; /* FALSE */ 01109 01110 cur = find_resource(name, 1); 01111 01112 return (cur != NULL); 01113 }
| 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. |
| A | possible completion of the partial match. | |
| NULL | if no matches were found. |
Definition at line 528 of file loader.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strdup, ast_module::info, name, and ast_module_info::reload.
Referenced by handle_modlist(), handle_reload(), handle_unload(), and load_module().
00529 { 00530 struct ast_module *cur; 00531 int i, which=0, l = strlen(word); 00532 char *ret = NULL; 00533 00534 if (pos != rpos) 00535 return NULL; 00536 00537 AST_LIST_LOCK(&module_list); 00538 AST_LIST_TRAVERSE(&module_list, cur, entry) { 00539 if (!strncasecmp(word, cur->resource, l) && 00540 (cur->info->reload || !needsreload) && 00541 ++which > state) { 00542 ret = ast_strdup(cur->resource); 00543 break; 00544 } 00545 } 00546 AST_LIST_UNLOCK(&module_list); 00547 00548 if (!ret) { 00549 for (i=0; !ret && reload_classes[i].name; i++) { 00550 if (!strncasecmp(word, reload_classes[i].name, l) && ++which > state) 00551 ret = ast_strdup(reload_classes[i].name); 00552 } 00553 } 00554 00555 return ret; 00556 }
| struct ast_module* ast_module_ref | ( | struct ast_module * | mod | ) | [read] |
Definition at line 1148 of file loader.c.
References ast_atomic_fetchadd_int(), ast_update_use_count(), and ast_module::usecount.
Referenced by __oh323_new(), agi_handle_command(), alsa_new(), ast_agi_register(), ast_iax2_new(), ast_timer_open(), dahdi_new(), fn_wrapper(), gtalk_new(), handle_cli_file_convert(), handle_orig(), mgcp_new(), newpvt(), oss_new(), phone_check_exception(), phone_new(), sip_new(), skinny_new(), smdi_load(), and usbradio_new().
01149 { 01150 ast_atomic_fetchadd_int(&mod->usecount, +1); 01151 ast_update_use_count(); 01152 01153 return mod; 01154 }
| void ast_module_register | ( | const struct ast_module_info * | info | ) |
Definition at line 133 of file loader.c.
References ast_calloc, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, embedded_module_list, embedding, ast_module::info, ast_module_info::name, resource_being_loaded, ast_module_info::self, and ast_module::users.
00134 { 00135 struct ast_module *mod; 00136 00137 if (embedding) { 00138 if (!(mod = ast_calloc(1, sizeof(*mod) + strlen(info->name) + 1))) 00139 return; 00140 strcpy(mod->resource, info->name); 00141 } else { 00142 mod = resource_being_loaded; 00143 } 00144 00145 mod->info = info; 00146 AST_LIST_HEAD_INIT(&mod->users); 00147 00148 /* during startup, before the loader has been initialized, 00149 there are no threads, so there is no need to take the lock 00150 on this list to manipulate it. it is also possible that it 00151 might be unsafe to use the list lock at that point... so 00152 let's avoid it altogether 00153 */ 00154 if (embedding) { 00155 AST_LIST_INSERT_TAIL(&embedded_module_list, mod, entry); 00156 } else { 00157 AST_LIST_LOCK(&module_list); 00158 /* it is paramount that the new entry be placed at the tail of 00159 the list, otherwise the code that uses dlopen() to load 00160 dynamic modules won't be able to find out if the module it 00161 just opened was registered or failed to load 00162 */ 00163 AST_LIST_INSERT_TAIL(&module_list, mod, entry); 00164 AST_LIST_UNLOCK(&module_list); 00165 } 00166 00167 /* give the module a copy of its own handle, for later use in registrations and the like */ 00168 *((struct ast_module **) &(info->self)) = mod; 00169 }
| int ast_module_reload | ( | const char * | name | ) |
Reload asterisk modules.
| name | the name of the module to reload |
This function reloads the specified module, or if no modules are specified, it will reload all loaded modules.
| 1 | if the module was found but cannot be reloaded. | |
| -1 | if a reload operation is already in progress. | |
| 2 | if the specfied module was found and reloaded. |
Definition at line 623 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_tvnow(), ast_verb, ast_verbose, ast_module::declined, ast_module_info::description, ast_module::flags, ast_module::info, LOG_NOTICE, queue_reload_request(), ast_module_info::reload, resource_name_match(), and ast_module::running.
Referenced by action_reload(), action_updateconfig(), ast_process_pending_reloads(), handle_reload(), manager_moduleload(), and monitor_sig_flags().
00624 { 00625 struct ast_module *cur; 00626 int res = 0; /* return value. 0 = not found, others, see below */ 00627 int i; 00628 00629 /* If we aren't fully booted, we just pretend we reloaded but we queue this 00630 up to run once we are booted up. */ 00631 if (!ast_fully_booted) { 00632 queue_reload_request(name); 00633 return 0; 00634 } 00635 00636 if (ast_mutex_trylock(&reloadlock)) { 00637 ast_verbose("The previous reload command didn't finish yet\n"); 00638 return -1; /* reload already in progress */ 00639 } 00640 ast_lastreloadtime = ast_tvnow(); 00641 00642 /* Call "predefined" reload here first */ 00643 for (i = 0; reload_classes[i].name; i++) { 00644 if (!name || !strcasecmp(name, reload_classes[i].name)) { 00645 reload_classes[i].reload_fn(); /* XXX should check error ? */ 00646 res = 2; /* found and reloaded */ 00647 } 00648 } 00649 00650 if (name && res) { 00651 ast_mutex_unlock(&reloadlock); 00652 return res; 00653 } 00654 00655 AST_LIST_LOCK(&module_list); 00656 AST_LIST_TRAVERSE(&module_list, cur, entry) { 00657 const struct ast_module_info *info = cur->info; 00658 00659 if (name && resource_name_match(name, cur->resource)) 00660 continue; 00661 00662 if (!cur->flags.running || cur->flags.declined) { 00663 if (!name) 00664 continue; 00665 ast_log(LOG_NOTICE, "The module '%s' was not properly initialized. " 00666 "Before reloading the module, you must run \"module load %s\" " 00667 "and fix whatever is preventing the module from being initialized.\n", 00668 name, name); 00669 res = 2; /* Don't report that the module was not found */ 00670 break; 00671 } 00672 00673 if (!info->reload) { /* cannot be reloaded */ 00674 if (res < 1) /* store result if possible */ 00675 res = 1; /* 1 = no reload() method */ 00676 continue; 00677 } 00678 00679 res = 2; 00680 ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description); 00681 info->reload(); 00682 } 00683 AST_LIST_UNLOCK(&module_list); 00684 00685 ast_mutex_unlock(&reloadlock); 00686 00687 return res; 00688 }
| 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 443 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, free, ast_module::info, ast_module_info::unload, and ast_module::users.
Referenced by quit_handler().
00444 { 00445 struct ast_module *mod; 00446 AST_LIST_HEAD_NOLOCK_STATIC(local_module_list, ast_module); 00447 00448 /* We have to call the unload() callbacks in reverse order that the modules 00449 * exist in the module list so it is the reverse order of how they were 00450 * loaded. */ 00451 00452 AST_LIST_LOCK(&module_list); 00453 while ((mod = AST_LIST_REMOVE_HEAD(&module_list, entry))) 00454 AST_LIST_INSERT_HEAD(&local_module_list, mod, entry); 00455 AST_LIST_UNLOCK(&module_list); 00456 00457 while ((mod = AST_LIST_REMOVE_HEAD(&local_module_list, entry))) { 00458 if (mod->info->unload) 00459 mod->info->unload(); 00460 /* Since this should only be called when shutting down "gracefully", 00461 * all channels should be down before we get to this point, meaning 00462 * there will be no module users left. */ 00463 AST_LIST_HEAD_DESTROY(&mod->users); 00464 free(mod); 00465 } 00466 }
| void ast_module_unref | ( | struct ast_module * | mod | ) |
Definition at line 1156 of file loader.c.
References ast_atomic_fetchadd_int(), ast_update_use_count(), and ast_module::usecount.
Referenced by agi_handle_command(), alsa_hangup(), ast_agi_unregister(), ast_smdi_interface_destroy(), ast_timer_close(), dahdi_destroy_channel_bynum(), dahdi_hangup(), destroy(), filestream_destructor(), gtalk_hangup(), handle_cli_file_convert(), handle_orig(), iax2_predestroy(), mgcp_hangup(), oh323_hangup(), oss_hangup(), phone_check_exception(), phone_hangup(), sip_hangup(), and usbradio_hangup().
01157 { 01158 ast_atomic_fetchadd_int(&mod->usecount, -1); 01159 ast_update_use_count(); 01160 }
| void ast_module_unregister | ( | const struct ast_module_info * | info | ) |
Definition at line 171 of file loader.c.
References ast_free, 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::info, and ast_module::users.
00172 { 00173 struct ast_module *mod = NULL; 00174 00175 /* it is assumed that the users list in the module structure 00176 will already be empty, or we cannot have gotten to this 00177 point 00178 */ 00179 AST_LIST_LOCK(&module_list); 00180 AST_LIST_TRAVERSE_SAFE_BEGIN(&module_list, mod, entry) { 00181 if (mod->info == info) { 00182 AST_LIST_REMOVE_CURRENT(entry); 00183 break; 00184 } 00185 } 00186 AST_LIST_TRAVERSE_SAFE_END; 00187 AST_LIST_UNLOCK(&module_list); 00188 00189 if (mod) { 00190 AST_LIST_HEAD_DESTROY(&mod->users); 00191 ast_free(mod); 00192 } 00193 }
| AST_MUTEX_DEFINE_STATIC | ( | reloadlock | ) |
| 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 558 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, and LOG_NOTICE.
Referenced by main().
00559 { 00560 struct reload_queue_item *item; 00561 00562 if (!ast_fully_booted) { 00563 return; 00564 } 00565 00566 AST_LIST_LOCK(&reload_queue); 00567 00568 if (do_full_reload) { 00569 do_full_reload = 0; 00570 AST_LIST_UNLOCK(&reload_queue); 00571 ast_log(LOG_NOTICE, "Executing deferred reload request.\n"); 00572 ast_module_reload(NULL); 00573 return; 00574 } 00575 00576 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) { 00577 ast_log(LOG_NOTICE, "Executing deferred reload request for module '%s'.\n", item->module); 00578 ast_module_reload(item->module); 00579 ast_free(item); 00580 } 00581 00582 AST_LIST_UNLOCK(&reload_queue); 00583 }
| 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. |
This function unloads a module. It will only unload modules that are not in use (usecount not zero), unless AST_FORCE_FIRM or AST_FORCE_HARD is specified. Setting AST_FORCE_FIRM or AST_FORCE_HARD will unload the module regardless of consequences (NOT RECOMMENDED).
| 0 | on success. | |
| -1 | on error. |
Definition at line 468 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::info, ast_module::lib, LOG_WARNING, ast_module_info::restore_globals, ast_module::running, ast_module_info::unload, and ast_module::usecount.
Referenced by exit_now(), handle_unload(), manager_moduleload(), reload(), and remove_module().
00469 { 00470 struct ast_module *mod; 00471 int res = -1; 00472 int error = 0; 00473 00474 AST_LIST_LOCK(&module_list); 00475 00476 if (!(mod = find_resource(resource_name, 0))) { 00477 AST_LIST_UNLOCK(&module_list); 00478 ast_log(LOG_WARNING, "Unload failed, '%s' could not be found\n", resource_name); 00479 return 0; 00480 } 00481 00482 if (!(mod->flags.running || mod->flags.declined)) 00483 error = 1; 00484 00485 if (!error && (mod->usecount > 0)) { 00486 if (force) 00487 ast_log(LOG_WARNING, "Warning: Forcing removal of module '%s' with use count %d\n", 00488 resource_name, mod->usecount); 00489 else { 00490 ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name, 00491 mod->usecount); 00492 error = 1; 00493 } 00494 } 00495 00496 if (!error) { 00497 __ast_module_user_hangup_all(mod); 00498 res = mod->info->unload(); 00499 00500 if (res) { 00501 ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name); 00502 if (force <= AST_FORCE_FIRM) 00503 error = 1; 00504 else 00505 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n"); 00506 } 00507 } 00508 00509 if (!error) 00510 mod->flags.running = mod->flags.declined = 0; 00511 00512 AST_LIST_UNLOCK(&module_list); 00513 00514 if (!error && !mod->lib && mod->info && mod->info->restore_globals) 00515 mod->info->restore_globals(); 00516 00517 #ifdef LOADABLE_MODULES 00518 if (!error) 00519 unload_dynamic_module(mod); 00520 #endif 00521 00522 if (!error) 00523 ast_update_use_count(); 00524 00525 return res; 00526 }
| 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 1082 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().
01084 { 01085 struct ast_module *cur; 01086 int unlock = -1; 01087 int total_mod_loaded = 0; 01088 01089 if (AST_LIST_TRYLOCK(&module_list)) 01090 unlock = 0; 01091 01092 AST_LIST_TRAVERSE(&module_list, cur, entry) { 01093 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, like); 01094 } 01095 01096 if (unlock) 01097 AST_LIST_UNLOCK(&module_list); 01098 01099 return total_mod_loaded; 01100 }
| 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 1070 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(), handle_request_do(), load_module(), oh323_request(), scheduler_process_request_queue(), sip_request_call(), start_resource(), and unistim_new().
01071 { 01072 /* Notify any module monitors that the use count for a 01073 resource has changed */ 01074 struct loadupdate *m; 01075 01076 AST_LIST_LOCK(&updaters); 01077 AST_LIST_TRAVERSE(&updaters, m, entry) 01078 m->updater(); 01079 AST_LIST_UNLOCK(&updaters); 01080 }
| static struct ast_module* find_resource | ( | const char * | resource, | |
| int | do_lock | |||
| ) | [static, read] |
Definition at line 325 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(), load_modules(), 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 690 of file loader.c.
References ast_log(), ast_strlen_zero(), buildopt_sum, ast_module_info::buildopt_sum, ast_module_info::description, ast_module::info, ast_module_info::key, LOG_WARNING, and verify_key().
Referenced by load_resource().
00691 { 00692 if (!mod->info->description) { 00693 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource); 00694 return 1; 00695 } 00696 00697 if (!mod->info->key) { 00698 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource); 00699 return 1; 00700 } 00701 00702 if (verify_key((unsigned char *) mod->info->key)) { 00703 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource); 00704 return 1; 00705 } 00706 00707 if (!ast_strlen_zero(mod->info->buildopt_sum) && 00708 strcmp(buildopt_sum, mod->info->buildopt_sum)) { 00709 ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource); 00710 ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource); 00711 return 1; 00712 } 00713 00714 return 0; 00715 }
| 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().
| int load_modules | ( | unsigned | int | ) |
Provided by loader.c
Definition at line 927 of file loader.c.
References add_to_load_order(), ast_config_AST_MODULE_DIR, ast_config_destroy(), ast_config_load2(), ast_free, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), AST_MODULE_CONFIG, ast_opt_quiet, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, dir, embedded_module_list, embedding, EVENT_FLAG_SYSTEM, find_resource(), ast_module::flags, ast_module::lib, load_resource_list(), LOG_NOTICE, LOG_WARNING, manager_event, ast_variable::name, ast_variable::next, load_order_entry::resource, resource_name_match(), ast_module::running, and ast_variable::value.
Referenced by main().
00928 { 00929 struct ast_config *cfg; 00930 struct ast_module *mod; 00931 struct load_order_entry *order; 00932 struct ast_variable *v; 00933 unsigned int load_count; 00934 struct load_order load_order; 00935 int res = 0; 00936 struct ast_flags config_flags = { 0 }; 00937 int modulecount = 0; 00938 00939 #ifdef LOADABLE_MODULES 00940 struct dirent *dirent; 00941 DIR *dir; 00942 #endif 00943 00944 /* all embedded modules have registered themselves by now */ 00945 embedding = 0; 00946 00947 ast_verb(1, "Asterisk Dynamic Loader Starting:\n"); 00948 00949 AST_LIST_HEAD_INIT_NOLOCK(&load_order); 00950 00951 AST_LIST_LOCK(&module_list); 00952 00953 if (embedded_module_list.first) { 00954 module_list.first = embedded_module_list.first; 00955 module_list.last = embedded_module_list.last; 00956 embedded_module_list.first = NULL; 00957 } 00958 00959 if (!(cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags))) { 00960 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG); 00961 goto done; 00962 } 00963 00964 /* first, find all the modules we have been explicitly requested to load */ 00965 for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) { 00966 if (!strcasecmp(v->name, preload_only ? "preload" : "load")) { 00967 add_to_load_order(v->value, &load_order); 00968 } 00969 } 00970 00971 /* check if 'autoload' is on */ 00972 if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) { 00973 /* if so, first add all the embedded modules that are not already running to the load order */ 00974 AST_LIST_TRAVERSE(&module_list, mod, entry) { 00975 /* if it's not embedded, skip it */ 00976 if (mod->lib) 00977 continue; 00978 00979 if (mod->flags.running) 00980 continue; 00981 00982 order = add_to_load_order(mod->resource, &load_order); 00983 } 00984 00985 #ifdef LOADABLE_MODULES 00986 /* if we are allowed to load dynamic modules, scan the directory for 00987 for all available modules and add them as well */ 00988 if ((dir = opendir(ast_config_AST_MODULE_DIR))) { 00989 while ((dirent = readdir(dir))) { 00990 int ld = strlen(dirent->d_name); 00991 00992 /* Must end in .so to load it. */ 00993 00994 if (ld < 4) 00995 continue; 00996 00997 if (strcasecmp(dirent->d_name + ld - 3, ".so")) 00998 continue; 00999 01000 /* if there is already a module by this name in the module_list, 01001 skip this file */ 01002 if (find_resource(dirent->d_name, 0)) 01003 continue; 01004 01005 add_to_load_order(dirent->d_name, &load_order); 01006 } 01007 01008 closedir(dir); 01009 } else { 01010 if (!ast_opt_quiet) 01011 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n", 01012 ast_config_AST_MODULE_DIR); 01013 } 01014 #endif 01015 } 01016 01017 /* now scan the config for any modules we are prohibited from loading and 01018 remove them from the load order */ 01019 for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) { 01020 if (strcasecmp(v->name, "noload")) 01021 continue; 01022 01023 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) { 01024 if (!resource_name_match(order->resource, v->value)) { 01025 AST_LIST_REMOVE_CURRENT(entry); 01026 ast_free(order->resource); 01027 ast_free(order); 01028 } 01029 } 01030 AST_LIST_TRAVERSE_SAFE_END; 01031 } 01032 01033 /* we are done with the config now, all the information we need is in the 01034 load_order list */ 01035 ast_config_destroy(cfg); 01036 01037 load_count = 0; 01038 AST_LIST_TRAVERSE(&load_order, order, entry) 01039 load_count++; 01040 01041 if (load_count) 01042 ast_log(LOG_NOTICE, "%d modules will be loaded.\n", load_count); 01043 01044 /* first, load only modules that provide global symbols */ 01045 if ((res = load_resource_list(&load_order, 1, &modulecount)) < 0) { 01046 goto done; 01047 } 01048 01049 /* now load everything else */ 01050 if ((res = load_resource_list(&load_order, 0, &modulecount)) < 0) { 01051 goto done; 01052 } 01053 01054 done: 01055 while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) { 01056 ast_free(order->resource); 01057 ast_free(order); 01058 } 01059 01060 AST_LIST_UNLOCK(&module_list); 01061 01062 /* Tell manager clients that are aggressive at logging in that we're done 01063 loading modules. If there's a DNS problem in chan_sip, we might not 01064 even reach this */ 01065 manager_event(EVENT_FLAG_SYSTEM, "ModuleLoadReport", "ModuleLoadStatus: Done\r\nModuleSelection: %s\r\nModuleCount: %d\r\n", preload_only ? "Preload" : "All", modulecount); 01066 01067 return res; 01068 }
| static enum ast_module_load_result load_resource | ( | const char * | resource_name, | |
| unsigned int | global_symbols_only, | |||
| struct ast_heap * | resource_heap | |||
| ) | [static] |
loads a resource based upon resource_name. If global_symbols_only is set only modules with global symbols will be loaded.
If the ast_heap is provided (not NULL) the module is found and added to the heap without running the module's load() function. By doing this, modules added to the resource_heap can be initialized later in order by priority.
If the ast_heap is not provided, the module's load function will be executed immediately
Definition at line 763 of file loader.c.
References ast_heap_push(), ast_log(), AST_MODFLAG_GLOBAL_SYMBOLS, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_PRIORITY, AST_MODULE_LOAD_SKIP, AST_MODULE_LOAD_SUCCESS, ast_test_flag, ast_module_info::backup_globals, ast_module::declined, find_resource(), ast_module::flags, ast_module::info, inspect_module(), ast_module::lib, LOG_WARNING, ast_module::running, and start_resource().
Referenced by ast_load_resource(), and load_resource_list().
00764 { 00765 struct ast_module *mod; 00766 enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS; 00767 00768 if ((mod = find_resource(resource_name, 0))) { 00769 if (mod->flags.running) { 00770 ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name); 00771 return AST_MODULE_LOAD_DECLINE; 00772 } 00773 if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS)) 00774 return AST_MODULE_LOAD_SKIP; 00775 } else { 00776 #ifdef LOADABLE_MODULES 00777 if (!(mod = load_dynamic_module(resource_name, global_symbols_only))) { 00778 /* don't generate a warning message during load_modules() */ 00779 if (!global_symbols_only) { 00780 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); 00781 return AST_MODULE_LOAD_DECLINE; 00782 } else { 00783 return AST_MODULE_LOAD_SKIP; 00784 } 00785 } 00786 #else 00787 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); 00788 return AST_MODULE_LOAD_DECLINE; 00789 #endif 00790 } 00791 00792 if (inspect_module(mod)) { 00793 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); 00794 #ifdef LOADABLE_MODULES 00795 unload_dynamic_module(mod); 00796 #endif 00797 return AST_MODULE_LOAD_DECLINE; 00798 } 00799 00800 if (!mod->lib && mod->info->backup_globals()) { 00801 ast_log(LOG_WARNING, "Module '%s' was unable to backup its global data.\n", resource_name); 00802 return AST_MODULE_LOAD_DECLINE; 00803 } 00804 00805 mod->flags.declined = 0; 00806 00807 if (resource_heap) { 00808 ast_heap_push(resource_heap, mod); 00809 res = AST_MODULE_LOAD_PRIORITY; 00810 } else { 00811 res = start_resource(mod); 00812 } 00813 00814 return res; 00815 }
| static int load_resource_list | ( | struct load_order * | load_order, | |
| unsigned int | global_symbols, | |||
| int * | mod_count | |||
| ) | [static] |
loads modules in order by load_pri, updates mod_count
Definition at line 869 of file loader.c.
References ast_free, ast_heap_create(), ast_heap_destroy(), ast_heap_pop(), AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_PRIORITY, AST_MODULE_LOAD_SKIP, AST_MODULE_LOAD_SUCCESS, load_resource(), mod_load_cmp(), load_order_entry::resource, and start_resource().
Referenced by load_modules().
00870 { 00871 struct ast_heap *resource_heap; 00872 struct load_order_entry *order; 00873 struct ast_module *mod; 00874 int count = 0; 00875 int res = 0; 00876 00877 if(!(resource_heap = ast_heap_create(8, mod_load_cmp, -1))) { 00878 return -1; 00879 } 00880 00881 /* first, add find and add modules to heap */ 00882 AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) { 00883 switch (load_resource(order->resource, global_symbols, resource_heap)) { 00884 case AST_MODULE_LOAD_SUCCESS: 00885 case AST_MODULE_LOAD_DECLINE: 00886 AST_LIST_REMOVE_CURRENT(entry); 00887 ast_free(order->resource); 00888 ast_free(order); 00889 break; 00890 case AST_MODULE_LOAD_FAILURE: 00891 res = -1; 00892 goto done; 00893 case AST_MODULE_LOAD_SKIP: 00894 break; 00895 case AST_MODULE_LOAD_PRIORITY: 00896 AST_LIST_REMOVE_CURRENT(entry); 00897 break; 00898 } 00899 } 00900 AST_LIST_TRAVERSE_SAFE_END; 00901 00902 /* second remove modules from heap sorted by priority */ 00903 while ((mod = ast_heap_pop(resource_heap))) { 00904 switch (start_resource(mod)) { 00905 case AST_MODULE_LOAD_SUCCESS: 00906 count++; 00907 case AST_MODULE_LOAD_DECLINE: 00908 break; 00909 case AST_MODULE_LOAD_FAILURE: 00910 res = -1; 00911 goto done; 00912 case AST_MODULE_LOAD_SKIP: 00913 case AST_MODULE_LOAD_PRIORITY: 00914 break; 00915 } 00916 } 00917 00918 done: 00919 if (mod_count) { 00920 *mod_count += count; 00921 } 00922 ast_heap_destroy(resource_heap); 00923 00924 return res; 00925 }
| static int mod_load_cmp | ( | void * | a, | |
| void * | b | |||
| ) | [static] |
Definition at line 852 of file loader.c.
References AST_MODFLAG_LOAD_ORDER, ast_test_flag, ast_module::info, and ast_module_info::load_pri.
Referenced by load_resource_list().
00853 { 00854 struct ast_module *a_mod = (struct ast_module *) a; 00855 struct ast_module *b_mod = (struct ast_module *) b; 00856 int res = -1; 00857 /* if load_pri is not set, default is 255. Lower is better*/ 00858 unsigned char a_pri = ast_test_flag(a_mod->info, AST_MODFLAG_LOAD_ORDER) ? a_mod->info->load_pri : 255; 00859 unsigned char b_pri = ast_test_flag(a_mod->info, AST_MODFLAG_LOAD_ORDER) ? b_mod->info->load_pri : 255; 00860 if (a_pri == b_pri) { 00861 res = 0; 00862 } else if (a_pri < b_pri) { 00863 res = 1; 00864 } 00865 return res; 00866 }
| static int printdigest | ( | const unsigned char * | d | ) | [static] |
| static void queue_reload_request | ( | const char * | module | ) | [static] |
Definition at line 585 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, and LOG_ERROR.
Referenced by ast_module_reload().
00586 { 00587 struct reload_queue_item *item; 00588 00589 AST_LIST_LOCK(&reload_queue); 00590 00591 if (do_full_reload) { 00592 AST_LIST_UNLOCK(&reload_queue); 00593 return; 00594 } 00595 00596 if (ast_strlen_zero(module)) { 00597 /* A full reload request (when module is NULL) wipes out any previous 00598 reload requests and causes the queue to ignore future ones */ 00599 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) { 00600 ast_free(item); 00601 } 00602 do_full_reload = 1; 00603 } else { 00604 /* No reason to add the same module twice */ 00605 AST_LIST_TRAVERSE(&reload_queue, item, entry) { 00606 if (!strcasecmp(item->module, module)) { 00607 AST_LIST_UNLOCK(&reload_queue); 00608 return; 00609 } 00610 } 00611 item = ast_calloc(1, sizeof(*item) + strlen(module) + 1); 00612 if (!item) { 00613 ast_log(LOG_ERROR, "Failed to allocate reload queue item.\n"); 00614 AST_LIST_UNLOCK(&reload_queue); 00615 return; 00616 } 00617 strcpy(item->module, module); 00618 AST_LIST_INSERT_TAIL(&reload_queue, item, entry); 00619 } 00620 AST_LIST_UNLOCK(&reload_queue); 00621 }
| 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(), find_resource(), and load_modules().
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 enum ast_module_load_result start_resource | ( | struct ast_module * | mod | ) | [static] |
Definition at line 717 of file loader.c.
References ast_fully_booted, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_PRIORITY, AST_MODULE_LOAD_SKIP, AST_MODULE_LOAD_SUCCESS, ast_opt_console, ast_update_use_count(), ast_verb, ast_verbose, COLOR_BLACK, COLOR_BROWN, ast_module::declined, ast_module_info::description, ast_module::flags, ast_module::info, ast_module_info::load, option_verbose, ast_module::running, and term_color().
Referenced by load_resource(), and load_resource_list().
00718 { 00719 char tmp[256]; 00720 enum ast_module_load_result res; 00721 00722 if (!mod->info->load) { 00723 return AST_MODULE_LOAD_FAILURE; 00724 } 00725 00726 res = mod->info->load(); 00727 00728 switch (res) { 00729 case AST_MODULE_LOAD_SUCCESS: 00730 if (!ast_fully_booted) { 00731 ast_verb(1, "%s => (%s)\n", mod->resource, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp))); 00732 if (ast_opt_console && !option_verbose) 00733 ast_verbose( "."); 00734 } else { 00735 ast_verb(1, "Loaded %s => (%s)\n", mod->resource, mod->info->description); 00736 } 00737 00738 mod->flags.running = 1; 00739 00740 ast_update_use_count(); 00741 break; 00742 case AST_MODULE_LOAD_DECLINE: 00743 mod->flags.declined = 1; 00744 break; 00745 case AST_MODULE_LOAD_FAILURE: 00746 case AST_MODULE_LOAD_SKIP: /* modules should never return this value */ 00747 case AST_MODULE_LOAD_PRIORITY: 00748 break; 00749 } 00750 00751 return res; 00752 }
| 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] |
Definition at line 78 of file loader.c.
Referenced by inspect_module().
int do_full_reload = 0 [static] |
Definition at line 121 of file loader.c.
Referenced by ast_process_pending_reloads(), and queue_reload_request().
struct module_list embedded_module_list [static] |
Definition at line 105 of file loader.c.
Referenced by ast_module_register(), and load_modules().
unsigned int embedding = 1 [static] |
Definition at line 80 of file loader.c.
Referenced by ast_module_register(), and load_modules().
unsigned char expected_key[] [static] |
{ 0x87, 0x76, 0x79, 0x35, 0x23, 0xea, 0x3a, 0xd3,
0x25, 0x2a, 0xbb, 0x35, 0x87, 0xe4, 0x22, 0x24 }
Definition at line 74 of file loader.c.
Referenced by verify_key().
| struct ast_module* resource_being_loaded |
Definition at line 129 of file loader.c.
Referenced by ast_module_register().
1.6.1