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