Main Page | Alphabetical List | Data Structures | Directories | 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"
#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.
int unload_module (void)
 Cleanup all module structures, sockets, etc.
int usecount (void)
 Provides a usecount.
char * description (void)
 Description.
char * key (void)
 Returns the ASTERISK_GPL_KEY.
int reload (void)
 Reload stuff.
int ast_load_resource (char *resource_name)
 Loads a module.
int ast_unload_resource (char *resource_name, int force)
 Unloads a module.
void ast_update_use_count (void)
 Notify when usecount has been changed.
int ast_update_module_list (int(*modentry)(char *module, char *description, int usecnt))
 Ask for a list of modules, descriptions, and use counts.
int ast_loader_register (int(*updater)(void))
 Ask this procedure to be run with modules have been updated.
int ast_loader_unregister (int(*updater)(void))
 No longer run me when modules are updated.
void ast_module_reload (const char *name)
 Reload all modules.
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"
 

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 196 of file loader.c.

References ast_config_AST_MODULE_DIR, 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, fully_booted, module::key, module::lib, module::load_module, LOG_WARNING, malloc, module::next, option_console, option_verbose, 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().

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

int ast_loader_register int(*)(void)  updater  ) 
 

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 490 of file loader.c.

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

00491 {
00492    struct loadupdate *tmp;
00493    /* XXX Should be more flexible here, taking > 1 verboser XXX */
00494    if ((tmp = malloc(sizeof (struct loadupdate)))) {
00495       tmp->updater = v;
00496       if (ast_mutex_lock(&modlock))
00497          ast_log(LOG_WARNING, "Failed to lock\n");
00498       tmp->next = updaters;
00499       updaters = tmp;
00500       ast_mutex_unlock(&modlock);
00501       return 0;
00502    }
00503    return -1;
00504 }

int ast_loader_unregister int(*)(void)  updater  ) 
 

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 506 of file loader.c.

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

00507 {
00508    int res = -1;
00509    struct loadupdate *tmp, *tmpl=NULL;
00510    if (ast_mutex_lock(&modlock))
00511       ast_log(LOG_WARNING, "Failed to lock\n");
00512    tmp = updaters;
00513    while(tmp) {
00514       if (tmp->updater == v)  {
00515          if (tmpl)
00516             tmpl->next = tmp->next;
00517          else
00518             updaters = tmp->next;
00519          break;
00520       }
00521       tmpl = tmp;
00522       tmp = tmp->next;
00523    }
00524    if (tmp)
00525       res = 0;
00526    ast_mutex_unlock(&modlock);
00527    return res;
00528 }

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 152 of file loader.c.

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

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

int ast_register_atexit void(*)(void)  func  ) 
 

Definition at line 135 of file asterisk.c.

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

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

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 108 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().

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

void ast_unregister_atexit void(*)(void)  func  ) 
 

Definition at line 153 of file asterisk.c.

References ast_mutex_lock, and ast_mutex_unlock.

Referenced by ast_register_atexit().

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

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

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 474 of file loader.c.

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

00475 {
00476    struct module *m;
00477    int unlock = -1;
00478    if (ast_mutex_trylock(&modlock))
00479       unlock = 0;
00480    m = module_list;
00481    while(m) {
00482       modentry(m->resource, m->description(), m->usecount());
00483       m = m->next;
00484    }
00485    if (unlock)
00486       ast_mutex_unlock(&modlock);
00487    return 0;
00488 }

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 458 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().

00459 {
00460    /* Notify any module monitors that the use count for a 
00461       resource has changed */
00462    struct loadupdate *m;
00463    if (ast_mutex_lock(&modlock))
00464       ast_log(LOG_WARNING, "Failed to lock\n");
00465    m = updaters;
00466    while(m) {
00467       m->updater();
00468       m = m->next;
00469    }
00470    ast_mutex_unlock(&modlock);
00471    
00472 }

char* description void   ) 
 

Description.

Returns a short description of your module.

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_config_destroy_all(), 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.

Referenced by ast_module_reload().

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 Sat Nov 25 19:10:12 2006 for Asterisk by  doxygen 1.4.2