Sat Sep 16 07:28:18 2006

Asterisk developer's documentation


loader.c File Reference

Module Loader. More...

#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/options.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/term.h"
#include "asterisk/manager.h"
#include "asterisk/cdr.h"
#include "asterisk/enum.h"
#include "asterisk/rtp.h"
#include "asterisk/lock.h"
#include <dlfcn.h>
#include "asterisk/md5.h"

Go to the source code of this file.

Data Structures

struct  loadupdate
struct  module

Defines

#define RTLD_NOW   0

Functions

static int __load_resource (const char *resource_name, const struct ast_config *cfg)
int ast_load_resource (const char *resource_name)
 Load a module.
int ast_loader_register (int(*v)(void))
 Add a procedure to be run when modules have been updated.
int ast_loader_unregister (int(*v)(void))
 Remove a procedure to be run when modules are updated.
char * ast_module_helper (char *line, char *word, int pos, int state, int rpos, int needsreload)
 Match modules names for the Asterisk cli.
int ast_module_reload (const char *name)
 Reload asterisk modules.
 AST_MUTEX_DEFINE_STATIC (reloadlock)
 AST_MUTEX_DEFINE_STATIC (modlock)
static int ast_resource_exists (char *resource)
int ast_unload_resource (const char *resource_name, int force)
 Unloads a module.
int ast_update_module_list (int(*modentry)(const char *module, const char *description, int usecnt, const char *like), const char *like)
 Ask for a list of modules, descriptions, and use counts.
void ast_update_use_count (void)
 Notify when usecount has been changed.
static int key_matches (unsigned char *key1, unsigned char *key2)
int load_modules (const int preload_only)
static int printdigest (unsigned char *d)
static int verify_key (unsigned char *key)

Variables

static unsigned char expected_key []
static const char * loadorder []
static int modlistver = 0
static struct modulemodule_list = NULL
static struct loadupdateupdaters


Detailed Description

Module Loader.

Definition in file loader.c.


Define Documentation

#define RTLD_NOW   0

Definition at line 54 of file loader.c.

Referenced by __load_resource(), dlopen(), and loadModule().


Function Documentation

static int __load_resource ( const char *  resource_name,
const struct ast_config cfg 
) [static]

Definition at line 270 of file loader.c.

References ast_config_AST_MODULE_DIR, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_true(), ast_unload_resource(), ast_update_use_count(), ast_variable_retrieve(), ast_verbose(), cfg, COLOR_BLACK, COLOR_BROWN, module::description, dlclose(), dlerror(), dlopen(), dlsym(), free, fully_booted, module::key, key(), module::lib, module::load_module, LOG_WARNING, malloc, module_list, module::next, option_console, option_verbose, module::reload, module::resource, RTLD_GLOBAL, RTLD_LAZY, RTLD_NOW, term_color(), module::unload_module, module::usecount, VERBOSE_PREFIX_1, and verify_key().

Referenced by ast_load_resource(), and load_modules().

