ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/modules.c
Revision: 3031
Committed: Tue Feb 25 11:50:53 2014 UTC (11 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 9117 byte(s)
Log Message:
- modules.c:load_one_module(): renamed variables to make less confusing

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

Properties

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