ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/modules.c
(Generate patch)

Comparing:
ircd-hybrid-8/src/modules.c (file contents), Revision 1309 by michael, Sun Mar 25 11:24:18 2012 UTC vs.
ircd-hybrid/trunk/src/modules.c (file contents), Revision 8431 by michael, Tue Mar 27 18:49:15 2018 UTC

# Line 1 | Line 1
1   /*
2 < *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 < *  modules.c: A module loader.
2 > *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (C) 2002 by the past and present ircd coders, and others.
4 > *  Copyright (c) 2000-2018 ircd-hybrid development team
5   *
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
# Line 16 | Line 15
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
18 > *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19   *  USA
20 < *
21 < *  $Id$
20 > */
21 >
22 > /*! \file modules.c
23 > * \brief A module loader.
24 > * \version $Id$
25   */
26  
27   #include "ltdl.h"
# Line 39 | Line 41
41   #include "memory.h"
42  
43  
44 < static dlink_list modules_list = { NULL, NULL, 0 };
45 <
46 < static const char *unknown_ver = "<unknown>";
44 > static dlink_list modules_list;
45 > static dlink_list modules_path;
46 > static dlink_list modules_conf;
47  
48 < static const char *core_module_table[] =
48 > static const char *const unknown_ver = "<unknown>";
49 > static const char *const core_module_table[] =
50   {
51 +  "m_bmask.la",
52    "m_die.la",
53    "m_error.la",
54    "m_join.la",
# Line 58 | Line 62 | static const char *core_module_table[] =
62    "m_server.la",
63    "m_sjoin.la",
64    "m_squit.la",
65 +  "m_tmode.la",
66    NULL
67   };
68  
64 static dlink_list mod_paths = { NULL, NULL, 0 };
65 static dlink_list conf_modules = { NULL, NULL, 0 };
66
67 static void mo_modload(struct Client *, struct Client *, int, char *[]);
68 static void mo_modlist(struct Client *, struct Client *, int, char *[]);
69 static void mo_modreload(struct Client *, struct Client *, int, char *[]);
70 static void mo_modunload(struct Client *, struct Client *, int, char *[]);
71 static void mo_modrestart(struct Client *, struct Client *, int, char *[]);
72
73 struct Message modload_msgtab = {
74 "MODLOAD", 0, 0, 2, 0, MFLG_SLOW, 0,
75  {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modload, m_ignore}
76 };
77
78 struct Message modunload_msgtab = {
79 "MODUNLOAD", 0, 0, 2, 0, MFLG_SLOW, 0,
80  {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modunload, m_ignore}
81 };
82
83 struct Message modreload_msgtab = {
84  "MODRELOAD", 0, 0, 2, 0, MFLG_SLOW, 0,
85  {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modreload, m_ignore}
86 };
87
88 struct Message modlist_msgtab = {
89 "MODLIST", 0, 0, 0, 0, MFLG_SLOW, 0,
90  {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modlist, m_ignore}
91 };
92
93 struct Message modrestart_msgtab = {
94 "MODRESTART", 0, 0, 0, 0, MFLG_SLOW, 0,
95 {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modrestart, m_ignore}
96 };
69  
70 + dlink_list *
71 + modules_get_list(void)
72 + {
73 +  return &modules_list;
74 + }
75  
76   int
77   modules_valid_suffix(const char *name)
# Line 122 | Line 99 | unload_one_module(const char *name, int
99  
100    assert(dlink_list_length(&modules_list) > 0);
101    dlinkDelete(&modp->node, &modules_list);
102 <  MyFree(modp->name);
102 >  xfree(modp->name);
103  
104    lt_dlclose(modp->handle);
105  
106    if (warn == 1)
107    {
108      ilog(LOG_TYPE_IRCD, "Module %s unloaded", name);
109 <    sendto_realops_flags(UMODE_ALL, L_ALL, "Module %s unloaded", name);
109 >    sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
110 >                         "Module %s unloaded", name);
111    }
112  
113    return 0;
# Line 142 | Line 120 | unload_one_module(const char *name, int
120   * side effects - loads a module if successful
121   */
122   int
123 < load_a_module(const char *path, int warn, int core)
123 > load_a_module(const char *path, int warn)
124   {
125    lt_dlhandle tmpptr = NULL;
126    const char *mod_basename = NULL;
# Line 151 | Line 129 | load_a_module(const char *path, int warn
129    if (findmodule_byname((mod_basename = libio_basename(path))))
130      return 1;
131  
132 <  if (!(tmpptr = lt_dlopen(path))) {
132 >  if ((tmpptr = lt_dlopen(path)) == NULL)
133 >  {
134      const char *err = ((err = lt_dlerror())) ? err : "<unknown>";
135  
136 <    sendto_realops_flags(UMODE_ALL, L_ALL, "Error loading module %s: %s",
136 >    sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
137 >                         "Error loading module %s: %s",
138                           mod_basename, err);
139      ilog(LOG_TYPE_IRCD, "Error loading module %s: %s", mod_basename, err);
140      return -1;
# Line 162 | Line 142 | load_a_module(const char *path, int warn
142  
143    if ((modp = lt_dlsym(tmpptr, "module_entry")) == NULL)
144    {
145 <    sendto_realops_flags(UMODE_ALL, L_ALL, "Module %s has no module_entry export",
146 <                         mod_basename);
147 <    ilog(LOG_TYPE_IRCD, "Module %s has no module_entry export", mod_basename);
145 >    const char *err = ((err = lt_dlerror())) ? err : "<unknown>";
146 >
147 >    sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
148 >                         "Error loading module %s: %s",
149 >                         mod_basename, err);
150 >    ilog(LOG_TYPE_IRCD, "Error loading module %s: %s", mod_basename, err);
151      lt_dlclose(tmpptr);
152      return -1;
153    }
# Line 174 | Line 157 | load_a_module(const char *path, int warn
157    if (EmptyString(modp->version))
158      modp->version = unknown_ver;
159  
160 <  if (core)
178 <    modp->flags |= MODULE_FLAG_CORE;
179 <
180 <  DupString(modp->name, mod_basename);
160 >  modp->name = xstrdup(mod_basename);
161    dlinkAdd(modp, &modp->node, &modules_list);
162  
163    if (modp->modinit)
# Line 185 | Line 165 | load_a_module(const char *path, int warn
165  
166    if (warn == 1)
167    {
168 <    sendto_realops_flags(UMODE_ALL, L_ALL,
168 >    sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
169                           "Module %s [version: %s handle: %p] loaded.",
170                           modp->name, modp->version, tmpptr);
171      ilog(LOG_TYPE_IRCD, "Module %s [version: %s handle: %p] loaded.",
# Line 209 | Line 189 | modules_init(void)
189    {
190      ilog(LOG_TYPE_IRCD, "Couldn't initialize the libltdl run time dynamic"
191           " link library. Exiting.");
192 <    exit(0);
192 >    exit(EXIT_FAILURE);
193    }
214
215  mod_add_cmd(&modload_msgtab);
216  mod_add_cmd(&modunload_msgtab);
217  mod_add_cmd(&modreload_msgtab);
218  mod_add_cmd(&modlist_msgtab);
219  mod_add_cmd(&modrestart_msgtab);
194   }
195  
196   /* mod_find_path()
# Line 228 | Line 202 | modules_init(void)
202   static struct module_path *
203   mod_find_path(const char *path)
204   {
205 <  dlink_node *ptr;
232 <  struct module_path *mpath;
205 >  dlink_node *node;
206  
207 <  DLINK_FOREACH(ptr, mod_paths.head)
207 >  DLINK_FOREACH(node, modules_path.head)
208    {
209 <    mpath = ptr->data;
209 >    struct module_path *mpath = node->data;
210  
211      if (!strcmp(path, mpath->path))
212        return mpath;
# Line 256 | Line 229 | mod_add_path(const char *path)
229    if (mod_find_path(path))
230      return;
231  
232 <  pathst = MyMalloc(sizeof(struct module_path));
233 <
234 <  strlcpy(pathst->path, path, sizeof(pathst->path));
262 <  dlinkAdd(pathst, &pathst->node, &mod_paths);
232 >  pathst = xcalloc(sizeof(*pathst));
233 >  pathst->path = xstrdup(path);
234 >  dlinkAdd(pathst, &pathst->node, &modules_path);
235   }
236  
237   /* add_conf_module
# Line 273 | Line 245 | add_conf_module(const char *name)
245   {
246    struct module_path *pathst;
247  
248 <  pathst = MyMalloc(sizeof(struct module_path));
249 <
250 <  strlcpy(pathst->path, name, sizeof(pathst->path));
279 <  dlinkAdd(pathst, &pathst->node, &conf_modules);
248 >  pathst = xcalloc(sizeof(*pathst));
249 >  pathst->path = xstrdup(name);
250 >  dlinkAdd(pathst, &pathst->node, &modules_conf);
251   }
252  
253   /* mod_clear_paths()
# Line 286 | Line 257 | add_conf_module(const char *name)
257   * side effects - clear the lists of paths and conf modules
258   */
259   void
260 < mod_clear_paths(void)
260 > modules_conf_clear(void)
261   {
262 <  struct module_path *pathst = NULL;
292 <  dlink_node *ptr = NULL, *next_ptr = NULL;
293 <
294 <  DLINK_FOREACH_SAFE(ptr, next_ptr, mod_paths.head)
262 >  while (modules_path.head)
263    {
264 <    pathst = ptr->data;
264 >    struct module_path *path = modules_path.head->data;
265  
266 <    dlinkDelete(&pathst->node, &mod_paths);
267 <    MyFree(pathst);
266 >    dlinkDelete(&path->node, &modules_path);
267 >    xfree(path->path);
268 >    xfree(path);
269    }
270  
271 <  DLINK_FOREACH_SAFE(ptr, next_ptr, conf_modules.head)
271 >  while (modules_conf.head)
272    {
273 <    pathst = ptr->data;
273 >    struct module_path *path = modules_conf.head->data;
274  
275 <    dlinkDelete(&pathst->node, &conf_modules);
276 <    MyFree(pathst);
275 >    dlinkDelete(&path->node, &modules_conf);
276 >    xfree(path->path);
277 >    xfree(path);
278    }
279   }
280  
# Line 317 | Line 287 | mod_clear_paths(void)
287   struct module *
288   findmodule_byname(const char *name)
289   {
290 <  dlink_node *ptr = NULL;
290 >  dlink_node *node;
291  
292 <  DLINK_FOREACH(ptr, modules_list.head)
292 >  DLINK_FOREACH(node, modules_list.head)
293    {
294 <    struct module *modp = ptr->data;
294 >    struct module *modp = node->data;
295  
296 <    if (strcmp(modp->name, name) == 0)
296 >    if (!strcmp(modp->name, name))
297        return modp;
298    }
299  
# Line 341 | Line 311 | load_all_modules(int warn)
311   {
312    DIR *system_module_dir = NULL;
313    struct dirent *ldirent = NULL;
314 <  char module_fq_name[PATH_MAX + 1];
345 <
346 <  modules_init();
314 >  char module_fq_name[HYB_PATH_MAX + 1];
315  
316    if ((system_module_dir = opendir(AUTOMODPATH)) == NULL)
317    {
# Line 352 | Line 320 | load_all_modules(int warn)
320      return;
321    }
322  
323 <  while ((ldirent = readdir(system_module_dir)) != NULL)
323 >  while ((ldirent = readdir(system_module_dir)))
324    {
325      if (modules_valid_suffix(ldirent->d_name))
326      {
327         snprintf(module_fq_name, sizeof(module_fq_name), "%s/%s",
328                  AUTOMODPATH, ldirent->d_name);
329 <       load_a_module(module_fq_name, warn, 0);
329 >       load_a_module(module_fq_name, warn);
330      }
331    }
332  
# Line 374 | Line 342 | load_all_modules(int warn)
342   void
343   load_conf_modules(void)
344   {
345 <  dlink_node *ptr = NULL;
378 <  struct module_path *mpath = NULL;
345 >  dlink_node *node;
346  
347 <  DLINK_FOREACH(ptr, conf_modules.head)
347 >  DLINK_FOREACH(node, modules_conf.head)
348    {
349 <    mpath = ptr->data;
349 >    struct module_path *mpath = node->data;
350  
351      if (findmodule_byname(mpath->path) == NULL)
352 <      load_one_module(mpath->path, 0);
352 >      load_one_module(mpath->path);
353    }
354   }
355  
# Line 395 | Line 362 | load_conf_modules(void)
362   void
363   load_core_modules(int warn)
364   {
365 <  char module_name[PATH_MAX + 1];
399 <  int i = 0;
365 >  char module_name[HYB_PATH_MAX + 1];
366  
367 <  for (; core_module_table[i]; ++i)
367 >  for (unsigned int i = 0; core_module_table[i]; ++i)
368    {
369      snprintf(module_name, sizeof(module_name), "%s%s",
370               MODPATH, core_module_table[i]);
371  
372 <    if (load_a_module(module_name, warn, 1) == -1)
372 >    if (load_a_module(module_name, warn) == -1)
373      {
374        ilog(LOG_TYPE_IRCD, "Error loading core module %s: terminating ircd",
375             core_module_table[i]);
# Line 416 | Line 382 | load_core_modules(int warn)
382   *
383   * input        - pointer to path
384   *              - flagged as core module or not
385 < * output       - -1 if error
385 > * output       - -1 if error
386   * side effects - module is loaded if found.
387   */
388   int
389 < load_one_module(const char *path, int coremodule)
389 > load_one_module(const char *name)
390   {
391 <  dlink_node *ptr = NULL;
392 <  char modpath[PATH_MAX + 1];
391 >  dlink_node *node;
392 >  char path[HYB_PATH_MAX + 1];
393    struct stat statbuf;
394  
395 <  DLINK_FOREACH(ptr, mod_paths.head)
395 >  DLINK_FOREACH(node, modules_path.head)
396    {
397 <    const struct module_path *mpath = ptr->data;
397 >    const struct module_path *mpath = node->data;
398  
399 <    snprintf(modpath, sizeof(modpath), "%s/%s", mpath->path, path);
399 >    snprintf(path, sizeof(path), "%s/%s", mpath->path, name);
400  
401 <    if (!modules_valid_suffix(path))
401 >    if (!modules_valid_suffix(name))
402        continue;
403  
404 <    if (strstr(modpath, "../") == NULL &&
405 <        strstr(modpath, "/..") == NULL)
406 <    {
407 <      if (!stat(modpath, &statbuf))
408 <      {
443 <        if (S_ISREG(statbuf.st_mode))
444 <        {
445 <          /* Regular files only please */
446 <          return load_a_module(modpath, 1, coremodule);
447 <        }
448 <      }
449 <    }
404 >    if (strstr(path, "../") == NULL &&
405 >        strstr(path, "/..") == NULL)
406 >      if (!stat(path, &statbuf))
407 >        if (S_ISREG(statbuf.st_mode))  /* Regular files only please */
408 >          return load_a_module(path, 1);
409    }
410  
411 <  sendto_realops_flags(UMODE_ALL, L_ALL,
412 <                       "Cannot locate module %s", path);
413 <  ilog(LOG_TYPE_IRCD, "Cannot locate module %s", path);
411 >  sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
412 >                       "Cannot locate module %s", name);
413 >  ilog(LOG_TYPE_IRCD, "Cannot locate module %s", name);
414    return -1;
415   }
457
458 /* load a module .. */
459 static void
460 mo_modload(struct Client *client_p, struct Client *source_p,
461           int parc, char *parv[])
462 {
463  const char *m_bn = NULL;
464
465  if (!HasOFlag(source_p, OPER_FLAG_MODULE))
466  {
467    sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
468               me.name, source_p->name);
469    return;
470  }
471
472  m_bn = libio_basename(parv[1]);
473
474  if (findmodule_byname(m_bn) != NULL)
475  {
476    sendto_one(source_p, ":%s NOTICE %s :Module %s is already loaded",
477               me.name, source_p->name, m_bn);
478    return;
479  }
480
481  load_one_module(parv[1], 0);
482 }
483
484 /* unload a module .. */
485 static void
486 mo_modunload(struct Client *client_p, struct Client *source_p,
487             int parc, char *parv[])
488 {
489  const char *m_bn = NULL;
490  struct module *modp = NULL;
491
492  if (!HasOFlag(source_p, OPER_FLAG_MODULE))
493  {
494    sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
495               me.name, source_p->name);
496    return;
497  }
498
499  m_bn = libio_basename(parv[1]);
500
501  if ((modp = findmodule_byname(m_bn)) == NULL)
502  {
503    sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
504               me.name, source_p->name, m_bn);
505    return;
506  }
507
508  if (modp->flags & MODULE_FLAG_CORE)
509  {
510    sendto_one(source_p,
511               ":%s NOTICE %s :Module %s is a core module and may not be unloaded",
512               me.name, source_p->name, m_bn);
513    return;
514  }
515
516  if (unload_one_module(m_bn, 1) == -1)
517  {
518    sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
519               me.name, source_p->name, m_bn);
520  }
521 }
522
523 /* unload and load in one! */
524 static void
525 mo_modreload(struct Client *client_p, struct Client *source_p,
526             int parc, char *parv[])
527 {
528  const char *m_bn = NULL;
529  struct module *modp = NULL;
530  int check_core;
531
532  if (!HasOFlag(source_p, OPER_FLAG_MODULE))
533  {
534    sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
535               me.name, source_p->name);
536    return;
537  }
538
539  m_bn = libio_basename(parv[1]);
540
541  if ((modp = findmodule_byname(m_bn)) == NULL)
542  {
543    sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
544               me.name, source_p->name, m_bn);
545    return;
546  }
547
548  check_core = (modp->flags & MODULE_FLAG_CORE) != 0;
549
550  if (unload_one_module(m_bn, 1) == -1)
551  {
552    sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
553               me.name, source_p->name, m_bn);
554    return;
555  }
556
557  if ((load_one_module(parv[1], check_core) == -1) && check_core)
558  {
559    sendto_realops_flags(UMODE_ALL, L_ALL, "Error reloading core "
560                         "module: %s: terminating ircd", parv[1]);
561    ilog(LOG_TYPE_IRCD, "Error loading core module %s: terminating ircd", parv[1]);
562    exit(0);
563  }
564 }
565
566 /* list modules .. */
567 static void
568 mo_modlist(struct Client *client_p, struct Client *source_p,
569           int parc, char *parv[])
570 {
571  const dlink_node *ptr = NULL;
572
573  if (!HasOFlag(source_p, OPER_FLAG_MODULE))
574  {
575    sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
576               me.name, source_p->name);
577    return;
578  }
579
580  DLINK_FOREACH(ptr, modules_list.head)
581  {
582    const struct module *modp = ptr->data;
583
584    if (parc > 1 && !match(parv[1], modp->name))
585      continue;
586
587    sendto_one(source_p, form_str(RPL_MODLIST), me.name, source_p->name,
588               modp->name, modp->handle,
589               modp->version, (modp->flags & MODULE_FLAG_CORE) ?"(core)":"");
590  }
591
592  sendto_one(source_p, form_str(RPL_ENDOFMODLIST),
593             me.name, source_p->name);
594 }
595
596 /* unload and reload all modules */
597 static void
598 mo_modrestart(struct Client *client_p, struct Client *source_p,
599              int parc, char *parv[])
600 {
601  unsigned int modnum = 0;
602  dlink_node *ptr = NULL, *ptr_next = NULL;
603
604  if (!HasOFlag(source_p, OPER_FLAG_MODULE))
605  {
606    sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
607               me.name, source_p->name);
608    return;
609  }
610
611  sendto_one(source_p, ":%s NOTICE %s :Reloading all modules",
612             me.name, source_p->name);
613
614  modnum = dlink_list_length(&modules_list);
615
616  DLINK_FOREACH_SAFE(ptr, ptr_next, modules_list.head)
617  {
618    struct module *modp = ptr->data;
619    unload_one_module(modp->name, 0);
620  }
621
622  load_all_modules(0);
623  load_conf_modules();
624  load_core_modules(0);
625
626  sendto_realops_flags(UMODE_ALL, L_ALL,
627                      "Module Restart: %u modules unloaded, %u modules loaded",
628                        modnum, dlink_list_length(&modules_list));
629  ilog(LOG_TYPE_IRCD, "Module Restart: %u modules unloaded, %u modules loaded",
630       modnum, dlink_list_length(&modules_list));
631 }

Comparing:
ircd-hybrid-8/src/modules.c (property svn:keywords), Revision 1309 by michael, Sun Mar 25 11:24:18 2012 UTC vs.
ircd-hybrid/trunk/src/modules.c (property svn:keywords), Revision 8431 by michael, Tue Mar 27 18:49:15 2018 UTC

# Line 1 | Line 1
1 < Id Revision
1 > Id

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)