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/src/modules.c (file contents), Revision 1155 by michael, Tue Aug 9 20:27:45 2011 UTC vs.
ircd-hybrid-8/src/modules.c (file contents), Revision 1238 by michael, Thu Sep 29 11:37:31 2011 UTC

# Line 22 | Line 22
22   *  $Id$
23   */
24  
25 + #include "ltdl.h"
26 +
27   #include "stdinc.h"
28   #include "list.h"
29   #include "modules.h"
# Line 38 | Line 40
40   #include "memory.h"
41  
42  
43 < dlink_list mod_list = { NULL, NULL, 0 };
43 > static dlink_list modules_list = { NULL, NULL, 0 };
44 >
45 > static const char *unknown_ver = "<unknown>";
46  
47   static const char *core_module_table[] =
48   {
# Line 93 | Line 97 | struct Message modrestart_msgtab = {
97   };
98  
99  
100 + int
101 + modules_valid_suffix(const char *name)
102 + {
103 +  return ((name = strrchr(name, '.'))) && !strcmp(name, ".la");
104 + }
105 +
106 + /* unload_one_module()
107 + *
108 + * inputs       - name of module to unload
109 + *              - 1 to say modules unloaded, 0 to not
110 + * output       - 0 if successful, -1 if error
111 + * side effects - module is unloaded
112 + */
113 + int
114 + unload_one_module(const char *name, int warn)
115 + {
116 +  struct module *modp = NULL;
117 +
118 +  if ((modp = findmodule_byname(name)) == NULL)
119 +    return -1;
120 +
121 +  if (modp->modexit)
122 +   modp->modexit();
123 +
124 +  assert(dlink_list_length(&modules_list) > 0);
125 +  dlinkDelete(&modp->node, &modules_list);
126 +  MyFree(modp->name);
127 +
128 +  lt_dlclose(modp->handle);
129 +
130 +  if (warn == 1)
131 +  {
132 +    ilog(L_INFO, "Module %s unloaded", name);
133 +    sendto_realops_flags(UMODE_ALL, L_ALL, "Module %s unloaded", name);
134 +  }
135 +
136 +  return 0;
137 + }
138 +
139 + /* load_a_module()
140 + *
141 + * inputs       - path name of module, int to notice, int of core
142 + * output       - -1 if error 0 if success
143 + * side effects - loads a module if successful
144 + */
145 + int
146 + load_a_module(const char *path, int warn, int core)
147 + {
148 +  lt_dlhandle tmpptr = NULL;
149 +  const char *mod_basename = NULL;
150 +  struct module *modp = NULL;
151 +
152 +  if (findmodule_byname((mod_basename = libio_basename(path))))
153 +    return 1;
154 +
155 +  if (!(tmpptr = lt_dlopen(path))) {
156 +    const char *err = ((err = lt_dlerror())) ? err : "<unknown>";
157 +
158 +    sendto_realops_flags(UMODE_ALL, L_ALL, "Error loading module %s: %s",
159 +                         mod_basename, err);
160 +    ilog(L_WARN, "Error loading module %s: %s", mod_basename, err);
161 +    return -1;
162 +  }
163 +
164 +  if ((modp = lt_dlsym(tmpptr, "module_entry")) == NULL)
165 +  {
166 +    sendto_realops_flags(UMODE_ALL, L_ALL, "Module %s has no module_entry export",
167 +                         mod_basename);
168 +    ilog(L_WARN, "Module %s has no module_entry export", mod_basename);
169 +    lt_dlclose(tmpptr);
170 +    return -1;
171 +  }
172 +
173 +  modp->handle = tmpptr;
174 +
175 +  if (EmptyString(modp->version))
176 +    modp->version = unknown_ver;
177 +
178 +  if (core)
179 +    modp->flags |= MODULE_FLAG_CORE;
180 +
181 +  DupString(modp->name, mod_basename);
182 +  dlinkAdd(modp, &modp->node, &modules_list);
183 +
184 +  if (modp->modinit)
185 +    modp->modinit();
186 +
187 +  if (warn == 1)
188 +  {
189 +    sendto_realops_flags(UMODE_ALL, L_ALL,
190 +                         "Module %s [version: %s handle: %p] loaded.",
191 +                         modp->name, modp->version, tmpptr);
192 +    ilog(L_WARN, "Module %s [version: %s handle: %p] loaded.",
193 +         modp->name, modp->version, tmpptr);
194 +  }
195 +
196 +  return 0;
197 + }
198 +
199   /*
200   * modules_init
201   *
# Line 103 | Line 206 | struct Message modrestart_msgtab = {
206   void
207   modules_init(void)
208   {
209 <  dynlink_init();
209 >  if (lt_dlinit())
210 >  {
211 >    ilog(L_ERROR, "Couldn't initialize the libltdl run time dynamic"
212 >         " link library. Exiting.");
213 >    exit(0);
214 >  }
215  
216    mod_add_cmd(&modload_msgtab);
217    mod_add_cmd(&modunload_msgtab);
# Line 181 | Line 289 | add_conf_module(const char *name)
289   void
290   mod_clear_paths(void)
291   {
292 <  struct module_path *pathst;
293 <  dlink_node *ptr;
186 <  dlink_node *next_ptr;
292 >  struct module_path *pathst = NULL;
293 >  dlink_node *ptr = NULL, *next_ptr = NULL;
294  
295    DLINK_FOREACH_SAFE(ptr, next_ptr, mod_paths.head)
296    {
# Line 208 | Line 315 | mod_clear_paths(void)
315   * output       - NULL if not found or pointer to module
316   * side effects - NONE
317   */
318 < dlink_node *
318 > struct module *
319   findmodule_byname(const char *name)
320   {
321 <  dlink_node *ptr;
215 <  struct module *modp;
321 >  dlink_node *ptr = NULL;
322  
323 <  DLINK_FOREACH(ptr, mod_list.head)
323 >  DLINK_FOREACH(ptr, modules_list.head)
324    {
325 <    modp = ptr->data;
325 >    struct module *modp = ptr->data;
326  
327      if (strcmp(modp->name, name) == 0)
328 <      return ptr;
328 >      return modp;
329    }
330  
331    return NULL;
# Line 357 | Line 463 | mo_modload(struct Client *client_p, stru
463   {
464    const char *m_bn = NULL;
465  
466 <  if (!IsAdmin(source_p))
466 >  if (!HasOFlag(source_p, OPER_FLAG_MODULE))
467    {
468      sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
469                 me.name, source_p->name);
# Line 382 | Line 488 | mo_modunload(struct Client *client_p, st
488               int parc, char *parv[])
489   {
490    const char *m_bn = NULL;
491 <  dlink_node *ptr;
386 <  struct module *modp;
491 >  struct module *modp = NULL;
492  
493 <  if (!IsAdmin(source_p))
493 >  if (!HasOFlag(source_p, OPER_FLAG_MODULE))
494    {
495      sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
496                 me.name, source_p->name);
# Line 394 | Line 499 | mo_modunload(struct Client *client_p, st
499  
500    m_bn = libio_basename(parv[1]);
501  
502 <  if ((ptr = findmodule_byname(m_bn)) == NULL)
502 >  if ((modp = findmodule_byname(m_bn)) == NULL)
503    {
504      sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
505                 me.name, source_p->name, m_bn);
506      return;
507    }
508  
509 <  modp = ptr->data;
405 <
406 <  if (modp->core == 1)
509 >  if (modp->flags & MODULE_FLAG_CORE)
510    {
511      sendto_one(source_p,
512                 ":%s NOTICE %s :Module %s is a core module and may not be unloaded",
# Line 411 | Line 514 | mo_modunload(struct Client *client_p, st
514      return;
515    }
516  
414  /* XXX might want to simply un dlink it here */
415
517    if (unload_one_module(m_bn, 1) == -1)
518    {
519      sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
# Line 426 | Line 527 | mo_modreload(struct Client *client_p, st
527               int parc, char *parv[])
528   {
529    const char *m_bn = NULL;
530 <  dlink_node *ptr;
430 <  struct module *modp;
530 >  struct module *modp = NULL;
531    int check_core;
532  
533 <  if (!IsAdmin(source_p))
533 >  if (!HasOFlag(source_p, OPER_FLAG_MODULE))
534    {
535      sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
536                 me.name, source_p->name);
# Line 439 | Line 539 | mo_modreload(struct Client *client_p, st
539  
540    m_bn = libio_basename(parv[1]);
541  
542 <  if ((ptr = findmodule_byname(m_bn)) == NULL)
542 >  if ((modp = findmodule_byname(m_bn)) == NULL)
543    {
544      sendto_one(source_p, ":%s NOTICE %s :Module %s is not loaded",
545                 me.name, source_p->name, m_bn);
546      return;
547    }
548  
549 <  modp = ptr->data;
450 <  check_core = modp->core;
549 >  check_core = (modp->flags & MODULE_FLAG_CORE) != 0;
550  
551    if (unload_one_module(m_bn, 1) == -1)
552    {
# Line 472 | Line 571 | mo_modlist(struct Client *client_p, stru
571   {
572    const dlink_node *ptr = NULL;
573  
574 <  if (!IsAdmin(source_p))
574 >  if (!HasOFlag(source_p, OPER_FLAG_MODULE))
575    {
576      sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
577                 me.name, source_p->name);
578      return;
579    }
580  
581 <  DLINK_FOREACH(ptr, mod_list.head)
581 >  DLINK_FOREACH(ptr, modules_list.head)
582    {
583      const struct module *modp = ptr->data;
584  
585      if (parc > 1 && !match(parv[1], modp->name))
586        continue;
587  
588 <    sendto_one(source_p, form_str(RPL_MODLIST), me.name, parv[0],
588 >    sendto_one(source_p, form_str(RPL_MODLIST), me.name, source_p->name,
589                 modp->name, modp->handle,
590 <               modp->version, modp->core?"(core)":"");
590 >               modp->version, (modp->flags & MODULE_FLAG_CORE) ?"(core)":"");
591    }
592  
593    sendto_one(source_p, form_str(RPL_ENDOFMODLIST),
# Line 503 | Line 602 | mo_modrestart(struct Client *client_p, s
602    unsigned int modnum = 0;
603    dlink_node *ptr = NULL, *ptr_next = NULL;
604  
605 <  if (!IsAdmin(source_p))
605 >  if (!HasOFlag(source_p, OPER_FLAG_MODULE))
606    {
607      sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
608                 me.name, source_p->name);
# Line 513 | Line 612 | mo_modrestart(struct Client *client_p, s
612    sendto_one(source_p, ":%s NOTICE %s :Reloading all modules",
613               me.name, source_p->name);
614  
615 <  modnum = dlink_list_length(&mod_list);
615 >  modnum = dlink_list_length(&modules_list);
616  
617 <  DLINK_FOREACH_SAFE(ptr, ptr_next, mod_list.head)
617 >  DLINK_FOREACH_SAFE(ptr, ptr_next, modules_list.head)
618    {
619      struct module *modp = ptr->data;
620      unload_one_module(modp->name, 0);
# Line 527 | Line 626 | mo_modrestart(struct Client *client_p, s
626  
627    sendto_realops_flags(UMODE_ALL, L_ALL,
628                "Module Restart: %u modules unloaded, %u modules loaded",
629 <                        modnum, dlink_list_length(&mod_list));
629 >                        modnum, dlink_list_length(&modules_list));
630    ilog(L_WARN, "Module Restart: %u modules unloaded, %u modules loaded",
631 <       modnum, dlink_list_length(&mod_list));
631 >       modnum, dlink_list_length(&modules_list));
632   }

Diff Legend

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