00271 {
00272    static char fn[256];
00273    int errors=0;
00274    int res;
00275    struct module *m;
00276    int flags=RTLD_NOW;
00277 #ifdef RTLD_GLOBAL
00278    char *val;
00279 #endif
00280    unsigned char *key;
00281    char tmp[80];
00282 
00283    if (strncasecmp(resource_name, "res_", 4)) {
00284 #ifdef RTLD_GLOBAL
00285       if (cfg) {
00286          if ((val = ast_variable_retrieve(cfg, "global", resource_name))
00287                && ast_true(val))
00288             flags |= RTLD_GLOBAL;
00289       }
00290 #endif
00291    } else {
00292       /* Resource modules are always loaded global and lazy */
00293 #ifdef RTLD_GLOBAL
00294       flags = (RTLD_GLOBAL | RTLD_LAZY);
00295 #else
00296       flags = RTLD_LAZY;
00297 #endif
00298    }
00299    
00300    if (ast_mutex_lock(&modlock))
00301       ast_log(LOG_WARNING, "Failed to lock\n");
00302    m = module_list;
00303    while(m) {
00304       if (!strcasecmp(m->resource, resource_name)) {
00305          ast_log(LOG_WARNING, "Module '%s' already exists\n", resource_name);
00306          ast_mutex_unlock(&modlock);
00307          return -1;
00308       }
00309       m = m->next;
00310    }
00311    m = malloc(sizeof(struct module));  
00312    if (!m) {
00313       ast_log(LOG_WARNING, "Out of memory\n");
00314       ast_mutex_unlock(&modlock);
00315       return -1;
00316    }
00317    strncpy(m->resource, resource_name, sizeof(m->resource)-1);
00318    if (resource_name[0] == '/') {
00319       strncpy(fn, resource_name, sizeof(fn)-1);
00320    } else {
00321       snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_MODULE_DIR, resource_name);
00322    }
00323    m->lib = dlopen(fn, flags);
00324    if (!m->lib) {
00325       ast_log(LOG_WARNING, "%s\n", dlerror());
00326       free(m);
00327       ast_mutex_unlock(&modlock);
00328       return -1;
00329    }
00330    m->load_module = dlsym(m->lib, "load_module");
00331    if (m->load_module == NULL)
00332       m->load_module = dlsym(m->lib, "_load_module");
00333    if (!m->load_module) {
00334       ast_log(LOG_WARNING, "No load_module in module %s\n", fn);
00335       errors++;
00336    }
00337    m->unload_module = dlsym(m->lib, "unload_module");
00338    if (m->unload_module == NULL)
00339       m->unload_module = dlsym(m->lib, "_unload_module");
00340    if (!m->unload_module) {
00341       ast_log(LOG_WARNING, "No unload_module in module %s\n", fn);
00342       errors++;
00343    }
00344    m->usecount = dlsym(m->lib, "usecount");
00345    if (m->usecount == NULL)
00346       m->usecount = dlsym(m->lib, "_usecount");
00347    if (!m->usecount) {
00348       ast_log(LOG_WARNING, "No usecount in module %s\n", fn);
00349       errors++;
00350    }
00351    m->description = dlsym(m->lib, "description");
00352    if (m->description == NULL)
00353       m->description = dlsym(m->lib, "_description");
00354    if (!m->description) {
00355       ast_log(LOG_WARNING, "No description in module %s\n", fn);
00356       errors++;
00357    }
00358    m->key = dlsym(m->lib, "key");
00359    if (m->key == NULL)
00360       m->key = dlsym(m->lib, "_key");
00361    if (!m->key) {
00362       ast_log(LOG_WARNING, "No key routine in module %s\n", fn);
00363       errors++;
00364    }
00365 
00366    m->reload = dlsym(m->lib, "reload");
00367    if (m->reload == NULL)
00368       m->reload = dlsym(m->lib, "_reload");
00369 
00370    if (!m->key || !(key = (unsigned char *) m->key())) {
00371       ast_log(LOG_WARNING, "Key routine returned NULL in module %s\n", fn);
00372       key = NULL;
00373       errors++;
00374    }
00375    if (key && verify_key(key)) {
00376       ast_log(LOG_WARNING, "Unexpected key returned by module %s\n", fn);
00377       errors++;
00378    }
00379    if (errors) {
00380       ast_log(LOG_WARNING, "%d error%s loading module %s, aborted\n", errors, (errors != 1) ? "s" : "", fn);
00381       dlclose(m->lib);
00382       free(m);
00383       ast_mutex_unlock(&modlock);
00384       return -1;
00385    }
00386    if (!fully_booted) {
00387       if (option_verbose) 
00388          ast_verbose( " => (%s)\n", term_color(tmp, m->description(), COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
00389       if (option_console && !option_verbose)
00390          ast_verbose( ".");
00391    } else {
00392       if (option_verbose)
00393          ast_verbose(VERBOSE_PREFIX_1 "Loaded %s => (%s)\n", fn, m->description());
00394    }
00395 
00396    /* add module 'm' to end of module_list chain
00397       so reload commands will be issued in same order modules were loaded */
00398    m->next = NULL;
00399    if (module_list == NULL) {
00400       /* empty list so far, add at front */
00401       module_list = m;
00402    }
00403    else {
00404       struct module *i;
00405       /* find end of chain, and add there */
00406       for (i = module_list; i->next; i = i->next)
00407          ;
00408       i->next = m;
00409    }
00410    
00411    modlistver = rand();
00412    ast_mutex_unlock(&modlock);
00413    if ((res = m->load_module())) {
00414       ast_log(LOG_WARNING, "%s: load_module failed, returning %d\n", m->resource, res);
00415       ast_unload_resource(resource_name, 0);
00416       return -1;
00417    }
00418    ast_update_use_count();
00419    return 0;
00420 }

int ast_load_resource ( const char *  resource_name  ) 

Load a module.

Parameters:
resource_name The filename of the module to load.
This function is run by the PBX to load the modules. It performs all loading and initilization tasks. Basically, to load a module, just give it the name of the module and it will do the rest.

Returns:
Zero on success, -1 on error.

Definition at line 422 of file loader.c.

References __load_resource(), ast_config_destroy(), ast_config_load(), AST_MODULE_CONFIG, cfg, and option_verbose.

Referenced by file_ok_sel(), handle_load(), load_module(), and reload_module().

00423 {
00424    int o;
00425    struct ast_config *cfg = NULL;
00426    int res;
00427 
00428    /* Keep the module file parsing silent */
00429    o = option_verbose;
00430    option_verbose = 0;
00431    cfg = ast_config_load(AST_MODULE_CONFIG);
00432    option_verbose = o;
00433    res = __load_resource(resource_name, cfg);
00434    if (cfg)
00435       ast_config_destroy(cfg);
00436    return res;
00437 }  

int ast_loader_register ( int(*)(void)  updater  ) 

Add a procedure to be run when modules have been updated.

Parameters:
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.

Returns:
Zero on success and -1 on failure.

Definition at line 608 of file loader.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, malloc, loadupdate::next, loadupdate::updater, and updaters.

Referenced by show_console().

00609 {
00610    struct loadupdate *tmp;
00611    /* XXX Should be more flexible here, taking > 1 verboser XXX */
00612    if ((tmp = malloc(sizeof (struct loadupdate)))) {
00613       tmp->updater = v;
00614       if (ast_mutex_lock(&modlock))
00615          ast_log(LOG_WARNING, "Failed to lock\n");
00616       tmp->next = updaters;
00617       updaters = tmp;
00618       ast_mutex_unlock(&modlock);
00619       return 0;
00620    }
00621    return -1;
00622 }

int ast_loader_unregister ( int(*)(void)  updater  ) 

Remove a procedure to be run when modules are updated.

Parameters:
updater The updater function to unregister.
This removes the given function from the updater list.

Returns:
Zero on success, -1 on failure.

Definition at line 624 of file loader.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, loadupdate::next, loadupdate::updater, and updaters.

Referenced by exit_now().

00625 {
00626    int res = -1;
00627    struct loadupdate *tmp, *tmpl=NULL;
00628    if (ast_mutex_lock(&modlock))
00629       ast_log(LOG_WARNING, "Failed to lock\n");
00630    tmp = updaters;
00631    while(tmp) {
00632       if (tmp->updater == v)  {
00633          if (tmpl)
00634             tmpl->next = tmp->next;
00635          else
00636             updaters = tmp->next;
00637          break;
00638       }
00639       tmpl = tmp;
00640       tmp = tmp->next;
00641    }
00642    if (tmp)
00643       res = 0;
00644    ast_mutex_unlock(&modlock);
00645    return res;
00646 }

char* ast_module_helper ( char *  line,
char *  word,
int  pos,
int  state,
int  rpos,
int  needsreload 
)

Match modules names for the Asterisk cli.

Parameters:
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.
Returns:
A possible completion of the partial match, or NULL if no matches were found.

Definition at line 166 of file loader.c.

References ast_mutex_lock(), ast_mutex_unlock(), module_list, module::next, module::reload, module::resource, and strdup.

Referenced by complete_mod_2(), and complete_mod_4().

00167 {
00168    struct module *m;
00169    int which=0;
00170    char *ret;
00171 
00172    if (pos != rpos)
00173       return NULL;
00174    ast_mutex_lock(&modlock);
00175    m = module_list;
00176    while(m) {
00177       if (!strncasecmp(word, m->resource, strlen(word)) && (m->reload || !needsreload)) {
00178          if (++which > state)
00179             break;
00180       }
00181       m = m->next;
00182    }
00183    if (m) {
00184       ret = strdup(m->resource);
00185    } else {
00186       ret = NULL;
00187       if (!strncasecmp(word, "extconfig", strlen(word))) {
00188          if (++which > state)
00189             ret = strdup("extconfig");
00190       } else if (!strncasecmp(word, "manager", strlen(word))) {
00191          if (++which > state)
00192             ret = strdup("manager");
00193       } else if (!strncasecmp(word, "enum", strlen(word))) {
00194          if (++which > state)
00195             ret = strdup("enum");
00196       } else if (!strncasecmp(word, "rtp", strlen(word))) {
00197          if (++which > state)
00198             ret = strdup("rtp");
00199       }
00200          
00201    }
00202    ast_mutex_unlock(&modlock);
00203    return ret;
00204 }

int ast_module_reload ( const char *  name  ) 

Reload asterisk modules.

Parameters:
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.

Note:
Modules are reloaded using their reload() functions, not unloading them and loading them again.
Returns:
Zero if the specified module was not found, 1 if the module was found but cannot be reloaded, -1 if a reload operation is already in progress, and 2 if the specfied module was found and reloaded.

Definition at line 206 of file loader.c.

References ast_cdr_engine_reload(), ast_enum_reload(), ast_lastreloadtime, ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_rtp_reload(), ast_verbose(), module::description, dnsmgr_reload(), module_list, module::next, option_verbose, read_config_maps(), reload(), module::reload, reload_manager(), module::resource, and VERBOSE_PREFIX_3.

Referenced by handle_reload(), and hup_handler().

00207 {
00208    struct module *m;
00209    int reloaded = 0;
00210    int oldversion;
00211    int (*reload)(void);
00212    /* We'll do the logger and manager the favor of calling its reload here first */
00213 
00214    if (ast_mutex_trylock(&reloadlock)) {
00215       ast_verbose("The previous reload command didn't finish yet\n");
00216       return -1;
00217    }
00218    if (!name || !strcasecmp(name, "extconfig")) {
00219       read_config_maps();
00220       reloaded = 2;
00221    }
00222    if (!name || !strcasecmp(name, "manager")) {
00223       reload_manager();
00224       reloaded = 2;
00225    }
00226    if (!name || !strcasecmp(name, "cdr")) {
00227       ast_cdr_engine_reload();
00228       reloaded = 2;
00229    }
00230    if (!name || !strcasecmp(name, "enum")) {
00231       ast_enum_reload();
00232       reloaded = 2;
00233    }
00234    if (!name || !strcasecmp(name, "rtp")) {
00235       ast_rtp_reload();
00236       reloaded = 2;
00237    }
00238    if (!name || !strcasecmp(name, "dnsmgr")) {
00239       dnsmgr_reload();
00240       reloaded = 2;
00241    }
00242    time(&ast_lastreloadtime);
00243 
00244    ast_mutex_lock(&modlock);
00245    oldversion = modlistver;
00246    m = module_list;
00247    while(m) {
00248       if (!name || !strcasecmp(name, m->resource)) {
00249          if (reloaded < 1)
00250             reloaded = 1;
00251          reload = m->reload;
00252          ast_mutex_unlock(&modlock);
00253          if (reload) {
00254             reloaded = 2;
00255             if (option_verbose > 2) 
00256                ast_verbose(VERBOSE_PREFIX_3 "Reloading module '%s' (%s)\n", m->resource, m->description());
00257             reload();
00258          }
00259          ast_mutex_lock(&modlock);
00260          if (oldversion != modlistver)
00261             break;
00262       }
00263       m = m->next;
00264    }
00265    ast_mutex_unlock(&modlock);
00266    ast_mutex_unlock(&reloadlock);
00267    return reloaded;
00268 }

AST_MUTEX_DEFINE_STATIC ( reloadlock   ) 

AST_MUTEX_DEFINE_STATIC ( modlock   ) 

static int ast_resource_exists ( char *  resource  )  [static]

Definition at line 439 of file loader.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, module_list, module::next, and module::resource.

00440 {
00441    struct module *m;
00442    if (ast_mutex_lock(&modlock))
00443       ast_log(LOG_WARNING, "Failed to lock\n");
00444    m = module_list;
00445    while(m) {
00446       if (!strcasecmp(resource, m->resource))
00447          break;
00448       m = m->next;
00449    }
00450    ast_mutex_unlock(&modlock);
00451    if (m)
00452       return -1;
00453    else
00454       return 0;
00455 }

int ast_unload_resource ( const char *  resource_name,
int  force 
)

Unloads a module.

Parameters:
resource_name The name of the module to unload.
force 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).

