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