diff options
Diffstat (limited to 'src/modules')
31 files changed, 4450 insertions, 0 deletions
diff --git a/src/modules/Makefile b/src/modules/Makefile new file mode 100644 index 000000000..cafbe451c --- /dev/null +++ b/src/modules/Makefile @@ -0,0 +1,48 @@ +include ./Makefile.inc + +MAKEARGS = 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'ANOPELIBS=${ANOPELIBS}' \ + 'LDFLAGS=${LDFLAGS}' 'BINDEST=${BINDEST}' 'INSTALL=${INSTALL}' \ + 'INCLUDEDIR=${INCLUDEDIR}' 'RM=${RM}' 'CP=${CP}' \ + 'TOUCH=${TOUCH}' 'SHELL=${SHELL}' 'DATDEST=${DATDEST}' \ + 'RUNGROUP=${RUNGROUP}' 'MODULE_PATH=${MODULE_PATH}' \ + 'PROFILE=${PROFILE}' 'SHARED=${SHARED}' 'MODULEFLAGS=${MODULEFLAGS}' + +OBJECTS= $(SRCS:.c=.o) +SO_FILES=$(OBJECTS:.o=.s) +CDEFS= -rdynamic -Wall + +all: modules subs + +modules: $(OBJECTS) $(SO_FILES) + +install: + $(CP) ./*.so $(MODULE_PATH) + @for i in $(SUBS); do \ + echo "make install in $$i..."; \ + (cd $$i; $(MAKE) $(MAKEARGS) install);done + +distclean: spotless + +.c.o: + $(CC) ${CFLAGS} ${CDEFS} ${MODULEFLAGS} -I../${INCLUDEDIR} -c $< + +.o.s: + $(CC) ${SHARED} ../mod_version.o $< -o $*.so ${PROFILE} + @$(TOUCH) $*.s + +subs: + @for i in $(SUBS); do \ + echo "make all in $$i..."; \ + (cd $$i; $(MAKE) $(MAKEARGS) all); done + +subs_clean: + @for i in $(SUBS); do \ + echo "cleaning in $$i..."; \ + (cd $$i; $(MAKE) $(MAKEARGS) clean); done + +clean: subs_clean + rm -f *.o *.s *.so *.c~ core + +spotless: + rm -f *.o *.s *.so *.c~ core *.so Makefile.inc + diff --git a/src/modules/Makefile.sub b/src/modules/Makefile.sub new file mode 100644 index 000000000..7697249bf --- /dev/null +++ b/src/modules/Makefile.sub @@ -0,0 +1,28 @@ +MAKEARGS = 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'ANOPELIBS=${ANOPELIBS}' \ + 'LDFLAGS=${LDFLAGS}' 'BINDEST=${BINDEST}' 'INSTALL=${INSTALL}' \ + 'INCLUDEDIR=${INCLUDEDIR}' 'RM=${RM}' 'CP=${CP}' \ + 'TOUCH=${TOUCH}' 'SHELL=${SHELL}' 'DATDEST=${DATDEST}' \ + 'RUNGROUP=${RUNGROUP}' 'MODULE_PATH=${MODULE_PATH}' \ + 'PROFILE=${PROFILE}' 'SHARED=${SHARED}' 'MODULEFLAGS=${MODULEFLAGS}' + +OBJECTS= $(SRCS:.c=.o) +SO_FILES=$(OBJECTS:.o=.s) +CDEFS= -rdynamic -Wall + +all: module + +module: $(OBJECTS) so + +distclean: spotless + +.c.o: + $(CC) ${CFLAGS} ${CDEFS} ${MODULEFLAGS} -I../ -I../../${INCLUDEDIR} -c $< + +so: + $(CC) ${SHARED} ../../mod_version.o $(OBJECTS) -o ../$(TARGET).so ${PROFILE} + +clean: + rm -f *.o *.so *.c~ core + +spotless: + rm -f *~ *.o *.so *.c~ core diff --git a/src/modules/README b/src/modules/README new file mode 100644 index 000000000..6aee0ac47 --- /dev/null +++ b/src/modules/README @@ -0,0 +1 @@ +Please read the "MODULES" file located on the "docs" directory. diff --git a/src/modules/bs_fantasy_unban.c b/src/modules/bs_fantasy_unban.c new file mode 100644 index 000000000..a17e06551 --- /dev/null +++ b/src/modules/bs_fantasy_unban.c @@ -0,0 +1,82 @@ +/* BotServ core fantasy functions + * + * (C) 2003-2008 Anope Team + * Contact us at info@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ +/*************************************************************************/ + +#include "module.h" + +int do_fantasy(int argc, char **argv); + +/** + * Create the hook, and tell anope about it. + * @param argc Argument count + * @param argv Argument list + * @return MOD_CONT to allow the module, MOD_STOP to stop it + **/ +int AnopeInit(int argc, char **argv) +{ + EvtHook *hook; + + moduleAddAuthor("Anope"); + moduleAddVersion + ("$Id$"); + moduleSetType(CORE); + + hook = createEventHook(EVENT_BOT_FANTASY, do_fantasy); + moduleAddEventHook(hook); + + return MOD_CONT; +} + +/** + * Unload the module + **/ +void AnopeFini(void) +{ + +} + +/** + * Handle unban fantasy command. + * @param argc Argument count + * @param argv Argument list + * @return MOD_CONT or MOD_STOP + **/ +int do_fantasy(int argc, char **argv) +{ + User *u; + ChannelInfo *ci; + char *target = NULL; + + if (argc < 3) + return MOD_CONT; + + if (stricmp(argv[0], "unban") == 0) { + u = finduser(argv[1]); + ci = cs_findchan(argv[2]); + if (!u || !ci || !check_access(u, ci, CA_UNBAN)) + return MOD_CONT; + + if (argc >= 4) + target = myStrGetToken(argv[3], ' ', 0); + if (!target) + common_unban(ci, u->nick); + else + common_unban(ci, target); + + /* free target if needed (#852) */ + Anope_Free(target); + } + + return MOD_CONT; +} diff --git a/src/modules/configure b/src/modules/configure new file mode 100755 index 000000000..cf2158d66 --- /dev/null +++ b/src/modules/configure @@ -0,0 +1,58 @@ +#!/bin/sh + +echo2 () { + $ECHO2 "$*$ECHO2SUF" # these are defined later +} + +ECHO2SUF='' +if [ "`echo -n a ; echo -n b`" = "ab" ] ; then + ECHO2='echo -n' +elif [ "`echo 'a\c' ; echo 'b\c'`" = "ab" ] ; then + ECHO2='echo' ; ECHO2SUF='\c' +elif [ "`printf 'a' 2>&1 ; printf 'b' 2>&1`" = "ab" ] ; then + ECHO2='printf "%s"' +else + # oh well... + ECHO2='echo' +fi +export ECHO2 ECHO2SUF + + +echo2 "SRCS=" > ./Makefile.inc +FIRST=1 +for oldfile in *.c +do + if [ "$FIRST" = 1 ] ; then + echo2 " "$oldfile >> ./Makefile.inc + else + echo "\\" >> ./Makefile.inc + echo2 " " $oldfile >> ./Makefile.inc + fi + FIRST=0 +done +echo "" >> ./Makefile.inc + +echo2 "SUBS=" >> ./Makefile.inc +FIRST=1 +for dir in * +do + if [ -d $dir ] ; then + if [ -f $dir/configure ] ; then + cd $dir + ./configure + cd .. + fi + if [ -f $dir/Makefile ] ; then + if [ "$FIRST" = 1 ] ; then + echo2 " "$dir >> ./Makefile.inc + else + echo "\\" >> ./Makefile.inc + echo2 " " $dir >> ./Makefile.inc + fi + FIRST=0 + fi + fi +done + +exit 0 + diff --git a/src/modules/cs_appendtopic.c b/src/modules/cs_appendtopic.c new file mode 100644 index 000000000..7e0d27bb4 --- /dev/null +++ b/src/modules/cs_appendtopic.c @@ -0,0 +1,247 @@ +/* cs_appendtopic.c - Add text to a channels topic + * + * (C) 2003-2008 Anope Team + * Contact us at info@anope.org + * + * Based on the original module by SGR <Alex_SGR@ntlworld.com> + * Included in the Anope module pack since Anope 1.7.9 + * Anope Coder: GeniusDex <geniusdex@anope.org> + * + * Please read COPYING and README for further details. + * + * Send bug reports to the Anope Coder instead of the module + * author, because any changes since the inclusion into anope + * are not supported by the original author. + * + */ +/*************************************************************************/ + +#include "module.h" + +#define AUTHOR "SGR" +#define VERSION "$Id$" + + /* ------------------------------------------------------------ + * Name: cs_appendtopic + * Author: SGR <Alex_SGR@ntlworld.com> + * Date: 31/08/2003 + * ------------------------------------------------------------ + * + * This module has no configurable options. For information on + * this module, load it and refer to /ChanServ APPENDTOPIC HELP + * + * Thanks to dengel, Rob and Certus for all there support. + * Especially Rob, who always manages to show me where I have + * not allocated any memory. Even if it takes a few weeks of + * pestering to get him to look at it. + * + * ------------------------------------------------------------ + */ + +/* ---------------------------------------------------------------------- */ +/* DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING */ +/* ---------------------------------------------------------------------- */ + +#define LNG_NUM_STRINGS 3 + +#define LNG_CHAN_HELP 0 +#define LNG_CHAN_HELP_APPENDTOPIC 1 +#define LNG_APPENDTOPIC_SYNTAX 2 + +int my_cs_appendtopic(User * u); +void my_cs_help(User * u); +int my_cs_help_appendtopic(User * u); +void my_add_languages(void); + +int AnopeInit(int argc, char **argv) +{ + Command *c; + int status; + + moduleAddAuthor(AUTHOR); + moduleAddVersion(VERSION); + moduleSetType(SUPPORTED); + + c = createCommand("APPENDTOPIC", my_cs_appendtopic, NULL, -1, -1, -1, + -1, -1); + if ((status = moduleAddCommand(CHANSERV, c, MOD_HEAD))) { + alog("[cs_appendtopic] Unable to create APPENDTOPIC command: %d", + status); + return MOD_STOP; + } + moduleAddHelp(c, my_cs_help_appendtopic); + moduleSetChanHelp(my_cs_help); + + my_add_languages(); + + alog("[cs_appendtopic] Loaded successfully"); + + return MOD_CONT; +} + +void AnopeFini(void) +{ + alog("[cs_appendtopic] Unloaded successfully"); +} + +void my_cs_help(User * u) +{ + moduleNoticeLang(s_ChanServ, u, LNG_CHAN_HELP); +} + +int my_cs_help_appendtopic(User * u) +{ + moduleNoticeLang(s_ChanServ, u, LNG_APPENDTOPIC_SYNTAX); + notice(s_ChanServ, u->nick, " "); + moduleNoticeLang(s_ChanServ, u, LNG_CHAN_HELP_APPENDTOPIC); + return MOD_STOP; +} + +int my_cs_appendtopic(User * u) +{ + char *cur_buffer; + char *chan; + char *newtopic; + char topic[1024]; + Channel *c; + ChannelInfo *ci; + + cur_buffer = moduleGetLastBuffer(); + chan = myStrGetToken(cur_buffer, ' ', 0); + newtopic = myStrGetTokenRemainder(cur_buffer, ' ', 1); + + if (!chan || !newtopic) { + moduleNoticeLang(s_ChanServ, u, LNG_APPENDTOPIC_SYNTAX); + } else if (!(c = findchan(chan))) { + notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan); + } else if (!(ci = c->ci)) { + notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, c->name); + } else if (ci->flags & CI_VERBOTEN) { + notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, ci->name); + } else if (!is_services_admin(u) && !check_access(u, ci, CA_TOPIC)) { + notice_lang(s_ChanServ, u, PERMISSION_DENIED); + } else { + if (ci->last_topic) { + snprintf(topic, sizeof(topic), "%s %s", ci->last_topic, + newtopic); + free(ci->last_topic); + } else { + strscpy(topic, newtopic, sizeof(topic)); + } + + ci->last_topic = *topic ? sstrdup(topic) : NULL; + strscpy(ci->last_topic_setter, u->nick, NICKMAX); + ci->last_topic_time = time(NULL); + + if (c->topic) + free(c->topic); + c->topic = *topic ? sstrdup(topic) : NULL; + strscpy(c->topic_setter, u->nick, NICKMAX); + if (ircd->topictsbackward) + c->topic_time = c->topic_time - 1; + else + c->topic_time = ci->last_topic_time; + + if (is_services_admin(u) && !check_access(u, ci, CA_TOPIC)) + alog("%s: %s!%s@%s changed topic of %s as services admin.", + s_ChanServ, u->nick, u->username, u->host, c->name); + if (ircd->join2set) { + if (whosends(ci) == s_ChanServ) { + anope_cmd_join(s_ChanServ, c->name, c->creation_time); + anope_cmd_mode(NULL, c->name, "+o %s", s_ChanServ); + } + } + anope_cmd_topic(whosends(ci), c->name, u->nick, topic, c->topic_time); + if (ircd->join2set) { + if (whosends(ci) == s_ChanServ) { + anope_cmd_part(s_ChanServ, c->name, NULL); + } + } + } + return MOD_CONT; +} + +void my_add_languages(void) +{ + /* English (US) */ + char *langtable_en_us[] = { + /* LNG_CHAN_HELP */ + " APPENDTOPIC Add text to a channels topic", + /* LNG_CHAN_HELP_APPENDTOPIC */ + "This command allows users to append text to a currently set\n" + "channel topic. When TOPICLOCK is on, the topic is updated and\n" + "the new, updated topic is locked.", + /* LNG_APPENDTOPIC_SYNTAX */ + "Syntax: APPENDTOPIC channel text\n" + }; + + /* Dutch (NL) */ + char *langtable_nl[] = { + /* LNG_CHAN_HELP */ + " APPENDTOPIC Voeg tekst aan een kanaal onderwerp toe", + /* LNG_CHAN_HELP_APPENDTOPIC */ + "Dit command stelt gebruikers in staat om text toe te voegen\n" + "achter het huidige onderwerp van een kanaal. Als TOPICLOCK aan\n" + "staat, zal het onderwerp worden bijgewerkt en zal het nieuwe,\n" + "bijgewerkte topic worden geforceerd.", + /* LNG_APPENDTOPIC_SYNTAX */ + "Gebruik: APPENDTOPIC kanaal tekst\n" + }; + + /* German (DE) */ + char *langtable_de[] = { + /* LNG_CHAN_HELP */ + " APPENDTOPIC Fьgt einen Text zu einem Channel-Topic hinzu.", + /* LNG_CHAN_HELP_APPENDTOPIC */ + "Dieser Befehl erlaubt Benutzern, einen Text zu dem vorhandenen Channel-Topic\n" + "hinzuzufьgen. Wenn TOPICLOCK gesetzt ist, wird das Topic aktualisiert\n" + "und das neue, aktualisierte Topic wird gesperrt.", + /* LNG_APPENDTOPIC_SYNTAX */ + "Syntax: APPENDTOPIC Channel Text\n" + }; + + /* Portuguese (PT) */ + char *langtable_pt[] = { + /* LNG_CHAN_HELP */ + " APPENDTOPIC Adiciona texto ao tуpico de um canal", + /* LNG_CHAN_HELP_APPENDTOPIC */ + "Este comando permite aos usuбrios anexar texto a um tуpico de canal\n" + "jб definido. Quando TOPICLOCK estб ativado, o tуpico й atualizado e\n" + "o novo tуpico й travado.", + /* LNG_APPENDTOPIC_SYNTAX */ + "Sintaxe: APPENDTOPIC canal texto\n" + }; + + /* Russian (RU) */ + char *langtable_ru[] = { + /* LNG_CHAN_HELP */ + " APPENDTOPIC Добавляет текст к топику канала", + /* LNG_CHAN_HELP_APPENDTOPIC */ + "Данная команда позволяет добавить текст к топику, который установлен на указанном\n" + "канале. Если активирован режим TOPICLOCK, топик будет обновлен и заблокирован.\n" + "Примечание: текст будет ДОБАВЛЕН к топику, то есть старый топик удален НЕ БУДЕТ.\n", + /* LNG_APPENDTOPIC_SYNTAX */ + "Синтаксис: APPENDTOPIC #канал текст\n" + }; + + /* Italian (IT) */ + char *langtable_it[] = { + /* LNG_CHAN_HELP */ + " APPENDTOPIC Aggiunge del testo al topic di un canale", + /* LNG_CHAN_HELP_APPENDTOPIC */ + "Questo comando permette agli utenti di aggiungere del testo ad un topic di un canale\n" + "giа impostato. Se TOPICLOCK и attivato, il topic viene aggiornato e il nuovo topic\n" + "viene bloccato.", + /* LNG_APPENDTOPIC_SYNTAX */ + "Sintassi: APPENDTOPIC canale testo\n" + }; + + moduleInsertLanguage(LANG_EN_US, LNG_NUM_STRINGS, langtable_en_us); + moduleInsertLanguage(LANG_NL, LNG_NUM_STRINGS, langtable_nl); + moduleInsertLanguage(LANG_DE, LNG_NUM_STRINGS, langtable_de); + moduleInsertLanguage(LANG_PT, LNG_NUM_STRINGS, langtable_pt); + moduleInsertLanguage(LANG_RU, LNG_NUM_STRINGS, langtable_ru); + moduleInsertLanguage(LANG_IT, LNG_NUM_STRINGS, langtable_it); +} + +/* EOF */ diff --git a/src/modules/cs_enforce.c b/src/modules/cs_enforce.c new file mode 100644 index 000000000..a9beec419 --- /dev/null +++ b/src/modules/cs_enforce.c @@ -0,0 +1,479 @@ +/* cs_enforce - Add a /cs ENFORCE command to enforce various set + * options and channelmodes on a channel. + * + * (C) 2003-2008 Anope Team + * Contact us at info@anope.org + * + * Included in the Anope module pack since Anope 1.7.9 + * Anope Coder: GeniusDex <geniusdex@anope.org> + * + * Please read COPYING and README for further details. + * + * Send any bug reports to the Anope Coder, as he will be able + * to deal with it best. + */ + +#include "module.h" + +#define AUTHOR "Anope" +#define VERSION "$Id$" + +int my_cs_enforce(User * u); +void my_cs_help(User * u); +int my_cs_help_enforce(User * u); +void my_add_languages(void); + +#define LNG_NUM_STRINGS 6 + +#define LNG_CHAN_HELP 0 +#define LNG_ENFORCE_SYNTAX 1 +#define LNG_CHAN_HELP_ENFORCE 2 +#define LNG_CHAN_HELP_ENFORCE_R_ENABLED 3 +#define LNG_CHAN_HELP_ENFORCE_R_DISABLED 4 +#define LNG_CHAN_RESPONSE 5 + +int AnopeInit(int argc, char **argv) +{ + Command *c; + int status; + + moduleAddAuthor(AUTHOR); + moduleAddVersion(VERSION); + moduleSetType(SUPPORTED); + + c = createCommand("ENFORCE", my_cs_enforce, NULL, -1, -1, -1, -1, -1); + if ((status = moduleAddCommand(CHANSERV, c, MOD_HEAD))) { + alog("[cs_enforce] Unable to create ENFORCE command: %d", status); + return MOD_STOP; + } + + moduleAddHelp(c, my_cs_help_enforce); + moduleSetChanHelp(my_cs_help); + + my_add_languages(); + + return MOD_CONT; +} + +void AnopeFini(void) +{ + /* Nothing to clean up */ +} + +/* Enforcing functions */ +void do_enforce_secureops(Channel * c) +{ + struct c_userlist *user; + struct c_userlist *next; + ChannelInfo *ci; + uint32 flags; + + if (!(ci = c->ci)) + return; + + if (debug) + alog("debug: cs_enforce: Enforcing SECUREOPS on %s", c->name); + + /* Dirty hack to allow chan_set_correct_modes to work ok. + * We pretend like SECUREOPS is on so it doesn't ignore that + * part of the code. This way we can enforce SECUREOPS even + * if it's off. + */ + flags = ci->flags; + ci->flags |= CI_SECUREOPS; + + user = c->users; + do { + next = user->next; + chan_set_correct_modes(user->user, c, 0); + user = next; + } while (user); + + ci->flags = flags; +} + +void do_enforce_restricted(Channel * c) +{ + struct c_userlist *user; + struct c_userlist *next; + ChannelInfo *ci; + int16 old_nojoin_level; + char mask[BUFSIZE]; + char *reason; + char *av[3]; + User *u; + + if (!(ci = c->ci)) + return; + + if (debug) + alog("debug: cs_enforce: Enforcing RESTRICTED on %s", c->name); + + old_nojoin_level = ci->levels[CA_NOJOIN]; + if (ci->levels[CA_NOJOIN] < 0) + ci->levels[CA_NOJOIN] = 0; + + user = c->users; + do { + next = user->next; + u = user->user; + if (check_access(u, c->ci, CA_NOJOIN)) { + get_idealban(ci, u, mask, sizeof(mask)); + reason = getstring(u->na, CHAN_NOT_ALLOWED_TO_JOIN); + anope_cmd_mode(whosends(ci), ci->name, "+b %s %lu", mask, + time(NULL)); + anope_cmd_kick(whosends(ci), ci->name, u->nick, "%s", reason); + av[0] = ci->name; + av[1] = u->nick; + av[2] = reason; + do_kick(s_ChanServ, 3, av); + } + user = next; + } while (user); + + ci->levels[CA_NOJOIN] = old_nojoin_level; +} + +void do_enforce_cmode_R(Channel * c) +{ + struct c_userlist *user; + struct c_userlist *next; + ChannelInfo *ci; + char mask[BUFSIZE]; + char *reason; + char *av[3]; + User *u; + CBMode *cbm; + + if (!(ci = c->ci)) + return; + + if (debug) + alog("debug: cs_enforce: Enforcing mode +R on %s", c->name); + + user = c->users; + do { + next = user->next; + u = user->user; + if (!nick_identified(u)) { + get_idealban(ci, u, mask, sizeof(mask)); + reason = getstring(u->na, CHAN_NOT_ALLOWED_TO_JOIN); + if (((cbm = &cbmodes['R'])->flag == 0) + || !(c->mode & cbm->flag)) + anope_cmd_mode(whosends(ci), ci->name, "+b %s %lu", mask, + time(NULL)); + anope_cmd_kick(whosends(ci), ci->name, u->nick, "%s", reason); + av[0] = ci->name; + av[1] = u->nick; + av[2] = reason; + do_kick(s_ChanServ, 3, av); + } + user = next; + } while (user); +} + +/* Enforcing Group Functions */ +void do_enforce_set(Channel * c) +{ + ChannelInfo *ci; + + if (!(ci = c->ci)) + return; + + if (ci->flags & CI_SECUREOPS) + do_enforce_secureops(c); + if (ci->flags & CI_RESTRICTED) + do_enforce_restricted(c); +} + +void do_enforce_modes(Channel * c) +{ + CBMode *cbm; + + if (((cbm = &cbmodes['R'])->flag != 0) && (c->mode & cbm->flag)) + do_enforce_cmode_R(c); +} + +/* End of enforcing functions */ + +int my_cs_enforce(User * u) +{ + char *cur_buffer; + char *chan=NULL; + char *what=NULL; + Channel *c; + ChannelInfo *ci; + + cur_buffer = moduleGetLastBuffer(); + chan = myStrGetToken(cur_buffer, ' ', 0); + + if (!chan) { + moduleNoticeLang(s_ChanServ, u, LNG_ENFORCE_SYNTAX); + } else if (!(c = findchan(chan))) { + notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan); + } else if (!(ci = c->ci)) { + notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan); + } else if (ci->flags & CI_VERBOTEN) { + notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, ci->name); + } else if (!is_services_admin(u) && !check_access(u, ci, CA_AKICK)) { + notice_lang(s_ChanServ, u, PERMISSION_DENIED); + } else { + what = myStrGetToken(cur_buffer, ' ', 1); + if (!what || (stricmp(what, "SET") == 0)) { + do_enforce_set(c); + moduleNoticeLang(s_ChanServ,u,LNG_CHAN_RESPONSE,what); + } else if (stricmp(what, "MODES") == 0) { + do_enforce_modes(c); + moduleNoticeLang(s_ChanServ,u,LNG_CHAN_RESPONSE,what); + } else if (stricmp(what, "SECUREOPS") == 0) { + do_enforce_secureops(c); + moduleNoticeLang(s_ChanServ,u,LNG_CHAN_RESPONSE,what); + } else if (stricmp(what, "RESTRICTED") == 0) { + do_enforce_restricted(c); + moduleNoticeLang(s_ChanServ,u,LNG_CHAN_RESPONSE,what); + } else if (stricmp(what, "+R") == 0) { + do_enforce_cmode_R(c); + moduleNoticeLang(s_ChanServ,u,LNG_CHAN_RESPONSE,what); + } else { + moduleNoticeLang(s_ChanServ, u, LNG_ENFORCE_SYNTAX); + } + } + + if(chan) free(chan); + if(what) free(what); + + return MOD_CONT; +} + +/* Language and response stuff */ +void my_cs_help(User * u) +{ + moduleNoticeLang(s_ChanServ, u, LNG_CHAN_HELP); +} + +int my_cs_help_enforce(User * u) +{ + moduleNoticeLang(s_ChanServ, u, LNG_ENFORCE_SYNTAX); + notice(s_ChanServ, u->nick, " "); + moduleNoticeLang(s_ChanServ, u, LNG_CHAN_HELP_ENFORCE); + notice(s_ChanServ, u->nick, " "); + if (cbmodes['R'].flag != 0) + moduleNoticeLang(s_ChanServ, u, LNG_CHAN_HELP_ENFORCE_R_ENABLED); + else + moduleNoticeLang(s_ChanServ, u, LNG_CHAN_HELP_ENFORCE_R_DISABLED); + + return MOD_STOP; +} + +void my_add_languages(void) +{ + /* English (US) */ + char *langtable_en_us[] = { + /* LNG_CHAN_HELP */ + " ENFORCE Enforce various channel modes and set options", + /* LNG_ENFORCE_SYNTAX */ + "Syntax: \002ENFORCE \037channel\037 [\037what\037]\002", + /* LNG_CHAN_HELP_ENFORCE */ + "Enforce various channel modes and set options. The \037channel\037\n" + "option indicates what channel to enforce the modes and options\n" + "on. The \037what\037 option indicates what modes and options to\n" + "enforce, and can be any of SET, SECUREOPS, RESTRICTED, MODES,\n" + "or +R. When left out, it defaults to SET.\n" + " \n" + "If \037what\037 is SET, it will enforce SECUREOPS and RESTRICTED\n" + "on the users currently in the channel, if they are set. Give\n" + "SECUREOPS to enforce the SECUREOPS option, even if it is not\n" + "enabled. Use RESTRICTED to enfore the RESTRICTED option, also\n" + "if it's not enabled.", + /* LNG_CHAN_HELP_ENFORCE_R_ENABLED */ + "If \037what\037 is MODES, it will enforce channelmode +R if it is\n" + "set. If +R is specified for \037what\037, the +R channelmode will\n" + "also be enforced, but even if it is not set. If it is not set,\n" + "users will be banned to ensure they don't just rejoin.", + /* LNG_CHAN_HELP_ENFORCE_R_DISABLED */ + "If \037what\037 is MODES, nothing will be enforced, since it would\n" + "enforce modes that the current ircd does not support. If +R is\n" + "specified for \037what\037, an equalivant of channelmode +R on\n" + "other ircds will be enforced. All users that are in the channel\n" + "but have not identified for their nickname will be kicked and\n" + "banned from the channel.", + /* LNG_CHAN_RESPONSE */ + "Enforced %s" + }; + + /* Dutch (NL) */ + char *langtable_nl[] = { + /* LNG_CHAN_HELP */ + " ENFORCE Forceer enkele kanaalmodes en set-opties", + /* LNG_ENFORCE_SYNTAX */ + "Syntax: \002ENFORCE \037kanaal\037 [\037wat\037]\002", + /* LNG_CHAN_HELP_ENFORCE */ + "Forceer enkele kannalmodes en set-opties. De \037kanaal\037 optie\n" + "geeft aan op welk kanaal de modes en opties geforceerd moeten\n" + "worden. De \037wat\037 optie geeft aan welke modes en opties\n" + "geforceerd moeten worden; dit kan SET, SECUREOPS, RESTRICTED,\n" + "MODES, of +R zijn. Indien weggelaten is dit standaard SET.\n" + " \n" + "Als er voor \037wat\037 SET wordt ingevuld, zullen SECUREOPS en\n" + "RESTRICTED geforceerd worden op de gebruikers in het kanaal,\n" + "maar alleen als die opties aangezet zijn voor het kanaal. Als\n" + "SECUREOPS of RESTRICTED wordt gegeven voor \037wat\037 zal die optie\n" + "altijd geforceerd worden, ook als die niet is aangezet.", + /* LNG_CHAN_HELP_ENFORCE_R_ENABLED */ + "Als er voor \037wat\037 MODES wordt ingevuld, zal kanaalmode +R worden\n" + "geforceerd, als die op het kanaal aan staat. Als +R wordt ingevuld,\n" + "zal kanaalmode +R worden geforceerd, maar ook als die niet aan" + "staat voor het kanaal. Als +R niet aan staat, zullen alle ook\n" + "gebanned worden om te zorgen dat ze niet opnieuw het kanaal binnen\n" + "kunnen komen.", + /* LNG_CHAN_HELP_ENFORCE_R_DISABLED */ + "Als er voor \037wat\037 MODES wordt ingevuld, zal er niks gebeuren.\n" + "Normaal gesproken wordt er een kanaalmode geforceerd die op deze\n" + "server niet ondersteund wordt. Als +R wordt ingevuld voor \037wat\037\n" + "zullen alle gebruikers die in het kanaal zitten maar zich niet\n" + "hebben geidentificeerd voor hun nick uit het kanaal gekicked en\n" + "verbannen worden.", + /* LNG_CHAN_RESPONSE */ + "Enforced %s" + }; + + /* German (DE) */ + char *langtable_de[] = { + /* LNG_CHAN_HELP */ + " ENFORCE Erzwingt verschieden Modes und SET Optionen", + /* LNG_ENFORCE_SYNTAX */ + "Syntax: \002ENFORCE \037Channel\037 [\037was\037]\002", + /* LNG_CHAN_HELP_ENFORCE */ + "Erzwingt verschieden Modes und SET Optionen. Die \037Channel\037\n" + "Option zeigt dir den Channel an, indem Modes und Optionen\n" + "zu erzwingen sind. Die \037was\037 Option zeigt dir welche Modes\n" + "und Optionen zu erzwingen sind. Die kцnnen nur SET, SECUREOPS,\n" + "RESTRICTED, MODES oder +R sein.Default ist SET.\n" + " \n" + "Wenn \037was\037 SET ist, wird SECUREOPS und RESTRICTED\n" + "auf die User die z.Z.in Channel sind erzwungen, wenn sie AN sind.\n" + "Benutze SECUREOPS oder RESTRICTED , um die Optionen einzeln\n" + "zu erzwingen, also wenn sie nicht eingeschaltet sind.", + /* LNG_CHAN_HELP_ENFORCE_R_ENABLED */ + "Wenn \037was\037 MODES ist, wird das ChannelMode +R erzwungen\n" + "falls an. Wenn \037was\037 +R ist, wird +R erzwungen aber eben\n" + "wenn noch nicht als Channel-Mode ist. Wenn +R noch nicht als\n" + "Channel-Mode war werden alle User aus den Channel gebannt um\n" + "sicher zu sein das sie nicht rejoinen.", + /* LNG_CHAN_HELP_ENFORCE_R_DISABLED */ + "Wenn \037was\037 MODES ist, wird nichts erzwungen weil es MODES seine\n" + "kцnnen die dein IRCD nicht unterstьtzt. Wenn \037was\037 +R ist\n" + "oder ein Modes was auf ein anderen IRCD gleich +R ist, wird es\n" + "erzwungen. Alle User die nicht fьr deren Nicknamen identifiziert\n" + "sind werden aus den Channel gekickt und gebannt.", + /* LNG_CHAN_RESPONSE */ + "Erzwungen %s" + }; + + /* Portuguese (PT) */ + char *langtable_pt[] = { + /* LNG_CHAN_HELP */ + " ENFORCE Verifica o cumprimento de vбrios modos de canal e opзхes ajustadas", + /* LNG_ENFORCE_SYNTAX */ + "Sintaxe: \002ENFORCE \037canal\037 [\037opзгo\037]\002", + /* LNG_CHAN_HELP_ENFORCE */ + "Verifica o cumprimento de vбrios modos de canal e opзхes ajustadas.\n" + "O campo \037canal\037 indica qual canal deve ter os modos e opзхes verificadas\n" + "O campo \037opзгo\037 indica quais modos e opзхes devem ser verificadas,\n" + "e pode ser: SET, SECUREOPS, RESTRICTED, MODES ou +R\n" + "Quando deixado em branco, o padrгo й SET.\n" + " \n" + "Se \037opзгo\037 for SET, serгo verificadas as opзхes SECUREOPS e RESTRICTED\n" + "para usuбrios que estiverem no canal, caso elas estejam ativadas. Use\n" + "SECUREOPS para verificar a opзгo SECUREOPS, mesmo que ela nгo esteja ativada\n" + "Use RESTRICTED para verificar a opзгo RESTRICTED, mesmo que ela nгo esteja\n" + "ativada.", + /* LNG_CHAN_HELP_ENFORCE_R_ENABLED */ + "Se \037opзгo\037 for MODES, serб verificado o modo de canal +R caso ele\n" + "esteja ativado. Se +R for especificado para \037opзгo\037, o modo de canal\n" + "+R tambйm serб verificado, mesmo que ele nгo esteja ativado. Se ele nгo\n" + "estiver ativado, os usuбrios serгo banidos para evitar que reentrem no canal.", + /* LNG_CHAN_HELP_ENFORCE_R_DISABLED */ + "Se \037opзгo\037 for MODES, nada serб verificado, visto que isto poderia\n" + "verificar modos que o IRCd atual nгo suporta. Se +R for especificado\n" + "para \037opзгo\037, um equivalente ao modo de canal +R em outros IRCds\n" + "serб verificado. Todos os usuбrios que estгo no canal, mas nгo estejam\n" + "identificados para seus nicks serгo kickados e banidos do canal.", + /* LNG_CHAN_RESPONSE */ + "Verificado %s" + }; + + /* Russian (RU) */ + char *langtable_ru[] = { + /* LNG_CHAN_HELP */ + " ENFORCE Перепроверка и установка различных режимов и опций канала", + /* LNG_ENFORCE_SYNTAX */ + "Синтаксис: \002ENFORCE \037#канал\037 \037параметр\037\002", + /* LNG_CHAN_HELP_ENFORCE */ + "Перепроверка и установка различных режимов и опций канала.\n" + "\037Параметр\037 указывает какие опции или режимы канала должны быть\n" + "перепроверены. В качестве параметра могут быть указаны: SET, SECUREOPS,\n" + "RESTRICTED, MODES, или +R. Если параметр не указан, по-умолчанию будет SET.\n" + " \n" + "Если в качестве \037параметра\037 указано SET, будут перепроверены опции\n" + "SECUREOPS и RESTRICTED относительно пользователей на указанном канале\n" + "(при условии, что опции включены). Отдельно указанный параметр SECUREOPS\n" + "применит опцию SECUREOPS (даже если она \037НЕ\037 установлена). Параметр\n" + "RESTRICTED применит опцию RESTRICTED (даже если она \037НЕ\037 установлена)", + /* LNG_CHAN_HELP_ENFORCE_R_ENABLED */ + "Если в качестве \037параметра\037 указано MODES, будет перепроверен режим +R\n" + "(если он установлен). Отдельно указанный параметр \037+R\037 применит\n" + "канальный режим +R, даже если он не установлен, и забанит всех пользователей,\n" + "которые не идентифицировались к своему нику или не имеют зарегистрированного ника.", + /* LNG_CHAN_HELP_ENFORCE_R_DISABLED */ + "Если в качестве \037параметра\037 указано MODES, перепроверка осуществлена\n" + "НЕ БУДЕТ, так как текущий IRCD не поддерживает необходимые режимы.\n" + "Отдельно указанный параметр \037+R\037 применит канальный режим, эквивалентный\n" + "режиму +R и забанит всех пользователей, которые не идентифицировались к своему\n" + "нику или не имеют зарегистрированного ника.", + /* LNG_CHAN_RESPONSE */ + "Перепроверено: %s" + }; + + /* Italian (IT) */ + char *langtable_it[] = { + /* LNG_CHAN_HELP */ + " ENFORCE Forza diversi modi di canale ed opzioni SET", + /* LNG_ENFORCE_SYNTAX */ + "Sintassi: \002ENFORCE \037canale\037 [\037cosa\037]\002", + /* LNG_CHAN_HELP_ENFORCE */ + "Forza diversi modi di canale ed opzioni SET. Il parametro \037canale\037\n" + "indica il canale sul quale forzare i modi e le opzioni. Il parametro\n" + "\037cosa\037 indica i modi e le opzioni da forzare, e possono essere\n" + "qualsiasi delle opzioni SET, SECUREOPS, RESTRICTED, MODES, o +R.\n" + "Se non specificato, viene sottointeso SET.\n" + " \n" + "Se \037cosa\037 и SET, forzerа SECUREOPS e RESTRICTED sugli utenti\n" + "attualmente nel canale, se sono impostati. Specifica SECUREOPS per\n" + "forzare l'opzione SECUREOPS, anche se non и attivata. Specifica\n" + "RESTRICTED per forzare l'opzione RESTRICTED, anche se non и\n" + "attivata.", + /* LNG_CHAN_HELP_ENFORCE_R_ENABLED */ + "Se \037cosa\037 и MODES, forzerа il modo del canale +R se и impostato.\n" + "Se +R и specificato per \037cosa\037, il modo del canale +R verrа\n" + "forzato, anche se non и impostato. Se non и impostato, gli utenti\n" + "verranno bannati per assicurare che non rientrino semplicemente.", + /* LNG_CHAN_HELP_ENFORCE_R_DISABLED */ + "Se \037cosa\037 и MODES, niente verrа forzato, siccome forzerebbe\n" + "dei modi che l'ircd in uso non supporterebbe. Se +R и specificato\n" + "per \037cosa\037, un modo equivalente a +R sui altri ircd verrа\n" + "forzato. Tutti gli utenti presenti nel canale ma non identificati\n" + "per il loro nickname verranno bannati ed espulsi dal canale.\n", + /* LNG_CHAN_RESPONSE */ + "Forzato %s" + }; + + moduleInsertLanguage(LANG_EN_US, LNG_NUM_STRINGS, langtable_en_us); + moduleInsertLanguage(LANG_NL, LNG_NUM_STRINGS, langtable_nl); + moduleInsertLanguage(LANG_DE, LNG_NUM_STRINGS, langtable_de); + moduleInsertLanguage(LANG_PT, LNG_NUM_STRINGS, langtable_pt); + moduleInsertLanguage(LANG_RU, LNG_NUM_STRINGS, langtable_ru); + moduleInsertLanguage(LANG_IT, LNG_NUM_STRINGS, langtable_it); +} + +/* EOF */ diff --git a/src/modules/cs_tban.c b/src/modules/cs_tban.c new file mode 100644 index 000000000..9558c92fd --- /dev/null +++ b/src/modules/cs_tban.c @@ -0,0 +1,253 @@ +/* cs_tban.c - Bans the user for a given length of time + * + * (C) 2003-2008 Anope Team + * Contact us at info@anope.org + * + * Based on the original module by Rob <rob@anope.org> + * Included in the Anope module pack since Anope 1.7.8 + * Anope Coder: Rob <rob@anope.org> + * + * Please read COPYING and README for further details. + * + * Send bug reports to the Anope Coder instead of the module + * author, because any changes since the inclusion into anope + * are not supported by the original author. + * + */ +/*************************************************************************/ + +#include "module.h" + +#define AUTHOR "Rob" +#define VERSION "$Id$" + +void myHelp(User * u); +void myFullHelpSyntax(User * u); +int myFullHelp(User * u); +void mySendResponse(User * u, char *channel, char *mask, char *time); + +int do_tban(User * u); +void addBan(Channel * c, time_t timeout, char *banmask); +int delBan(int argc, char **argv); +int canBanUser(Channel * c, User * u, User * u2); + +void mAddLanguages(void); + +#define LANG_NUM_STRINGS 4 +#define TBAN_HELP 0 +#define TBAN_SYNTAX 1 +#define TBAN_HELP_DETAIL 2 +#define TBAN_RESPONSE 3 + +int AnopeInit(int argc, char **argv) +{ + Command *c; + int status = 0; + + moduleSetChanHelp(myHelp); + c = createCommand("TBAN", do_tban, NULL, -1, -1, -1, -1, -1); + moduleAddHelp(c, myFullHelp); + status = moduleAddCommand(CHANSERV, c, MOD_HEAD); + + mAddLanguages(); + + moduleAddAuthor(AUTHOR); + moduleAddVersion(VERSION); + moduleSetType(SUPPORTED); + + if (status != MOD_ERR_OK) { + return MOD_STOP; + } + return MOD_CONT; +} + +void AnopeFini(void) +{ + /* module is unloading */ +} + +void myHelp(User * u) +{ + moduleNoticeLang(s_ChanServ, u, TBAN_HELP); +} + +void myFullHelpSyntax(User * u) +{ + moduleNoticeLang(s_ChanServ, u, TBAN_SYNTAX); +} + +int myFullHelp(User * u) +{ + myFullHelpSyntax(u); + notice(s_ChanServ, u->nick, ""); + moduleNoticeLang(s_ChanServ, u, TBAN_HELP_DETAIL); + return MOD_CONT; +} + +void mySendResponse(User * u, char *channel, char *mask, char *time) +{ + moduleNoticeLang(s_ChanServ, u, TBAN_RESPONSE, mask, channel, time); +} + +int do_tban(User * u) +{ + char mask[BUFSIZE]; + Channel *c; + User *u2 = NULL; + + char *buffer = moduleGetLastBuffer(); + char *chan; + char *nick; + char *time; + + chan = myStrGetToken(buffer, ' ', 0); + nick = myStrGetToken(buffer, ' ', 1); + time = myStrGetToken(buffer, ' ', 2); + + if (time && chan && nick) { + + if (!(c = findchan(chan))) { + notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan); + } else if (!(u2 = finduser(nick))) { + notice_lang(s_ChanServ, u, NICK_X_NOT_IN_USE, nick); + } else { + if (canBanUser(c, u, u2)) { + get_idealban(c->ci, u2, mask, sizeof(mask)); + addBan(c, dotime(time), mask); + mySendResponse(u, chan, mask, time); + } + } + } else { + myFullHelpSyntax(u); + } + if (time) + free(time); + if (nick) + free(nick); + if (chan) + free(chan); + + return MOD_CONT; +} + +void addBan(Channel * c, time_t timeout, char *banmask) +{ + char *av[3]; + char *cb[2]; + + cb[0] = c->name; + cb[1] = banmask; + + av[0] = sstrdup("+b"); + av[1] = banmask; + + anope_cmd_mode(whosends(c->ci), c->name, "+b %s", av[1]); + chan_set_modes(s_ChanServ, c, 2, av, 1); + + free(av[0]); + moduleAddCallback("tban", time(NULL) + timeout, delBan, 2, cb); +} + +int delBan(int argc, char **argv) +{ + char *av[3]; + Channel *c; + + av[0] = sstrdup("-b"); + av[1] = argv[1]; + + if ((c = findchan(argv[0])) && c->ci) { + anope_cmd_mode(whosends(c->ci), c->name, "-b %s", av[1]); + chan_set_modes(s_ChanServ, c, 2, av, 1); + } + + free(av[0]); + + return MOD_CONT; +} + +int canBanUser(Channel * c, User * u, User * u2) +{ + ChannelInfo *ci; + int ok = 0; + if (!(ci = c->ci)) { + notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, c->name); + } else if (ci->flags & CI_VERBOTEN) { + notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, c->name); + } else if (!check_access(u, ci, CA_BAN)) { + notice_lang(s_ChanServ, u, ACCESS_DENIED); + } else if (ircd->except && is_excepted(ci, u2)) { + notice_lang(s_ChanServ, u, CHAN_EXCEPTED, u2->nick, ci->name); + } else if (ircd->protectedumode && is_protected(u2)) { + notice_lang(s_ChanServ, u, PERMISSION_DENIED); + } else { + ok = 1; + } + + return ok; +} + + +void mAddLanguages(void) +{ + char *langtable_en_us[] = { + " TBAN Bans the user for a given length of time", + "Syntax: TBAN channel nick time", + "Bans the given user from a channel for a specified length of\n" + "time. If the ban is removed before by hand, it will NOT be replaced.", + "%s banned from %s, will auto-expire in %s" + }; + + char *langtable_nl[] = { + " TBAN Verban een gebruiker voor een bepaalde tijd", + "Syntax: TBAN kanaal nick tijd", + "Verbant de gegeven gebruiken van het gegeven kanaal voor de\n" + "gegeven tijdsduur. Als de verbanning eerder wordt verwijderd,\n" + "zal deze NIET worden vervangen.", + "%s verbannen van %s, zal verlopen in %s" + }; + + char *langtable_de[] = { + " TBAN Bant ein User fьr eine bestimmte Zeit aus ein Channel", + "Syntax: TBAN Channel Nickname Zeit", + "Bant ein User fьr eine bestimmte Zeit aus ein Channel\n" + "Wenn der Ban manuell entfernt wird, wird es NICHT ersetzt.", + "%s gebannt von %s, wird auto-auslaufen in %s" + }; + + char *langtable_pt[] = { + " TBAN Bane o usuбrio por um determinado perнodo de tempo", + "Sintaxe: TBAN canal nick tempo", + "Bane de um canal o usuбrio especificado por um determinado perнodo de\n" + "tempo. Se o ban for removido manualmente antes do tempo, ele nгo serб recolocado.", + "%s foi banido do %s, irб auto-expirar em %s" + }; + + char *langtable_ru[] = { + " TBAN Банит пользователя на указанный промежуток времени", + "Синтаксис: TBAN #канал ник время", + "Банит пользователя на указанный промежуток времени в секундах\n" + "Примечание: удаленный вручную (до своего истечения) бан НЕ БУДЕТ\n" + "переустановлен сервисами автоматически!", + "Установленный бан %s на канале %s истечет через %s секунд" + }; + + char *langtable_it[] = { + " TBAN Banna l'utente per un periodo di tempo specificato", + "Sintassi: TBAN canale nick tempo", + "Banna l'utente specificato da un canale per un periodo di tempo\n" + "specificato. Se il ban viene rimosso a mano prima della scadenza, NON verrа rimpiazzato.", + "%s bannato da %s, scadrа automaticamente tra %s" + }; + + moduleInsertLanguage(LANG_EN_US, LANG_NUM_STRINGS, langtable_en_us); + moduleInsertLanguage(LANG_NL, LANG_NUM_STRINGS, langtable_nl); + moduleInsertLanguage(LANG_DE, LANG_NUM_STRINGS, langtable_de); + moduleInsertLanguage(LANG_PT, LANG_NUM_STRINGS, langtable_pt); + moduleInsertLanguage(LANG_RU, LANG_NUM_STRINGS, langtable_ru); + moduleInsertLanguage(LANG_IT, LANG_NUM_STRINGS, langtable_it); + +} + + +/* EOF */ diff --git a/src/modules/demos/catserv/Makefile b/src/modules/demos/catserv/Makefile new file mode 100644 index 000000000..5b2f4efa3 --- /dev/null +++ b/src/modules/demos/catserv/Makefile @@ -0,0 +1,9 @@ +SRCS= ircd_catserv.c \ + catserv_messages.c \ + meow.c \ + purr.c + +TARGET=ircd_catserv + +include ../Makefile.sub + diff --git a/src/modules/demos/catserv/README b/src/modules/demos/catserv/README new file mode 100644 index 000000000..c3d3f7084 --- /dev/null +++ b/src/modules/demos/catserv/README @@ -0,0 +1,4 @@ +This is an EXAMPLE module, it serves no real purpose. + +This module was broken down into multiple files to demonstrate how multiple files can be used. + diff --git a/src/modules/demos/catserv/catserv_extern.h b/src/modules/demos/catserv/catserv_extern.h new file mode 100644 index 000000000..02c21addb --- /dev/null +++ b/src/modules/demos/catserv/catserv_extern.h @@ -0,0 +1,11 @@ +#ifndef CATSERV_DEFS_H +#define CATSERV_DEFS_H + +#ifdef _WIN32 +extern __declspec(dllexport) char *s_CatServ; +#else +E char *s_CatServ; +#endif + +#endif + diff --git a/src/modules/demos/catserv/catserv_messages.c b/src/modules/demos/catserv/catserv_messages.c new file mode 100644 index 000000000..e11235b4e --- /dev/null +++ b/src/modules/demos/catserv/catserv_messages.c @@ -0,0 +1,14 @@ +#include "catserv_messages.h" +#include "module.h" +#include "meow.h" +#include "purr.h" + +void addMessageList(void) +{ + Command *c; + c = createCommand("meow", do_meow, NULL, -1, -1, -1, -1, -1); + moduleAddCommand(Catserv_cmdTable, c, MOD_UNIQUE); + c = createCommand("purr", do_purr, NULL, -1, -1, -1, -1, -1); + moduleAddCommand(Catserv_cmdTable, c, MOD_UNIQUE); +} + diff --git a/src/modules/demos/catserv/catserv_messages.h b/src/modules/demos/catserv/catserv_messages.h new file mode 100644 index 000000000..bb3f82dd0 --- /dev/null +++ b/src/modules/demos/catserv/catserv_messages.h @@ -0,0 +1,10 @@ +#ifndef CATSERV_MESSAGES_H +#define CATSERV_MESSAGES_H + +#include "module.h" + +CommandHash *Catserv_cmdTable[MAX_CMD_HASH]; +void addMessageList(void); + +#endif + diff --git a/src/modules/demos/catserv/ircd_catserv.c b/src/modules/demos/catserv/ircd_catserv.c new file mode 100644 index 000000000..ae34d6161 --- /dev/null +++ b/src/modules/demos/catserv/ircd_catserv.c @@ -0,0 +1,112 @@ +/** + * Simple module to load up a client called CatServ and process commands for it + * This module is an example, and has no useful purpose! + * + * Please visit http://modules.anope.org for useful modules! + * + **/ + +#include "module.h" +#include "catserv_messages.h" + +#define AUTHOR "Anope" +#define VERSION "$Id$" + +int my_privmsg(char *source, int ac, char **av); + +void addClient(char *nick, char *realname); +void delClient(void); +void catserv(User * u, char *buf); + +char *s_CatServ = "CatServ"; + +int AnopeInit(int argc, char **argv) +{ + Message *msg = NULL; + int status; +#ifdef IRC_UNREAL32 + if (UseTokens) { + msg = createMessage("!", my_privmsg); + } else { + msg = createMessage("PRIVMSG", my_privmsg); + } +#else + msg = createMessage("PRIVMSG", my_privmsg); +#endif + status = moduleAddMessage(msg, MOD_HEAD); + if (status == MOD_ERR_OK) { + addClient(s_CatServ, "meow!"); + addMessageList(); + } + moduleAddAuthor(AUTHOR); + moduleAddVersion(VERSION); + alog("ircd_catserv.so: loaded, message status [%d]", status); + return MOD_CONT; +} + +void AnopeFini(void) +{ + delClient(); +} + +int my_privmsg(char *source, int ac, char **av) +{ + User *u; + char *s; + + /* First, some basic checks */ + if (ac != 2) + return MOD_CONT; /* bleh */ + if (!(u = finduser(source))) { + return MOD_CONT; + } /* non-user source */ + if (*av[0] == '#') { + return MOD_CONT; + } + /* Channel message */ + /* we should prolly honour the ignore list here, but i cba for this... */ + s = strchr(av[0], '@'); + if (s) { + *s++ = 0; + if (stricmp(s, ServerName) != 0) + return MOD_CONT; + } + if ((stricmp(av[0], s_CatServ)) == 0) { /* its for US! */ + catserv(u, av[1]); + return MOD_STOP; + } else { /* ok it isnt us, let the old code have it */ + return MOD_CONT; + } +} + +void addClient(char *nick, char *realname) +{ + anope_cmd_bot_nick(nick, "catserv", "meow.meow.land", realname, "+"); +} + +void delClient(void) +{ + anope_cmd_quit(s_CatServ, "QUIT :Module Unloaded!"); +} + +/*****************************************************************************/ +/* Main CatServ routine. */ +void catserv(User * u, char *buf) +{ + char *cmd, *s; + + cmd = strtok(buf, " "); + + if (!cmd) { + return; + } else if (stricmp(cmd, "\1PING") == 0) { + if (!(s = strtok(NULL, ""))) + s = "\1"; + notice(s_CatServ, u->nick, "\1PING %s", s); + } else if (skeleton) { + notice_lang(s_CatServ, u, SERVICE_OFFLINE, s_CatServ); + } else { + mod_run_cmd(s_CatServ, u, Catserv_cmdTable, cmd); + } +} + diff --git a/src/modules/demos/catserv/makefile.win32 b/src/modules/demos/catserv/makefile.win32 new file mode 100644 index 000000000..638704440 --- /dev/null +++ b/src/modules/demos/catserv/makefile.win32 @@ -0,0 +1,4 @@ +SRCS=ircd_catserv.c purr.c catserv_messages.c meow.c +TARGET=ircd_catserv.dll + +include ..\Makefile.sub.win32 diff --git a/src/modules/demos/catserv/meow.c b/src/modules/demos/catserv/meow.c new file mode 100644 index 000000000..9279eec0b --- /dev/null +++ b/src/modules/demos/catserv/meow.c @@ -0,0 +1,9 @@ +#include "meow.h" + +#include "catserv_extern.h" + +int do_meow(User * u) { + notice(s_CatServ, u->nick, "MEOW!"); + return MOD_STOP; +} + diff --git a/src/modules/demos/catserv/meow.h b/src/modules/demos/catserv/meow.h new file mode 100644 index 000000000..0f28673a0 --- /dev/null +++ b/src/modules/demos/catserv/meow.h @@ -0,0 +1,9 @@ +#ifndef CATSERV_MEOW_H +#define CATSERV_MEOW_H + +#include "module.h" + +int do_meow(User * u); + +#endif + diff --git a/src/modules/demos/catserv/purr.c b/src/modules/demos/catserv/purr.c new file mode 100644 index 000000000..5a39dc26e --- /dev/null +++ b/src/modules/demos/catserv/purr.c @@ -0,0 +1,8 @@ +#include "purr.h" +#include "catserv_extern.h" + +int do_purr(User * u) +{ + notice(s_CatServ, u->nick, "PURR!"); + return MOD_STOP; +} diff --git a/src/modules/demos/catserv/purr.h b/src/modules/demos/catserv/purr.h new file mode 100644 index 000000000..a92e421f6 --- /dev/null +++ b/src/modules/demos/catserv/purr.h @@ -0,0 +1,9 @@ +#ifndef CATSERV_PURR_H +#define CATSERV_PURR_H + +#include "module.h" + +int do_purr(User * u); + +#endif + diff --git a/src/modules/demos/events.c b/src/modules/demos/events.c new file mode 100644 index 000000000..dad0fd0e6 --- /dev/null +++ b/src/modules/demos/events.c @@ -0,0 +1,82 @@ +/** + * Simple module to show the usage of event messages and hooks + * This module is an example, and has no useful purpose! + * + * Please visit http://modules.anope.org for useful modules! + * + **/ + +#include "module.h" + +#define AUTHOR "Anope" +#define VERSION "$Id$" + +int my_nick(char *source, int ac, char **av); +int my_save(int argc, char **argv); +int do_moo(int argc, char **argv); + +int AnopeInit(int argc, char **argv) +{ + EvtMessage *msg = NULL; + EvtHook *hook = NULL; + int status; + msg = createEventHandler("NICK", my_nick); + status = moduleAddEventHandler(msg); + + hook = createEventHook(EVENT_DB_SAVING, my_save); + status = moduleAddEventHook(hook); + + + hook = createEventHook(EVENT_BOT_FANTASY, do_moo); + status = moduleAddEventHook(hook); + + moduleAddAuthor(AUTHOR); + moduleAddVersion(VERSION); + return MOD_CONT; +} + +void AnopeFini(void) +{ + /* unloading */ +} + +int my_nick(char *source, int ac, char **av) +{ + alog("Internal Event - nick is %s",av[0]); + return MOD_CONT; +} + +int my_save(int argc, char **argv) +{ + if(argc>=1) { + if (!stricmp(argv[0], EVENT_START)) { + alog("Saving the databases! has started"); + } else { + alog("Saving the databases is complete"); + } + } + return MOD_CONT; +} + +/** + * command to be called when a EVENT_BOT_FANTASY event is recived. + * @param argc The paramater count for this event. + * @param argv[0] The cmd used. + * @param argv[1] The nick of the command user. + * @param argv[2] The channel name the command was used in. + * @param argv[3] The rest of the text after the command. + * @return MOD_CONT or MOD_STOP + **/ +int do_moo(int argc, char **argv) { + ChannelInfo *ci; + if(argc>=3) { /* We need at least 3 arguments */ + if(stricmp(argv[0],"moo")==0) { /* is it meant for us? */ + if((ci = cs_findchan(argv[2]))) { /* channel should always exist */ + anope_cmd_privmsg(ci->bi->nick, ci->name, "%cACTION moo's at %s %c",1,argv[1],1); + return MOD_STOP; /* We've dealt with it, dont let others */ + } + } + } + return MOD_CONT; /* guess it wasnt for us, pass it on */ +} + diff --git a/src/modules/demos/hs_conf.c b/src/modules/demos/hs_conf.c new file mode 100644 index 000000000..45b4bb330 --- /dev/null +++ b/src/modules/demos/hs_conf.c @@ -0,0 +1,74 @@ +#include "module.h" + +#define AUTHOR "Anope" +#define VERSION "1" + +/** + * Default setting to be used if no confing value is found + **/ +#define DEFAULT_SETTING "moo" + +int mShowSetting(User *u); +int mReadConfig(int argc, char **argv); + +char *setting; + +int AnopeInit(int argc, char **argv) { + Command *c; + EvtHook *hook; + int status = 0; + + setting = NULL; + + mReadConfig(0,NULL); + + c = createCommand("SHOW",mShowSetting,NULL,-1,-1,-1,-1,-1); + status = moduleAddCommand(HOSTSERV, c, MOD_HEAD); + + hook = createEventHook(EVENT_RELOAD, mReadConfig); + status = moduleAddEventHook(hook); + + if(status!=MOD_ERR_OK) { + return MOD_STOP; + } + return MOD_CONT; +} + +/** + * free the globals when we close + **/ +void AnopeFini(void) { + if(setting) + free(setting); +} + +/** + * Simple function to show the user the current config setting + **/ +int mShowSetting(User *u) { + notice(s_HostServ,u->nick,"Setting in use is [%s]",setting); + return MOD_CONT; +} + +/** + * Load the config setting up, this will be called whenever + * the EVENT_RELOAD event is recived. + **/ +int mReadConfig(int argc, char **argv) { + char *tmp=NULL; + Directive d[] = {{"HSConfigSetting", {{PARAM_STRING, PARAM_RELOAD, &tmp}}}}; + moduleGetConfigDirective(d); + + if(setting) { + free(setting); + } + if(tmp) { + setting = tmp; + } else { + setting = sstrdup(DEFAULT_SETTING); + } + return MOD_CONT; +} + + +/* EOF */ diff --git a/src/modules/demos/hs_moo.c b/src/modules/demos/hs_moo.c new file mode 100644 index 000000000..b65e83bb6 --- /dev/null +++ b/src/modules/demos/hs_moo.c @@ -0,0 +1,119 @@ +/** + * This is an EXAMPLE module, which adds the "moo" command to HostServ + * + * This command does NOT do anything useful at all! + * + * Please visit http://modules.anope.org for useful modules! + * + **/ +#include "module.h" + +#define AUTHOR "Anope" /* Set the Author for a modinfo reply */ +#define VERSION "$Id$" /* Set the version for a modinfo reply */ + +int hs_moo_show(User * u); /* Function to use when a /hs moo command is recived */ +int test(int argc, char **argv); +void myHostServHelp(User *u); /* Function to display out help in a /hs help response */ +int myHostServMooHelp(User *u); /* Function to display help to _everyone_ when a /hs help moo is called*/ +int myHostServMooRegHelp(User *u); /* Function to display extra help to regular-users when a /hs help moo is called*/ +int myHostServMooOperHelp(User *u); /* Function to display extra help to opers when a /hs help moo is called*/ +int myHostServMooAdminHelp(User *u); /* Function to display extra help to admins when a /hs help moo is called*/ +int myHostServMooRootHelp(User *u); /* Function to display extra help to roors when a /hs help moo is called*/ + +int AnopeInit(int argc, char **argv) /* This will be executed when the module is loaded */ +{ + Command *c; /* Pointer to a Command */ + int status = 0; /* the status of our new command */ + c = createCommand("moo", hs_moo_show, NULL, -1, -1, -1, -1, -1); /* Create a new command "moo" pointing to hs_moo */ + + moduleAddHelp(c,myHostServMooHelp); /* add help for all users to this command */ + moduleAddRegHelp(c,myHostServMooRegHelp); /* add extra regular-user only help to this command */ + moduleAddOperHelp(c,myHostServMooOperHelp); /* add extra oper only help to this command */ + moduleAddAdminHelp(c,myHostServMooAdminHelp); /* add extra admin only help to this command */ + moduleAddRootHelp(c,myHostServMooRootHelp); /* add extra root only help to this command */ + + moduleSetHostHelp(myHostServHelp); /* add us to the .hs help list */ + + status = moduleAddCommand(HOSTSERV, c, MOD_HEAD); /* Add the command to the HOSTSERV cmd table */ + + /* Check if we have any argv's */ + if(argc>0) { + /* we do, the first will be the nick of the person modload'ing us */ + /* or NULL if we were auto-loaded */ + if(argv[0]) { + alog("hs_moo was modloaded by: [%s]",argv[0]); + } else { + alog("hs_moo was automatically loaded by anope"); + } + } + alog("hs_moo.so: Add Command 'moo' Status: %d",status); /* Log the command being added */ + + moduleAddCallback("test",time(NULL)+dotime("15s"),test,0,NULL); /* set a call-back function to exec in 3 mins time */ + moduleDelCallback("test"); + moduleAddAuthor(AUTHOR); /* tell Anope about the author */ + moduleAddVersion(VERSION); /* Tell Anope about the verison */ + + if(status!=MOD_ERR_OK) { + return MOD_STOP; + } + return MOD_CONT; +} + +int hs_moo_show(User * u) +{ + notice(s_HostServ, u->nick, "MOO! - This command was loaded via a module!"); /* Just notice the user */ + return MOD_STOP; /* MOD_STOP means we will NOT pass control back to other */ +} /* modules waiting to handle the /hs moo command! */ + +int test(int argc, char **argv) { + alog("CallBack from hs_moo with %d paramaters",argc); + return MOD_CONT; +} + +void AnopeFini(void) +{ + /* module is unloading */ +} + +/***************************************************************************************************************************************/ +/* The code below here shows various ways of dealing with the module help system */ +/***************************************************************************************************************************************/ + +void myHostServHelp(User *u) { + notice(s_HostServ,u->nick, " MOO Moo's at the user!"); /* this will appear in the help list */ +} + +int myHostServMooHelp(User *u) { + notice(s_HostServ,u->nick,"Syntax: Moo"); /* this will be sent to everyone who does /msg hostserv help moo */ + notice(s_HostServ,u->nick,"This command is an example provided"); + notice(s_HostServ,u->nick,"by the Anope development team."); + return MOD_CONT; /* allow any other module's with help for /hs moo to run */ +} + +int myHostServMooRootHelp(User *u) { /* this will only be sent to ROOTS ONLY who /msg hostserv moo */ + myHostServMooAdminHelp(u); /* this line lets us show roots the ADMIN help as well as the root help */ + notice(s_HostServ,u->nick,"Only roots will see this part of the help"); + return MOD_CONT; +} + +int myHostServMooAdminHelp(User *u) { /* this will only be sent to ADMINS ONLY who /msg hostserv moo */ + myHostServMooOperHelp(u); /* this line lets us show admins the OPER help as well as the admin help */ + notice(s_HostServ,u->nick,"Only admins will see this part of the help"); + notice(s_HostServ,u->nick,"why not visit us on www.anope.org ?"); + return MOD_CONT; +} + +int myHostServMooOperHelp(User *u) { /* this will only be sent to OPERS ONLY who /msg hostserv moo */ + notice(s_HostServ,u->nick,"Only opers will see this part of the help"); + notice(s_HostServ,u->nick,"for more help/support with modules"); + notice(s_HostServ,u->nick,"visit us on irc.anope.org #anope! :)"); + return MOD_CONT; +} + +int myHostServMooRegHelp(User *u) { /* this will only be sent to REGULAR USERS ONLY who /msg hostserv moo */ + notice(s_HostServ,u->nick,"Only non-opers will see this part of the help"); + notice(s_HostServ,u->nick,"as we've left it hidden from opers"); + return MOD_CONT; +} + +/* EOF */ diff --git a/src/modules/dummy/Makefile b/src/modules/dummy/Makefile new file mode 100644 index 000000000..ec93af36d --- /dev/null +++ b/src/modules/dummy/Makefile @@ -0,0 +1,6 @@ +all: DUMMY + +DUMMY: +clean: +distclean: +install: diff --git a/src/modules/hs_request.c b/src/modules/hs_request.c new file mode 100644 index 000000000..dde94070c --- /dev/null +++ b/src/modules/hs_request.c @@ -0,0 +1,986 @@ +/* hs_request.c - Add request and activate functionality to HostServ, + * along with adding +req as optional param to HostServ list. + * + * (C) 2003-2008 Anope Team + * Contact us at info@anope.org + * + * Based on the original module by Rob <rob@anope.org> + * Included in the Anope module pack since Anope 1.7.11 + * Anope Coder: GeniusDex <geniusdex@anope.org> + * + * Please read COPYING and README for further details. + * + * Send bug reports to the Anope Coder instead of the module + * author, because any changes since the inclusion into anope + * are not supported by the original author. + */ + +#include "module.h" + +#define AUTHOR "Rob" +#define VERSION "$Id$" + +/* Configuration variables */ +int HSRequestMemoUser = 0; +int HSRequestMemoOper = 0; +int HSRequestMemoSetters = 0; +char *HSRequestDBName = NULL; + +#define HSREQ_DEFAULT_DBNAME "hs_request.db" + +/* Language defines */ +#define LNG_NUM_STRINGS 21 + +#define LNG_REQUEST_SYNTAX 0 +#define LNG_REQUESTED 1 +#define LNG_REQUEST_WAIT 2 +#define LNG_REQUEST_MEMO 3 +#define LNG_ACTIVATE_SYNTAX 4 +#define LNG_ACTIVATED 5 +#define LNG_ACTIVATE_MEMO 6 +#define LNG_REJECT_SYNTAX 7 +#define LNG_REJECTED 8 +#define LNG_REJECT_MEMO 9 +#define LNG_REJECT_MEMO_REASON 10 +#define LNG_NO_REQUEST 11 +#define LNG_HELP 12 +#define LNG_HELP_SETTER 13 +#define LNG_HELP_REQUEST 14 +#define LNG_HELP_ACTIVATE 15 +#define LNG_HELP_ACTIVATE_MEMO 16 +#define LNG_HELP_REJECT 17 +#define LNG_HELP_REJECT_MEMO 18 +#define LNG_WAITING_SYNTAX 19 +#define LNG_HELP_WAITING 20 + +int hs_do_request(User * u); +int hs_do_activate(User * u); +int hs_do_reject(User * u); +int hs_do_list_out(User * u); + +int hs_help_request(User * u); +int hs_help_activate(User * u); +int hs_help_reject(User * u); +int hs_help_waiting(User * u); +void hs_help(User * u); + +void my_add_host_request(char *nick, char *vIdent, char *vhost, + char *creator, int32 tmp_time); +int my_isvalidchar(const char c); +void my_memo_lang(User * u, char *name, int z, int number, ...); +void req_send_memos(User * u, char *vHost); +void show_list(User * u); +int hs_do_waiting(User * u); +int ns_do_drop(User * u); + +void hsreq_save_db(void); +void hsreq_load_db(void); +int hsreqevt_db_saving(int argc, char **argv); +int hsreqevt_db_backup(int argc, char **argv); + +void my_load_config(void); +void my_add_languages(void); + +HostCore *hs_request_head; + +int AnopeInit(int argc, char **argv) +{ + Command *c; + EvtHook *hook; + + c = createCommand("request", hs_do_request, nick_identified, -1, -1, + -1, -1, -1); + moduleAddHelp(c, hs_help_request); + moduleAddCommand(HOSTSERV, c, MOD_HEAD); + + c = createCommand("activate", hs_do_activate, is_host_setter, -1, -1, + -1, -1, -1); + moduleAddHelp(c, hs_help_activate); + moduleAddCommand(HOSTSERV, c, MOD_HEAD); + + c = createCommand("reject", hs_do_reject, is_host_setter, -1, -1, -1, + -1, -1); + moduleAddHelp(c, hs_help_reject); + moduleAddCommand(HOSTSERV, c, MOD_HEAD); + + c = createCommand("waiting", hs_do_waiting, is_host_setter, -1, -1, -1, + -1, -1); + moduleAddHelp(c, hs_help_waiting); + moduleAddCommand(HOSTSERV, c, MOD_HEAD); + + c = createCommand("list", hs_do_list_out, is_services_oper, -1, -1, -1, + -1, -1); + moduleAddCommand(HOSTSERV, c, MOD_HEAD); + + c = createCommand("drop", ns_do_drop, NULL, -1, -1, -1, -1, -1); + moduleAddCommand(NICKSERV, c, MOD_HEAD); + + hook = createEventHook(EVENT_DB_SAVING, hsreqevt_db_saving); + moduleAddEventHook(hook); + + hook = createEventHook(EVENT_DB_BACKUP, hsreqevt_db_backup); + moduleAddEventHook(hook); + + moduleSetHostHelp(hs_help); + moduleAddAuthor(AUTHOR); + moduleAddVersion(VERSION); + moduleSetType(SUPPORTED); + + my_load_config(); + my_add_languages(); + hs_request_head = NULL; + + if (debug) + alog("[hs_request] Loading database..."); + hsreq_load_db(); + alog("hs_request loaded"); + return MOD_CONT; +} + +void AnopeFini(void) +{ + if (debug) + alog("[hs_request] Saving database..."); + hsreq_save_db(); + + /* Clean up all open host requests */ + while (hs_request_head) + hs_request_head = deleteHostCore(hs_request_head, NULL); + + free(HSRequestDBName); + alog("hs_request un-loaded"); +} + +int hs_do_request(User * u) +{ + char *cur_buffer; + char *nick; + char *rawhostmask; + char hostmask[HOSTMAX]; + NickAlias *na; + int32 tmp_time; + char *s; + char *vIdent = NULL; + time_t now = time(NULL); + + cur_buffer = moduleGetLastBuffer(); + nick = u->nick; + rawhostmask = myStrGetToken(cur_buffer, ' ', 0); + + if (!nick || !rawhostmask) { + if (rawhostmask) + free(rawhostmask); + moduleNoticeLang(s_HostServ, u, LNG_REQUEST_SYNTAX); + return MOD_CONT; + } + + vIdent = myStrGetOnlyToken(rawhostmask, '@', 0); /* Get the first substring, @ as delimiter */ + if (vIdent) { + rawhostmask = myStrGetTokenRemainder(rawhostmask, '@', 1); /* get the remaining string */ + if (!rawhostmask) { + moduleNoticeLang(s_HostServ, u, LNG_REQUEST_SYNTAX); + free(vIdent); + return MOD_CONT; + } + if (strlen(vIdent) > USERMAX - 1) { + notice_lang(s_HostServ, u, HOST_SET_IDENTTOOLONG, USERMAX); + free(vIdent); + free(rawhostmask); + return MOD_CONT; + } else { + for (s = vIdent; *s; s++) { + if (!my_isvalidchar(*s)) { + notice_lang(s_HostServ, u, HOST_SET_IDENT_ERROR); + free(vIdent); + free(rawhostmask); + return MOD_CONT; + } + } + } + if (!ircd->vident) { + notice_lang(s_HostServ, u, HOST_NO_VIDENT); + free(vIdent); + free(rawhostmask); + return MOD_CONT; + } + } + if (strlen(rawhostmask) < HOSTMAX - 1) { + snprintf(hostmask, HOSTMAX, "%s", rawhostmask); + } else { + notice_lang(s_HostServ, u, HOST_SET_TOOLONG, HOSTMAX); + if (vIdent) + free(vIdent); + free(rawhostmask); + return MOD_CONT; + } + + if (!isValidHost(hostmask, 3)) { + notice_lang(s_HostServ, u, HOST_SET_ERROR); + if (vIdent) + free(vIdent); + free(rawhostmask); + return MOD_CONT; + } + + tmp_time = time(NULL); + if ((na = findnick(nick))) { + if (HSRequestMemoOper || HSRequestMemoSetters) { + if (MSSendDelay > 0 && u + && u->lastmemosend + MSSendDelay > now) { + moduleNoticeLang(s_HostServ, u, LNG_REQUEST_WAIT, + MSSendDelay); + u->lastmemosend = now; + if (vIdent) + free(vIdent); + free(rawhostmask); + return MOD_CONT; + } + } + my_add_host_request(nick, vIdent, hostmask, u->nick, tmp_time); + + moduleNoticeLang(s_HostServ, u, LNG_REQUESTED); + req_send_memos(u, hostmask); + alog("New vHost Requested by %s", nick); + } else { + notice_lang(s_HostServ, u, HOST_NOREG, nick); + } + + if (vIdent) + free(vIdent); + free(rawhostmask); + + return MOD_CONT; +} + +void my_memo_lang(User * u, char *name, int z, int number, ...) +{ + va_list va; + char buffer[4096], outbuf[4096]; + char *fmt = NULL; + int lang = LANG_EN_US; + char *s, *t, *buf; + User *u2; + + if ((mod_current_module_name) + && (!mod_current_module + || strcmp(mod_current_module_name, mod_current_module->name))) + mod_current_module = findModule(mod_current_module_name); + + u2 = finduser(name); + /* Find the users lang, and use it if we cant */ + if (u2 && u2->na && u2->na->nc) + lang = u2->na->nc->language; + + /* If the users lang isnt supported, drop back to enlgish */ + if (mod_current_module->lang[lang].argc == 0) + lang = LANG_EN_US; + + /* If the requested lang string exists for the language */ + if (mod_current_module->lang[lang].argc > number) { + fmt = mod_current_module->lang[lang].argv[number]; + + buf = sstrdup(fmt); + s = buf; + while (*s) { + t = s; + s += strcspn(s, "\n"); + if (*s) + *s++ = '\0'; + strscpy(outbuf, t, sizeof(outbuf)); + + va_start(va, number); + vsnprintf(buffer, 4095, outbuf, va); + va_end(va); + memo_send(u, name, buffer, z); + } + free(buf); + } else { + alog("%s: INVALID language string call, language: [%d], String [%d]", mod_current_module->name, lang, number); + } +} + + +void req_send_memos(User * u, char *vHost) +{ + int i; + int z = 2; + + if (checkDefCon(DEFCON_NO_NEW_MEMOS)) + return; + + if (HSRequestMemoOper == 1) { + for (i = 0; i < servopers.count; i++) { + my_memo_lang(u, (((NickCore *) servopers.list[i])->display), z, + LNG_REQUEST_MEMO, vHost); + } + for (i = 0; i < servadmins.count; i++) { + my_memo_lang(u, (((NickCore *) servadmins.list[i])->display), + z, LNG_REQUEST_MEMO, vHost); + } + for (i = 0; i < RootNumber; i++) { + my_memo_lang(u, ServicesRoots[i], z, LNG_REQUEST_MEMO, vHost); + } + } + if (HSRequestMemoSetters == 1) { + for (i = 0; i < HostNumber; i++) { + my_memo_lang(u, HostSetters[i], z, LNG_REQUEST_MEMO, vHost); + } + } +} + +int ns_do_drop(User * u) +{ + HostCore *tmp; + boolean found = false; + NickAlias *na; + + na = findnick(u->nick); + tmp = findHostCore(hs_request_head, u->nick, &found); + + if (found && na) + hs_request_head = deleteHostCore(hs_request_head, tmp); + + return MOD_CONT; +} + +int hs_do_reject(User * u) +{ + char *cur_buffer; + char *nick; + char *reason; + HostCore *tmp, *hc; + boolean found = false; + + cur_buffer = moduleGetLastBuffer(); + nick = myStrGetToken(cur_buffer, ' ', 0); + reason = myStrGetTokenRemainder(cur_buffer, ' ', 1); + + if (!nick) { + moduleNoticeLang(s_HostServ, u, LNG_REJECT_SYNTAX); + if (reason) + free(reason); + return MOD_CONT; + } + + tmp = findHostCore(hs_request_head, nick, &found); + if (found) { + if (!tmp) + hc = hs_request_head; + else + hc = tmp->next; + + if (HSRequestMemoUser) { + if (reason) + my_memo_lang(u, hc->nick, 2, LNG_REJECT_MEMO_REASON, + reason); + else + my_memo_lang(u, hc->nick, 2, LNG_REJECT_MEMO); + } + + hs_request_head = deleteHostCore(hs_request_head, tmp); + moduleNoticeLang(s_HostServ, u, LNG_REJECTED, nick); + alog("Host Request for %s rejected by %s (%s)", nick, u->nick, + reason ? reason : ""); + } else { + moduleNoticeLang(s_HostServ, u, LNG_NO_REQUEST, nick); + } + + free(nick); + if (reason) + free(reason); + + return MOD_CONT; +} + +int hs_do_activate(User * u) +{ + char *cur_buffer; + char *nick; + NickAlias *na; + HostCore *tmp, *hc; + boolean found = false; + + cur_buffer = moduleGetLastBuffer(); + nick = myStrGetToken(cur_buffer, ' ', 0); + + if (!nick) { + moduleNoticeLang(s_HostServ, u, LNG_ACTIVATE_SYNTAX); + return MOD_CONT; + } + + if ((na = findnick(nick))) { + tmp = findHostCore(hs_request_head, nick, &found); + if (found) { + if (!tmp) + hc = hs_request_head; + else + hc = tmp->next; + + addHostCore(hc->nick, hc->vIdent, hc->vHost, u->nick, + time(NULL)); + + if (HSRequestMemoUser) + my_memo_lang(u, hc->nick, 2, LNG_ACTIVATE_MEMO); + + hs_request_head = deleteHostCore(hs_request_head, tmp); + moduleNoticeLang(s_HostServ, u, LNG_ACTIVATED, nick); + alog("Host Request for %s activated by %s", nick, u->nick); + } else { + moduleNoticeLang(s_HostServ, u, LNG_NO_REQUEST, nick); + } + } else { + notice_lang(s_HostServ, u, NICK_X_NOT_REGISTERED, nick); + } + + free(nick); + return MOD_CONT; +} + + +void my_add_host_request(char *nick, char *vIdent, char *vhost, + char *creator, int32 tmp_time) +{ + HostCore *tmp; + boolean found = false; + + if (!hs_request_head) { + hs_request_head = + createHostCorelist(hs_request_head, nick, vIdent, vhost, + creator, tmp_time); + } else { + tmp = findHostCore(hs_request_head, nick, &found); + if (!found) { + hs_request_head = + insertHostCore(hs_request_head, tmp, nick, vIdent, vhost, + creator, tmp_time); + } else { + hs_request_head = deleteHostCore(hs_request_head, tmp); /* delete the old entry */ + my_add_host_request(nick, vIdent, vhost, creator, tmp_time); /* recursive call to add new entry */ + } + } +} + +int my_isvalidchar(const char c) +{ + if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) + || ((c >= '0') && (c <= '9')) || (c == '.') || (c == '-')) + return 1; + else + return 0; +} + +int hs_do_list_out(User * u) +{ + char *key; + + key = moduleGetLastBuffer(); + if (!key) + return MOD_CONT; + + if (stricmp(key, "+req") != 0) + return MOD_CONT; + + show_list(u); + + return MOD_CONT; +} + +int hs_do_waiting(User * u) +{ + show_list(u); + + return MOD_CONT; +} + +void show_list(User * u) +{ + struct tm *tm; + char buf[BUFSIZE]; + int counter = 1; + int from = 0, to = 0; + int display_counter = 0; + HostCore *current; + + current = hs_request_head; + while (current) { + if ((((counter >= from) && (counter <= to)) + || ((from == 0) && (to == 0))) + && (display_counter < NSListMax)) { + display_counter++; + tm = localtime(¤t->time); + strftime(buf, sizeof(buf), + getstring(NULL, STRFTIME_DATE_TIME_FORMAT), tm); + if (current->vIdent) + notice_lang(s_HostServ, u, HOST_IDENT_ENTRY, counter, + current->nick, current->vIdent, current->vHost, + current->creator, buf); + else + notice_lang(s_HostServ, u, HOST_ENTRY, counter, + current->nick, current->vHost, + current->creator, buf); + } + counter++; + current = current->next; + } + notice_lang(s_HostServ, u, HOST_LIST_FOOTER, display_counter); +} + +int hs_help_request(User * u) +{ + moduleNoticeLang(s_HostServ, u, LNG_REQUEST_SYNTAX); + notice(s_HostServ, u->nick, " "); + moduleNoticeLang(s_HostServ, u, LNG_HELP_REQUEST); + + return MOD_CONT; +} + +int hs_help_activate(User * u) +{ + if (is_host_setter(u)) { + moduleNoticeLang(s_HostServ, u, LNG_ACTIVATE_SYNTAX); + notice(s_HostServ, u->nick, " "); + moduleNoticeLang(s_HostServ, u, LNG_HELP_ACTIVATE); + if (HSRequestMemoUser) + moduleNoticeLang(s_HostServ, u, LNG_HELP_ACTIVATE_MEMO); + } else { + notice_lang(s_HostServ, u, NO_HELP_AVAILABLE, "ACTIVATE"); + } + + return MOD_CONT; +} + +int hs_help_reject(User * u) +{ + if (is_host_setter(u)) { + moduleNoticeLang(s_HostServ, u, LNG_REJECT_SYNTAX); + notice(s_HostServ, u->nick, " "); + moduleNoticeLang(s_HostServ, u, LNG_HELP_REJECT); + if (HSRequestMemoUser) + moduleNoticeLang(s_HostServ, u, LNG_HELP_REJECT_MEMO); + } else { + notice_lang(s_HostServ, u, NO_HELP_AVAILABLE, "REJECT"); + } + + return MOD_CONT; +} + +int hs_help_waiting(User * u) +{ + if (is_host_setter(u)) { + moduleNoticeLang(s_HostServ, u, LNG_WAITING_SYNTAX); + notice(s_HostServ, u->nick, " "); + moduleNoticeLang(s_HostServ, u, LNG_HELP_WAITING); + } else { + notice_lang(s_HostServ, u, NO_HELP_AVAILABLE, "WAITING"); + } + + return MOD_CONT; +} + +void hs_help(User * u) +{ + moduleNoticeLang(s_HostServ, u, LNG_HELP); + if (is_host_setter(u)) + moduleNoticeLang(s_HostServ, u, LNG_HELP_SETTER); +} +void hsreq_load_db(void) +{ + FILE *fp; + char *filename; + char readbuf[1024]; + char *nick, *vident, *vhost, *creator, *tmp; + int32 tmp_time; + char *buf; + + if (HSRequestDBName) + filename = HSRequestDBName; + else + filename = HSREQ_DEFAULT_DBNAME; + + fp = fopen(filename, "r"); + if (!fp) { + alog("[hs_request] Unable to open database ('%s') for reading", + filename); + return; + } + + while (fgets(readbuf, 1024, fp)) { + buf = normalizeBuffer(readbuf); + if (buf || *buf) { + nick = myStrGetToken(buf, ':', 0); + vident = myStrGetToken(buf, ':', 1); + vhost = myStrGetToken(buf, ':', 2); + tmp = myStrGetToken(buf, ':', 3); + if (tmp) { + tmp_time = strtol(tmp, (char **) NULL, 16); + free(tmp); + } else { + tmp_time = 0; + } + creator = myStrGetToken(buf, ':', 4); + if (!nick || !vident || !vhost || !creator) { + alog("[hs_request] Error while reading database, skipping record"); + continue; + } + if (stricmp(vident, "(null)") == 0) { + free(vident); + vident = NULL; + } + my_add_host_request(nick, vident, vhost, creator, tmp_time); + free(nick); + free(vhost); + free(creator); + if (vident) + free(vident); + } + free(buf); + } + + fclose(fp); + + if (debug) + alog("[hs_request] Succesfully loaded database"); +} + +void hsreq_save_db(void) +{ + FILE *fp; + char *filename; + char *vident; + HostCore *current; + + if (HSRequestDBName) + filename = HSRequestDBName; + else + filename = HSREQ_DEFAULT_DBNAME; + + fp = fopen(filename, "w"); + if (!fp) { + alog("[hs_request] Unable to open database ('%s') for writing", + filename); + return; + } + + current = hs_request_head; + while (current) { + vident = (current->vIdent ? current->vIdent : "(null)"); + fprintf(fp, "%s:%s:%s:%X:%s\n", current->nick, vident, + current->vHost, (uint32) current->time, current->creator); + current = current->next; + } + + fclose(fp); + + if (debug) + alog("[hs_request] Succesfully saved database"); +} + +int hsreqevt_db_saving(int argc, char **argv) +{ + if ((argc >= 1) && (stricmp(argv[0], EVENT_START) == 0)) + hsreq_save_db(); + + return MOD_CONT; +} + +int hsreqevt_db_backup(int argc, char **argv) +{ + if ((argc >= 1) && (stricmp(argv[0], EVENT_START) == 0)) { + if (HSRequestDBName) + ModuleDatabaseBackup(HSRequestDBName); + else + ModuleDatabaseBackup(HSREQ_DEFAULT_DBNAME); + } + + return MOD_CONT; +} + +void my_load_config(void) +{ + int i; + char *tmp = NULL; + + Directive confvalues[][1] = { + {{"HSRequestMemoUser", + {{PARAM_SET, PARAM_RELOAD, &HSRequestMemoUser}}}}, + {{"HSRequestMemoOper", + {{PARAM_SET, PARAM_RELOAD, &HSRequestMemoOper}}}}, + {{"HSRequestMemoSetters", + {{PARAM_SET, PARAM_RELOAD, &HSRequestMemoSetters}}}}, + {{"HSRequestDBName", {{PARAM_STRING, PARAM_RELOAD, &tmp}}}} + }; + + for (i = 0; i < 4; i++) + moduleGetConfigDirective(confvalues[i]); + + if (tmp) { + if (HSRequestDBName) + free(HSRequestDBName); + HSRequestDBName = sstrdup(tmp); + } else { + HSRequestDBName = sstrdup(HSREQ_DEFAULT_DBNAME); + } + + if (debug) + alog("debug: [hs_request] Set config vars: MemoUser=%d MemoOper=%d MemoSetters=%d DBName='%s'", HSRequestMemoUser, HSRequestMemoOper, HSRequestMemoSetters, HSRequestDBName); +} + +void my_add_languages(void) +{ + char *langtable_en_us[] = { + /* LNG_REQUEST_SYNTAX */ + "Syntax: \002REQUEST \037vhost\037\002", + /* LNG_REQUESTED */ + "Your vHost has been requested", + /* LNG_REQUEST_WAIT */ + "Please wait %d seconds before requesting a new vHost", + /* LNG_REQUEST_MEMO */ + "[auto memo] vHost \002%s\002 has been requested.", + /* LNG_ACTIVATE_SYNTAX */ + "Syntax: \002ACTIVATE \037nick\037\002", + /* LNG_ACTIVATED */ + "vHost for %s has been activated", + /* LNG_ACTIVATE_MEMO */ + "[auto memo] Your requested vHost has been approved.", + /* LNG_REJECT_SYNTAX */ + "Syntax: \002REJECT \037nick\037\002", + /* LNG_REJECTED */ + "vHost for %s has been rejected", + /* LNG_REJECT_MEMO */ + "[auto memo] Your requested vHost has been rejected.", + /* LNG_REJECT_MEMO_REASON */ + "[auto memo] Your requested vHost has been rejected. Reason: %s", + /* LNG_NO_REQUEST */ + "No request for nick %s found.", + /* LNG_HELP */ + " REQUEST Request a vHost for your nick", + /* LNG_HELP_SETTER */ + " ACTIVATE Approve the requested vHost of a user\n" + " REJECT Reject the requested vHost of a user\n" + " WAITING Convenience command for LIST +req", + /* LNG_HELP_REQUEST */ + "Request the given vHost to be actived for your nick by the\n" + "network administrators. Please be patient while your request\n" + "is being considered.", + /* LNG_HELP_ACTIVATE */ + "Activate the requested vHost for the given nick.", + /* LNG_HELP_ACTIVATE_MEMO */ + "A memo informing the user will also be sent.", + /* LNG_HELP_REJECT */ + "Reject the requested vHost for the given nick.", + /* LNG_HELP_REJECT_MEMO */ + "A memo informing the user will also be sent.", + /* LNG_WAITING_SYNTAX */ + "Syntax: \002WAITING\002", + /* LNG_HELP_WAITING */ + "This command is provided for convenience. It is essentially\n" + "the same as performing a LIST +req ." + }; + + char *langtable_nl[] = { + /* LNG_REQUEST_SYNTAX */ + "Gebruik: \002REQUEST \037vhost\037\002", + /* LNG_REQUESTED */ + "Je vHost is aangevraagd", + /* LNG_REQUEST_WAIT */ + "Wacht %d seconden voor je een nieuwe vHost aanvraagt", + /* LNG_REQUEST_MEMO */ + "[auto memo] vHost \002%s\002 is aangevraagd.", + /* LNG_ACTIVATE_SYNTAX */ + "Gebruik: \002ACTIVATE \037nick\037\002", + /* LNG_ACTIVATED */ + "vHost voor %s is geactiveerd", + /* LNG_ACTIVATE_MEMO */ + "[auto memo] Je aangevraagde vHost is geaccepteerd.", + /* LNG_REJECT_SYNTAX */ + "Gebruik: \002REJECT \037nick\037\002", + /* LNG_REJECTED */ + "vHost voor %s is afgekeurd", + /* LNG_REJECT_MEMO */ + "[auto memo] Je aangevraagde vHost is afgekeurd.", + /* LNG_REJECT_MEMO_REASON */ + "[auto memo] Je aangevraagde vHost is afgekeurd. Reden: %s", + /* LNG_NO_REQUEST */ + "Geen aanvraag voor nick %s gevonden.", + /* LNG_HELP */ + " REQUEST Vraag een vHost aan voor je nick", + /* LNG_HELP_SETTER */ + " ACTIVATE Activeer de aangevraagde vHost voor een gebruiker\n" + " REJECT Keur de aangevraagde vHost voor een gebruiker af\n" + " WAITING Snelkoppeling naar LIST +req", + /* LNG_HELP_REQUEST */ + "Verzoek de gegeven vHost te activeren voor jouw nick bij de\n" + "netwerk beheerders. Het kan even duren voordat je aanvraag\n" + "afgehandeld wordt.", + /* LNG_HELP_ACTIVATE */ + "Activeer de aangevraagde vHost voor de gegeven nick.", + /* LNG_HELP_ACTIVATE_MEMO */ + "Een memo die de gebruiker op de hoogste stelt zal ook worden verstuurd.", + /* LNG_HELP_REJECT */ + "Keur de aangevraagde vHost voor de gegeven nick af.", + /* LNG_HELP_REJECT_MEMO */ + "Een memo die de gebruiker op de hoogste stelt zal ook worden verstuurd.", + /* LNG_WAITING_SYNTAX */ + "Gebruik: \002WAITING\002", + /* LNG_HELP_WAITING */ + "Dit commando is beschikbaar als handigheid. Het is simpelweg\n" + "hetzelfde als LIST +req ." + }; + + char *langtable_pt[] = { + /* LNG_REQUEST_SYNTAX */ + "Sintaxe: \002REQUEST \037vhost\037\002", + /* LNG_REQUESTED */ + "Seu pedido de vHost foi encaminhado", + /* LNG_REQUEST_WAIT */ + "Por favor, espere %d segundos antes de fazer um novo pedido de vHost", + /* LNG_REQUEST_MEMO */ + "[Auto Memo] O vHost \002%s\002 foi solicitado.", + /* LNG_ACTIVATE_SYNTAX */ + "Sintaxe: \002ACTIVATE \037nick\037\002", + /* LNG_ACTIVATED */ + "O vHost para %s foi ativado", + /* LNG_ACTIVATE_MEMO */ + "[Auto Memo] Seu pedido de vHost foi aprovado.", + /* LNG_REJECT_SYNTAX */ + "Sintaxe: \002REJECT \037nick\037\002", + /* LNG_REJECTED */ + "O vHost de %s foi recusado", + /* LNG_REJECT_MEMO */ + "[Auto Memo] Seu pedido de vHost foi recusado.", + /* LNG_REJECT_MEMO_REASON */ + "[Auto Memo] Seu pedido de vHost foi recusado. Motivo: %s", + /* LNG_NO_REQUEST */ + "Nenhum pedido encontrado para o nick %s.", + /* LNG_HELP */ + " REQUEST Request a vHost for your nick", + /* LNG_HELP_SETTER */ + " ACTIVATE Aprova o pedido de vHost de um usuбrio\n" + " REJECT Recusa o pedido de vHost de um usuбrio\n" + " WAITING Comando para LISTAR +req", + /* LNG_HELP_REQUEST */ + "Solicita a ativaзгo do vHost fornecido em seu nick pelos\n" + "administradores da rede. Por favor, tenha paciкncia\n" + "enquanto seu pedido й analisado.", + /* LNG_HELP_ACTIVATE */ + "Ativa o vHost solicitado para o nick fornecido.", + /* LNG_HELP_ACTIVATE_MEMO */ + "Um memo informando o usuбrio tambйm serб enviado.", + /* LNG_HELP_REJECT */ + "Recusa o pedido de vHost para o nick fornecido.", + /* LNG_HELP_REJECT_MEMO */ + "Um memo informando o usuбrio tambйm serб enviado.", + /* LNG_WAITING_SYNTAX */ + "Sintaxe: \002WAITING\002", + /* LNG_HELP_WAITING */ + "Este comando й usado por conveniкncia. Й essencialmente\n" + "o mesmo que fazer um LIST +req" + }; + + char *langtable_ru[] = { + /* LNG_REQUEST_SYNTAX */ + "Синтаксис: \002REQUEST \037vHost\037\002", + /* LNG_REQUESTED */ + "Ваш запрос на vHost отправлен.", + /* LNG_REQUEST_WAIT */ + "Пожалуйста, подождите %d секунд, прежде чем запрашивать новый vHost", + /* LNG_REQUEST_MEMO */ + "[авто-сообщение] Был запрошен vHost \002%s\002", + /* LNG_ACTIVATE_SYNTAX */ + "Синтаксис: \002ACTIVATE \037ник\037\002", + /* LNG_ACTIVATED */ + "vHost для %s успешно активирован", + /* LNG_ACTIVATE_MEMO */ + "[авто-сообщение] Запрашиваемый вами vHost утвержден и активирован.", + /* LNG_REJECT_SYNTAX */ + "Синтаксис: \002REJECT \037ник\037\002", + /* LNG_REJECTED */ + "vHost для %s отклонен.", + /* LNG_REJECT_MEMO */ + "[авто-сообщение] Запрашиваемый вами vHost отклонен.", + /* LNG_REJECT_MEMO_REASON */ + "[авто-сообщение] Запрашиваемый вами vHost отклонен. Причина: %s", + /* LNG_NO_REQUEST */ + "Запрос на vHost для ника %s не найден.", + /* LNG_HELP */ + " REQUEST Запрос на vHost для вашего текущего ника", + /* LNG_HELP_SETTER */ + " ACTIVATE Утвердить запрашиваемый пользователем vHost\n" + " REJECT Отклонить запрашиваемый пользователем vHost\n" + " WAITING Список запросов ожидающих обработки (аналог LIST +req)", + /* LNG_HELP_REQUEST */ + "Отправляет запрос на активацию vHost, который будет рассмотрен одним из\n" + "администраторов сети. Просьба проявить терпение, пока запрос\n" + "рассматривается администрацией.", + /* LNG_HELP_ACTIVATE */ + "Утвердить запрашиваемый vHost для указанного ника.", + /* LNG_HELP_ACTIVATE_MEMO */ + "Пользователю будет послано авто-уведомление об активации его запроса.", + /* LNG_HELP_REJECT */ + "Отклонить запрашиваемый vHost для указанного ника.", + /* LNG_HELP_REJECT_MEMO */ + "Пользователю будет послано авто-уведомление об отклонении его запроса.", + /* LNG_WAITING_SYNTAX */ + "Синтаксис: \002WAITING\002", + /* LNG_HELP_WAITING */ + "Данная команда создана для удобства использования и выводит список запросов,\n" + "ожидающих обработки. Аналогичная команда: LIST +req ." + }; + + char *langtable_it[] = { + /* LNG_REQUEST_SYNTAX */ + "Sintassi: \002REQUEST \037vhost\037\002", + /* LNG_REQUESTED */ + "Il tuo vHost и stato richiesto", + /* LNG_REQUEST_WAIT */ + "Prego attendere %d secondi prima di richiedere un nuovo vHost", + /* LNG_REQUEST_MEMO */ + "[auto memo] и stato richiesto il vHost \002%s\002.", + /* LNG_ACTIVATE_SYNTAX */ + "Sintassi: \002ACTIVATE \037nick\037\002", + /* LNG_ACTIVATED */ + "Il vHost per %s и stato attivato", + /* LNG_ACTIVATE_MEMO */ + "[auto memo] Il vHost da te richiesto и stato approvato.", + /* LNG_REJECT_SYNTAX */ + "Sintassi: \002REJECT \037nick\037\002", + /* LNG_REJECTED */ + "Il vHost per %s и stato rifiutato", + /* LNG_REJECT_MEMO */ + "[auto memo] Il vHost da te richiesto и stato rifiutato.", + /* LNG_REJECT_MEMO_REASON */ + "[auto memo] Il vHost da te richiesto и stato rifiutato. Motivo: %s", + /* LNG_NO_REQUEST */ + "Nessuna richiesta trovata per il nick %s.", + /* LNG_HELP */ + " REQUEST Richiede un vHost per il tuo nick", + /* LNG_HELP_SETTER */ + " ACTIVATE Approva il vHost richiesto di un utente\n" + " REJECT Rifiuta il vHost richiesto di un utente\n" + " WAITING Comando per LIST +req", + /* LNG_HELP_REQUEST */ + "Richiede l'attivazione del vHost specificato per il tuo nick da parte\n" + "degli amministratori di rete. Sei pregato di pazientare finchи la tua\n" + "richiesta viene elaborata.", + /* LNG_HELP_ACTIVATE */ + "Attiva il vHost richiesto per il nick specificato.", + /* LNG_HELP_ACTIVATE_MEMO */ + "Viene inviato un memo per informare l'utente.", + /* LNG_HELP_REJECT */ + "Rifiuta il vHost richiesto per il nick specificato.", + /* LNG_HELP_REJECT_MEMO */ + "Viene inviato un memo per informare l'utente.", + /* LNG_WAITING_SYNTAX */ + "Sintassi: \002WAITING\002", + /* LNG_HELP_WAITING */ + "Questo comando и per comoditа. Praticamente и la stessa cosa che\n" + "eseguire un LIST +req ." + }; + moduleInsertLanguage(LANG_EN_US, LNG_NUM_STRINGS, langtable_en_us); + moduleInsertLanguage(LANG_NL, LNG_NUM_STRINGS, langtable_nl); + moduleInsertLanguage(LANG_PT, LNG_NUM_STRINGS, langtable_pt); + moduleInsertLanguage(LANG_RU, LNG_NUM_STRINGS, langtable_ru); + moduleInsertLanguage(LANG_IT, LNG_NUM_STRINGS, langtable_it); +} + +/* EOF */ diff --git a/src/modules/makefile.inc.win32 b/src/modules/makefile.inc.win32 new file mode 100644 index 000000000..f6a646329 --- /dev/null +++ b/src/modules/makefile.inc.win32 @@ -0,0 +1,2 @@ +SRCS=cs_appendtopic.c cs_enforce.c cs_tban.c ns_maxemail.c hs_request.c os_info.c bs_fantasy_unban.c +SUBS=test diff --git a/src/modules/makefile.sub.win32 b/src/modules/makefile.sub.win32 new file mode 100644 index 000000000..4a811622e --- /dev/null +++ b/src/modules/makefile.sub.win32 @@ -0,0 +1,19 @@ +include ../../../Makefile.inc.win32 + +OBJECTS= $(SRCS:.c=.obj) +CFLAGS=/nologo /LD /MD /D MODULE_COMPILE $(CFLAGS) /I"../../../include" /I "../" +LFLAGS=/nologo ../../anope.lib wsock32.lib $(LIBS) $(LFLAGS) $(MYSQL_LIB_PATH) /export:AnopeInit /export:AnopeFini /OUT:$(TARGET) + +all: + $(CC) $(SRCS) $(CFLAGS) ..\..\mod_version.c /link $(LFLAGS) + +distclean: clean spotless + +clean: + -@del *.obj + +spotless: clean + -@del *.dll *.lib *.exp *.manifest + +install: + -@copy *.dll ..\..\..\$(DATDEST)\modules diff --git a/src/modules/makefile.win32 b/src/modules/makefile.win32 new file mode 100644 index 000000000..038ff25ba --- /dev/null +++ b/src/modules/makefile.win32 @@ -0,0 +1,41 @@ +include ../../Makefile.inc.win32 +include ./Makefile.inc.win32 + +OBJECTS= $(SRCS:.c=.dll) +CFLAGS=/LD /MD /D MODULE_COMPILE $(CFLAGS) /I"../../include" +LFLAGS=/link ../anope.lib wsock32.lib $(LIBS) $(LFLAGS) $(MYSQL_LIB_PATH) /export:AnopeInit /export:AnopeFini + +all: $(OBJECTS) subs + +distclean: clean spotless + +.c.dll: + $(CC) $(CFLAGS) $(IRCTYPE) $< ..\mod_version.c $(LFLAGS) + +subs: + @for %i in ( $(SUBS) ); do \ + @if exist %i; @cd %i && $(MAKE) $(MAKEARGS) && cd .. + +clean: subs-clean + -@del *.obj + +subs-clean: + @for %i in ( $(SUBS) ); do \ + @if exist %i; @cd %i && $(MAKE) $(MAKEARGS) clean && cd .. + +spotless: clean subs-spotless + -@del *.dll *.lib *.exp *.manifest + +subs-spotless: + @for %i in ( $(SUBS) ); do \ + @if exist %i; @cd %i && $(MAKE) $(MAKEARGS) spotless && cd .. + +install: + -@mkdir ..\..\$(DATDEST)\modules + -@mkdir ..\..\$(DATDEST)\modules\runtime + -@copy *.dll ..\..\$(DATDEST)\modules + +subs-install: install + @for %i in ( $(SUBS) ); do \ + @if exist %i; @cd %i && $(MAKE) $(MAKEARGS) install && cd .. + diff --git a/src/modules/ns_maxemail.c b/src/modules/ns_maxemail.c new file mode 100644 index 000000000..04747ff5a --- /dev/null +++ b/src/modules/ns_maxemail.c @@ -0,0 +1,228 @@ +/* ns_maxemail.c - Limit the amount of times an email address + * can be used for a NickServ account. + * + * (C) 2003-2008 Anope Team + * Contact us at info@anope.org + * + * Included in the Anope module pack since Anope 1.7.9 + * Anope Coder: GeniusDex <geniusdex@anope.org> + * + * Please read COPYING and README for further details. + * + * Send any bug reports to the Anope Coder, as he will be able + * to deal with it best. + */ + +#include "module.h" + +#define AUTHOR "Anope" +#define VERSION "$Id$" + +void my_load_config(void); +void my_add_languages(void); +int my_ns_register(User * u); +int my_ns_set(User * u); +int my_event_reload(int argc, char **argv); + +int NSEmailMax = 0; + +#define LNG_NUM_STRINGS 2 +#define LNG_NSEMAILMAX_REACHED 0 +#define LNG_NSEMAILMAX_REACHED_ONE 1 + +int AnopeInit(int argc, char **argv) +{ + Command *c; + EvtHook *evt; + int status; + + moduleAddAuthor(AUTHOR); + moduleAddVersion(VERSION); + moduleSetType(SUPPORTED); + + c = createCommand("REGISTER", my_ns_register, NULL, -1, -1, -1, -1, + -1); + if ((status = moduleAddCommand(NICKSERV, c, MOD_HEAD))) { + alog("[ns_maxemail] Unable to create REGISTER command: %d", + status); + return MOD_STOP; + } + + c = createCommand("SET", my_ns_set, NULL, -1, -1, -1, -1, -1); + if ((status = moduleAddCommand(NICKSERV, c, MOD_HEAD))) { + alog("[ns_maxemail] Unable to create SET command: %d", status); + return MOD_STOP; + } + + evt = createEventHook(EVENT_RELOAD, my_event_reload); + if ((status = moduleAddEventHook(evt))) { + alog("[ns_maxemail] Unable to hook to EVENT_RELOAD: %d", status); + return MOD_STOP; + } + + my_load_config(); + my_add_languages(); + + return MOD_CONT; +} + +void AnopeFini(void) +{ + /* Nothing to do while unloading */ +} + +int count_email_in_use(char *email, User * u) +{ + NickCore *nc; + int i; + int count = 0; + + if (!email) + return 0; + + for (i = 0; i < 1024; i++) { + for (nc = nclists[i]; nc; nc = nc->next) { + if (!(u->na && u->na->nc && (u->na->nc == nc)) && nc->email && (stricmp(nc->email, email) == 0)) + count++; + } + } + + return count; +} + +int check_email_limit_reached(char *email, User * u) +{ + if ((NSEmailMax < 1) || !email || is_services_admin(u)) + return MOD_CONT; + + if (count_email_in_use(email, u) < NSEmailMax) + return MOD_CONT; + + if (NSEmailMax == 1) + moduleNoticeLang(s_NickServ, u, LNG_NSEMAILMAX_REACHED_ONE); + else + moduleNoticeLang(s_NickServ, u, LNG_NSEMAILMAX_REACHED, + NSEmailMax); + + return MOD_STOP; +} + +int my_ns_register(User * u) +{ + char *cur_buffer; + char *email; + int ret; + + cur_buffer = moduleGetLastBuffer(); + email = myStrGetToken(cur_buffer, ' ', 1); + if (!email) + return MOD_CONT; + + ret = check_email_limit_reached(email, u); + free(email); + + return ret; +} + +int my_ns_set(User * u) +{ + char *cur_buffer; + char *set; + char *email; + int ret; + + cur_buffer = moduleGetLastBuffer(); + set = myStrGetToken(cur_buffer, ' ', 0); + + if (!set) + return MOD_CONT; + + if (stricmp(set, "email") != 0) { + free(set); + return MOD_CONT; + } + + free(set); + email = myStrGetToken(cur_buffer, ' ', 1); + if (!email) + return MOD_CONT; + + ret = check_email_limit_reached(email, u); + free(email); + + return ret; +} + +int my_event_reload(int argc, char **argv) +{ + if ((argc > 0) && (stricmp(argv[0], EVENT_START) == 0)) + my_load_config(); + + return MOD_CONT; +} + +void my_load_config(void) +{ + Directive confvalues[] = { + {"NSEmailMax", {{PARAM_INT, PARAM_RELOAD, &NSEmailMax}}} + }; + + moduleGetConfigDirective(confvalues); + + if (debug) + alog("debug: [ns_maxemail] NSEmailMax set to %d", NSEmailMax); +} + +void my_add_languages(void) +{ + char *langtable_en_us[] = { + /* LNG_NSEMAILMAX_REACHED */ + "The given email address has reached it's usage limit of %d users.", + /* LNG_NSEMAILMAX_REACHED_ONE */ + "The given email address has reached it's usage limit of 1 user." + }; + + char *langtable_nl[] = { + /* LNG_NSEMAILMAX_REACHED */ + "Het gegeven email adres heeft de limiet van %d gebruikers bereikt.", + /* LNG_NSEMAILMAX_REACHED_ONE */ + "Het gegeven email adres heeft de limiet van 1 gebruiker bereikt." + }; + + char *langtable_de[] = { + /* LNG_NSEMAILMAX_REACHED */ + "Die angegebene eMail hat die limit Begrenzung von %d User erreicht.", + /* LNG_NSEMAILMAX_REACHED_ONE */ + "Die angegebene eMail hat die limit Begrenzung von 1 User erreicht." + }; + + char *langtable_pt[] = { + /* LNG_NSEMAILMAX_REACHED */ + "O endereзo de email fornecido alcanзou seu limite de uso de %d usuбrios.", + /* LNG_NSEMAILMAX_REACHED_ONE */ + "O endereзo de email fornecido alcanзou seu limite de uso de 1 usuбrio." + }; + + char *langtable_ru[] = { + /* LNG_NSEMAILMAX_REACHED */ + "Указанный вами email-адрес используется максимально допустимое кол-во раз: %d", + /* LNG_NSEMAILMAX_REACHED_ONE */ + "Указанный вами email-адрес уже кем-то используется." + }; + + char *langtable_it[] = { + /* LNG_NSEMAILMAX_REACHED */ + "L'indirizzo email specificato ha raggiunto il suo limite d'utilizzo di %d utenti.", + /* LNG_NSEMAILMAX_REACHED_ONE */ + "L'indirizzo email specificato ha raggiunto il suo limite d'utilizzo di 1 utente." + }; + + moduleInsertLanguage(LANG_EN_US, LNG_NUM_STRINGS, langtable_en_us); + moduleInsertLanguage(LANG_NL, LNG_NUM_STRINGS, langtable_nl); + moduleInsertLanguage(LANG_DE, LNG_NUM_STRINGS, langtable_de); + moduleInsertLanguage(LANG_PT, LNG_NUM_STRINGS, langtable_pt); + moduleInsertLanguage(LANG_RU, LNG_NUM_STRINGS, langtable_ru); + moduleInsertLanguage(LANG_IT, LNG_NUM_STRINGS, langtable_it); +} + +/* EOF */ diff --git a/src/modules/ns_noop_convert.c b/src/modules/ns_noop_convert.c new file mode 100644 index 000000000..2858bef1e --- /dev/null +++ b/src/modules/ns_noop_convert.c @@ -0,0 +1,173 @@ +/* ns_noop.c - Allows users to optionaly set autoop to off + * + * (C) 2003-2008 Anope Team + * Contact us at info@anope.org + * + * Based on the original module by Rob <rob@anope.org> + * Included in the Anope module pack since Anope 1.7.9 + * Anope Coder: DrStein <drstein@anope.org> + * + * Please read COPYING and README for further details. + * + * Send bug reports to the Anope Coder instead of the module + * author, because any changes since the inclusion into anope + * are not supported by the original author. + * + */ +/*************************************************************************/ + +#include "module.h" + +#define AUTHOR "Rob" +#define VERSION "$Id$" + +/* The name of the default database to save info to */ +#define DEFAULT_DB_NAME "autoop.db" + +/* Multi-language stuff */ +#define LANG_NUM_STRINGS 8 + +#define AUTOOP_SYNTAX 0 +#define AUTOOP_STATUS_ON 1 +#define AUTOOP_STATUS_OFF 2 +#define AUTOOP_NO_NICK 3 +#define AUTOOP_ON 4 +#define AUTOOP_OFF 5 +#define AUTOOP_DESC 6 +#define AUTOOP_HELP 7 + +/*************************************************************************/ + +User *currentUser; +int m_isIRCop = 0; + +char *NSAutoOPDBName; + +int myNickServAutoOpHelp(User * u); +void myNickServHelp(User * u); + +int noop(User * u); +int mEventJoin(int argc, char **argv); +int setAutoOp(User * u); +int UnsetAutoOp(User * u); + +int mLoadData(void); +int mSaveData(int argc, char **argv); +int mLoadConfig(int argc, char **argv); + +void m_AddLanguages(void); + +/*************************************************************************/ + +/** + * AnopeInit is called when the module is loaded + * @param argc Argument count + * @param argv Argument list + * @return MOD_CONT to allow the module, MOD_STOP to stop it + **/ +int AnopeInit(int argc, char **argv) +{ + NSAutoOPDBName = NULL; + + moduleAddAuthor(AUTHOR); + moduleAddVersion(VERSION); + moduleSetType(SUPPORTED); + + if (mLoadConfig(0, NULL)) + return MOD_STOP; + + mLoadData(); + + alog("ns_noop_convert: Your auto-op database has been converted and this module will now"); + alog("ns_noop_convert: unload itself. You can now remove this module from your config"); + + return MOD_STOP; +} + +/** + * Unload the module + **/ +void AnopeFini(void) +{ + if (NSAutoOPDBName) + free(NSAutoOPDBName); +} + +/*************************************************************************/ + +/** + * Load data from the db file, and populate the autoop setting + * @return 0 for success + **/ +int mLoadData(void) +{ + int ret = 0; + int len = 0; + + char *name = NULL; + + NickAlias *na = NULL; + FILE *in; + + /* will _never_ be this big thanks to the 512 limit of a message */ + char buffer[2000]; + if ((in = fopen(NSAutoOPDBName, "r")) == NULL) { + alog("ns_noop: WARNING: Can not open database file! (it might not exist, this is not fatal)"); + ret = 1; + } else { + while (fgets(buffer, 1500, in)) { + name = myStrGetToken(buffer, ' ', 0); + if (name) { + len = strlen(name); + /* Take the \n from the end of the line */ + name[len - 1] = '\0'; + if ((na = findnick(name))) { + na->nc->flags |= NI_AUTOOP; + } + free(name); + } + } + } + return ret; +} + +/*************************************************************************/ + +/** + * Load the configuration directives from Services configuration file. + * @return 0 for success + **/ +int mLoadConfig(int argc, char **argv) +{ + char *tmp = NULL; + + Directive d[] = { + {"NSAutoOPDBName", {{PARAM_STRING, PARAM_RELOAD, &tmp}}}, + }; + + moduleGetConfigDirective(d); + + if (NSAutoOPDBName) + free(NSAutoOPDBName); + + if (tmp) { + NSAutoOPDBName = tmp; + } else { + NSAutoOPDBName = sstrdup(DEFAULT_DB_NAME); + alog("ns_noop: NSAutoOPDBName is not defined in Services configuration file, using default %s", NSAutoOPDBName); + } + + if (!NSAutoOPDBName) { + alog("ns_noop: FATAL: Can't read required configuration directives!"); + return MOD_STOP; + } else { + alog("ns_noop: Directive NSAutoOPDBName loaded (%s)...", + NSAutoOPDBName); + } + + return MOD_CONT; +} + +/*************************************************************************/ + +/* EOF */ diff --git a/src/modules/os_ignore_db.c b/src/modules/os_ignore_db.c new file mode 100644 index 000000000..474959068 --- /dev/null +++ b/src/modules/os_ignore_db.c @@ -0,0 +1,545 @@ +/* os_ignore_db.c - Provides a database backend for OS IGNORE.
+ *
+ * (C) 2003-2008 Anope Team
+ * Contact us at info@anope.org
+ *
+ * Included in the Anope module pack since Anope 1.7.23
+ * Anope Coder: Viper <viper@anope.org>
+ *
+ * Please read COPYING and README for further details.
+ *
+ */
+/* ------------------------------------------------------------------------------- */
+
+#include "module.h"
+
+#define AUTHOR "Viper"
+#define VERSION "$Id$"
+
+/* Default database name */
+#define DefIgnoreDB "os_ignore.db"
+#define IGNOREDBVERSION 1
+
+/* Database seperators */
+#define SEPARATOR '^' /* End of a key, seperates keys from values */
+#define BLOCKEND '\n' /* End of a block, e.g. a whole ignore */
+#define VALUEEND '\000' /* End of a value */
+#define SUBSTART '\010' /* Beginning of a new subblock, closed by a BLOCKEND */
+
+/* Database reading return values */
+#define DB_READ_SUCCESS 0
+#define DB_READ_ERROR 1
+#define DB_EOF_ERROR 2
+#define DB_VERSION_ERROR 3
+#define DB_READ_BLOCKEND 4
+#define DB_READ_SUBSTART 5
+
+#define DB_WRITE_SUCCESS 0
+#define DB_WRITE_ERROR 1
+#define DB_WRITE_NOVAL 2
+
+/* Database Key, Value max length */
+#define MAXKEYLEN 128
+#define MAXVALLEN 1024
+
+/* Structs */
+typedef struct db_file_ DBFile;
+
+struct db_file_ {
+ FILE *fptr; /* Pointer to the opened file */
+ int db_version; /* The db version of the datafiles (only needed for reading) */
+ int core_db_version; /* The current db version of this anope source */
+ char service[256]; /* StatServ/etc. */
+ char filename[256]; /* Filename of the database */
+ char temp_name[262]; /* Temp filename of the database */
+};
+
+
+/* Variables */
+char *IgnoreDB;
+
+/* Functions */
+int new_open_db_read(DBFile *dbptr, char **key, char **value);
+int new_open_db_write(DBFile *dbptr);
+void new_close_db(FILE *fptr, char **key, char **value);
+int new_read_db_entry(char **key, char **value, FILE * fptr);
+int new_write_db_entry(const char *key, DBFile *dbptr, const char *fmt, ...);
+int new_write_db_endofblock(DBFile *dbptr);
+void fill_db_ptr(DBFile *dbptr, int version, int core_version, char service[256], char filename[256]);
+
+int save_ignoredb(int argc, char **argv);
+int backup_ignoredb(int argc, char **argv);
+void load_ignore_db(void);
+void save_ignore_db(void);
+void load_config(void);
+int reload_config(int argc, char **argv);
+
+/* ------------------------------------------------------------------------------- */
+
+/**
+ * AnopeInit is called when the module is loaded
+ * @param argc Argument count
+ * @param argv Argument list
+ * @return MOD_CONT to allow the module, MOD_STOP to stop it
+ **/
+int AnopeInit(int argc, char **argv) {
+ EvtHook *hook;
+ IgnoreDB = NULL;
+
+ moduleAddAuthor(AUTHOR);
+ moduleAddVersion(VERSION);
+ moduleSetType(SUPPORTED);
+
+ hook = createEventHook(EVENT_RELOAD, reload_config);
+ if (moduleAddEventHook(hook) != MOD_ERR_OK) {
+ alog("[\002os_ignore_db\002] Can't hook to EVENT_RELOAD event");
+ return MOD_STOP;
+ }
+
+ hook = createEventHook(EVENT_DB_SAVING, save_ignoredb);
+ if (moduleAddEventHook(hook) != MOD_ERR_OK) {
+ alog("[\002os_ignore_db\002] Can't hook to EVENT_DB_SAVING event");
+ return MOD_STOP;
+ }
+
+ hook = createEventHook(EVENT_DB_BACKUP, backup_ignoredb);
+ if (moduleAddEventHook(hook) != MOD_ERR_OK) {
+ alog("[\002os_ignore_db\002] Can't hook to EVENT_DB_BACKUP event");
+ return MOD_STOP;
+ }
+
+ load_config();
+ /* Load the ignore database and re-add them to anopes ignorelist. */
+ load_ignore_db();
+
+ return MOD_CONT;
+}
+
+/**
+ * Unload the module
+ **/
+void AnopeFini(void) {
+ /* Save the ignore database before bailing out.. */
+ save_ignore_db();
+
+ if (IgnoreDB)
+ free(IgnoreDB);
+}
+
+/* ------------------------------------------------------------------------------- */
+
+void load_config(void) {
+ int i;
+
+ Directive confvalues[][1] = {
+ {{"OSIgnoreDBName", {{PARAM_STRING, PARAM_RELOAD, &IgnoreDB}}}},
+ };
+
+ if (IgnoreDB)
+ free(IgnoreDB);
+ IgnoreDB = NULL;
+
+ for (i = 0; i < 1; i++)
+ moduleGetConfigDirective(confvalues[i]);
+
+ if (!IgnoreDB)
+ IgnoreDB = sstrdup(DefIgnoreDB);
+
+ if (debug)
+ alog("[os_ignore_db] debug: Set config vars: OSIgnoreDBName='%s'", IgnoreDB);
+}
+
+/**
+ * Upon /os reload call the routines for reloading the configuration directives
+ **/
+int reload_config(int argc, char **argv) {
+ if (argc >= 1) {
+ if (!stricmp(argv[0], EVENT_START)) {
+ load_config();
+ }
+ }
+ return MOD_CONT;
+}
+
+/**
+ * When anope saves her databases, we do the same.
+ **/
+int save_ignoredb(int argc, char **argv) {
+ if ((argc >= 1) && (!stricmp(argv[0], EVENT_STOP)))
+ save_ignore_db();
+
+ return MOD_CONT;
+}
+
+
+/**
+ * When anope backs her databases up, we do the same.
+ **/
+int backup_ignoredb(int argc, char **argv) {
+ if ((argc >= 1) && (!stricmp(argv[0], EVENT_STOP))) {
+ if (debug)
+ alog("[os_ignore_db] debug: Backing up %s database...", IgnoreDB);
+ ModuleDatabaseBackup(IgnoreDB);
+ }
+ return MOD_CONT;
+}
+
+/* ------------------------------------------------------------------------------- */
+
+/**************************************************************************
+ * DataBase Handling
+ **************************************************************************/
+
+void load_ignore_db(void) {
+ DBFile *dbptr = scalloc(1, sizeof(DBFile));
+ char *key, *value, *mask = NULL;
+ int retval = 0;
+ time_t expiry_time;
+ IgnoreData *ign;
+
+ expiry_time = time(NULL);
+ fill_db_ptr(dbptr, 0, IGNOREDBVERSION, s_OperServ, IgnoreDB);
+
+ /* let's remove existing temp files here, because we only load dbs on startup */
+ remove(dbptr->temp_name);
+
+ /* Open the db, fill the rest of dbptr and allocate memory for key and value */
+ if (new_open_db_read(dbptr, &key, &value)) {
+ free(dbptr);
+ return; /* Bang, an error occurred */
+ }
+
+ while (1) {
+ /* read a new entry and fill key and value with it -Certus */
+ retval = new_read_db_entry(&key, &value, dbptr->fptr);
+
+ if (retval == DB_READ_ERROR) {
+ new_close_db(dbptr->fptr, &key, &value);
+ free(dbptr);
+ return;
+
+ } else if (retval == DB_EOF_ERROR) {
+ new_close_db(dbptr->fptr, &key, &value);
+ free(dbptr);
+ return;
+ } else if (retval == DB_READ_BLOCKEND) { /* DB_READ_BLOCKEND */
+ /* Check if we have everything to add the ignore..
+ * We shouldn't bother with already expired ignores either.. */
+ if (mask && (expiry_time > time(NULL) || expiry_time == 0)) {
+ /* We should check for double entries.. */
+ for (ign = ignore; ign; ign = ign->next)
+ if (!stricmp(ign->mask, mask))
+ break;
+
+ if (!ign) {
+ /* Create a fresh entry.. */
+ ign = scalloc(sizeof(*ign), 1);
+ ign->mask = sstrdup(mask);
+ ign->time = expiry_time;
+ ign->prev = NULL;
+ ign->next = ignore;
+ if (ignore)
+ ignore->prev = ign;
+ ignore = ign;
+ if (debug)
+ alog("[os_ignore_db] debug: Added new ignore entry for %s", mask);
+ } else {
+ /* Update time on existing entry.
+ * The longest expiry time survives.. */
+ if (expiry_time == 0 || ign->time == 0)
+ ign->time = 0;
+ else if (expiry_time > ign->time)
+ ign->time = expiry_time;
+ }
+ }
+
+ if (mask) free(mask);
+ mask = NULL;
+ expiry_time = time(NULL);
+ } else { /* DB_READ_SUCCESS */
+ if (!*key || !*value)
+ continue;
+
+ /* mask */
+ if (!stricmp(key, "m")) {
+ if (mask)
+ free(mask);
+ mask = sstrdup(value);
+
+ /* expiry time */
+ } else if (!stricmp(key, "t")) {
+ expiry_time = atoi(value);
+
+ } else if (!stricmp(key, "IGNORE_DB_VERSION")) {
+ if ((int)atoi(value) != IGNOREDBVERSION) {
+ alog("[\002os_ignore_db\002] Database version does not match any database versions supported by this module.");
+ alog("[\002os_ignore_db\002] Continuing with clean database...");
+ break;
+ }
+ }
+ } /* else */
+ } /* while */
+
+ free(dbptr);
+}
+
+
+void save_ignore_db(void) {
+ DBFile *dbptr = scalloc(1, sizeof(DBFile));
+ time_t now;
+ IgnoreData *ign, *next;
+
+ now = time(NULL);
+ fill_db_ptr(dbptr, 0, IGNOREDBVERSION, s_OperServ, IgnoreDB);
+
+ /* time to backup the old db */
+ rename(IgnoreDB, dbptr->temp_name);
+
+ if (new_open_db_write(dbptr)) {
+ rename(dbptr->temp_name, IgnoreDB);
+ free(dbptr);
+ return; /* Bang, an error occurred */
+ }
+
+ /* Store the version of the DB in the DB as well...
+ * This will make stuff a lot easier if the database scheme needs to modified. */
+ new_write_db_entry("IGNORE_DB_VERSION", dbptr, "%d", IGNOREDBVERSION);
+ new_write_db_endofblock(dbptr);
+
+ /* Go over the entire ignorelist, check whether each entry is still valid
+ * and write it to the database if it is.*/
+ for (ign = ignore; ign; ign = next) {
+ next = ign->next;
+
+ if (ign->time != 0 && ign->time <= now) {
+ if (debug)
+ alog("[os_ignore_db] debug: Expiring ignore entry %s", ign->mask);
+ if (ign->prev)
+ ign->prev->next = ign->next;
+ else if (ignore == ign)
+ ignore = ign->next;
+ if (ign->next)
+ ign->next->prev = ign->prev;
+ free(ign->mask);
+ free(ign);
+ ign = NULL;
+ } else {
+ new_write_db_entry("m", dbptr, "%s", ign->mask);
+ new_write_db_entry("t", dbptr, "%d", ign->time);
+ new_write_db_endofblock(dbptr);
+ }
+ }
+
+ if (dbptr) {
+ new_close_db(dbptr->fptr, NULL, NULL); /* close file */
+ remove(dbptr->temp_name); /* saved successfully, no need to keep the old one */
+ free(dbptr); /* free the db struct */
+ }
+}
+
+
+/* ------------------------------------------------------------------------------- */
+
+/**************************************************************************
+ * Generic DataBase Functions (Borrowed this from Trystan :-) )
+ **************************************************************************/
+
+
+int new_open_db_read(DBFile *dbptr, char **key, char **value) {
+ *key = malloc(MAXKEYLEN);
+ *value = malloc(MAXVALLEN);
+
+ if (!(dbptr->fptr = fopen(dbptr->filename, "rb"))) {
+ if (debug) {
+ alog("debug: Can't read %s database %s : errno(%d)", dbptr->service,
+ dbptr->filename, errno);
+ }
+ free(*key);
+ *key = NULL;
+ free(*value);
+ *value = NULL;
+ return DB_READ_ERROR;
+ }
+ dbptr->db_version = fgetc(dbptr->fptr) << 24 | fgetc(dbptr->fptr) << 16
+ | fgetc(dbptr->fptr) << 8 | fgetc(dbptr->fptr);
+
+ if (ferror(dbptr->fptr)) {
+ if (debug) {
+ alog("debug: Error reading version number on %s", dbptr->filename);
+ }
+ free(*key);
+ *key = NULL;
+ free(*value);
+ *value = NULL;
+ return DB_READ_ERROR;
+ } else if (feof(dbptr->fptr)) {
+ if (debug) {
+ alog("debug: Error reading version number on %s: End of file detected",
+ dbptr->filename);
+ }
+ free(*key);
+ *key = NULL;
+ free(*value);
+ *value = NULL;
+ return DB_EOF_ERROR;
+ } else if (dbptr->db_version < 1) {
+ if (debug) {
+ alog("debug: Invalid version number (%d) on %s", dbptr->db_version, dbptr->filename);
+ }
+ free(*key);
+ *key = NULL;
+ free(*value);
+ *value = NULL;
+ return DB_VERSION_ERROR;
+ }
+ return DB_READ_SUCCESS;
+}
+
+
+int new_open_db_write(DBFile *dbptr) {
+ if (!(dbptr->fptr = fopen(dbptr->filename, "wb"))) {
+ if (debug) {
+ alog("debug: %s Can't open %s database for writing", dbptr->service, dbptr->filename);
+ }
+ return DB_WRITE_ERROR;
+ }
+
+ if (fputc(dbptr->core_db_version >> 24 & 0xFF, dbptr->fptr) < 0 ||
+ fputc(dbptr->core_db_version >> 16 & 0xFF, dbptr->fptr) < 0 ||
+ fputc(dbptr->core_db_version >> 8 & 0xFF, dbptr->fptr) < 0 ||
+ fputc(dbptr->core_db_version & 0xFF, dbptr->fptr) < 0) {
+ if (debug) {
+ alog("debug: Error writing version number on %s", dbptr->filename);
+ }
+ return DB_WRITE_ERROR;
+ }
+ return DB_WRITE_SUCCESS;
+}
+
+
+void new_close_db(FILE *fptr, char **key, char **value) {
+ if (key && *key) {
+ free(*key);
+ *key = NULL;
+ }
+ if (value && *value) {
+ free(*value);
+ *value = NULL;
+ }
+
+ if (fptr) {
+ fclose(fptr);
+ }
+}
+
+
+int new_read_db_entry(char **key, char **value, FILE *fptr) {
+ char *string = *key;
+ int character;
+ int i = 0;
+
+ **key = '\0';
+ **value = '\0';
+
+ while (1) {
+ if ((character = fgetc(fptr)) == EOF) { /* a problem occurred reading the file */
+ if (ferror(fptr)) {
+ return DB_READ_ERROR; /* error! */
+ }
+ return DB_EOF_ERROR; /* end of file */
+ } else if (character == BLOCKEND) { /* END OF BLOCK */
+ return DB_READ_BLOCKEND;
+ } else if (character == VALUEEND) { /* END OF VALUE */
+ string[i] = '\0'; /* end of value */
+ return DB_READ_SUCCESS;
+ } else if (character == SEPARATOR) { /* END OF KEY */
+ string[i] = '\0'; /* end of key */
+ string = *value; /* beginning of value */
+ i = 0; /* start with the first character of our value */
+ } else {
+ if ((i == (MAXKEYLEN - 1)) && (string == *key)) { /* max key length reached, continuing with value */
+ string[i] = '\0'; /* end of key */
+ string = *value; /* beginning of value */
+ i = 0; /* start with the first character of our value */
+ } else if ((i == (MAXVALLEN - 1)) && (string == *value)) { /* max value length reached, returning */
+ string[i] = '\0';
+ return DB_READ_SUCCESS;
+ } else {
+ string[i] = character; /* read string (key or value) */
+ i++;
+ }
+ }
+ }
+}
+
+
+int new_write_db_entry(const char *key, DBFile *dbptr, const char *fmt, ...) {
+ char string[MAXKEYLEN + MAXVALLEN + 2], value[MAXVALLEN]; /* safety byte :P */
+ va_list ap;
+ unsigned int length;
+
+ if (!dbptr) {
+ return DB_WRITE_ERROR;
+ }
+
+ va_start(ap, fmt);
+ vsnprintf(value, MAXVALLEN, fmt, ap);
+ va_end(ap);
+
+ if (!stricmp(value, "(null)")) {
+ return DB_WRITE_NOVAL;
+ }
+ snprintf(string, MAXKEYLEN + MAXVALLEN + 1, "%s%c%s", key, SEPARATOR, value);
+ length = strlen(string);
+ string[length] = VALUEEND;
+ length++;
+
+ if (fwrite(string, 1, length, dbptr->fptr) < length) {
+ if (debug) {
+ alog("debug: Error writing to %s", dbptr->filename);
+ }
+ new_close_db(dbptr->fptr, NULL, NULL);
+ if (debug) {
+ alog("debug: Restoring backup.");
+ }
+ remove(dbptr->filename);
+ rename(dbptr->temp_name, dbptr->filename);
+ free(dbptr);
+ dbptr = NULL;
+ return DB_WRITE_ERROR;
+ }
+ return DB_WRITE_SUCCESS;
+}
+
+
+int new_write_db_endofblock(DBFile *dbptr) {
+ if (!dbptr) {
+ return DB_WRITE_ERROR;
+ }
+ if (fputc(BLOCKEND, dbptr->fptr) == EOF) {
+ if (debug) {
+ alog("debug: Error writing to %s", dbptr->filename);
+ }
+ new_close_db(dbptr->fptr, NULL, NULL);
+ return DB_WRITE_ERROR;
+ }
+ return DB_WRITE_SUCCESS;
+}
+
+
+
+void fill_db_ptr(DBFile *dbptr, int version, int core_version,
+ char service[256], char filename[256]) {
+ dbptr->db_version = version;
+ dbptr->core_db_version = core_version;
+ if (!service)
+ strcpy(dbptr->service, service);
+ else
+ strcpy(dbptr->service, "");
+
+ strcpy(dbptr->filename, filename);
+ snprintf(dbptr->temp_name, 261, "%s.temp", filename);
+ return;
+}
+
+/* EOF */
diff --git a/src/modules/os_info.c b/src/modules/os_info.c new file mode 100644 index 000000000..0343f957e --- /dev/null +++ b/src/modules/os_info.c @@ -0,0 +1,780 @@ +/* os_info.c - Adds oper information lines to nicks/channels + * + * (C) 2003-2008 Anope Team + * Contact us at info@anope.org + * + * Based on the original module by Rob <rob@anope.org> + * Included in the Anope module pack since Anope 1.7.9 + * Anope Coder: DrStein <drstein@anope.org> + * + * Please read COPYING and README for further details. + * + * Send bug reports to the Anope Coder instead of the module + * author, because any changes since the inclusion into anope + * are not supported by the original author. + * + */ +/*************************************************************************/ + +#include "module.h" + +#define AUTHOR "Rob" +#define VERSION "$Id$" + +/* Default database name */ +#define DEFAULT_DB_NAME "os_info.db" + +/* Multi-language stuff */ +#define LANG_NUM_STRINGS 10 + +#define OINFO_SYNTAX 0 +#define OINFO_ADD_SUCCESS 1 +#define OINFO_DEL_SUCCESS 2 +#define OCINFO_SYNTAX 3 +#define OCINFO_ADD_SUCCESS 4 +#define OCINFO_DEL_SUCCESS 5 +#define OINFO_HELP 6 +#define OCINFO_HELP 7 +#define OINFO_HELP_CMD 8 +#define OCINFO_HELP_CMD 9 + +/*************************************************************************/ + +char *OSInfoDBName = NULL; + +int myAddNickInfo(User * u); +int myAddChanInfo(User * u); +int myNickInfo(User * u); +int myChanInfo(User * u); + +int mNickHelp(User * u); +int mChanHelp(User * u); +void mMainChanHelp(User * u); +void mMainNickHelp(User * u); +void m_AddLanguages(void); + +int mLoadData(void); +int mSaveData(int argc, char **argv); +int mBackupData(int argc, char **argv); +int mLoadConfig(); +int mEventReload(int argc, char **argv); + +/*************************************************************************/ + +/** + * AnopeInit is called when the module is loaded + * @param argc Argument count + * @param argv Argument list + * @return MOD_CONT to allow the module, MOD_STOP to stop it + **/ +int AnopeInit(int argc, char **argv) +{ + Command *c; + EvtHook *hook = NULL; + + int status; + + moduleAddAuthor(AUTHOR); + moduleAddVersion(VERSION); + moduleSetType(SUPPORTED); + + alog("os_info: Loading configuration directives..."); + if (mLoadConfig()) { + return MOD_STOP; + } + + c = createCommand("oInfo", myAddNickInfo, is_oper, -1, -1, -1, -1, -1); + moduleAddHelp(c, mNickHelp); + status = moduleAddCommand(NICKSERV, c, MOD_HEAD); + + c = createCommand("Info", myNickInfo, NULL, -1, -1, -1, -1, -1); + status = moduleAddCommand(NICKSERV, c, MOD_TAIL); + + c = createCommand("oInfo", myAddChanInfo, is_oper, -1, -1, -1, -1, -1); + moduleAddHelp(c, mChanHelp); + status = moduleAddCommand(CHANSERV, c, MOD_HEAD); + + c = createCommand("Info", myChanInfo, NULL, -1, -1, -1, -1, -1); + status = moduleAddCommand(CHANSERV, c, MOD_TAIL); + + hook = createEventHook(EVENT_DB_SAVING, mSaveData); + status = moduleAddEventHook(hook); + + hook = createEventHook(EVENT_DB_BACKUP, mBackupData); + status = moduleAddEventHook(hook); + + hook = createEventHook(EVENT_RELOAD, mEventReload); + status = moduleAddEventHook(hook); + + moduleSetNickHelp(mMainNickHelp); + moduleSetChanHelp(mMainChanHelp); + + mLoadData(); + m_AddLanguages(); + + return MOD_CONT; +} + +/** + * Unload the module + **/ +void AnopeFini(void) +{ + char *av[1]; + + av[0] = sstrdup(EVENT_START); + mSaveData(1, av); + free(av[0]); + + if (OSInfoDBName) + free(OSInfoDBName); +} + +/*************************************************************************/ + +/** + * Provide the user interface to add/remove/update oper information + * about a nick. + * We are going to assume that anyone who gets this far is an oper; + * the createCommand should have handled this checking for us and its + * tedious / a waste to do it twice. + * @param u The user who executed this command + * @return MOD_CONT if we want to process other commands in this command + * stack, MOD_STOP if we dont + **/ +int myAddNickInfo(User * u) +{ + char *text = NULL; + char *cmd = NULL; + char *nick = NULL; + char *info = NULL; + NickAlias *na = NULL; + + /* Get the last buffer anope recived */ + text = moduleGetLastBuffer(); + if (text) { + cmd = myStrGetToken(text, ' ', 0); + nick = myStrGetToken(text, ' ', 1); + info = myStrGetTokenRemainder(text, ' ', 2); + if (cmd && nick) { + if (strcasecmp(cmd, "ADD") == 0) { + /* Syntax error, again! */ + if (info) { + /* ok we've found the user */ + if ((na = findnick(nick))) { + /* Add the module data to the user */ + moduleAddData(&na->nc->moduleData, "info", info); + moduleNoticeLang(s_NickServ, u, + OINFO_ADD_SUCCESS, nick); + /* NickCore not found! */ + } else { + notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, + nick); + } + free(info); + } + } else if (strcasecmp(cmd, "DEL") == 0) { + /* ok we've found the user */ + if ((na = findnick(nick))) { + moduleDelData(&na->nc->moduleData, "info"); + moduleNoticeLang(s_NickServ, u, + OINFO_DEL_SUCCESS, nick); + /* NickCore not found! */ + } else { + notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, + nick); + } + /* another syntax error! */ + } else { + moduleNoticeLang(s_NickServ, u, OINFO_SYNTAX); + } + free(cmd); + free(nick); + /* Syntax error */ + } else if (cmd) { + moduleNoticeLang(s_NickServ, u, OINFO_SYNTAX); + free(cmd); + /* Syntax error */ + } else { + moduleNoticeLang(s_NickServ, u, OINFO_SYNTAX); + } + } + return MOD_CONT; +} + +/** + * Provide the user interface to add/remove/update oper information + * about a channel. + * We are going to assume that anyone who gets this far is an oper; + * the createCommand should have handled this checking for us and + * its tedious / a waste to do it twice. + * @param u The user who executed this command + * @return MOD_CONT if we want to process other commands in this command + * stack, MOD_STOP if we dont + **/ +int myAddChanInfo(User * u) +{ + char *text = NULL; + char *cmd = NULL; + char *chan = NULL; + char *info = NULL; + ChannelInfo *ci = NULL; + + /* Get the last buffer anope recived */ + text = moduleGetLastBuffer(); + if (text) { + cmd = myStrGetToken(text, ' ', 0); + chan = myStrGetToken(text, ' ', 1); + info = myStrGetTokenRemainder(text, ' ', 2); + if (cmd && chan) { + if (strcasecmp(cmd, "ADD") == 0) { + if (info) { + if ((ci = cs_findchan(chan))) { + /* Add the module data to the channel */ + moduleAddData(&ci->moduleData, "info", info); + moduleNoticeLang(s_ChanServ, u, + OCINFO_ADD_SUCCESS, chan); + /* ChanInfo */ + } else { + notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, + chan); + } + free(info); + } + } else if (strcasecmp(cmd, "DEL") == 0) { + if ((ci = cs_findchan(chan))) { + /* Del the module data from the channel */ + moduleDelData(&ci->moduleData, "info"); + moduleNoticeLang(s_ChanServ, u, + OCINFO_DEL_SUCCESS, chan); + /* ChanInfo */ + } else { + notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, + chan); + } + /* another syntax error! */ + } else { + moduleNoticeLang(s_ChanServ, u, OCINFO_SYNTAX); + } + free(cmd); + free(chan); + /* Syntax error */ + } else if (cmd) { + moduleNoticeLang(s_ChanServ, u, OCINFO_SYNTAX); + free(cmd); + /* Syntax error */ + } else { + moduleNoticeLang(s_ChanServ, u, OCINFO_SYNTAX); + } + } + return MOD_CONT; +} + +/*************************************************************************/ + +/** + * Called after a user does a /msg nickserv info [nick] + * @param u The user who requested info + * @return MOD_CONT to continue processing commands or MOD_STOP to stop + **/ +int myNickInfo(User * u) +{ + char *text = NULL; + char *nick = NULL; + char *info = NULL; + NickAlias *na = NULL; + + /* Only show our goodies to opers */ + if (is_oper(u)) { + /* Get the last buffer anope recived */ + text = moduleGetLastBuffer(); + if (text) { + nick = myStrGetToken(text, ' ', 0); + if (nick) { + /* ok we've found the user */ + if ((na = findnick(nick))) { + /* If we have any info on this user */ + if ((info = moduleGetData(&na->nc->moduleData, "info"))) { + notice_user(s_NickServ, u, " OperInfo: %s", info); + free(info); + } + /* NickCore not found! */ + } else { + /* we dont care! */ + } + free(nick); + } + } + } + return MOD_CONT; +} + +/** + * Called after a user does a /msg chanserv info chan + * @param u The user who requested info + * @return MOD_CONT to continue processing commands or MOD_STOP to stop + **/ +int myChanInfo(User * u) +{ + char *text = NULL; + char *chan = NULL; + char *info = NULL; + ChannelInfo *ci = NULL; + + /* Only show our goodies to opers */ + if (is_oper(u)) { + /* Get the last buffer anope recived */ + text = moduleGetLastBuffer(); + if (text) { + chan = myStrGetToken(text, ' ', 0); + if (chan) { + if ((ci = cs_findchan(chan))) { + /* If we have any info on this channel */ + if ((info = moduleGetData(&ci->moduleData, "info"))) { + notice_user(s_ChanServ, u, " OperInfo: %s", info); + free(info); + } + } + free(chan); + } + } + } + return MOD_CONT; +} + +/*************************************************************************/ + +/** + * Load data from the db file, and populate our OperInfo lines + * @return 0 for success + **/ +int mLoadData(void) +{ + int ret = 0; + FILE *in; + + char *type = NULL; + char *name = NULL; + char *info = NULL; + int len = 0; + + ChannelInfo *ci = NULL; + NickAlias *na = NULL; + + /* will _never_ be this big thanks to the 512 limit of a message */ + char buffer[2000]; + if ((in = fopen(OSInfoDBName, "r")) == NULL) { + alog("os_info: WARNING: can not open the database file! (it might not exist, this is not fatal)"); + ret = 1; + } else { + while (fgets(buffer, 1500, in)) { + type = myStrGetToken(buffer, ' ', 0); + name = myStrGetToken(buffer, ' ', 1); + info = myStrGetTokenRemainder(buffer, ' ', 2); + if (type) { + if (name) { + if (info) { + len = strlen(info); + /* Take the \n from the end of the line */ + info[len - 1] = '\0'; + if (stricmp(type, "C") == 0) { + if ((ci = cs_findchan(name))) { + moduleAddData(&ci->moduleData, "info", + info); + } + } else if (stricmp(type, "N") == 0) { + if ((na = findnick(name))) { + moduleAddData(&na->nc->moduleData, "info", + info); + } + } + free(info); + } + free(name); + } + free(type); + } + } + } + return ret; +} + +/** + * Save all our data to our db file + * First walk through the nick CORE list, and any nick core which has + * oper info attached to it, write to the file. + * Next do the same again for ChannelInfos + * @return 0 for success + **/ +int mSaveData(int argc, char **argv) +{ + ChannelInfo *ci = NULL; + NickCore *nc = NULL; + int i = 0; + int ret = 0; + FILE *out; + char *info = NULL; + + if (argc >= 1) { + if (!stricmp(argv[0], EVENT_START)) { + if ((out = fopen(OSInfoDBName, "w")) == NULL) { + alog("os_info: ERROR: can not open the database file!"); + anope_cmd_global(s_OperServ, + "os_info: ERROR: can not open the database file!"); + ret = 1; + } else { + for (i = 0; i < 1024; i++) { + for (nc = nclists[i]; nc; nc = nc->next) { + /* If we have any info on this user */ + if ((info = moduleGetData(&nc->moduleData, "info"))) { + fprintf(out, "N %s %s\n", nc->display, info); + free(info); + } + } + } + + + for (i = 0; i < 256; i++) { + for (ci = chanlists[i]; ci; ci = ci->next) { + /* If we have any info on this channel */ + if ((info = moduleGetData(&ci->moduleData, "info"))) { + fprintf(out, "C %s %s\n", ci->name, info); + free(info); + } + } + } + fclose(out); + } + } else { + ret = 0; + } + } + + return ret; +} + +/** + * Backup our databases using the commands provided by Anope + * @return MOD_CONT + **/ +int mBackupData(int argc, char **argv) +{ + ModuleDatabaseBackup(OSInfoDBName); + + return MOD_CONT; +} + +/** + * Load the configuration directives from Services configuration file. + * @return 0 for success + **/ +int mLoadConfig(void) +{ + char *tmp = NULL; + + Directive directivas[] = { + {"OSInfoDBName", {{PARAM_STRING, PARAM_RELOAD, &tmp}}}, + }; + + Directive *d = &directivas[0]; + moduleGetConfigDirective(d); + + if (OSInfoDBName) + free(OSInfoDBName); + + if (tmp) { + OSInfoDBName = tmp; + } else { + OSInfoDBName = sstrdup(DEFAULT_DB_NAME); + alog("os_info: OSInfoDBName is not defined in Services configuration file, using default %s", OSInfoDBName); + } + + alog("os_info: Directive OSInfoDBName loaded (%s)...", OSInfoDBName); + + return 0; +} + +/** + * Manage the RELOAD EVENT + * @return MOD_CONT + **/ +int mEventReload(int argc, char **argv) +{ + int ret = 0; + if (argc >= 1) { + if (!stricmp(argv[0], EVENT_START)) { + alog("os_info: Reloading configuration directives..."); + ret = mLoadConfig(); + } else { + /* Nothing for now */ + } + } + + if (ret) + alog("os_info.c: ERROR: An error has occured while reloading the configuration file"); + + return MOD_CONT; +} + +/*************************************************************************/ + +/** + * manages the multilanguage stuff + **/ +void m_AddLanguages(void) +{ + char *langtable_en_us[] = { + /* OINFO_SYNTAX */ + "Syntax: OINFO [ADD|DEL] nick <info>", + /* OINFO_ADD_SUCCESS */ + "OperInfo line has been added to nick %s", + /* OINFO_DEL_SUCCESS */ + "OperInfo line has been removed from nick %s", + /* OCINFO_SYNTAX */ + "Syntax: OINFO [ADD|DEL] chan <info>", + /* OCINFO_ADD_SUCCESS */ + "OperInfo line has been added to channel %s", + /* OCINFO_DEL_SUCCESS */ + "OperInfo line has been removed from channel %s", + /* OINFO_HELP */ + "Syntax: OINFO [ADD|DEL] nick <info>\n" + "Add or Delete Oper information for the given nick\n" + "This will show up when any oper /ns info nick's the user.\n" + "and can be used for 'tagging' users etc....", + /* OCINFO_HELP */ + "Syntax: OINFO [ADD|DEL] chan <info>\n" + "Add or Delete Oper information for the given channel\n" + "This will show up when any oper /cs info's the channel.\n" + "and can be used for 'tagging' channels etc....", + /* OINFO_HELP_CMD */ + " OINFO Add / Del an OperInfo line to a nick", + /* OCINFO_HELP_CMD */ + " OINFO Add / Del an OperInfo line to a channel" + }; + + char *langtable_es[] = { + /* OINFO_SYNTAX */ + "Sintaxis: OINFO [ADD|DEL] nick <info>", + /* OINFO_ADD_SUCCESS */ + "Una linea OperInfo ha sido agregada al nick %s", + /* OINFO_DEL_SUCCESS */ + "La linea OperInfo ha sido removida del nick %s", + /* OCINFO_SYNTAX */ + "Sintaxis: OINFO [ADD|DEL] chan <info>", + /* OCINFO_ADD_SUCCESS */ + "Linea OperInfo ha sido agregada al canal %s", + /* OCINFO_DEL_SUCCESS */ + "La linea OperInfo ha sido removida del canal %s", + /* OINFO_HELP */ + "Sintaxis: OINFO [ADD|DEL] nick <info>\n" + "Agrega o elimina informacion para Operadores al nick dado\n" + "Esto se mostrara cuando cualquier operador haga /ns info nick\n" + "y puede ser usado para 'marcado' de usuarios, etc....", + /* OCINFO_HELP */ + "Sintaxis: OINFO [ADD|DEL] chan <info>\n" + "Agrega o elimina informacion para Operadores al canal dado\n" + "Esto se mostrara cuando cualquier operador haga /cs info canal\n" + "y puede ser usado para 'marcado' de canales, etc....", + /* OINFO_HELP_CMD */ + " OINFO Agrega / Elimina una linea OperInfo al nick", + /* OCINFO_HELP_CMD */ + " OINFO Agrega / Elimina una linea OperInfo al canal" + }; + + char *langtable_nl[] = { + /* OINFO_SYNTAX */ + "Gebruik: OINFO [ADD|DEL] nick <info>", + /* OINFO_ADD_SUCCESS */ + "OperInfo regel is toegevoegd aan nick %s", + /* OINFO_DEL_SUCCESS */ + "OperInfo regel is weggehaald van nick %s", + /* OCINFO_SYNTAX */ + "Gebruik: OINFO [ADD|DEL] kanaal <info>", + /* OCINFO_ADD_SUCCESS */ + "OperInfo regel is toegevoegd aan kanaal %s", + /* OCINFO_DEL_SUCCESS */ + "OperInfo regel is weggehaald van kanaal %s", + /* OINFO_HELP */ + "Gebruik: OINFO [ADD|DEL] nick <info>\n" + "Voeg een Oper informatie regel toe aan de gegeven nick, of\n" + "verwijder deze. Deze regel zal worden weergegeven wanneer\n" + "een oper /ns info nick doet voor deze gebruiker, en kan worden\n" + "gebruikt om een gebruiker te 'markeren' etc...", + /* OCINFO_HELP */ + "Gebruik: OINFO [ADD|DEL] kanaal <info>\n" + "Voeg een Oper informatie regel toe aan de gegeven kanaal, of\n" + "verwijder deze. Deze regel zal worden weergegeven wanneer\n" + "een oper /cs info kanaal doet voor dit kanaal, en kan worden\n" + "gebruikt om een kanaal te 'markeren' etc...", + /* OINFO_HELP_CMD */ + " OINFO Voeg een OperInfo regel toe aan een nick of verwijder deze", + /* OCINFO_HELP_CMD */ + " OINFO Voeg een OperInfo regel toe aan een kanaal of verwijder deze" + }; + + char *langtable_de[] = { + /* OINFO_SYNTAX */ + "Syntax: OINFO [ADD|DEL] Nickname <Information>", + /* OINFO_ADD_SUCCESS */ + "Eine OperInfo Linie wurde zu den Nicknamen %s hinzugefьgt", + /* OINFO_DEL_SUCCESS */ + "Die OperInfo Linie wurde von den Nicknamen %s enfernt", + /* OCINFO_SYNTAX */ + "Syntax: OINFO [ADD|DEL] Channel <Information>", + /* OCINFO_ADD_SUCCESS */ + "Eine OperInfo Linie wurde zu den Channel %s hinzugefьgt", + /* OCINFO_DEL_SUCCESS */ + "Die OperInfo Linie wurde von den Channel %s enfernt", + /* OINFO_HELP */ + "Syntax: OINFO [ADD|DEL] Nickname <Information>\n" + "Addiert oder lцscht eine OperInfo Linie zu den angegebenen\n" + "Nicknamen.Sie wird angezeigt wenn ein Oper mit /ns info sich\n" + "ьber den Nicknamen informiert.", + /* OCINFO_HELP */ + "Syntax: OINFO [ADD|DEL] chan <info>\n" + "Addiert oder lцscht eine OperInfo Linie zu den angegebenen\n" + "Channel.Sie wird angezeigt wenn ein Oper mit /cs info sich\n" + "ьber den Channel informiert.", + /* OINFO_HELP_CMD */ + " OINFO Addiert / Lцscht eine OperInfo Linie zu / von einen Nicknamen", + /* OCINFO_HELP_CMD */ + " OINFO Addiert / Lцscht eine OperInfo Linie zu / von einen Channel" + }; + + char *langtable_pt[] = { + /* OINFO_SYNTAX */ + "Sintaxe: OINFO [ADD|DEL] nick <informaзгo>", + /* OINFO_ADD_SUCCESS */ + "A linha OperInfo foi adicionada ao nick %s", + /* OINFO_DEL_SUCCESS */ + "A linha OperInfo foi removida do nick %s", + /* OCINFO_SYNTAX */ + "Sintaxe: OINFO [ADD|DEL] canal <informaзгo>", + /* OCINFO_ADD_SUCCESS */ + "A linha OperInfo foi adicionada ao canal %s", + /* OCINFO_DEL_SUCCESS */ + "A linha OperInfo foi removida do canal %s", + /* OINFO_HELP */ + "Sintaxe: OINFO [ADD|DEL] nick <informaзгo>\n" + "Adiciona ou apaga informaзгo para Operadores ao nick fornecido\n" + "Isto serб mostrado quando qualquer Operador usar /ns info nick\n" + "e pode ser usado para 'etiquetar' usuбrios etc...", + /* OCINFO_HELP */ + "Sintaxe: OINFO [ADD|DEL] canal <informaзгo>\n" + "Adiciona ou apaga informaзгo para Operadores ao canal fornecido\n" + "Isto serб mostrado quando qualquer Operador usar /cs info canal\n" + "e pode ser usado para 'etiquetar' canais etc...", + /* OINFO_HELP_CMD */ + " OINFO Adiciona ou Apaga a linha OperInfo para um nick", + /* OCINFO_HELP_CMD */ + " OINFO Adiciona ou Apaga a linha OperInfo para um canal" + }; + + char *langtable_ru[] = { + /* OINFO_SYNTAX */ + "Синтаксис: OINFO ADD|DEL ник тест", + /* OINFO_ADD_SUCCESS */ + "Опер-Информация для ника %s добавлена", + /* OINFO_DEL_SUCCESS */ + "Опер-Информация для ника %s была удалена", + /* OCINFO_SYNTAX */ + "Синтаксис: OINFO ADD|DEL #канал текст", + /* OCINFO_ADD_SUCCESS */ + "Опер-Информация для канала %s успешно установлена", + /* OCINFO_DEL_SUCCESS */ + "Опер-Информация для канала %s была удалена", + /* OINFO_HELP */ + "Синтаксис: OINFO ADD|DEL ник текст\n" + "Устанавливает или удаляет Опер-Информацию для указанного ника,\n" + "которая будет показана любому оператору, запрашивающему INFO ника.\n" + "Может быть использована для 'пометки' пользователей и т. д...", + /* OCINFO_HELP */ + "Синтаксис: OINFO ADD|DEL #канал текст\n" + "Устанавливает или удаляет Опер-Информацию для указанного канала,\n" + "которая будет показана любому оператору, запрашивающему INFO канала.\n" + "Может быть использована для 'пометки' каналов и т. д...", + /* OINFO_HELP_CMD */ + " OINFO Добавляет/Удаляет опер-инфо для ника", + /* OCINFO_HELP_CMD */ + " OINFO Добавляет/Удаляет опер-инфо для канала" + }; + + char *langtable_it[] = { + /* OINFO_SYNTAX */ + "Sintassi: OINFO [ADD|DEL] nick <info>", + /* OINFO_ADD_SUCCESS */ + "Linea OperInfo aggiunta al nick %s", + /* OINFO_DEL_SUCCESS */ + "Linea OperInfo rimossa dal nick %s", + /* OCINFO_SYNTAX */ + "Sintassi: OINFO [ADD|DEL] chan <info>", + /* OCINFO_ADD_SUCCESS */ + "Linea OperInfo aggiunta al canale %s", + /* OCINFO_DEL_SUCCESS */ + "Linea OperInfo rimossa dal canale %s", + /* OINFO_HELP */ + "Sintassi: OINFO [ADD|DEL] nick <info>\n" + "Aggiunge o rimuove informazioni Oper per il nick specificato\n" + "Queste vengono mostrate quando un oper esegue il comando /ns info <nick>\n" + "e possono essere utilizzate per 'marchiare' gli utenti ecc...", + /* OCINFO_HELP */ + "Sintassi: OINFO [ADD|DEL] chan <info>\n" + "Aggiunge o rimuove informazioni Oper per il canale specificato\n" + "Queste vengono mostrate quando un oper esegue il comando /cs info <canale>\n" + "e possono essere utilizzate per 'marchiare' i canali ecc...", + /* OINFO_HELP_CMD */ + " OINFO Aggiunge/Rimuove una linea OperInfo ad/da un nick", + /* OCINFO_HELP_CMD */ + " OINFO Aggiunge/Rimuove una linea OperInfo ad/da un canale" + }; + + moduleInsertLanguage(LANG_EN_US, LANG_NUM_STRINGS, langtable_en_us); + moduleInsertLanguage(LANG_ES, LANG_NUM_STRINGS, langtable_es); + moduleInsertLanguage(LANG_NL, LANG_NUM_STRINGS, langtable_nl); + moduleInsertLanguage(LANG_DE, LANG_NUM_STRINGS, langtable_de); + moduleInsertLanguage(LANG_PT, LANG_NUM_STRINGS, langtable_pt); + moduleInsertLanguage(LANG_RU, LANG_NUM_STRINGS, langtable_ru); + moduleInsertLanguage(LANG_IT, LANG_NUM_STRINGS, langtable_it); +} + +/*************************************************************************/ + +int mNickHelp(User * u) +{ + if (is_oper(u)) { + moduleNoticeLang(s_NickServ, u, OINFO_HELP); + } else { + notice_lang(s_NickServ, u, NO_HELP_AVAILABLE, "OINFO"); + } + return MOD_CONT; +} + +int mChanHelp(User * u) +{ + if (is_oper(u)) { + moduleNoticeLang(s_ChanServ, u, OCINFO_HELP); + } else { + notice_lang(s_ChanServ, u, NO_HELP_AVAILABLE, "OINFO"); + } + return MOD_CONT; +} + +/* This help will be added to the main NickServ list */ +void mMainNickHelp(User * u) +{ + if (is_oper(u)) { + moduleNoticeLang(s_NickServ, u, OINFO_HELP_CMD); + } +} + +/* This help will be added to the main NickServ list */ +void mMainChanHelp(User * u) +{ + if (is_oper(u)) { + moduleNoticeLang(s_ChanServ, u, OCINFO_HELP_CMD); + } +} + +/*************************************************************************/ + +/* EOF */ |