Returns:
Zero on success, -1 on error.

Definition at line 122 of file loader.c.

References AST_FORCE_FIRM, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_update_use_count(), dlclose(), free, module::lib, LOG_WARNING, module_list, module::next, module::resource, module::unload_module, and module::usecount.

Referenced by __load_resource(), exit_now(), handle_unload(), reload_module(), and remove_module().

00123 {
00124    struct module *m, *ml = NULL;
00125    int res = -1;
00126    if (ast_mutex_lock(&modlock))
00127       ast_log(LOG_WARNING, "Failed to lock\n");
00128    m = module_list;
00129    while(m) {
00130       if (!strcasecmp(m->resource, resource_name)) {
00131          if ((res = m->usecount()) > 0)  {
00132             if (force) 
00133                ast_log(LOG_WARNING, "Warning:  Forcing removal of module %s with use count %d\n", resource_name, res);
00134             else {
00135                ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name, res);
00136                ast_mutex_unlock(&modlock);
00137                return -1;
00138             }
00139          }
00140          res = m->unload_module();
00141          if (res) {
00142             ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
00143             if (force <= AST_FORCE_FIRM) {
00144                ast_mutex_unlock(&modlock);
00145                return -1;
00146             } else
00147                ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
00148          }
00149          if (ml)
00150             ml->next = m->next;
00151          else
00152             module_list = m->next;
00153          dlclose(m->lib);
00154          free(m);
00155          break;
00156       }
00157       ml = m;
00158       m = m->next;
00159    }
00160    modlistver = rand();
00161    ast_mutex_unlock(&modlock);
00162    ast_update_use_count();
00163    return res;
00164 }

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.

