1 /* modules.c - Compiled-in module support
2 * Copyright 2002-2003 srvx Development Team
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version. Important limitations are
8 * listed in the COPYING file that accompanies this software.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, email srvx-maintainers@srvx.net.
32 int (*init_func)(void);
33 int (*finalize_func)(void);
35 enum init_state state;
38 #define WITH_MODULE(x) extern int x##_init(void); extern int x##_finalize(void); extern const char *x##_module_deps[];
39 #include "modules-list.h"
42 static struct cmodule cmodules[] = {
43 #define WITH_MODULE(x) { #x, x##_init, x##_finalize, x##_module_deps, UNINIT },
44 #include "modules-list.h"
46 /* Placeholder at end of array */
47 { NULL, NULL, NULL, NULL, UNINIT }
51 modules_bsearch(const void *a, const void *b) {
53 const struct cmodule *cmod = b;
54 return irccasecmp(key, cmod->name);
58 modules_qsort(const void *a, const void *b) {
59 const struct cmodule *ca = a, *cb = b;
60 return irccasecmp(ca->name, cb->name);
64 module_init(struct cmodule *cmod, int final) {
68 switch (cmod->state) {
70 case INITED: if (!final) return 1; break;
72 case BROKEN: return 0;
74 log_module(MAIN_LOG, LOG_ERROR, "Tried to recursively enable code module %s.", cmod->name);
77 cmod->state = WORKING;
78 for (ii=0; cmod->deps[ii]; ++ii) {
79 dep = bsearch(cmod->deps[ii], cmodules, ArrayLength(cmodules)-1, sizeof(cmodules[0]), modules_bsearch);
81 log_module(MAIN_LOG, LOG_ERROR, "Code module %s depends on unknown module %s.", cmod->name, cmod->deps[ii]);
85 if (!module_init(dep, final)) {
86 log_module(MAIN_LOG, LOG_ERROR, "Failed to initialize dependency %s of code module %s.", dep->name, cmod->name);
92 if (!cmod->finalize_func()) {
93 log_module(MAIN_LOG, LOG_ERROR, "Failed to finalize code module %s.", cmod->name);
100 if (!cmod->init_func()) {
101 log_module(MAIN_LOG, LOG_ERROR, "Failed to initialize code module %s.", cmod->name);
102 cmod->state = BROKEN;
105 cmod->state = INITED;
114 qsort(cmodules, ArrayLength(cmodules)-1, sizeof(cmodules[0]), modules_qsort);
115 for (ii=0; cmodules[ii].name; ++ii) {
116 if (cmodules[ii].state != UNINIT) continue;
117 module_init(cmodules + ii, 0);
118 if (cmodules[ii].state != INITED) {
119 log_module(MAIN_LOG, LOG_WARNING, "Code module %s not properly initialized.", cmodules[ii].name);
125 modules_finalize(void) {
128 for (ii=0; cmodules[ii].name; ++ii) {
129 if (cmodules[ii].state != INITED) continue;
130 module_init(cmodules + ii, 1);
131 if (cmodules[ii].state != DONE) {
132 log_module(MAIN_LOG, LOG_WARNING, "Code module %s not properly finalized.", cmodules[ii].name);