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