Parameters:
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.
Returns:
the number of modules loaded

Definition at line 588 of file loader.c.

References ast_mutex_trylock(), ast_mutex_unlock(), module::description, module_list, module::next, module::resource, and module::usecount.

Referenced by handle_modlist(), and mod_update().

00590 {
00591    struct module *m;
00592    int unlock = -1;
00593    int total_mod_loaded = 0;
00594 
00595    if (ast_mutex_trylock(&modlock))
00596       unlock = 0;
00597    m = module_list;
00598    while (m) {
00599       total_mod_loaded += modentry(m->resource, m->description(), m->usecount(), like);
00600       m = m->next;
00601    }
00602    if (unlock)
00603       ast_mutex_unlock(&modlock);
00604 
00605    return total_mod_loaded;
00606 }

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.

Note:
The LOCAL_USER macros take care of calling this function for you.

Definition at line 572 of file loader.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, loadupdate::next, loadupdate::updater, and updaters.

Referenced by __load_resource(), __oh323_new(), adpcm_destroy(), adpcmtolin_new(), agent_new(), alaw_destroy(), alawtolin_new(), alawtoulaw_new(), alsa_new(), aopen_decusecnt(), aopen_incusecnt(), ast_iax2_new(), ast_modem_new(), ast_unload_resource(), au_close(), au_open(), au_rewrite(), bestdata_decusecnt(), bestdata_incusecnt(), exit_now(), features_new(), g723_close(), g723_destroy(), g723_open(), g723_rewrite(), g723tolin_new(), g726_16_open(), g726_16_rewrite(), g726_24_open(), g726_24_rewrite(), g726_32_open(), g726_32_rewrite(), g726_40_open(), g726_40_rewrite(), g726_close(), g726_destroy(), g726tolin_new(), g729_close(), g729_open(), g729_rewrite(), gsm_close(), gsm_open(), gsm_rewrite(), h263_close(), h263_open(), h263_rewrite(), i4l_decusecnt(), i4l_incusecnt(), iax2_predestroy(), ilbc_close(), ilbc_open(), ilbc_rewrite(), lintoadpcm_new(), lintoalaw_new(), lintog723_new(), lintog726_new(), lintoulaw_new(), load_module(), local_new(), mgcp_hangup(), mgcp_new(), modem_hangup(), nbs_new(), ogg_vorbis_close(), ogg_vorbis_open(), ogg_vorbis_rewrite(), oh323_hangup(), oh323_request(), oss_new(), pcm_close(), pcm_open(), pcm_rewrite(), phone_check_exception(), phone_hangup(), phone_new(), sip_hangup(), sip_new(), sip_request_call(), sipsock_read(), skinny_new(), slinear_close(), slinear_open(), slinear_rewrite(), ulaw_destroy(), ulawtoalaw_new(), ulawtolin_new(), vox_close(), vox_open(), vox_rewrite(), vpb_hangup(), vpb_new(), wav_close(), wav_open(), wav_rewrite(), zt_hangup(), and zt_new().

