ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/src/modules.c
Revision: 4976
Committed: Thu Dec 4 15:12:10 2014 UTC (9 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 9180 byte(s)
Log Message:
- Style corrections; constifications

File Contents

# User Rev Content
1 adx 30 /*
2 michael 2916 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 adx 30 *
4 michael 2916 * Copyright (c) 2000-2014 ircd-hybrid development team
5 adx 30 *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18 michael 4564 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 adx 30 * USA
20     */
21    
22 michael 2916 /*! \file modules.c
23     * \brief A module loader.
24     * \version $Id$
25     */
26    
27 michael 1237 #include "ltdl.h"
28    
29 adx 30 #include "stdinc.h"
30 michael 1011 #include "list.h"
31 adx 30 #include "modules.h"
32 michael 1309 #include "log.h"
33 adx 30 #include "ircd.h"
34     #include "client.h"
35     #include "send.h"
36 michael 1309 #include "conf.h"
37 adx 30 #include "numeric.h"
38     #include "parse.h"
39     #include "ircd_defs.h"
40     #include "irc_string.h"
41     #include "memory.h"
42    
43    
44 michael 2959 static dlink_list modules_list;
45     static dlink_list modules_path;
46     static dlink_list modules_conf;
47 adx 30
48 michael 4976 static const char *const unknown_ver = "<unknown>";
49     static const char *const core_module_table[] =
50 adx 30 {
51 michael 3356 "m_bmask.la",
52 michael 912 "m_die.la",
53 michael 946 "m_error.la",
54 michael 912 "m_join.la",
55     "m_kick.la",
56     "m_kill.la",
57     "m_message.la",
58     "m_mode.la",
59     "m_nick.la",
60     "m_part.la",
61     "m_quit.la",
62     "m_server.la",
63     "m_sjoin.la",
64     "m_squit.la",
65 michael 3356 "m_tmode.la",
66 adx 30 NULL
67     };
68    
69 michael 2959
70     dlink_list *
71     modules_get_list(void)
72     {
73     return &modules_list;
74     }
75    
76 michael 1237 int
77     modules_valid_suffix(const char *name)
78     {
79     return ((name = strrchr(name, '.'))) && !strcmp(name, ".la");
80     }
81    
82     /* unload_one_module()
83     *
84     * inputs - name of module to unload
85     * - 1 to say modules unloaded, 0 to not
86     * output - 0 if successful, -1 if error
87     * side effects - module is unloaded
88     */
89     int
90     unload_one_module(const char *name, int warn)
91     {
92     struct module *modp = NULL;
93    
94     if ((modp = findmodule_byname(name)) == NULL)
95     return -1;
96    
97     if (modp->modexit)
98     modp->modexit();
99    
100 michael 1238 assert(dlink_list_length(&modules_list) > 0);
101     dlinkDelete(&modp->node, &modules_list);
102 michael 1237 MyFree(modp->name);
103    
104     lt_dlclose(modp->handle);
105    
106     if (warn == 1)
107     {
108 michael 1247 ilog(LOG_TYPE_IRCD, "Module %s unloaded", name);
109 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
110     "Module %s unloaded", name);
111 michael 1237 }
112    
113     return 0;
114     }
115    
116     /* load_a_module()
117     *
118     * inputs - path name of module, int to notice, int of core
119     * output - -1 if error 0 if success
120     * side effects - loads a module if successful
121     */
122     int
123 michael 1404 load_a_module(const char *path, int warn)
124 michael 1237 {
125     lt_dlhandle tmpptr = NULL;
126     const char *mod_basename = NULL;
127     struct module *modp = NULL;
128    
129     if (findmodule_byname((mod_basename = libio_basename(path))))
130     return 1;
131    
132 michael 2525 if (!(tmpptr = lt_dlopen(path)))
133     {
134 michael 1237 const char *err = ((err = lt_dlerror())) ? err : "<unknown>";
135    
136 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
137     "Error loading module %s: %s",
138 michael 1237 mod_basename, err);
139 michael 1247 ilog(LOG_TYPE_IRCD, "Error loading module %s: %s", mod_basename, err);
140 michael 1237 return -1;
141     }
142    
143     if ((modp = lt_dlsym(tmpptr, "module_entry")) == NULL)
144     {
145 michael 1574 const char *err = ((err = lt_dlerror())) ? err : "<unknown>";
146    
147 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
148     "Error loading module %s: %s",
149 michael 1574 mod_basename, err);
150     ilog(LOG_TYPE_IRCD, "Error loading module %s: %s", mod_basename, err);
151 michael 1237 lt_dlclose(tmpptr);
152     return -1;
153     }
154    
155     modp->handle = tmpptr;
156    
157     if (EmptyString(modp->version))
158     modp->version = unknown_ver;
159    
160 michael 1646 modp->name = xstrdup(mod_basename);
161 michael 1238 dlinkAdd(modp, &modp->node, &modules_list);
162 michael 1237
163     if (modp->modinit)
164     modp->modinit();
165    
166     if (warn == 1)
167     {
168 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
169 michael 1237 "Module %s [version: %s handle: %p] loaded.",
170     modp->name, modp->version, tmpptr);
171 michael 1247 ilog(LOG_TYPE_IRCD, "Module %s [version: %s handle: %p] loaded.",
172 michael 1237 modp->name, modp->version, tmpptr);
173     }
174    
175     return 0;
176     }
177    
178 adx 30 /*
179     * modules_init
180     *
181     * input - NONE
182     * output - NONE
183     * side effects - The basic module manipulation modules are loaded
184     */
185     void
186     modules_init(void)
187     {
188 michael 1237 if (lt_dlinit())
189     {
190 michael 1247 ilog(LOG_TYPE_IRCD, "Couldn't initialize the libltdl run time dynamic"
191 michael 1237 " link library. Exiting.");
192     exit(0);
193     }
194 adx 30 }
195    
196     /* mod_find_path()
197     *
198     * input - path
199     * output - none
200     * side effects - returns a module path from path
201     */
202     static struct module_path *
203     mod_find_path(const char *path)
204     {
205 michael 4816 dlink_node *node = NULL;
206 adx 30
207 michael 4816 DLINK_FOREACH(node, modules_path.head)
208 adx 30 {
209 michael 4816 struct module_path *mpath = node->data;
210 adx 30
211     if (!strcmp(path, mpath->path))
212     return mpath;
213     }
214    
215     return NULL;
216     }
217    
218     /* mod_add_path()
219     *
220     * input - path
221     * output - NONE
222     * side effects - adds path to list
223     */
224     void
225     mod_add_path(const char *path)
226     {
227     struct module_path *pathst;
228    
229     if (mod_find_path(path))
230     return;
231    
232 michael 3505 pathst = MyCalloc(sizeof(struct module_path));
233 adx 30
234     strlcpy(pathst->path, path, sizeof(pathst->path));
235 michael 2959 dlinkAdd(pathst, &pathst->node, &modules_path);
236 adx 30 }
237    
238     /* add_conf_module
239     *
240     * input - module name
241     * output - NONE
242     * side effects - adds module to conf_mod
243     */
244     void
245     add_conf_module(const char *name)
246     {
247     struct module_path *pathst;
248    
249 michael 3505 pathst = MyCalloc(sizeof(struct module_path));
250 adx 30
251     strlcpy(pathst->path, name, sizeof(pathst->path));
252 michael 2959 dlinkAdd(pathst, &pathst->node, &modules_conf);
253 adx 30 }
254    
255     /* mod_clear_paths()
256     *
257     * input - NONE
258     * output - NONE
259     * side effects - clear the lists of paths and conf modules
260     */
261     void
262     mod_clear_paths(void)
263     {
264 michael 4816 dlink_node *node = NULL, *node_next = NULL;
265 adx 30
266 michael 4816 DLINK_FOREACH_SAFE(node, node_next, modules_path.head)
267 adx 30 {
268 michael 4816 dlinkDelete(node, &modules_path);
269     MyFree(node->data);
270 adx 30 }
271    
272 michael 4816 DLINK_FOREACH_SAFE(node, node_next, modules_conf.head)
273 adx 30 {
274 michael 4816 dlinkDelete(node, &modules_conf);
275     MyFree(node->data);
276 adx 30 }
277     }
278    
279     /* findmodule_byname
280     *
281     * input - name of module
282     * output - NULL if not found or pointer to module
283     * side effects - NONE
284     */
285 michael 1230 struct module *
286 adx 30 findmodule_byname(const char *name)
287     {
288 michael 4816 dlink_node *node = NULL;
289 adx 30
290 michael 4816 DLINK_FOREACH(node, modules_list.head)
291 adx 30 {
292 michael 4816 struct module *modp = node->data;
293 adx 30
294 michael 3235 if (!strcmp(modp->name, name))
295 michael 1230 return modp;
296 adx 30 }
297    
298     return NULL;
299     }
300    
301     /* load_all_modules()
302     *
303     * input - int flag warn
304     * output - NONE
305     * side effects - load all modules found in autoload directory
306     */
307     void
308     load_all_modules(int warn)
309     {
310     DIR *system_module_dir = NULL;
311     struct dirent *ldirent = NULL;
312 michael 1737 char module_fq_name[HYB_PATH_MAX + 1];
313 adx 30
314     if ((system_module_dir = opendir(AUTOMODPATH)) == NULL)
315     {
316 michael 1247 ilog(LOG_TYPE_IRCD, "Could not load modules from %s: %s",
317 adx 30 AUTOMODPATH, strerror(errno));
318     return;
319     }
320    
321 michael 3235 while ((ldirent = readdir(system_module_dir)))
322 adx 30 {
323 michael 912 if (modules_valid_suffix(ldirent->d_name))
324 adx 30 {
325     snprintf(module_fq_name, sizeof(module_fq_name), "%s/%s",
326     AUTOMODPATH, ldirent->d_name);
327 michael 1404 load_a_module(module_fq_name, warn);
328 adx 30 }
329     }
330    
331     closedir(system_module_dir);
332     }
333    
334     /* load_conf_modules()
335     *
336     * input - NONE
337     * output - NONE
338     * side effects - load modules given in ircd.conf
339     */
340     void
341     load_conf_modules(void)
342     {
343 michael 4816 dlink_node *node = NULL;
344 adx 30
345 michael 4816 DLINK_FOREACH(node, modules_conf.head)
346 adx 30 {
347 michael 4816 struct module_path *mpath = node->data;
348 adx 30
349     if (findmodule_byname(mpath->path) == NULL)
350 michael 1404 load_one_module(mpath->path);
351 adx 30 }
352     }
353    
354     /* load_core_modules()
355     *
356     * input - int flag warn
357     * output - NONE
358     * side effects - core modules are loaded, if any fail, kill ircd
359     */
360     void
361     load_core_modules(int warn)
362     {
363 michael 1737 char module_name[HYB_PATH_MAX + 1];
364 adx 30
365 michael 3235 for (unsigned int i = 0; core_module_table[i]; ++i)
366 adx 30 {
367 michael 912 snprintf(module_name, sizeof(module_name), "%s%s",
368     MODPATH, core_module_table[i]);
369 adx 30
370 michael 1404 if (load_a_module(module_name, warn) == -1)
371 adx 30 {
372 michael 1247 ilog(LOG_TYPE_IRCD, "Error loading core module %s: terminating ircd",
373 michael 912 core_module_table[i]);
374 adx 30 exit(EXIT_FAILURE);
375     }
376     }
377     }
378    
379     /* load_one_module()
380     *
381     * input - pointer to path
382     * - flagged as core module or not
383 michael 2345 * output - -1 if error
384 adx 30 * side effects - module is loaded if found.
385     */
386     int
387 michael 3031 load_one_module(const char *name)
388 adx 30 {
389 michael 4816 dlink_node *node = NULL;
390 michael 3031 char path[HYB_PATH_MAX + 1];
391 adx 30 struct stat statbuf;
392    
393 michael 4816 DLINK_FOREACH(node, modules_path.head)
394 adx 30 {
395 michael 4816 const struct module_path *mpath = node->data;
396 adx 30
397 michael 3031 snprintf(path, sizeof(path), "%s/%s", mpath->path, name);
398 adx 30
399 michael 3031 if (!modules_valid_suffix(name))
400 michael 912 continue;
401    
402 michael 3031 if (strstr(path, "../") == NULL &&
403     strstr(path, "/..") == NULL)
404     if (!stat(path, &statbuf))
405 michael 1404 if (S_ISREG(statbuf.st_mode)) /* Regular files only please */
406 michael 3031 return load_a_module(path, 1);
407 adx 30 }
408    
409 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
410 michael 3031 "Cannot locate module %s", name);
411     ilog(LOG_TYPE_IRCD, "Cannot locate module %s", name);
412 adx 30 return -1;
413     }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision