Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

module.h File Reference

Go to the source code of this file.

Defines

#define ASTERISK_GPL_KEY   "This paragraph is Copyright (C) 2000, Linux Support Services, Inc. \In order for your module to load, it must return this key via a function \called \"key\". Any code which includes this paragraph must be licensed under \the GNU General Public License version 2 or later (at your option). Linux \Support Services, Inc. reserves the right to allow other parties to license \this paragraph under other terms as well."
#define AST_MODULE_CONFIG   "modules.conf" /*! Module configuration file */
#define AST_FORCE_SOFT   0
#define AST_FORCE_FIRM   1
#define AST_FORCE_HARD   2
#define STANDARD_LOCAL_USER
#define LOCAL_USER_DECL
#define LOCAL_USER_ADD(u)
#define LOCAL_USER_REMOVE(u)
#define STANDARD_HANGUP_LOCALUSERS
#define STANDARD_USECOUNT(res)

Functions

int load_module (void)
 Initialize the module. More...

int unload_module (void)
 Cleanup all module structures, sockets, etc. More...

int usecount (void)
 Provides a usecount. More...

char * description (void)
 Description. More...

char * key (void)
 Returns the ASTERISK_GPL_KEY. More...

int reload (void)
 Reload stuff. More...

int ast_load_resource (char *resource_name)
 Loads a module. More...

int ast_unload_resource (char *resource_name, int force)
 Unloads a module. More...

void ast_update_use_count (void)
 Notify when usecount has been changed. More...

int ast_update_module_list (int(*modentry)(char *module, char *description, int usecnt))
 Ask for a list of modules, descriptions, and use counts. More...

int ast_loader_register (int(*updater)(void))
 Ask this procedure to be run with modules have been updated. More...

int ast_loader_unregister (int(*updater)(void))
 No longer run me when modules are updated. More...

void ast_module_reload (const char *name)
 Reload all modules. More...

int ast_register_atexit (void(*func)(void))
void ast_unregister_atexit (void(*func)(void))


Define Documentation

#define AST_FORCE_FIRM   1
 

Definition at line 80 of file module.h.

Referenced by ast_unload_resource().

#define AST_FORCE_HARD   2
 

Definition at line 81 of file module.h.

#define AST_FORCE_SOFT   0
 

Definition at line 79 of file module.h.

#define AST_MODULE_CONFIG   "modules.conf" /*! Module configuration file */
 

Definition at line 77 of file module.h.

Referenced by ast_load_resource(), and load_modules().

#define ASTERISK_GPL_KEY   "This paragraph is Copyright (C) 2000, Linux Support Services, Inc. \In order for your module to load, it must return this key via a function \called \"key\". Any code which includes this paragraph must be licensed under \the GNU General Public License version 2 or later (at your option). Linux \Support Services, Inc. reserves the right to allow other parties to license \this paragraph under other terms as well."
 

reload configs

Definition at line 69 of file module.h.

#define LOCAL_USER_ADD  
 

Definition at line 159 of file module.h.

#define LOCAL_USER_DECL
 

Value:

AST_MUTEX_DEFINE_STATIC(localuser_lock); \
                  static struct localuser *localusers = NULL; \
                  static int localusecnt = 0;

Definition at line 155 of file module.h.

#define LOCAL_USER_REMOVE  
 

Definition at line 174 of file module.h.

#define STANDARD_HANGUP_LOCALUSERS
 

Definition at line 195 of file module.h.

#define STANDARD_LOCAL_USER
 

Value:

struct localuser { \
                        struct ast_channel *chan; \
                        struct localuser *next; \
                     }

Definition at line 150 of file module.h.

#define STANDARD_USECOUNT res   
 

Value:

{ \
   ast_mutex_lock(&localuser_lock); \
   res = localusecnt; \
   ast_mutex_unlock(&localuser_lock); \
}

Definition at line 209 of file module.h.


Function Documentation

int ast_load_resource char *    resource_name
 

Loads a module.