00573 {
00574    /* Notify any module monitors that the use count for a 
00575       resource has changed */
00576    struct loadupdate *m;
00577    if (ast_mutex_lock(&modlock))
00578       ast_log(LOG_WARNING, "Failed to lock\n");
00579    m = updaters;
00580    while(m) {
00581       m->updater();
00582       m = m->next;
00583    }
00584    ast_mutex_unlock(&modlock);
00585    
00586 }

static int key_matches ( unsigned char *  key1,
unsigned char *  key2 
) [static]

Definition at line 99 of file loader.c.

References match().

Referenced by verify_key().

00100 {
00101    int match = 1;
00102    int x;
00103    for (x=0; x<16; x++) {
00104       match &= (key1[x] == key2[x]);
00105    }
00106    return match;
00107 }

int load_modules ( const int  preload_only  ) 

Definition at line 465 of file loader.c.

References __load_resource(), ast_config_destroy(), ast_config_load(), ast_log(), AST_MODULE_CONFIG, ast_variable_browse(), ast_verbose(), cfg, COLOR_BRWHITE, LOG_DEBUG, LOG_WARNING, ast_variable::name, ast_variable::next, option_debug, option_verbose, term_color(), ast_variable::value, and VERBOSE_PREFIX_1.

Referenced by main().

