loader: Process dependencies for built-in modules.
[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 /*** MODULEINFO
31         <support_level>core</support_level>
32  ***/
33
34 #include "asterisk.h"
35
36 #include "asterisk/_private.h"
37 #include "asterisk/paths.h"     /* use ast_config_AST_MODULE_DIR */
38 #include <dirent.h>
39
40 #include "asterisk/dlinkedlists.h"
41 #include "asterisk/module.h"
42 #include "asterisk/config.h"
43 #include "asterisk/channel.h"
44 #include "asterisk/term.h"
45 #include "asterisk/manager.h"
46 #include "asterisk/io.h"
47 #include "asterisk/lock.h"
48 #include "asterisk/vector.h"
49 #include "asterisk/app.h"
50 #include "asterisk/test.h"
51 #include "asterisk/cli.h"
52
53 #include <dlfcn.h>
54
55 #include "asterisk/md5.h"
56 #include "asterisk/utils.h"
57
58 /*** DOCUMENTATION
59         <managerEvent language="en_US" name="Reload">
60                 <managerEventInstance class="EVENT_FLAG_SYSTEM">
61                         <synopsis>Raised when a module has been reloaded in Asterisk.</synopsis>
62                         <syntax>
63                                 <parameter name="Module">
64                                         <para>The name of the module that was reloaded, or
65                                         <literal>All</literal> if all modules were reloaded</para>
66                                 </parameter>
67                                 <parameter name="Status">
68                                         <para>The numeric status code denoting the success or failure
69                                         of the reload request.</para>
70                                         <enumlist>
71                                                 <enum name="0"><para>Success</para></enum>
72                                                 <enum name="1"><para>Request queued</para></enum>
73                                                 <enum name="2"><para>Module not found</para></enum>
74                                                 <enum name="3"><para>Error</para></enum>
75                                                 <enum name="4"><para>Reload already in progress</para></enum>
76                                                 <enum name="5"><para>Module uninitialized</para></enum>
77                                                 <enum name="6"><para>Reload not supported</para></enum>
78                                         </enumlist>
79                                 </parameter>
80                         </syntax>
81                 </managerEventInstance>
82         </managerEvent>
83         <managerEvent language="en_US" name="Load">
84                 <managerEventInstance class="EVENT_FLAG_SYSTEM">
85                         <synopsis>Raised when a module has been loaded in Asterisk.</synopsis>
86                         <syntax>
87                                 <parameter name="Module">
88                                         <para>The name of the module that was loaded</para>
89                                 </parameter>
90                                 <parameter name="Status">
91                                         <para>The result of the load request.</para>
92                                         <enumlist>
93                                                 <enum name="Failure"><para>Module could not be loaded properly</para></enum>
94                                                 <enum name="Success"><para>Module loaded and configured</para></enum>
95                                                 <enum name="Decline"><para>Module is not configured</para></enum>
96                                         </enumlist>
97                                 </parameter>
98                         </syntax>
99                 </managerEventInstance>
100         </managerEvent>
101         <managerEvent language="en_US" name="Unload">
102                 <managerEventInstance class="EVENT_FLAG_SYSTEM">
103                         <synopsis>Raised when a module has been unloaded in Asterisk.</synopsis>
104                         <syntax>
105                                 <parameter name="Module">
106                                         <para>The name of the module that was unloaded</para>
107                                 </parameter>
108                                 <parameter name="Status">
109                                         <para>The result of the unload request.</para>
110                                         <enumlist>
111                                                 <enum name="Success"><para>Module unloaded successfully</para></enum>
112                                         </enumlist>
113                                 </parameter>
114                         </syntax>
115                 </managerEventInstance>
116         </managerEvent>
117  ***/
118
119 #ifndef RTLD_NOW
120 #define RTLD_NOW 0
121 #endif
122
123 #ifndef RTLD_LOCAL
124 #define RTLD_LOCAL 0
125 #endif
126
127 struct ast_module_user {
128         struct ast_channel *chan;
129         AST_LIST_ENTRY(ast_module_user) entry;
130 };
131
132 AST_DLLIST_HEAD(module_user_list, ast_module_user);
133
134 static const unsigned char expected_key[] =
135 { 0x87, 0x76, 0x79, 0x35, 0x23, 0xea, 0x3a, 0xd3,
136   0x25, 0x2a, 0xbb, 0x35, 0x87, 0xe4, 0x22, 0x24 };
137
138 static char buildopt_sum[33] = AST_BUILDOPT_SUM;
139
140 AST_VECTOR(module_vector, struct ast_module *);
141
142 /* Built-in module registrations need special handling at startup */
143 static unsigned int loader_ready;
144
145 /*!
146  * \brief Internal flag to indicate all modules have been initially loaded.
147  */
148 static int modules_loaded;
149
150 struct ast_module {
151         const struct ast_module_info *info;
152         /*! Used to get module references into refs log */
153         void *ref_debug;
154         /*! The shared lib. */
155         void *lib;
156         /*! Number of 'users' and other references currently holding the module. */
157         int usecount;
158         /*! List of users holding the module. */
159         struct module_user_list users;
160
161         /*! List of required module names. */
162         struct ast_vector_string requires;
163         /*! List of optional api modules. */
164         struct ast_vector_string optional_modules;
165         /*! List of modules this enhances. */
166         struct ast_vector_string enhances;
167
168         /*!
169          * \brief Vector holding pointers to modules we have a reference to.
170          *
171          * When one module requires another, the required module gets added
172          * to this list with a reference.
173          */
174         struct module_vector reffed_deps;
175         struct {
176                 /*! The module running and ready to accept requests. */
177                 unsigned int running:1;
178                 /*! The module has declined to start. */
179                 unsigned int declined:1;
180                 /*! This module is being held open until it's time to shutdown. */
181                 unsigned int keepuntilshutdown:1;
182                 /*! The module is built-in. */
183                 unsigned int builtin:1;
184                 /*! The admin has declared this module is required. */
185                 unsigned int required:1;
186                 /*! This module is marked for preload. */
187                 unsigned int preload:1;
188         } flags;
189         AST_DLLIST_ENTRY(ast_module) entry;
190         char resource[0];
191 };
192
193 static AST_DLLIST_HEAD_STATIC(module_list, ast_module);
194
195
196 struct load_results_map {
197         int result;
198         const char *name;
199 };
200
201 static const struct load_results_map load_results[] = {
202         { AST_MODULE_LOAD_SUCCESS, "Success" },
203         { AST_MODULE_LOAD_DECLINE, "Decline" },
204         { AST_MODULE_LOAD_SKIP, "Skip" },
205         { AST_MODULE_LOAD_PRIORITY, "Priority" },
206         { AST_MODULE_LOAD_FAILURE, "Failure" },
207 };
208 #define AST_MODULE_LOAD_UNKNOWN_STRING          "Unknown"               /* Status string for unknown load status */
209
210 static void publish_load_message_type(const char* type, const char *name, const char *status);
211 static void publish_reload_message(const char *name, enum ast_module_reload_result result);
212 static void publish_load_message(const char *name, enum ast_module_load_result result);
213 static void publish_unload_message(const char *name, const char* status);
214
215
216 /*
217  * module_list is cleared by its constructor possibly after
218  * we start accumulating built-in modules, so we need to
219  * use another list (without the lock) to accumulate them.
220  */
221 static struct module_list builtin_module_list;
222
223 static int module_vector_strcasecmp(struct ast_module *a, struct ast_module *b)
224 {
225         return strcasecmp(a->resource, b->resource);
226 }
227
228 static int module_vector_cmp(struct ast_module *a, struct ast_module *b)
229 {
230         int preload_diff = (int)b->flags.preload - (int)a->flags.preload;
231         /* if load_pri is not set, default is 128.  Lower is better */
232         int a_pri = ast_test_flag(a->info, AST_MODFLAG_LOAD_ORDER)
233                 ? a->info->load_pri : AST_MODPRI_DEFAULT;
234         int b_pri = ast_test_flag(b->info, AST_MODFLAG_LOAD_ORDER)
235                 ? b->info->load_pri : AST_MODPRI_DEFAULT;
236
237         if (preload_diff) {
238                 /* -1 preload a but not b */
239                 /*  0 preload both or neither */
240                 /*  1 preload b but not a */
241                 return preload_diff;
242         }
243
244         /*
245          * Returns comparison values for a vector sorted by priority.
246          * <0 a_pri < b_pri
247          * =0 a_pri == b_pri
248          * >0 a_pri > b_pri
249          */
250         return a_pri - b_pri;
251 }
252
253 static struct ast_module *find_resource(const char *resource, int do_lock);
254
255 /*!
256  * \internal
257  * \brief Add a reference from mod to dep.
258  *
259  * \param mod Owner of the new reference.
260  * \param dep Module to reference
261  * \param missing Vector to store name of \a dep if it is not running.
262  *
263  * This function returns failure if \a dep is not running and \a missing
264  * is NULL.  If \a missing is not NULL errors will only be returned for
265  * allocation failures.
266  *
267  * \retval 0 Success
268  * \retval -1 Failure
269  *
270  * \note Adding a second reference to the same dep will return success
271  *       without doing anything.
272  */
273 static int module_reffed_deps_add(struct ast_module *mod, struct ast_module *dep,
274         struct ast_vector_const_string *missing)
275 {
276         if (!dep->flags.running) {
277                 return !missing ? -1 : AST_VECTOR_APPEND(missing, dep->info->name);
278         }
279
280         if (AST_VECTOR_GET_CMP(&mod->reffed_deps, dep, AST_VECTOR_ELEM_DEFAULT_CMP)) {
281                 /* Skip duplicate. */
282                 return 0;
283         }
284
285         if (AST_VECTOR_APPEND(&mod->reffed_deps, dep)) {
286                 return -1;
287         }
288
289         ast_module_ref(dep);
290
291         return 0;
292 }
293
294 /*!
295  * \internal
296  * \brief Add references for modules that enhance a dependency.
297  *
298  * \param mod Owner of the new references.
299  * \param dep Module to check for enhancers.
300  * \param missing Vector to store name of any enhancer that is not running or declined.
301  *
302  * \retval 0 Success
303  * \retval -1 Failure
304  */
305 static int module_reffed_deps_add_dep_enhancers(struct ast_module *mod,
306         struct ast_module *dep, struct ast_vector_const_string *missing)
307 {
308         struct ast_module *cur;
309
310         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
311                 if (cur->flags.declined) {
312                         continue;
313                 }
314
315                 if (!AST_VECTOR_GET_CMP(&cur->enhances, dep->info->name, !strcasecmp)) {
316                         /* dep is not enhanced by cur. */
317                         continue;
318                 }
319
320                 /* dep is enhanced by cur, therefore mod requires cur. */
321                 if (module_reffed_deps_add(mod, cur, missing)) {
322                         return -1;
323                 }
324         }
325
326         return 0;
327 }
328
329 /*!
330  * \internal
331  * \brief Add references to a list of dependencies.
332  *
333  * \param mod Owner of the new references.
334  * \param vec List of required modules to process
335  * \param missing Vector to store names of modules that are not running.
336  * \param ref_enhancers Reference all enhancers of each required module.
337  * \param isoptional Modules that are not loaded can be ignored.
338  *
339  * \retval 0 Success
340  * \retval -1 Failure
341  */
342 static int module_deps_process_reqlist(struct ast_module *mod,
343         struct ast_vector_string *vec, struct ast_vector_const_string *missing,
344         int ref_enhancers, int isoptional)
345 {
346         int idx;
347
348         for (idx = 0; idx < AST_VECTOR_SIZE(vec); idx++) {
349                 const char *depname = AST_VECTOR_GET(vec, idx);
350                 struct ast_module *dep = find_resource(depname, 0);
351
352                 if (!dep || !dep->flags.running) {
353                         if (isoptional && !dep) {
354                                 continue;
355                         }
356
357                         if (missing && !AST_VECTOR_APPEND(missing, depname)) {
358                                 continue;
359                         }
360
361                         return -1;
362                 }
363
364                 if (module_reffed_deps_add(mod, dep, missing)) {
365                         return -1;
366                 }
367
368                 if (ref_enhancers && module_reffed_deps_add_dep_enhancers(mod, dep, missing)) {
369                         return -1;
370                 }
371         }
372
373         return 0;
374 }
375
376 /*!
377  * \internal
378  * \brief Grab all references required to start the module.
379  *
380  * \param mod The module we're trying to start.
381  * \param missing Vector to store a list of missing dependencies.
382  *
383  * \retval 0 Success
384  * \retval -1 Failure
385  *
386  * \note module_list must be locked.
387  *
388  * \note Caller is responsible for initializing and freeing the vector.
389  *       Elements are safely read only while module_list remains locked.
390  */
391 static int module_deps_reference(struct ast_module *mod, struct ast_vector_const_string *missing)
392 {
393         int res = 0;
394
395         /* Grab references to modules we enhance but not other enhancements. */
396         res |= module_deps_process_reqlist(mod, &mod->enhances, missing, 0, 0);
397
398         /* Grab references to modules we require plus enhancements. */
399         res |= module_deps_process_reqlist(mod, &mod->requires, missing, 1, 0);
400
401         /* Grab references to optional modules including enhancements. */
402         res |= module_deps_process_reqlist(mod, &mod->optional_modules, missing, 1, 1);
403
404         return res;
405 }
406
407 /*!
408  * \brief Recursively find required dependencies that are not running.
409  *
410  * \param mod Module to scan for dependencies.
411  * \param missingdeps Vector listing modules that must be started first.
412  *
413  * \retval 0 All dependencies resolved.
414  * \retval -1 Failed to resolve some dependencies.
415  *
416  * An error from this function usually means a required module is not even
417  * loaded.  This function is safe from infinite recursion, but dependency
418  * loops are not reported as an error from here.  On success missingdeps
419  * will contain a list of every module that needs to be running before this
420  * module can start.  missingdeps is sorted by load priority so any missing
421  * dependencies can be started if needed.
422  */
423 static int module_deps_missing_recursive(struct ast_module *mod, struct module_vector *missingdeps)
424 {
425         int i = 0;
426         int res = -1;
427         struct ast_vector_const_string localdeps;
428         struct ast_module *dep;
429
430         /*
431          * localdeps stores a copy of all dependencies that mod could not reference.
432          * First we discard modules that we've already found. We add all newly found
433          * modules to the missingdeps vector then scan them recursively.  This will
434          * ensure we quickly run out of stuff to do.
435          */
436         AST_VECTOR_INIT(&localdeps, 0);
437         if (module_deps_reference(mod, &localdeps)) {
438                 goto clean_return;
439         }
440
441         while (i < AST_VECTOR_SIZE(&localdeps)) {
442                 dep = find_resource(AST_VECTOR_GET(&localdeps, i), 0);
443                 if (!dep) {
444                         goto clean_return;
445                 }
446
447                 if (AST_VECTOR_GET_CMP(missingdeps, dep, AST_VECTOR_ELEM_DEFAULT_CMP)) {
448                         /* Skip common dependency.  We have already searched it. */
449                         AST_VECTOR_REMOVE(&localdeps, i, 0);
450                 } else {
451                         /* missingdeps is the real list so keep it sorted. */
452                         if (AST_VECTOR_ADD_SORTED(missingdeps, dep, module_vector_cmp)) {
453                                 goto clean_return;
454                         }
455                         i++;
456                 }
457         }
458
459         res = 0;
460         for (i = 0; !res && i < AST_VECTOR_SIZE(&localdeps); i++) {
461                 dep = find_resource(AST_VECTOR_GET(&localdeps, i), 0);
462                 /* We've already confirmed dep is loaded in the first loop. */
463                 res = module_deps_missing_recursive(dep, missingdeps);
464         }
465
466 clean_return:
467         AST_VECTOR_FREE(&localdeps);
468
469         return res;
470 }
471
472 const char *ast_module_name(const struct ast_module *mod)
473 {
474         if (!mod || !mod->info) {
475                 return NULL;
476         }
477
478         return mod->info->name;
479 }
480
481 struct loadupdate {
482         int (*updater)(void);
483         AST_LIST_ENTRY(loadupdate) entry;
484 };
485
486 static AST_DLLIST_HEAD_STATIC(updaters, loadupdate);
487
488 AST_MUTEX_DEFINE_STATIC(reloadlock);
489
490 struct reload_queue_item {
491         AST_LIST_ENTRY(reload_queue_item) entry;
492         char module[0];
493 };
494
495 static int do_full_reload = 0;
496
497 static AST_DLLIST_HEAD_STATIC(reload_queue, reload_queue_item);
498
499 /*!
500  * \internal
501  *
502  * This variable is set by load_dynamic_module so ast_module_register
503  * can know what pointer is being registered.
504  *
505  * This is protected by the module_list lock.
506  */
507 static struct ast_module * volatile resource_being_loaded;
508
509 /*!
510  * \internal
511  * \brief Used by AST_MODULE_INFO to register with the module loader.
512  *
513  * This function is automatically called when each module is opened.
514  * It must never be used from outside AST_MODULE_INFO.
515  */
516 void ast_module_register(const struct ast_module_info *info)
517 {
518         struct ast_module *mod;
519
520         if (!loader_ready) {
521                 mod = ast_std_calloc(1, sizeof(*mod) + strlen(info->name) + 1);
522                 if (!mod) {
523                         /* We haven't even reached main() yet, if we can't
524                          * allocate memory at this point just give up. */
525                         fprintf(stderr, "Allocation failure during startup.\n");
526                         exit(2);
527                 }
528                 strcpy(mod->resource, info->name); /* safe */
529                 mod->info = info;
530                 mod->flags.builtin = 1;
531                 AST_DLLIST_INSERT_TAIL(&builtin_module_list, mod, entry);
532
533                 /* ast_module_register for built-in modules is run again during module preload. */
534                 return;
535         }
536
537         /*
538          * This lock protects resource_being_loaded as well as the module
539          * list.  Normally we already have a lock on module_list when we
540          * begin the load but locking again from here prevents corruption
541          * if an asterisk module is dlopen'ed from outside the module loader.
542          */
543         AST_DLLIST_LOCK(&module_list);
544         mod = resource_being_loaded;
545         if (!mod) {
546                 AST_DLLIST_UNLOCK(&module_list);
547                 return;
548         }
549
550         ast_debug(5, "Registering module %s\n", info->name);
551
552         /* This tells load_dynamic_module that we're registered. */
553         resource_being_loaded = NULL;
554
555         mod->info = info;
556         if (ast_opt_ref_debug) {
557                 mod->ref_debug = ao2_t_alloc(0, NULL, info->name);
558         }
559         AST_LIST_HEAD_INIT(&mod->users);
560         AST_VECTOR_INIT(&mod->requires, 0);
561         AST_VECTOR_INIT(&mod->optional_modules, 0);
562         AST_VECTOR_INIT(&mod->enhances, 0);
563         AST_VECTOR_INIT(&mod->reffed_deps, 0);
564
565         AST_DLLIST_INSERT_TAIL(&module_list, mod, entry);
566         AST_DLLIST_UNLOCK(&module_list);
567
568         /* give the module a copy of its own handle, for later use in registrations and the like */
569         *((struct ast_module **) &(info->self)) = mod;
570 }
571
572 static int module_post_register(struct ast_module *mod)
573 {
574         int res;
575
576         /* Split lists from mod->info. */
577         res  = ast_vector_string_split(&mod->requires, mod->info->requires, ",", 0, strcasecmp);
578         res |= ast_vector_string_split(&mod->optional_modules, mod->info->optional_modules, ",", 0, strcasecmp);
579         res |= ast_vector_string_split(&mod->enhances, mod->info->enhances, ",", 0, strcasecmp);
580
581         return res;
582 }
583
584 static void module_destroy(struct ast_module *mod)
585 {
586         AST_VECTOR_CALLBACK_VOID(&mod->requires, ast_free);
587         AST_VECTOR_FREE(&mod->requires);
588
589         AST_VECTOR_CALLBACK_VOID(&mod->optional_modules, ast_free);
590         AST_VECTOR_FREE(&mod->optional_modules);
591
592         AST_VECTOR_CALLBACK_VOID(&mod->enhances, ast_free);
593         AST_VECTOR_FREE(&mod->enhances);
594
595         /* Release references to all dependencies. */
596         AST_VECTOR_CALLBACK_VOID(&mod->reffed_deps, ast_module_unref);
597         AST_VECTOR_FREE(&mod->reffed_deps);
598
599         AST_LIST_HEAD_DESTROY(&mod->users);
600         ao2_cleanup(mod->ref_debug);
601         if (mod->flags.builtin) {
602                 ast_std_free(mod);
603         } else {
604                 ast_free(mod);
605         }
606 }
607
608 void ast_module_unregister(const struct ast_module_info *info)
609 {
610         struct ast_module *mod = NULL;
611
612         /* it is assumed that the users list in the module structure
613            will already be empty, or we cannot have gotten to this
614            point
615         */
616         AST_DLLIST_LOCK(&module_list);
617         AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&module_list, mod, entry) {
618                 if (mod->info == info) {
619                         AST_DLLIST_REMOVE_CURRENT(entry);
620                         break;
621                 }
622         }
623         AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
624         AST_DLLIST_UNLOCK(&module_list);
625
626         if (mod && !mod->usecount) {
627                 /*
628                  * We are intentionally leaking mod if usecount is not zero.
629                  * This is necessary if the module is being forcefully unloaded.
630                  * In addition module_destroy is not safe to run after exit()
631                  * is called.  ast_module_unregister is run during cleanup of
632                  * the process when libc releases each module's shared object
633                  * library.
634                  */
635                 ast_debug(5, "Unregistering module %s\n", info->name);
636                 module_destroy(mod);
637         }
638 }
639
640 struct ast_module_user *__ast_module_user_add(struct ast_module *mod, struct ast_channel *chan)
641 {
642         struct ast_module_user *u;
643
644         u = ast_calloc(1, sizeof(*u));
645         if (!u) {
646                 return NULL;
647         }
648
649         u->chan = chan;
650
651         AST_LIST_LOCK(&mod->users);
652         AST_LIST_INSERT_HEAD(&mod->users, u, entry);
653         AST_LIST_UNLOCK(&mod->users);
654
655         if (mod->ref_debug) {
656                 ao2_ref(mod->ref_debug, +1);
657         }
658
659         ast_atomic_fetchadd_int(&mod->usecount, +1);
660
661         ast_update_use_count();
662
663         return u;
664 }
665
666 void __ast_module_user_remove(struct ast_module *mod, struct ast_module_user *u)
667 {
668         if (!u) {
669                 return;
670         }
671
672         AST_LIST_LOCK(&mod->users);
673         u = AST_LIST_REMOVE(&mod->users, u, entry);
674         AST_LIST_UNLOCK(&mod->users);
675         if (!u) {
676                 /*
677                  * Was not in the list.  Either a bad pointer or
678                  * __ast_module_user_hangup_all() has been called.
679                  */
680                 return;
681         }
682
683         if (mod->ref_debug) {
684                 ao2_ref(mod->ref_debug, -1);
685         }
686
687         ast_atomic_fetchadd_int(&mod->usecount, -1);
688         ast_free(u);
689
690         ast_update_use_count();
691 }
692
693 void __ast_module_user_hangup_all(struct ast_module *mod)
694 {
695         struct ast_module_user *u;
696
697         AST_LIST_LOCK(&mod->users);
698         while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) {
699                 if (u->chan) {
700                         ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD);
701                 }
702
703                 if (mod->ref_debug) {
704                         ao2_ref(mod->ref_debug, -1);
705                 }
706
707                 ast_atomic_fetchadd_int(&mod->usecount, -1);
708                 ast_free(u);
709         }
710         AST_LIST_UNLOCK(&mod->users);
711
712         ast_update_use_count();
713 }
714
715 static int printdigest(const unsigned char *d)
716 {
717         int x, pos;
718         char buf[256]; /* large enough so we don't have to worry */
719
720         for (pos = 0, x = 0; x < 16; x++)
721                 pos += sprintf(buf + pos, " %02hhx", *d++);
722
723         ast_debug(1, "Unexpected signature:%s\n", buf);
724
725         return 0;
726 }
727
728 static int key_matches(const unsigned char *key1, const unsigned char *key2)
729 {
730         int x;
731
732         for (x = 0; x < 16; x++) {
733                 if (key1[x] != key2[x])
734                         return 0;
735         }
736
737         return 1;
738 }
739
740 static int verify_key(const unsigned char *key)
741 {
742         struct MD5Context c;
743         unsigned char digest[16];
744
745         MD5Init(&c);
746         MD5Update(&c, key, strlen((char *)key));
747         MD5Final(digest, &c);
748
749         if (key_matches(expected_key, digest))
750                 return 0;
751
752         printdigest(digest);
753
754         return -1;
755 }
756
757 static size_t resource_name_baselen(const char *name)
758 {
759         size_t len = strlen(name);
760
761         if (len > 3 && !strcasecmp(name + len - 3, ".so")) {
762                 return len - 3;
763         }
764
765         return len;
766 }
767
768 static int resource_name_match(const char *name1, size_t baselen1, const char *name2)
769 {
770         if (baselen1 != resource_name_baselen(name2)) {
771                 return -1;
772         }
773
774         return strncasecmp(name1, name2, baselen1);
775 }
776
777 static struct ast_module *find_resource(const char *resource, int do_lock)
778 {
779         struct ast_module *cur;
780         size_t resource_baselen = resource_name_baselen(resource);
781
782         if (do_lock) {
783                 AST_DLLIST_LOCK(&module_list);
784         }
785
786         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
787                 if (!resource_name_match(resource, resource_baselen, cur->resource)) {
788                         break;
789                 }
790         }
791
792         if (do_lock) {
793                 AST_DLLIST_UNLOCK(&module_list);
794         }
795
796         return cur;
797 }
798
799 /*!
800  * \brief dlclose(), with failure logging.
801  */
802 static void logged_dlclose(const char *name, void *lib)
803 {
804         char *error;
805
806         if (!lib) {
807                 return;
808         }
809
810         /* Clear any existing error */
811         dlerror();
812         if (dlclose(lib)) {
813                 error = dlerror();
814                 ast_log(AST_LOG_ERROR, "Failure in dlclose for module '%s': %s\n",
815                         S_OR(name, "unknown"), S_OR(error, "Unknown error"));
816         }
817 }
818
819 #if defined(HAVE_RTLD_NOLOAD)
820 /*!
821  * \brief Check to see if the given resource is loaded.
822  *
823  * \param resource_name Name of the resource, including .so suffix.
824  * \return False (0) if module is not loaded.
825  * \return True (non-zero) if module is loaded.
826  */
827 static int is_module_loaded(const char *resource_name)
828 {
829         char fn[PATH_MAX] = "";
830         void *lib;
831
832         snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_MODULE_DIR,
833                 resource_name);
834
835         lib = dlopen(fn, RTLD_LAZY | RTLD_NOLOAD);
836
837         if (lib) {
838                 logged_dlclose(resource_name, lib);
839                 return 1;
840         }
841
842         return 0;
843 }
844 #endif
845
846 static void unload_dynamic_module(struct ast_module *mod)
847 {
848 #if defined(HAVE_RTLD_NOLOAD)
849         char *name = ast_strdupa(ast_module_name(mod));
850 #endif
851         void *lib = mod->lib;
852
853         /* WARNING: the structure pointed to by mod is going to
854            disappear when this operation succeeds, so we can't
855            dereference it */
856         logged_dlclose(ast_module_name(mod), lib);
857
858         /* There are several situations where the module might still be resident
859          * in memory.
860          *
861          * If somehow there was another dlopen() on the same module (unlikely,
862          * since that all is supposed to happen in loader.c).
863          *
864          * Avoid the temptation of repeating the dlclose(). The other code that
865          * dlopened the module still has its module reference, and should close
866          * it itself. In other situations, dlclose() will happily return success
867          * for as many times as you wish to call it.
868          */
869 #if defined(HAVE_RTLD_NOLOAD)
870         if (is_module_loaded(name)) {
871                 ast_log(LOG_WARNING, "Module '%s' could not be completely unloaded\n", name);
872         }
873 #endif
874 }
875
876 /*!
877  * \internal
878  * \brief Attempt to dlopen a module.
879  *
880  * \param resource_in The module name to load.
881  * \param so_ext ".so" or blank if ".so" is already part of resource_in.
882  * \param filename Passed directly to dlopen.
883  * \param flags Passed directly to dlopen.
884  * \param suppress_logging Do not log any error from dlopen.
885  *
886  * \return Pointer to opened module, NULL on error.
887  *
888  * \warning module_list must be locked before calling this function.
889  */
890 static struct ast_module *load_dlopen(const char *resource_in, const char *so_ext,
891         const char *filename, int flags, unsigned int suppress_logging)
892 {
893         struct ast_module *mod;
894
895         ast_assert(!resource_being_loaded);
896
897         mod = ast_calloc(1, sizeof(*mod) + strlen(resource_in) + strlen(so_ext) + 1);
898         if (!mod) {
899                 return NULL;
900         }
901
902         sprintf(mod->resource, "%s%s", resource_in, so_ext); /* safe */
903
904         resource_being_loaded = mod;
905         mod->lib = dlopen(filename, flags);
906         if (resource_being_loaded) {
907                 resource_being_loaded = NULL;
908                 if (mod->lib) {
909                         ast_log(LOG_ERROR, "Module '%s' did not register itself during load\n", resource_in);
910                         logged_dlclose(resource_in, mod->lib);
911                 } else if (!suppress_logging) {
912                         ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
913                 }
914                 ast_free(mod);
915
916                 return NULL;
917         }
918
919         return mod;
920 }
921
922 static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int suppress_logging)
923 {
924         char fn[PATH_MAX];
925         struct ast_module *mod;
926         size_t resource_in_len = strlen(resource_in);
927         const char *so_ext = "";
928
929         if (resource_in_len < 4 || strcasecmp(resource_in + resource_in_len - 3, ".so")) {
930                 so_ext = ".so";
931         }
932
933         snprintf(fn, sizeof(fn), "%s/%s%s", ast_config_AST_MODULE_DIR, resource_in, so_ext);
934
935         /* Try loading in quiet mode first with RTLD_LOCAL.  The majority of modules do not
936          * export symbols so this allows the least number of calls to dlopen. */
937         mod = load_dlopen(resource_in, so_ext, fn, RTLD_NOW | RTLD_LOCAL, suppress_logging);
938
939         if (!mod || !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS)) {
940                 return mod;
941         }
942
943         /* Close the module so we can reopen with correct flags. */
944         logged_dlclose(resource_in, mod->lib);
945
946         return load_dlopen(resource_in, so_ext, fn, RTLD_NOW | RTLD_GLOBAL, 0);
947 }
948
949 int modules_shutdown(void)
950 {
951         struct ast_module *mod;
952         int somethingchanged;
953         int res;
954
955         AST_DLLIST_LOCK(&module_list);
956
957         /*!\note Some resources, like timers, are started up dynamically, and thus
958          * may be still in use, even if all channels are dead.  We must therefore
959          * check the usecount before asking modules to unload. */
960         do {
961                 /* Reset flag before traversing the list */
962                 somethingchanged = 0;
963
964                 AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&module_list, mod, entry) {
965                         if (mod->usecount) {
966                                 ast_debug(1, "Passing on %s: its use count is %d\n",
967                                         mod->resource, mod->usecount);
968                                 continue;
969                         }
970                         AST_DLLIST_REMOVE_CURRENT(entry);
971                         if (mod->flags.running && !mod->flags.declined && mod->info->unload) {
972                                 ast_verb(1, "Unloading %s\n", mod->resource);
973                                 mod->info->unload();
974                         }
975                         module_destroy(mod);
976                         somethingchanged = 1;
977                 }
978                 AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
979                 if (!somethingchanged) {
980                         AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
981                                 if (mod->flags.keepuntilshutdown) {
982                                         ast_module_unref(mod);
983                                         mod->flags.keepuntilshutdown = 0;
984                                         somethingchanged = 1;
985                                 }
986                         }
987                 }
988         } while (somethingchanged);
989
990         res = AST_DLLIST_EMPTY(&module_list);
991         AST_DLLIST_UNLOCK(&module_list);
992
993         return !res;
994 }
995
996 int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force)
997 {
998         struct ast_module *mod;
999         int res = -1;
1000         int error = 0;
1001
1002         AST_DLLIST_LOCK(&module_list);
1003
1004         if (!(mod = find_resource(resource_name, 0))) {
1005                 AST_DLLIST_UNLOCK(&module_list);
1006                 ast_log(LOG_WARNING, "Unload failed, '%s' could not be found\n", resource_name);
1007                 return -1;
1008         }
1009
1010         if (!mod->flags.running || mod->flags.declined) {
1011                 ast_log(LOG_WARNING, "Unload failed, '%s' is not loaded.\n", resource_name);
1012                 error = 1;
1013         }
1014
1015         if (!error && (mod->usecount > 0)) {
1016                 if (force)
1017                         ast_log(LOG_WARNING, "Warning:  Forcing removal of module '%s' with use count %d\n",
1018                                 resource_name, mod->usecount);
1019                 else {
1020                         ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name,
1021                                 mod->usecount);
1022                         error = 1;
1023                 }
1024         }
1025
1026         if (!error) {
1027                 /* Request any channels attached to the module to hangup. */
1028                 __ast_module_user_hangup_all(mod);
1029
1030                 ast_verb(1, "Unloading %s\n", mod->resource);
1031                 res = mod->info->unload();
1032                 if (res) {
1033                         ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
1034                         if (force <= AST_FORCE_FIRM) {
1035                                 error = 1;
1036                         } else {
1037                                 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
1038                         }
1039                 }
1040
1041                 if (!error) {
1042                         /*
1043                          * Request hangup on any channels that managed to get attached
1044                          * while we called the module unload function.
1045                          */
1046                         __ast_module_user_hangup_all(mod);
1047                         sched_yield();
1048                 }
1049         }
1050
1051         if (!error)
1052                 mod->flags.running = mod->flags.declined = 0;
1053
1054         AST_DLLIST_UNLOCK(&module_list);
1055
1056         if (!error) {
1057                 unload_dynamic_module(mod);
1058                 ast_test_suite_event_notify("MODULE_UNLOAD", "Message: %s", resource_name);
1059                 ast_update_use_count();
1060                 publish_unload_message(resource_name, "Success");
1061         }
1062
1063         return res;
1064 }
1065
1066 static int module_matches_helper_type(struct ast_module *mod, enum ast_module_helper_type type)
1067 {
1068         switch (type) {
1069         case AST_MODULE_HELPER_UNLOAD:
1070                 return !mod->usecount && mod->flags.running && !mod->flags.declined;
1071
1072         case AST_MODULE_HELPER_RELOAD:
1073                 return mod->flags.running && mod->info->reload;
1074
1075         case AST_MODULE_HELPER_RUNNING:
1076                 return mod->flags.running;
1077
1078         case AST_MODULE_HELPER_LOADED:
1079                 /* if we have a 'struct ast_module' then we're loaded. */
1080                 return 1;
1081         default:
1082                 /* This function is not called for AST_MODULE_HELPER_LOAD. */
1083                 /* Unknown ast_module_helper_type. Assume it doesn't match. */
1084                 ast_assert(0);
1085
1086                 return 0;
1087         }
1088 }
1089
1090 struct module_load_word {
1091         const char *word;
1092         size_t len;
1093         size_t moddir_len;
1094 };
1095
1096 static int module_load_helper_on_file(const char *dir_name, const char *filename, void *obj)
1097 {
1098         struct module_load_word *word = obj;
1099         struct ast_module *mod;
1100         char *filename_merged = NULL;
1101
1102         /* dir_name will never be shorter than word->moddir_len. */
1103         dir_name += word->moddir_len;
1104         if (!ast_strlen_zero(dir_name)) {
1105                 ast_assert(dir_name[0] == '/');
1106
1107                 dir_name += 1;
1108                 if (ast_asprintf(&filename_merged, "%s/%s", dir_name, filename) < 0) {
1109                         /* If we can't allocate the string just give up! */
1110                         return -1;
1111                 }
1112                 filename = filename_merged;
1113         }
1114
1115         if (!strncasecmp(filename, word->word, word->len)) {
1116                 /* Don't list files that are already loaded! */
1117                 mod = find_resource(filename, 0);
1118                 if (!mod || !mod->flags.running) {
1119                         ast_cli_completion_add(ast_strdup(filename));
1120                 }
1121         }
1122
1123         ast_free(filename_merged);
1124
1125         return 0;
1126 }
1127
1128 static void module_load_helper(const char *word)
1129 {
1130         struct module_load_word word_l = {
1131                 .word = word,
1132                 .len = strlen(word),
1133                 .moddir_len = strlen(ast_config_AST_MODULE_DIR),
1134         };
1135
1136         AST_DLLIST_LOCK(&module_list);
1137         ast_file_read_dirs(ast_config_AST_MODULE_DIR, module_load_helper_on_file, &word_l, -1);
1138         AST_DLLIST_UNLOCK(&module_list);
1139 }
1140
1141 char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, enum ast_module_helper_type type)
1142 {
1143         struct ast_module *mod;
1144         int which = 0;
1145         int wordlen = strlen(word);
1146         char *ret = NULL;
1147
1148         if (pos != rpos) {
1149                 return NULL;
1150         }
1151
1152         if (type == AST_MODULE_HELPER_LOAD) {
1153                 module_load_helper(word);
1154
1155                 return NULL;
1156         }
1157
1158         AST_DLLIST_LOCK(&module_list);
1159         AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
1160                 if (!module_matches_helper_type(mod, type)) {
1161                         continue;
1162                 }
1163
1164                 if (!strncasecmp(word, mod->resource, wordlen) && ++which > state) {
1165                         ret = ast_strdup(mod->resource);
1166                         break;
1167                 }
1168         }
1169         AST_DLLIST_UNLOCK(&module_list);
1170
1171         return ret;
1172 }
1173
1174 void ast_process_pending_reloads(void)
1175 {
1176         struct reload_queue_item *item;
1177
1178         modules_loaded = 1;
1179
1180         AST_LIST_LOCK(&reload_queue);
1181
1182         if (do_full_reload) {
1183                 do_full_reload = 0;
1184                 AST_LIST_UNLOCK(&reload_queue);
1185                 ast_log(LOG_NOTICE, "Executing deferred reload request.\n");
1186                 ast_module_reload(NULL);
1187                 return;
1188         }
1189
1190         while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
1191                 ast_log(LOG_NOTICE, "Executing deferred reload request for module '%s'.\n", item->module);
1192                 ast_module_reload(item->module);
1193                 ast_free(item);
1194         }
1195
1196         AST_LIST_UNLOCK(&reload_queue);
1197 }
1198
1199 static void queue_reload_request(const char *module)
1200 {
1201         struct reload_queue_item *item;
1202
1203         AST_LIST_LOCK(&reload_queue);
1204
1205         if (do_full_reload) {
1206                 AST_LIST_UNLOCK(&reload_queue);
1207                 return;
1208         }
1209
1210         if (ast_strlen_zero(module)) {
1211                 /* A full reload request (when module is NULL) wipes out any previous
1212                    reload requests and causes the queue to ignore future ones */
1213                 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
1214                         ast_free(item);
1215                 }
1216                 do_full_reload = 1;
1217         } else {
1218                 /* No reason to add the same module twice */
1219                 AST_LIST_TRAVERSE(&reload_queue, item, entry) {
1220                         if (!strcasecmp(item->module, module)) {
1221                                 AST_LIST_UNLOCK(&reload_queue);
1222                                 return;
1223                         }
1224                 }
1225                 item = ast_calloc(1, sizeof(*item) + strlen(module) + 1);
1226                 if (!item) {
1227                         ast_log(LOG_ERROR, "Failed to allocate reload queue item.\n");
1228                         AST_LIST_UNLOCK(&reload_queue);
1229                         return;
1230                 }
1231                 strcpy(item->module, module);
1232                 AST_LIST_INSERT_TAIL(&reload_queue, item, entry);
1233         }
1234         AST_LIST_UNLOCK(&reload_queue);
1235 }
1236
1237 /*!
1238  * \since 12
1239  * \internal
1240  * \brief Publish a \ref stasis message regarding the type.
1241  */
1242 static void publish_load_message_type(const char* type, const char *name, const char *status)
1243 {
1244         RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
1245         RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
1246         RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
1247         RAII_VAR(struct ast_json *, event_object, NULL, ast_json_unref);
1248
1249         ast_assert(type != NULL);
1250         ast_assert(!ast_strlen_zero(name));
1251         ast_assert(!ast_strlen_zero(status));
1252
1253         if (!ast_manager_get_generic_type()) {
1254                 return;
1255         }
1256
1257         event_object = ast_json_pack("{s:s, s:s}",
1258                         "Module", name,
1259                         "Status", status);
1260         json_object = ast_json_pack("{s:s, s:i, s:o}",
1261                         "type", type,
1262                         "class_type", EVENT_FLAG_SYSTEM,
1263                         "event", ast_json_ref(event_object));
1264         if (!json_object) {
1265                 return;
1266         }
1267
1268         payload = ast_json_payload_create(json_object);
1269         if (!payload) {
1270                 return;
1271         }
1272
1273         message = stasis_message_create(ast_manager_get_generic_type(), payload);
1274         if (!message) {
1275                 return;
1276         }
1277
1278         stasis_publish(ast_manager_get_topic(), message);
1279 }
1280
1281 static const char* loadresult2str(enum ast_module_load_result result)
1282 {
1283         int i;
1284         for (i = 0; i < ARRAY_LEN(load_results); i++) {
1285                 if (load_results[i].result == result) {
1286                         return load_results[i].name;
1287                 }
1288         }
1289
1290         ast_log(LOG_WARNING, "Failed to find correct load result status. result %d\n", result);
1291         return AST_MODULE_LOAD_UNKNOWN_STRING;
1292 }
1293
1294 /*!
1295  * \internal
1296  * \brief Publish a \ref stasis message regarding the load result
1297  */
1298 static void publish_load_message(const char *name, enum ast_module_load_result result)
1299 {
1300         const char *status;
1301
1302         status = loadresult2str(result);
1303
1304         publish_load_message_type("Load", name, status);
1305 }
1306
1307 /*!
1308  * \internal
1309  * \brief Publish a \ref stasis message regarding the unload result
1310  */
1311 static void publish_unload_message(const char *name, const char* status)
1312 {
1313         publish_load_message_type("Unload", name, status);
1314 }
1315
1316 /*!
1317  * \since 12
1318  * \internal
1319  * \brief Publish a \ref stasis message regarding the reload result
1320  */
1321 static void publish_reload_message(const char *name, enum ast_module_reload_result result)
1322 {
1323         char res_buffer[8];
1324
1325         snprintf(res_buffer, sizeof(res_buffer), "%u", result);
1326         publish_load_message_type("Reload", S_OR(name, "All"), res_buffer);
1327 }
1328
1329 enum ast_module_reload_result ast_module_reload(const char *name)
1330 {
1331         struct ast_module *cur;
1332         enum ast_module_reload_result res = AST_MODULE_RELOAD_NOT_FOUND;
1333         size_t name_baselen = name ? resource_name_baselen(name) : 0;
1334
1335         /* If we aren't fully booted, we just pretend we reloaded but we queue this
1336            up to run once we are booted up. */
1337         if (!modules_loaded) {
1338                 queue_reload_request(name);
1339                 res = AST_MODULE_RELOAD_QUEUED;
1340                 goto module_reload_exit;
1341         }
1342
1343         if (ast_mutex_trylock(&reloadlock)) {
1344                 ast_verb(3, "The previous reload command didn't finish yet\n");
1345                 res = AST_MODULE_RELOAD_IN_PROGRESS;
1346                 goto module_reload_exit;
1347         }
1348         ast_sd_notify("RELOAD=1");
1349         ast_lastreloadtime = ast_tvnow();
1350
1351         if (ast_opt_lock_confdir) {
1352                 int try;
1353                 int res;
1354                 for (try = 1, res = AST_LOCK_TIMEOUT; try < 6 && (res == AST_LOCK_TIMEOUT); try++) {
1355                         res = ast_lock_path(ast_config_AST_CONFIG_DIR);
1356                         if (res == AST_LOCK_TIMEOUT) {
1357                                 ast_log(LOG_WARNING, "Failed to grab lock on %s, try %d\n", ast_config_AST_CONFIG_DIR, try);
1358                         }
1359                 }
1360                 if (res != AST_LOCK_SUCCESS) {
1361                         ast_log(AST_LOG_WARNING, "Cannot grab lock on %s\n", ast_config_AST_CONFIG_DIR);
1362                         res = AST_MODULE_RELOAD_ERROR;
1363                         goto module_reload_done;
1364                 }
1365         }
1366
1367         AST_DLLIST_LOCK(&module_list);
1368         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
1369                 const struct ast_module_info *info = cur->info;
1370
1371                 if (name && resource_name_match(name, name_baselen, cur->resource)) {
1372                         continue;
1373                 }
1374
1375                 if (!cur->flags.running || cur->flags.declined) {
1376                         if (res == AST_MODULE_RELOAD_NOT_FOUND) {
1377                                 res = AST_MODULE_RELOAD_UNINITIALIZED;
1378                         }
1379                         if (!name) {
1380                                 continue;
1381                         }
1382                         break;
1383                 }
1384
1385                 if (!info->reload) {    /* cannot be reloaded */
1386                         if (res == AST_MODULE_RELOAD_NOT_FOUND) {
1387                                 res = AST_MODULE_RELOAD_NOT_IMPLEMENTED;
1388                         }
1389                         if (!name) {
1390                                 continue;
1391                         }
1392                         break;
1393                 }
1394                 ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description);
1395                 if (info->reload() == AST_MODULE_LOAD_SUCCESS) {
1396                         res = AST_MODULE_RELOAD_SUCCESS;
1397                 }
1398                 if (name) {
1399                         break;
1400                 }
1401         }
1402         AST_DLLIST_UNLOCK(&module_list);
1403
1404         if (ast_opt_lock_confdir) {
1405                 ast_unlock_path(ast_config_AST_CONFIG_DIR);
1406         }
1407 module_reload_done:
1408         ast_mutex_unlock(&reloadlock);
1409         ast_sd_notify("READY=1");
1410
1411 module_reload_exit:
1412         publish_reload_message(name, res);
1413         return res;
1414 }
1415
1416 static unsigned int inspect_module(const struct ast_module *mod)
1417 {
1418         if (!mod->info->description) {
1419                 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource);
1420                 return 1;
1421         }
1422
1423         if (!mod->info->key) {
1424                 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource);
1425                 return 1;
1426         }
1427
1428         if (verify_key((unsigned char *) mod->info->key)) {
1429                 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource);
1430                 return 1;
1431         }
1432
1433         if (!ast_strlen_zero(mod->info->buildopt_sum) &&
1434             strcmp(buildopt_sum, mod->info->buildopt_sum)) {
1435                 ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource);
1436                 ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource);
1437                 return 1;
1438         }
1439
1440         return 0;
1441 }
1442
1443 static enum ast_module_load_result start_resource(struct ast_module *mod)
1444 {
1445         char tmp[256];
1446         enum ast_module_load_result res;
1447
1448         if (mod->flags.running) {
1449                 return AST_MODULE_LOAD_SUCCESS;
1450         }
1451
1452         if (!mod->info->load) {
1453                 return AST_MODULE_LOAD_FAILURE;
1454         }
1455
1456         if (module_deps_reference(mod, NULL)) {
1457                 struct module_vector missing;
1458                 int i;
1459
1460                 AST_VECTOR_INIT(&missing, 0);
1461                 if (module_deps_missing_recursive(mod, &missing)) {
1462                         ast_log(LOG_ERROR, "%s has one or more unknown dependencies.\n", mod->info->name);
1463                 }
1464                 for (i = 0; i < AST_VECTOR_SIZE(&missing); i++) {
1465                         ast_log(LOG_ERROR, "%s loaded before dependency %s!\n", mod->info->name,
1466                                 AST_VECTOR_GET(&missing, i)->info->name);
1467                 }
1468                 AST_VECTOR_FREE(&missing);
1469
1470                 return AST_MODULE_LOAD_DECLINE;
1471         }
1472
1473         if (!ast_fully_booted) {
1474                 ast_verb(1, "Loading %s.\n", mod->resource);
1475         }
1476         res = mod->info->load();
1477
1478         switch (res) {
1479         case AST_MODULE_LOAD_SUCCESS:
1480                 if (!ast_fully_booted) {
1481                         ast_verb(2, "%s => (%s)\n", mod->resource, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
1482                 } else {
1483                         ast_verb(1, "Loaded %s => (%s)\n", mod->resource, mod->info->description);
1484                 }
1485
1486                 mod->flags.running = 1;
1487                 if (mod->flags.builtin) {
1488                         /* Built-in modules cannot be unloaded. */
1489                         ast_module_shutdown_ref(mod);
1490                 }
1491
1492                 ast_update_use_count();
1493                 break;
1494         case AST_MODULE_LOAD_DECLINE:
1495                 mod->flags.declined = 1;
1496                 if (mod->flags.required) {
1497                         res = AST_MODULE_LOAD_FAILURE;
1498                 }
1499                 break;
1500         case AST_MODULE_LOAD_FAILURE:
1501         case AST_MODULE_LOAD_SKIP: /* modules should never return this value */
1502         case AST_MODULE_LOAD_PRIORITY:
1503                 break;
1504         }
1505
1506         /* Make sure the newly started module is at the end of the list */
1507         AST_DLLIST_LOCK(&module_list);
1508         AST_DLLIST_REMOVE(&module_list, mod, entry);
1509         AST_DLLIST_INSERT_TAIL(&module_list, mod, entry);
1510         AST_DLLIST_UNLOCK(&module_list);
1511
1512         return res;
1513 }
1514
1515 /*! loads a resource based upon resource_name. If global_symbols_only is set
1516  *  only modules with global symbols will be loaded.
1517  *
1518  *  If the module_vector is provided (not NULL) the module is found and added to the
1519  *  vector without running the module's load() function.  By doing this, modules
1520  *  can be initialized later in order by priority and dependencies.
1521  *
1522  *  If the module_vector is not provided, the module's load function will be executed
1523  *  immediately */
1524 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int suppress_logging,
1525         struct module_vector *module_priorities, int required, int preload)
1526 {
1527         struct ast_module *mod;
1528         enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
1529
1530         if ((mod = find_resource(resource_name, 0))) {
1531                 if (mod->flags.running) {
1532                         ast_log(LOG_WARNING, "Module '%s' already loaded and running.\n", resource_name);
1533                         return AST_MODULE_LOAD_DECLINE;
1534                 }
1535         } else {
1536                 mod = load_dynamic_module(resource_name, suppress_logging);
1537                 if (!mod) {
1538                         return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
1539                 }
1540
1541                 if (module_post_register(mod)) {
1542                         goto prestart_error;
1543                 }
1544         }
1545
1546         mod->flags.required |= required;
1547         mod->flags.preload |= preload;
1548
1549         if (inspect_module(mod)) {
1550                 goto prestart_error;
1551         }
1552
1553         mod->flags.declined = 0;
1554
1555         if (module_priorities) {
1556                 if (AST_VECTOR_ADD_SORTED(module_priorities, mod, module_vector_cmp)) {
1557                         goto prestart_error;
1558                 }
1559                 res = AST_MODULE_LOAD_PRIORITY;
1560         } else {
1561                 res = start_resource(mod);
1562         }
1563
1564         if (ast_fully_booted && !ast_shutdown_final()) {
1565                 publish_load_message(resource_name, res);
1566         }
1567
1568         return res;
1569
1570 prestart_error:
1571         ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
1572         unload_dynamic_module(mod);
1573         res = required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
1574         if (ast_fully_booted && !ast_shutdown_final()) {
1575                 publish_load_message(resource_name, res);
1576         }
1577         return res;
1578 }
1579
1580 int ast_load_resource(const char *resource_name)
1581 {
1582         int res;
1583         AST_DLLIST_LOCK(&module_list);
1584         res = load_resource(resource_name, 0, NULL, 0, 0);
1585         if (!res) {
1586                 ast_test_suite_event_notify("MODULE_LOAD", "Message: %s", resource_name);
1587         }
1588         AST_DLLIST_UNLOCK(&module_list);
1589
1590         return res;
1591 }
1592
1593 struct load_order_entry {
1594         char *resource;
1595         int required;
1596         int preload;
1597         int builtin;
1598         AST_LIST_ENTRY(load_order_entry) entry;
1599 };
1600
1601 AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
1602
1603 static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order, int required, int preload, int builtin)
1604 {
1605         struct load_order_entry *order;
1606         size_t resource_baselen = resource_name_baselen(resource);
1607
1608         AST_LIST_TRAVERSE(load_order, order, entry) {
1609                 if (!resource_name_match(resource, resource_baselen, order->resource)) {
1610                         /* Make sure we have the proper setting for the required field
1611                            (we might have both load= and required= lines in modules.conf) */
1612                         order->required |= required;
1613                         order->preload |= preload;
1614                         return order;
1615                 }
1616         }
1617
1618         order = ast_calloc(1, sizeof(*order));
1619         if (!order) {
1620                 return NULL;
1621         }
1622
1623         order->resource = ast_strdup(resource);
1624         if (!order->resource) {
1625                 ast_free(order);
1626
1627                 return NULL;
1628         }
1629         order->required = required;
1630         order->preload = preload;
1631         order->builtin = builtin;
1632         AST_LIST_INSERT_TAIL(load_order, order, entry);
1633
1634         return order;
1635 }
1636
1637 AST_LIST_HEAD_NOLOCK(load_retries, load_order_entry);
1638
1639 static enum ast_module_load_result start_resource_attempt(struct ast_module *mod, int *count)
1640 {
1641         enum ast_module_load_result lres;
1642
1643         /* Try to grab required references. */
1644         if (module_deps_reference(mod, NULL)) {
1645                 /* We're likely to retry so not an error. */
1646                 ast_debug(1, "Module %s is missing dependencies\n", mod->resource);
1647                 return AST_MODULE_LOAD_SKIP;
1648         }
1649
1650         lres = start_resource(mod);
1651         ast_debug(3, "START: %-46s[%d] %d\n",
1652                 mod->resource,
1653                 ast_test_flag(mod->info, AST_MODFLAG_LOAD_ORDER) ? mod->info->load_pri : AST_MODPRI_DEFAULT,
1654                 lres);
1655
1656         if (lres == AST_MODULE_LOAD_SUCCESS) {
1657                 (*count)++;
1658         } else if (lres == AST_MODULE_LOAD_FAILURE) {
1659                 ast_log(LOG_ERROR, "*** Failed to load module %s\n", mod->resource);
1660         }
1661
1662         return lres;
1663 }
1664
1665 static int start_resource_list(struct module_vector *resources, int *mod_count)
1666 {
1667         struct module_vector missingdeps;
1668         int res = 0;
1669
1670         AST_VECTOR_INIT(&missingdeps, 0);
1671         while (AST_VECTOR_SIZE(resources)) {
1672                 struct ast_module *mod = AST_VECTOR_REMOVE(resources, 0, 1);
1673                 enum ast_module_load_result lres;
1674
1675 retry_load:
1676                 lres = start_resource_attempt(mod, mod_count);
1677                 if (lres == AST_MODULE_LOAD_SUCCESS) {
1678                         /* No missing dependencies, successful. */
1679                         continue;
1680                 }
1681
1682                 if (lres == AST_MODULE_LOAD_FAILURE) {
1683                         ast_log(LOG_ERROR, "Failed to load %s.\n", ast_module_name(mod));
1684                         res = -2;
1685                         break;
1686                 }
1687
1688                 if (lres == AST_MODULE_LOAD_DECLINE) {
1689                         continue;
1690                 }
1691
1692                 res = module_deps_missing_recursive(mod, &missingdeps);
1693                 if (res) {
1694                         AST_VECTOR_RESET(&missingdeps, AST_VECTOR_ELEM_CLEANUP_NOOP);
1695                         ast_log(LOG_ERROR, "Failed to resolve dependencies for %s\n", ast_module_name(mod));
1696                         mod->flags.declined = 1;
1697
1698                         continue;
1699                 }
1700
1701                 if (!AST_VECTOR_SIZE(&missingdeps)) {
1702                         ast_log(LOG_WARNING, "%s load function returned an invalid result. "
1703                                 "This is a bug in the module.\n", ast_module_name(mod));
1704                         /* Dependencies were met but the module failed to start and the result
1705                          * code was not AST_MODULE_LOAD_FAILURE or AST_MODULE_LOAD_DECLINE. */
1706                         res = -1;
1707                         break;
1708                 }
1709
1710                 ast_debug(1, "%s has %d dependencies\n",
1711                         ast_module_name(mod), (int)AST_VECTOR_SIZE(&missingdeps));
1712                 while (AST_VECTOR_SIZE(&missingdeps)) {
1713                         int didwork = 0;
1714                         int i = 0;
1715
1716                         while (i < AST_VECTOR_SIZE(&missingdeps)) {
1717                                 struct ast_module *dep = AST_VECTOR_GET(&missingdeps, i);
1718
1719                                 ast_debug(1, "%s trying to start %s\n", ast_module_name(mod), ast_module_name(dep));
1720                                 if (!start_resource_attempt(dep, mod_count)) {
1721                                         ast_debug(1, "%s started %s\n", ast_module_name(mod), ast_module_name(dep));
1722                                         AST_VECTOR_REMOVE(&missingdeps, i, 1);
1723                                         AST_VECTOR_REMOVE_CMP_ORDERED(resources, dep,
1724                                                 AST_VECTOR_ELEM_DEFAULT_CMP, AST_VECTOR_ELEM_CLEANUP_NOOP);
1725                                         didwork++;
1726                                         continue;
1727                                 }
1728                                 ast_debug(1, "%s failed to start %s\n", ast_module_name(mod), ast_module_name(dep));
1729                                 i++;
1730                         }
1731
1732                         if (!didwork) {
1733                                 break;
1734                         }
1735                 }
1736
1737                 if (AST_VECTOR_SIZE(&missingdeps)) {
1738                         ast_log(LOG_WARNING, "Failed to load %s due to unfilled dependencies.\n",
1739                                 ast_module_name(mod));
1740                         mod->flags.declined = 1;
1741                         AST_VECTOR_RESET(&missingdeps, AST_VECTOR_ELEM_CLEANUP_NOOP);
1742
1743                         continue;
1744                 }
1745
1746                 /* If we're here it means that we started with missingdeps and they're all loaded
1747                  * now.  It's impossible to reach this point a second time for the same module. */
1748                 goto retry_load;
1749         }
1750
1751         AST_VECTOR_FREE(&missingdeps);
1752
1753         return res;
1754 }
1755
1756 /*! loads modules in order by load_pri, updates mod_count
1757         \return -1 on failure to load module, -2 on failure to load required module, otherwise 0
1758 */
1759 static int load_resource_list(struct load_order *load_order, int *mod_count)
1760 {
1761         struct module_vector module_priorities;
1762         struct load_order_entry *order;
1763         int attempt = 0;
1764         int count = 0;
1765         int res = 0;
1766         int didwork;
1767         int lasttry = 0;
1768
1769         if (AST_VECTOR_INIT(&module_priorities, 500)) {
1770                 ast_log(LOG_ERROR, "Failed to initialize module loader.\n");
1771
1772                 return -1;
1773         }
1774
1775         while (!res) {
1776                 didwork = 0;
1777
1778                 AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
1779                         enum ast_module_load_result lres;
1780
1781                         /* Suppress log messages unless this is the last pass */
1782                         lres = load_resource(order->resource, !lasttry, &module_priorities, order->required, order->preload);
1783                         ast_debug(3, "PASS %d: %-46s %d\n", attempt, order->resource, lres);
1784                         switch (lres) {
1785                         case AST_MODULE_LOAD_SUCCESS:
1786                         case AST_MODULE_LOAD_SKIP:
1787                                 /* We're supplying module_priorities so SUCCESS isn't possible but we
1788                                  * still have to test for it.  SKIP is only used when we try to start a
1789                                  * module that is missing dependencies. */
1790                                 break;
1791                         case AST_MODULE_LOAD_DECLINE:
1792                                 break;
1793                         case AST_MODULE_LOAD_FAILURE:
1794                                 /* LOAD_FAILURE only happens for required modules */
1795                                 if (lasttry) {
1796                                         /* This run is just to print errors. */
1797                                         ast_log(LOG_ERROR, "*** Failed to load module %s - Required\n", order->resource);
1798                                         fprintf(stderr, "*** Failed to load module %s - Required\n", order->resource);
1799                                         res =  -2;
1800                                 }
1801                                 break;
1802                         case AST_MODULE_LOAD_PRIORITY:
1803                                 /* load_resource worked and the module was added to module_priorities */
1804                                 AST_LIST_REMOVE_CURRENT(entry);
1805                                 ast_free(order->resource);
1806                                 ast_free(order);
1807                                 didwork = 1;
1808                                 break;
1809                         }
1810                 }
1811                 AST_LIST_TRAVERSE_SAFE_END;
1812
1813                 if (!didwork) {
1814                         if (lasttry) {
1815                                 break;
1816                         }
1817                         /* We know the next try is going to fail, it's only being performed
1818                          * so we can print errors. */
1819                         lasttry = 1;
1820                 }
1821                 attempt++;
1822         }
1823
1824         if (!res) {
1825                 res = start_resource_list(&module_priorities, &count);
1826         }
1827
1828         if (mod_count) {
1829                 *mod_count += count;
1830         }
1831         AST_VECTOR_FREE(&module_priorities);
1832
1833         return res;
1834 }
1835
1836 static int loader_builtin_init(struct load_order *load_order)
1837 {
1838         struct ast_module *mod;
1839
1840         /*
1841          * All built-in modules have registered the first time, now it's time to complete
1842          * the registration and add them to the priority list.
1843          */
1844         loader_ready = 1;
1845
1846         while ((resource_being_loaded = AST_DLLIST_REMOVE_HEAD(&builtin_module_list, entry))) {
1847                 /* ast_module_register doesn't finish when first run by built-in modules. */
1848                 ast_module_register(resource_being_loaded->info);
1849         }
1850
1851         /* Add all built-in modules to the load order. */
1852         AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
1853                 if (!mod->flags.builtin) {
1854                         continue;
1855                 }
1856
1857                 /* Parse dependendencies from mod->info. */
1858                 if (module_post_register(mod)) {
1859                         return -1;
1860                 }
1861
1862                 /* Built-in modules are not preloaded, most have an early load priority. */
1863                 if (!add_to_load_order(mod->resource, load_order, 0, 0, 1)) {
1864                         return -1;
1865                 }
1866         }
1867
1868         return 0;
1869 }
1870
1871 static int loader_config_init(struct load_order *load_order)
1872 {
1873         int res = -1;
1874         struct load_order_entry *order;
1875         struct ast_config *cfg;
1876         struct ast_variable *v;
1877         struct ast_flags config_flags = { 0 };
1878
1879         cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags);
1880         if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
1881                 ast_log(LOG_WARNING, "'%s' invalid or missing.\n", AST_MODULE_CONFIG);
1882
1883                 return -1;
1884         }
1885
1886         /* first, find all the modules we have been explicitly requested to load */
1887         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1888                 int required;
1889                 int preload = 0;
1890
1891                 if (!strncasecmp(v->name, "preload", strlen("preload"))) {
1892                         preload = 1;
1893                         if (!strcasecmp(v->name, "preload")) {
1894                                 required = 0;
1895                         } else if (!strcasecmp(v->name, "preload-require")) {
1896                                 required = 1;
1897                         } else {
1898                                 ast_log(LOG_ERROR, "Unknown configuration option '%s'", v->name);
1899                                 goto done;
1900                         }
1901                 } else if (!strcasecmp(v->name, "load")) {
1902                         required = 0;
1903                 } else if (!strcasecmp(v->name, "require")) {
1904                         required = 1;
1905                 } else if (!strcasecmp(v->name, "noload") || !strcasecmp(v->name, "autoload")) {
1906                         continue;
1907                 } else {
1908                         ast_log(LOG_ERROR, "Unknown configuration option '%s'", v->name);
1909                         goto done;
1910                 }
1911
1912                 if (required) {
1913                         ast_debug(2, "Adding module to required list: %s (%s)\n", v->value, v->name);
1914                 }
1915
1916                 if (!add_to_load_order(v->value, load_order, required, preload, 0)) {
1917                         goto done;
1918                 }
1919         }
1920
1921         /* check if 'autoload' is on */
1922         if (ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
1923                 /* if we are allowed to load dynamic modules, scan the directory for
1924                    for all available modules and add them as well */
1925                 DIR *dir = opendir(ast_config_AST_MODULE_DIR);
1926                 struct dirent *dirent;
1927
1928                 if (dir) {
1929                         while ((dirent = readdir(dir))) {
1930                                 int ld = strlen(dirent->d_name);
1931
1932                                 /* Must end in .so to load it.  */
1933
1934                                 if (ld < 4)
1935                                         continue;
1936
1937                                 if (strcasecmp(dirent->d_name + ld - 3, ".so"))
1938                                         continue;
1939
1940                                 /* if there is already a module by this name in the module_list,
1941                                    skip this file */
1942                                 if (find_resource(dirent->d_name, 0))
1943                                         continue;
1944
1945                                 if (!add_to_load_order(dirent->d_name, load_order, 0, 0, 0)) {
1946                                         closedir(dir);
1947                                         goto done;
1948                                 }
1949                         }
1950
1951                         closedir(dir);
1952                 } else {
1953                         ast_log(LOG_ERROR, "Unable to open modules directory '%s'.\n", ast_config_AST_MODULE_DIR);
1954                         goto done;
1955                 }
1956         }
1957
1958         /* now scan the config for any modules we are prohibited from loading and
1959            remove them from the load order */
1960         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1961                 size_t baselen;
1962
1963                 if (strcasecmp(v->name, "noload")) {
1964                         continue;
1965                 }
1966
1967                 baselen = resource_name_baselen(v->value);
1968                 AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
1969                         if (!resource_name_match(v->value, baselen, order->resource)) {
1970                                 if (order->builtin) {
1971                                         ast_log(LOG_ERROR, "%s is a built-in module, you cannot specify 'noload'.\n", v->value);
1972                                         goto done;
1973                                 }
1974
1975                                 if (order->required) {
1976                                         ast_log(LOG_ERROR, "%s is configured with '%s' and 'noload', this is impossible.\n",
1977                                                 v->value, order->preload ? "preload-require" : "require");
1978                                         goto done;
1979                                 }
1980                                 AST_LIST_REMOVE_CURRENT(entry);
1981                                 ast_free(order->resource);
1982                                 ast_free(order);
1983                         }
1984                 }
1985                 AST_LIST_TRAVERSE_SAFE_END;
1986         }
1987
1988         res = 0;
1989 done:
1990         ast_config_destroy(cfg);
1991
1992         return res;
1993 }
1994
1995 int load_modules(void)
1996 {
1997         struct load_order_entry *order;
1998         unsigned int load_count;
1999         struct load_order load_order;
2000         int res = 0;
2001         int modulecount = 0;
2002
2003         ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
2004
2005         AST_LIST_HEAD_INIT_NOLOCK(&load_order);
2006         AST_DLLIST_LOCK(&module_list);
2007
2008         res = loader_builtin_init(&load_order);
2009         if (res) {
2010                 goto done;
2011         }
2012
2013         res = loader_config_init(&load_order);
2014         if (res) {
2015                 goto done;
2016         }
2017
2018         load_count = 0;
2019         AST_LIST_TRAVERSE(&load_order, order, entry)
2020                 load_count++;
2021
2022         if (load_count)
2023                 ast_log(LOG_NOTICE, "%u modules will be loaded.\n", load_count);
2024
2025         res = load_resource_list(&load_order, &modulecount);
2026
2027 done:
2028         while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
2029                 ast_free(order->resource);
2030                 ast_free(order);
2031         }
2032
2033         AST_DLLIST_UNLOCK(&module_list);
2034         return res;
2035 }
2036
2037 void ast_update_use_count(void)
2038 {
2039         /* Notify any module monitors that the use count for a
2040            resource has changed */
2041         struct loadupdate *m;
2042
2043         AST_LIST_LOCK(&updaters);
2044         AST_LIST_TRAVERSE(&updaters, m, entry)
2045                 m->updater();
2046         AST_LIST_UNLOCK(&updaters);
2047 }
2048
2049 /*!
2050  * \internal
2051  * \brief Build an alpha sorted list of modules.
2052  *
2053  * \param alpha_module_list Pointer to uninitialized module_vector.
2054  *
2055  * This function always initializes alpha_module_list.
2056  *
2057  * \pre module_list must be locked.
2058  */
2059 static int alpha_module_list_create(struct module_vector *alpha_module_list)
2060 {
2061         struct ast_module *cur;
2062
2063         if (AST_VECTOR_INIT(alpha_module_list, 32)) {
2064                 return -1;
2065         }
2066
2067         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
2068                 if (AST_VECTOR_ADD_SORTED(alpha_module_list, cur, module_vector_strcasecmp)) {
2069                         return -1;
2070                 }
2071         }
2072
2073         return 0;
2074 }
2075
2076 int ast_update_module_list(int (*modentry)(const char *module, const char *description,
2077                                            int usecnt, const char *status, const char *like,
2078                                                                                    enum ast_module_support_level support_level),
2079                            const char *like)
2080 {
2081         int total_mod_loaded = 0;
2082         struct module_vector alpha_module_list;
2083
2084         AST_DLLIST_LOCK(&module_list);
2085
2086         if (!alpha_module_list_create(&alpha_module_list)) {
2087                 int idx;
2088
2089                 for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) {
2090                         struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
2091
2092                         total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
2093                                 cur->flags.running ? "Running" : "Not Running", like, cur->info->support_level);
2094                 }
2095         }
2096
2097         AST_DLLIST_UNLOCK(&module_list);
2098         AST_VECTOR_FREE(&alpha_module_list);
2099
2100         return total_mod_loaded;
2101 }
2102
2103 int ast_update_module_list_data(int (*modentry)(const char *module, const char *description,
2104                                                 int usecnt, const char *status, const char *like,
2105                                                 enum ast_module_support_level support_level,
2106                                                 void *data),
2107                                 const char *like, void *data)
2108 {
2109         int total_mod_loaded = 0;
2110         struct module_vector alpha_module_list;
2111
2112         AST_DLLIST_LOCK(&module_list);
2113
2114         if (!alpha_module_list_create(&alpha_module_list)) {
2115                 int idx;
2116
2117                 for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) {
2118                         struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
2119
2120                         total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
2121                                 cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data);
2122                 }
2123         }
2124
2125         AST_DLLIST_UNLOCK(&module_list);
2126         AST_VECTOR_FREE(&alpha_module_list);
2127
2128         return total_mod_loaded;
2129 }
2130
2131 int ast_update_module_list_condition(int (*modentry)(const char *module, const char *description,
2132                                                      int usecnt, const char *status,
2133                                                      const char *like,
2134                                                      enum ast_module_support_level support_level,
2135                                                      void *data, const char *condition),
2136                                      const char *like, void *data, const char *condition)
2137 {
2138         int conditions_met = 0;
2139         struct module_vector alpha_module_list;
2140
2141         AST_DLLIST_LOCK(&module_list);
2142
2143         if (!alpha_module_list_create(&alpha_module_list)) {
2144                 int idx;
2145
2146                 for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) {
2147                         struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
2148
2149                         conditions_met += modentry(cur->resource, cur->info->description, cur->usecount,
2150                                 cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data,
2151                                 condition);
2152                 }
2153         }
2154
2155         AST_DLLIST_UNLOCK(&module_list);
2156         AST_VECTOR_FREE(&alpha_module_list);
2157
2158         return conditions_met;
2159 }
2160
2161 /*! \brief Check if module exists */
2162 int ast_module_check(const char *name)
2163 {
2164         struct ast_module *cur;
2165
2166         if (ast_strlen_zero(name))
2167                 return 0;       /* FALSE */
2168
2169         cur = find_resource(name, 1);
2170
2171         return (cur != NULL);
2172 }
2173
2174
2175 int ast_loader_register(int (*v)(void))
2176 {
2177         struct loadupdate *tmp;
2178
2179         if (!(tmp = ast_malloc(sizeof(*tmp))))
2180                 return -1;
2181
2182         tmp->updater = v;
2183         AST_LIST_LOCK(&updaters);
2184         AST_LIST_INSERT_HEAD(&updaters, tmp, entry);
2185         AST_LIST_UNLOCK(&updaters);
2186
2187         return 0;
2188 }
2189
2190 int ast_loader_unregister(int (*v)(void))
2191 {
2192         struct loadupdate *cur;
2193
2194         AST_LIST_LOCK(&updaters);
2195         AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) {
2196                 if (cur->updater == v)  {
2197                         AST_LIST_REMOVE_CURRENT(entry);
2198                         break;
2199                 }
2200         }
2201         AST_LIST_TRAVERSE_SAFE_END;
2202         AST_LIST_UNLOCK(&updaters);
2203
2204         return cur ? 0 : -1;
2205 }
2206
2207 struct ast_module *__ast_module_ref(struct ast_module *mod, const char *file, int line, const char *func)
2208 {
2209         if (!mod) {
2210                 return NULL;
2211         }
2212
2213         if (mod->ref_debug) {
2214                 __ao2_ref(mod->ref_debug, +1, "", file, line, func);
2215         }
2216
2217         ast_atomic_fetchadd_int(&mod->usecount, +1);
2218         ast_update_use_count();
2219
2220         return mod;
2221 }
2222
2223 struct ast_module *__ast_module_running_ref(struct ast_module *mod,
2224         const char *file, int line, const char *func)
2225 {
2226         if (!mod || !mod->flags.running) {
2227                 return NULL;
2228         }
2229
2230         return __ast_module_ref(mod, file, line, func);
2231 }
2232
2233 void __ast_module_shutdown_ref(struct ast_module *mod, const char *file, int line, const char *func)
2234 {
2235         if (!mod || mod->flags.keepuntilshutdown) {
2236                 return;
2237         }
2238
2239         __ast_module_ref(mod, file, line, func);
2240         mod->flags.keepuntilshutdown = 1;
2241 }
2242
2243 void __ast_module_unref(struct ast_module *mod, const char *file, int line, const char *func)
2244 {
2245         if (!mod) {
2246                 return;
2247         }
2248
2249         if (mod->ref_debug) {
2250                 __ao2_ref(mod->ref_debug, -1, "", file, line, func);
2251         }
2252
2253         ast_atomic_fetchadd_int(&mod->usecount, -1);
2254         ast_update_use_count();
2255 }
2256
2257 const char *support_level_map [] = {
2258         [AST_MODULE_SUPPORT_UNKNOWN] = "unknown",
2259         [AST_MODULE_SUPPORT_CORE] = "core",
2260         [AST_MODULE_SUPPORT_EXTENDED] = "extended",
2261         [AST_MODULE_SUPPORT_DEPRECATED] = "deprecated",
2262 };
2263
2264 const char *ast_module_support_level_to_string(enum ast_module_support_level support_level)
2265 {
2266         return support_level_map[support_level];
2267 }