Parameters:
resource_name  the filename of the module to load This function is ran by the PBX to load the modules. It performs all loading, setting up of it's module related data structures, etc. Basically, to load a module, you just give it the name of the module and it will do the rest. It returns 0 on success, -1 on error

Definition at line 186 of file loader.c.

References ast_destroy(), ast_load(), ast_log(), AST_MODULE_CONFIG, ast_mutex_lock, ast_mutex_unlock, ast_true(), ast_unload_resource(), ast_update_use_count(), ast_variable_retrieve(), ast_verbose(), COLOR_BLACK, COLOR_BROWN, module::description, dlclose(), dlerror(), dlopen(), dlsym(), free, module::key, key(), module::lib, module::load_module, LOG_WARNING, malloc, module::next, module::reload, module::resource, RTLD_GLOBAL, RTLD_LAZY, RTLD_NOW, term_color(), module::unload_module, module::usecount, and VERBOSE_PREFIX_1.

Referenced by load_modules().

00187 {
00188    static char fn[256];
00189    int errors=0;
00190    int res;
00191    struct module *m;
00192    int flags=RTLD_NOW;
00193 #ifdef RTLD_GLOBAL
00194    char *val;
00195 #endif
00196    char *key;
00197    int o;
00198    struct ast_config *cfg;
00199    char tmp[80];
00200    /* Keep the module file parsing silent */
00201    o = option_verbose;
00202    if (strncasecmp(resource_name, "res_", 4)) {
00203       option_verbose = 0;
00204       cfg = ast_load(AST_MODULE_CONFIG);
00205       option_verbose = o;
00206       if (cfg) {
00207 #ifdef RTLD_GLOBAL
00208          if ((val = ast_variable_retrieve(cfg, "global", resource_name))
00209                && ast_true(val))
00210             flags |= RTLD_GLOBAL;
00211 #endif
00212          ast_destroy(cfg);
00213       }
00214    } else {
00215       /* Resource modules are always loaded global and lazy */
00216 #ifdef RTLD_GLOBAL
00217       flags = (RTLD_GLOBAL | RTLD_LAZY);
00218 #else
00219       flags = RTLD_LAZY;
00220 #endif
00221    }
00222    
00223    if (ast_mutex_lock(&modlock))
00224       ast_log(LOG_WARNING, "Failed to lock\n");
00225    m = module_list;
00226    while(m) {
00227       if (!strcasecmp(m->resource, resource_name)) {
00228          ast_log(LOG_WARNING, "Module '%s' already exists\n", resource_name);
00229          ast_mutex_unlock(&modlock);
00230          return -1;
00231       }
00232       m = m->next;
00233    }
00234    m = malloc(sizeof(struct module));  
00235    if (!m) {
00236       ast_log(LOG_WARNING, "Out of memory\n");
00237       ast_mutex_unlock(&modlock);
00238       return -1;
00239    }
00240    strncpy(m->resource, resource_name, sizeof(m->resource)-1);
00241    if (resource_name[0] == '/') {
00242       strncpy(fn, resource_name, sizeof(fn)-1);
00243    } else {
00244       snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_MODULE_DIR, resource_name);
00245    }
00246    m->lib = dlopen(fn, flags);
00247    if (!m->lib) {
00248       ast_log(LOG_WARNING, "%s\n", dlerror());
00249       free(m);
00250       ast_mutex_unlock(&modlock);
00251       return -1;
00252    }
00253    m->load_module = dlsym(m->lib, "load_module");
00254    if (m->load_module == NULL)
00255       m->load_module = dlsym(m->lib, "_load_module");
00256    if (!m->load_module) {
00257       ast_log(LOG_WARNING, "No load_module in module %s\n", fn);
00258       errors++;
00259    }
00260    m->unload_module = dlsym(m->lib, "unload_module");
00261    if (m->unload_module == NULL)
00262       m->unload_module = dlsym(m->lib, "_unload_module");
00263    if (!m->unload_module) {
00264       ast_log(LOG_WARNING, "No unload_module in module %s\n", fn);
00265       errors++;
00266    }
00267    m->usecount = dlsym(m->lib, "usecount");
00268    if (m->usecount == NULL)
00269       m->usecount = dlsym(m->lib, "_usecount");
00270    if (!m->usecount) {
00271       ast_log(LOG_WARNING, "No usecount in module %s\n", fn);
00272       errors++;
00273    }
00274    m->description = dlsym(m->lib, "description");
00275    if (m->description == NULL)
00276       m->description = dlsym(m->lib, "_description");
00277    if (!m->description) {
00278       ast_log(LOG_WARNING, "No description in module %s\n", fn);
00279       errors++;
00280    }
00281    m->key = dlsym(m->lib, "key");
00282    if (m->key == NULL)
00283       m->key = dlsym(m->lib, "_key");
00284    if (!m->key) {
00285       ast_log(LOG_WARNING, "No key routine in module %s\n", fn);
00286       errors++;
00287    }
00288    m->reload = dlsym(m->lib, "reload");
00289    if (m->reload == NULL)
00290       m->reload = dlsym(m->lib, "_reload");
00291    if (!m->key || !(key = m->key())) {
00292       ast_log(LOG_WARNING, "Key routine returned NULL in module %s\n", fn);
00293       key = NULL;
00294       errors++;
00295    }
00296    if (key && verify_key(key)) {
00297       ast_log(LOG_WARNING, "Unexpected key returned by module %s\n", fn);
00298       errors++;
00299    }
00300    if (errors) {
00301       ast_log(LOG_WARNING, "%d error(s) loading module %s, aborted\n", errors, fn);
00302       dlclose(m->lib);
00303       free(m);
00304       ast_mutex_unlock(&modlock);
00305       return -1;
00306    }
00307    if (!fully_booted) {
00308       if (option_verbose) 
00309          ast_verbose( " => (%s)\n", term_color(tmp, m->description(), COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
00310       if (option_console && !option_verbose)
00311          ast_verbose( ".");
00312    } else {
00313       if (option_verbose)
00314          ast_verbose(VERBOSE_PREFIX_1 "Loaded %s => (%s)\n", fn, m->description());
00315    }
00316 
00317    // add module 'm' to end of module_list chain
00318    // so reload commands will be issued in same order modules were loaded
00319    m->next = NULL;
00320    if (module_list == NULL) {
00321       // empty list so far, add at front
00322       module_list = m;
00323    }
00324    else {
00325       struct module *i;
00326       // find end of chain, and add there
00327       for (i = module_list; i->next; i = i->next)
00328          ;
00329       i->next = m;
00330    }
00331    
00332    ast_mutex_unlock(&modlock);
00333    if ((res = m->load_module())) {
00334       ast_log(LOG_WARNING, "%s: load_module failed, returning %d\n", m->resource, res);
00335       ast_unload_resource(resource_name, 0);
00336       return -1;
00337    }
00338    ast_update_use_count();
00339    return 0;
00340 }  

int ast_loader_register int(*    updater)(void)
 

Ask this procedure to be run with 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. It returns 0 on success and -1 on failure.

Definition at line 479 of file loader.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, LOG_WARNING, and malloc.

00480 {
00481    struct loadupdate *tmp;
00482    /* XXX Should be more flexible here, taking > 1 verboser XXX */
00483    if ((tmp = malloc(sizeof (struct loadupdate)))) {
00484       tmp->updater = v;
00485       if (ast_mutex_lock(&modlock))
00486          ast_log(LOG_WARNING, "Failed to lock\n");
00487       tmp->next = updaters;
00488       updaters = tmp;
00489       ast_mutex_unlock(&modlock);
00490       return 0;
00491    }
00492    return -1;
00493 }

int ast_loader_unregister int(*    updater)(void)
 

No longer run me when modules are updated.

Parameters:
updater  function to unregister This removes the given function from the updater list. It returns 0 on success, -1 on failure.

Definition at line 495 of file loader.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, and LOG_WARNING.

00496 {
00497    int res = -1;
00498    struct loadupdate *tmp, *tmpl=NULL;
00499    if (ast_mutex_lock(&modlock))
00500       ast_log(LOG_WARNING, "Failed to lock\n");
00501    tmp = updaters;
00502    while(tmp) {
00503       if (tmp->updater == v)  {
00504          if (tmpl)
00505             tmpl->next = tmp->next;
00506          else
00507             updaters = tmp->next;
00508          break;
00509       }
00510       tmpl = tmp;
00511       tmp = tmp->next;
00512    }
00513    if (tmp)
00514       res = 0;
00515    ast_mutex_unlock(&modlock);
00516    return res;
00517 }

void ast_module_reload const char *    name
 

Reload all modules.

This reloads all modules set to load in asterisk. It does NOT run the unload routine and then loads them again, it runs the given reload routine.

Definition at line 150 of file loader.c.

References ast_enum_reload(), ast_mutex_lock, ast_mutex_trylock, ast_mutex_unlock, ast_rtp_reload(), ast_verbose(), module::description, module::next, read_ast_cust_config(), module::reload, reload_manager(), module::resource, and VERBOSE_PREFIX_3.

00151 {
00152    struct module *m;
00153 
00154    /* We'll do the logger and manager the favor of calling its reload here first */
00155 
00156    if (ast_mutex_trylock(&reloadlock)) {
00157       ast_verbose("The previous reload command didn't finish yet\n");
00158       return;
00159    }
00160    if (!name || !strcasecmp(name, "astconfig"))
00161       read_ast_cust_config();
00162    if (!name || !strcasecmp(name, "manager"))
00163       reload_manager();
00164    if (!name || !strcasecmp(name, "enum"))
00165       ast_enum_reload();
00166    if (!name || !strcasecmp(name, "rtp"))
00167       ast_rtp_reload();
00168    time(&ast_lastreloadtime);
00169 
00170    ast_mutex_lock(&modlock);
00171    m = module_list;
00172    while(m) {
00173       if (!name || !strcasecmp(name, m->resource)) {
00174          if (m->reload) {
00175             if (option_verbose > 2) 
00176                ast_verbose(VERBOSE_PREFIX_3 "Reloading module '%s' (%s)\n", m->resource, m->description());
00177             m->reload();
00178          }
00179       }
00180       m = m->next;
00181    }
00182    ast_mutex_unlock(&modlock);
00183    ast_mutex_unlock(&reloadlock);
00184 }

int ast_register_atexit void(*    func)(void)
 

Definition at line 134 of file asterisk.c.

References ast_mutex_lock, ast_mutex_unlock, ast_unregister_atexit(), and malloc.

00135 {
00136    int res = -1;
00137    struct ast_atexit *ae;
00138    ast_unregister_atexit(func);
00139    ae = malloc(sizeof(struct ast_atexit));
00140    ast_mutex_lock(&atexitslock);
00141    if (ae) {
00142       memset(ae, 0, sizeof(struct ast_atexit));
00143       ae->next = atexits;
00144       ae->func = func;
00145       atexits = ae;
00146       res = 0;
00147    }
00148    ast_mutex_unlock(&atexitslock);
00149    return res;
00150 }

int ast_unload_resource char *    resource_name,
int    force
 

Unloads a module.

Parameters:
resourcename  the name of the module to unload
force  the force flag. Setting this to non-zero will force the module to be unloaded This function unloads a particular module. If the force flag is not set, it will not unload a module with a usecount > 0. However, if it is set, it will unload the module regardless of consequences (NOT_RECOMMENDED)

Definition at line 107 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::next, module::resource, module::unload_module, and module::usecount.

Referenced by ast_load_resource().

00108 {
00109    struct module *m, *ml = NULL;
00110    int res = -1;
00111    if (ast_mutex_lock(&modlock))
00112       ast_log(LOG_WARNING, "Failed to lock\n");
00113    m = module_list;
00114    while(m) {
00115       if (!strcasecmp(m->resource, resource_name)) {
00116          if ((res = m->usecount()) > 0)  {
00117             if (force) 
00118                ast_log(LOG_WARNING, "Warning:  Forcing removal of module %s with use count %d\n", resource_name, res);
00119             else {
00120                ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name, res);
00121                ast_mutex_unlock(&modlock);
00122                return -1;
00123             }
00124          }
00125          res = m->unload_module();
00126          if (res) {
00127             ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
00128             if (force <= AST_FORCE_FIRM) {
00129                ast_mutex_unlock(&modlock);
00130                return -1;
00131             } else
00132                ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
00133          }
00134          if (ml)
00135             ml->next = m->next;
00136          else
00137             module_list = m->next;
00138          dlclose(m->lib);
00139          free(m);
00140          break;
00141       }
00142       ml = m;
00143       m = m->next;
00144    }
00145    ast_mutex_unlock(&modlock);
00146    ast_update_use_count();
00147    return res;
00148 }

