39 |
|
#include "memory.h" |
40 |
|
|
41 |
|
|
42 |
< |
static dlink_list modules_list = { NULL, NULL, 0 }; |
42 |
> |
dlink_list modules_list = { NULL, NULL, 0 }; |
43 |
|
|
44 |
|
static const char *unknown_ver = "<unknown>"; |
45 |
|
|
64 |
|
static dlink_list mod_paths = { NULL, NULL, 0 }; |
65 |
|
static dlink_list conf_modules = { NULL, NULL, 0 }; |
66 |
|
|
67 |
– |
static void mo_module(struct Client *, struct Client *, int, char *[]); |
68 |
– |
|
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 |
– |
|
67 |
|
int |
68 |
|
modules_valid_suffix(const char *name) |
69 |
|
{ |
97 |
|
if (warn == 1) |
98 |
|
{ |
99 |
|
ilog(LOG_TYPE_IRCD, "Module %s unloaded", name); |
100 |
< |
sendto_realops_flags(UMODE_ALL, L_ALL, "Module %s unloaded", name); |
100 |
> |
sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, |
101 |
> |
"Module %s unloaded", name); |
102 |
|
} |
103 |
|
|
104 |
|
return 0; |
123 |
|
if (!(tmpptr = lt_dlopen(path))) { |
124 |
|
const char *err = ((err = lt_dlerror())) ? err : "<unknown>"; |
125 |
|
|
126 |
< |
sendto_realops_flags(UMODE_ALL, L_ALL, "Error loading module %s: %s", |
126 |
> |
sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, |
127 |
> |
"Error loading module %s: %s", |
128 |
|
mod_basename, err); |
129 |
|
ilog(LOG_TYPE_IRCD, "Error loading module %s: %s", mod_basename, err); |
130 |
|
return -1; |
132 |
|
|
133 |
|
if ((modp = lt_dlsym(tmpptr, "module_entry")) == NULL) |
134 |
|
{ |
135 |
< |
sendto_realops_flags(UMODE_ALL, L_ALL, "Module %s has no module_entry export", |
136 |
< |
mod_basename); |
137 |
< |
ilog(LOG_TYPE_IRCD, "Module %s has no module_entry export", mod_basename); |
135 |
> |
const char *err = ((err = lt_dlerror())) ? err : "<unknown>"; |
136 |
> |
|
137 |
> |
sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, |
138 |
> |
"Error loading module %s: %s", |
139 |
> |
mod_basename, err); |
140 |
> |
ilog(LOG_TYPE_IRCD, "Error loading module %s: %s", mod_basename, err); |
141 |
|
lt_dlclose(tmpptr); |
142 |
|
return -1; |
143 |
|
} |
155 |
|
|
156 |
|
if (warn == 1) |
157 |
|
{ |
158 |
< |
sendto_realops_flags(UMODE_ALL, L_ALL, |
158 |
> |
sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, |
159 |
|
"Module %s [version: %s handle: %p] loaded.", |
160 |
|
modp->name, modp->version, tmpptr); |
161 |
|
ilog(LOG_TYPE_IRCD, "Module %s [version: %s handle: %p] loaded.", |
181 |
|
" link library. Exiting."); |
182 |
|
exit(0); |
183 |
|
} |
186 |
– |
|
187 |
– |
mod_add_cmd(&module_msgtab); |
184 |
|
} |
185 |
|
|
186 |
|
/* mod_find_path() |
397 |
|
return load_a_module(modpath, 1); |
398 |
|
} |
399 |
|
|
400 |
< |
sendto_realops_flags(UMODE_ALL, L_ALL, |
400 |
> |
sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, |
401 |
|
"Cannot locate module %s", path); |
402 |
|
ilog(LOG_TYPE_IRCD, "Cannot locate module %s", path); |
403 |
|
return -1; |
404 |
|
} |
409 |
– |
|
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_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 |
– |
{ |
434 |
– |
sendto_one(source_p, form_str(ERR_NOPRIVILEGES), |
435 |
– |
me.name, source_p->name); |
436 |
– |
return; |
437 |
– |
} |
438 |
– |
|
439 |
– |
if (EmptyString(parv[1])) |
440 |
– |
{ |
441 |
– |
sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), |
442 |
– |
me.name, source_p->name, "MODULE"); |
443 |
– |
return; |
444 |
– |
} |
445 |
– |
|
446 |
– |
if (!irccmp(parv[1], "LOAD")) |
447 |
– |
{ |
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 |
– |
load_one_module(parv[2]); |
456 |
– |
return; |
457 |
– |
} |
458 |
– |
|
459 |
– |
if (!irccmp(parv[1], "UNLOAD")) |
460 |
– |
{ |
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 (!irccmp(parv[1], "RELOAD")) |
483 |
– |
{ |
484 |
– |
if (!strcmp(parv[2], "*")) |
485 |
– |
{ |
486 |
– |
unsigned int modnum = 0; |
487 |
– |
dlink_node *ptr = NULL, *ptr_next = NULL; |
488 |
– |
|
489 |
– |
sendto_one(source_p, ":%s NOTICE %s :Reloading all modules", |
490 |
– |
me.name, source_p->name); |
491 |
– |
|
492 |
– |
modnum = dlink_list_length(&modules_list); |
493 |
– |
|
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 |
– |
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 ((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 |
– |
} |
518 |
– |
|
519 |
– |
check_core = (modp->flags & MODULE_FLAG_CORE) != 0; |
520 |
– |
|
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 |
– |
|
536 |
– |
return; |
537 |
– |
} |
538 |
– |
|
539 |
– |
if (!irccmp(parv[1], "LIST")) |
540 |
– |
{ |
541 |
– |
const dlink_node *ptr = NULL; |
542 |
– |
|
543 |
– |
DLINK_FOREACH(ptr, modules_list.head) |
544 |
– |
{ |
545 |
– |
if (parc > 2 && !match(parv[2], modp->name)) |
546 |
– |
continue; |
547 |
– |
|
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 |
– |
sendto_one(source_p, form_str(RPL_ENDOFMODLIST), |
554 |
– |
me.name, source_p->name); |
555 |
– |
return; |
556 |
– |
} |
557 |
– |
} |