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 1237 by michael, Thu Sep 29 11:32:21 2011 UTC vs.
Revision 1437 by michael, Mon Jun 18 19:02:48 2012 UTC

# Line 27 | Line 27
27   #include "stdinc.h"
28   #include "list.h"
29   #include "modules.h"
30 < #include "s_log.h"
30 > #include "log.h"
31   #include "ircd.h"
32   #include "client.h"
33   #include "send.h"
34 < #include "s_conf.h"
35 < #include "handlers.h"
34 > #include "conf.h"
35   #include "numeric.h"
36   #include "parse.h"
37   #include "ircd_defs.h"
# Line 40 | Line 39
39   #include "memory.h"
40  
41  
42 < dlink_list mod_list = { NULL, NULL, 0 };
44 <
42 > static dlink_list modules_list = { NULL, NULL, 0 };
43  
44   static const char *unknown_ver = "<unknown>";
45  
# Line 66 | Line 64 | static const char *core_module_table[] =
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 *[]);
70 < static void mo_modlist(struct Client *, struct Client *, int, char *[]);
71 < static void mo_modreload(struct Client *, struct Client *, int, char *[]);
72 < static void mo_modunload(struct Client *, struct Client *, int, char *[]);
73 < static void mo_modrestart(struct Client *, struct Client *, int, char *[]);
74 <
75 < struct Message modload_msgtab = {
76 < "MODLOAD", 0, 0, 2, 0, MFLG_SLOW, 0,
77 <  {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modload, m_ignore}
78 < };
79 <
80 < struct Message modunload_msgtab = {
81 < "MODUNLOAD", 0, 0, 2, 0, MFLG_SLOW, 0,
82 <  {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modunload, m_ignore}
83 < };
84 <
85 < struct Message modreload_msgtab = {
86 <  "MODRELOAD", 0, 0, 2, 0, MFLG_SLOW, 0,
87 <  {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modreload, m_ignore}
88 < };
89 <
90 < struct Message modlist_msgtab = {
91 < "MODLIST", 0, 0, 0, 0, MFLG_SLOW, 0,
92 <  {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modlist, m_ignore}
93 < };
67 > static void mo_module(struct Client *, struct Client *, int, char *[]);
68  
69 < struct Message modrestart_msgtab = {
70 < "MODRESTART", 0, 0, 0, 0, MFLG_SLOW, 0,
71 < {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_modrestart, m_ignore}
69 > struct Message module_msgtab = {
70 > "MODULE", 0, 0, 2, 0, MFLG_SLOW, 0,
71 >  {m_unregistered, m_not_oper, m_ignore, m_ignore, mo_module, m_ignore}
72   };
73  
100
74   int
75   modules_valid_suffix(const char *name)
76   {
# Line 122 | Line 95 | unload_one_module(const char *name, int
95    if (modp->modexit)
96     modp->modexit();
97  
98 <  assert(dlink_list_length(&mod_list) > 0);
99 <  dlinkDelete(&modp->node, &mod_list);
98 >  assert(dlink_list_length(&modules_list) > 0);
99 >  dlinkDelete(&modp->node, &modules_list);
100    MyFree(modp->name);
101  
102    lt_dlclose(modp->handle);
103  
104    if (warn == 1)
105    {
106 <    ilog(L_INFO, "Module %s unloaded", name);
106 >    ilog(LOG_TYPE_IRCD, "Module %s unloaded", name);
107      sendto_realops_flags(UMODE_ALL, L_ALL, "Module %s unloaded", name);
108    }
109  
# Line 144 | Line 117 | unload_one_module(const char *name, int
117   * side effects - loads a module if successful
118   */
119   int
120 < load_a_module(const char *path, int warn, int core)
120 > load_a_module(const char *path, int warn)
121   {
122    lt_dlhandle tmpptr = NULL;
123    const char *mod_basename = NULL;
# Line 158 | Line 131 | load_a_module(const char *path, int warn
131  
132      sendto_realops_flags(UMODE_ALL, L_ALL, "Error loading module %s: %s",
133                           mod_basename, err);
134 <    ilog(L_WARN, "Error loading module %s: %s", mod_basename, err);
134 >    ilog(LOG_TYPE_IRCD, "Error loading module %s: %s", mod_basename, err);
135      return -1;
136    }
137  
# Line 166 | Line 139 | load_a_module(const char *path, int warn
139    {
140      sendto_realops_flags(UMODE_ALL, L_ALL, "Module %s has no module_entry export",
141                           mod_basename);
142 <    ilog(L_WARN, "Module %s has no module_entry export", mod_basename);
142 >    ilog(LOG_TYPE_IRCD, "Module %s has no module_entry export", mod_basename);
143      lt_dlclose(tmpptr);
144      return -1;
145    }
# Line 176 | Line 149 | load_a_module(const char *path, int warn
149    if (EmptyString(modp->version))
150      modp->version = unknown_ver;
151  
179  if (core)
180    modp->flags |= MODULE_FLAG_CORE;
181
152    DupString(modp->name, mod_basename);
153 <  dlinkAdd(modp, &modp->node, &mod_list);
153 >  dlinkAdd(modp, &modp->node, &modules_list);
154  
155    if (modp->modinit)
156      modp->modinit();
# Line 190 | Line 160 | load_a_module(const char *path, int warn
160      sendto_realops_flags(UMODE_ALL, L_ALL,
161                           "Module %s [version: %s handle: %p] loaded.",
162                           modp->name, modp->version, tmpptr);
163 <    ilog(L_WARN, "Module %s [version: %s handle: %p] loaded.",
163 >    ilog(LOG_TYPE_IRCD, "Module %s [version: %s handle: %p] loaded.",
164           modp->name, modp->version, tmpptr);
165    }
166  
# Line 209 | Line 179 | modules_init(void)
179   {
180    if (lt_dlinit())
181    {
182 <    ilog(L_ERROR, "Couldn't initialize the libltdl run time dynamic"
182 >    ilog(LOG_TYPE_IRCD, "Couldn't initialize the libltdl run time dynamic"
183           " link library. Exiting.");
184      exit(0);
185    }
186  
187 <  mod_add_cmd(&modload_msgtab);
218 <  mod_add_cmd(&modunload_msgtab);
219 <  mod_add_cmd(&modreload_msgtab);
220 <  mod_add_cmd(&modlist_msgtab);
221 <  mod_add_cmd(&modrestart_msgtab);
187 >  mod_add_cmd(&module_msgtab);
188   }
189  
190   /* mod_find_path()
# Line 231 | Line 197 | static struct module_path *
197   mod_find_path(const char *path)
198   {
199    dlink_node *ptr;
234  struct module_path *mpath;
200  
201    DLINK_FOREACH(ptr, mod_paths.head)
202    {
203 <    mpath = ptr->data;
203 >    struct module_path *mpath = ptr->data;
204  
205      if (!strcmp(path, mpath->path))
206        return mpath;
# Line 290 | Line 255 | add_conf_module(const char *name)
255   void
256   mod_clear_paths(void)
257   {
293  struct module_path *pathst = NULL;
258    dlink_node *ptr = NULL, *next_ptr = NULL;
259  
260    DLINK_FOREACH_SAFE(ptr, next_ptr, mod_paths.head)
261    {
262 <    pathst = ptr->data;
263 <
300 <    dlinkDelete(&pathst->node, &mod_paths);
301 <    MyFree(pathst);
262 >    dlinkDelete(ptr, &mod_paths);
263 >    MyFree(ptr->data);
264    }
265  
266    DLINK_FOREACH_SAFE(ptr, next_ptr, conf_modules.head)
267    {
268 <    pathst = ptr->data;
269 <
308 <    dlinkDelete(&pathst->node, &conf_modules);
309 <    MyFree(pathst);
268 >    dlinkDelete(ptr, &conf_modules);
269 >    MyFree(ptr->data);
270    }
271   }
272  
# Line 321 | Line 281 | findmodule_byname(const char *name)
281   {
282    dlink_node *ptr = NULL;
283  
284 <  DLINK_FOREACH(ptr, mod_list.head)
284 >  DLINK_FOREACH(ptr, modules_list.head)
285    {
286      struct module *modp = ptr->data;
287  
# Line 345 | Line 305 | load_all_modules(int warn)
305    struct dirent *ldirent = NULL;
306    char module_fq_name[PATH_MAX + 1];
307  
348  modules_init();
349
308    if ((system_module_dir = opendir(AUTOMODPATH)) == NULL)
309    {
310 <    ilog(L_WARN, "Could not load modules from %s: %s",
310 >    ilog(LOG_TYPE_IRCD, "Could not load modules from %s: %s",
311           AUTOMODPATH, strerror(errno));
312      return;
313    }
# Line 360 | Line 318 | load_all_modules(int warn)
318      {
319         snprintf(module_fq_name, sizeof(module_fq_name), "%s/%s",
320                  AUTOMODPATH, ldirent->d_name);
321 <       load_a_module(module_fq_name, warn, 0);
321 >       load_a_module(module_fq_name, warn);
322      }
323    }
324  
# Line 377 | Line 335 | void
335   load_conf_modules(void)
336   {
337    dlink_node *ptr = NULL;
380  struct module_path *mpath = NULL;
338  
339    DLINK_FOREACH(ptr, conf_modules.head)
340    {
341 <    mpath = ptr->data;
341 >    struct module_path *mpath = ptr->data;
342  
343      if (findmodule_byname(mpath->path) == NULL)
344 <      load_one_module(mpath->path, 0);
344 >      load_one_module(mpath->path);
345    }
346   }
347  
# Line 405 | Line 362 | load_core_modules(int warn)
362      snprintf(module_name, sizeof(module_name), "%s%s",
363               MODPATH, core_module_table[i]);
364  
365 <    if (load_a_module(module_name, warn, 1) == -1)
365 >    if (load_a_module(module_name, warn) == -1)
366      {
367 <      ilog(L_CRIT, "Error loading core module %s: terminating ircd",
367 >      ilog(LOG_TYPE_IRCD, "Error loading core module %s: terminating ircd",
368             core_module_table[i]);
369        exit(EXIT_FAILURE);
370      }
# Line 422 | Line 379 | load_core_modules(int warn)
379   * side effects - module is loaded if found.
380   */
381   int
382 < load_one_module(const char *path, int coremodule)
382 > load_one_module(const char *path)
383   {
384    dlink_node *ptr = NULL;
385    char modpath[PATH_MAX + 1];
# Line 439 | Line 396 | load_one_module(const char *path, int co
396  
397      if (strstr(modpath, "../") == NULL &&
398          strstr(modpath, "/..") == NULL)
442    {
399        if (!stat(modpath, &statbuf))
400 <      {
401 <        if (S_ISREG(statbuf.st_mode))
446 <        {
447 <          /* Regular files only please */
448 <          return load_a_module(modpath, 1, coremodule);
449 <        }
450 <      }
451 <    }
400 >        if (S_ISREG(statbuf.st_mode))  /* Regular files only please */
401 >          return load_a_module(modpath, 1);
402    }
403  
404    sendto_realops_flags(UMODE_ALL, L_ALL,
405                         "Cannot locate module %s", path);
406 <  ilog(L_WARN, "Cannot locate module %s", path);
406 >  ilog(LOG_TYPE_IRCD, "Cannot locate module %s", path);
407    return -1;
408   }
409  
410 < /* load a module .. */
410 > /*! \brief MODULE command handler (called by operators)
411 > *
412 > * \param client_p Pointer to allocated Client struct with physical connection
413 > *                 to this server, i.e. with an open socket connected.
414 > * \param source_p Pointer to allocated Client struct from which the message
415 > *                 originally comes from.  This can be a local or remote client.
416 > * \param parc     Integer holding the number of supplied arguments.
417 > * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
418 > *                 pointers.
419 > * \note Valid arguments for this command are:
420 > *      - parv[0] = sender prefix
421 > *      - parv[1] = action [LOAD, UNLOAD, RELOAD, LIST]
422 > *      - parv[2] = module name
423 > */
424   static void
425 < mo_modload(struct Client *client_p, struct Client *source_p,
426 <           int parc, char *parv[])
425 > mo_module(struct Client *client_p, struct Client *source_p,
426 >          int parc, char *parv[])
427   {
428    const char *m_bn = NULL;
429 +  struct module *modp = NULL;
430 +  int check_core;
431  
432    if (!HasOFlag(source_p, OPER_FLAG_MODULE))
433    {
# Line 471 | Line 436 | mo_modload(struct Client *client_p, stru
436      return;
437    }
438  
439 <  m_bn = libio_basename(parv[1]);
475 <
476 <  if (findmodule_byname(m_bn) != NULL)
439 >  if (EmptyString(parv[1]))
440    {
441 <    sendto_one(source_p, ":%s NOTICE %s :Module %s is already loaded",
442 <               me.name, source_p->name, m_bn);
441 >    sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
442 >               me.name, source_p->name, "MODULE");
443      return;
444    }
445  
446 <  load_one_module(parv[1], 0);
484 < }
485 <
486 < /* unload a module .. */
487 < static void
488 < mo_modunload(struct Client *client_p, struct Client *source_p,
489 <             int parc, char *parv[])
490 < {
491 <  const char *m_bn = NULL;
492 <  struct module *modp = NULL;
493 <
494 <  if (!HasOFlag(source_p, OPER_FLAG_MODULE))
446 >  if (!irccmp(parv[1], "LOAD"))
447    {
448 <    sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
449 <               me.name, source_p->name);
450 <    return;
451 <  }
452 <
453 <  m_bn = libio_basename(parv[1]);
448 >    if (findmodule_byname((m_bn = libio_basename(parv[2]))) != NULL)
449 >    {
450 >      sendto_one(source_p, ":%s NOTICE %s :Module %s is already loaded",
451 >                 me.name, source_p->name, m_bn);
452 >      return;
453 >    }
454  
455 <  if ((modp = findmodule_byname(m_bn)) == NULL)
504 <  {
505 <    sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
506 <               me.name, source_p->name, m_bn);
455 >    load_one_module(parv[2]);
456      return;
457    }
458  
459 <  if (modp->flags & MODULE_FLAG_CORE)
459 >  if (!irccmp(parv[1], "UNLOAD"))
460    {
461 <    sendto_one(source_p,
462 <               ":%s NOTICE %s :Module %s is a core module and may not be unloaded",
463 <               me.name, source_p->name, m_bn);
461 >    if ((modp = findmodule_byname((m_bn = libio_basename(parv[2])))) == NULL)
462 >    {
463 >      sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
464 >                 me.name, source_p->name, m_bn);
465 >      return;
466 >    }
467 >
468 >    if (modp->flags & MODULE_FLAG_CORE)
469 >    {
470 >      sendto_one(source_p,
471 >                 ":%s NOTICE %s :Module %s is a core module and may not be unloaded",
472 >                 me.name, source_p->name, m_bn);
473 >      return;
474 >    }
475 >
476 >    if (unload_one_module(m_bn, 1) == -1)
477 >      sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
478 >                 me.name, source_p->name, m_bn);
479      return;
480    }
481  
482 <  if (unload_one_module(m_bn, 1) == -1)
482 >  if (!irccmp(parv[1], "RELOAD"))
483    {
484 <    sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
485 <               me.name, source_p->name, m_bn);
486 <  }
487 < }
524 <
525 < /* unload and load in one! */
526 < static void
527 < mo_modreload(struct Client *client_p, struct Client *source_p,
528 <             int parc, char *parv[])
529 < {
530 <  const char *m_bn = NULL;
531 <  struct module *modp = NULL;
532 <  int check_core;
484 >    if (!strcmp(parv[2], "*"))
485 >    {
486 >      unsigned int modnum = 0;
487 >      dlink_node *ptr = NULL, *ptr_next = NULL;
488  
489 <  if (!HasOFlag(source_p, OPER_FLAG_MODULE))
490 <  {
536 <    sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
537 <               me.name, source_p->name);
538 <    return;
539 <  }
489 >      sendto_one(source_p, ":%s NOTICE %s :Reloading all modules",
490 >                 me.name, source_p->name);
491  
492 <  m_bn = libio_basename(parv[1]);
492 >      modnum = dlink_list_length(&modules_list);
493  
494 <  if ((modp = findmodule_byname(m_bn)) == NULL)
495 <  {
496 <    sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
497 <               me.name, source_p->name, m_bn);
498 <    return;
548 <  }
494 >      DLINK_FOREACH_SAFE(ptr, ptr_next, modules_list.head)
495 >      {
496 >        modp = ptr->data;
497 >        unload_one_module(modp->name, 0);
498 >      }
499  
500 <  check_core = (modp->flags & MODULE_FLAG_CORE) != 0;
500 >      load_all_modules(0);
501 >      load_conf_modules();
502 >      load_core_modules(0);
503 >
504 >      sendto_realops_flags(UMODE_ALL, L_ALL,
505 >                           "Module Restart: %u modules unloaded, %u modules loaded",
506 >                           modnum, dlink_list_length(&modules_list));
507 >      ilog(LOG_TYPE_IRCD, "Module Restart: %u modules unloaded, %u modules loaded",
508 >           modnum, dlink_list_length(&modules_list));
509 >      return;
510 >    }
511  
512 <  if (unload_one_module(m_bn, 1) == -1)
513 <  {
514 <    sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
512 >    if ((modp = findmodule_byname((m_bn = libio_basename(parv[2])))) == NULL)
513 >    {
514 >      sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
515                 me.name, source_p->name, m_bn);
516 <    return;
517 <  }
516 >      return;
517 >    }
518  
519 <  if ((load_one_module(parv[1], check_core) == -1) && check_core)
560 <  {
561 <    sendto_realops_flags(UMODE_ALL, L_ALL, "Error reloading core "
562 <                         "module: %s: terminating ircd", parv[1]);
563 <    ilog(L_CRIT, "Error loading core module %s: terminating ircd", parv[1]);
564 <    exit(0);
565 <  }
566 < }
519 >    check_core = (modp->flags & MODULE_FLAG_CORE) != 0;
520  
521 < /* list modules .. */
522 < static void
523 < mo_modlist(struct Client *client_p, struct Client *source_p,
524 <           int parc, char *parv[])
525 < {
526 <  const dlink_node *ptr = NULL;
521 >    if (unload_one_module(m_bn, 1) == -1)
522 >    {
523 >      sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
524 >                 me.name, source_p->name, m_bn);
525 >      return;
526 >    }
527 >
528 >    if ((load_one_module(parv[2]) == -1) && check_core)
529 >    {
530 >      sendto_realops_flags(UMODE_ALL, L_ALL, "Error reloading core "
531 >                           "module: %s: terminating ircd", parv[2]);
532 >      ilog(LOG_TYPE_IRCD, "Error loading core module %s: terminating ircd", parv[2]);
533 >      exit(0);
534 >    }
535  
575  if (!HasOFlag(source_p, OPER_FLAG_MODULE))
576  {
577    sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
578               me.name, source_p->name);
536      return;
537    }
538  
539 <  DLINK_FOREACH(ptr, mod_list.head)
539 >  if (!irccmp(parv[1], "LIST"))
540    {
541 <    const struct module *modp = ptr->data;
585 <
586 <    if (parc > 1 && !match(parv[1], modp->name))
587 <      continue;
588 <
589 <    sendto_one(source_p, form_str(RPL_MODLIST), me.name, source_p->name,
590 <               modp->name, modp->handle,
591 <               modp->version, (modp->flags & MODULE_FLAG_CORE) ?"(core)":"");
592 <  }
541 >    const dlink_node *ptr = NULL;
542  
543 <  sendto_one(source_p, form_str(RPL_ENDOFMODLIST),
544 <             me.name, source_p->name);
545 < }
543 >    DLINK_FOREACH(ptr, modules_list.head)
544 >    {
545 >      if (parc > 2 && !match(parv[2], modp->name))
546 >        continue;
547  
548 < /* unload and reload all modules */
549 < static void
550 < mo_modrestart(struct Client *client_p, struct Client *source_p,
551 <              int parc, char *parv[])
602 < {
603 <  unsigned int modnum = 0;
604 <  dlink_node *ptr = NULL, *ptr_next = NULL;
548 >      sendto_one(source_p, form_str(RPL_MODLIST), me.name, source_p->name,
549 >                 modp->name, modp->handle,
550 >                 modp->version, (modp->flags & MODULE_FLAG_CORE) ?"(core)":"");
551 >    }
552  
553 <  if (!HasOFlag(source_p, OPER_FLAG_MODULE))
607 <  {
608 <    sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
553 >    sendto_one(source_p, form_str(RPL_ENDOFMODLIST),
554                 me.name, source_p->name);
555      return;
556    }
612
613  sendto_one(source_p, ":%s NOTICE %s :Reloading all modules",
614             me.name, source_p->name);
615
616  modnum = dlink_list_length(&mod_list);
617
618  DLINK_FOREACH_SAFE(ptr, ptr_next, mod_list.head)
619  {
620    struct module *modp = ptr->data;
621    unload_one_module(modp->name, 0);
622  }
623
624  load_all_modules(0);
625  load_conf_modules();
626  load_core_modules(0);
627
628  sendto_realops_flags(UMODE_ALL, L_ALL,
629              "Module Restart: %u modules unloaded, %u modules loaded",
630                        modnum, dlink_list_length(&mod_list));
631  ilog(L_WARN, "Module Restart: %u modules unloaded, %u modules loaded",
632       modnum, dlink_list_length(&mod_list));
557   }

Diff Legend

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