diff --git a/Changes b/Changes index 52965d8d2..627b4df12 100644 --- a/Changes +++ b/Changes @@ -309,3 +309,6 @@ - Added "get_host" old 'H' O:flag - Added #define KILL_LOGGING, by otherguy - Added /cycle #channels, suggested by ^loki^ +- Added Modules, using dlopen() and LoadLibrary for *nix/win32. +- Added /module load , /module status (list modules), + /module unload diff --git a/Config b/Config index 77fdaa811..8de72e8ff 100755 --- a/Config +++ b/Config @@ -64,7 +64,7 @@ DIR=`pwd` # # Some reasonable defaults # -DEFOPT="-O -g" +DEFOPT="-O -g -export-dynamic" DEFCFLAGS="$DEFOPT" DEFLIBS="none" MKPASSWDLIBS="-lcrypt" @@ -273,10 +273,10 @@ __EOF__ GLIBCVERS=`$EXEC` if [ -n "$GLIBCVERS" -a "$GLIBCVERS" -ge 2 ];then OSNAME="Linux (with GLIBC 2.x or greater)" - DEFLIBS="-lcrypt -lresolv" + DEFLIBS="-lcrypt -lresolv -ldl" else OSNAME="Linux" - DEFLIBS="" + DEFLIBS="-ldl" fi DEFCFLAGS="$DEFOPT" ;; diff --git a/Makefile.dist b/Makefile.dist index 3c0e082eb..0e21cabdc 100644 --- a/Makefile.dist +++ b/Makefile.dist @@ -35,6 +35,7 @@ XCFLAGS= IRCDLIBS= CRYPTOLIB= OPENSSLINCLUDES= + # # use the following on MIPS: #CFLAGS= -systype bsd43 -DSYSTYPE_BSD43 -I$(INCLUDEDIR) @@ -223,7 +224,8 @@ install: all pem: src/ssl.cnf @echo "Generating certificate request .. " - $(OPENSSLPATH) req -new -config src/ssl.cnf -out server.req.pem \ + $(OPENSSLPATH) req -new \ + -config src/ssl.cnf -out server.req.pem \ -keyout server.key.pem -nodes @echo "Generating self-signed certificate .. " $(OPENSSLPATH) req -x509 -days 365 -in server.req.pem \ diff --git a/TODO b/TODO index 09e443695..d5180e432 100644 --- a/TODO +++ b/TODO @@ -26,109 +26,109 @@ TODO : ---- * stskeeps - Tue Dec 12 2000 - 1 - [ IPv6 ] OPEN: - Add IPv6 compatiblity (requested by many people). Must allow :'s in - hostnames, will kill backwards compatiblity when IPv6 is enabled +Add IPv6 compatiblity (requested by many people). Must allow :'s in +hostnames, will kill backwards compatiblity when IPv6 is enabled * stskeeps - Tue Dec 12 2000 - 1 - [ Code ] OPEN: - Split up code, and make the placement of functions more logic +Split up code, and make the placement of functions more logic * codemastr - Tue Dec 12 2000 - 4 - [ Zip_Links ] OPEN: - Actually add this since it was planned for 3.0 +Actually add this since it was planned for 3.0 * codemastr - Tue Dec 12 2000 - 5 - [ Dynconf Recode ] IN-REPAIR stskeeps: - Dynconf has a bunch of bugs that can be resolved with a recode - We are doing this with the newconf :) -stskeeps +Dynconf has a bunch of bugs that can be resolved with a recode +We are doing this with the newconf :) -stskeeps * codemastr - Tue Dec 12 2000 - 8 - [ +I Fixes ]: - +I still has some bugs that may cause desync and show users - that the +I user is actually on the channel. ++I still has some bugs that may cause desync and show users +that the +I user is actually on the channel. * stskeeps - Tue Dec 12 2000 - 1 - [ Bugfixes/Hash ] CLOSED stskeeps: - Check for possible hash bug with del_from_client_table or something - People still complain about crashes - We might have fixed this with recent SERVER passwd fix and other passwd - fixes +Check for possible hash bug with del_from_client_table or something +People still complain about crashes +We might have fixed this with recent SERVER passwd fix and other passwd +fixes * stskeeps - Wed Dec 13 2000 - 10 - [ Bugfixes ] NO-PRODUCE: [[r00t3d](~lok70@168.213.226.rox-62220)] The other one, is lets say you are on - server (a), and you set +p to your channel. All the users on Server - (b,c, etc..) when they do a /list can see the +p channel in the - list. Now if I set it wih chanserv ie.. mlock +ntp, it doesn't do - that.. ON all servers (a,b,c) no one sees the +p channel in /list - unless they are in the channel allready. - Solution: Fix send_list to use PubChannel instead of SecretChannel +server (a), and you set +p to your channel. All the users on Server +(b,c, etc..) when they do a /list can see the +p channel in the +list. Now if I set it wih chanserv ie.. mlock +ntp, it doesn't do +that.. ON all servers (a,b,c) no one sees the +p channel in /list +unless they are in the channel allready. +Solution: Fix send_list to use PubChannel instead of SecretChannel (Unable to reproduce. +p channels are hidden on all servers -- codemastr) * stskeeps - Wed Dec 13 2000 - 10 - [ Bugfixes ]: [[r00t3d](~lok70@168.213.226.rox-62220)] If you are set +I (Tech - Admin/Network Admin) and you are set +q/+a in a channel. When someone /whoises - you hey see the channel names: *#channel ^#channel. +Admin/Network Admin) and you are set +q/+a in a channel. When someone /whoises +you hey see the channel names: *#channel ^#channel. Fix /whois ShowChannel code * stskeeps - Wed Dec 13 2000 - 5 - [ Bugfixes ]: [RexHsu(~webmin@202.109.72.rox-42822)] #TVB ÄÖÄÖ H root@61.151.53.User-42432 - :0 none +:0 none [RexHsu(~webmin@202.109.72.rox-42822)] #TVB ÄÖÄÖ H@ - ~webmin@202.109.72.User-42822 :0 none +~webmin@202.109.72.User-42822 :0 none [RexHsu(~webmin@202.109.72.rox-42822)] * End of /WHO list. - Chinese nicks "clash", this is not the right nicks i typed in +Chinese nicks "clash", this is not the right nicks i typed in * stskeeps - Wed Dec 13 2000 - 5 - [ Bugfixes ]: [eYe-Man(none@of.your.fucking.business)] Can you show me how you got - OP? +OP? [eYe-Man(none@of.your.fucking.business)] me i dont know how!!!!! - even i dont see where i got OP +even i dont see where i got OP [eYe-Man(none@of.your.fucking.business)] or when some server gave me - SJOIN gives people ops? :P +SJOIN gives people ops? :P * stskeeps - Thu Dec 14 2000 - 10 - [ Bugfixes ] InTe[_:#roxnet> -oxygen.phrozen.org- *** Global -- from Irc.LinuxFreakz.Net: - No response from dumper.roxnet.org[130.240.202.121], closing - link - Users can see that using +g ??? - FIXED: Sat Dec 30 2000 by stskeeps + No response from dumper.roxnet.org[130.240.202.121], closing + link + Users can see that using +g ??? +FIXED: Sat Dec 30 2000 by stskeeps * stskeeps - Fri Dec 14 2000 - 1 - [ SSL ] Challenge/Response kind of thing. - + /CHALLENGE nick keyname/commonidentifier type :b64text type = 0, challenge type = 1, response - Must be flood controlled in some way - Can only work between servers and or U:lines and or - +z users +Must be flood controlled in some way +Can only work between servers and or U:lines and or + +z users Example: - > :Stskeeps CHALLENGE RaYmAn rayman.pem 0 :0D0FE5F6D46 - < :RaYmAn CHALLENGE Stskeeps rayman.pem 1 :D0F5F543433 - +> :Stskeeps CHALLENGE RaYmAn rayman.pem 0 :0D0FE5F6D46 +< :RaYmAn CHALLENGE Stskeeps rayman.pem 1 :D0F5F543433 + The way this works is, that the challenger got RaYmAn's public RSA key - and he needs to authenticate that he is really talking to RaYmAn (the - real one). He then sends a random string to RaYmAn, encrypted with - RaYmAn's public key. RaYmAn then decrypts it using his private key, and - then re-encrypts the random stuff using his private key, and sends back - to Stskeeps, Sts then checks with decrypting the crypted text using the public - key, and if its OK, then considers him OK. + and he needs to authenticate that he is really talking to RaYmAn (the + real one). He then sends a random string to RaYmAn, encrypted with + RaYmAn's public key. RaYmAn then decrypts it using his private key, and + then re-encrypts the random stuff using his private key, and sends back + to Stskeeps, Sts then checks with decrypting the crypted text using the public + key, and if its OK, then considers him OK. - We can use this for NickServ authentication using RSA keys, - or server<->server authentication, or /oper authentication - (no more stolen passwords, yipieeeeeeee) + We can use this for NickServ authentication using RSA keys, + or server<->server authentication, or /oper authentication + (no more stolen passwords, yipieeeeeeee) - This is also easily possible to add, in IRCii, in BitchX, EPIC, - mIRC (DLLs), etc. - - This is also good for raising security/authenticating to another level. - Users can check if they are talking to the right person, NickServ databases - no longer needs to have passwords, just use RSA keys + This is also easily possible to add, in IRCii, in BitchX, EPIC, + mIRC (DLLs), etc. + + This is also good for raising security/authenticating to another level. + Users can check if they are talking to the right person, NickServ databases + no longer needs to have passwords, just use RSA keys * stskeeps - Sun 17 Dec 2000 - 1 - [ General ] - - P:ip:W:*:port - UnrealHTTPD! - Sat 30 Dec 2000 - stskeeps - *cough* listen::option http ;) + +P:ip:W:*:port + UnrealHTTPD! +Sat 30 Dec 2000 - stskeeps - *cough* listen::option http ;) * codemastr - Wed 20 Dec 2000 - 3 - [ General ] @@ -142,15 +142,15 @@ InTe[_:#roxnet> -oxygen.phrozen.org- *** Global -- from Irc.LinuxFreakz.Net: connect to a server, /oper, then run telnet and link a server. Close the telnet but do NOT send a SQUIT, the server displays no notice to opers that the server split. - Stskeeps> +j? but yes, there's a bug there +Stskeeps> +j? but yes, there's a bug there - FIXED Sat 30 Dec 2000 by Stskeeps + FIXED Sat 30 Dec 2000 by Stskeeps * stskeeps - Sat Dec 23 2000 - 10 - [ Bugfixes ] - There's some kind of bug that shows people being on same channel - twice. I got a feeling its to do with JOIN/SJOIN as its only remote. - [ Stskeeps ] [@ChanServ ] [@Fresh-Prin] [ Fresh-Prin] [@Fresh-Prin] - Same person +There's some kind of bug that shows people being on same channel +twice. I got a feeling its to do with JOIN/SJOIN as its only remote. +[ Stskeeps ] [@ChanServ ] [@Fresh-Prin] [ Fresh-Prin] [@Fresh-Prin] +Same person * codemastr - Tue Dec 26 2000 - 6 - [ Bugfixes ] (too lazy to type it out) @@ -158,21 +158,21 @@ InTe[_:#roxnet> -oxygen.phrozen.org- *** Global -- from Irc.LinuxFreakz.Net: That fix will work except it needs to be modified so it checks remote before denying because of not being oper * stskeeps - Wed Dec 27 2000 - 5 - [Configuration] - Add a SWHOIS option to oper {} block, suggested by Robertsog + Add a SWHOIS option to oper {} block, suggested by Robertsog * codemastr - Tue Dec 26 2000 - 6 - [ Bugfixes ] (too lazy to type it out) http://sourceforge.net/bugs/?func=detailbug&bug_id=126645&group_id=1968 That fix will work except it needs to be modified so it checks remote before denying because of not being oper * stskeeps - Sun Dec 30 2000 - 10 - [ Bugfixes ] - /whois shows what channels +S are in + /whois shows what channels +S are in * codemastr - Tue Jan 03 2001 - 1 - [ Idea ] Add /kill logging option suggested by Cerb * stskeeps - Tue Jan 9 2001 - 1 Idea limit whowas outputs -hedge * stskeeps - Wed Jan 10 2001 - 1 Idea - - unknown mode char only once per command + -unknown mode char only once per command when i whoised a user who was on the same server as the one i was on diff --git a/include/config.h b/include/config.h index 021115114..3c6c5c73b 100644 --- a/include/config.h +++ b/include/config.h @@ -97,6 +97,12 @@ */ #define ADMINCHAT 1 + +/* + * Kill logging -otherguy +*/ +#undef KILL_LOGGING + /* If you want SHUN_NOTICES, define this */ diff --git a/include/modules.h b/include/modules.h new file mode 100644 index 000000000..86aa730f9 --- /dev/null +++ b/include/modules.h @@ -0,0 +1,60 @@ +/************************************************************************ + * Unreal Internet Relay Chat Daemon, include/modules.h + * (C) Carsten V. Munk 2000 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + */ + +#define MOD_VERSION 1 +#define MAXMODULES 50 +#ifdef _WIN32 +#define DLLFUNC _declspec(dllexport) +#define irc_dlopen LoadLibrary +#define irc_dlclose FreeLibrary +#define irc_dlsym (void *)GetProcAddress +#define irc_dlerror strerror(GetLastError()) +#else +#define irc_dlopen dlopen +#define irc_dlclose dlclose +#define irc_dlsym dlsym +#define irc_dlerror dlerror +#define DLLFUNC +#endif + +typedef struct moduleInfo ModuleInfo; + +struct moduleInfo +{ + short mversion; /* Written for module header version */ + char *name; /* Name of module */ + char *version; /* $Id$ */ + char *description; /* Small description */ +#ifdef _WIN32 + HMODULE dll; /* Return value of LoadLibrary */ +#else + void *dll; /* Return value of dlopen */ +#endif + void (*unload)(); /* pointer to mod_unload */ +}; + +extern ModuleInfo *module_buffer; + +void module_init(void); +int load_module(char *module); +int unload_module(char *name); + + diff --git a/include/msg.h b/include/msg.h index f832e8523..80873fe92 100644 --- a/include/msg.h +++ b/include/msg.h @@ -294,6 +294,9 @@ #define MSG_CYCLE "CYCLE" #define TOK_CYCLE "BP" +#define MSG_MODULE "MODULE" +#define TOK_MODULE "BQ" + #define MAXPARA 15 extern int m_private(), m_topic(), m_join(), m_part(), m_mode(), m_svsmode(); @@ -333,6 +336,7 @@ extern int m_chgident(), m_swhois(), m_svso(), m_svsfline(); extern int m_tkl(), m_vhost(), m_botmotd(), m_sjoin(), m_htm(); extern int m_umode2(), m_dccdeny(), m_undccdeny(); extern int m_chgname(), m_shun(), m_post(), m_cycle(); +extern int m_module(); #ifdef GUEST extern int m_guest(); #endif diff --git a/include/struct.h b/include/struct.h index 35cd28799..c58fad67e 100644 --- a/include/struct.h +++ b/include/struct.h @@ -27,6 +27,7 @@ #include "common.h" #include "sys.h" #include "hash.h" +#include "modules.h" #include #include #ifdef ZIP_LINKS diff --git a/src/Makefile b/src/Makefile index 1545f720b..963070d6e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -25,12 +25,14 @@ LINTFLAGS=-hba OBJS=agent.o aln.o badwords.o bsd.o channel.o cloak.o crule.o dbuf.o \ fdlist.o hash.o help.o ircd.o ircsprintf.o list.o lusers.o \ - match.o packet.o parse.o $(REGEX) res.o $(RES) s_auth.o \ + match.o modules.o packet.o parse.o $(REGEX) res.o $(RES) s_auth.o \ s_bsd.o s_conf.o s_debug.o s_err.o s_extra.o s_kline.o \ s_misc.o s_numeric.o s_serv.o s_socks.o s_svs.o $(STRTOUL) ssl.o s_unreal.o \ s_user.o scache.o send.o support.o userload.o version.o webtv.o \ whowas.o zip.o +MODULES=libdummy.so + SRC=$(OBJS:%.o=%.c) MAKE = make 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'IRCDLIBS=${IRCDLIBS}' \ @@ -51,7 +53,7 @@ version.c: version.c.SH version.o: version.c ../include/version.h $(CC) $(CFLAGS) -c version.c -ircd: $(OBJS) +ircd: $(OBJS) $(MODULES) # $(CC) $(CFLAGS) $(CRYPTOLIB) -o ircd $(OBJS) $(LDFLAGS) $(IRCDLIBS) -lssl $(CC) $(CFLAGS) $(CRYPTOINCLUDES) -o ircd $(CRYPTOLIB) $(OBJS) $(LDFLAGS) $(IRCDLIBS) $(CRYPTOLIB) chmod $(IRCDMODE) ircd @@ -69,6 +71,10 @@ saber: $(SRC) lint: lint $(LINTFLAGS) -I../include $(SRC) | egrep -v 'sendto_|debug' +libdummy.so: m_test.c $(INCLUDES) + $(CC) $(CFLAGS) -DDYNAMIC_LINKING \ + -fPIC -DPIC -shared -o libdummy.so m_test.c + parse.o: parse.c $(INCLUDES) $(CC) $(CFLAGS) -c parse.c @@ -128,7 +134,7 @@ help.o: help.c $(INCLUDES) # ./buildm4 ${IRCDDIR} clean: - $(RM) -f *.o *~ core ircd version.c chkconf + $(RM) -f *.o *.so *~ core ircd version.c chkconf cleandir: clean diff --git a/src/m_test.c b/src/m_test.c new file mode 100644 index 000000000..9b06d3b50 --- /dev/null +++ b/src/m_test.c @@ -0,0 +1,89 @@ +/* + * Typical UnrealIRCd module skeleton + * (C) Carsten V. Munk 2000, may be used for everything + */ +#include "config.h" +#include "struct.h" +#include "common.h" +#include "sys.h" +#include "numeric.h" +#include "msg.h" +#include "channel.h" +#include "userload.h" +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#endif +#include +#include "h.h" +#ifdef STRIPBADWORDS +#include "badwords.h" +#endif +#ifdef _WIN32 +#include "version.h" +#endif + +/* Place includes here */ +/* replace this with a common name of your module */ +#define modulename dummy +#define MSG_DUMMY "DUMMY" +#define TOK_DUMMY "DU" + +DLLFUNC int m_dummy(aClient *cptr, aClient *sptr, char *parv[], int parc); + +ModuleInfo modulename_info + = { + 1, + "dummy", /* Name of module */ + "$Id$", /* Version */ + "description", /* Short description of module */ + NULL, /* Pointer to our dlopen() return value */ + NULL + }; + +/* + * The purpose of these ifdefs, are that we can "static" link the ircd if we + * want to +*/ + +#ifdef DYNAMIC_LINKING +DLLFUNC void mod_init(void) +#else +void modulename_init(void) +#endif +{ + /* extern variable to export modulename_info to temporary + ModuleInfo *modulebuffer; + the module_load() will use this to add to the modules linked + list + */ + module_buffer = &modulename_info; + /* + * We call our add_Command crap here + */ + add_Command(MSG_DUMMY, TOK_DUMMY, m_dummy, MAXPARA); +} + +#ifdef DYNAMIC_LINKING +DLLFUNC void mod_unload(void) +#else +void _modulename_unload(void) +#endif +{ + if (del_Command(MSG_DUMMY, TOK_DUMMY, m_dummy) < 0) + { + sendto_realops("Failed to delete commands when unloading %s", + modulename); + } + /* do etc stuff here */ + sendto_ops("Unloaded"); +} + +DLLFUNC int m_dummy(aClient *cptr, aClient *sptr, char *parv[], int parc) +{ + sendto_ops("MOOO"); +} diff --git a/src/modules.c b/src/modules.c new file mode 100644 index 000000000..67a35e603 --- /dev/null +++ b/src/modules.c @@ -0,0 +1,237 @@ +/************************************************************************ + * UnrealIRCd - Unreal Internet Relay Chat Daemon - src/modules.c + * (C) 1999-2000 Carsten Munk (Techie/Stskeeps) + * + * See file AUTHORS in IRC package for additional names of + * the programmers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "struct.h" +#include "common.h" +#include "sys.h" +#include "numeric.h" +#include "msg.h" +#include "channel.h" +#include "userload.h" +#include "version.h" +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#endif +#include +#include "h.h" +#include + +ModuleInfo *Modules[MAXMODULES]; +int modules_loaded = 0; +ModuleInfo *module_buffer; +void module_init(void) +{ + bzero(Modules, sizeof(Modules)); + modules_loaded = 0; +} + +int load_module(char *module) +{ +#ifdef _WIN32 + HMODULE Mod; +#else + void *Mod; +#endif + void (*mod_init) (); + void (*mod_unload) (); + int i; + module_buffer = NULL; + if (Mod = irc_dlopen(module, RTLD_LAZY)) + { + /* Succeed loading module */ + /* Locate mod_init function */ + mod_init = irc_dlsym(Mod, "mod_init"); + if (!mod_init) + { + mod_init = irc_dlsym(Mod, "_mod_init"); + if (!mod_init) + { + sendto_realops + ("Failed to load module %s: Could not locate mod_init", + module); + irc_dlclose(Mod); + return -1; + } + } + /* Run mod_init */ + (*mod_init) (); + if (!module_buffer) + { + sendto_realops + ("Failed to load module %s: mod_init did not set module_buffer", + module); + irc_dlclose(Mod); + return -1; + } + if (module_buffer->mversion != MOD_VERSION) + { + sendto_realops + ("Failed to load module %s: mversion is %i, not %i as we require", + module, module_buffer->mversion, MOD_VERSION); + irc_dlclose(Mod); + return -1; + } + if (!module_buffer->name || !module_buffer->version + || !module_buffer->description) + { + sendto_realops + ("Failed to load module %s: name/version/description missing", + module); + irc_dlclose(Mod); + return -1; + } + mod_unload = irc_dlsym(Mod, "mod_unload"); + if (!mod_unload) + { + mod_unload = irc_dlsym(Mod, "_mod_unload"); + if (!mod_unload) + { + sendto_realops + ("Failed to load module %s: Could not locate mod_unload", + module); + irc_dlclose(Mod); + return -1; + } + } + module_buffer->dll = Mod; + module_buffer->unload = mod_unload; + for (i = 0; i <= MAXMODULES; i++) + { + if (!Modules[i]) + { + Modules[i] = module_buffer; + modules_loaded++; + break; + } + } + if (i == MAXMODULES) + { + sendto_realops + ("Failed to load module %s: Too many modules loaded"); + irc_dlclose(Mod); + return -1; + } + return 1; + } + else + { + const char *err = irc_dlerror(); + + if (err) + { + sendto_realops("Failed to load module %s: %s", + module, err); + } + return -1; + } +} + +int unload_module(char *name) +{ + int i; + + for (i = 0; i <= MAXMODULES; i++) + if (Modules[i]) + if (!strcmp(Modules[i]->name, name)) + break; + if (i == MAXMODULES) + return -1; + + /* Call unload */ + (*Modules[i]->unload)(); + + irc_dlclose(Modules[i]->dll); + + Modules[i] = NULL; + modules_loaded--; + return 1; +} + +int m_module(aClient *cptr, aClient *sptr, int parc, char *parv[]) +{ + int i; + ModuleInfo *mi; + + if (!IsAdmin(sptr)) + { + sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); + return 0; + } + if (parc < 2) + { + sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), + me.name, parv[0], "MODULE"); + return 0; + } + if (!match(parv[1], "load")) + { + if (parc < 3) + { + sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), + me.name, parv[0], "MODULES LOAD"); + return 0; + } + sendto_realops("Trying to load module %s", parv[2]); + if (load_module(parv[2]) == 1) + sendto_realops("Loaded module %s", parv[2]); + } + else + if (!match(parv[1], "unload")) + { + if (parc < 3) + { + sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), + me.name, parv[0], "MODULES UNLOAD"); + return 0; + } + sendto_realops("Trying to unload module %s", parv[2]); + if (unload_module(parv[2]) == 1) + sendto_realops("Unloaded module %s", parv[2]); + + } + else + if (!match(parv[1], "status")) + { + if (modules_loaded == 0) + { + sendto_one(sptr, ":%s NOTICE %s :*** No modules loaded", me.name, sptr->name); + return 1; + } + for (i = 0; i < MAXMODULES; i++) + if (mi = Modules[i]) + { + sendto_one(sptr, ":%s NOTICE %s :*** %s - %s (%s)", me.name, sptr->name, + mi->name, mi->version, mi->description); + } + } + else + { + sendto_one(sptr, ":%s NOTICE %s :*** Syntax: /module load|unload|status", + me.name, sptr->name); + } + return 1; +} \ No newline at end of file diff --git a/src/packet.c b/src/packet.c index 3d09e19bf..1d8634696 100644 --- a/src/packet.c +++ b/src/packet.c @@ -268,6 +268,7 @@ void init_CommandHash(void) add_Command(MSG_BOTSERV, TOK_BOTSERV, m_botserv, 1); add_Command(TOK_BOTSERV, TOK_BOTSERV, m_botserv, 1); add_Command(MSG_CYCLE, TOK_CYCLE, m_cycle, MAXPARA); + add_Command(MSG_MODULE, TOK_MODULE, m_module, MAXPARA); #ifdef DEVELOP_DEBUG for (i = 0; i <= 255; i++) { diff --git a/src/ssl.rnd b/src/ssl.rnd index d1290ef14..3c547a0f3 100644 Binary files a/src/ssl.rnd and b/src/ssl.rnd differ