e51505ea073766663627aa442c6938e56ccf095a
[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 <stdio.h>
35 #include <dirent.h>
36 #include <unistd.h>
37 #include <stdlib.h>
38 #include <errno.h>
39 #include <string.h>
40
41 #include "asterisk/linkedlists.h"
42 #include "asterisk/module.h"
43 #include "asterisk/options.h"
44 #include "asterisk/config.h"
45 #include "asterisk/logger.h"
46 #include "asterisk/channel.h"
47 #include "asterisk/term.h"
48 #include "asterisk/manager.h"
49 #include "asterisk/cdr.h"
50 #include "asterisk/enum.h"
51 #include "asterisk/rtp.h"
52 #include "asterisk/http.h"
53 #include "asterisk/lock.h"
54
55 #ifdef DLFCNCOMPAT
56 #include "asterisk/dlfcn-compat.h"
57 #else
58 #include <dlfcn.h>
59 #endif
60
61 #include "asterisk/md5.h"
62 #include "asterisk/utils.h"
63
64 #ifndef RTLD_NOW
65 #define RTLD_NOW 0
66 #endif
67
68 struct ast_module_user {
69         struct ast_channel *chan;
70         AST_LIST_ENTRY(ast_module_user) entry;
71 };
72
73 AST_LIST_HEAD(module_user_list, ast_module_user);
74
75 static unsigned char expected_key[] =
76 { 0x87, 0x76, 0x79, 0x35, 0x23, 0xea, 0x3a, 0xd3,
77   0x25, 0x2a, 0xbb, 0x35, 0x87, 0xe4, 0x22, 0x24 };
78
79 static unsigned int embedding = 1; /* we always start out by registering embedded modules,
80                                       since they are here before we dlopen() any
81                                    */
82
83 struct ast_module {
84         const struct ast_module_info *info;
85         void *lib;                                      /* the shared lib, or NULL if embedded */
86         int usecount;                                   /* the number of 'users' currently in this module */
87         struct module_user_list users;                  /* the list of users in the module */
88         struct {
89                 unsigned int running:1;
90                 unsigned int declined:1;
91         } flags;
92         AST_LIST_ENTRY(ast_module) entry;
93         char resource[0];
94 };
95
96 static AST_LIST_HEAD_STATIC(module_list, ast_module);
97
98 /*
99  * module_list is cleared by its constructor possibly after
100  * we start accumulating embedded modules, so we need to
101  * use another list (without the lock) to accumulate them.
102  * Then we update the main list when embedding is done.
103  */
104 static struct module_list embedded_module_list;
105
106 struct loadupdate {
107         int (*updater)(void);
108         AST_LIST_ENTRY(loadupdate) entry;
109 };
110
111 static AST_LIST_HEAD_STATIC(updaters, loadupdate);
112
113 AST_MUTEX_DEFINE_STATIC(reloadlock);
114
115 /* when dynamic modules are being loaded, ast_module_register() will
116    need to know what filename the module was loaded from while it
117    is being registered
118 */
119 struct ast_module *resource_being_loaded;
120
121 /* XXX: should we check for duplicate resource names here? */
122
123 void ast_module_register(const struct ast_module_info *info)
124 {
125         struct ast_module *mod;
126
127         if (embedding) {
128                 if (!(mod = ast_calloc(1, sizeof(*mod) + strlen(info->name) + 1)))
129                         return;
130                 strcpy(mod->resource, info->name);
131         } else {
132                 mod = resource_being_loaded;
133         }
134
135         mod->info = info;
136         AST_LIST_HEAD_INIT(&mod->users);
137
138         /* during startup, before the loader has been initialized,
139            there are no threads, so there is no need to take the lock
140            on this list to manipulate it. it is also possible that it
141            might be unsafe to use the list lock at that point... so
142            let's avoid it altogether
143         */
144         if (embedding) {
145                 AST_LIST_INSERT_TAIL(&embedded_module_list, mod, entry);
146         } else {
147                 AST_LIST_LOCK(&module_list);
148                 /* it is paramount that the new entry be placed at the tail of
149                    the list, otherwise the code that uses dlopen() to load
150                    dynamic modules won't be able to find out if the module it
151                    just opened was registered or failed to load
152                 */
153                 AST_LIST_INSERT_TAIL(&module_list, mod, entry);
154                 AST_LIST_UNLOCK(&module_list);
155         }
156
157         /* give the module a copy of its own handle, for later use in registrations and the like */
158         *((struct ast_module **) &(info->self)) = mod;
159 }
160
161 void ast_module_unregister(const struct ast_module_info *info)
162 {
163         struct ast_module *mod = NULL;
164
165         /* it is assumed that the users list in the module structure
166            will already be empty, or we cannot have gotten to this
167            point
168         */
169         AST_LIST_LOCK(&module_list);
170         AST_LIST_TRAVERSE_SAFE_BEGIN(&module_list, mod, entry) {
171                 if (mod->info == info) {
172                         AST_LIST_REMOVE_CURRENT(entry);
173                         break;
174                 }
175         }
176         AST_LIST_TRAVERSE_SAFE_END;
177         AST_LIST_UNLOCK(&module_list);
178
179         if (mod) {
180                 AST_LIST_HEAD_DESTROY(&mod->users);
181                 ast_free(mod);
182         }
183 }
184
185 struct ast_module_user *__ast_module_user_add(struct ast_module *mod,
186                                               struct ast_channel *chan)
187 {
188         struct ast_module_user *u = ast_calloc(1, sizeof(*u));
189
190         if (!u)
191                 return NULL;
192
193         u->chan = chan;
194
195         AST_LIST_LOCK(&mod->users);
196         AST_LIST_INSERT_HEAD(&mod->users, u, entry);
197         AST_LIST_UNLOCK(&mod->users);
198
199         ast_atomic_fetchadd_int(&mod->usecount, +1);
200
201         ast_update_use_count();
202
203         return u;
204 }
205
206 void __ast_module_user_remove(struct ast_module *mod, struct ast_module_user *u)
207 {
208         AST_LIST_LOCK(&mod->users);
209         AST_LIST_REMOVE(&mod->users, u, entry);
210         AST_LIST_UNLOCK(&mod->users);
211         ast_atomic_fetchadd_int(&mod->usecount, -1);
212         ast_free(u);
213
214         ast_update_use_count();
215 }
216
217 void __ast_module_user_hangup_all(struct ast_module *mod)
218 {
219         struct ast_module_user *u;
220
221         AST_LIST_LOCK(&mod->users);
222         while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) {
223                 ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD);
224                 ast_atomic_fetchadd_int(&mod->usecount, -1);
225                 ast_free(u);
226         }
227         AST_LIST_UNLOCK(&mod->users);
228
229         ast_update_use_count();
230 }
231
232 /*! \note
233  * In addition to modules, the reload command handles some extra keywords
234  * which are listed here together with the corresponding handlers.
235  * This table is also used by the command completion code.
236  */
237 static struct reload_classes {
238         const char *name;
239         int (*reload_fn)(void);
240 } reload_classes[] = {  /* list in alpha order, longest match first for cli completion */
241         { "cdr",        ast_cdr_engine_reload },
242         { "dnsmgr",     dnsmgr_reload },
243         { "extconfig",  read_config_maps },
244         { "enum",       ast_enum_reload },
245         { "manager",    reload_manager },
246         { "rtp",        ast_rtp_reload },
247         { "http",       ast_http_reload },
248         { NULL,         NULL }
249 };
250
251 static int printdigest(const unsigned char *d)
252 {
253         int x, pos;
254         char buf[256]; /* large enough so we don't have to worry */
255
256         for (pos = 0, x = 0; x < 16; x++)
257                 pos += sprintf(buf + pos, " %02x", *d++);
258
259         ast_debug(1, "Unexpected signature:%s\n", buf);
260
261         return 0;
262 }
263
264 static int key_matches(const unsigned char *key1, const unsigned char *key2)
265 {
266         int x;
267
268         for (x = 0; x < 16; x++) {
269                 if (key1[x] != key2[x])
270                         return 0;
271         }
272
273         return 1;
274 }
275
276 static int verify_key(const unsigned char *key)
277 {
278         struct MD5Context c;
279         unsigned char digest[16];
280
281         MD5Init(&c);
282         MD5Update(&c, key, strlen((char *)key));
283         MD5Final(digest, &c);
284
285         if (key_matches(expected_key, digest))
286                 return 0;
287
288         printdigest(digest);
289
290         return -1;
291 }
292
293 static int resource_name_match(const char *name1_in, const char *name2_in)
294 {
295         char *name1 = (char *) name1_in;
296         char *name2 = (char *) name2_in;
297
298         /* trim off any .so extensions */
299         if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) {
300                 name1 = ast_strdupa(name1);
301                 name1[strlen(name1) - 3] = '\0';
302         }
303         if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) {
304                 name2 = ast_strdupa(name2);
305                 name2[strlen(name2) - 3] = '\0';
306         }
307
308         return strcasecmp(name1, name2);
309 }
310
311 static struct ast_module *find_resource(const char *resource, int do_lock)
312 {
313         struct ast_module *cur;
314
315         if (do_lock)
316                 AST_LIST_LOCK(&module_list);
317
318         AST_LIST_TRAVERSE(&module_list, cur, entry) {
319                 if (!resource_name_match(resource, cur->resource))
320                         break;
321         }
322
323         if (do_lock)
324                 AST_LIST_UNLOCK(&module_list);
325
326         return cur;
327 }
328
329 #ifdef LOADABLE_MODULES
330 static void unload_dynamic_module(struct ast_module *mod)
331 {
332         void *lib = mod->lib;
333
334         /* WARNING: the structure pointed to by mod is going to
335            disappear when this operation succeeds, so we can't
336            dereference it */
337
338         if (lib)
339                 while (!dlclose(lib));
340 }
341
342 static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int global_symbols_only)
343 {
344         char fn[256] = "";
345         void *lib = NULL;
346         struct ast_module *mod;
347         char *resource = (char *) resource_in;
348         unsigned int wants_global;
349
350         if (strcasecmp(resource + strlen(resource) - 3, ".so")) {
351                 resource = alloca(strlen(resource_in) + 3);
352                 strcpy(resource, resource_in);
353                 strcat(resource, ".so");
354         }
355
356         snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_MODULE_DIR, resource);
357
358         /* make a first load of the module in 'quiet' mode... don't try to resolve
359            any symbols, and don't export any symbols. this will allow us to peek into
360            the module's info block (if available) to see what flags it has set */
361
362         if (!(resource_being_loaded = ast_calloc(1, sizeof(*resource_being_loaded) + strlen(resource) + 1)))
363                 return NULL;
364
365         strcpy(resource_being_loaded->resource, resource);
366
367         if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_LOCAL))) {
368                 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
369                 ast_free(resource_being_loaded);
370                 return NULL;
371         }
372
373         /* the dlopen() succeeded, let's find out if the module
374            registered itself */
375         /* note that this will only work properly as long as
376            ast_module_register() (which is called by the module's
377            constructor) places the new module at the tail of the
378            module_list
379         */
380         if (resource_being_loaded != (mod = AST_LIST_LAST(&module_list))) {
381                 ast_log(LOG_WARNING, "Module '%s' did not register itself during load\n", resource_in);
382                 /* no, it did not, so close it and return */
383                 while (!dlclose(lib));
384                 /* note that the module's destructor will call ast_module_unregister(),
385                    which will free the structure we allocated in resource_being_loaded */
386                 return NULL;
387         }
388
389         wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS);
390
391         /* if we are being asked only to load modules that provide global symbols,
392            and this one does not, then close it and return */
393         if (global_symbols_only && !wants_global) {
394                 while (!dlclose(lib));
395                 return NULL;
396         }
397
398         /* if the system supports RTLD_NOLOAD, we can just 'promote' the flags
399            on the already-opened library to what we want... if not, we have to
400            close it and start over
401         */
402 #if defined(HAVE_RTLD_NOLOAD) && !defined(__Darwin__)
403         if (!dlopen(fn, RTLD_NOLOAD | (wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) {
404                 ast_log(LOG_WARNING, "Unable to promote flags on module '%s': %s\n", resource_in, dlerror());
405                 while (!dlclose(lib));
406                 ast_free(resource_being_loaded);
407                 return NULL;
408         }
409 #else
410         while (!dlclose(lib));
411         resource_being_loaded = NULL;
412
413         /* start the load process again */
414
415         if (!(resource_being_loaded = ast_calloc(1, sizeof(*resource_being_loaded) + strlen(resource) + 1)))
416                 return NULL;
417
418         strcpy(resource_being_loaded->resource, resource);
419
420         if (!(lib = dlopen(fn, wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) {
421                 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
422                 ast_free(resource_being_loaded);
423                 return NULL;
424         }
425
426         /* since the module was successfully opened, and it registered itself
427            the previous time we did that, we're going to assume it worked this
428            time too :) */
429 #endif
430
431         AST_LIST_LAST(&module_list)->lib = lib;
432         resource_being_loaded = NULL;
433
434         return AST_LIST_LAST(&module_list);
435 }
436 #endif
437
438 void ast_module_shutdown(void)
439 {
440         struct ast_module *mod;
441         AST_LIST_HEAD_NOLOCK_STATIC(local_module_list, ast_module);
442
443         /* We have to call the unload() callbacks in reverse order that the modules
444          * exist in the module list so it is the reverse order of how they were
445          * loaded. */
446
447         AST_LIST_LOCK(&module_list);
448         while ((mod = AST_LIST_REMOVE_HEAD(&module_list, entry)))
449                 AST_LIST_INSERT_HEAD(&local_module_list, mod, entry);
450         AST_LIST_UNLOCK(&module_list);
451
452         while ((mod = AST_LIST_REMOVE_HEAD(&local_module_list, entry))) {
453                 if (mod->info->unload)
454                         mod->info->unload();
455                 /* Since this should only be called when shutting down "gracefully",
456                  * all channels should be down before we get to this point, meaning
457                  * there will be no module users left. */
458                 AST_LIST_HEAD_DESTROY(&mod->users);
459                 free(mod);
460         }
461 }
462
463 int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force)
464 {
465         struct ast_module *mod;
466         int res = -1;
467         int error = 0;
468
469         AST_LIST_LOCK(&module_list);
470
471         if (!(mod = find_resource(resource_name, 0))) {
472                 AST_LIST_UNLOCK(&module_list);
473                 return 0;
474         }
475
476         if (!(mod->flags.running || mod->flags.declined))
477                 error = 1;
478
479         if (!error && (mod->usecount > 0)) {
480                 if (force)
481                         ast_log(LOG_WARNING, "Warning:  Forcing removal of module '%s' with use count %d\n",
482                                 resource_name, mod->usecount);
483                 else {
484                         ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name,
485                                 mod->usecount);
486                         error = 1;
487                 }
488         }
489
490         if (!error) {
491                 __ast_module_user_hangup_all(mod);
492                 res = mod->info->unload();
493
494                 if (res) {
495                         ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
496                         if (force <= AST_FORCE_FIRM)
497                                 error = 1;
498                         else
499                                 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
500                 }
501         }
502
503         if (!error)
504                 mod->flags.running = mod->flags.declined = 0;
505
506         AST_LIST_UNLOCK(&module_list);
507
508         if (!error && !mod->lib)
509                 mod->info->restore_globals();
510
511 #ifdef LOADABLE_MODULES
512         if (!error)
513                 unload_dynamic_module(mod);
514 #endif
515
516         if (!error)
517                 ast_update_use_count();
518
519         return res;
520 }
521
522 char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload)
523 {
524         struct ast_module *cur;
525         int i, which=0, l = strlen(word);
526         char *ret = NULL;
527
528         if (pos != rpos)
529                 return NULL;
530
531         AST_LIST_LOCK(&module_list);
532         AST_LIST_TRAVERSE(&module_list, cur, entry) {
533                 if (!strncasecmp(word, cur->resource, l) &&
534                     (cur->info->reload || !needsreload) &&
535                     ++which > state) {
536                         ret = ast_strdup(cur->resource);
537                         break;
538                 }
539         }
540         AST_LIST_UNLOCK(&module_list);
541
542         if (!ret) {
543                 for (i=0; !ret && reload_classes[i].name; i++) {
544                         if (!strncasecmp(word, reload_classes[i].name, l) && ++which > state)
545                                 ret = ast_strdup(reload_classes[i].name);
546                 }
547         }
548
549         return ret;
550 }
551
552 int ast_module_reload(const char *name)
553 {
554         struct ast_module *cur;
555         int res = 0; /* return value. 0 = not found, others, see below */
556         int i;
557
558         if (ast_mutex_trylock(&reloadlock)) {
559                 ast_verbose("The previous reload command didn't finish yet\n");
560                 return -1;      /* reload already in progress */
561         }
562         ast_lastreloadtime = ast_tvnow();
563
564         /* Call "predefined" reload here first */
565         for (i = 0; reload_classes[i].name; i++) {
566                 if (!name || !strcasecmp(name, reload_classes[i].name)) {
567                         reload_classes[i].reload_fn();  /* XXX should check error ? */
568                         res = 2;        /* found and reloaded */
569                 }
570         }
571
572         if (name && res) {
573                 ast_mutex_unlock(&reloadlock);
574                 return res;
575         }
576
577         AST_LIST_LOCK(&module_list);
578         AST_LIST_TRAVERSE(&module_list, cur, entry) {
579                 const struct ast_module_info *info = cur->info;
580
581                 if (name && resource_name_match(name, cur->resource))
582                         continue;
583
584                 if (!(cur->flags.running || cur->flags.declined))
585                         continue;
586
587                 if (!info->reload) {    /* cannot be reloaded */
588                         if (res < 1)    /* store result if possible */
589                                 res = 1;        /* 1 = no reload() method */
590                         continue;
591                 }
592
593                 res = 2;
594                 ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description);
595                 info->reload();
596         }
597         AST_LIST_UNLOCK(&module_list);
598
599         ast_mutex_unlock(&reloadlock);
600
601         return res;
602 }
603
604 static unsigned int inspect_module(const struct ast_module *mod)
605 {
606         if (!mod->info->description) {
607                 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource);
608                 return 1;
609         }
610
611         if (!mod->info->key) {
612                 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource);
613                 return 1;
614         }
615
616         if (verify_key((unsigned char *) mod->info->key)) {
617                 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource);
618                 return 1;
619         }
620
621         return 0;
622 }
623
624 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only)
625 {
626         struct ast_module *mod;
627         enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
628         char tmp[256];
629
630         if ((mod = find_resource(resource_name, 0))) {
631                 if (mod->flags.running) {
632                         ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name);
633                         return AST_MODULE_LOAD_DECLINE;
634                 }
635                 if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS))
636                         return AST_MODULE_LOAD_SKIP;
637         } else {
638 #ifdef LOADABLE_MODULES
639                 if (!(mod = load_dynamic_module(resource_name, global_symbols_only))) {
640                         /* don't generate a warning message during load_modules() */
641                         if (!global_symbols_only) {
642                                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
643                                 return AST_MODULE_LOAD_DECLINE;
644                         } else {
645                                 return AST_MODULE_LOAD_SKIP;
646                         }
647                 }
648 #else
649                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
650                 return AST_MODULE_LOAD_DECLINE;
651 #endif
652         }
653
654         if (inspect_module(mod)) {
655                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
656 #ifdef LOADABLE_MODULES
657                 unload_dynamic_module(mod);
658 #endif
659                 return AST_MODULE_LOAD_DECLINE;
660         }
661
662         if (!mod->lib && mod->info->backup_globals()) {
663                 ast_log(LOG_WARNING, "Module '%s' was unable to backup its global data.\n", resource_name);
664                 return AST_MODULE_LOAD_DECLINE;
665         }
666
667         mod->flags.declined = 0;
668
669         if (mod->info->load)
670                 res = mod->info->load();
671
672         switch (res) {
673         case AST_MODULE_LOAD_SUCCESS:
674                 if (!ast_fully_booted) {
675                         ast_verb(1, "%s => (%s)\n", resource_name, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
676                         if (ast_opt_console && !option_verbose)
677                                 ast_verbose( ".");
678                 } else {
679                         ast_verb(1, "Loaded %s => (%s)\n", resource_name, mod->info->description);
680                 }
681
682                 mod->flags.running = 1;
683
684                 ast_update_use_count();
685                 break;
686         case AST_MODULE_LOAD_DECLINE:
687                 mod->flags.declined = 1;
688                 break;
689         case AST_MODULE_LOAD_FAILURE:
690                 break;
691         case AST_MODULE_LOAD_SKIP:
692                 /* modules should never return this value */
693                 break;
694         }
695
696         return res;
697 }
698
699 int ast_load_resource(const char *resource_name)
700 {
701        AST_LIST_LOCK(&module_list);
702        load_resource(resource_name, 0);
703        AST_LIST_UNLOCK(&module_list);
704
705        return 0;
706 }
707
708 struct load_order_entry {
709         char *resource;
710         AST_LIST_ENTRY(load_order_entry) entry;
711 };
712
713 AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
714
715 static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order)
716 {
717         struct load_order_entry *order;
718
719         AST_LIST_TRAVERSE(load_order, order, entry) {
720                 if (!resource_name_match(order->resource, resource))
721                         return NULL;
722         }
723
724         if (!(order = ast_calloc(1, sizeof(*order))))
725                 return NULL;
726
727         order->resource = ast_strdup(resource);
728         AST_LIST_INSERT_TAIL(load_order, order, entry);
729
730         return order;
731 }
732
733 int load_modules(unsigned int preload_only)
734 {
735         struct ast_config *cfg;
736         struct ast_module *mod;
737         struct load_order_entry *order;
738         struct ast_variable *v;
739         unsigned int load_count;
740         struct load_order load_order;
741         int res = 0;
742         struct ast_flags config_flags = { 0 };
743 #ifdef LOADABLE_MODULES
744         struct dirent *dirent;
745         DIR *dir;
746 #endif
747
748         /* all embedded modules have registered themselves by now */
749         embedding = 0;
750
751         ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
752
753         AST_LIST_HEAD_INIT_NOLOCK(&load_order);
754
755         AST_LIST_LOCK(&module_list);
756
757         if (embedded_module_list.first) {
758                 module_list.first = embedded_module_list.first;
759                 module_list.last = embedded_module_list.last;
760                 embedded_module_list.first = NULL;
761         }
762
763         if (!(cfg = ast_config_load(AST_MODULE_CONFIG, config_flags))) {
764                 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
765                 goto done;
766         }
767
768         /* first, find all the modules we have been explicitly requested to load */
769         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
770                 if (!strcasecmp(v->name, preload_only ? "preload" : "load"))
771                         add_to_load_order(v->value, &load_order);
772         }
773
774         /* check if 'autoload' is on */
775         if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
776                 /* if so, first add all the embedded modules that are not already running to the load order */
777                 AST_LIST_TRAVERSE(&module_list, mod, entry) {
778                         /* if it's not embedded, skip it */
779                         if (mod->lib)
780                                 continue;
781
782                         if (mod->flags.running)
783                                 continue;
784
785                         order = add_to_load_order(mod->resource, &load_order);
786                 }
787
788 #ifdef LOADABLE_MODULES
789                 /* if we are allowed to load dynamic modules, scan the directory for
790                    for all available modules and add them as well */
791                 if ((dir  = opendir(ast_config_AST_MODULE_DIR))) {
792                         while ((dirent = readdir(dir))) {
793                                 int ld = strlen(dirent->d_name);
794
795                                 /* Must end in .so to load it.  */
796
797                                 if (ld < 4)
798                                         continue;
799
800                                 if (strcasecmp(dirent->d_name + ld - 3, ".so"))
801                                         continue;
802
803                                 /* if there is already a module by this name in the module_list,
804                                    skip this file */
805                                 if (find_resource(dirent->d_name, 0))
806                                         continue;
807
808                                 add_to_load_order(dirent->d_name, &load_order);
809                         }
810
811                         closedir(dir);
812                 } else {
813                         if (!ast_opt_quiet)
814                                 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",
815                                         ast_config_AST_MODULE_DIR);
816                 }
817 #endif
818         }
819
820         /* now scan the config for any modules we are prohibited from loading and
821            remove them from the load order */
822         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
823                 if (strcasecmp(v->name, "noload"))
824                         continue;
825
826                 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
827                         if (!resource_name_match(order->resource, v->value)) {
828                                 AST_LIST_REMOVE_CURRENT(entry);
829                                 ast_free(order->resource);
830                                 ast_free(order);
831                         }
832                 }
833                 AST_LIST_TRAVERSE_SAFE_END;
834         }
835
836         /* we are done with the config now, all the information we need is in the
837            load_order list */
838         ast_config_destroy(cfg);
839
840         load_count = 0;
841         AST_LIST_TRAVERSE(&load_order, order, entry)
842                 load_count++;
843
844         if (load_count)
845                 ast_log(LOG_NOTICE, "%d modules will be loaded.\n", load_count);
846
847         /* first, load only modules that provide global symbols */
848         AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
849                 switch (load_resource(order->resource, 1)) {
850                 case AST_MODULE_LOAD_SUCCESS:
851                 case AST_MODULE_LOAD_DECLINE:
852                         AST_LIST_REMOVE_CURRENT(entry);
853                         ast_free(order->resource);
854                         ast_free(order);
855                         break;
856                 case AST_MODULE_LOAD_FAILURE:
857                         res = -1;
858                         goto done;
859                 case AST_MODULE_LOAD_SKIP:
860                         /* try again later */
861                         break;
862                 }
863         }
864         AST_LIST_TRAVERSE_SAFE_END;
865
866         /* now load everything else */
867         AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
868                 switch (load_resource(order->resource, 0)) {
869                 case AST_MODULE_LOAD_SUCCESS:
870                 case AST_MODULE_LOAD_DECLINE:
871                         AST_LIST_REMOVE_CURRENT(entry);
872                         ast_free(order->resource);
873                         ast_free(order);
874                         break;
875                 case AST_MODULE_LOAD_FAILURE:
876                         res = -1;
877                         goto done;
878                 case AST_MODULE_LOAD_SKIP:
879                         /* should not happen */
880                         break;
881                 }
882         }
883         AST_LIST_TRAVERSE_SAFE_END;
884
885 done:
886         while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
887                 ast_free(order->resource);
888                 ast_free(order);
889         }
890
891         AST_LIST_UNLOCK(&module_list);
892
893         return res;
894 }
895
896 void ast_update_use_count(void)
897 {
898         /* Notify any module monitors that the use count for a
899            resource has changed */
900         struct loadupdate *m;
901
902         AST_LIST_LOCK(&module_list);
903         AST_LIST_TRAVERSE(&updaters, m, entry)
904                 m->updater();
905         AST_LIST_UNLOCK(&module_list);
906 }
907
908 int ast_update_module_list(int (*modentry)(const char *module, const char *description, int usecnt, const char *like),
909                            const char *like)
910 {
911         struct ast_module *cur;
912         int unlock = -1;
913         int total_mod_loaded = 0;
914
915         if (AST_LIST_TRYLOCK(&module_list))
916                 unlock = 0;
917  
918         AST_LIST_TRAVERSE(&module_list, cur, entry) {
919                 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, like);
920         }
921
922         if (unlock)
923                 AST_LIST_UNLOCK(&module_list);
924
925         return total_mod_loaded;
926 }
927
928 /*! \brief Check if module exists */
929 int ast_module_check(const char *name)
930 {
931         struct ast_module *cur;
932
933         if (ast_strlen_zero(name))
934                 return 0;       /* FALSE */
935
936         cur = find_resource(name, 1);
937
938         return (cur != NULL);
939 }
940
941
942 int ast_loader_register(int (*v)(void))
943 {
944         struct loadupdate *tmp;
945
946         if (!(tmp = ast_malloc(sizeof(*tmp))))
947                 return -1;
948
949         tmp->updater = v;
950         AST_LIST_LOCK(&module_list);
951         AST_LIST_INSERT_HEAD(&updaters, tmp, entry);
952         AST_LIST_UNLOCK(&module_list);
953
954         return 0;
955 }
956
957 int ast_loader_unregister(int (*v)(void))
958 {
959         struct loadupdate *cur;
960
961         AST_LIST_LOCK(&module_list);
962         AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) {
963                 if (cur->updater == v)  {
964                         AST_LIST_REMOVE_CURRENT(entry);
965                         break;
966                 }
967         }
968         AST_LIST_TRAVERSE_SAFE_END;
969         AST_LIST_UNLOCK(&module_list);
970
971         return cur ? 0 : -1;
972 }
973
974 struct ast_module *ast_module_ref(struct ast_module *mod)
975 {
976         ast_atomic_fetchadd_int(&mod->usecount, +1);
977         ast_update_use_count();
978
979         return mod;
980 }
981
982 void ast_module_unref(struct ast_module *mod)
983 {
984         ast_atomic_fetchadd_int(&mod->usecount, -1);
985         ast_update_use_count();
986 }