00466 {
00467    struct ast_config *cfg;
00468    struct ast_variable *v;
00469    char tmp[80];
00470 
00471    if (option_verbose) {
00472       if (preload_only)
00473          ast_verbose("Asterisk Dynamic Loader loading preload modules:\n");
00474       else
00475          ast_verbose("Asterisk Dynamic Loader Starting:\n");
00476    }
00477 
00478    cfg = ast_config_load(AST_MODULE_CONFIG);
00479    if (cfg) {
00480       int doload;
00481 
00482       /* Load explicitly defined modules */
00483       for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
00484          doload = 0;
00485 
00486          if (preload_only)
00487             doload = !strcasecmp(v->name, "preload");
00488          else
00489             doload = !strcasecmp(v->name, "load");
00490 
00491              if (doload) {
00492             if (option_debug && !option_verbose)
00493                ast_log(LOG_DEBUG, "Loading module %s\n", v->value);
00494             if (option_verbose) {
00495                ast_verbose(VERBOSE_PREFIX_1 "[%s]", term_color(tmp, v->value, COLOR_BRWHITE, 0, sizeof(tmp)));
00496                fflush(stdout);
00497             }
00498             if (__load_resource(v->value, cfg)) {
00499                ast_log(LOG_WARNING, "Loading module %s failed!\n", v->value);
00500                ast_config_destroy(cfg);
00501                return -1;
00502             }
00503          }
00504       }
00505    }
00506 
00507    if (preload_only) {
00508       ast_config_destroy(cfg);
00509       return 0;
00510    }
00511 
00512    if (!cfg || ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
00513       /* Load all modules */
00514       DIR *mods;
00515       struct dirent *d;
00516       int x;
00517 
00518       /* Loop through each order */
00519       for (x=0; x<sizeof(loadorder) / sizeof(loadorder[0]); x++) {
00520          mods = opendir((char *)ast_config_AST_MODULE_DIR);
00521          if (mods) {
00522             while((d = readdir(mods))) {
00523                /* Must end in .so to load it.  */
00524                if ((strlen(d->d_name) > 3) && 
00525                    (!loadorder[x] || !strncasecmp(d->d_name, loadorder[x], strlen(loadorder[x]))) && 
00526                    !strcasecmp(d->d_name + strlen(d->d_name) - 3, ".so") &&
00527                   !ast_resource_exists(d->d_name)) {
00528                   /* It's a shared library -- Just be sure we're allowed to load it -- kinda
00529                      an inefficient way to do it, but oh well. */
00530                   if (cfg) {
00531                      v = ast_variable_browse(cfg, "modules");
00532                      while(v) {
00533                         if (!strcasecmp(v->name, "noload") &&
00534                             !strcasecmp(v->value, d->d_name)) 
00535                            break;
00536                         v = v->next;
00537                      }
00538                      if (v) {
00539                         if (option_verbose) {
00540                            ast_verbose( VERBOSE_PREFIX_1 "[skipping %s]\n", d->d_name);
00541                            fflush(stdout);
00542                         }
00543                         continue;
00544                      }
00545                      
00546                   }
00547                   if (option_debug && !option_verbose)
00548                      ast_log(LOG_DEBUG, "Loading module %s\n", d->d_name);
00549                   if (option_verbose) {
00550                      ast_verbose( VERBOSE_PREFIX_1 "[%s]", term_color(tmp, d->d_name, COLOR_BRWHITE, 0, sizeof(tmp)));
00551                      fflush(stdout);
00552                   }
00553                   if (__load_resource(d->d_name, cfg)) {
00554                      ast_log(LOG_WARNING, "Loading module %s failed!\n", d->d_name);
00555                      if (cfg)
00556                         ast_config_destroy(cfg);
00557                      return -1;
00558                   }
00559                }
00560             }
00561             closedir(mods);
00562          } else {
00563             if (!option_quiet)
00564                ast_log(LOG_WARNING, "Unable to open modules directory %s.\n", (char *)ast_config_AST_MODULE_DIR);
00565          }
00566       }
00567    } 
00568    ast_config_destroy(cfg);
00569    return 0;
00570 }

