02fb8a905dad92db9171b8869b5bb50d627e18fc
[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         { NULL,         NULL }
255 };
256
257 static int printdigest(const unsigned char *d)
258 {
259         int x, pos;
260         char buf[256]; /* large enough so we don't have to worry */
261
262         for (pos = 0, x = 0; x < 16; x++)
263                 pos += sprintf(buf + pos, " %02x", *d++);
264
265         ast_debug(1, "Unexpected signature:%s\n", buf);
266
267         return 0;
268 }
269
270 static int key_matches(const unsigned char *key1, const unsigned char *key2)
271 {
272         int x;
273
274         for (x = 0; x < 16; x++) {
275                 if (key1[x] != key2[x])
276                         return 0;
277         }
278
279         return 1;
280 }
281
282 static int verify_key(const unsigned char *key)
283 {
284         struct MD5Context c;
285         unsigned char digest[16];
286
287         MD5Init(&c);
288         MD5Update(&c, key, strlen((char *)key));
289         MD5Final(digest, &c);
290
291         if (key_matches(expected_key, digest))
292                 return 0;
293
294         printdigest(digest);
295
296         return -1;
297 }
298
299 static int resource_name_match(const char *name1_in, const char *name2_in)
300 {
301         char *name1 = (char *) name1_in;
302         char *name2 = (char *) name2_in;
303
304         /* trim off any .so extensions */
305         if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) {
306                 name1 = ast_strdupa(name1);
307                 name1[strlen(name1) - 3] = '\0';
308         }
309         if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) {
310                 name2 = ast_strdupa(name2);
311                 name2[strlen(name2) - 3] = '\0';
312         }
313
314         return strcasecmp(name1, name2);
315 }
316
317 static struct ast_module *find_resource(const char *resource, int do_lock)
318 {
319         struct ast_module *cur;
320
321         if (do_lock)
322                 AST_LIST_LOCK(&module_list);
323
324         AST_LIST_TRAVERSE(&module_list, cur, entry) {
325                 if (!resource_name_match(resource, cur->resource))
326                         break;
327         }
328
329         if (do_lock)
330                 AST_LIST_UNLOCK(&module_list);
331
332         return cur;
333 }
334
335 #ifdef LOADABLE_MODULES
336 static void unload_dynamic_module(struct ast_module *mod)
337 {
338         void *lib = mod->lib;
339
340         /* WARNING: the structure pointed to by mod is going to
341            disappear when this operation succeeds, so we can't
342            dereference it */
343
344         if (lib)
345                 while (!dlclose(lib));
346 }
347
348 static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int global_symbols_only)
349 {
350         char fn[256] = "";
351         void *lib = NULL;
352         struct ast_module *mod;
353         char *resource = (char *) resource_in;
354         unsigned int wants_global;
355
356         if (strcasecmp(resource + strlen(resource) - 3, ".so")) {
357                 resource = alloca(strlen(resource_in) + 3);
358                 strcpy(resource, resource_in);
359                 strcat(resource, ".so");
360         }
361
362         snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_MODULE_DIR, resource);
363
364         /* make a first load of the module in 'quiet' mode... don't try to resolve
365            any symbols, and don't export any symbols. this will allow us to peek into
366            the module's info block (if available) to see what flags it has set */
367
368         if (!(resource_being_loaded = ast_calloc(1, sizeof(*resource_being_loaded) + strlen(resource) + 1)))
369                 return NULL;
370
371         strcpy(resource_being_loaded->resource, resource);
372
373         if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_LOCAL))) {
374                 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
375                 ast_free(resource_being_loaded);
376                 return NULL;
377         }
378
379         /* the dlopen() succeeded, let's find out if the module
380            registered itself */
381         /* note that this will only work properly as long as
382            ast_module_register() (which is called by the module's
383            constructor) places the new module at the tail of the
384            module_list
385         */
386         if (resource_being_loaded != (mod = AST_LIST_LAST(&module_list))) {
387                 ast_log(LOG_WARNING, "Module '%s' did not register itself during load\n", resource_in);
388                 /* no, it did not, so close it and return */
389                 while (!dlclose(lib));
390                 /* note that the module's destructor will call ast_module_unregister(),
391                    which will free the structure we allocated in resource_being_loaded */
392                 return NULL;
393         }
394
395         wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS);
396
397         /* if we are being asked only to load modules that provide global symbols,
398            and this one does not, then close it and return */
399         if (global_symbols_only && !wants_global) {
400                 while (!dlclose(lib));
401                 return NULL;
402         }
403
404         /* if the system supports RTLD_NOLOAD, we can just 'promote' the flags
405            on the already-opened library to what we want... if not, we have to
406            close it and start over
407         */
408 #if defined(HAVE_RTLD_NOLOAD) && !defined(__Darwin__)
409         if (!dlopen(fn, RTLD_NOLOAD | (wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) {
410                 ast_log(LOG_WARNING, "Unable to promote flags on module '%s': %s\n", resource_in, dlerror());
411                 while (!dlclose(lib));
412                 ast_free(resource_being_loaded);
413                 return NULL;
414         }
415 #else
416         while (!dlclose(lib));
417         resource_being_loaded = NULL;
418
419         /* start the load process again */
420
421         if (!(resource_being_loaded = ast_calloc(1, sizeof(*resource_being_loaded) + strlen(resource) + 1)))
422                 return NULL;
423
424         strcpy(resource_being_loaded->resource, resource);
425
426         if (!(lib = dlopen(fn, wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) {
427                 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
428                 ast_free(resource_being_loaded);
429                 return NULL;
430         }
431
432         /* since the module was successfully opened, and it registered itself
433            the previous time we did that, we're going to assume it worked this
434            time too :) */
435 #endif
436
437         AST_LIST_LAST(&module_list)->lib = lib;
438         resource_being_loaded = NULL;
439
440         return AST_LIST_LAST(&module_list);
441 }
442 #endif
443
444 void ast_module_shutdown(void)
445 {
446         struct ast_module *mod;
447         AST_LIST_HEAD_NOLOCK_STATIC(local_module_list, ast_module);
448
449         /* We have to call the unload() callbacks in reverse order that the modules
450          * exist in the module list so it is the reverse order of how they were
451          * loaded. */
452
453         AST_LIST_LOCK(&module_list);
454         while ((mod = AST_LIST_REMOVE_HEAD(&module_list, entry)))
455                 AST_LIST_INSERT_HEAD(&local_module_list, mod, entry);
456         AST_LIST_UNLOCK(&module_list);
457
458         while ((mod = AST_LIST_REMOVE_HEAD(&local_module_list, entry))) {
459                 if (mod->info->unload)
460                         mod->info->unload();
461                 /* Since this should only be called when shutting down "gracefully",
462                  * all channels should be down before we get to this point, meaning
463                  * there will be no module users left. */
464                 AST_LIST_HEAD_DESTROY(&mod->users);
465                 free(mod);
466         }
467 }
468
469 int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force)
470 {
471         struct ast_module *mod;
472         int res = -1;
473         int error = 0;
474
475         AST_LIST_LOCK(&module_list);
476
477         if (!(mod = find_resource(resource_name, 0))) {
478                 AST_LIST_UNLOCK(&module_list);
479                 return 0;
480         }
481
482         if (!(mod->flags.running || mod->flags.declined))
483                 error = 1;
484
485         if (!error && (mod->usecount > 0)) {
486                 if (force)
487                         ast_log(LOG_WARNING, "Warning:  Forcing removal of module '%s' with use count %d\n",
488                                 resource_name, mod->usecount);
489                 else {
490                         ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name,
491                                 mod->usecount);
492                         error = 1;
493                 }
494         }
495
496         if (!error) {
497                 __ast_module_user_hangup_all(mod);
498                 res = mod->info->unload();
499
500                 if (res) {
501                         ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
502                         if (force <= AST_FORCE_FIRM)
503                                 error = 1;
504                         else
505                                 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
506                 }
507         }
508
509         if (!error)
510                 mod->flags.running = mod->flags.declined = 0;
511
512         AST_LIST_UNLOCK(&module_list);
513
514         if (!error && !mod->lib)
515                 mod->info->restore_globals();
516
517 #ifdef LOADABLE_MODULES
518         if (!error)
519                 unload_dynamic_module(mod);
520 #endif
521
522         if (!error)
523                 ast_update_use_count();
524
525         return res;
526 }
527
528 char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload)
529 {
530         struct ast_module *cur;
531         int i, which=0, l = strlen(word);
532         char *ret = NULL;
533
534         if (pos != rpos)
535                 return NULL;
536
537         AST_LIST_LOCK(&module_list);
538         AST_LIST_TRAVERSE(&module_list, cur, entry) {
539                 if (!strncasecmp(word, cur->resource, l) &&
540                     (cur->info->reload || !needsreload) &&
541                     ++which > state) {
542                         ret = ast_strdup(cur->resource);
543                         break;
544                 }
545         }
546         AST_LIST_UNLOCK(&module_list);
547
548         if (!ret) {
549                 for (i=0; !ret && reload_classes[i].name; i++) {
550                         if (!strncasecmp(word, reload_classes[i].name, l) && ++which > state)
551                                 ret = ast_strdup(reload_classes[i].name);
552                 }
553         }
554
555         return ret;
556 }
557
558 int ast_module_reload(const char *name)
559 {
560         struct ast_module *cur;
561         int res = 0; /* return value. 0 = not found, others, see below */
562         int i;
563
564         if (ast_mutex_trylock(&reloadlock)) {
565                 ast_verbose("The previous reload command didn't finish yet\n");
566                 return -1;      /* reload already in progress */
567         }
568         ast_lastreloadtime = ast_tvnow();
569
570         /* Call "predefined" reload here first */
571         for (i = 0; reload_classes[i].name; i++) {
572                 if (!name || !strcasecmp(name, reload_classes[i].name)) {
573                         reload_classes[i].reload_fn();  /* XXX should check error ? */
574                         res = 2;        /* found and reloaded */
575                 }
576         }
577
578         if (name && res) {
579                 ast_mutex_unlock(&reloadlock);
580                 return res;
581         }
582
583         AST_LIST_LOCK(&module_list);
584         AST_LIST_TRAVERSE(&module_list, cur, entry) {
585                 const struct ast_module_info *info = cur->info;
586
587                 if (name && resource_name_match(name, cur->resource))
588                         continue;
589
590                 if (!(cur->flags.running || cur->flags.declined))
591                         continue;
592
593                 if (!info->reload) {    /* cannot be reloaded */
594                         if (res < 1)    /* store result if possible */
595                                 res = 1;        /* 1 = no reload() method */
596                         continue;
597                 }
598
599                 res = 2;
600                 ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description);
601                 info->reload();
602         }
603         AST_LIST_UNLOCK(&module_list);
604
605         ast_mutex_unlock(&reloadlock);
606
607         return res;
608 }
609
610 static unsigned int inspect_module(const struct ast_module *mod)
611 {
612         if (!mod->info->description) {
613                 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource);
614                 return 1;
615         }
616
617         if (!mod->info->key) {
618                 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource);
619                 return 1;
620         }
621
622         if (verify_key((unsigned char *) mod->info->key)) {
623                 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource);
624                 return 1;
625         }
626
627         if (!ast_strlen_zero(mod->info->buildopt_sum) &&
628             strcmp(buildopt_sum, mod->info->buildopt_sum)) {
629                 ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource);
630                 ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource);
631                 return 1;
632         }
633
634         return 0;
635 }
636
637 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only)
638 {
639         struct ast_module *mod;
640         enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
641         char tmp[256];
642
643         if ((mod = find_resource(resource_name, 0))) {
644                 if (mod->flags.running) {
645                         ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name);
646                         return AST_MODULE_LOAD_DECLINE;
647                 }
648                 if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS))
649                         return AST_MODULE_LOAD_SKIP;
650         } else {
651 #ifdef LOADABLE_MODULES
652                 if (!(mod = load_dynamic_module(resource_name, global_symbols_only))) {
653                         /* don't generate a warning message during load_modules() */
654                         if (!global_symbols_only) {
655                                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
656                                 return AST_MODULE_LOAD_DECLINE;
657                         } else {
658                                 return AST_MODULE_LOAD_SKIP;
659                         }
660                 }
661 #else
662                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
663                 return AST_MODULE_LOAD_DECLINE;
664 #endif
665         }
666
667         if (inspect_module(mod)) {
668                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
669 #ifdef LOADABLE_MODULES
670                 unload_dynamic_module(mod);
671 #endif
672                 return AST_MODULE_LOAD_DECLINE;
673         }
674
675         if (!mod->lib && mod->info->backup_globals()) {
676                 ast_log(LOG_WARNING, "Module '%s' was unable to backup its global data.\n", resource_name);
677                 return AST_MODULE_LOAD_DECLINE;
678         }
679
680         mod->flags.declined = 0;
681
682         if (mod->info->load)
683                 res = mod->info->load();
684
685         switch (res) {
686         case AST_MODULE_LOAD_SUCCESS:
687                 if (!ast_fully_booted) {
688                         ast_verb(1, "%s => (%s)\n", resource_name, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
689                         if (ast_opt_console && !option_verbose)
690                                 ast_verbose( ".");
691                 } else {
692                         ast_verb(1, "Loaded %s => (%s)\n", resource_name, mod->info->description);
693                 }
694
695                 mod->flags.running = 1;
696
697                 ast_update_use_count();
698                 break;
699         case AST_MODULE_LOAD_DECLINE:
700                 mod->flags.declined = 1;
701                 break;
702         case AST_MODULE_LOAD_FAILURE:
703                 break;
704         case AST_MODULE_LOAD_SKIP:
705                 /* modules should never return this value */
706                 break;
707         }
708
709         return res;
710 }
711
712 int ast_load_resource(const char *resource_name)
713 {
714        AST_LIST_LOCK(&module_list);
715        load_resource(resource_name, 0);
716        AST_LIST_UNLOCK(&module_list);
717
718        return 0;
719 }
720
721 struct load_order_entry {
722         char *resource;
723         AST_LIST_ENTRY(load_order_entry) entry;
724 };
725
726 AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
727
728 static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order)
729 {
730         struct load_order_entry *order;
731
732         AST_LIST_TRAVERSE(load_order, order, entry) {
733                 if (!resource_name_match(order->resource, resource))
734                         return NULL;
735         }
736
737         if (!(order = ast_calloc(1, sizeof(*order))))
738                 return NULL;
739
740         order->resource = ast_strdup(resource);
741         AST_LIST_INSERT_TAIL(load_order, order, entry);
742
743         return order;
744 }
745
746 int load_modules(unsigned int preload_only)
747 {
748         struct ast_config *cfg;
749         struct ast_module *mod;
750         struct load_order_entry *order;
751         struct ast_variable *v;
752         unsigned int load_count;
753         struct load_order load_order;
754         int res = 0;
755         struct ast_flags config_flags = { 0 };
756         int modulecount = 0;
757 #ifdef LOADABLE_MODULES
758         struct dirent *dirent;
759         DIR *dir;
760 #endif
761
762         /* all embedded modules have registered themselves by now */
763         embedding = 0;
764
765         ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
766
767         AST_LIST_HEAD_INIT_NOLOCK(&load_order);
768
769         AST_LIST_LOCK(&module_list);
770
771         if (embedded_module_list.first) {
772                 module_list.first = embedded_module_list.first;
773                 module_list.last = embedded_module_list.last;
774                 embedded_module_list.first = NULL;
775         }
776
777         if (!(cfg = ast_config_load(AST_MODULE_CONFIG, config_flags))) {
778                 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
779                 goto done;
780         }
781
782         /* first, find all the modules we have been explicitly requested to load */
783         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
784                 if (!strcasecmp(v->name, preload_only ? "preload" : "load"))
785                         add_to_load_order(v->value, &load_order);
786         }
787
788         /* check if 'autoload' is on */
789         if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
790                 /* if so, first add all the embedded modules that are not already running to the load order */
791                 AST_LIST_TRAVERSE(&module_list, mod, entry) {
792                         /* if it's not embedded, skip it */
793                         if (mod->lib)
794                                 continue;
795
796                         if (mod->flags.running)
797                                 continue;
798
799                         order = add_to_load_order(mod->resource, &load_order);
800                 }
801
802 #ifdef LOADABLE_MODULES
803                 /* if we are allowed to load dynamic modules, scan the directory for
804                    for all available modules and add them as well */
805                 if ((dir  = opendir(ast_config_AST_MODULE_DIR))) {
806                         while ((dirent = readdir(dir))) {
807                                 int ld = strlen(dirent->d_name);
808
809                                 /* Must end in .so to load it.  */
810
811                                 if (ld < 4)
812                                         continue;
813
814                                 if (strcasecmp(dirent->d_name + ld - 3, ".so"))
815                                         continue;
816
817                                 /* if there is already a module by this name in the module_list,
818                                    skip this file */
819                                 if (find_resource(dirent->d_name, 0))
820                                         continue;
821
822                                 add_to_load_order(dirent->d_name, &load_order);
823                         }
824
825                         closedir(dir);
826                 } else {
827                         if (!ast_opt_quiet)
828                                 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",
829                                         ast_config_AST_MODULE_DIR);
830                 }
831 #endif
832         }
833
834         /* now scan the config for any modules we are prohibited from loading and
835            remove them from the load order */
836         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
837                 if (strcasecmp(v->name, "noload"))
838                         continue;
839
840                 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
841                         if (!resource_name_match(order->resource, v->value)) {
842                                 AST_LIST_REMOVE_CURRENT(entry);
843                                 ast_free(order->resource);
844                                 ast_free(order);
845                         }
846                 }
847                 AST_LIST_TRAVERSE_SAFE_END;
848         }
849
850         /* we are done with the config now, all the information we need is in the
851            load_order list */
852         ast_config_destroy(cfg);
853
854         load_count = 0;
855         AST_LIST_TRAVERSE(&load_order, order, entry)
856                 load_count++;
857
858         if (load_count)
859                 ast_log(LOG_NOTICE, "%d modules will be loaded.\n", load_count);
860
861         /* first, load only modules that provide global symbols */
862         AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
863                 switch (load_resource(order->resource, 1)) {
864                 case AST_MODULE_LOAD_SUCCESS:
865                         modulecount++;
866                 case AST_MODULE_LOAD_DECLINE:
867                         AST_LIST_REMOVE_CURRENT(entry);
868                         ast_free(order->resource);
869                         ast_free(order);
870                         break;
871                 case AST_MODULE_LOAD_FAILURE:
872                         res = -1;
873                         goto done;
874                 case AST_MODULE_LOAD_SKIP:
875                         /* try again later */
876                         break;
877                 }
878         }
879         AST_LIST_TRAVERSE_SAFE_END;
880
881         /* now load everything else */
882         AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
883                 switch (load_resource(order->resource, 0)) {
884                 case AST_MODULE_LOAD_SUCCESS:
885                         modulecount++;
886                 case AST_MODULE_LOAD_DECLINE:
887                         AST_LIST_REMOVE_CURRENT(entry);
888                         ast_free(order->resource);
889                         ast_free(order);
890                         break;
891                 case AST_MODULE_LOAD_FAILURE:
892                         res = -1;
893                         goto done;
894                 case AST_MODULE_LOAD_SKIP:
895                         /* should not happen */
896                         break;
897                 }
898         }
899         AST_LIST_TRAVERSE_SAFE_END;
900
901 done:
902         while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
903                 ast_free(order->resource);
904                 ast_free(order);
905         }
906
907         AST_LIST_UNLOCK(&module_list);
908
909         ast_manager_register2("ModuleLoad", EVENT_FLAG_SYSTEM, manager_moduleload, "Module management", mandescr_moduleload);
910         ast_manager_register2("ModuleCheck", EVENT_FLAG_SYSTEM, manager_modulecheck, "Check if module is loaded", mandescr_modulecheck);
911
912         /* Tell manager clients that are aggressive at logging in that we're done
913            loading modules. If there's a DNS problem in chan_sip, we might not
914            even reach this */
915         manager_event(EVENT_FLAG_SYSTEM, "ModuleLoadReport", "ModuleLoadStatus: Done\r\nModuleSelection: %s\r\nModuleCount: %d\r\n", preload_only ? "Preload" : "All", modulecount);
916         return res;
917 }
918
919 void ast_update_use_count(void)
920 {
921         /* Notify any module monitors that the use count for a
922            resource has changed */
923         struct loadupdate *m;
924
925         AST_LIST_LOCK(&module_list);
926         AST_LIST_TRAVERSE(&updaters, m, entry)
927                 m->updater();
928         AST_LIST_UNLOCK(&module_list);
929 }
930
931 int ast_update_module_list(int (*modentry)(const char *module, const char *description, int usecnt, const char *like),
932                            const char *like)
933 {
934         struct ast_module *cur;
935         int unlock = -1;
936         int total_mod_loaded = 0;
937
938         if (AST_LIST_TRYLOCK(&module_list))
939                 unlock = 0;
940  
941         AST_LIST_TRAVERSE(&module_list, cur, entry) {
942                 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, like);
943         }
944
945         if (unlock)
946                 AST_LIST_UNLOCK(&module_list);
947
948         return total_mod_loaded;
949 }
950
951 /*! \brief Check if module exists */
952 int ast_module_check(const char *name)
953 {
954         struct ast_module *cur;
955
956         if (ast_strlen_zero(name))
957                 return 0;       /* FALSE */
958
959         cur = find_resource(name, 1);
960
961         return (cur != NULL);
962 }
963
964
965 int ast_loader_register(int (*v)(void))
966 {
967         struct loadupdate *tmp;
968
969         if (!(tmp = ast_malloc(sizeof(*tmp))))
970                 return -1;
971
972         tmp->updater = v;
973         AST_LIST_LOCK(&module_list);
974         AST_LIST_INSERT_HEAD(&updaters, tmp, entry);
975         AST_LIST_UNLOCK(&module_list);
976
977         return 0;
978 }
979
980 int ast_loader_unregister(int (*v)(void))
981 {
982         struct loadupdate *cur;
983
984         AST_LIST_LOCK(&module_list);
985         AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) {
986                 if (cur->updater == v)  {
987                         AST_LIST_REMOVE_CURRENT(entry);
988                         break;
989                 }
990         }
991         AST_LIST_TRAVERSE_SAFE_END;
992         AST_LIST_UNLOCK(&module_list);
993
994         return cur ? 0 : -1;
995 }
996
997 struct ast_module *ast_module_ref(struct ast_module *mod)
998 {
999         ast_atomic_fetchadd_int(&mod->usecount, +1);
1000         ast_update_use_count();
1001
1002         return mod;
1003 }
1004
1005 void ast_module_unref(struct ast_module *mod)
1006 {
1007         ast_atomic_fetchadd_int(&mod->usecount, -1);
1008         ast_update_use_count();
1009 }
1010
1011 static char mandescr_modulecheck[] = 
1012 "Description: Checks if Asterisk module is loaded\n"
1013 "Variables: \n"
1014 "  ActionID: <id>          Action ID for this transaction. Will be returned.\n"
1015 "  Module: <name>          Asterisk module name (not including extension)\n"
1016 "\n"
1017 "Will return Success/Failure\n"
1018 "For success returns, the module revision number is included.\n";
1019
1020 /* Manager function to check if module is loaded */
1021 static int manager_modulecheck(struct mansession *s, const struct message *m)
1022 {
1023         int res;
1024         const char *module = astman_get_header(m, "Module");
1025         const char *id = astman_get_header(m,"ActionID");
1026         char idText[BUFSIZ];
1027         const char *version;
1028         char filename[BUFSIZ/2];
1029         char *cut;
1030
1031         snprintf(filename, sizeof(filename), module);
1032         if ((cut = strchr(filename, '.'))) {
1033                 *cut = '\0';
1034         } else {
1035                 cut = filename + strlen(filename);
1036         }
1037         sprintf(cut, ".so");
1038         ast_log(LOG_DEBUG, "**** ModuleCheck .so file %s\n", filename);
1039         res = ast_module_check(filename);
1040         if (!res) {
1041                 astman_send_error(s, m, "Module not loaded");
1042                 return 0;
1043         }
1044         sprintf(cut, ".c");
1045         ast_log(LOG_DEBUG, "**** ModuleCheck .c file %s\n", filename);
1046         version = ast_file_version_find(filename);
1047
1048         if (!ast_strlen_zero(id))
1049                 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
1050         astman_append(s, "Response: Success\r\n%s", idText);
1051         astman_append(s, "Version: %s\r\n\r\n", version ? version : "");
1052         return 0;
1053 }
1054
1055
1056 static char mandescr_moduleload[] = 
1057 "Description: Loads, unloads or reloads an Asterisk module in a running system.\n"
1058 "Variables: \n"
1059 "  ActionID: <id>          Action ID for this transaction. Will be returned.\n"
1060 "  Module: <name>          Asterisk module name (including .so extension)\n"
1061 "                          or subsystem identifier:\n"
1062 "                               cdr, enum, dnsmgr, extconfig, manager, rtp, http\n"
1063 "  LoadType: load | unload | reload\n"
1064 "                          The operation to be done on module\n"
1065 " If no module is specified for a reload loadtype, all modules are reloaded";
1066
1067 static int manager_moduleload(struct mansession *s, const struct message *m)
1068 {
1069         int res;
1070         const char *module = astman_get_header(m, "Module");
1071         const char *loadtype = astman_get_header(m, "LoadType");
1072
1073         if (!loadtype || strlen(loadtype) == 0)
1074                 astman_send_error(s, m, "Incomplete ModuleLoad action.");
1075         if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0)
1076                 astman_send_error(s, m, "Need module name");
1077
1078         if (!strcasecmp(loadtype, "load")) {
1079                 res = ast_load_resource(module);
1080                 if (res)
1081                         astman_send_error(s, m, "Could not load module.");
1082                 else
1083                         astman_send_ack(s, m, "Module loaded.");
1084         } else if (!strcasecmp(loadtype, "unload")) {
1085                 res = ast_unload_resource(module, AST_FORCE_SOFT);
1086                 if (res)
1087                         astman_send_error(s, m, "Could not unload module.");
1088                 else
1089                         astman_send_ack(s, m, "Module unloaded.");
1090         } else if (!strcasecmp(loadtype, "reload")) {
1091                 if (module != NULL) {
1092                         res = ast_module_reload(module);
1093                         if (res == 0)
1094                                 astman_send_error(s, m, "No such module.");
1095                         else if (res == 1)
1096                                 astman_send_error(s, m, "Module does not support reload action.");
1097                         else
1098                                 astman_send_ack(s, m, "Module reloaded.");
1099                 } else {
1100                         ast_module_reload(NULL);        /* Reload all modules */
1101                         astman_send_ack(s, m, "All modules reloaded");
1102                 }
1103         } else 
1104                 astman_send_error(s, m, "Incomplete ModuleLoad action.");
1105         return 0;
1106 }