ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/modules.c
Revision: 8603
Committed: Sun Oct 28 19:43:30 2018 UTC (6 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 9166 byte(s)
Log Message:
- Fixed style inconsistencies in various places

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 michael 8603 return ((name = strrchr(name, '.'))) && strcmp(name, ".la") == 0;
80 michael 1237 }
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 dlinkDelete(&modp->node, &modules_list);
101 michael 7032 xfree(modp->name);
102 michael 1237
103     lt_dlclose(modp->handle);
104    
105     if (warn == 1)
106     {
107 michael 1247 ilog(LOG_TYPE_IRCD, "Module %s unloaded", name);
108 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
109 michael 1618 "Module %s unloaded", name);
110 michael 1237 }
111    
112     return 0;
113     }
114    
115     /* load_a_module()
116     *
117     * inputs - path name of module, int to notice, int of core
118     * output - -1 if error 0 if success
119     * side effects - loads a module if successful
120     */
121     int
122 michael 1404 load_a_module(const char *path, int warn)
123 michael 1237 {
124     lt_dlhandle tmpptr = NULL;
125     const char *mod_basename = NULL;
126     struct module *modp = NULL;
127    
128     if (findmodule_byname((mod_basename = libio_basename(path))))
129     return 1;
130    
131 michael 8431 if ((tmpptr = lt_dlopen(path)) == NULL)
132 michael 2525 {
133 michael 1237 const char *err = ((err = lt_dlerror())) ? err : "<unknown>";
134    
135 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
136 michael 1618 "Error loading module %s: %s",
137 michael 1237 mod_basename, err);
138 michael 1247 ilog(LOG_TYPE_IRCD, "Error loading module %s: %s", mod_basename, err);
139 michael 1237 return -1;
140     }
141    
142     if ((modp = lt_dlsym(tmpptr, "module_entry")) == NULL)
143     {
144 michael 1574 const char *err = ((err = lt_dlerror())) ? err : "<unknown>";
145    
146 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
147 michael 1618 "Error loading module %s: %s",
148 michael 1574 mod_basename, err);
149     ilog(LOG_TYPE_IRCD, "Error loading module %s: %s", mod_basename, err);
150 michael 1237 lt_dlclose(tmpptr);
151     return -1;
152     }
153    
154     modp->handle = tmpptr;
155    
156     if (EmptyString(modp->version))
157     modp->version = unknown_ver;
158    
159 michael 1646 modp->name = xstrdup(mod_basename);
160 michael 1238 dlinkAdd(modp, &modp->node, &modules_list);
161 michael 1237
162     if (modp->modinit)
163     modp->modinit();
164    
165     if (warn == 1)
166     {
167 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
168 michael 1237 "Module %s [version: %s handle: %p] loaded.",
169     modp->name, modp->version, tmpptr);
170 michael 1247 ilog(LOG_TYPE_IRCD, "Module %s [version: %s handle: %p] loaded.",
171 michael 1237 modp->name, modp->version, tmpptr);
172     }
173    
174     return 0;
175     }
176    
177 adx 30 /*
178     * modules_init
179     *
180     * input - NONE
181     * output - NONE
182     * side effects - The basic module manipulation modules are loaded
183     */
184     void
185     modules_init(void)
186     {
187 michael 1237 if (lt_dlinit())
188     {
189 michael 1247 ilog(LOG_TYPE_IRCD, "Couldn't initialize the libltdl run time dynamic"
190 michael 1237 " link library. Exiting.");
191 michael 6553 exit(EXIT_FAILURE);
192 michael 1237 }
193 adx 30 }
194    
195     /* mod_find_path()
196     *
197     * input - path
198     * output - none
199     * side effects - returns a module path from path
200     */
201     static struct module_path *
202     mod_find_path(const char *path)
203     {
204 michael 8059 dlink_node *node;
205 adx 30
206 michael 4815 DLINK_FOREACH(node, modules_path.head)
207 adx 30 {
208 michael 4815 struct module_path *mpath = node->data;
209 adx 30
210 michael 8540 if (strcmp(path, mpath->path) == 0)
211 adx 30 return mpath;
212     }
213    
214     return NULL;
215     }
216    
217     /* mod_add_path()
218     *
219     * input - path
220     * output - NONE
221     * side effects - adds path to list
222     */
223     void
224     mod_add_path(const char *path)
225     {
226     struct module_path *pathst;
227    
228     if (mod_find_path(path))
229     return;
230    
231 michael 8310 pathst = xcalloc(sizeof(*pathst));
232 michael 7499 pathst->path = xstrdup(path);
233 michael 2959 dlinkAdd(pathst, &pathst->node, &modules_path);
234 adx 30 }
235    
236     /* add_conf_module
237     *
238     * input - module name
239     * output - NONE
240     * side effects - adds module to conf_mod
241     */
242     void
243     add_conf_module(const char *name)
244     {
245     struct module_path *pathst;
246    
247 michael 8310 pathst = xcalloc(sizeof(*pathst));
248 michael 7499 pathst->path = xstrdup(name);
249 michael 2959 dlinkAdd(pathst, &pathst->node, &modules_conf);
250 adx 30 }
251    
252     /* mod_clear_paths()
253     *
254     * input - NONE
255     * output - NONE
256     * side effects - clear the lists of paths and conf modules
257     */
258     void
259 michael 7245 modules_conf_clear(void)
260 adx 30 {
261 michael 7245 while (modules_path.head)
262     {
263     struct module_path *path = modules_path.head->data;
264 adx 30
265 michael 7245 dlinkDelete(&path->node, &modules_path);
266 michael 7499 xfree(path->path);
267 michael 7245 xfree(path);
268 adx 30 }
269    
270 michael 7245 while (modules_conf.head)
271 adx 30 {
272 michael 7245 struct module_path *path = modules_conf.head->data;
273    
274     dlinkDelete(&path->node, &modules_conf);
275 michael 7499 xfree(path->path);
276 michael 7245 xfree(path);
277 adx 30 }
278     }
279    
280     /* findmodule_byname
281     *
282     * input - name of module
283     * output - NULL if not found or pointer to module
284     * side effects - NONE
285     */
286 michael 1230 struct module *
287 adx 30 findmodule_byname(const char *name)
288     {
289 michael 8059 dlink_node *node;
290 adx 30
291 michael 4815 DLINK_FOREACH(node, modules_list.head)
292 adx 30 {
293 michael 4815 struct module *modp = node->data;
294 adx 30
295 michael 8540 if (strcmp(modp->name, name) == 0)
296 michael 1230 return modp;
297 adx 30 }
298    
299     return NULL;
300     }
301    
302     /* load_all_modules()
303     *
304     * input - int flag warn
305     * output - NONE
306     * side effects - load all modules found in autoload directory
307     */
308     void
309     load_all_modules(int warn)
310     {
311     DIR *system_module_dir = NULL;
312     struct dirent *ldirent = NULL;
313 michael 1737 char module_fq_name[HYB_PATH_MAX + 1];
314 adx 30
315     if ((system_module_dir = opendir(AUTOMODPATH)) == NULL)
316     {
317 michael 1247 ilog(LOG_TYPE_IRCD, "Could not load modules from %s: %s",
318 adx 30 AUTOMODPATH, strerror(errno));
319     return;
320     }
321    
322 michael 3235 while ((ldirent = readdir(system_module_dir)))
323 adx 30 {
324 michael 912 if (modules_valid_suffix(ldirent->d_name))
325 adx 30 {
326     snprintf(module_fq_name, sizeof(module_fq_name), "%s/%s",
327     AUTOMODPATH, ldirent->d_name);
328 michael 1404 load_a_module(module_fq_name, warn);
329 adx 30 }
330     }
331    
332     closedir(system_module_dir);
333     }
334    
335     /* load_conf_modules()
336     *
337     * input - NONE
338     * output - NONE
339     * side effects - load modules given in ircd.conf
340     */
341     void
342     load_conf_modules(void)
343     {
344 michael 8059 dlink_node *node;
345 adx 30
346 michael 4815 DLINK_FOREACH(node, modules_conf.head)
347 adx 30 {
348 michael 4815 struct module_path *mpath = node->data;
349 adx 30
350     if (findmodule_byname(mpath->path) == NULL)
351 michael 1404 load_one_module(mpath->path);
352 adx 30 }
353     }
354    
355     /* load_core_modules()
356     *
357     * input - int flag warn
358     * output - NONE
359     * side effects - core modules are loaded, if any fail, kill ircd
360     */
361     void
362     load_core_modules(int warn)
363     {
364 michael 1737 char module_name[HYB_PATH_MAX + 1];
365 adx 30
366 michael 3235 for (unsigned int i = 0; core_module_table[i]; ++i)
367 adx 30 {
368 michael 912 snprintf(module_name, sizeof(module_name), "%s%s",
369     MODPATH, core_module_table[i]);
370 adx 30
371 michael 1404 if (load_a_module(module_name, warn) == -1)
372 adx 30 {
373 michael 1247 ilog(LOG_TYPE_IRCD, "Error loading core module %s: terminating ircd",
374 michael 912 core_module_table[i]);
375 adx 30 exit(EXIT_FAILURE);
376     }
377     }
378     }
379    
380     /* load_one_module()
381     *
382     * input - pointer to path
383     * - flagged as core module or not
384 michael 2345 * output - -1 if error
385 adx 30 * side effects - module is loaded if found.
386     */
387     int
388 michael 3031 load_one_module(const char *name)
389 adx 30 {
390 michael 8059 dlink_node *node;
391 michael 3031 char path[HYB_PATH_MAX + 1];
392 adx 30 struct stat statbuf;
393    
394 michael 4815 DLINK_FOREACH(node, modules_path.head)
395 adx 30 {
396 michael 4815 const struct module_path *mpath = node->data;
397 adx 30
398 michael 3031 snprintf(path, sizeof(path), "%s/%s", mpath->path, name);
399 adx 30
400 michael 8540 if (modules_valid_suffix(name) == 0)
401 michael 912 continue;
402    
403 michael 3031 if (strstr(path, "../") == NULL &&
404     strstr(path, "/..") == NULL)
405 michael 8540 if (stat(path, &statbuf) == 0)
406 michael 1404 if (S_ISREG(statbuf.st_mode)) /* Regular files only please */
407 michael 3031 return load_a_module(path, 1);
408 adx 30 }
409    
410 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
411 michael 3031 "Cannot locate module %s", name);
412     ilog(LOG_TYPE_IRCD, "Cannot locate module %s", name);
413 adx 30 return -1;
414     }

Properties

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