res_rtp_asterisk.c: Fix rtp source address learning for broken clients
[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 #include <editline/readline.h>
40
41 #include "asterisk/dlinkedlists.h"
42 #include "asterisk/module.h"
43 #include "asterisk/config.h"
44 #include "asterisk/channel.h"
45 #include "asterisk/term.h"
46 #include "asterisk/acl.h"
47 #include "asterisk/manager.h"
48 #include "asterisk/cdr.h"
49 #include "asterisk/enum.h"
50 #include "asterisk/http.h"
51 #include "asterisk/lock.h"
52 #include "asterisk/features_config.h"
53 #include "asterisk/dsp.h"
54 #include "asterisk/udptl.h"
55 #include "asterisk/heap.h"
56 #include "asterisk/app.h"
57 #include "asterisk/test.h"
58 #include "asterisk/sounds_index.h"
59
60 #include <dlfcn.h>
61
62 #include "asterisk/md5.h"
63 #include "asterisk/utils.h"
64
65 /*** DOCUMENTATION
66         <managerEvent language="en_US" name="Reload">
67                 <managerEventInstance class="EVENT_FLAG_SYSTEM">
68                         <synopsis>Raised when a module has been reloaded in Asterisk.</synopsis>
69                         <syntax>
70                                 <parameter name="Module">
71                                         <para>The name of the module that was reloaded, or
72                                         <literal>All</literal> if all modules were reloaded</para>
73                                 </parameter>
74                                 <parameter name="Status">
75                                         <para>The numeric status code denoting the success or failure
76                                         of the reload request.</para>
77                                         <enumlist>
78                                                 <enum name="0"><para>Success</para></enum>
79                                                 <enum name="1"><para>Request queued</para></enum>
80                                                 <enum name="2"><para>Module not found</para></enum>
81                                                 <enum name="3"><para>Error</para></enum>
82                                                 <enum name="4"><para>Reload already in progress</para></enum>
83                                                 <enum name="5"><para>Module uninitialized</para></enum>
84                                                 <enum name="6"><para>Reload not supported</para></enum>
85                                         </enumlist>
86                                 </parameter>
87                         </syntax>
88                 </managerEventInstance>
89         </managerEvent>
90  ***/
91
92 #ifndef RTLD_NOW
93 #define RTLD_NOW 0
94 #endif
95
96 #ifndef RTLD_LOCAL
97 #define RTLD_LOCAL 0
98 #endif
99
100 struct ast_module_user {
101         struct ast_channel *chan;
102         AST_LIST_ENTRY(ast_module_user) entry;
103 };
104
105 AST_DLLIST_HEAD(module_user_list, ast_module_user);
106
107 static const unsigned char expected_key[] =
108 { 0x87, 0x76, 0x79, 0x35, 0x23, 0xea, 0x3a, 0xd3,
109   0x25, 0x2a, 0xbb, 0x35, 0x87, 0xe4, 0x22, 0x24 };
110
111 static char buildopt_sum[33] = AST_BUILDOPT_SUM;
112
113 /*!
114  * \brief Internal flag to indicate all modules have been initially loaded.
115  */
116 static int modules_loaded;
117
118 struct ast_module {
119         const struct ast_module_info *info;
120         /* Used to get module references into refs log */
121         void *ref_debug;
122         void *lib;                                      /* the shared lib, or NULL if embedded */
123         int usecount;                                   /* the number of 'users' currently in this module */
124         struct module_user_list users;                  /* the list of users in the module */
125         struct {
126                 unsigned int running:1;
127                 unsigned int declined:1;
128                 unsigned int keepuntilshutdown:1;
129         } flags;
130         AST_LIST_ENTRY(ast_module) list_entry;
131         AST_DLLIST_ENTRY(ast_module) entry;
132         char resource[0];
133 };
134
135 static AST_DLLIST_HEAD_STATIC(module_list, ast_module);
136
137 const char *ast_module_name(const struct ast_module *mod)
138 {
139         if (!mod || !mod->info) {
140                 return NULL;
141         }
142
143         return mod->info->name;
144 }
145
146 struct loadupdate {
147         int (*updater)(void);
148         AST_LIST_ENTRY(loadupdate) entry;
149 };
150
151 static AST_DLLIST_HEAD_STATIC(updaters, loadupdate);
152
153 AST_MUTEX_DEFINE_STATIC(reloadlock);
154
155 struct reload_queue_item {
156         AST_LIST_ENTRY(reload_queue_item) entry;
157         char module[0];
158 };
159
160 static int do_full_reload = 0;
161
162 static AST_DLLIST_HEAD_STATIC(reload_queue, reload_queue_item);
163
164 /* when dynamic modules are being loaded, ast_module_register() will
165    need to know what filename the module was loaded from while it
166    is being registered
167 */
168 static struct ast_module *resource_being_loaded;
169
170 /* XXX: should we check for duplicate resource names here? */
171
172 void ast_module_register(const struct ast_module_info *info)
173 {
174         struct ast_module *mod = resource_being_loaded;
175
176         ast_debug(5, "Registering module %s\n", info->name);
177
178         mod->info = info;
179         if (ast_opt_ref_debug) {
180                 mod->ref_debug = ao2_t_alloc(0, NULL, info->name);
181         }
182         AST_LIST_HEAD_INIT(&mod->users);
183
184         /* during startup, before the loader has been initialized,
185            there are no threads, so there is no need to take the lock
186            on this list to manipulate it. it is also possible that it
187            might be unsafe to use the list lock at that point... so
188            let's avoid it altogether
189         */
190         AST_DLLIST_LOCK(&module_list);
191         /* it is paramount that the new entry be placed at the tail of
192            the list, otherwise the code that uses dlopen() to load
193            dynamic modules won't be able to find out if the module it
194            just opened was registered or failed to load
195         */
196         AST_DLLIST_INSERT_TAIL(&module_list, mod, entry);
197         AST_DLLIST_UNLOCK(&module_list);
198
199         /* give the module a copy of its own handle, for later use in registrations and the like */
200         *((struct ast_module **) &(info->self)) = mod;
201 }
202
203 void ast_module_unregister(const struct ast_module_info *info)
204 {
205         struct ast_module *mod = NULL;
206
207         /* it is assumed that the users list in the module structure
208            will already be empty, or we cannot have gotten to this
209            point
210         */
211         AST_DLLIST_LOCK(&module_list);
212         AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&module_list, mod, entry) {
213                 if (mod->info == info) {
214                         AST_DLLIST_REMOVE_CURRENT(entry);
215                         break;
216                 }
217         }
218         AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
219         AST_DLLIST_UNLOCK(&module_list);
220
221         if (mod) {
222                 ast_debug(5, "Unregistering module %s\n", info->name);
223                 AST_LIST_HEAD_DESTROY(&mod->users);
224                 ao2_cleanup(mod->ref_debug);
225                 ast_free(mod);
226         }
227 }
228
229 struct ast_module_user *__ast_module_user_add(struct ast_module *mod, struct ast_channel *chan)
230 {
231         struct ast_module_user *u;
232
233         u = ast_calloc(1, sizeof(*u));
234         if (!u) {
235                 return NULL;
236         }
237
238         u->chan = chan;
239
240         AST_LIST_LOCK(&mod->users);
241         AST_LIST_INSERT_HEAD(&mod->users, u, entry);
242         AST_LIST_UNLOCK(&mod->users);
243
244         if (mod->ref_debug) {
245                 ao2_ref(mod->ref_debug, +1);
246         }
247
248         ast_atomic_fetchadd_int(&mod->usecount, +1);
249
250         ast_update_use_count();
251
252         return u;
253 }
254
255 void __ast_module_user_remove(struct ast_module *mod, struct ast_module_user *u)
256 {
257         if (!u) {
258                 return;
259         }
260
261         AST_LIST_LOCK(&mod->users);
262         u = AST_LIST_REMOVE(&mod->users, u, entry);
263         AST_LIST_UNLOCK(&mod->users);
264         if (!u) {
265                 /*
266                  * Was not in the list.  Either a bad pointer or
267                  * __ast_module_user_hangup_all() has been called.
268                  */
269                 return;
270         }
271
272         if (mod->ref_debug) {
273                 ao2_ref(mod->ref_debug, -1);
274         }
275
276         ast_atomic_fetchadd_int(&mod->usecount, -1);
277         ast_free(u);
278
279         ast_update_use_count();
280 }
281
282 void __ast_module_user_hangup_all(struct ast_module *mod)
283 {
284         struct ast_module_user *u;
285
286         AST_LIST_LOCK(&mod->users);
287         while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) {
288                 if (u->chan) {
289                         ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD);
290                 }
291
292                 if (mod->ref_debug) {
293                         ao2_ref(mod->ref_debug, -1);
294                 }
295
296                 ast_atomic_fetchadd_int(&mod->usecount, -1);
297                 ast_free(u);
298         }
299         AST_LIST_UNLOCK(&mod->users);
300
301         ast_update_use_count();
302 }
303
304 /*! \note
305  * In addition to modules, the reload command handles some extra keywords
306  * which are listed here together with the corresponding handlers.
307  * This table is also used by the command completion code.
308  */
309 static struct reload_classes {
310         const char *name;
311         int (*reload_fn)(void);
312 } reload_classes[] = {  /* list in alpha order, longest match first for cli completion */
313         { "acl",         ast_named_acl_reload },
314         { "cdr",         ast_cdr_engine_reload },
315         { "cel",         ast_cel_engine_reload },
316         { "dnsmgr",      dnsmgr_reload },
317         { "dsp",         ast_dsp_reload},
318         { "extconfig",   read_config_maps },
319         { "enum",        ast_enum_reload },
320         { "features",    ast_features_config_reload },
321         { "http",        ast_http_reload },
322         { "indications", ast_indications_reload },
323         { "logger",      logger_reload },
324         { "manager",     reload_manager },
325         { "plc",         ast_plc_reload },
326         { "sounds",      ast_sounds_reindex },
327         { "udptl",       ast_udptl_reload },
328         { NULL,          NULL }
329 };
330
331 static int printdigest(const unsigned char *d)
332 {
333         int x, pos;
334         char buf[256]; /* large enough so we don't have to worry */
335
336         for (pos = 0, x = 0; x < 16; x++)
337                 pos += sprintf(buf + pos, " %02hhx", *d++);
338
339         ast_debug(1, "Unexpected signature:%s\n", buf);
340
341         return 0;
342 }
343
344 static int key_matches(const unsigned char *key1, const unsigned char *key2)
345 {
346         int x;
347
348         for (x = 0; x < 16; x++) {
349                 if (key1[x] != key2[x])
350                         return 0;
351         }
352
353         return 1;
354 }
355
356 static int verify_key(const unsigned char *key)
357 {
358         struct MD5Context c;
359         unsigned char digest[16];
360
361         MD5Init(&c);
362         MD5Update(&c, key, strlen((char *)key));
363         MD5Final(digest, &c);
364
365         if (key_matches(expected_key, digest))
366                 return 0;
367
368         printdigest(digest);
369
370         return -1;
371 }
372
373 static int resource_name_match(const char *name1_in, const char *name2_in)
374 {
375         char *name1 = (char *) name1_in;
376         char *name2 = (char *) name2_in;
377
378         /* trim off any .so extensions */
379         if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) {
380                 name1 = ast_strdupa(name1);
381                 name1[strlen(name1) - 3] = '\0';
382         }
383         if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) {
384                 name2 = ast_strdupa(name2);
385                 name2[strlen(name2) - 3] = '\0';
386         }
387
388         return strcasecmp(name1, name2);
389 }
390
391 static struct ast_module *find_resource(const char *resource, int do_lock)
392 {
393         struct ast_module *cur;
394
395         if (do_lock) {
396                 AST_DLLIST_LOCK(&module_list);
397         }
398
399         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
400                 if (!resource_name_match(resource, cur->resource))
401                         break;
402         }
403
404         if (do_lock) {
405                 AST_DLLIST_UNLOCK(&module_list);
406         }
407
408         return cur;
409 }
410
411 /*!
412  * \brief dlclose(), with failure logging.
413  */
414 static void logged_dlclose(const char *name, void *lib)
415 {
416         char *error;
417
418         if (!lib) {
419                 return;
420         }
421
422         /* Clear any existing error */
423         dlerror();
424         if (dlclose(lib)) {
425                 error = dlerror();
426                 ast_log(AST_LOG_ERROR, "Failure in dlclose for module '%s': %s\n",
427                         S_OR(name, "unknown"), S_OR(error, "Unknown error"));
428         }
429 }
430
431 #if defined(HAVE_RTLD_NOLOAD)
432 /*!
433  * \brief Check to see if the given resource is loaded.
434  *
435  * \param resource_name Name of the resource, including .so suffix.
436  * \return False (0) if module is not loaded.
437  * \return True (non-zero) if module is loaded.
438  */
439 static int is_module_loaded(const char *resource_name)
440 {
441         char fn[PATH_MAX] = "";
442         void *lib;
443
444         snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_MODULE_DIR,
445                 resource_name);
446
447         lib = dlopen(fn, RTLD_LAZY | RTLD_NOLOAD);
448
449         if (lib) {
450                 logged_dlclose(resource_name, lib);
451                 return 1;
452         }
453
454         return 0;
455 }
456 #endif
457
458 static void unload_dynamic_module(struct ast_module *mod)
459 {
460 #if defined(HAVE_RTLD_NOLOAD)
461         char *name = ast_strdupa(ast_module_name(mod));
462 #endif
463         void *lib = mod->lib;
464
465         /* WARNING: the structure pointed to by mod is going to
466            disappear when this operation succeeds, so we can't
467            dereference it */
468         logged_dlclose(ast_module_name(mod), lib);
469
470         /* There are several situations where the module might still be resident
471          * in memory.
472          *
473          * If somehow there was another dlopen() on the same module (unlikely,
474          * since that all is supposed to happen in loader.c).
475          *
476          * Or the lazy resolution of a global symbol (very likely, since that is
477          * how we load all of our modules that export global symbols).
478          *
479          * Avoid the temptation of repeating the dlclose(). The other code that
480          * dlopened the module still has its module reference, and should close
481          * it itself. In other situations, dlclose() will happily return success
482          * for as many times as you wish to call it.
483          */
484 #if defined(HAVE_RTLD_NOLOAD)
485         if (is_module_loaded(name)) {
486                 ast_log(LOG_WARNING, "Module '%s' could not be completely unloaded\n", name);
487         }
488 #endif
489 }
490
491 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, unsigned int suppress_logging, struct ast_heap *resource_heap, int required);
492
493 #define MODULE_LOCAL_ONLY (void *)-1
494
495 static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int global_symbols_only, unsigned int suppress_logging, struct ast_heap *resource_heap)
496 {
497         char fn[PATH_MAX] = "";
498         void *lib = NULL;
499         struct ast_module *mod;
500         unsigned int wants_global;
501         int space;      /* room needed for the descriptor */
502         int missing_so = 0;
503
504         space = sizeof(*resource_being_loaded) + strlen(resource_in) + 1;
505         if (strcasecmp(resource_in + strlen(resource_in) - 3, ".so")) {
506                 missing_so = 1;
507                 space += 3;     /* room for the extra ".so" */
508         }
509
510         snprintf(fn, sizeof(fn), "%s/%s%s", ast_config_AST_MODULE_DIR, resource_in, missing_so ? ".so" : "");
511
512         /* make a first load of the module in 'quiet' mode... don't try to resolve
513            any symbols, and don't export any symbols. this will allow us to peek into
514            the module's info block (if available) to see what flags it has set */
515
516         resource_being_loaded = ast_calloc(1, space);
517         if (!resource_being_loaded)
518                 return NULL;
519         strcpy(resource_being_loaded->resource, resource_in);
520         if (missing_so)
521                 strcat(resource_being_loaded->resource, ".so");
522
523         if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_GLOBAL))) {
524                 if (!suppress_logging) {
525                         ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
526                 }
527                 ast_free(resource_being_loaded);
528                 return NULL;
529         }
530
531         /* the dlopen() succeeded, let's find out if the module
532            registered itself */
533         /* note that this will only work properly as long as
534            ast_module_register() (which is called by the module's
535            constructor) places the new module at the tail of the
536            module_list
537         */
538         if (resource_being_loaded != (mod = AST_DLLIST_LAST(&module_list))) {
539                 ast_log(LOG_WARNING, "Module '%s' did not register itself during load\n", resource_in);
540                 /* no, it did not, so close it and return */
541                 logged_dlclose(resource_in, lib);
542                 /* note that the module's destructor will call ast_module_unregister(),
543                    which will free the structure we allocated in resource_being_loaded */
544                 return NULL;
545         }
546
547         wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS);
548
549         /* if we are being asked only to load modules that provide global symbols,
550            and this one does not, then close it and return */
551         if (global_symbols_only && !wants_global) {
552                 logged_dlclose(resource_in, lib);
553                 return MODULE_LOCAL_ONLY;
554         }
555
556         logged_dlclose(resource_in, lib);
557         resource_being_loaded = NULL;
558
559         /* start the load process again */
560         resource_being_loaded = ast_calloc(1, space);
561         if (!resource_being_loaded)
562                 return NULL;
563         strcpy(resource_being_loaded->resource, resource_in);
564         if (missing_so)
565                 strcat(resource_being_loaded->resource, ".so");
566
567         if (!(lib = dlopen(fn, wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) {
568                 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
569                 ast_free(resource_being_loaded);
570                 return NULL;
571         }
572
573         /* since the module was successfully opened, and it registered itself
574            the previous time we did that, we're going to assume it worked this
575            time too :) */
576
577         AST_DLLIST_LAST(&module_list)->lib = lib;
578         resource_being_loaded = NULL;
579
580         return AST_DLLIST_LAST(&module_list);
581 }
582
583 int modules_shutdown(void)
584 {
585         struct ast_module *mod;
586         int somethingchanged = 1, final = 0;
587
588         AST_DLLIST_LOCK(&module_list);
589
590         /*!\note Some resources, like timers, are started up dynamically, and thus
591          * may be still in use, even if all channels are dead.  We must therefore
592          * check the usecount before asking modules to unload. */
593         do {
594                 if (!somethingchanged) {
595                         /*!\note If we go through the entire list without changing
596                          * anything, ignore the usecounts and unload, then exit. */
597                         final = 1;
598                 }
599
600                 /* Reset flag before traversing the list */
601                 somethingchanged = 0;
602
603                 AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&module_list, mod, entry) {
604                         if (!final && mod->usecount) {
605                                 ast_debug(1, "Passing on %s: its use count is %d\n",
606                                         mod->resource, mod->usecount);
607                                 continue;
608                         }
609                         AST_DLLIST_REMOVE_CURRENT(entry);
610                         if (mod->flags.running && !mod->flags.declined && mod->info->unload) {
611                                 ast_verb(1, "Unloading %s\n", mod->resource);
612                                 mod->info->unload();
613                         }
614                         AST_LIST_HEAD_DESTROY(&mod->users);
615                         ao2_cleanup(mod->ref_debug);
616                         ast_free(mod);
617                         somethingchanged = 1;
618                 }
619                 AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
620                 if (!somethingchanged) {
621                         AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
622                                 if (mod->flags.keepuntilshutdown) {
623                                         ast_module_unref(mod);
624                                         mod->flags.keepuntilshutdown = 0;
625                                         somethingchanged = 1;
626                                 }
627                         }
628                 }
629         } while (somethingchanged && !final);
630
631         final = AST_DLLIST_EMPTY(&module_list);
632         AST_DLLIST_UNLOCK(&module_list);
633
634         return !final;
635 }
636
637 int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force)
638 {
639         struct ast_module *mod;
640         int res = -1;
641         int error = 0;
642
643         AST_DLLIST_LOCK(&module_list);
644
645         if (!(mod = find_resource(resource_name, 0))) {
646                 AST_DLLIST_UNLOCK(&module_list);
647                 ast_log(LOG_WARNING, "Unload failed, '%s' could not be found\n", resource_name);
648                 return -1;
649         }
650
651         if (!mod->flags.running || mod->flags.declined) {
652                 ast_log(LOG_WARNING, "Unload failed, '%s' is not loaded.\n", resource_name);
653                 error = 1;
654         }
655
656         if (!error && (mod->usecount > 0)) {
657                 if (force)
658                         ast_log(LOG_WARNING, "Warning:  Forcing removal of module '%s' with use count %d\n",
659                                 resource_name, mod->usecount);
660                 else {
661                         ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name,
662                                 mod->usecount);
663                         error = 1;
664                 }
665         }
666
667         if (!error) {
668                 /* Request any channels attached to the module to hangup. */
669                 __ast_module_user_hangup_all(mod);
670
671                 ast_verb(1, "Unloading %s\n", mod->resource);
672                 res = mod->info->unload();
673                 if (res) {
674                         ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
675                         if (force <= AST_FORCE_FIRM) {
676                                 error = 1;
677                         } else {
678                                 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
679                         }
680                 }
681
682                 if (!error) {
683                         /*
684                          * Request hangup on any channels that managed to get attached
685                          * while we called the module unload function.
686                          */
687                         __ast_module_user_hangup_all(mod);
688                         sched_yield();
689                 }
690         }
691
692         if (!error)
693                 mod->flags.running = mod->flags.declined = 0;
694
695         AST_DLLIST_UNLOCK(&module_list);
696
697         if (!error) {
698                 unload_dynamic_module(mod);
699                 ast_test_suite_event_notify("MODULE_UNLOAD", "Message: %s", resource_name);
700                 ast_update_use_count();
701         }
702
703         return res;
704 }
705
706 static int module_matches_helper_type(struct ast_module *mod, enum ast_module_helper_type type)
707 {
708         switch (type) {
709         case AST_MODULE_HELPER_UNLOAD:
710                 return !mod->usecount && mod->flags.running && !mod->flags.declined;
711
712         case AST_MODULE_HELPER_RELOAD:
713                 return mod->flags.running && mod->info->reload;
714
715         case AST_MODULE_HELPER_RUNNING:
716                 return mod->flags.running;
717
718         case AST_MODULE_HELPER_LOADED:
719                 /* if we have a 'struct ast_module' then we're loaded. */
720                 return 1;
721         default:
722                 /* This function is not called for AST_MODULE_HELPER_LOAD. */
723                 /* Unknown ast_module_helper_type. Assume it doesn't match. */
724                 ast_assert(0);
725
726                 return 0;
727         }
728 }
729
730 static char *module_load_helper(const char *word, int state)
731 {
732         struct ast_module *mod;
733         int which = 0;
734         char *name;
735         char *ret = NULL;
736         char *editline_ret;
737         char fullpath[PATH_MAX];
738         int idx = 0;
739         /* This is needed to avoid listing modules that are already running. */
740         AST_VECTOR(, char *) running_modules;
741
742         AST_VECTOR_INIT(&running_modules, 200);
743
744         AST_DLLIST_LOCK(&module_list);
745         AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
746                 if (mod->flags.running) {
747                         AST_VECTOR_APPEND(&running_modules, mod->resource);
748                 }
749         }
750
751         if (word[0] == '/') {
752                 /* BUGBUG: we should not support this. */
753                 ast_copy_string(fullpath, word, sizeof(fullpath));
754         } else {
755                 snprintf(fullpath, sizeof(fullpath), "%s/%s", ast_config_AST_MODULE_DIR, word);
756         }
757
758         /*
759          * This is ugly that we keep calling filename_completion_function.
760          * The only way to avoid this would be to make a copy of the function
761          * that skips matches found in the running_modules vector.
762          */
763         while (!ret && (name = editline_ret = filename_completion_function(fullpath, idx++))) {
764                 if (word[0] != '/') {
765                         name += (strlen(ast_config_AST_MODULE_DIR) + 1);
766                 }
767
768                 /* Don't list files that are already loaded! */
769                 if (!AST_VECTOR_GET_CMP(&running_modules, name, !strcasecmp) && ++which > state) {
770                         ret = ast_strdup(name);
771                 }
772
773                 ast_std_free(editline_ret);
774         }
775
776         /* Do not clean-up the elements, they belong to module_list. */
777         AST_VECTOR_FREE(&running_modules);
778         AST_DLLIST_UNLOCK(&module_list);
779
780         return ret;
781 }
782
783 char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, enum ast_module_helper_type type)
784 {
785         struct ast_module *mod;
786         int which = 0;
787         int wordlen = strlen(word);
788         char *ret = NULL;
789
790         if (pos != rpos) {
791                 return NULL;
792         }
793
794         if (type == AST_MODULE_HELPER_LOAD) {
795                 return module_load_helper(word, state);
796         }
797
798         if (type == AST_MODULE_HELPER_RELOAD) {
799                 int idx;
800
801                 for (idx = 0; reload_classes[idx].name; idx++) {
802                         if (!strncasecmp(word, reload_classes[idx].name, wordlen) && ++which > state) {
803                                 return ast_strdup(reload_classes[idx].name);
804                         }
805                 }
806         }
807
808         AST_DLLIST_LOCK(&module_list);
809         AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
810                 if (!module_matches_helper_type(mod, type)) {
811                         continue;
812                 }
813
814                 if (!strncasecmp(word, mod->resource, wordlen) && ++which > state) {
815                         ret = ast_strdup(mod->resource);
816                         break;
817                 }
818         }
819         AST_DLLIST_UNLOCK(&module_list);
820
821         return ret;
822 }
823
824 void ast_process_pending_reloads(void)
825 {
826         struct reload_queue_item *item;
827
828         modules_loaded = 1;
829
830         AST_LIST_LOCK(&reload_queue);
831
832         if (do_full_reload) {
833                 do_full_reload = 0;
834                 AST_LIST_UNLOCK(&reload_queue);
835                 ast_log(LOG_NOTICE, "Executing deferred reload request.\n");
836                 ast_module_reload(NULL);
837                 return;
838         }
839
840         while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
841                 ast_log(LOG_NOTICE, "Executing deferred reload request for module '%s'.\n", item->module);
842                 ast_module_reload(item->module);
843                 ast_free(item);
844         }
845
846         AST_LIST_UNLOCK(&reload_queue);
847 }
848
849 static void queue_reload_request(const char *module)
850 {
851         struct reload_queue_item *item;
852
853         AST_LIST_LOCK(&reload_queue);
854
855         if (do_full_reload) {
856                 AST_LIST_UNLOCK(&reload_queue);
857                 return;
858         }
859
860         if (ast_strlen_zero(module)) {
861                 /* A full reload request (when module is NULL) wipes out any previous
862                    reload requests and causes the queue to ignore future ones */
863                 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
864                         ast_free(item);
865                 }
866                 do_full_reload = 1;
867         } else {
868                 /* No reason to add the same module twice */
869                 AST_LIST_TRAVERSE(&reload_queue, item, entry) {
870                         if (!strcasecmp(item->module, module)) {
871                                 AST_LIST_UNLOCK(&reload_queue);
872                                 return;
873                         }
874                 }
875                 item = ast_calloc(1, sizeof(*item) + strlen(module) + 1);
876                 if (!item) {
877                         ast_log(LOG_ERROR, "Failed to allocate reload queue item.\n");
878                         AST_LIST_UNLOCK(&reload_queue);
879                         return;
880                 }
881                 strcpy(item->module, module);
882                 AST_LIST_INSERT_TAIL(&reload_queue, item, entry);
883         }
884         AST_LIST_UNLOCK(&reload_queue);
885 }
886
887 /*!
888  * \since 12
889  * \internal
890  * \brief Publish a \ref stasis message regarding the reload result
891  */
892 static void publish_reload_message(const char *name, enum ast_module_reload_result result)
893 {
894         RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
895         RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
896         RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
897         RAII_VAR(struct ast_json *, event_object, NULL, ast_json_unref);
898         char res_buffer[8];
899
900         if (!ast_manager_get_generic_type()) {
901                 return;
902         }
903
904         snprintf(res_buffer, sizeof(res_buffer), "%u", result);
905         event_object = ast_json_pack("{s: s, s: s}",
906                         "Module", S_OR(name, "All"),
907                         "Status", res_buffer);
908         json_object = ast_json_pack("{s: s, s: i, s: o}",
909                         "type", "Reload",
910                         "class_type", EVENT_FLAG_SYSTEM,
911                         "event", ast_json_ref(event_object));
912
913         if (!json_object) {
914                 return;
915         }
916
917         payload = ast_json_payload_create(json_object);
918         if (!payload) {
919                 return;
920         }
921
922         message = stasis_message_create(ast_manager_get_generic_type(), payload);
923         if (!message) {
924                 return;
925         }
926
927         stasis_publish(ast_manager_get_topic(), message);
928 }
929
930 enum ast_module_reload_result ast_module_reload(const char *name)
931 {
932         struct ast_module *cur;
933         enum ast_module_reload_result res = AST_MODULE_RELOAD_NOT_FOUND;
934         int i;
935
936         /* If we aren't fully booted, we just pretend we reloaded but we queue this
937            up to run once we are booted up. */
938         if (!modules_loaded) {
939                 queue_reload_request(name);
940                 res = AST_MODULE_RELOAD_QUEUED;
941                 goto module_reload_exit;
942         }
943
944         if (ast_mutex_trylock(&reloadlock)) {
945                 ast_verb(3, "The previous reload command didn't finish yet\n");
946                 res = AST_MODULE_RELOAD_IN_PROGRESS;
947                 goto module_reload_exit;
948         }
949         ast_sd_notify("RELOAD=1");
950         ast_lastreloadtime = ast_tvnow();
951
952         if (ast_opt_lock_confdir) {
953                 int try;
954                 int res;
955                 for (try = 1, res = AST_LOCK_TIMEOUT; try < 6 && (res == AST_LOCK_TIMEOUT); try++) {
956                         res = ast_lock_path(ast_config_AST_CONFIG_DIR);
957                         if (res == AST_LOCK_TIMEOUT) {
958                                 ast_log(LOG_WARNING, "Failed to grab lock on %s, try %d\n", ast_config_AST_CONFIG_DIR, try);
959                         }
960                 }
961                 if (res != AST_LOCK_SUCCESS) {
962                         ast_log(AST_LOG_WARNING, "Cannot grab lock on %s\n", ast_config_AST_CONFIG_DIR);
963                         res = AST_MODULE_RELOAD_ERROR;
964                         goto module_reload_done;
965                 }
966         }
967
968         /* Call "predefined" reload here first */
969         for (i = 0; reload_classes[i].name; i++) {
970                 if (!name || !strcasecmp(name, reload_classes[i].name)) {
971                         if (reload_classes[i].reload_fn() == AST_MODULE_LOAD_SUCCESS) {
972                                 res = AST_MODULE_RELOAD_SUCCESS;
973                         }
974                 }
975         }
976
977         if (name && res == AST_MODULE_RELOAD_SUCCESS) {
978                 if (ast_opt_lock_confdir) {
979                         ast_unlock_path(ast_config_AST_CONFIG_DIR);
980                 }
981                 goto module_reload_done;
982         }
983
984         AST_DLLIST_LOCK(&module_list);
985         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
986                 const struct ast_module_info *info = cur->info;
987
988                 if (name && resource_name_match(name, cur->resource))
989                         continue;
990
991                 if (!cur->flags.running || cur->flags.declined) {
992                         if (res == AST_MODULE_RELOAD_NOT_FOUND) {
993                                 res = AST_MODULE_RELOAD_UNINITIALIZED;
994                         }
995                         if (!name) {
996                                 continue;
997                         }
998                         break;
999                 }
1000
1001                 if (!info->reload) {    /* cannot be reloaded */
1002                         if (res == AST_MODULE_RELOAD_NOT_FOUND) {
1003                                 res = AST_MODULE_RELOAD_NOT_IMPLEMENTED;
1004                         }
1005                         if (!name) {
1006                                 continue;
1007                         }
1008                         break;
1009                 }
1010                 ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description);
1011                 if (info->reload() == AST_MODULE_LOAD_SUCCESS) {
1012                         res = AST_MODULE_RELOAD_SUCCESS;
1013                 }
1014                 if (name) {
1015                         break;
1016                 }
1017         }
1018         AST_DLLIST_UNLOCK(&module_list);
1019
1020         if (ast_opt_lock_confdir) {
1021                 ast_unlock_path(ast_config_AST_CONFIG_DIR);
1022         }
1023 module_reload_done:
1024         ast_mutex_unlock(&reloadlock);
1025         ast_sd_notify("READY=1");
1026
1027 module_reload_exit:
1028         publish_reload_message(name, res);
1029         return res;
1030 }
1031
1032 static unsigned int inspect_module(const struct ast_module *mod)
1033 {
1034         if (!mod->info->description) {
1035                 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource);
1036                 return 1;
1037         }
1038
1039         if (!mod->info->key) {
1040                 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource);
1041                 return 1;
1042         }
1043
1044         if (verify_key((unsigned char *) mod->info->key)) {
1045                 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource);
1046                 return 1;
1047         }
1048
1049         if (!ast_strlen_zero(mod->info->buildopt_sum) &&
1050             strcmp(buildopt_sum, mod->info->buildopt_sum)) {
1051                 ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource);
1052                 ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource);
1053                 return 1;
1054         }
1055
1056         return 0;
1057 }
1058
1059 static enum ast_module_load_result start_resource(struct ast_module *mod)
1060 {
1061         char tmp[256];
1062         enum ast_module_load_result res;
1063
1064         if (mod->flags.running) {
1065                 return AST_MODULE_LOAD_SUCCESS;
1066         }
1067
1068         if (!mod->info->load) {
1069                 return AST_MODULE_LOAD_FAILURE;
1070         }
1071
1072         if (!ast_fully_booted) {
1073                 ast_verb(1, "Loading %s.\n", mod->resource);
1074         }
1075         res = mod->info->load();
1076
1077         switch (res) {
1078         case AST_MODULE_LOAD_SUCCESS:
1079                 if (!ast_fully_booted) {
1080                         ast_verb(2, "%s => (%s)\n", mod->resource, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
1081                 } else {
1082                         ast_verb(1, "Loaded %s => (%s)\n", mod->resource, mod->info->description);
1083                 }
1084
1085                 mod->flags.running = 1;
1086
1087                 ast_update_use_count();
1088                 break;
1089         case AST_MODULE_LOAD_DECLINE:
1090                 mod->flags.declined = 1;
1091                 break;
1092         case AST_MODULE_LOAD_FAILURE:
1093         case AST_MODULE_LOAD_SKIP: /* modules should never return this value */
1094         case AST_MODULE_LOAD_PRIORITY:
1095                 break;
1096         }
1097
1098         /* Make sure the newly started module is at the end of the list */
1099         AST_DLLIST_LOCK(&module_list);
1100         AST_DLLIST_REMOVE(&module_list, mod, entry);
1101         AST_DLLIST_INSERT_TAIL(&module_list, mod, entry);
1102         AST_DLLIST_UNLOCK(&module_list);
1103
1104         return res;
1105 }
1106
1107 /*! loads a resource based upon resource_name. If global_symbols_only is set
1108  *  only modules with global symbols will be loaded.
1109  *
1110  *  If the ast_heap is provided (not NULL) the module is found and added to the
1111  *  heap without running the module's load() function.  By doing this, modules
1112  *  added to the resource_heap can be initialized later in order by priority.
1113  *
1114  *  If the ast_heap is not provided, the module's load function will be executed
1115  *  immediately */
1116 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, unsigned int suppress_logging, struct ast_heap *resource_heap, int required)
1117 {
1118         struct ast_module *mod;
1119         enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
1120
1121         if ((mod = find_resource(resource_name, 0))) {
1122                 if (mod->flags.running) {
1123                         ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name);
1124                         return AST_MODULE_LOAD_DECLINE;
1125                 }
1126                 if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS))
1127                         return AST_MODULE_LOAD_SKIP;
1128         } else {
1129                 mod = load_dynamic_module(resource_name, global_symbols_only, suppress_logging, resource_heap);
1130                 if (mod == MODULE_LOCAL_ONLY) {
1131                                 return AST_MODULE_LOAD_SKIP;
1132                 }
1133                 if (!mod) {
1134                         if (!global_symbols_only) {
1135                                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
1136                         }
1137                         return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
1138                 }
1139         }
1140
1141         if (inspect_module(mod)) {
1142                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
1143                 unload_dynamic_module(mod);
1144                 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
1145         }
1146
1147         mod->flags.declined = 0;
1148
1149         if (resource_heap) {
1150                 ast_heap_push(resource_heap, mod);
1151                 res = AST_MODULE_LOAD_PRIORITY;
1152         } else {
1153                 res = start_resource(mod);
1154         }
1155
1156         return res;
1157 }
1158
1159 int ast_load_resource(const char *resource_name)
1160 {
1161         int res;
1162         AST_DLLIST_LOCK(&module_list);
1163         res = load_resource(resource_name, 0, 0, NULL, 0);
1164         if (!res) {
1165                 ast_test_suite_event_notify("MODULE_LOAD", "Message: %s", resource_name);
1166         }
1167         AST_DLLIST_UNLOCK(&module_list);
1168
1169         return res;
1170 }
1171
1172 struct load_order_entry {
1173         char *resource;
1174         int required;
1175         AST_LIST_ENTRY(load_order_entry) entry;
1176 };
1177
1178 AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
1179
1180 static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order, int required)
1181 {
1182         struct load_order_entry *order;
1183
1184         AST_LIST_TRAVERSE(load_order, order, entry) {
1185                 if (!resource_name_match(order->resource, resource)) {
1186                         /* Make sure we have the proper setting for the required field
1187                            (we might have both load= and required= lines in modules.conf) */
1188                         order->required |= required;
1189                         return NULL;
1190                 }
1191         }
1192
1193         if (!(order = ast_calloc(1, sizeof(*order))))
1194                 return NULL;
1195
1196         order->resource = ast_strdup(resource);
1197         order->required = required;
1198         AST_LIST_INSERT_TAIL(load_order, order, entry);
1199
1200         return order;
1201 }
1202
1203 static int mod_load_cmp(void *a, void *b)
1204 {
1205         struct ast_module *a_mod = (struct ast_module *) a;
1206         struct ast_module *b_mod = (struct ast_module *) b;
1207         /* if load_pri is not set, default is 128.  Lower is better */
1208         int a_pri = ast_test_flag(a_mod->info, AST_MODFLAG_LOAD_ORDER) ? a_mod->info->load_pri : 128;
1209         int b_pri = ast_test_flag(b_mod->info, AST_MODFLAG_LOAD_ORDER) ? b_mod->info->load_pri : 128;
1210
1211         /*
1212          * Returns comparison values for a min-heap
1213          * <0 a_pri > b_pri
1214          * =0 a_pri == b_pri
1215          * >0 a_pri < b_pri
1216          */
1217         return b_pri - a_pri;
1218 }
1219
1220 AST_LIST_HEAD_NOLOCK(load_retries, load_order_entry);
1221
1222 /*! loads modules in order by load_pri, updates mod_count
1223         \return -1 on failure to load module, -2 on failure to load required module, otherwise 0
1224 */
1225 static int load_resource_list(struct load_order *load_order, unsigned int global_symbols, int *mod_count)
1226 {
1227         struct ast_heap *resource_heap;
1228         struct load_order_entry *order;
1229         struct ast_module *mod;
1230         struct load_retries load_retries;
1231         int count = 0;
1232         int res = 0;
1233         int i = 0;
1234 #define LOAD_RETRIES 4
1235
1236         AST_LIST_HEAD_INIT_NOLOCK(&load_retries);
1237
1238         if(!(resource_heap = ast_heap_create(8, mod_load_cmp, -1))) {
1239                 return -1;
1240         }
1241
1242         /* first, add find and add modules to heap */
1243         AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
1244                 enum ast_module_load_result lres;
1245
1246                 /* Suppress log messages unless this is the last pass */
1247                 lres = load_resource(order->resource, global_symbols, 1, resource_heap, order->required);
1248                 ast_debug(3, "PASS 0: %-46s %d %d\n", order->resource, lres, global_symbols);
1249                 switch (lres) {
1250                 case AST_MODULE_LOAD_SUCCESS:
1251                         /* We're supplying a heap so SUCCESS isn't possible but we still have to test for it. */
1252                         break;
1253                 case AST_MODULE_LOAD_FAILURE:
1254                 case AST_MODULE_LOAD_DECLINE:
1255                         /*
1256                          * DECLINE or FAILURE means there was an issue with dlopen or module_register
1257                          * which might be retryable.  LOAD_FAILURE only happens for required modules
1258                          * but we're still going to retry.  We need to remove the entry from the
1259                          * load_order list and add it to the load_retries list.
1260                          */
1261                         AST_LIST_REMOVE_CURRENT(entry);
1262                         AST_LIST_INSERT_TAIL(&load_retries, order, entry);
1263                         break;
1264                 case AST_MODULE_LOAD_SKIP:
1265                         /*
1266                          * SKIP means that dlopen worked but global_symbols was set and this module doesn't qualify.
1267                          * Leave it in load_order for the next call of load_resource_list.
1268                          */
1269                         break;
1270                 case AST_MODULE_LOAD_PRIORITY:
1271                         /* load_resource worked and the module was added to the priority heap */
1272                         AST_LIST_REMOVE_CURRENT(entry);
1273                         ast_free(order->resource);
1274                         ast_free(order);
1275                         break;
1276                 }
1277         }
1278         AST_LIST_TRAVERSE_SAFE_END;
1279
1280         /* Retry the failures until the list is empty or we reach LOAD_RETRIES */
1281         for (i = 0; !AST_LIST_EMPTY(&load_retries) && i < LOAD_RETRIES; i++) {
1282                 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_retries, order, entry) {
1283                         enum ast_module_load_result lres;
1284
1285                         /* Suppress log messages unless this is the last pass */
1286                         lres = load_resource(order->resource, global_symbols, (i < LOAD_RETRIES - 1), resource_heap, order->required);
1287                         ast_debug(3, "PASS %d %-46s %d %d\n", i + 1, order->resource, lres, global_symbols);
1288                         switch (lres) {
1289                         /* These are all retryable. */
1290                         case AST_MODULE_LOAD_SUCCESS:
1291                         case AST_MODULE_LOAD_DECLINE:
1292                                 break;
1293                         case AST_MODULE_LOAD_FAILURE:
1294                                 /* LOAD_FAILURE only happens for required modules */
1295                                 if (i == LOAD_RETRIES - 1) {
1296                                         /* This was the last chance to load a required module*/
1297                                         ast_log(LOG_ERROR, "*** Failed to load module %s - Required\n", order->resource);
1298                                         fprintf(stderr, "*** Failed to load module %s - Required\n", order->resource);
1299                                         res =  -2;
1300                                         goto done;
1301                                 }
1302                                 break;;
1303                         case AST_MODULE_LOAD_SKIP:
1304                                 /*
1305                                  * SKIP means that dlopen worked but global_symbols was set and this module
1306                                  * doesn't qualify.  Put it back in load_order for the next call of
1307                                  * load_resource_list.
1308                                  */
1309                                 AST_LIST_REMOVE_CURRENT(entry);
1310                                 AST_LIST_INSERT_TAIL(load_order, order, entry);
1311                                 break;
1312                         case AST_MODULE_LOAD_PRIORITY:
1313                                 /* load_resource worked and the module was added to the priority heap */
1314                                 AST_LIST_REMOVE_CURRENT(entry);
1315                                 ast_free(order->resource);
1316                                 ast_free(order);
1317                                 break;
1318                         }
1319                 }
1320                 AST_LIST_TRAVERSE_SAFE_END;
1321         }
1322
1323         /* second remove modules from heap sorted by priority */
1324         while ((mod = ast_heap_pop(resource_heap))) {
1325                 enum ast_module_load_result lres;
1326
1327                 lres = start_resource(mod);
1328                 ast_debug(3, "START: %-46s %d %d\n", mod->resource, lres, global_symbols);
1329                 switch (lres) {
1330                 case AST_MODULE_LOAD_SUCCESS:
1331                         count++;
1332                 case AST_MODULE_LOAD_DECLINE:
1333                         break;
1334                 case AST_MODULE_LOAD_FAILURE:
1335                         ast_log(LOG_ERROR, "*** Failed to load module %s\n", mod->resource);
1336                         res = -1;
1337                         goto done;
1338                 case AST_MODULE_LOAD_SKIP:
1339                 case AST_MODULE_LOAD_PRIORITY:
1340                         break;
1341                 }
1342         }
1343
1344 done:
1345
1346         while ((order = AST_LIST_REMOVE_HEAD(&load_retries, entry))) {
1347                 ast_free(order->resource);
1348                 ast_free(order);
1349         }
1350
1351         if (mod_count) {
1352                 *mod_count += count;
1353         }
1354         ast_heap_destroy(resource_heap);
1355
1356         return res;
1357 }
1358
1359 int load_modules(unsigned int preload_only)
1360 {
1361         struct ast_config *cfg;
1362         struct load_order_entry *order;
1363         struct ast_variable *v;
1364         unsigned int load_count;
1365         struct load_order load_order;
1366         int res = 0;
1367         struct ast_flags config_flags = { 0 };
1368         int modulecount = 0;
1369         struct dirent *dirent;
1370         DIR *dir;
1371
1372         ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
1373
1374         AST_LIST_HEAD_INIT_NOLOCK(&load_order);
1375
1376         AST_DLLIST_LOCK(&module_list);
1377
1378         cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags);
1379         if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
1380                 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
1381                 goto done;
1382         }
1383
1384         /* first, find all the modules we have been explicitly requested to load */
1385         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1386                 if (!strcasecmp(v->name, preload_only ? "preload" : "load")) {
1387                         add_to_load_order(v->value, &load_order, 0);
1388                 }
1389                 if (!strcasecmp(v->name, preload_only ? "preload-require" : "require")) {
1390                         /* Add the module to the list and make sure it's required */
1391                         add_to_load_order(v->value, &load_order, 1);
1392                         ast_debug(2, "Adding module to required list: %s (%s)\n", v->value, v->name);
1393                 }
1394
1395         }
1396
1397         /* check if 'autoload' is on */
1398         if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
1399                 /* if we are allowed to load dynamic modules, scan the directory for
1400                    for all available modules and add them as well */
1401                 if ((dir = opendir(ast_config_AST_MODULE_DIR))) {
1402                         while ((dirent = readdir(dir))) {
1403                                 int ld = strlen(dirent->d_name);
1404
1405                                 /* Must end in .so to load it.  */
1406
1407                                 if (ld < 4)
1408                                         continue;
1409
1410                                 if (strcasecmp(dirent->d_name + ld - 3, ".so"))
1411                                         continue;
1412
1413                                 /* if there is already a module by this name in the module_list,
1414                                    skip this file */
1415                                 if (find_resource(dirent->d_name, 0))
1416                                         continue;
1417
1418                                 add_to_load_order(dirent->d_name, &load_order, 0);
1419                         }
1420
1421                         closedir(dir);
1422                 } else {
1423                         if (!ast_opt_quiet)
1424                                 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",
1425                                         ast_config_AST_MODULE_DIR);
1426                 }
1427         }
1428
1429         /* now scan the config for any modules we are prohibited from loading and
1430            remove them from the load order */
1431         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1432                 if (strcasecmp(v->name, "noload"))
1433                         continue;
1434
1435                 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
1436                         if (!resource_name_match(order->resource, v->value)) {
1437                                 AST_LIST_REMOVE_CURRENT(entry);
1438                                 ast_free(order->resource);
1439                                 ast_free(order);
1440                         }
1441                 }
1442                 AST_LIST_TRAVERSE_SAFE_END;
1443         }
1444
1445         /* we are done with the config now, all the information we need is in the
1446            load_order list */
1447         ast_config_destroy(cfg);
1448
1449         load_count = 0;
1450         AST_LIST_TRAVERSE(&load_order, order, entry)
1451                 load_count++;
1452
1453         if (load_count)
1454                 ast_log(LOG_NOTICE, "%u modules will be loaded.\n", load_count);
1455
1456         /* first, load only modules that provide global symbols */
1457         if ((res = load_resource_list(&load_order, 1, &modulecount)) < 0) {
1458                 goto done;
1459         }
1460
1461         /* now load everything else */
1462         if ((res = load_resource_list(&load_order, 0, &modulecount)) < 0) {
1463                 goto done;
1464         }
1465
1466 done:
1467         while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
1468                 ast_free(order->resource);
1469                 ast_free(order);
1470         }
1471
1472         AST_DLLIST_UNLOCK(&module_list);
1473         return res;
1474 }
1475
1476 void ast_update_use_count(void)
1477 {
1478         /* Notify any module monitors that the use count for a
1479            resource has changed */
1480         struct loadupdate *m;
1481
1482         AST_LIST_LOCK(&updaters);
1483         AST_LIST_TRAVERSE(&updaters, m, entry)
1484                 m->updater();
1485         AST_LIST_UNLOCK(&updaters);
1486 }
1487
1488 int ast_update_module_list(int (*modentry)(const char *module, const char *description,
1489                                            int usecnt, const char *status, const char *like,
1490                                                                                    enum ast_module_support_level support_level),
1491                            const char *like)
1492 {
1493         struct ast_module *cur;
1494         int unlock = -1;
1495         int total_mod_loaded = 0;
1496         AST_LIST_HEAD_NOLOCK(, ast_module) alpha_module_list = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
1497
1498         if (AST_DLLIST_TRYLOCK(&module_list)) {
1499                 unlock = 0;
1500         }
1501
1502         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
1503                 AST_LIST_INSERT_SORTALPHA(&alpha_module_list, cur, list_entry, resource);
1504         }
1505
1506         while ((cur = AST_LIST_REMOVE_HEAD(&alpha_module_list, list_entry))) {
1507                 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
1508                                                 cur->flags.running ? "Running" : "Not Running", like, cur->info->support_level);
1509         }
1510
1511         if (unlock) {
1512                 AST_DLLIST_UNLOCK(&module_list);
1513         }
1514
1515         return total_mod_loaded;
1516 }
1517
1518 int ast_update_module_list_data(int (*modentry)(const char *module, const char *description,
1519                                                 int usecnt, const char *status, const char *like,
1520                                                 enum ast_module_support_level support_level,
1521                                                 void *data),
1522                                 const char *like, void *data)
1523 {
1524         struct ast_module *cur;
1525         int total_mod_loaded = 0;
1526         AST_LIST_HEAD_NOLOCK(, ast_module) alpha_module_list = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
1527
1528         AST_DLLIST_LOCK(&module_list);
1529
1530         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
1531                 AST_LIST_INSERT_SORTALPHA(&alpha_module_list, cur, list_entry, resource);
1532         }
1533
1534         while ((cur = AST_LIST_REMOVE_HEAD(&alpha_module_list, list_entry))) {
1535                 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
1536                         cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data);
1537         }
1538
1539         AST_DLLIST_UNLOCK(&module_list);
1540
1541         return total_mod_loaded;
1542 }
1543
1544 int ast_update_module_list_condition(int (*modentry)(const char *module, const char *description,
1545                                                      int usecnt, const char *status,
1546                                                      const char *like,
1547                                                      enum ast_module_support_level support_level,
1548                                                      void *data, const char *condition),
1549                                      const char *like, void *data, const char *condition)
1550 {
1551         struct ast_module *cur;
1552         int conditions_met = 0;
1553         AST_LIST_HEAD_NOLOCK(, ast_module) alpha_module_list = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
1554
1555         AST_DLLIST_LOCK(&module_list);
1556
1557         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
1558                 AST_LIST_INSERT_SORTALPHA(&alpha_module_list, cur, list_entry, resource);
1559         }
1560
1561         while ((cur = AST_LIST_REMOVE_HEAD(&alpha_module_list, list_entry))) {
1562                 conditions_met += modentry(cur->resource, cur->info->description, cur->usecount,
1563                         cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data,
1564                         condition);
1565         }
1566
1567         AST_DLLIST_UNLOCK(&module_list);
1568
1569         return conditions_met;
1570 }
1571
1572 /*! \brief Check if module exists */
1573 int ast_module_check(const char *name)
1574 {
1575         struct ast_module *cur;
1576
1577         if (ast_strlen_zero(name))
1578                 return 0;       /* FALSE */
1579
1580         cur = find_resource(name, 1);
1581
1582         return (cur != NULL);
1583 }
1584
1585
1586 int ast_loader_register(int (*v)(void))
1587 {
1588         struct loadupdate *tmp;
1589
1590         if (!(tmp = ast_malloc(sizeof(*tmp))))
1591                 return -1;
1592
1593         tmp->updater = v;
1594         AST_LIST_LOCK(&updaters);
1595         AST_LIST_INSERT_HEAD(&updaters, tmp, entry);
1596         AST_LIST_UNLOCK(&updaters);
1597
1598         return 0;
1599 }
1600
1601 int ast_loader_unregister(int (*v)(void))
1602 {
1603         struct loadupdate *cur;
1604
1605         AST_LIST_LOCK(&updaters);
1606         AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) {
1607                 if (cur->updater == v)  {
1608                         AST_LIST_REMOVE_CURRENT(entry);
1609                         break;
1610                 }
1611         }
1612         AST_LIST_TRAVERSE_SAFE_END;
1613         AST_LIST_UNLOCK(&updaters);
1614
1615         return cur ? 0 : -1;
1616 }
1617
1618 struct ast_module *__ast_module_ref(struct ast_module *mod, const char *file, int line, const char *func)
1619 {
1620         if (!mod) {
1621                 return NULL;
1622         }
1623
1624         if (mod->ref_debug) {
1625                 __ao2_ref(mod->ref_debug, +1, "", file, line, func);
1626         }
1627
1628         ast_atomic_fetchadd_int(&mod->usecount, +1);
1629         ast_update_use_count();
1630
1631         return mod;
1632 }
1633
1634 void __ast_module_shutdown_ref(struct ast_module *mod, const char *file, int line, const char *func)
1635 {
1636         if (!mod || mod->flags.keepuntilshutdown) {
1637                 return;
1638         }
1639
1640         __ast_module_ref(mod, file, line, func);
1641         mod->flags.keepuntilshutdown = 1;
1642 }
1643
1644 void __ast_module_unref(struct ast_module *mod, const char *file, int line, const char *func)
1645 {
1646         if (!mod) {
1647                 return;
1648         }
1649
1650         if (mod->ref_debug) {
1651                 __ao2_ref(mod->ref_debug, -1, "", file, line, func);
1652         }
1653
1654         ast_atomic_fetchadd_int(&mod->usecount, -1);
1655         ast_update_use_count();
1656 }
1657
1658 const char *support_level_map [] = {
1659         [AST_MODULE_SUPPORT_UNKNOWN] = "unknown",
1660         [AST_MODULE_SUPPORT_CORE] = "core",
1661         [AST_MODULE_SUPPORT_EXTENDED] = "extended",
1662         [AST_MODULE_SUPPORT_DEPRECATED] = "deprecated",
1663 };
1664
1665 const char *ast_module_support_level_to_string(enum ast_module_support_level support_level)
1666 {
1667         return support_level_map[support_level];
1668 }