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