/* NeoStats - IRC Statistical Services ** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond ** http://www.neostats.net/ ** ** Portions Copyright (c) 2000-2001 ^Enigma^ ** ** Portions Copyright (c) 1999 Johnathan George net@lite.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ** USA ** ** NeoStats CVS Identification ** $Id$ */ #include #include "stats.h" #include "ircd.h" #include "dl.h" #include "sock.h" #include "log.h" #include "users.h" #include "chans.h" #include "services.h" #include "server.h" #include "bans.h" #include "dns.h" ircd_server ircd_srv; static char ircd_buf[BUFSIZE]; static char UmodeStringBuf[64]; #ifdef GOTUSERSMODES static char SmodeStringBuf[64]; #endif long services_bot_umode= 0; /* Fully split buffer */ static char privmsgbuffer[BUFSIZE]; /* Temp flag for backward compatibility in new splitbuf system */ static int SkipModuleFunction = 0; static int signon_newbot (const char *nick, const char *user, const char *host, const char *realname, long Umode); #ifdef IRCU int scmode_op (const char *who, const char *chan, const char *mode, const char *bot); #endif /** @brief init_ircd * * ircd initialisation * * @return */ void init_ircd () { #ifdef IRCU /* Temp: force tokens for IRCU */ ircd_srv.token = 1; #endif services_bot_umode = UmodeStringToMask(services_bot_modes, 0); }; /** @brief UmodeMaskToString * * Translate a mode mask to the string equivalent * * @return */ char* UmodeMaskToString(const long Umode) { int i, j; UmodeStringBuf[0] = '+'; j = 1; for (i = 0; i < ircd_umodecount; i++) { if (Umode & user_umodes[i].umode) { UmodeStringBuf[j] = user_umodes[i].mode; j++; } } UmodeStringBuf[j] = '\0'; return(UmodeStringBuf); } /** @brief UmodeStringToMask * * Translate a mode string to the mask equivalent * * @return */ long UmodeStringToMask(const char* UmodeString, long Umode) { int i; int add = 0; char tmpmode; /* Walk through mode string and convert to umode */ tmpmode = *(UmodeString); while (tmpmode) { switch (tmpmode) { case '+': add = 1; break; case '-': add = 0; break; default: for (i = 0; i < ircd_umodecount; i++) { if (user_umodes[i].mode == tmpmode) { if (add) { Umode |= user_umodes[i].umode; break; } else { Umode &= ~user_umodes[i].umode; break; } } } } tmpmode = *UmodeString++; } return(Umode); } #ifdef GOTUSERSMODES /** @brief SmodeMaskToString * * Translate a smode mask to the string equivalent * * @return */ char* SmodeMaskToString(const long Smode) { int i, j; SmodeStringBuf[0] = '+'; j = 1; for (i = 0; i < ircd_smodecount; i++) { if (Smode & user_smodes[i].umode) { SmodeStringBuf[j] = user_smodes[i].mode; j++; } } SmodeStringBuf[j] = '\0'; return(SmodeStringBuf); } /** @brief SmodeStringToMask * * Translate a smode string to the mask equivalent * * @return */ long SmodeStringToMask(const char* SmodeString, long Smode) { int i; int add = 0; char tmpmode; /* Walk through mode string and convert to smode */ tmpmode = *(SmodeString); while (tmpmode) { switch (tmpmode) { case '+': add = 1; break; case '-': add = 0; break; default: for (i = 0; i < ircd_smodecount; i++) { if (user_smodes[i].mode == tmpmode) { if (add) { Smode |= user_smodes[i].umode; break; } else { Smode &= ~user_smodes[i].umode; break; } } } } tmpmode = *SmodeString++; } return(Smode); } #endif /** @brief join_bot_to_chan * * * * @return NS_SUCCESS if suceeds, NS_FAILURE if not */ int join_bot_to_chan (const char *who, const char *chan, unsigned long chflag) { char savemod[SEGV_INMODULE_BUFSIZE]; strlcpy(savemod, segv_inmodule, SEGV_INMODULE_BUFSIZE); #ifdef GOTSJOIN ssjoin_cmd(who, chan, chflag); #else sjoin_cmd(who, chan); if(chflag == CMODE_CHANOP || chflag == CMODE_CHANADMIN) #if defined(IRCU) scmode_op(who, chan, "+o", who); #else schmode_cmd(who, chan, "+o", who); #endif #endif SET_SEGV_INMODULE(savemod); return NS_SUCCESS; } /** @brief signon_newbot * * work in progress to replace ircd specific routines * needs sjoin fix to complete * * @return NS_SUCCESS if suceeds, NS_FAILURE if not */ int signon_newbot (const char *nick, const char *user, const char *host, const char *realname, long Umode) { snewnick_cmd (nick, user, host, realname, Umode); if ((me.allbots > 0) || (Umode & services_bot_umode)) { #ifdef GOTSJOIN ssjoin_cmd (nick, me.chan, CMODE_CHANADMIN); #else sjoin_cmd (nick, me.chan); #if defined(IRCU) scmode_op(nick, me.chan, "+o", nick); #else schmode_cmd(nick, me.chan, "+o", nick); #endif #endif } return NS_SUCCESS; } /** @brief init_bot * * * * @return NS_SUCCESS if suceeds, NS_FAILURE if not */ int init_bot (char *nick, char *user, char *host, char *realname, const char *modes, char *mod_name) { User *u; long Umode; SET_SEGV_LOCATION(); u = finduser (nick); if (u) { nlog (LOG_WARNING, LOG_CORE, "Attempting to Login with a Nickname that already Exists: %s", nick); return NS_FAILURE; } if(!add_mod_user (nick, mod_name)) { nlog (LOG_WARNING, LOG_CORE, "add_mod_user failed for module %s bot %s", mod_name, nick); return NS_FAILURE; } Umode = UmodeStringToMask(modes, 0); signon_newbot (nick, user, host, realname, Umode); /* restore segv_inmodule from SIGNON */ SET_SEGV_INMODULE(mod_name); return NS_SUCCESS; } /** @brief init_mod_bot * * replacement for init_bot - work in progress * * @return NS_SUCCESS if suceeds, NS_FAILURE if not */ ModUser * init_mod_bot (char * nick, char * user, char * host, char * realname, const char *modes, unsigned int flags, bot_cmd *bot_cmd_list, bot_setting *bot_setting_list, char * mod_name) { ModUser * bot_ptr; User *u; long Umode; SET_SEGV_LOCATION(); u = finduser (nick); if (u) { nlog (LOG_WARNING, LOG_CORE, "Attempting to Login with a Nickname that already Exists: %s", nick); return NULL; } bot_ptr = add_mod_user (nick, mod_name); if(!bot_ptr) { nlog (LOG_WARNING, LOG_CORE, "add_mod_user failed for module %s bot %s", mod_name, nick); return NULL; } Umode = UmodeStringToMask(modes, 0); signon_newbot (nick, user, host, realname, Umode); #ifdef UMODE_DEAF if(flags&BOT_FLAG_DEAF) { sumode_cmd (nick, nick, UMODE_DEAF); } #endif /* restore segv_inmodule from SIGNON */ SET_SEGV_INMODULE(mod_name); bot_ptr->flags = flags; add_bot_cmd_list(bot_ptr, bot_cmd_list); if (bot_setting_list != NULL) { bot_ptr->bot_settings = bot_setting_list; /* Default SET to ROOT only */ bot_ptr->set_ulevel = NS_ULEVEL_ROOT; /* Now calculate minimum defined user level */ while(bot_setting_list->option != NULL) { if(bot_setting_list->ulevel < bot_ptr->set_ulevel) bot_ptr->set_ulevel = bot_setting_list->ulevel; bot_setting_list++; } } else { bot_ptr->bot_settings = NULL; bot_ptr->set_ulevel = NS_ULEVEL_ROOT; } return bot_ptr; } /** @brief del_bot * * * * @return NS_SUCCESS if suceeds, NS_FAILURE if not */ int del_bot (char *nick, char *reason) { User *u; SET_SEGV_LOCATION(); u = finduser (nick); if (!u) { nlog (LOG_WARNING, LOG_CORE, "Attempting to Logoff with a Nickname that does not Exists: %s", nick); return NS_FAILURE; } nlog (LOG_DEBUG1, LOG_CORE, "Deleting bot %s for %s", nick, reason); //XXXX TODO: need to free the channel list hash. We dont according to valgrind squit_cmd (nick, reason); del_mod_user (nick); return NS_SUCCESS; } /** @brief CloakBotHost * * Create a hidden hostmask for the bot * Currently only Unreal support via UMODE auto cloaking * but function created for future use and propogation to * external modules to avoid a future joint release. * * @return NS_SUCCESS if suceeds, NS_FAILURE if not */ int CloakHost (ModUser *bot_ptr) { #ifdef GOTUMODECLOAKING sumode_cmd (bot_ptr->nick, bot_ptr->nick, UMODE_HIDE); return NS_SUCCESS; #else return NS_FAILURE; #endif } /** @brief split_buf * Taken from Epona - Thanks! * Split a buffer into arguments and store the arguments in an * argument vector pointed to by argv (which will be malloc'd * as necessary); return the argument count. If colon_special * is non-zero, then treat a parameter with a leading ':' as * the last parameter of the line, per the IRC RFC. Destroys * the buffer by side effect. * * @return */ #ifndef IRCD_SPLITBUF int splitbuf (char *buf, char ***argv, int colon_special) { int argvsize = 8; int argc; char *s; int colcount = 0; SET_SEGV_LOCATION(); *argv = calloc (sizeof (char *) * argvsize, 1); argc = 0; /*if (*buf == ':') buf++;*/ while (*buf) { if (argc == argvsize) { argvsize += 8; *argv = realloc (*argv, sizeof (char *) * argvsize); } if ((*buf == ':') && (colcount < 1)) { buf++; colcount++; if(colon_special) { (*argv)[argc++] = buf; break; } } s = strpbrk (buf, " "); if (s) { *s++ = 0; while (isspace (*s)) s++; } else { s = buf + strnlen (buf, BUFSIZE); } if (*buf == 0) { buf++; } (*argv)[argc++] = buf; buf = s; } return argc; } #endif int split_buf (char *buf, char ***argv, int colon_special) { int argvsize = 8; int argc; char *s; int colcount = 0; SET_SEGV_LOCATION(); *argv = calloc (sizeof (char *) * argvsize, 1); argc = 0; if (*buf == ':') buf++; while (*buf) { if (argc == argvsize) { argvsize += 8; *argv = realloc (*argv, sizeof (char *) * argvsize); } if ((*buf == ':') && (colcount < 1)) { buf++; colcount++; } s = strpbrk (buf, " "); if (s) { *s++ = 0; while (isspace (*s)) s++; } else { s = buf + strnlen (buf, BUFSIZE); } if (*buf == 0) { buf++; } (*argv)[argc++] = buf; buf = s; } return argc; } /** @brief joinbuf * * * * @return */ char * joinbuf (char **av, int ac, int from) { int i; char *buf; buf = malloc (BUFSIZE); /* from is zero based while ac has base of 1. * Therefore we need to check >= before trying to perform * the join. * The current (null) string we return may not be needed * so should be removed once all joinbuf calls are checked. * Maybe we should just return NULL if we fail and let * the caller handle that case. */ if(from >= ac) { nlog (LOG_DEBUG1, LOG_CORE, "joinbuf: from (%d) >= ac (%d)", from, ac); strlcpy (buf, "(null)", BUFSIZE); } else { strlcpy (buf, av[from], BUFSIZE); for (i = from + 1; i < ac; i++) { strlcat (buf, " ", BUFSIZE); strlcat (buf, av[i], BUFSIZE); } } return (char *) buf; } /** @brief process privmsg * * * * @return none */ void m_notice (char* origin, char **av, int ac, int cmdptr) { int i; int splitargc; char **splitargv; int argc; char **argv; SET_SEGV_LOCATION(); if( av[0] == NULL) { nlog (LOG_DEBUG1, LOG_CORE, "m_notice: dropping unknown privmsg from %s, to %s : %s", origin, av[0], av[ac-1]); return; } #if 0 if( ircstrcasecmp(av[0], "AUTH")) { nlog (LOG_DEBUG1, LOG_CORE, "m_notice: dropping server notice from %s, to %s : %s", origin, av[0], av[ac-1]); return; } #endif nlog (LOG_DEBUG1, LOG_CORE, "m_notice: from %s, to %s : %s", origin, av[0], av[ac-1]); strlcpy (privmsgbuffer, av[ac-1], BUFSIZE); splitargc = split_buf (av[ac-1], &splitargv, 0); argc = 0; AddStringToList (&argv, av[0], &argc); for( i = 0 ; i < splitargc ; i++ ) { AddStringToList (&argv, splitargv[i], &argc); } ModuleFunction (cmdptr, MSG_NOTICE, origin, argv, argc); free (argv); argc = 0; AddStringToList (&argv, origin, &argc); AddStringToList (&argv, av[0], &argc); AddStringToList (&argv, privmsgbuffer, &argc); if(av[0][0] == '#') { ModuleEvent (EVENT_CNOTICE, argv, argc); } else { ModuleEvent (EVENT_NOTICE, argv, argc); } free (argv); SkipModuleFunction = 1; } /** @brief process privmsg * * * * @return none */ void m_private (char* origin, char **av, int ac, int cmdptr) { int i; int ret = NS_SUCCESS; int splitargc; char **splitargv; int argc; char **argv; char target[64]; SET_SEGV_LOCATION(); if( av[0] == NULL) { nlog (LOG_DEBUG1, LOG_CORE, "m_private: dropping unknown privmsg from %s, to %s : %s", origin, av[0], av[ac-1]); return; } nlog (LOG_DEBUG1, LOG_CORE, "m_private: from %s, to %s : %s", origin, av[0], av[ac-1]); /* its a privmsg, now lets see who too... */ if (strstr (av[0], "!")) { strlcpy (target, av[0], 64); av[0] = strtok (target, "!"); } else if (strstr (av[0], "@")) { strlcpy (target, av[0], 64); av[0] = strtok (target, "@"); } strlcpy (privmsgbuffer, av[ac-1], BUFSIZE); splitargc = split_buf (av[ac-1], &splitargv, 0); argc = 0; AddStringToList (&argv, av[0], &argc); for( i = 0 ; i < splitargc ; i++ ) { AddStringToList (&argv, splitargv[i], &argc); } if(av[0][0] == '#') { bot_chan_message (origin, argv, argc); /* we need this to fool the check below */ ret = NS_FAILURE; } else { ret = bot_message (origin, argv, argc); } free (argv); free (splitargv); if(ret == NS_FAILURE) { argc = 0; AddStringToList (&argv, origin, &argc); AddStringToList (&argv, av[0], &argc); AddStringToList (&argv, privmsgbuffer, &argc); if(av[0][0] == '#') { ModuleEvent (EVENT_CPRIVATE, argv, argc); } else { ModuleEvent (EVENT_PRIVATE, argv, argc); } free (argv); } return; } /** @brief process ircd commands * * * * @return none */ #ifdef IRCU void #else static void #endif process_ircd_cmd (int cmdptr, char *cmd, char* origin, char **av, int ac) { int i; SET_SEGV_LOCATION(); for (i = 0; i < ircd_cmdcount; i++) { if (!strcmp (cmd_list[i].name, cmd) #ifdef GOTTOKENSUPPORT ||(ircd_srv.token && cmd_list[i].token && !strcmp (cmd_list[i].token, cmd)) #endif ) { if(cmd_list[i].function) { nlog (LOG_DEBUG3, LOG_CORE, "process_ircd_cmd: running command %s", cmd_list[i].name); cmd_list[i].function (origin, av, ac, cmdptr); } else { nlog (LOG_DEBUG3, LOG_CORE, "process_ircd_cmd: ignoring command %s", cmd); } cmd_list[i].usage++; break; } } #if 0 if(i >= ircd_cmdcount) { nlog (LOG_INFO, LOG_CORE, "No support for %s", cmd); } #endif /* Send to modules */ if(!SkipModuleFunction) { ModuleFunction (cmdptr, cmd, origin, av, ac); } SkipModuleFunction = 0; } /** @brief parse * * * * @return none */ #ifndef IRCD_PARSE void parse (char *line) { char origin[64], cmd[64], *coreLine; int cmdptr = 0; int ac; char **av; SET_SEGV_LOCATION(); strip (line); strlcpy (recbuf, line, BUFSIZE); if (!(*line)) return; nlog (LOG_DEBUG1, LOG_CORE, "--------------------------BEGIN PARSE---------------------------"); nlog (LOG_DEBUG1, LOG_CORE, "R: %s", line); if (*line == ':') { coreLine = strpbrk (line, " "); if (!coreLine) return; *coreLine = 0; while (isspace (*++coreLine)); strlcpy (origin, line + 1, sizeof (origin)); memmove (line, coreLine, strnlen (coreLine, BUFSIZE) + 1); cmdptr = 1; } else { cmdptr = 0; *origin = 0; } if (!*line) return; coreLine = strpbrk (line, " "); if (coreLine) { *coreLine = 0; while (isspace (*++coreLine)); } else { coreLine = line + strlen (line); } strlcpy (cmd, line, sizeof (cmd)); nlog (LOG_DEBUG1, LOG_CORE, "origin: %s", origin); nlog (LOG_DEBUG1, LOG_CORE, "cmd : %s", cmd); nlog (LOG_DEBUG1, LOG_CORE, "args : %s", coreLine); ac = splitbuf (coreLine, &av, 1); process_ircd_cmd (cmdptr, cmd, origin, av, ac); nlog (LOG_DEBUG1, LOG_CORE, "---------------------------END PARSE----------------------------"); free (av); } #endif /** @brief init_services_bot * * * * @return none */ int init_services_bot (void) { char **av; int ac = 0; long Umode; SET_SEGV_LOCATION(); if (finduser (s_Services)) { /* nick already exists on the network */ strlcat (s_Services, "1", MAXNICK); } ircsnprintf (me.realname, MAXREALNAME, "/msg %s \2HELP\2", s_Services); Umode = UmodeStringToMask(services_bot_modes, 0); signon_newbot (s_Services, me.user, me.host, me.realname, Umode); #ifdef UMODE_DEAF sumode_cmd (s_Services, s_Services, UMODE_DEAF); #endif me.onchan = 1; AddStringToList (&av, me.uplink, &ac); ModuleEvent (EVENT_ONLINE, av, ac); free (av); return NS_SUCCESS; } /** @brief do_ping * * * * @return none */ void do_ping (const char* origin, const char* destination) { send_pong (origin); #ifdef MSG_BURST if (ircd_srv.burst) { send_ping (me.name, origin, origin); } #endif } /** @brief do_pong * * * * @return none */ void do_pong (const char* origin, const char* destination) { Server *s; char **av; int ac = 0; s = findserver (origin); if (s) { s->ping = me.now - ping.last_sent; if (ping.ulag > 1) s->ping -= (float) ping.ulag; if (!strcmp (me.s->name, s->name)) ping.ulag = me.s->ping; AddStringToList (&av, s->name, &ac); ModuleEvent (EVENT_PONG, av, ac); free (av); } else { nlog (LOG_NOTICE, LOG_CORE, "Received PONG from unknown server: %s", origin); } } /** @brief flood * * * * @return */ int flood (User * u) { time_t current = me.now; if (!u) { nlog (LOG_WARNING, LOG_CORE, "flood: can't find user"); return 0; } if (UserLevel (u) >= NS_ULEVEL_OPER) /* locop or higher */ return 0; if (current - u->t_flood > 10) { u->t_flood = me.now; u->flood = 0; return 0; } if (u->flood >= 5) { nlog (LOG_NORMAL, LOG_CORE, "FLOODING: %s!%s@%s", u->nick, u->username, u->hostname); ssvskill_cmd (u->nick, "%s!%s (Flooding Services.)", me.host, s_Services); return 1; } else { u->flood++; } return 0; } /** @brief Display NeoStats version info * * * * @return */ void do_version (const char* nick, const char *remoteserver) { SET_SEGV_LOCATION(); numeric (RPL_VERSION, nick, "%s :%s -> %s %s", me.versionfull, me.name, version_date, version_time); ModulesVersion (nick, remoteserver); } /** @brief Display our MOTD Message of the Day from the external neostats.motd file * * * * @return */ void do_motd (const char* nick, const char *remoteserver) { FILE *fp; char buf[BUFSIZE]; SET_SEGV_LOCATION(); fp = fopen (MOTD_FILENAME, "r"); if(!fp) { numeric (ERR_NOMOTD, nick, "MOTD File is missing"); } else { numeric (RPL_MOTDSTART, nick, ":- %s Message of the Day -", me.name); numeric (RPL_MOTD, nick, ":- %s. Copyright (c) 1999 - 2004 The NeoStats Group", me.versionfull); numeric (RPL_MOTD, nick, ":-"); if (fp) { while (fgets (buf, sizeof (buf), fp)) { buf[strnlen (buf, BUFSIZE) - 1] = 0; numeric (RPL_MOTD, nick, ":- %s", buf); } fclose (fp); } else { numeric (RPL_MOTD, nick, ":- MOTD file Missing"); } numeric (RPL_ENDOFMOTD, nick, ":End of MOTD command."); } } /** @brief Display the ADMIN Message from the external stats.admin file * * * * @return */ void do_admin (const char* nick, const char *remoteserver) { FILE *fp; char buf[BUFSIZE]; SET_SEGV_LOCATION(); fp = fopen (ADMIN_FILENAME, "r"); if(!fp) { numeric (ERR_NOADMININFO, nick, "%s :No administrative info available", me.name); } else { numeric (RPL_ADMINME, nick, ":%s :Administrative info", me.name); numeric (RPL_ADMINME, nick, ":%s. Copyright (c) 1999 - 2004 The NeoStats Group", me.versionfull); if (fp) { while (fgets (buf, sizeof (buf), fp)) { buf[strnlen (buf, BUFSIZE) - 1] = 0; numeric (RPL_ADMINLOC1, nick, ":- %s", buf); } fclose (fp); } numeric (RPL_ADMINLOC2, nick, "End of /ADMIN command."); } } /** @brief * * * * @return */ void do_credits (const char* nick, const char *remoteserver) { SET_SEGV_LOCATION(); numeric (RPL_VERSION, nick, ":- NeoStats %s Credits ", me.versionfull); numeric (RPL_VERSION, nick, ":- Now Maintained by Shmad (shmad@neostats.net) and ^Enigma^ (enigma@neostats.net)"); numeric (RPL_VERSION, nick, ":- For Support, you can find ^Enigma^ or Shmad at"); numeric (RPL_VERSION, nick, ":- irc.irc-chat.net #NeoStats"); numeric (RPL_VERSION, nick, ":- Thanks to:"); numeric (RPL_VERSION, nick, ":- Enigma for being part of the dev team"); numeric (RPL_VERSION, nick, ":- Stskeeps for writing the best IRCD ever!"); numeric (RPL_VERSION, nick, ":- chrisv@b0rked.dhs.org for the Code for Dynamically Loading Modules (Hurrican IRCD)"); numeric (RPL_VERSION, nick, ":- monkeyIRCD for the Module Segv Catching code"); numeric (RPL_VERSION, nick, ":- the Users of Global-irc.net and Dreaming.org for being our Guinea Pigs!"); numeric (RPL_VERSION, nick, ":- Andy For Ideas"); numeric (RPL_VERSION, nick, ":- HeadBang for BetaTesting, and Ideas, And Hassling us for Beta Copies"); numeric (RPL_VERSION, nick, ":- sre and Jacob for development systems and access"); numeric (RPL_VERSION, nick, ":- Error51 for Translating our FAQ and README files"); numeric (RPL_VERSION, nick, ":- users and opers of irc.irc-chat.net/org for putting up with our constant coding crashes!"); numeric (RPL_VERSION, nick, ":- Eggy for proving to use our code still had bugs when we thought it didn't (and all the bug reports!)"); numeric (RPL_VERSION, nick, ":- Hwy - Helping us even though he also has a similar project, and providing solaris porting tips :)"); numeric (RPL_VERSION, nick, ":- M - Updating lots of Doco and code and providing lots of great feedback"); numeric (RPL_VERSION, nick, ":- J Michael Jones - Giving us Patches to support QuantumIRCd"); numeric (RPL_VERSION, nick, ":- Blud - Giving us patches for Mystic IRCd"); numeric (RPL_VERSION, nick, ":- herrohr - Giving us patches for Liquid IRCd support"); numeric (RPL_VERSION, nick, ":- OvErRiTe - Giving us patches for Viagra IRCd support"); numeric (RPL_VERSION, nick, ":- Reed Loden - Contributions to IRCu support"); } /** @brief * * * * @return */ void do_stats (const char* nick, const char *what) { time_t tmp; time_t tmp2; int i; #ifdef EXTAUTH int dl; int (*listauth) (User * u); #endif User *u; SET_SEGV_LOCATION(); u = finduser (nick); if (!u) { nlog (LOG_WARNING, LOG_CORE, "do_stats: message from unknown user %s", nick); return; } if (!ircstrcasecmp (what, "u")) { /* server uptime - Shmad */ int uptime = me.now - me.t_start; numeric (RPL_STATSUPTIME, u->nick, "Statistical Server up %d days, %d:%02d:%02d", uptime / 86400, (uptime / 3600) % 24, (uptime / 60) % 60, uptime % 60); } else if (!ircstrcasecmp (what, "c")) { /* Connections */ numeric (RPL_STATSNLINE, u->nick, "N *@%s * * %d 50", me.uplink, me.port); numeric (RPL_STATSCLINE, u->nick, "C *@%s * * %d 50", me.uplink, me.port); } else if (!ircstrcasecmp (what, "o")) { /* Operators */ #ifdef EXTAUTH dl = get_dl_handle ("extauth"); if (dl > 0) { listauth = ns_dlsym ((int *) dl, "__list_auth"); if (listauth) (*listauth) (u); } else #endif numeric (RPL_STATSOLINE, u->nick, "Operators think they are God, but you and I know they are not!"); } else if (!ircstrcasecmp (what, "l")) { /* Port Lists */ tmp = me.now - me.lastmsg; tmp2 = me.now - me.t_start; numeric (RPL_STATSLINKINFO, u->nick, "l SendQ SendM SendBytes RcveM RcveBytes Open_Since CPU :IDLE"); numeric (RPL_STATSLLINE, u->nick, "%s 0 %d %d %d %d %d 0 :%d", me.uplink, (int)me.SendM, (int)me.SendBytes, (int)me.RcveM, (int)me.RcveBytes, (int)tmp2, (int)tmp); } else if (!ircstrcasecmp (what, "M")) { for (i = 0; i < ircd_cmdcount; i++) { if (cmd_list[i].usage > 0) numeric (RPL_STATSCOMMANDS, u->nick, "Command %s Usage %d", cmd_list[i].name, cmd_list[i].usage); } } else if (!ircstrcasecmp(what, "Z")) { if (UserLevel(u) >= NS_ULEVEL_ADMIN) { do_dns_stats_Z(u); } } numeric (RPL_ENDOFSTATS, u->nick, "%s :End of /STATS report", what); chanalert (s_Services, "%s Requested Stats %s", u->nick, what); }; void do_protocol (char *origin, char **argv, int argc) { int i; ircd_srv.unkline = 0; for (i = 0; i < argc; i++) { #ifdef GOTTOKENSUPPORT if (!ircstrcasecmp ("TOKEN", argv[i])) { ircd_srv.token = 1; } #endif #ifdef GOTCLIENTSUPPORT if (!ircstrcasecmp ("CLIENT", argv[i])) { me.client = 1; } #endif #if defined(HYBRID7) if (!ircstrcasecmp ("UNKLN", argv[i])) { ircd_srv.unkline = 1; } #endif #ifdef GOTNOQUITSUPPORT if (!ircstrcasecmp ("NOQUIT", argv[i])) { ircd_srv.noquit = 1; } #endif #ifdef UNREAL32 if (!ircstrcasecmp ("NICKIP", argv[i])) { ircd_srv.nickip = 1; } #endif } } void privmsg_list (char *to, char *from, const char **text) { while (*text) { if (**text) prefmsg (to, from, (char*)*text); else prefmsg (to, from, " "); text++; } } void chanalert (char *from, char *fmt, ...) { va_list ap; if (!me.onchan) return; va_start (ap, fmt); ircvsnprintf (ircd_buf, BUFSIZE, fmt, ap); va_end (ap); send_privmsg (from, me.chan, ircd_buf); } void prefmsg (char *to, const char *from, char *fmt, ...) { va_list ap; if (findbot (to)) { chanalert (s_Services, "Message From our Bot(%s) to Our Bot(%s), Dropping Message", from, to); return; } va_start (ap, fmt); ircvsnprintf (ircd_buf, BUFSIZE, fmt, ap); va_end (ap); if (me.want_privmsg) { send_privmsg (from, to, ircd_buf); } else { send_notice (from, to, ircd_buf); } } void privmsg (char *to, const char *from, char *fmt, ...) { va_list ap; if (findbot (to)) { chanalert (s_Services, "Message From our Bot(%s) to Our Bot(%s), Dropping Message", from, to); return; } va_start (ap, fmt); ircvsnprintf (ircd_buf, BUFSIZE, fmt, ap); va_end (ap); send_privmsg (from, to, ircd_buf); } void notice (char *to, const char *from, char *fmt, ...) { va_list ap; if (findbot (to)) { chanalert (s_Services, "Message From our Bot(%s) to Our Bot(%s), Dropping Message", from, to); return; } va_start (ap, fmt); ircvsnprintf (ircd_buf, BUFSIZE, fmt, ap); va_end (ap); send_notice (from, to, ircd_buf); } void globops (char *from, char *fmt, ...) { va_list ap; va_start (ap, fmt); ircvsnprintf (ircd_buf, BUFSIZE, fmt, ap); va_end (ap); if (me.onchan) { send_globops(from, ircd_buf); } else { nlog (LOG_NORMAL, LOG_CORE, ircd_buf); } } int wallops (const char *from, const char *msg, ...) { va_list ap; va_start (ap, msg); ircvsnprintf (ircd_buf, BUFSIZE, msg, ap); va_end (ap); send_wallops ((char*)from, (char*)ircd_buf); return NS_SUCCESS; } int numeric (const int numeric, const char *target, const char *data, ...) { va_list ap; va_start (ap, data); ircvsnprintf (ircd_buf, BUFSIZE, data, ap); va_end (ap); send_numeric (me.name, numeric, target, ircd_buf); return NS_SUCCESS; } void unsupported_cmd(const char* cmd) { chanalert (s_Services, "Warning, %s tried to %s which is not supported", ((segvinmodule[0] != 0)? segvinmodule : ""), cmd); nlog (LOG_NOTICE, LOG_CORE, "Warning, %s tried to %s, which is not supported", ((segvinmodule[0] != 0)? segvinmodule : ""), cmd); } int sumode_cmd (const char *who, const char *target, long mode) { char* newmode; newmode = UmodeMaskToString(mode); send_umode (who, target, newmode); UserMode (target, newmode); return NS_SUCCESS; } int spart_cmd (const char *who, const char *chan) { send_part(who, chan); part_chan (finduser (who), (char *) chan, NULL); return NS_SUCCESS; } int snick_cmd (const char *oldnick, const char *newnick) { UserNick (oldnick, newnick, NULL); send_nickchange (oldnick, newnick, me.now); return NS_SUCCESS; } #ifdef IRCU int scmode_op (const char *who, const char *chan, const char *mode, const char *bot) { char **av; int ac; send_cmode (me.name, who, chan, mode, nicktobase64 (bot), me.now); ircsnprintf (ircd_buf, BUFSIZE, "%s %s %s", chan, mode, bot); ac = split_buf (ircd_buf, &av, 0); ChanMode (me.name, av, ac); free (av); return NS_SUCCESS; } #endif int schmode_cmd (const char *who, const char *chan, const char *mode, const char *args) { char **av; int ac; send_cmode (me.name, who, chan, mode, args, me.now); ircsnprintf (ircd_buf, BUFSIZE, "%s %s %s", chan, mode, args); ac = split_buf (ircd_buf, &av, 0); ChanMode (me.name, av, ac); free (av); return NS_SUCCESS; } int squit_cmd (const char *who, const char *quitmsg) { send_quit (who, quitmsg); do_quit (who, quitmsg); return NS_SUCCESS; } int skill_cmd (const char *from, const char *target, const char *reason, ...) { va_list ap; va_start (ap, reason); ircvsnprintf (ircd_buf, BUFSIZE, reason, ap); va_end (ap); send_kill (from, target, ircd_buf); do_quit (target, ircd_buf); return NS_SUCCESS; } int ssvskill_cmd (const char *target, const char *reason, ...) { va_list ap; va_start (ap, reason); ircvsnprintf (ircd_buf, BUFSIZE, reason, ap); va_end (ap); #ifdef GOTSVSKILL send_svskill (me.name, target, ircd_buf); #else send_kill (me.name, target, ircd_buf); do_quit (target, ircd_buf); #endif return NS_SUCCESS; } #ifdef GOTSVSTIME int ssvstime_cmd (const time_t ts) { send_svstime(me.name, (unsigned long)ts); nlog (LOG_NOTICE, LOG_CORE, "ssvstime_cmd: synching server times to %lu", ts); return NS_SUCCESS; } #endif int skick_cmd (const char *who, const char *chan, const char *target, const char *reason) { send_kick (who, chan, target, reason); part_chan (finduser (target), (char *) chan, reason[0] != 0 ? (char *)reason : NULL); return NS_SUCCESS; } int sinvite_cmd (const char *from, const char *to, const char *chan) { send_invite(from, to, chan); return NS_SUCCESS; } int ssvsmode_cmd (const char *target, const char *modes) { #ifdef GOTSVSMODE User *u; u = finduser (target); if (!u) { nlog (LOG_WARNING, LOG_CORE, "ssvsmode_cmd: can't find user %s", target); return 0; } send_svsmode(me.name, target, modes); UserMode (target, modes); #else unsupported_cmd("SVSMODE"); #endif return NS_SUCCESS; } int ssvshost_cmd (const char *who, const char *vhost) { #ifdef GOTSVSHOST User *u; u = finduser (who); if (!u) { nlog (LOG_WARNING, LOG_CORE, "ssvshost_cmd: can't find user %s", who); return 0; } strlcpy (u->vhost, vhost, MAXHOST); send_svshost(me.name, who, vhost); #else unsupported_cmd("SVSHOST"); #endif return NS_SUCCESS; } int ssvsjoin_cmd (const char *target, const char *chan) { #ifdef GOTSVSJOIN send_svsjoin (me.name, target, chan); #else unsupported_cmd("SVSJOIN"); #endif return NS_SUCCESS; } int ssvspart_cmd (const char *target, const char *chan) { #ifdef GOTSVSPART send_svspart (me.name, target, chan); #else unsupported_cmd("SVSPART"); #endif return NS_SUCCESS; } int sswhois_cmd (const char *target, const char *swhois) { #ifdef GOTSWHOIS send_swhois (me.name, target, swhois); #else unsupported_cmd("SWHOIS"); #endif return NS_SUCCESS; } int ssvsnick_cmd (const char *target, const char *newnick) { #ifdef GOTSVSNICK send_svsnick (me.name, target, newnick, me.now); #else notice (s_Services, "Warning Module %s tried to SVSNICK, which is not supported", segvinmodule); nlog (LOG_NOTICE, LOG_CORE, "Warning. Module %s tried to SVSNICK, which is not supported", segvinmodule); #endif return NS_SUCCESS; } int ssmo_cmd (const char *from, const char *umodetarget, const char *msg) { #ifdef GOTSMO send_smo (from, umodetarget, msg); #else unsupported_cmd("SMO"); #endif return NS_SUCCESS; } int sakill_cmd (const char *host, const char *ident, const char *setby, const int length, const char *reason, ...) { va_list ap; va_start (ap, reason); ircvsnprintf (ircd_buf, BUFSIZE, reason, ap); va_end (ap); send_akill(me.name, host, ident, setby, length, ircd_buf, me.now); return NS_SUCCESS; } int srakill_cmd (const char *host, const char *ident) { send_rakill (me.name, host, ident); return NS_SUCCESS; } int ssjoin_cmd (const char *who, const char *chan, unsigned long chflag) { char flag; char mode; char **av; int ac; time_t ts; Chans *c; c = findchan ((char *) chan); if (!c) { ts = me.now; } else { ts = c->tstime; } switch (chflag) { #ifdef CMODE_FL_CHANOP case CMODE_CHANOP: flag = CMODE_FL_CHANOP; mode= CMODE_CH_CHANOP; break; #endif #ifdef CMODE_FL_VOICE case CMODE_VOICE: flag = CMODE_FL_VOICE; mode= CMODE_CH_VOICE; break; #endif #ifdef CMODE_FL_CHANOWNER case CMODE_CHANOWNER: flag = CMODE_FL_CHANOWNER; mode= CMODE_CH_CHANOWNER; break; #endif #ifdef CMODE_FL_CHANPROT case CMODE_CHANPROT: flag = CMODE_FL_CHANPROT; mode= CMODE_CH_CHANPROT; break; #endif #ifdef CMODE_FL_VIP case CMODE_VIP: flag = CMODE_FL_VIP; mode= CMODE_CH_VIP; break; #endif #ifdef CMODE_FL_HALFOP case CMODE_HALFOP: flag = CMODE_FL_HALFOP; mode= CMODE_CH_HALFOP; break; #endif #ifdef CMODE_FL_UOP case CMODE_UOP: flag = CMODE_FL_UOP; mode= CMODE_CH_UOP; break; #endif #ifndef FAKE_CMODE_CHANADMIN #ifdef CMODE_FL_CHANADMIN case CMODE_CHANADMIN: flag = CMODE_FL_CHANADMIN; mode= CMODE_CH_CHANADMIN; break; #endif #endif #ifdef CMODE_SILENCE case CMODE_FL_SILENCE: flag = CMODE_FL_SILENCE; mode= CMODE_CH_SILENCE; break; #endif default: flag = ' '; mode= '\0'; } if (mode == 0) { ircsnprintf (ircd_buf, BUFSIZE, "%s", who); } else { ircsnprintf (ircd_buf, BUFSIZE, "%c%s", flag, who); } send_sjoin (me.name, ircd_buf, chan, (unsigned long)ts); join_chan (who, chan); ircsnprintf (ircd_buf, BUFSIZE, "%s +%c %s", chan, mode, who); ac = split_buf (ircd_buf, &av, 0); ChanMode (me.name, av, ac); free (av); return NS_SUCCESS; } int sjoin_cmd (const char *who, const char *chan) { send_join (me.name, who, chan, me.now); join_chan (who, chan); return NS_SUCCESS; } int sping_cmd (const char *from, const char *reply, const char *to) { send_ping (from, reply, to); return NS_SUCCESS; } int spong_cmd (const char *reply) { send_pong (reply); return NS_SUCCESS; } int sserver_cmd (const char *name, const int numeric, const char *infoline) { send_server (me.name, name, numeric, infoline); return NS_SUCCESS; } int ssquit_cmd (const char *server, const char *quitmsg) { send_squit (server, quitmsg); return NS_SUCCESS; } int snewnick_cmd (const char *nick, const char *ident, const char *host, const char *realname, long mode) { char* newmode; newmode = UmodeMaskToString(mode); AddUser (nick, ident, host, realname, me.name, NULL, NULL, NULL); send_nick (nick, (unsigned long)me.now, newmode, ident, host, me.name, realname); #if defined(ULTIMATE3) || defined(BAHAMUT) || defined(HYBRID7) || defined(IRCU) || defined(NEOIRCD) || defined(QUANTUM) || defined(LIQUID) UserMode (nick, newmode); #else sumode_cmd (nick, nick, mode); #endif return NS_SUCCESS; } /* SJOIN # :[@][+] ... [@][+] */ void do_sjoin (char* tstime, char* channame, char *modes, char *sjoinnick, char **argv, int argc) { char nick[MAXNICK]; char* nicklist; int modeexists; long mode = 0; int ok = 1, i, j = 3; ModesParm *m; Chans *c; lnode_t *mn = NULL; char **param; int paramcnt = 0; int paramidx = 0; if (*modes == '#') { join_chan (sjoinnick, modes); return; } paramcnt = split_buf(argv[argc-1], ¶m, 0); while (paramcnt > paramidx) { nicklist = param[paramidx]; #ifdef UNREAL /* Unreal passes +b(&) and +e(") via SJ3 so skip them for now */ if(*nicklist == '&' || *nicklist == '"') { nlog (LOG_DEBUG1, LOG_CORE, "Skipping %s", nicklist); paramidx++; continue; } #endif mode = 0; while (ok == 1) { for (i = 0; i < ircd_cmodecount; i++) { if (chan_modes[i].sjoin != 0) { if (*nicklist == chan_modes[i].sjoin) { mode |= chan_modes[i].mode; nicklist++; i = -1; } } else { /* sjoin's should be at the top of the list */ ok = 0; strlcpy (nick, nicklist, MAXNICK); break; } } } join_chan (nick, channame); ChanUserMode (channame, nick, 1, mode); paramidx++; ok = 1; } c = findchan (channame); if(c) { /* update the TS time */ SetChanTS (c, atoi (tstime)); if (*modes == '+') { while (*modes) { for (i = 0; i < ircd_cmodecount; i++) { if (*modes == chan_modes[i].flag) { if (chan_modes[i].parameters) { mn = list_first (c->modeparms); modeexists = 0; while (mn) { m = lnode_get (mn); /* mode limit and mode key replace current values */ if ((m->mode == CMODE_LIMIT) && (chan_modes[i].mode == CMODE_LIMIT)) { strlcpy (m->param, argv[j], PARAMSIZE); j++; modeexists = 1; break; } else if ((m->mode == CMODE_KEY) && (chan_modes[i].mode == CMODE_KEY)) { strlcpy (m->param, argv[j], PARAMSIZE); j++; modeexists = 1; break; } else if (((int *) m->mode == (int *) chan_modes[i].mode) && !ircstrcasecmp (m->param, argv[j])) { nlog (LOG_INFO, LOG_CORE, "ChanMode: Mode %c (%s) already exists, not adding again", chan_modes[i].flag, argv[j]); j++; modeexists = 1; break; } mn = list_next (c->modeparms, mn); } if (modeexists != 1) { m = smalloc (sizeof (ModesParm)); m->mode = chan_modes[i].mode; strlcpy (m->param, argv[j], PARAMSIZE); mn = lnode_create (m); if (list_isfull (c->modeparms)) { nlog (LOG_CRITICAL, LOG_CORE, "ChanMode: modelist is full adding to channel %s", c->name); do_exit (NS_EXIT_ERROR, "List full - see log file"); } else { list_append (c->modeparms, mn); } j++; } } else { c->modes |= chan_modes[i].mode; } } } modes++; } } } free(param); } #ifdef MSG_NETINFO void do_netinfo(const char* maxglobalcnt, const char* tsendsync, const char* prot, const char* cloak, const char* netname) { ircd_srv.maxglobalcnt = atoi (maxglobalcnt); ircd_srv.tsendsync = atoi (tsendsync); ircd_srv.uprot = atoi (prot); strlcpy (ircd_srv.cloak, cloak, CLOAKKEYLEN); strlcpy (me.netname, netname, MAXPASS); send_netinfo (me.name, ircd_srv.uprot, ircd_srv.cloak, me.netname, me.now); init_services_bot (); globops (me.name, "Link with Network \2Complete!\2"); ModuleEvent (EVENT_NETINFO, NULL, 0); me.synced = 1; } #endif #ifdef MSG_SNETINFO void do_snetinfo(const char* maxglobalcnt, const char* tsendsync, const char* prot, const char* cloak, const char* netname) { ircd_srv.uprot = atoi (prot); strlcpy (ircd_srv.cloak, cloak, CLOAKKEYLEN); strlcpy (me.netname, netname, MAXPASS); send_snetinfo (me.name, ircd_srv.uprot, ircd_srv.cloak, me.netname, me.now); init_services_bot (); globops (me.name, "Link with Network \2Complete!\2"); ModuleEvent (EVENT_NETINFO, NULL, 0); me.synced = 1; } #endif void do_join (const char* nick, const char* chanlist, const char* keys) { char *s, *t; t = (char*)chanlist; while (*(s = t)) { t = s + strcspn (s, ","); if (*t) *t++ = 0; join_chan (nick, s); } } void do_part (const char* nick, const char* chan, const char* reason) { part_chan (finduser (nick), chan, reason); } void do_nick (const char *nick, const char *hopcount, const char* TS, const char *user, const char *host, const char *server, const char *ip, const char *servicestamp, const char *modes, const char *vhost, const char *realname, const char *numeric #ifdef GOTUSERSMODES , const char *smodes #endif ) { AddUser (nick, user, host, realname, server, ip, TS, numeric); if(modes) { UserMode (nick, modes); } if(vhost) { SetUserVhost(nick, vhost); } #ifdef GOTUSERSMODES if(smodes) { UserSMode (nick, smodes); } #endif } void do_client (const char *nick, const char *arg1, const char *TS, const char *modes, const char *smodes, const char *user, const char *host, const char *vhost, const char *server, const char *arg9, const char *ip, const char *realname) { AddUser (nick, user, host, realname, server, ip, TS, NULL); if(modes) { UserMode (nick, modes); } if(vhost) { SetUserVhost(nick, vhost); } #ifdef GOTUSERSMODES if(smodes) { UserSMode (nick, smodes); } #endif } void do_kill (const char *nick, const char *reason) { DelUser (nick, 1, reason); } void do_quit (const char *nick, const char *quitmsg) { DelUser (nick, 0, quitmsg); } void do_squit(const char *name, const char* reason) { DelServer (name, reason); } void do_kick (const char *kickby, const char *chan, const char *kicked, const char *kickreason) { kick_chan (kickby, chan, kicked, kickreason); } #ifdef MSG_SVINFO void do_svinfo (void) { send_svinfo (TS_CURRENT, TS_MIN, (unsigned long)me.now); } #endif #ifdef MSG_VCTRL void do_vctrl (const char* uprot, const char* nicklen, const char* modex, const char* gc, const char* netname) { ircd_srv.uprot = atoi(uprot); ircd_srv.nicklen = atoi(nicklen); ircd_srv.modex = atoi(modex); ircd_srv.gc = atoi(gc); strlcpy (me.netname, netname, MAXPASS); send_vctrl (ircd_srv.uprot, ircd_srv.nicklen, ircd_srv.modex, ircd_srv.gc, me.netname); } #endif #ifdef GOTUSERSMODES void do_smode (const char* nick, const char* modes) { UserSMode (nick, modes); } #endif void do_mode_user (const char* nick, const char* modes) { UserMode (nick, modes); } void do_svsmode_user (const char* nick, const char* modes, const char* ts) { char modebuf[MODESIZE]; if (ts && isdigit(*ts)) { const char* pModes; char* pNewModes; SetUserServicesTS (nick, ts); /* If only setting TS, we do not need further mode processing */ if(strcasecmp(modes, "+d") == 0) { nlog (LOG_DEBUG3, LOG_CORE, "dropping modes since this is a services TS %s", modes); return; } /* We need to strip the d from the mode string */ pNewModes = modebuf; pModes = modes; while(*pModes) { if(*pModes != 'd') { *pNewModes = *pModes; } pModes++; pNewModes++; } /* NULL terminate */ *pNewModes = 0; UserMode (nick, modebuf); } else { UserMode (nick, modes); } } void do_mode_channel (char *origin, char **argv, int argc) { ChanMode (origin, argv, argc); } void do_away (const char* nick, const char *reason) { UserAway (nick, reason); } void do_vhost (const char* nick, const char *vhost) { SetUserVhost(nick, vhost); } void do_nickchange (const char * oldnick, const char *newnick, const char * ts) { UserNick (oldnick, newnick, ts); } void do_topic (const char* chan, const char *owner, const char* ts, const char *topic) { ChanTopic (chan, owner, ts, topic); } void do_server (const char *name, const char *uplink, const char* hops, const char *numeric, const char *infoline, int srv) { if(srv == 0) { if (uplink == NULL || *uplink == 0) { me.s = AddServer (name, me.name, hops, numeric, infoline); } else { me.s = AddServer (name, uplink, hops, numeric, infoline); } } else { AddServer (name, uplink, hops, numeric, infoline); } } #ifndef IRCU #ifdef MSG_BURST void do_burst (char *origin, char **argv, int argc) { if (argc > 0) { if (ircd_srv.burst == 1) { send_burst (0); ircd_srv.burst = 0; me.synced = 1; init_services_bot (); } } else { ircd_srv.burst = 1; } } #endif #endif #ifdef MSG_SWHOIS void do_swhois (char *who, char *swhois) { User* u; u = finduser(who); if(u) { strlcpy(u->swhois, swhois, MAXHOST); } } #endif #ifdef MSG_TKL void do_tkl(const char *add, const char *type, const char *user, const char *host, const char *setby, const char *tsexpire, const char *tsset, const char *reason) { char mask[MAXHOST]; ircsnprintf(mask, MAXHOST, "%s@%s", user, host); if(add[0] == '+') { AddBan(type, user, host, mask, reason, setby, tsset, tsexpire); } else { DelBan(type, user, host, mask, reason, setby, tsset, tsexpire); } } #endif #ifdef MSG_EOS void do_eos (const char *name) { Server *s; s = findserver (name); if(s) { SynchServer(s); nlog (LOG_DEBUG1, LOG_CORE, "do_eos: server %s is now synched", name); } else { nlog (LOG_WARNING, LOG_CORE, "do_eos: server %s not found", name); } } #endif void send_cmd (char *fmt, ...) { va_list ap; char buf[BUFSIZE]; int buflen; va_start (ap, fmt); ircvsnprintf (buf, BUFSIZE, fmt, ap); va_end (ap); nlog (LOG_DEBUG2, LOG_CORE, "SENT: %s", buf); if(strnlen (buf, BUFSIZE) < BUFSIZE - 2) { strlcat (buf, "\n", BUFSIZE); } else { buf[BUFSIZE - 1] = 0; buf[BUFSIZE - 2] = '\n'; } buflen = strnlen (buf, BUFSIZE); sts (buf, buflen); } #ifdef BASE64SERVERNAME void setserverbase64 (const char *name, const char* num) { Server *s; s = findserver(name); if(s) { nlog (LOG_DEBUG1, LOG_CORE, "setserverbase64: setting %s to %s", name, num); strlcpy(s->name64, num, 6); } else { nlog (LOG_DEBUG1, LOG_CORE, "setserverbase64: cannot find %s for %s", name, num); } } char* servertobase64 (const char* name) { Server *s; nlog (LOG_DEBUG1, LOG_CORE, "servertobase64: scanning for %s", name); s = findserver(name); if(s) { return s->name64; } else { nlog (LOG_DEBUG1, LOG_CORE, "servertobase64: cannot find %s", name); } return NULL; } char* base64toserver (const char* num) { Server *s; nlog (LOG_DEBUG1, LOG_CORE, "base64toserver: scanning for %s", num); s = findserverbase64(num); if(s) { return s->name; } else { nlog (LOG_DEBUG1, LOG_CORE, "base64toserver: cannot find %s", num); } return NULL; } #endif #ifdef BASE64NICKNAME void setnickbase64 (const char *nick, const char* num) { User *u; u = finduser(nick); if(u) { nlog (LOG_DEBUG1, LOG_CORE, "setnickbase64: setting %s to %s", nick, num); strlcpy(u->nick64, num, B64SIZE); } else { nlog (LOG_DEBUG1, LOG_CORE, "setnickbase64: cannot find %s for %s", nick, num); } } char* nicktobase64 (const char* nick) { User *u; nlog (LOG_DEBUG1, LOG_CORE, "nicktobase64: scanning for %s", nick); u = finduser(nick); if(u) { return u->nick64; } else { nlog (LOG_DEBUG1, LOG_CORE, "nicktobase64: cannot find %s", nick); } return NULL; } char* base64tonick (const char* num) { User *u; nlog (LOG_DEBUG1, LOG_CORE, "base64tonick: scanning for %s", num); u = finduserbase64(num); if(u) { return u->nick; } else { nlog (LOG_DEBUG1, LOG_CORE, "base64tonick: cannot find %s", num); } return NULL; } #endif