ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/modules.c
Revision: 2916
Committed: Sat Jan 25 21:09:18 2014 UTC (12 years, 8 months ago) by michael
Content type: text/x-csrc
File size: 9101 byte(s)
Log Message:
- Clean up all files in include/ (fixed indentation, removed whitespaces/tabs)
- Fixed copyright years

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

Properties

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