void ast_unregister_atexit void(*    func)(void)
 

Definition at line 152 of file asterisk.c.

References ast_mutex_lock, and ast_mutex_unlock.

Referenced by ast_register_atexit().

00153 {
00154    struct ast_atexit *ae, *prev = NULL;
00155    ast_mutex_lock(&atexitslock);
00156    ae = atexits;
00157    while(ae) {
00158       if (ae->func == func) {
00159          if (prev)
00160             prev->next = ae->next;
00161          else
00162             atexits = ae->next;
00163          break;
00164       }
00165       prev = ae;
00166       ae = ae->next;
00167    }
00168    ast_mutex_unlock(&atexitslock);
00169 }

int ast_update_module_list int(*    modentry)(char *module, char *description, int usecnt)
 

Ask for a list of modules, descriptions, and use counts.

Parameters:
modentry  a callback to an updater function For each of the modules loaded, modentry will be executed with the resource, description, and usecount values of each particular module.

Definition at line 463 of file loader.c.

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

00464 {
00465    struct module *m;
00466    int unlock = -1;
00467    if (ast_mutex_trylock(&modlock))
00468       unlock = 0;
00469    m = module_list;
00470    while(m) {
00471       modentry(m->resource, m->description(), m->usecount());
00472       m = m->next;
00473    }
00474    if (unlock)
00475       ast_mutex_unlock(&modlock);
00476    return 0;
00477 }

