Add the capability to require a module to be loaded, or else Asterisk exits.
[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         int somethingchanged = 1, final = 0;
447
448         AST_LIST_LOCK(&module_list);
449
450         /*!\note Some resources, like timers, are started up dynamically, and thus
451          * may be still in use, even if all channels are dead.  We must therefore
452          * check the usecount before asking modules to unload. */
453         do {
454                 if (!somethingchanged) {
455                         /*!\note If we go through the entire list without changing
456                          * anything, ignore the usecounts and unload, then exit. */
457                         final = 1;
458                 }
459
460                 /* Reset flag before traversing the list */
461                 somethingchanged = 0;
462
463                 AST_LIST_TRAVERSE_SAFE_BEGIN(&module_list, mod, entry) {
464                         if (!final && mod->usecount) {
465                                 continue;
466                         }
467                         AST_LIST_REMOVE_CURRENT(entry);
468                         if (mod->info->unload) {
469                                 mod->info->unload();
470                         }
471                         AST_LIST_HEAD_DESTROY(&mod->users);
472                         free(mod);
473                         somethingchanged = 1;
474                 }
475                 AST_LIST_TRAVERSE_SAFE_END;
476         } while (somethingchanged && !final);
477
478         AST_LIST_UNLOCK(&module_list);
479 }
480
481 int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force)
482 {
483         struct ast_module *mod;
484         int res = -1;
485         int error = 0;
486
487         AST_LIST_LOCK(&module_list);
488
489         if (!(mod = find_resource(resource_name, 0))) {
490                 AST_LIST_UNLOCK(&module_list);
491                 ast_log(LOG_WARNING, "Unload failed, '%s' could not be found\n", resource_name);
492                 return 0;
493         }
494
495         if (!(mod->flags.running || mod->flags.declined))
496                 error = 1;
497
498         if (!error && (mod->usecount > 0)) {
499                 if (force)
500                         ast_log(LOG_WARNING, "Warning:  Forcing removal of module '%s' with use count %d\n",
501                                 resource_name, mod->usecount);
502                 else {
503                         ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name,
504                                 mod->usecount);
505                         error = 1;
506                 }
507         }
508
509         if (!error) {
510                 __ast_module_user_hangup_all(mod);
511                 res = mod->info->unload();
512
513                 if (res) {
514                         ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
515                         if (force <= AST_FORCE_FIRM)
516                                 error = 1;
517                         else
518                                 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
519                 }
520         }
521
522         if (!error)
523                 mod->flags.running = mod->flags.declined = 0;
524
525         AST_LIST_UNLOCK(&module_list);
526
527         if (!error && !mod->lib && mod->info && mod->info->restore_globals)
528                 mod->info->restore_globals();
529
530 #ifdef LOADABLE_MODULES
531         if (!error)
532                 unload_dynamic_module(mod);
533 #endif
534
535         if (!error)
536                 ast_update_use_count();
537
538         return res;
539 }
540
541 char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload)
542 {
543         struct ast_module *cur;
544         int i, which=0, l = strlen(word);
545         char *ret = NULL;
546
547         if (pos != rpos)
548                 return NULL;
549
550         AST_LIST_LOCK(&module_list);
551         AST_LIST_TRAVERSE(&module_list, cur, entry) {
552                 if (!strncasecmp(word, cur->resource, l) &&
553                     (cur->info->reload || !needsreload) &&
554                     ++which > state) {
555                         ret = ast_strdup(cur->resource);
556                         break;
557                 }
558         }
559         AST_LIST_UNLOCK(&module_list);
560
561         if (!ret) {
562                 for (i=0; !ret && reload_classes[i].name; i++) {
563                         if (!strncasecmp(word, reload_classes[i].name, l) && ++which > state)
564                                 ret = ast_strdup(reload_classes[i].name);
565                 }
566         }
567
568         return ret;
569 }
570
571 void ast_process_pending_reloads(void)
572 {
573         struct reload_queue_item *item;
574
575         if (!ast_fully_booted) {
576                 return;
577         }
578
579         AST_LIST_LOCK(&reload_queue);
580
581         if (do_full_reload) {
582                 do_full_reload = 0;
583                 AST_LIST_UNLOCK(&reload_queue);
584                 ast_log(LOG_NOTICE, "Executing deferred reload request.\n");
585                 ast_module_reload(NULL);
586                 return;
587         }
588
589         while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
590                 ast_log(LOG_NOTICE, "Executing deferred reload request for module '%s'.\n", item->module);
591                 ast_module_reload(item->module);
592                 ast_free(item);
593         }
594
595         AST_LIST_UNLOCK(&reload_queue);
596 }
597
598 static void queue_reload_request(const char *module)
599 {
600         struct reload_queue_item *item;
601
602         AST_LIST_LOCK(&reload_queue);
603
604         if (do_full_reload) {
605                 AST_LIST_UNLOCK(&reload_queue);
606                 return;
607         }
608
609         if (ast_strlen_zero(module)) {
610                 /* A full reload request (when module is NULL) wipes out any previous
611                    reload requests and causes the queue to ignore future ones */
612                 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
613                         ast_free(item);
614                 }
615                 do_full_reload = 1;
616         } else {
617                 /* No reason to add the same module twice */
618                 AST_LIST_TRAVERSE(&reload_queue, item, entry) {
619                         if (!strcasecmp(item->module, module)) {
620                                 AST_LIST_UNLOCK(&reload_queue);
621                                 return;
622                         }
623                 }
624                 item = ast_calloc(1, sizeof(*item) + strlen(module) + 1);
625                 if (!item) {
626                         ast_log(LOG_ERROR, "Failed to allocate reload queue item.\n");
627                         AST_LIST_UNLOCK(&reload_queue);
628                         return;
629                 }
630                 strcpy(item->module, module);
631                 AST_LIST_INSERT_TAIL(&reload_queue, item, entry);
632         }
633         AST_LIST_UNLOCK(&reload_queue);
634 }
635
636 int ast_module_reload(const char *name)
637 {
638         struct ast_module *cur;
639         int res = 0; /* return value. 0 = not found, others, see below */
640         int i;
641
642         /* If we aren't fully booted, we just pretend we reloaded but we queue this
643            up to run once we are booted up. */
644         if (!ast_fully_booted) {
645                 queue_reload_request(name);
646                 return 0;
647         }
648
649         if (ast_mutex_trylock(&reloadlock)) {
650                 ast_verbose("The previous reload command didn't finish yet\n");
651                 return -1;      /* reload already in progress */
652         }
653         ast_lastreloadtime = ast_tvnow();
654
655         /* Call "predefined" reload here first */
656         for (i = 0; reload_classes[i].name; i++) {
657                 if (!name || !strcasecmp(name, reload_classes[i].name)) {
658                         reload_classes[i].reload_fn();  /* XXX should check error ? */
659                         res = 2;        /* found and reloaded */
660                 }
661         }
662
663         if (name && res) {
664                 ast_mutex_unlock(&reloadlock);
665                 return res;
666         }
667
668         AST_LIST_LOCK(&module_list);
669         AST_LIST_TRAVERSE(&module_list, cur, entry) {
670                 const struct ast_module_info *info = cur->info;
671
672                 if (name && resource_name_match(name, cur->resource))
673                         continue;
674
675                 if (!cur->flags.running || cur->flags.declined) {
676                         if (!name)
677                                 continue;
678                         ast_log(LOG_NOTICE, "The module '%s' was not properly initialized.  "
679                                 "Before reloading the module, you must run \"module load %s\" "
680                                 "and fix whatever is preventing the module from being initialized.\n",
681                                 name, name);
682                         res = 2; /* Don't report that the module was not found */
683                         break;
684                 }
685
686                 if (!info->reload) {    /* cannot be reloaded */
687                         if (res < 1)    /* store result if possible */
688                                 res = 1;        /* 1 = no reload() method */
689                         continue;
690                 }
691
692                 res = 2;
693                 ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description);
694                 info->reload();
695         }
696         AST_LIST_UNLOCK(&module_list);
697
698         ast_mutex_unlock(&reloadlock);
699
700         return res;
701 }
702
703 static unsigned int inspect_module(const struct ast_module *mod)
704 {
705         if (!mod->info->description) {
706                 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource);
707                 return 1;
708         }
709
710         if (!mod->info->key) {
711                 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource);
712                 return 1;
713         }
714
715         if (verify_key((unsigned char *) mod->info->key)) {
716                 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource);
717                 return 1;
718         }
719
720         if (!ast_strlen_zero(mod->info->buildopt_sum) &&
721             strcmp(buildopt_sum, mod->info->buildopt_sum)) {
722                 ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource);
723                 ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource);
724                 return 1;
725         }
726
727         return 0;
728 }
729
730 static enum ast_module_load_result start_resource(struct ast_module *mod)
731 {
732         char tmp[256];
733         enum ast_module_load_result res;
734
735         if (!mod->info->load) {
736                 return AST_MODULE_LOAD_FAILURE;
737         }
738
739         res = mod->info->load();
740
741         switch (res) {
742         case AST_MODULE_LOAD_SUCCESS:
743                 if (!ast_fully_booted) {
744                         ast_verb(1, "%s => (%s)\n", mod->resource, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
745                         if (ast_opt_console && !option_verbose)
746                                 ast_verbose( ".");
747                 } else {
748                         ast_verb(1, "Loaded %s => (%s)\n", mod->resource, mod->info->description);
749                 }
750
751                 mod->flags.running = 1;
752
753                 ast_update_use_count();
754                 break;
755         case AST_MODULE_LOAD_DECLINE:
756                 mod->flags.declined = 1;
757                 break;
758         case AST_MODULE_LOAD_FAILURE:
759         case AST_MODULE_LOAD_SKIP: /* modules should never return this value */
760         case AST_MODULE_LOAD_PRIORITY:
761                 break;
762         }
763
764         return res;
765 }
766
767 /*! loads a resource based upon resource_name. If global_symbols_only is set
768  *  only modules with global symbols will be loaded.
769  *
770  *  If the ast_heap is provided (not NULL) the module is found and added to the
771  *  heap without running the module's load() function.  By doing this, modules
772  *  added to the resource_heap can be initialized later in order by priority. 
773  *
774  *  If the ast_heap is not provided, the module's load function will be executed
775  *  immediately */
776 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap, int required)
777 {
778         struct ast_module *mod;
779         enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
780
781         if ((mod = find_resource(resource_name, 0))) {
782                 if (mod->flags.running) {
783                         ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name);
784                         return AST_MODULE_LOAD_DECLINE;
785                 }
786                 if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS))
787                         return AST_MODULE_LOAD_SKIP;
788         } else {
789 #ifdef LOADABLE_MODULES
790                 if (!(mod = load_dynamic_module(resource_name, global_symbols_only))) {
791                         /* don't generate a warning message during load_modules() */
792                         if (!global_symbols_only) {
793                                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
794                                 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
795                         } else {
796                                 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SKIP;
797                         }
798                 }
799 #else
800                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
801                 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
802 #endif
803         }
804
805         if (inspect_module(mod)) {
806                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
807 #ifdef LOADABLE_MODULES
808                 unload_dynamic_module(mod);
809 #endif
810                 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
811         }
812
813         if (!mod->lib && mod->info->backup_globals()) {
814                 ast_log(LOG_WARNING, "Module '%s' was unable to backup its global data.\n", resource_name);
815                 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
816         }
817
818         mod->flags.declined = 0;
819
820         if (resource_heap) {
821                 ast_heap_push(resource_heap, mod);
822                 res = AST_MODULE_LOAD_PRIORITY;
823         } else {
824                 res = start_resource(mod);
825         }
826
827         return res;
828 }
829
830 int ast_load_resource(const char *resource_name)
831 {
832         int res;
833         AST_LIST_LOCK(&module_list);
834         res = load_resource(resource_name, 0, NULL, 0);
835         AST_LIST_UNLOCK(&module_list);
836
837         return res;
838 }
839
840 struct load_order_entry {
841         char *resource;
842         int required;
843         AST_LIST_ENTRY(load_order_entry) entry;
844 };
845
846 AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
847
848 static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order, int required)
849 {
850         struct load_order_entry *order;
851
852         AST_LIST_TRAVERSE(load_order, order, entry) {
853                 if (!resource_name_match(order->resource, resource)) {
854                         /* Make sure we have the proper setting for the required field 
855                            (we might have both load= and required= lines in modules.conf) */
856                                 order->required |= required;
857                         }
858                         return NULL;
859                 }
860         }
861
862         if (!(order = ast_calloc(1, sizeof(*order))))
863                 return NULL;
864
865         order->resource = ast_strdup(resource);
866         order->required = required;
867         AST_LIST_INSERT_TAIL(load_order, order, entry);
868
869         return order;
870 }
871
872 static int mod_load_cmp(void *a, void *b)
873 {
874         struct ast_module *a_mod = (struct ast_module *) a;
875         struct ast_module *b_mod = (struct ast_module *) b;
876         int res = -1;
877         /* if load_pri is not set, default is 255.  Lower is better*/
878         unsigned char a_pri = ast_test_flag(a_mod->info, AST_MODFLAG_LOAD_ORDER) ? a_mod->info->load_pri : 255;
879         unsigned char b_pri = ast_test_flag(b_mod->info, AST_MODFLAG_LOAD_ORDER) ? b_mod->info->load_pri : 255;
880         if (a_pri == b_pri) {
881                 res = 0;
882         } else if (a_pri < b_pri) {
883                 res = 1;
884         }
885         return res;
886 }
887
888 /*! loads modules in order by load_pri, updates mod_count 
889         \return -1 on failure to load module, -2 on failure to load required module, otherwise 0
890 */
891 static int load_resource_list(struct load_order *load_order, unsigned int global_symbols, int *mod_count)
892 {
893         struct ast_heap *resource_heap;
894         struct load_order_entry *order;
895         struct ast_module *mod;
896         int count = 0;
897         int res = 0;
898
899         if(!(resource_heap = ast_heap_create(8, mod_load_cmp, -1))) {
900                 return -1;
901         }
902
903         /* first, add find and add modules to heap */
904         AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
905                 switch (load_resource(order->resource, global_symbols, resource_heap, order->required)) {
906                 case AST_MODULE_LOAD_SUCCESS:
907                 case AST_MODULE_LOAD_DECLINE:
908                         AST_LIST_REMOVE_CURRENT(entry);
909                         ast_free(order->resource);
910                         ast_free(order);
911                         break;
912                 case AST_MODULE_LOAD_FAILURE:
913                         ast_log(LOG_ERROR, "*** Failed to load module %s - %s\n", order->resource, order->required ? "Required" : "Not required");
914                         fprintf(stderr, "*** Failed to load module %s - %s\n", order->resource, order->required ? "Required" : "Not required");
915                         res = order->required ? -2 : -1;
916                         goto done;
917                 case AST_MODULE_LOAD_SKIP:
918                         break;
919                 case AST_MODULE_LOAD_PRIORITY:
920                         AST_LIST_REMOVE_CURRENT(entry);
921                         break;
922                 }
923         }
924         AST_LIST_TRAVERSE_SAFE_END;
925
926         /* second remove modules from heap sorted by priority */
927         while ((mod = ast_heap_pop(resource_heap))) {
928                 switch (start_resource(mod)) {
929                 case AST_MODULE_LOAD_SUCCESS:
930                         count++;
931                 case AST_MODULE_LOAD_DECLINE:
932                         break;
933                 case AST_MODULE_LOAD_FAILURE:
934                         res = -1;
935                         goto done;
936                 case AST_MODULE_LOAD_SKIP:
937                 case AST_MODULE_LOAD_PRIORITY:
938                         break;
939                 }
940         }
941
942 done:
943         if (mod_count) {
944                 *mod_count += count;
945         }
946         ast_heap_destroy(resource_heap);
947
948         return res;
949 }
950
951 int load_modules(unsigned int preload_only)
952 {
953         struct ast_config *cfg;
954         struct ast_module *mod;
955         struct load_order_entry *order;
956         struct ast_variable *v;
957         unsigned int load_count;
958         struct load_order load_order;
959         int res = 0;
960         struct ast_flags config_flags = { 0 };
961         int modulecount = 0;
962
963 #ifdef LOADABLE_MODULES
964         struct dirent *dirent;
965         DIR *dir;
966 #endif
967
968         /* all embedded modules have registered themselves by now */
969         embedding = 0;
970
971         ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
972
973         AST_LIST_HEAD_INIT_NOLOCK(&load_order);
974
975         AST_LIST_LOCK(&module_list);
976
977         if (embedded_module_list.first) {
978                 module_list.first = embedded_module_list.first;
979                 module_list.last = embedded_module_list.last;
980                 embedded_module_list.first = NULL;
981         }
982
983         cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags);
984         if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
985                 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
986                 goto done;
987         }
988
989         /* first, find all the modules we have been explicitly requested to load */
990         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
991                 if (!strcasecmp(v->name, preload_only ? "preload" : "load")) {
992                         add_to_load_order(v->value, &load_order, 0);
993                 }
994                 if (!strcasecmp(v->name, preload_only ? "preload-require" : "require")) {
995                         /* Add the module to the list and make sure it's required */
996                         add_to_load_order(v->value, &load_order, 1);
997                         ast_debug(2, "Adding module to required list: %s (%s)\n", v->value, v->name);
998                 }
999
1000         }
1001
1002         /* check if 'autoload' is on */
1003         if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
1004                 /* if so, first add all the embedded modules that are not already running to the load order */
1005                 AST_LIST_TRAVERSE(&module_list, mod, entry) {
1006                         /* if it's not embedded, skip it */
1007                         if (mod->lib)
1008                                 continue;
1009
1010                         if (mod->flags.running)
1011                                 continue;
1012
1013                         order = add_to_load_order(mod->resource, &load_order, 0);
1014                 }
1015
1016 #ifdef LOADABLE_MODULES
1017                 /* if we are allowed to load dynamic modules, scan the directory for
1018                    for all available modules and add them as well */
1019                 if ((dir  = opendir(ast_config_AST_MODULE_DIR))) {
1020                         while ((dirent = readdir(dir))) {
1021                                 int ld = strlen(dirent->d_name);
1022
1023                                 /* Must end in .so to load it.  */
1024
1025                                 if (ld < 4)
1026                                         continue;
1027
1028                                 if (strcasecmp(dirent->d_name + ld - 3, ".so"))
1029                                         continue;
1030
1031                                 /* if there is already a module by this name in the module_list,
1032                                    skip this file */
1033                                 if (find_resource(dirent->d_name, 0))
1034                                         continue;
1035
1036                                 add_to_load_order(dirent->d_name, &load_order, 0);
1037                         }
1038
1039                         closedir(dir);
1040                 } else {
1041                         if (!ast_opt_quiet)
1042                                 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",
1043                                         ast_config_AST_MODULE_DIR);
1044                 }
1045 #endif
1046         }
1047
1048         /* now scan the config for any modules we are prohibited from loading and
1049            remove them from the load order */
1050         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1051                 if (strcasecmp(v->name, "noload"))
1052                         continue;
1053
1054                 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
1055                         if (!resource_name_match(order->resource, v->value)) {
1056                                 AST_LIST_REMOVE_CURRENT(entry);
1057                                 ast_free(order->resource);
1058                                 ast_free(order);
1059                         }
1060                 }
1061                 AST_LIST_TRAVERSE_SAFE_END;
1062         }
1063
1064         /* we are done with the config now, all the information we need is in the
1065            load_order list */
1066         ast_config_destroy(cfg);
1067
1068         load_count = 0;
1069         AST_LIST_TRAVERSE(&load_order, order, entry)
1070                 load_count++;
1071
1072         if (load_count)
1073                 ast_log(LOG_NOTICE, "%d modules will be loaded.\n", load_count);
1074
1075         /* first, load only modules that provide global symbols */
1076         if ((res = load_resource_list(&load_order, 1, &modulecount)) < 0) {
1077                 goto done;
1078         }
1079
1080         /* now load everything else */
1081         if ((res = load_resource_list(&load_order, 0, &modulecount)) < 0) {
1082                 goto done;
1083         }
1084
1085 done:
1086         while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
1087                 ast_free(order->resource);
1088                 ast_free(order);
1089         }
1090
1091         AST_LIST_UNLOCK(&module_list);
1092         
1093         /* Tell manager clients that are aggressive at logging in that we're done
1094            loading modules. If there's a DNS problem in chan_sip, we might not
1095            even reach this */
1096         manager_event(EVENT_FLAG_SYSTEM, "ModuleLoadReport", "ModuleLoadStatus: Done\r\nModuleSelection: %s\r\nModuleCount: %d\r\n", preload_only ? "Preload" : "All", modulecount);
1097         
1098         return res;
1099 }
1100
1101 void ast_update_use_count(void)
1102 {
1103         /* Notify any module monitors that the use count for a
1104            resource has changed */
1105         struct loadupdate *m;
1106
1107         AST_LIST_LOCK(&updaters);
1108         AST_LIST_TRAVERSE(&updaters, m, entry)
1109                 m->updater();
1110         AST_LIST_UNLOCK(&updaters);
1111 }
1112
1113 int ast_update_module_list(int (*modentry)(const char *module, const char *description, int usecnt, const char *like),
1114                            const char *like)
1115 {
1116         struct ast_module *cur;
1117         int unlock = -1;
1118         int total_mod_loaded = 0;
1119
1120         if (AST_LIST_TRYLOCK(&module_list))
1121                 unlock = 0;
1122  
1123         AST_LIST_TRAVERSE(&module_list, cur, entry) {
1124                 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, like);
1125         }
1126
1127         if (unlock)
1128                 AST_LIST_UNLOCK(&module_list);
1129
1130         return total_mod_loaded;
1131 }
1132
1133 /*! \brief Check if module exists */
1134 int ast_module_check(const char *name)
1135 {
1136         struct ast_module *cur;
1137
1138         if (ast_strlen_zero(name))
1139                 return 0;       /* FALSE */
1140
1141         cur = find_resource(name, 1);
1142
1143         return (cur != NULL);
1144 }
1145
1146
1147 int ast_loader_register(int (*v)(void))
1148 {
1149         struct loadupdate *tmp;
1150
1151         if (!(tmp = ast_malloc(sizeof(*tmp))))
1152                 return -1;
1153
1154         tmp->updater = v;
1155         AST_LIST_LOCK(&updaters);
1156         AST_LIST_INSERT_HEAD(&updaters, tmp, entry);
1157         AST_LIST_UNLOCK(&updaters);
1158
1159         return 0;
1160 }
1161
1162 int ast_loader_unregister(int (*v)(void))
1163 {
1164         struct loadupdate *cur;
1165
1166         AST_LIST_LOCK(&updaters);
1167         AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) {
1168                 if (cur->updater == v)  {
1169                         AST_LIST_REMOVE_CURRENT(entry);
1170                         break;
1171                 }
1172         }
1173         AST_LIST_TRAVERSE_SAFE_END;
1174         AST_LIST_UNLOCK(&updaters);
1175
1176         return cur ? 0 : -1;
1177 }
1178
1179 struct ast_module *ast_module_ref(struct ast_module *mod)
1180 {
1181         ast_atomic_fetchadd_int(&mod->usecount, +1);
1182         ast_update_use_count();
1183
1184         return mod;
1185 }
1186
1187 void ast_module_unref(struct ast_module *mod)
1188 {
1189         ast_atomic_fetchadd_int(&mod->usecount, -1);
1190         ast_update_use_count();
1191 }