static int printdigest ( unsigned char *  d  )  [static]

Definition at line 84 of file loader.c.

References ast_log(), and LOG_DEBUG.

Referenced by verify_key().

00085 {
00086    int x;
00087    char buf[256];
00088    char buf2[16];
00089    snprintf(buf, sizeof(buf), "Unexpected signature:");
00090    for (x=0; x<16; x++) {
00091       snprintf(buf2, sizeof(buf2), " %02x", *(d++));
00092       strcat(buf, buf2);
00093    }
00094    strcat(buf, "\n");
00095    ast_log(LOG_DEBUG, "%s", buf);
00096    return 0;
00097 }

static int verify_key ( unsigned char *  key  )  [static]

Definition at line 109 of file loader.c.

References key_matches(), MD5Final(), MD5Init(), MD5Update(), and printdigest().

Referenced by __load_resource().

00110 {
00111    struct MD5Context c;
00112    unsigned char digest[16];
00113    MD5Init(&c);
00114    MD5Update(&c, key, strlen((char *)key));
00115    MD5Final(digest, &c);
00116    if (key_matches(expected_key, digest))
00117       return 0;
00118    printdigest(digest);
00119    return -1;
00120 }


Variable Documentation

unsigned char expected_key[] [static]

Initial value:

{ 0x8e, 0x93, 0x22, 0x83, 0xf5, 0xc3, 0xc0, 0x75,
  0xff, 0x8b, 0xa9, 0xbe, 0x7c, 0x43, 0x74, 0x63 }

Definition at line 63 of file loader.c.

const char* loadorder[] [static]

Definition at line 457 of file loader.c.

int modlistver = 0 [static]

Definition at line 61 of file loader.c.

struct module* module_list = NULL [static]

Definition at line 60 of file loader.c.

Referenced by __load_resource(), ast_module_helper(), ast_module_reload(), ast_resource_exists(), ast_unload_resource(), and ast_update_module_list().

struct loadupdate * updaters [static]

Referenced by ast_loader_register(), ast_loader_unregister(), and ast_update_use_count().


Generated on Sat Sep 16 07:28:18 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7