Version 0.1.2 from FTP
[asterisk/asterisk.git] / loader.c
index af52f65..63c44df 100755 (executable)
--- a/loader.c
+++ b/loader.c
@@ -3,7 +3,7 @@
  *
  * Module Loader
  * 
- * Copyright (C) 1999, Adtran Inc. and Linux Support Services, LLC
+ * Copyright (C) 1999, Mark Spencer
  *
  * Mark Spencer <markster@linux-support.net>
  *
@@ -91,9 +91,38 @@ int ast_load_resource(char *resource_name)
        static char fn[256];
        int errors=0;
        int res;
-       struct module *m = malloc(sizeof(struct module));
+       struct module *m;
+       int flags=0;
+       char *val;
+       int o;
+       struct ast_config *cfg;
+       /* Keep the module file parsing silent */
+       o = option_verbose;
+       option_verbose = 0;
+       cfg = ast_load(AST_MODULE_CONFIG);
+       option_verbose = o;
+       if (cfg) {
+               if ((val = ast_variable_retrieve(cfg, "global", resource_name))
+                               && ast_true(val))
+                       flags |= RTLD_GLOBAL;
+               ast_destroy(cfg);
+       }
+       
+       if (pthread_mutex_lock(&modlock))
+               ast_log(LOG_WARNING, "Failed to lock\n");
+       m = module_list;
+       while(m) {
+               if (!strcasecmp(m->resource, resource_name)) {
+                       ast_log(LOG_WARNING, "Module '%s' already exists\n", resource_name);
+                       pthread_mutex_unlock(&modlock);
+                       return -1;
+               }
+               m = m->next;
+       }
+       m = malloc(sizeof(struct module));      
        if (!m) {
                ast_log(LOG_WARNING, "Out of memory\n");
+               pthread_mutex_unlock(&modlock);
                return -1;
        }
        strncpy(m->resource, resource_name, sizeof(m->resource));
@@ -102,10 +131,11 @@ int ast_load_resource(char *resource_name)
        } else {
                snprintf(fn, sizeof(fn), "%s/%s", AST_MODULE_DIR, resource_name);
        }
-       m->lib = dlopen(fn, RTLD_NOW  | RTLD_GLOBAL);
+       m->lib = dlopen(fn, RTLD_NOW | flags);
        if (!m->lib) {
                ast_log(LOG_WARNING, "%s\n", dlerror());
                free(m);
+               pthread_mutex_unlock(&modlock);
                return -1;
        }
        m->load_module = dlsym(m->lib, "load_module");
@@ -132,25 +162,31 @@ int ast_load_resource(char *resource_name)
                ast_log(LOG_WARNING, "%d error(s) loading module %s, aborted\n", errors, fn);
                dlclose(m->lib);
                free(m);
+               pthread_mutex_unlock(&modlock);
                return -1;
        }
-       if (option_verbose) 
-               ast_verbose( " => (%s)\n", m->description());
-       if ((res = m->load_module())) {
-               ast_log(LOG_WARNING, "%s: load_module failed, returning %d\n", m->resource, fn, res);
-               free(m);
-               return -1;
+       if (!fully_booted) {
+               if (option_verbose) 
+                       ast_verbose( " => (%s)\n", m->description());
+               if (option_console && !option_verbose)
+                       ast_verbose( ".");
+       } else {
+               if (option_verbose)
+                       ast_verbose(VERBOSE_PREFIX_1 "Loaded %s => (%s)\n", fn, m->description());
        }
-       if (pthread_mutex_lock(&modlock))
-               ast_log(LOG_WARNING, "Failed to lock\n");
        m->next = module_list;
        module_list = m;
        pthread_mutex_unlock(&modlock);
+       if ((res = m->load_module())) {
+               ast_log(LOG_WARNING, "%s: load_module failed, returning %d\n", m->resource, res);
+               ast_unload_resource(resource_name, 0);
+               return -1;
+       }
        ast_update_use_count();
        return 0;
 }      
 
-int ast_resource_exists(char *resource)
+static int ast_resource_exists(char *resource)
 {
        struct module *m;
        if (pthread_mutex_lock(&modlock))