c216a94628fae3486ec4f43f1a8cb549f01d44aa
[asterisk/asterisk.git] / main / loader.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  * Kevin P. Fleming <kpfleming@digium.com>
8  * Luigi Rizzo <rizzo@icir.org>
9  *
10  * See http://www.asterisk.org for more information about
11  * the Asterisk project. Please do not directly contact
12  * any of the maintainers of this project for assistance;
13  * the project provides a web site, mailing lists and IRC
14  * channels for your use.
15  *
16  * This program is free software, distributed under the terms of
17  * the GNU General Public License Version 2. See the LICENSE file
18  * at the top of the source tree.
19  */
20
21 /*! \file
22  *
23  * \brief Module Loader
24  * \author Mark Spencer <markster@digium.com>
25  * \author Kevin P. Fleming <kpfleming@digium.com>
26  * \author Luigi Rizzo <rizzo@icir.org>
27  * - See ModMngMnt
28  */
29
30 #include "asterisk.h"
31
32 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
33
34 #include "asterisk/_private.h"
35 #include "asterisk/paths.h"     /* use ast_config_AST_MODULE_DIR */
36 #include <dirent.h>
37
38 #include "asterisk/linkedlists.h"
39 #include "asterisk/module.h"
40 #include "asterisk/config.h"
41 #include "asterisk/channel.h"
42 #include "asterisk/term.h"
43 #include "asterisk/manager.h"
44 #include "asterisk/cdr.h"
45 #include "asterisk/enum.h"
46 #include "asterisk/http.h"
47 #include "asterisk/lock.h"
48 #include "asterisk/features.h"
49 #include "asterisk/dsp.h"
50 #include "asterisk/udptl.h"
51 #include "asterisk/heap.h"
52
53 #include <dlfcn.h>
54
55 #include "asterisk/md5.h"
56 #include "asterisk/utils.h"
57
58 #ifndef RTLD_NOW
59 #define RTLD_NOW 0
60 #endif
61
62 #ifndef RTLD_LOCAL
63 #define RTLD_LOCAL 0
64 #endif
65
66 struct ast_module_user {
67         struct ast_channel *chan;
68         AST_LIST_ENTRY(ast_module_user) entry;
69 };
70
71 AST_LIST_HEAD(module_user_list, ast_module_user);
72
73 static const unsigned char expected_key[] =
74 { 0x87, 0x76, 0x79, 0x35, 0x23, 0xea, 0x3a, 0xd3,
75   0x25, 0x2a, 0xbb, 0x35, 0x87, 0xe4, 0x22, 0x24 };
76
77 static char buildopt_sum[33] = AST_BUILDOPT_SUM;
78
79 static unsigned int embedding = 1; /* we always start out by registering embedded modules,
80                                       since they are here before we dlopen() any
81                                    */
82
83 struct ast_module {
84         const struct ast_module_info *info;
85         void *lib;                                      /* the shared lib, or NULL if embedded */
86         int usecount;                                   /* the number of 'users' currently in this module */
87         struct module_user_list users;                  /* the list of users in the module */
88         struct {
89                 unsigned int running:1;
90                 unsigned int declined:1;
91         } flags;
92         AST_LIST_ENTRY(ast_module) entry;
93         char resource[0];
94 };
95
96 static AST_LIST_HEAD_STATIC(module_list, ast_module);
97
98 /*
99  * module_list is cleared by its constructor possibly after
100  * we start accumulating embedded modules, so we need to
101  * use another list (without the lock) to accumulate them.
102  * Then we update the main list when embedding is done.
103  */
104 static struct module_list embedded_module_list;
105
106 struct loadupdate {
107         int (*updater)(void);
108         AST_LIST_ENTRY(loadupdate) entry;
109 };
110
111 static AST_LIST_HEAD_STATIC(updaters, loadupdate);
112
113 AST_MUTEX_DEFINE_STATIC(reloadlock);
114
115 struct reload_queue_item {
116         AST_LIST_ENTRY(reload_queue_item) entry;
117         char module[0];
118 };
119
120 static int do_full_reload = 0;
121
122 static AST_LIST_HEAD_STATIC(reload_queue, reload_queue_item);
123
124 /* when dynamic modules are being loaded, ast_module_register() will
125    need to know what filename the module was loaded from while it
126    is being registered
127 */
128 static struct ast_module *resource_being_loaded;
129
130 /* XXX: should we check for duplicate resource names here? */
131
132 void ast_module_register(const struct ast_module_info *info)
133 {
134         struct ast_module *mod;
135
136         if (embedding) {
137                 if (!(mod = ast_calloc(1, sizeof(*mod) + strlen(info->name) + 1)))
138                         return;
139                 strcpy(mod->resource, info->name);
140         } else {
141                 mod = resource_being_loaded;
142         }
143
144         mod->info = info;
145         AST_LIST_HEAD_INIT(&mod->users);
146
147         /* during startup, before the loader has been initialized,
148            there are no threads, so there is no need to take the lock
149            on this list to manipulate it. it is also possible that it
150            might be unsafe to use the list lock at that point... so
151            let's avoid it altogether
152         */
153         if (embedding) {
154                 AST_LIST_INSERT_TAIL(&embedded_module_list, mod, entry);
155         } else {
156                 AST_LIST_LOCK(&module_list);
157                 /* it is paramount that the new entry be placed at the tail of
158                    the list, otherwise the code that uses dlopen() to load
159                    dynamic modules won't be able to find out if the module it
160                    just opened was registered or failed to load
161                 */
162                 AST_LIST_INSERT_TAIL(&module_list, mod, entry);
163                 AST_LIST_UNLOCK(&module_list);
164         }
165
166         /* give the module a copy of its own handle, for later use in registrations and the like */
167         *((struct ast_module **) &(info->self)) = mod;
168 }
169
170 void ast_module_unregister(const struct ast_module_info *info)
171 {
172         struct ast_module *mod = NULL;
173
174         /* it is assumed that the users list in the module structure
175            will already be empty, or we cannot have gotten to this
176            point
177         */
178         AST_LIST_LOCK(&module_list);
179         AST_LIST_TRAVERSE_SAFE_BEGIN(&module_list, mod, entry) {
180                 if (mod->info == info) {
181                         AST_LIST_REMOVE_CURRENT(entry);
182                         break;
183                 }
184         }
185         AST_LIST_TRAVERSE_SAFE_END;
186         AST_LIST_UNLOCK(&module_list);
187
188         if (mod) {
189                 AST_LIST_HEAD_DESTROY(&mod->users);
190                 ast_free(mod);
191         }
192 }
193
194 struct ast_module_user *__ast_module_user_add(struct ast_module *mod,
195                                               struct ast_channel *chan)
196 {
197         struct ast_module_user *u = ast_calloc(1, sizeof(*u));
198
199         if (!u)
200                 return NULL;
201
202         u->chan = chan;
203
204         AST_LIST_LOCK(&mod->users);
205         AST_LIST_INSERT_HEAD(&mod->users, u, entry);
206         AST_LIST_UNLOCK(&mod->users);
207
208         ast_atomic_fetchadd_int(&mod->usecount, +1);
209
210         ast_update_use_count();
211
212         return u;
213 }
214
215 void __ast_module_user_remove(struct ast_module *mod, struct ast_module_user *u)
216 {
217         AST_LIST_LOCK(&mod->users);
218         AST_LIST_REMOVE(&mod->users, u, entry);
219         AST_LIST_UNLOCK(&mod->users);
220         ast_atomic_fetchadd_int(&mod->usecount, -1);
221         ast_free(u);
222
223         ast_update_use_count();
224 }
225
226 void __ast_module_user_hangup_all(struct ast_module *mod)
227 {
228         struct ast_module_user *u;
229
230         AST_LIST_LOCK(&mod->users);
231         while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) {
232                 ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD);
233                 ast_atomic_fetchadd_int(&mod->usecount, -1);
234                 ast_free(u);
235         }
236         AST_LIST_UNLOCK(&mod->users);
237
238         ast_update_use_count();
239 }
240
241 /*! \note
242  * In addition to modules, the reload command handles some extra keywords
243  * which are listed here together with the corresponding handlers.
244  * This table is also used by the command completion code.
245  */
246 static struct reload_classes {
247         const char *name;
248         int (*reload_fn)(void);
249 } reload_classes[] = {  /* list in alpha order, longest match first for cli completion */
250         { "cdr",        ast_cdr_engine_reload },
251         { "dnsmgr",     dnsmgr_reload },
252         { "extconfig",  read_config_maps },
253         { "enum",       ast_enum_reload },
254         { "manager",    reload_manager },
255         { "http",       ast_http_reload },
256         { "logger",     logger_reload },
257         { "features",   ast_features_reload },
258         { "dsp",        ast_dsp_reload},
259         { "udptl",      ast_udptl_reload },
260         { "indications", ast_indications_reload },
261         { "cel",        ast_cel_engine_reload },
262         { NULL,         NULL }
263 };
264
265 static int printdigest(const unsigned char *d)
266 {
267         int x, pos;
268         char buf[256]; /* large enough so we don't have to worry */
269
270         for (pos = 0, x = 0; x < 16; x++)
271                 pos += sprintf(buf + pos, " %02x", *d++);
272
273         ast_debug(1, "Unexpected signature:%s\n", buf);
274
275         return 0;
276 }
277
278 static int key_matches(const unsigned char *key1, const unsigned char *key2)
279 {
280         int x;
281
282         for (x = 0; x < 16; x++) {
283                 if (key1[x] != key2[x])
284                         return 0;
285         }
286
287         return 1;
288 }
289
290 static int verify_key(const unsigned char *key)
291 {
292         struct MD5Context c;
293         unsigned char digest[16];
294
295         MD5Init(&c);
296         MD5Update(&c, key, strlen((char *)key));
297         MD5Final(digest, &c);
298
299         if (key_matches(expected_key, digest))
300                 return 0;
301
302         printdigest(digest);
303
304         return -1;
305 }
306
307 static int resource_name_match(const char *name1_in, const char *name2_in)
308 {
309         char *name1 = (char *) name1_in;
310         char *name2 = (char *) name2_in;
311
312         /* trim off any .so extensions */
313         if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) {
314                 name1 = ast_strdupa(name1);
315                 name1[strlen(name1) - 3] = '\0';
316         }
317         if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) {
318                 name2 = ast_strdupa(name2);
319                 name2[strlen(name2) - 3] = '\0';
320         }
321
322         return strcasecmp(name1, name2);
323 }
324
325 static struct ast_module *find_resource(const char *resource, int do_lock)
326 {
327         struct ast_module *cur;
328
329         if (do_lock)
330                 AST_LIST_LOCK(&module_list);
331
332         AST_LIST_TRAVERSE(&module_list, cur, entry) {
333                 if (!resource_name_match(resource, cur->resource))
334                         break;
335         }
336
337         if (do_lock)
338                 AST_LIST_UNLOCK(&module_list);
339
340         return cur;
341 }
342
343 #ifdef LOADABLE_MODULES
344 static void unload_dynamic_module(struct ast_module *mod)
345 {
346         void *lib = mod->lib;
347
348         /* WARNING: the structure pointed to by mod is going to
349            disappear when this operation succeeds, so we can't
350            dereference it */
351
352         if (lib)
353                 while (!dlclose(lib));
354 }
355
356 static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int global_symbols_only)
357 {
358         char fn[PATH_MAX] = "";
359         void *lib = NULL;
360         struct ast_module *mod;
361         unsigned int wants_global;
362         int space;      /* room needed for the descriptor */
363         int missing_so = 0;
364
365         space = sizeof(*resource_being_loaded) + strlen(resource_in) + 1;
366         if (strcasecmp(resource_in + strlen(resource_in) - 3, ".so")) {
367                 missing_so = 1;
368                 space += 3;     /* room for the extra ".so" */
369         }
370
371         snprintf(fn, sizeof(fn), "%s/%s%s", ast_config_AST_MODULE_DIR, resource_in, missing_so ? ".so" : "");
372
373         /* make a first load of the module in 'quiet' mode... don't try to resolve
374            any symbols, and don't export any symbols. this will allow us to peek into
375            the module's info block (if available) to see what flags it has set */
376
377         resource_being_loaded = ast_calloc(1, space);
378         if (!resource_being_loaded)
379                 return NULL;
380         strcpy(resource_being_loaded->resource, resource_in);
381         if (missing_so)
382                 strcat(resource_being_loaded->resource, ".so");
383
384         if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_LOCAL))) {
385                 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
386                 ast_free(resource_being_loaded);
387                 return NULL;
388         }
389
390         /* the dlopen() succeeded, let's find out if the module
391            registered itself */
392         /* note that this will only work properly as long as
393            ast_module_register() (which is called by the module's
394            constructor) places the new module at the tail of the
395            module_list
396         */
397         if (resource_being_loaded != (mod = AST_LIST_LAST(&module_list))) {
398                 ast_log(LOG_WARNING, "Module '%s' did not register itself during load\n", resource_in);
399                 /* no, it did not, so close it and return */
400                 while (!dlclose(lib));
401                 /* note that the module's destructor will call ast_module_unregister(),
402                    which will free the structure we allocated in resource_being_loaded */
403                 return NULL;
404         }
405
406         wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS);
407
408         /* if we are being asked only to load modules that provide global symbols,
409            and this one does not, then close it and return */
410         if (global_symbols_only && !wants_global) {
411                 while (!dlclose(lib));
412                 return NULL;
413         }
414
415         while (!dlclose(lib));
416         resource_being_loaded = NULL;
417
418         /* start the load process again */
419         resource_being_loaded = ast_calloc(1, space);
420         if (!resource_being_loaded)
421                 return NULL;
422         strcpy(resource_being_loaded->resource, resource_in);
423         if (missing_so)
424                 strcat(resource_being_loaded->resource, ".so");
425
426         if (!(lib = dlopen(fn, wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) {
427                 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
428                 ast_free(resource_being_loaded);
429                 return NULL;
430         }
431
432         /* since the module was successfully opened, and it registered itself
433            the previous time we did that, we're going to assume it worked this
434            time too :) */
435
436         AST_LIST_LAST(&module_list)->lib = lib;
437         resource_being_loaded = NULL;
438
439         return AST_LIST_LAST(&module_list);
440 }
441 #endif
442
443 void ast_module_shutdown(void)
444 {
445         struct ast_module *mod;
446         AST_LIST_HEAD_NOLOCK_STATIC(local_module_list, ast_module);
447
448         /* We have to call the unload() callbacks in reverse order that the modules
449          * exist in the module list so it is the reverse order of how they were
450          * loaded. */
451
452         AST_LIST_LOCK(&module_list);
453         while ((mod = AST_LIST_REMOVE_HEAD(&module_list, entry)))
454                 AST_LIST_INSERT_HEAD(&local_module_list, mod, entry);
455         AST_LIST_UNLOCK(&module_list);
456
457         while ((mod = AST_LIST_REMOVE_HEAD(&local_module_list, entry))) {
458                 if (mod->info->unload)
459                         mod->info->unload();
460                 /* Since this should only be called when shutting down "gracefully",
461                  * all channels should be down before we get to this point, meaning
462                  * there will be no module users left. */
463                 AST_LIST_HEAD_DESTROY(&mod->users);
464                 free(mod);
465         }
466 }
467
468 int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force)
469 {
470         struct ast_module *mod;
471         int res = -1;
472         int error = 0;
473
474         AST_LIST_LOCK(&module_list);
475
476         if (!(mod = find_resource(resource_name, 0))) {
477                 AST_LIST_UNLOCK(&module_list);
478                 ast_log(LOG_WARNING, "Unload failed, '%s' could not be found\n", resource_name);
479                 return 0;
480         }
481
482         if (!(mod->flags.running || mod->flags.declined))
483                 error = 1;
484
485         if (!error && (mod->usecount > 0)) {
486                 if (force)
487                         ast_log(LOG_WARNING, "Warning:  Forcing removal of module '%s' with use count %d\n",
488                                 resource_name, mod->usecount);
489                 else {
490                         ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name,
491                                 mod->usecount);
492                         error = 1;
493                 }
494         }
495
496         if (!error) {
497                 __ast_module_user_hangup_all(mod);
498                 res = mod->info->unload();
499
500                 if (res) {
501                         ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
502                         if (force <= AST_FORCE_FIRM)
503                                 error = 1;
504                         else
505                                 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
506                 }
507         }
508
509         if (!error)
510                 mod->flags.running = mod->flags.declined = 0;
511
512         AST_LIST_UNLOCK(&module_list);
513
514         if (!error && !mod->lib && mod->info && mod->info->restore_globals)
515                 mod->info->restore_globals();
516
517 #ifdef LOADABLE_MODULES
518         if (!error)
519                 unload_dynamic_module(mod);
520 #endif
521
522         if (!error)
523                 ast_update_use_count();
524
525         return res;
526 }
527
528 char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload)
529 {
530         struct ast_module *cur;
531         int i, which=0, l = strlen(word);
532         char *ret = NULL;
533
534         if (pos != rpos)
535                 return NULL;
536
537         AST_LIST_LOCK(&module_list);
538         AST_LIST_TRAVERSE(&module_list, cur, entry) {
539                 if (!strncasecmp(word, cur->resource, l) &&
540                     (cur->info->reload || !needsreload) &&
541                     ++which > state) {
542                         ret = ast_strdup(cur->resource);
543                         break;
544                 }
545         }
546         AST_LIST_UNLOCK(&module_list);
547
548         if (!ret) {
549                 for (i=0; !ret && reload_classes[i].name; i++) {
550                         if (!strncasecmp(word, reload_classes[i].name, l) && ++which > state)
551                                 ret = ast_strdup(reload_classes[i].name);
552                 }
553         }
554
555         return ret;
556 }
557
558 void ast_process_pending_reloads(void)
559 {
560         struct reload_queue_item *item;
561
562         if (!ast_fully_booted) {
563                 return;
564         }
565
566         AST_LIST_LOCK(&reload_queue);
567
568         if (do_full_reload) {
569                 do_full_reload = 0;
570                 AST_LIST_UNLOCK(&reload_queue);
571                 ast_log(LOG_NOTICE, "Executing deferred reload request.\n");
572                 ast_module_reload(NULL);
573                 return;
574         }
575
576         while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
577                 ast_log(LOG_NOTICE, "Executing deferred reload request for module '%s'.\n", item->module);
578                 ast_module_reload(item->module);
579                 ast_free(item);
580         }
581
582         AST_LIST_UNLOCK(&reload_queue);
583 }
584
585 static void queue_reload_request(const char *module)
586 {
587         struct reload_queue_item *item;
588
589         AST_LIST_LOCK(&reload_queue);
590
591         if (do_full_reload) {
592                 AST_LIST_UNLOCK(&reload_queue);
593                 return;
594         }
595
596         if (ast_strlen_zero(module)) {
597                 /* A full reload request (when module is NULL) wipes out any previous
598                    reload requests and causes the queue to ignore future ones */
599                 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
600                         ast_free(item);
601                 }
602                 do_full_reload = 1;
603         } else {
604                 /* No reason to add the same module twice */
605                 AST_LIST_TRAVERSE(&reload_queue, item, entry) {
606                         if (!strcasecmp(item->module, module)) {
607                                 AST_LIST_UNLOCK(&reload_queue);
608                                 return;
609                         }
610                 }
611                 item = ast_calloc(1, sizeof(*item) + strlen(module) + 1);
612                 if (!item) {
613                         ast_log(LOG_ERROR, "Failed to allocate reload queue item.\n");
614                         AST_LIST_UNLOCK(&reload_queue);
615                         return;
616                 }
617                 strcpy(item->module, module);
618                 AST_LIST_INSERT_TAIL(&reload_queue, item, entry);
619         }
620         AST_LIST_UNLOCK(&reload_queue);
621 }
622
623 int ast_module_reload(const char *name)
624 {
625         struct ast_module *cur;
626         int res = 0; /* return value. 0 = not found, others, see below */
627         int i;
628
629         /* If we aren't fully booted, we just pretend we reloaded but we queue this
630            up to run once we are booted up. */
631         if (!ast_fully_booted) {
632                 queue_reload_request(name);
633                 return 0;
634         }
635
636         if (ast_mutex_trylock(&reloadlock)) {
637                 ast_verbose("The previous reload command didn't finish yet\n");
638                 return -1;      /* reload already in progress */
639         }
640         ast_lastreloadtime = ast_tvnow();
641
642         /* Call "predefined" reload here first */
643         for (i = 0; reload_classes[i].name; i++) {
644                 if (!name || !strcasecmp(name, reload_classes[i].name)) {
645                         reload_classes[i].reload_fn();  /* XXX should check error ? */
646                         res = 2;        /* found and reloaded */
647                 }
648         }
649
650         if (name && res) {
651                 ast_mutex_unlock(&reloadlock);
652                 return res;
653         }
654
655         AST_LIST_LOCK(&module_list);
656         AST_LIST_TRAVERSE(&module_list, cur, entry) {
657                 const struct ast_module_info *info = cur->info;
658
659                 if (name && resource_name_match(name, cur->resource))
660                         continue;
661
662                 if (!cur->flags.running || cur->flags.declined) {
663                         if (!name)
664                                 continue;
665                         ast_log(LOG_NOTICE, "The module '%s' was not properly initialized.  "
666                                 "Before reloading the module, you must run \"module load %s\" "
667                                 "and fix whatever is preventing the module from being initialized.\n",
668                                 name, name);
669                         res = 2; /* Don't report that the module was not found */
670                         break;
671                 }
672
673                 if (!info->reload) {    /* cannot be reloaded */
674                         if (res < 1)    /* store result if possible */
675                                 res = 1;        /* 1 = no reload() method */
676                         continue;
677                 }
678
679                 res = 2;
680                 ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description);
681                 info->reload();
682         }
683         AST_LIST_UNLOCK(&module_list);
684
685         ast_mutex_unlock(&reloadlock);
686
687         return res;
688 }
689
690 static unsigned int inspect_module(const struct ast_module *mod)
691 {
692         if (!mod->info->description) {
693                 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource);
694                 return 1;
695         }
696
697         if (!mod->info->key) {
698                 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource);
699                 return 1;
700         }
701
702         if (verify_key((unsigned char *) mod->info->key)) {
703                 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource);
704                 return 1;
705         }
706
707         if (!ast_strlen_zero(mod->info->buildopt_sum) &&
708             strcmp(buildopt_sum, mod->info->buildopt_sum)) {
709                 ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource);
710                 ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource);
711                 return 1;
712         }
713
714         return 0;
715 }
716
717 static enum ast_module_load_result start_resource(struct ast_module *mod)
718 {
719         char tmp[256];
720         enum ast_module_load_result res;
721
722         if (!mod->info->load) {
723                 return AST_MODULE_LOAD_FAILURE;
724         }
725
726         res = mod->info->load();
727
728         switch (res) {
729         case AST_MODULE_LOAD_SUCCESS:
730                 if (!ast_fully_booted) {
731                         ast_verb(1, "%s => (%s)\n", mod->resource, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
732                         if (ast_opt_console && !option_verbose)
733                                 ast_verbose( ".");
734                 } else {
735                         ast_verb(1, "Loaded %s => (%s)\n", mod->resource, mod->info->description);
736                 }
737
738                 mod->flags.running = 1;
739
740                 ast_update_use_count();
741                 break;
742         case AST_MODULE_LOAD_DECLINE:
743                 mod->flags.declined = 1;
744                 break;
745         case AST_MODULE_LOAD_FAILURE:
746         case AST_MODULE_LOAD_SKIP: /* modules should never return this value */
747         case AST_MODULE_LOAD_PRIORITY:
748                 break;
749         }
750
751         return res;
752 }
753
754 /*! loads a resource based upon resource_name. If global_symbols_only is set
755  *  only modules with global symbols will be loaded.
756  *
757  *  If the ast_heap is provided (not NULL) the module is found and added to the
758  *  heap without running the module's load() function.  By doing this, modules
759  *  added to the resource_heap can be initialized later in order by priority. 
760  *
761  *  If the ast_heap is not provided, the module's load function will be executed
762  *  immediately */
763 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap)
764 {
765         struct ast_module *mod;
766         enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
767
768         if ((mod = find_resource(resource_name, 0))) {
769                 if (mod->flags.running) {
770                         ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name);
771                         return AST_MODULE_LOAD_DECLINE;
772                 }
773                 if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS))
774                         return AST_MODULE_LOAD_SKIP;
775         } else {
776 #ifdef LOADABLE_MODULES
777                 if (!(mod = load_dynamic_module(resource_name, global_symbols_only))) {
778                         /* don't generate a warning message during load_modules() */
779                         if (!global_symbols_only) {
780                                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
781                                 return AST_MODULE_LOAD_DECLINE;
782                         } else {
783                                 return AST_MODULE_LOAD_SKIP;
784                         }
785                 }
786 #else
787                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
788                 return AST_MODULE_LOAD_DECLINE;
789 #endif
790         }
791
792         if (inspect_module(mod)) {
793                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
794 #ifdef LOADABLE_MODULES
795                 unload_dynamic_module(mod);
796 #endif
797                 return AST_MODULE_LOAD_DECLINE;
798         }
799
800         if (!mod->lib && mod->info->backup_globals()) {
801                 ast_log(LOG_WARNING, "Module '%s' was unable to backup its global data.\n", resource_name);
802                 return AST_MODULE_LOAD_DECLINE;
803         }
804
805         mod->flags.declined = 0;
806
807         if (resource_heap) {
808                 ast_heap_push(resource_heap, mod);
809                 res = AST_MODULE_LOAD_PRIORITY;
810         } else {
811                 res = start_resource(mod);
812         }
813
814         return res;
815 }
816
817 int ast_load_resource(const char *resource_name)
818 {
819         int res;
820         AST_LIST_LOCK(&module_list);
821         res = load_resource(resource_name, 0, NULL);
822         AST_LIST_UNLOCK(&module_list);
823
824         return res;
825 }
826
827 struct load_order_entry {
828         char *resource;
829         AST_LIST_ENTRY(load_order_entry) entry;
830 };
831
832 AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
833
834 static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order)
835 {
836         struct load_order_entry *order;
837
838         AST_LIST_TRAVERSE(load_order, order, entry) {
839                 if (!resource_name_match(order->resource, resource))
840                         return NULL;
841         }
842
843         if (!(order = ast_calloc(1, sizeof(*order))))
844                 return NULL;
845
846         order->resource = ast_strdup(resource);
847         AST_LIST_INSERT_TAIL(load_order, order, entry);
848
849         return order;
850 }
851
852 static int mod_load_cmp(void *a, void *b)
853 {
854         struct ast_module *a_mod = (struct ast_module *) a;
855         struct ast_module *b_mod = (struct ast_module *) b;
856         int res = -1;
857         /* if load_pri is not set, default is 255.  Lower is better*/
858         unsigned char a_pri = ast_test_flag(a_mod->info, AST_MODFLAG_LOAD_ORDER) ? a_mod->info->load_pri : 255;
859         unsigned char b_pri = ast_test_flag(a_mod->info, AST_MODFLAG_LOAD_ORDER) ? b_mod->info->load_pri : 255;
860         if (a_pri == b_pri) {
861                 res = 0;
862         } else if (a_pri < b_pri) {
863                 res = 1;
864         }
865         return res;
866 }
867
868 /*! loads modules in order by load_pri, updates mod_count */
869 static int load_resource_list(struct load_order *load_order, unsigned int global_symbols, int *mod_count)
870 {
871         struct ast_heap *resource_heap;
872         struct load_order_entry *order;
873         struct ast_module *mod;
874         int count = 0;
875         int res = 0;
876
877         if(!(resource_heap = ast_heap_create(8, mod_load_cmp, -1))) {
878                 return -1;
879         }
880
881         /* first, add find and add modules to heap */
882         AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
883                 switch (load_resource(order->resource, global_symbols, resource_heap)) {
884                 case AST_MODULE_LOAD_SUCCESS:
885                 case AST_MODULE_LOAD_DECLINE:
886                         AST_LIST_REMOVE_CURRENT(entry);
887                         ast_free(order->resource);
888                         ast_free(order);
889                         break;
890                 case AST_MODULE_LOAD_FAILURE:
891                         res = -1;
892                         goto done;
893                 case AST_MODULE_LOAD_SKIP:
894                         break;
895                 case AST_MODULE_LOAD_PRIORITY:
896                         AST_LIST_REMOVE_CURRENT(entry);
897                         break;
898                 }
899         }
900         AST_LIST_TRAVERSE_SAFE_END;
901
902         /* second remove modules from heap sorted by priority */
903         while ((mod = ast_heap_pop(resource_heap))) {
904                 switch (start_resource(mod)) {
905                 case AST_MODULE_LOAD_SUCCESS:
906                         count++;
907                 case AST_MODULE_LOAD_DECLINE:
908                         break;
909                 case AST_MODULE_LOAD_FAILURE:
910                         res = -1;
911                         goto done;
912                 case AST_MODULE_LOAD_SKIP:
913                 case AST_MODULE_LOAD_PRIORITY:
914                         break;
915                 }
916         }
917
918 done:
919         if (mod_count) {
920                 *mod_count += count;
921         }
922         ast_heap_destroy(resource_heap);
923
924         return res;
925 }
926
927 int load_modules(unsigned int preload_only)
928 {
929         struct ast_config *cfg;
930         struct ast_module *mod;
931         struct load_order_entry *order;
932         struct ast_variable *v;
933         unsigned int load_count;
934         struct load_order load_order;
935         int res = 0;
936         struct ast_flags config_flags = { 0 };
937         int modulecount = 0;
938
939 #ifdef LOADABLE_MODULES
940         struct dirent *dirent;
941         DIR *dir;
942 #endif
943
944         /* all embedded modules have registered themselves by now */
945         embedding = 0;
946
947         ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
948
949         AST_LIST_HEAD_INIT_NOLOCK(&load_order);
950
951         AST_LIST_LOCK(&module_list);
952
953         if (embedded_module_list.first) {
954                 module_list.first = embedded_module_list.first;
955                 module_list.last = embedded_module_list.last;
956                 embedded_module_list.first = NULL;
957         }
958
959         cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags);
960         if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
961                 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
962                 goto done;
963         }
964
965         /* first, find all the modules we have been explicitly requested to load */
966         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
967                 if (!strcasecmp(v->name, preload_only ? "preload" : "load")) {
968                         add_to_load_order(v->value, &load_order);
969                 }
970         }
971
972         /* check if 'autoload' is on */
973         if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
974                 /* if so, first add all the embedded modules that are not already running to the load order */
975                 AST_LIST_TRAVERSE(&module_list, mod, entry) {
976                         /* if it's not embedded, skip it */
977                         if (mod->lib)
978                                 continue;
979
980                         if (mod->flags.running)
981                                 continue;
982
983                         order = add_to_load_order(mod->resource, &load_order);
984                 }
985
986 #ifdef LOADABLE_MODULES
987                 /* if we are allowed to load dynamic modules, scan the directory for
988                    for all available modules and add them as well */
989                 if ((dir  = opendir(ast_config_AST_MODULE_DIR))) {
990                         while ((dirent = readdir(dir))) {
991                                 int ld = strlen(dirent->d_name);
992
993                                 /* Must end in .so to load it.  */
994
995                                 if (ld < 4)
996                                         continue;
997
998                                 if (strcasecmp(dirent->d_name + ld - 3, ".so"))
999                                         continue;
1000
1001                                 /* if there is already a module by this name in the module_list,
1002                                    skip this file */
1003                                 if (find_resource(dirent->d_name, 0))
1004                                         continue;
1005
1006                                 add_to_load_order(dirent->d_name, &load_order);
1007                         }
1008
1009                         closedir(dir);
1010                 } else {
1011                         if (!ast_opt_quiet)
1012                                 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",
1013                                         ast_config_AST_MODULE_DIR);
1014                 }
1015 #endif
1016         }
1017
1018         /* now scan the config for any modules we are prohibited from loading and
1019            remove them from the load order */
1020         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1021                 if (strcasecmp(v->name, "noload"))
1022                         continue;
1023
1024                 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
1025                         if (!resource_name_match(order->resource, v->value)) {
1026                                 AST_LIST_REMOVE_CURRENT(entry);
1027                                 ast_free(order->resource);
1028                                 ast_free(order);
1029                         }
1030                 }
1031                 AST_LIST_TRAVERSE_SAFE_END;
1032         }
1033
1034         /* we are done with the config now, all the information we need is in the
1035            load_order list */
1036         ast_config_destroy(cfg);
1037
1038         load_count = 0;
1039         AST_LIST_TRAVERSE(&load_order, order, entry)
1040                 load_count++;
1041
1042         if (load_count)
1043                 ast_log(LOG_NOTICE, "%d modules will be loaded.\n", load_count);
1044
1045         /* first, load only modules that provide global symbols */
1046         if ((res = load_resource_list(&load_order, 1, &modulecount)) < 0) {
1047                 goto done;
1048         }
1049
1050         /* now load everything else */
1051         if ((res = load_resource_list(&load_order, 0, &modulecount)) < 0) {
1052                 goto done;
1053         }
1054
1055 done:
1056         while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
1057                 ast_free(order->resource);
1058                 ast_free(order);
1059         }
1060
1061         AST_LIST_UNLOCK(&module_list);
1062         
1063         /* Tell manager clients that are aggressive at logging in that we're done
1064            loading modules. If there's a DNS problem in chan_sip, we might not
1065            even reach this */
1066         manager_event(EVENT_FLAG_SYSTEM, "ModuleLoadReport", "ModuleLoadStatus: Done\r\nModuleSelection: %s\r\nModuleCount: %d\r\n", preload_only ? "Preload" : "All", modulecount);
1067         
1068         return res;
1069 }
1070
1071 void ast_update_use_count(void)
1072 {
1073         /* Notify any module monitors that the use count for a
1074            resource has changed */
1075         struct loadupdate *m;
1076
1077         AST_LIST_LOCK(&updaters);
1078         AST_LIST_TRAVERSE(&updaters, m, entry)
1079                 m->updater();
1080         AST_LIST_UNLOCK(&updaters);
1081 }
1082
1083 int ast_update_module_list(int (*modentry)(const char *module, const char *description, int usecnt, const char *like),
1084                            const char *like)
1085 {
1086         struct ast_module *cur;
1087         int unlock = -1;
1088         int total_mod_loaded = 0;
1089
1090         if (AST_LIST_TRYLOCK(&module_list))
1091                 unlock = 0;
1092  
1093         AST_LIST_TRAVERSE(&module_list, cur, entry) {
1094                 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, like);
1095         }
1096
1097         if (unlock)
1098                 AST_LIST_UNLOCK(&module_list);
1099
1100         return total_mod_loaded;
1101 }
1102
1103 /*! \brief Check if module exists */
1104 int ast_module_check(const char *name)
1105 {
1106         struct ast_module *cur;
1107
1108         if (ast_strlen_zero(name))
1109                 return 0;       /* FALSE */
1110
1111         cur = find_resource(name, 1);
1112
1113         return (cur != NULL);
1114 }
1115
1116
1117 int ast_loader_register(int (*v)(void))
1118 {
1119         struct loadupdate *tmp;
1120
1121         if (!(tmp = ast_malloc(sizeof(*tmp))))
1122                 return -1;
1123
1124         tmp->updater = v;
1125         AST_LIST_LOCK(&updaters);
1126         AST_LIST_INSERT_HEAD(&updaters, tmp, entry);
1127         AST_LIST_UNLOCK(&updaters);
1128
1129         return 0;
1130 }
1131
1132 int ast_loader_unregister(int (*v)(void))
1133 {
1134         struct loadupdate *cur;
1135
1136         AST_LIST_LOCK(&updaters);
1137         AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) {
1138                 if (cur->updater == v)  {
1139                         AST_LIST_REMOVE_CURRENT(entry);
1140                         break;
1141                 }
1142         }
1143         AST_LIST_TRAVERSE_SAFE_END;
1144         AST_LIST_UNLOCK(&updaters);
1145
1146         return cur ? 0 : -1;
1147 }
1148
1149 struct ast_module *ast_module_ref(struct ast_module *mod)
1150 {
1151         ast_atomic_fetchadd_int(&mod->usecount, +1);
1152         ast_update_use_count();
1153
1154         return mod;
1155 }
1156
1157 void ast_module_unref(struct ast_module *mod)
1158 {
1159         ast_atomic_fetchadd_int(&mod->usecount, -1);
1160         ast_update_use_count();
1161 }