void ast_update_use_count void   
 

Notify when usecount has been changed.

This function goes through and calulates use counts. It also notifies anybody trying to keep track of them.

Definition at line 447 of file loader.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, and LOG_WARNING.

Referenced by ast_load_resource(), and ast_unload_resource().

00448 {
00449    /* Notify any module monitors that the use count for a 
00450       resource has changed */
00451    struct loadupdate *m;
00452    if (ast_mutex_lock(&modlock))
00453       ast_log(LOG_WARNING, "Failed to lock\n");
00454    m = updaters;
00455    while(m) {
00456       m->updater();
00457       m = m->next;
00458    }
00459    ast_mutex_unlock(&modlock);
00460    
00461 }

char* description void   
 

Description.

Returns a short description of your module.

Referenced by ast_channel_register(), ast_channel_register_ex(), ast_manager_register2(), ast_register_application(), ast_update_module_list(), and load_pbx().

char* key void   
 

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message, i.e. char *key(void){return ASTERISK_GPL_KEY;}

Referenced by ast_db_del(), ast_db_deltree(), ast_db_get(), ast_db_put(), ast_load_resource(), ast_privacy_check(), and ast_privacy_set().

int load_module void   
 

Initialize the module.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

int reload void   
 

Reload stuff.

This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload. Return 0 on success, and other than 0 on problem.

int unload_module void   
 

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit). Return 0 on success, or other than 0 if there is a problem.

int usecount void   
 

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere.


Generated on Thu Oct 28 11:33:03 2004 for Asterisk by doxygen1.2.15