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