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-7.2/src/modules.c (file contents), Revision 978 by michael, Sun Aug 9 09:47:58 2009 UTC vs.
ircd-hybrid-8/src/modules.c (file contents), Revision 1247 by michael, Sat Oct 1 07:54:24 2011 UTC

# Line 22 | Line 22
22   *  $Id$
23   */
24  
25 + #include "ltdl.h"
26 +
27   #include "stdinc.h"
28 < #include "tools.h"
28 > #include "list.h"
29   #include "modules.h"
30   #include "s_log.h"
31   #include "ircd.h"
32   #include "client.h"
33   #include "send.h"
34   #include "s_conf.h"
33 #include "handlers.h"
35   #include "numeric.h"
36   #include "parse.h"
37   #include "ircd_defs.h"
38   #include "irc_string.h"
39   #include "memory.h"
39 #include "list.h"
40  
41  
42 < dlink_list mod_list = { NULL, NULL, 0 };
42 > static dlink_list modules_list = { NULL, NULL, 0 };
43 >
44 > static const char *unknown_ver = "<unknown>";
45  
46   static const char *core_module_table[] =
47   {
# Line 94 | Line 96 | struct Message modrestart_msgtab = {
96   };
97  
98  
99 < extern struct Message error_msgtab;
99 > int
100 > modules_valid_suffix(const char *name)
101 > {
102 >  return ((name = strrchr(name, '.'))) && !strcmp(name, ".la");
103 > }
104 >
105 > /* unload_one_module()
106 > *
107 > * inputs       - name of module to unload
108 > *              - 1 to say modules unloaded, 0 to not
109 > * output       - 0 if successful, -1 if error
110 > * side effects - module is unloaded
111 > */
112 > int
113 > unload_one_module(const char *name, int warn)
114 > {
115 >  struct module *modp = NULL;
116 >
117 >  if ((modp = findmodule_byname(name)) == NULL)
118 >    return -1;
119 >
120 >  if (modp->modexit)
121 >   modp->modexit();
122 >
123 >  assert(dlink_list_length(&modules_list) > 0);
124 >  dlinkDelete(&modp->node, &modules_list);
125 >  MyFree(modp->name);
126 >
127 >  lt_dlclose(modp->handle);
128 >
129 >  if (warn == 1)
130 >  {
131 >    ilog(LOG_TYPE_IRCD, "Module %s unloaded", name);
132 >    sendto_realops_flags(UMODE_ALL, L_ALL, "Module %s unloaded", name);
133 >  }
134 >
135 >  return 0;
136 > }
137 >
138 > /* load_a_module()
139 > *
140 > * inputs       - path name of module, int to notice, int of core
141 > * output       - -1 if error 0 if success
142 > * side effects - loads a module if successful
143 > */
144 > int
145 > load_a_module(const char *path, int warn, int core)
146 > {
147 >  lt_dlhandle tmpptr = NULL;
148 >  const char *mod_basename = NULL;
149 >  struct module *modp = NULL;
150 >
151 >  if (findmodule_byname((mod_basename = libio_basename(path))))
152 >    return 1;
153 >
154 >  if (!(tmpptr = lt_dlopen(path))) {
155 >    const char *err = ((err = lt_dlerror())) ? err : "<unknown>";
156 >
157 >    sendto_realops_flags(UMODE_ALL, L_ALL, "Error loading module %s: %s",
158 >                         mod_basename, err);
159 >    ilog(LOG_TYPE_IRCD, "Error loading module %s: %s", mod_basename, err);
160 >    return -1;
161 >  }
162 >
163 >  if ((modp = lt_dlsym(tmpptr, "module_entry")) == NULL)
164 >  {
165 >    sendto_realops_flags(UMODE_ALL, L_ALL, "Module %s has no module_entry export",
166 >                         mod_basename);
167 >    ilog(LOG_TYPE_IRCD, "Module %s has no module_entry export", mod_basename);
168 >    lt_dlclose(tmpptr);
169 >    return -1;
170 >  }
171 >
172 >  modp->handle = tmpptr;
173 >
174 >  if (EmptyString(modp->version))
175 >    modp->version = unknown_ver;
176 >
177 >  if (core)
178 >    modp->flags |= MODULE_FLAG_CORE;
179 >
180 >  DupString(modp->name, mod_basename);
181 >  dlinkAdd(modp, &modp->node, &modules_list);
182 >
183 >  if (modp->modinit)
184 >    modp->modinit();
185 >
186 >  if (warn == 1)
187 >  {
188 >    sendto_realops_flags(UMODE_ALL, L_ALL,
189 >                         "Module %s [version: %s handle: %p] loaded.",
190 >                         modp->name, modp->version, tmpptr);
191 >    ilog(LOG_TYPE_IRCD, "Module %s [version: %s handle: %p] loaded.",
192 >         modp->name, modp->version, tmpptr);
193 >  }
194 >
195 >  return 0;
196 > }
197  
198   /*
199   * modules_init
# Line 106 | Line 205 | extern struct Message error_msgtab;
205   void
206   modules_init(void)
207   {
208 <  dynlink_init();
208 >  if (lt_dlinit())
209 >  {
210 >    ilog(LOG_TYPE_IRCD, "Couldn't initialize the libltdl run time dynamic"
211 >         " link library. Exiting.");
212 >    exit(0);
213 >  }
214  
215    mod_add_cmd(&modload_msgtab);
216    mod_add_cmd(&modunload_msgtab);
# Line 184 | Line 288 | add_conf_module(const char *name)
288   void
289   mod_clear_paths(void)
290   {
291 <  struct module_path *pathst;
292 <  dlink_node *ptr;
189 <  dlink_node *next_ptr;
291 >  struct module_path *pathst = NULL;
292 >  dlink_node *ptr = NULL, *next_ptr = NULL;
293  
294    DLINK_FOREACH_SAFE(ptr, next_ptr, mod_paths.head)
295    {
# Line 211 | Line 314 | mod_clear_paths(void)
314   * output       - NULL if not found or pointer to module
315   * side effects - NONE
316   */
317 < dlink_node *
317 > struct module *
318   findmodule_byname(const char *name)
319   {
320 <  dlink_node *ptr;
218 <  struct module *modp;
320 >  dlink_node *ptr = NULL;
321  
322 <  DLINK_FOREACH(ptr, mod_list.head)
322 >  DLINK_FOREACH(ptr, modules_list.head)
323    {
324 <    modp = ptr->data;
324 >    struct module *modp = ptr->data;
325  
326      if (strcmp(modp->name, name) == 0)
327 <      return ptr;
327 >      return modp;
328    }
329  
330    return NULL;
# Line 245 | Line 347 | load_all_modules(int warn)
347  
348    if ((system_module_dir = opendir(AUTOMODPATH)) == NULL)
349    {
350 <    ilog(L_WARN, "Could not load modules from %s: %s",
350 >    ilog(LOG_TYPE_IRCD, "Could not load modules from %s: %s",
351           AUTOMODPATH, strerror(errno));
352      return;
353    }
# Line 303 | Line 405 | load_core_modules(int warn)
405  
406      if (load_a_module(module_name, warn, 1) == -1)
407      {
408 <      ilog(L_CRIT, "Error loading core module %s: terminating ircd",
408 >      ilog(LOG_TYPE_IRCD, "Error loading core module %s: terminating ircd",
409             core_module_table[i]);
410        exit(EXIT_FAILURE);
411      }
# Line 349 | Line 451 | load_one_module(const char *path, int co
451  
452    sendto_realops_flags(UMODE_ALL, L_ALL,
453                         "Cannot locate module %s", path);
454 <  ilog(L_WARN, "Cannot locate module %s", path);
454 >  ilog(LOG_TYPE_IRCD, "Cannot locate module %s", path);
455    return -1;
456   }
457  
# Line 360 | Line 462 | mo_modload(struct Client *client_p, stru
462   {
463    const char *m_bn = NULL;
464  
465 <  if (!IsAdmin(source_p))
465 >  if (!HasOFlag(source_p, OPER_FLAG_MODULE))
466    {
467      sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
468                 me.name, source_p->name);
# Line 385 | Line 487 | mo_modunload(struct Client *client_p, st
487               int parc, char *parv[])
488   {
489    const char *m_bn = NULL;
490 <  dlink_node *ptr;
389 <  struct module *modp;
490 >  struct module *modp = NULL;
491  
492 <  if (!IsAdmin(source_p))
492 >  if (!HasOFlag(source_p, OPER_FLAG_MODULE))
493    {
494      sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
495                 me.name, source_p->name);
# Line 397 | Line 498 | mo_modunload(struct Client *client_p, st
498  
499    m_bn = libio_basename(parv[1]);
500  
501 <  if ((ptr = findmodule_byname(m_bn)) == NULL)
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 <  modp = ptr->data;
408 <
409 <  if (modp->core == 1)
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",
# Line 414 | Line 513 | mo_modunload(struct Client *client_p, st
513      return;
514    }
515  
417  /* XXX might want to simply un dlink it here */
418
516    if (unload_one_module(m_bn, 1) == -1)
517    {
518      sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
# Line 429 | Line 526 | mo_modreload(struct Client *client_p, st
526               int parc, char *parv[])
527   {
528    const char *m_bn = NULL;
529 <  dlink_node *ptr;
433 <  struct module *modp;
529 >  struct module *modp = NULL;
530    int check_core;
531  
532 <  if (!IsAdmin(source_p))
532 >  if (!HasOFlag(source_p, OPER_FLAG_MODULE))
533    {
534      sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
535                 me.name, source_p->name);
# Line 442 | Line 538 | mo_modreload(struct Client *client_p, st
538  
539    m_bn = libio_basename(parv[1]);
540  
541 <  if ((ptr = findmodule_byname(m_bn)) == NULL)
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 <  modp = ptr->data;
453 <  check_core = modp->core;
548 >  check_core = (modp->flags & MODULE_FLAG_CORE) != 0;
549  
550    if (unload_one_module(m_bn, 1) == -1)
551    {
# Line 463 | Line 558 | mo_modreload(struct Client *client_p, st
558    {
559      sendto_realops_flags(UMODE_ALL, L_ALL, "Error reloading core "
560                           "module: %s: terminating ircd", parv[1]);
561 <    ilog(L_CRIT, "Error loading core 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   }
# Line 475 | Line 570 | mo_modlist(struct Client *client_p, stru
570   {
571    const dlink_node *ptr = NULL;
572  
573 <  if (!IsAdmin(source_p))
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, mod_list.head)
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, parv[0],
587 >    sendto_one(source_p, form_str(RPL_MODLIST), me.name, source_p->name,
588                 modp->name, modp->handle,
589 <               modp->version, modp->core?"(core)":"");
589 >               modp->version, (modp->flags & MODULE_FLAG_CORE) ?"(core)":"");
590    }
591  
592    sendto_one(source_p, form_str(RPL_ENDOFMODLIST),
# Line 506 | Line 601 | mo_modrestart(struct Client *client_p, s
601    unsigned int modnum = 0;
602    dlink_node *ptr = NULL, *ptr_next = NULL;
603  
604 <  if (!IsAdmin(source_p))
604 >  if (!HasOFlag(source_p, OPER_FLAG_MODULE))
605    {
606      sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
607                 me.name, source_p->name);
# Line 516 | Line 611 | mo_modrestart(struct Client *client_p, s
611    sendto_one(source_p, ":%s NOTICE %s :Reloading all modules",
612               me.name, source_p->name);
613  
614 <  modnum = dlink_list_length(&mod_list);
614 >  modnum = dlink_list_length(&modules_list);
615  
616 <  DLINK_FOREACH_SAFE(ptr, ptr_next, mod_list.head)
616 >  DLINK_FOREACH_SAFE(ptr, ptr_next, modules_list.head)
617    {
618      struct module *modp = ptr->data;
619      unload_one_module(modp->name, 0);
# Line 529 | Line 624 | mo_modrestart(struct Client *client_p, s
624    load_core_modules(0);
625  
626    sendto_realops_flags(UMODE_ALL, L_ALL,
627 <              "Module Restart: %u modules unloaded, %lu modules loaded",
628 <                        modnum, dlink_list_length(&mod_list));
629 <  ilog(L_WARN, "Module Restart: %u modules unloaded, %lu modules loaded",
630 <       modnum, dlink_list_length(&mod_list));
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   }

Diff Legend

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