ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/modules.c
Revision: 8431
Committed: Tue Mar 27 18:49:15 2018 UTC (8 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 9194 byte(s)
Log Message:
- Stylistic changes

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 8279 * Copyright (c) 2000-2018 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 4565 * 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 4977 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 7032 xfree(modp->name);
103 michael 1237
104     lt_dlclose(modp->handle);
105    
106     if (warn == 1)
107     {
108 michael 1247 ilog(LOG_TYPE_IRCD, "Module %s unloaded", name);
109 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
110 michael 1618 "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 8431 if ((tmpptr = lt_dlopen(path)) == NULL)
133 michael 2525 {
134 michael 1237 const char *err = ((err = lt_dlerror())) ? err : "<unknown>";
135    
136 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
137 michael 1618 "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 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
148 michael 1618 "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 6318 sendto_realops_flags(UMODE_SERVNOTICE, 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 michael 6553 exit(EXIT_FAILURE);
193 michael 1237 }
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 8059 dlink_node *node;
206 adx 30
207 michael 4815 DLINK_FOREACH(node, modules_path.head)
208 adx 30 {
209 michael 4815 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 8310 pathst = xcalloc(sizeof(*pathst));
233 michael 7499 pathst->path = xstrdup(path);
234 michael 2959 dlinkAdd(pathst, &pathst->node, &modules_path);
235 adx 30 }
236    
237     /* add_conf_module
238     *
239     * input - module name
240     * output - NONE
241     * side effects - adds module to conf_mod
242     */
243     void
244     add_conf_module(const char *name)
245     {
246     struct module_path *pathst;
247    
248 michael 8310 pathst = xcalloc(sizeof(*pathst));
249 michael 7499 pathst->path = xstrdup(name);
250 michael 2959 dlinkAdd(pathst, &pathst->node, &modules_conf);
251 adx 30 }
252    
253     /* mod_clear_paths()
254     *
255     * input - NONE
256     * output - NONE
257     * side effects - clear the lists of paths and conf modules
258     */
259     void
260 michael 7245 modules_conf_clear(void)
261 adx 30 {
262 michael 7245 while (modules_path.head)
263     {
264     struct module_path *path = modules_path.head->data;
265 adx 30
266 michael 7245 dlinkDelete(&path->node, &modules_path);
267 michael 7499 xfree(path->path);
268 michael 7245 xfree(path);
269 adx 30 }
270    
271 michael 7245 while (modules_conf.head)
272 adx 30 {
273 michael 7245 struct module_path *path = modules_conf.head->data;
274    
275     dlinkDelete(&path->node, &modules_conf);
276 michael 7499 xfree(path->path);
277 michael 7245 xfree(path);
278 adx 30 }
279     }
280    
281     /* findmodule_byname
282     *
283     * input - name of module
284     * output - NULL if not found or pointer to module
285     * side effects - NONE
286     */
287 michael 1230 struct module *
288 adx 30 findmodule_byname(const char *name)
289     {
290 michael 8059 dlink_node *node;
291 adx 30
292 michael 4815 DLINK_FOREACH(node, modules_list.head)
293 adx 30 {
294 michael 4815 struct module *modp = node->data;
295 adx 30
296 michael 3235 if (!strcmp(modp->name, name))
297 michael 1230 return modp;
298 adx 30 }
299    
300     return NULL;
301     }
302    
303     /* load_all_modules()
304     *
305     * input - int flag warn
306     * output - NONE
307     * side effects - load all modules found in autoload directory
308     */
309     void
310     load_all_modules(int warn)
311     {
312     DIR *system_module_dir = NULL;
313     struct dirent *ldirent = NULL;
314 michael 1737 char module_fq_name[HYB_PATH_MAX + 1];
315 adx 30
316     if ((system_module_dir = opendir(AUTOMODPATH)) == NULL)
317     {
318 michael 1247 ilog(LOG_TYPE_IRCD, "Could not load modules from %s: %s",
319 adx 30 AUTOMODPATH, strerror(errno));
320     return;
321     }
322    
323 michael 3235 while ((ldirent = readdir(system_module_dir)))
324 adx 30 {
325 michael 912 if (modules_valid_suffix(ldirent->d_name))
326 adx 30 {
327     snprintf(module_fq_name, sizeof(module_fq_name), "%s/%s",
328     AUTOMODPATH, ldirent->d_name);
329 michael 1404 load_a_module(module_fq_name, warn);
330 adx 30 }
331     }
332    
333     closedir(system_module_dir);
334     }
335    
336     /* load_conf_modules()
337     *
338     * input - NONE
339     * output - NONE
340     * side effects - load modules given in ircd.conf
341     */
342     void
343     load_conf_modules(void)
344     {
345 michael 8059 dlink_node *node;
346 adx 30
347 michael 4815 DLINK_FOREACH(node, modules_conf.head)
348 adx 30 {
349 michael 4815 struct module_path *mpath = node->data;
350 adx 30
351     if (findmodule_byname(mpath->path) == NULL)
352 michael 1404 load_one_module(mpath->path);
353 adx 30 }
354     }
355    
356     /* load_core_modules()
357     *
358     * input - int flag warn
359     * output - NONE
360     * side effects - core modules are loaded, if any fail, kill ircd
361     */
362     void
363     load_core_modules(int warn)
364     {
365 michael 1737 char module_name[HYB_PATH_MAX + 1];
366 adx 30
367 michael 3235 for (unsigned int i = 0; core_module_table[i]; ++i)
368 adx 30 {
369 michael 912 snprintf(module_name, sizeof(module_name), "%s%s",
370     MODPATH, core_module_table[i]);
371 adx 30
372 michael 1404 if (load_a_module(module_name, warn) == -1)
373 adx 30 {
374 michael 1247 ilog(LOG_TYPE_IRCD, "Error loading core module %s: terminating ircd",
375 michael 912 core_module_table[i]);
376 adx 30 exit(EXIT_FAILURE);
377     }
378     }
379     }
380    
381     /* load_one_module()
382     *
383     * input - pointer to path
384     * - flagged as core module or not
385 michael 2345 * output - -1 if error
386 adx 30 * side effects - module is loaded if found.
387     */
388     int
389 michael 3031 load_one_module(const char *name)
390 adx 30 {
391 michael 8059 dlink_node *node;
392 michael 3031 char path[HYB_PATH_MAX + 1];
393 adx 30 struct stat statbuf;
394    
395 michael 4815 DLINK_FOREACH(node, modules_path.head)
396 adx 30 {
397 michael 4815 const struct module_path *mpath = node->data;
398 adx 30
399 michael 3031 snprintf(path, sizeof(path), "%s/%s", mpath->path, name);
400 adx 30
401 michael 3031 if (!modules_valid_suffix(name))
402 michael 912 continue;
403    
404 michael 3031 if (strstr(path, "../") == NULL &&
405     strstr(path, "/..") == NULL)
406     if (!stat(path, &statbuf))
407 michael 1404 if (S_ISREG(statbuf.st_mode)) /* Regular files only please */
408 michael 3031 return load_a_module(path, 1);
409 adx 30 }
410    
411 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
412 michael 3031 "Cannot locate module %s", name);
413     ilog(LOG_TYPE_IRCD, "Cannot locate module %s", name);
414 adx 30 return -1;
415     }

Properties

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