924 lines
26 KiB
C
924 lines
26 KiB
C
/* NeoStats - IRC Statistical Services
|
|
** Copyright (c) 1999-2005 Adam Rutter, Justin Hammond, Mark Hetherington
|
|
** http://www.neostats.net/
|
|
**
|
|
** Portions Copyright (c) 2000-2001 ^Enigma^
|
|
**
|
|
** 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 "neostats.h"
|
|
#include "protocol.h"
|
|
|
|
/* Messages/Tokens */
|
|
char *MSG_PRIVATE = "PRIVMSG";/* PRIV */
|
|
char *TOK_PRIVATE = "!";/* 33 */
|
|
char *MSG_WHOIS = "WHOIS";/* WHOI */
|
|
char *TOK_WHOIS = "#";/* 35 */
|
|
char *MSG_WHOWAS = "WHOWAS";/* WHOW */
|
|
char *TOK_WHOWAS = "$";/* 36 */
|
|
char *MSG_USER = "USER";/* USER */
|
|
char *TOK_USER = "%";/* 37 */
|
|
char *MSG_NICK = "NICK";/* NICK */
|
|
char *TOK_NICK = "&";/* 38 */
|
|
char *MSG_SERVER = "SERVER";/* SERV */
|
|
char *TOK_SERVER = "'";/* 39 */
|
|
char *MSG_LIST = "LIST";/* LIST */
|
|
char *TOK_LIST = "(";/* 40 */
|
|
char *MSG_TOPIC = "TOPIC";/* TOPI */
|
|
char *TOK_TOPIC = ")";/* 41 */
|
|
char *MSG_INVITE = "INVITE";/* INVI */
|
|
char *TOK_INVITE = "*";/* 42 */
|
|
char *MSG_VERSION = "VERSION";/* VERS */
|
|
char *TOK_VERSION = "+";/* 43 */
|
|
char *MSG_QUIT = "QUIT";/* QUIT */
|
|
char *TOK_QUIT = ",";/* 44 */
|
|
char *MSG_SQUIT = "SQUIT";/* SQUI */
|
|
char *TOK_SQUIT = "-";/* 45 */
|
|
char *MSG_KILL = "KILL";/* KILL */
|
|
char *TOK_KILL = ".";/* 46 */
|
|
char *MSG_INFO = "INFO";/* INFO */
|
|
char *TOK_INFO = "/";/* 47 */
|
|
char *MSG_LINKS = "LINKS";/* LINK */
|
|
char *TOK_LINKS = "0";/* 48 */
|
|
char *MSG_SUMMON = "SUMMON";/* SUMM */
|
|
char *TOK_SUMMON = "1";/* 49 */
|
|
char *MSG_STATS = "STATS";/* STAT */
|
|
char *TOK_STATS = "2";/* 50 */
|
|
char *MSG_USERS = "USERS";/* USER -> USRS */
|
|
char *TOK_USERS = "3";/* 51 */
|
|
char *MSG_HELP = "HELP";/* HELP */
|
|
char *MSG_HELPOP = "HELPOP";/* HELP */
|
|
char *TOK_HELP = "4";/* 52 */
|
|
char *MSG_ERROR = "ERROR";/* ERRO */
|
|
char *TOK_ERROR = "5";/* 53 */
|
|
char *MSG_AWAY = "AWAY";/* AWAY */
|
|
char *TOK_AWAY = "6";/* 54 */
|
|
char *MSG_CONNECT = "CONNECT";/* CONN */
|
|
char *TOK_CONNECT = "7";/* 55 */
|
|
char *MSG_PING = "PING";/* PING */
|
|
char *TOK_PING = "8";/* 56 */
|
|
char *MSG_PONG = "PONG";/* PONG */
|
|
char *TOK_PONG = "9";/* 57 */
|
|
char *MSG_OPER = "OPER";/* OPER */
|
|
char *TOK_OPER = ";";/* 59 */
|
|
char *MSG_PASS = "PASS";/* PASS */
|
|
char *TOK_PASS = "<";/* 60 */
|
|
char *MSG_WALLOPS = "WALLOPS";/* WALL */
|
|
char *TOK_WALLOPS = "=";/* 61 */
|
|
char *MSG_TIME = "TIME";/* TIME */
|
|
char *TOK_TIME = ">";/* 62 */
|
|
char *MSG_NAMES = "NAMES";/* NAME */
|
|
char *TOK_NAMES = "?";/* 63 */
|
|
char *MSG_ADMIN = "ADMIN";/* ADMI */
|
|
char *TOK_ADMIN = "@";/* 64 */
|
|
char *MSG_NOTICE = "NOTICE";/* NOTI */
|
|
char *TOK_NOTICE = "B";/* 66 */
|
|
char *MSG_JOIN = "JOIN";/* JOIN */
|
|
char *TOK_JOIN = "C";/* 67 */
|
|
char *MSG_PART = "PART";/* PART */
|
|
char *TOK_PART = "D";/* 68 */
|
|
char *MSG_LUSERS = "LUSERS";/* LUSE */
|
|
char *TOK_LUSERS = "E";/* 69 */
|
|
char *MSG_MOTD = "MOTD";/* MOTD */
|
|
char *TOK_MOTD = "F";/* 70 */
|
|
char *MSG_MODE = "MODE";/* MODE */
|
|
char *TOK_MODE = "G";/* 71 */
|
|
char *MSG_KICK = "KICK";/* KICK */
|
|
char *TOK_KICK = "H";/* 72 */
|
|
char *MSG_SERVICE = "SERVICE";/* SERV -> SRVI */
|
|
char *TOK_SERVICE = "I";/* 73 */
|
|
char *MSG_USERHOST = "USERHOST";/* USER -> USRH */
|
|
char *TOK_USERHOST = "J";/* 74 */
|
|
char *MSG_ISON = "ISON";/* ISON */
|
|
char *TOK_ISON = "K";/* 75 */
|
|
char *MSG_REHASH = "REHASH";/* REHA */
|
|
char *TOK_REHASH = "O";/* 79 */
|
|
char *MSG_RESTART = "RESTART";/* REST */
|
|
char *TOK_RESTART = "P";/* 80 */
|
|
char *MSG_CLOSE = "CLOSE";/* CLOS */
|
|
char *TOK_CLOSE = "Q";/* 81 */
|
|
char *MSG_DIE = "DIE";/* DIE */
|
|
char *TOK_DIE = "R";/* 82 */
|
|
char *MSG_HASH = "HASH";/* HASH */
|
|
char *TOK_HASH = "S";/* 83 */
|
|
char *MSG_DNS = "DNS";/* DNS -> DNSS */
|
|
char *TOK_DNS = "T";/* 84 */
|
|
char *MSG_SILENCE = "SILENCE";/* SILE */
|
|
char *TOK_SILENCE = "U";/* 85 */
|
|
char *MSG_AKILL = "AKILL";/* AKILL */
|
|
char *TOK_AKILL = "V";/* 86 */
|
|
char *MSG_KLINE = "KLINE";/* KLINE */
|
|
char *TOK_KLINE = "W";/* 87 */
|
|
char *MSG_UNKLINE = "UNKLINE";/* UNKLINE */
|
|
char *TOK_UNKLINE = "X";/* 88 */
|
|
char *MSG_RAKILL = "RAKILL";/* RAKILL */
|
|
char *TOK_RAKILL = "Y";/* 89 */
|
|
char *MSG_GNOTICE = "GNOTICE";/* GNOTICE */
|
|
char *TOK_GNOTICE = "Z";/* 90 */
|
|
char *MSG_GOPER = "GOPER";/* GOPER */
|
|
char *TOK_GOPER = "[";/* 91 */
|
|
char *MSG_GLOBOPS = "GLOBOPS";/* GLOBOPS */
|
|
char *TOK_GLOBOPS = "]";/* 93 */
|
|
char *MSG_LOCOPS = "LOCOPS";/* LOCOPS */
|
|
char *TOK_LOCOPS = "^";/* 94 */
|
|
char *MSG_PROTOCTL = "PROTOCTL";/* PROTOCTL */
|
|
char *TOK_PROTOCTL = "_";/* 95 */
|
|
char *MSG_WATCH = "WATCH";/* WATCH */
|
|
char *TOK_WATCH = "`";/* 96 */
|
|
char *MSG_TRACE = "TRACE";/* TRAC */
|
|
char *TOK_TRACE = "b";/* 97 */
|
|
char *MSG_SQLINE = "SQLINE";/* SQLINE */
|
|
char *TOK_SQLINE = "c";/* 98 */
|
|
char *MSG_UNSQLINE = "UNSQLINE";/* UNSQLINE */
|
|
char *TOK_UNSQLINE = "d";/* 99 */
|
|
char *MSG_SVSNICK = "SVSNICK";/* SVSNICK */
|
|
char *TOK_SVSNICK = "e";/* 100 */
|
|
char *MSG_SVSNOOP = "SVSNOOP";/* SVSNOOP */
|
|
char *TOK_SVSNOOP = "f";/* 101 */
|
|
char *MSG_IDENTIFY = "IDENTIFY";/* IDENTIFY */
|
|
char *TOK_IDENTIFY = "g";/* 102 */
|
|
char *MSG_SVSKILL = "SVSKILL";/* SVSKILL */
|
|
char *TOK_SVSKILL = "h";/* 103 */
|
|
char *MSG_NICKSERV = "NICKSERV";/* NICKSERV */
|
|
char *MSG_NS = "NS";
|
|
char *TOK_NICKSERV = "i";/* 104 */
|
|
char *MSG_CHANSERV = "CHANSERV";/* CHANSERV */
|
|
char *MSG_CS = "CS";
|
|
char *TOK_CHANSERV = "j";/* 105 */
|
|
char *MSG_OPERSERV = "OPERSERV";/* OPERSERV */
|
|
char *MSG_OS = "OS";
|
|
char *TOK_OPERSERV = "k";/* 106 */
|
|
char *MSG_MEMOSERV = "MEMOSERV";/* MEMOSERV */
|
|
char *MSG_MS = "MS";
|
|
char *TOK_MEMOSERV = "l";/* 107 */
|
|
char *MSG_SERVICES = "SERVICES";/* SERVICES */
|
|
char *TOK_SERVICES = "m";/* 108 */
|
|
char *MSG_SVSMODE = "SVSMODE";/* SVSMODE */
|
|
char *TOK_SVSMODE = "n";/* 109 */
|
|
char *MSG_SAMODE = "SAMODE";/* SAMODE */
|
|
char *TOK_SAMODE = "o";/* 110 */
|
|
char *MSG_CHATOPS = "CHATOPS";/* CHATOPS */
|
|
char *TOK_CHATOPS = "p";/* 111 */
|
|
char *MSG_ZLINE = "ZLINE";/* ZLINE */
|
|
char *TOK_ZLINE = "q";/* 112 */
|
|
char *MSG_UNZLINE = "UNZLINE";/* UNZLINE */
|
|
char *TOK_UNZLINE = "r";/* 113 */
|
|
char *MSG_HELPSERV = "HELPSERV";/* HELPSERV */
|
|
char *MSG_HS = "HS";
|
|
char *TOK_HELPSERV = "s";/* 114 */
|
|
char *MSG_RULES = "RULES";/* RULES */
|
|
char *TOK_RULES = "t";/* 115 */
|
|
char *MSG_MAP = "MAP";/* MAP */
|
|
char *TOK_MAP = "u";/* 117 */
|
|
char *MSG_SVS2MODE = "SVS2MODE";/* SVS2MODE */
|
|
char *TOK_SVS2MODE = "v";/* 118 */
|
|
char *MSG_DALINFO = "DALINFO";/* dalinfo */
|
|
char *TOK_DALINFO = "w";/* 119 */
|
|
char *MSG_ADMINCHAT = "ADCHAT";/* Admin chat */
|
|
char *TOK_ADMINCHAT = "x";/* 120 */
|
|
char *MSG_MKPASSWD = "MKPASSWD";/* MKPASSWD */
|
|
char *TOK_MKPASSWD = "y";/* 121 */
|
|
char *MSG_ADDLINE = "ADDLINE";/* ADDLINE */
|
|
char *TOK_ADDLINE = "z";/* 122 */
|
|
char *MSG_GLINE = "GLINE";/* The awesome g-line */
|
|
char *TOK_GLINE = "}";/* 125 */
|
|
char *MSG_SJOIN = "SJOIN";
|
|
char *TOK_SJOIN = "~";
|
|
char *MSG_SETHOST = "SETHOST";/* sethost */
|
|
char *TOK_SETHOST = "AA";/* 127 4ever !;) */
|
|
char *MSG_NACHAT = "NACHAT";/* netadmin chat */
|
|
char *TOK_NACHAT = "AC";/* *beep* */
|
|
char *MSG_SETIDENT = "SETIDENT";
|
|
char *TOK_SETIDENT = "AD";
|
|
char *MSG_SETNAME = "SETNAME";/* set GECOS */
|
|
char *TOK_SETNAME = "AE";/* its almost unreeaaall... */
|
|
char *MSG_LAG = "LAG";/* Lag detect */
|
|
char *TOK_LAG = "AF";/* a or ? */
|
|
char *MSG_STATSERV = "STATSERV";/* alias */
|
|
char *TOK_STATSERV = "AH";
|
|
char *MSG_KNOCK = "KNOCK";
|
|
char *TOK_KNOCK = "AI";
|
|
char *MSG_CREDITS = "CREDITS";
|
|
char *TOK_CREDITS = "AJ";
|
|
char *MSG_LICENSE = "LICENSE";
|
|
char *TOK_LICENSE = "AK";
|
|
char *MSG_CHGHOST = "CHGHOST";
|
|
char *TOK_CHGHOST = "AL";
|
|
char *MSG_RPING = "RPING";
|
|
char *TOK_RPING = "AM";
|
|
char *MSG_RPONG = "RPONG";
|
|
char *TOK_RPONG = "AN";
|
|
char *MSG_NETINFO = "NETINFO";
|
|
char *TOK_NETINFO = "AO";
|
|
char *MSG_SENDUMODE = "SENDUMODE";
|
|
char *TOK_SENDUMODE = "AP";
|
|
char *MSG_ADDMOTD = "ADDMOTD";
|
|
char *TOK_ADDMOTD = "AQ";
|
|
char *MSG_ADDOMOTD = "ADDOMOTD";
|
|
char *TOK_ADDOMOTD = "AR";
|
|
char *MSG_SVSMOTD = "SVSMOTD";
|
|
char *TOK_SVSMOTD = "AS";
|
|
char *MSG_SMO = "SMO";
|
|
char *TOK_SMO = "AU";
|
|
char *MSG_OPERMOTD = "OPERMOTD";
|
|
char *TOK_OPERMOTD = "AV";
|
|
char *MSG_TSCTL = "TSCTL";
|
|
char *TOK_TSCTL = "AW";
|
|
char *MSG_SVSJOIN = "SVSJOIN";
|
|
char *TOK_SVSJOIN = "BR";
|
|
char *MSG_SAJOIN = "SAJOIN";
|
|
char *TOK_SAJOIN = "AX";
|
|
char *MSG_SVSPART = "SVSPART";
|
|
char *TOK_SVSPART = "BT";
|
|
char *MSG_SAPART = "SAPART";
|
|
char *TOK_SAPART = "AY";
|
|
char *MSG_CHGIDENT = "CHGIDENT";
|
|
char *TOK_CHGIDENT = "AZ";
|
|
char *MSG_SWHOIS = "SWHOIS";
|
|
char *TOK_SWHOIS = "BA";
|
|
char *MSG_SVSO = "SVSO";
|
|
char *TOK_SVSO = "BB";
|
|
char *MSG_SVSFLINE = "SVSFLINE";
|
|
char *TOK_SVSFLINE = "BC";
|
|
char *MSG_TKL = "TKL";
|
|
char *TOK_TKL = "BD";
|
|
char *MSG_VHOST = "VHOST";
|
|
char *TOK_VHOST = "BE";
|
|
char *MSG_BOTMOTD = "BOTMOTD";
|
|
char *TOK_BOTMOTD = "BF";
|
|
char *MSG_REMGLINE = "REMGLINE";/* remove g-line */
|
|
char *TOK_REMGLINE = "BG";
|
|
char *MSG_HTM = "HTM";
|
|
char *TOK_HTM = "BH";
|
|
char *MSG_UMODE2 = "UMODE2";
|
|
char *TOK_UMODE2 = "|";
|
|
char *MSG_DCCDENY = "DCCDENY";
|
|
char *TOK_DCCDENY = "BI";
|
|
char *MSG_UNDCCDENY = "UNDCCDENY";
|
|
char *TOK_UNDCCDENY = "BJ";
|
|
char *MSG_CHGNAME = "CHGNAME";
|
|
char *MSG_SVSNAME = "SVSNAME";
|
|
char *TOK_CHGNAME = "BK";
|
|
char *MSG_SHUN = "SHUN";
|
|
char *TOK_SHUN = "BL";
|
|
char *MSG_NEWJOIN = "NEWJOIN";/* For CR Java Chat */
|
|
char *MSG_POST = "POST";
|
|
char *TOK_POST = "BN";
|
|
char *MSG_INFOSERV = "INFOSERV";
|
|
char *MSG_IS = "IS";
|
|
char *TOK_INFOSERV = "BO";
|
|
char *MSG_BOTSERV = "BOTSERV";
|
|
char *TOK_BOTSERV = "BS";
|
|
char *MSG_CYCLE = "CYCLE";
|
|
char *TOK_CYCLE = "BP";
|
|
char *MSG_MODULE = "MODULE";
|
|
char *TOK_MODULE = "BQ";
|
|
char *MSG_SENDSNO = "SENDSNO";
|
|
char *TOK_SENDSNO = "Ss";
|
|
char *MSG_EOS = "EOS";
|
|
char *TOK_EOS = "ES";
|
|
|
|
/* Umodes */
|
|
#define UMODE_FAILOP 0x00200000
|
|
#define UMODE_SERVNOTICE 0x00400000
|
|
#define UMODE_NOCTCP 0x00800000
|
|
#define UMODE_WEBTV 0x01000000
|
|
#define UMODE_WHOIS 0x02000000
|
|
#define UMODE_SECURE 0x04000000
|
|
#define UMODE_VICTIM 0x08000000
|
|
#define UMODE_HIDEOPER 0x10000000
|
|
#define UMODE_SETHOST 0x20000000
|
|
#define UMODE_STRIPBADWORDS 0x40000000
|
|
#define UMODE_HIDEWHOIS 0x80000000
|
|
|
|
/* Cmodes */
|
|
#define CMODE_NOKICKS 0x02000000
|
|
#define CMODE_MODREG 0x04000000
|
|
#define CMODE_STRIPBADWORDS 0x08000000
|
|
#define CMODE_NOCTCP 0x10000000
|
|
#define CMODE_AUDITORIUM 0x20000000
|
|
#define CMODE_ONLYSECURE 0x40000000
|
|
#define CMODE_NONICKCHANGE 0x80000000
|
|
|
|
static void m_server( char *origin, char **argv, int argc, int srv );
|
|
static void m_umode2( char *origin, char **argv, int argc, int srv );
|
|
static void m_svsmode( char *origin, char **argv, int argc, int srv );
|
|
static void m_nick( char *origin, char **argv, int argc, int srv );
|
|
static void m_eos( char *origin, char **argv, int argc, int srv );
|
|
static void m_sjoin( char *origin, char **argv, int argc, int srv );
|
|
static void m_smo( char *origin, char **argv, int argc, int srv );
|
|
static void m_swhois( char *origin, char **argv, int argc, int srv );
|
|
static void m_tkl( char *origin, char **argv, int argc, int srv );
|
|
|
|
ProtocolInfo protocol_info =
|
|
{
|
|
/* Protocol options required by this IRCd */
|
|
PROTOCOL_SJOIN,
|
|
/* Protocol options negotiated at link by this IRCd */
|
|
PROTOCOL_TOKEN | PROTOCOL_NICKIP | PROTOCOL_NICKv2 | PROTOCOL_SJ3,
|
|
/* Features supported by this IRCd */
|
|
FEATURE_UMODECLOAK,
|
|
/* Max host length */
|
|
128,
|
|
/* Max password length */
|
|
32,
|
|
/* Max nick length */
|
|
30,
|
|
/* Max user length */
|
|
10,
|
|
/* Max real name length */
|
|
50,
|
|
/* Max channel name length */
|
|
32,
|
|
/* Max topic length */
|
|
307,
|
|
/* Default operator modes for NeoStats service bots */
|
|
"+OwoSq",
|
|
/* Default channel mode for NeoStats service bots */
|
|
"+o",
|
|
};
|
|
|
|
irc_cmd cmd_list[] =
|
|
{
|
|
/*Message Token Function usage */
|
|
{&MSG_SERVER, &TOK_SERVER, m_server, 0},
|
|
{&MSG_UMODE2, &TOK_UMODE2, m_umode2, 0},
|
|
{&MSG_SVSMODE, &TOK_SVSMODE, m_svsmode, 0},
|
|
{&MSG_SVS2MODE, &TOK_SVS2MODE, m_svsmode, 0},
|
|
{&MSG_NICK, &TOK_NICK, m_nick, 0},
|
|
{&MSG_SJOIN, &TOK_SJOIN, m_sjoin, 0},
|
|
{&MSG_SWHOIS, &TOK_SWHOIS, m_swhois, 0},
|
|
{&MSG_SMO, &TOK_SMO, m_smo, 0},
|
|
{&MSG_EOS, &TOK_EOS, m_eos, 0},
|
|
{&MSG_TKL, &TOK_TKL, m_tkl, 0},
|
|
IRC_CMD_END()
|
|
};
|
|
|
|
mode_init chan_umodes[] =
|
|
{
|
|
{'h', CUMODE_HALFOP, 0, '%'},
|
|
{'a', CUMODE_CHANPROT, 0, '*'},
|
|
{'q', CUMODE_CHANOWNER, 0, '~'},
|
|
MODE_INIT_END()
|
|
};
|
|
|
|
mode_init chan_modes[] =
|
|
{
|
|
{'r', CMODE_RGSTR, 0, 0},
|
|
{'R', CMODE_RGSTRONLY, 0, 0},
|
|
{'c', CMODE_NOCOLOR, 0, 0},
|
|
{'O', CMODE_OPERONLY, 0, 0},
|
|
{'A', CMODE_ADMONLY, 0, 0},
|
|
{'L', CMODE_LINK, MODEPARAM, 0},
|
|
{'Q', CMODE_NOKICKS, 0, 0},
|
|
{'S', CMODE_STRIP, 0, 0},
|
|
{'e', CMODE_EXCEPT, MODEPARAM, 0},
|
|
{'K', CMODE_NOKNOCK, 0, 0},
|
|
{'V', CMODE_NOINVITE, 0, 0},
|
|
{'f', CMODE_FLOODLIMIT, MODEPARAM, 0},
|
|
{'M', CMODE_MODREG, 0, 0},
|
|
{'G', CMODE_STRIPBADWORDS, 0, 0},
|
|
{'C', CMODE_NOCTCP, 0, 0},
|
|
{'u', CMODE_AUDITORIUM, 0, 0},
|
|
{'z', CMODE_ONLYSECURE, 0, 0},
|
|
{'N', CMODE_NONICKCHANGE, 0, 0},
|
|
MODE_INIT_END()
|
|
};
|
|
|
|
mode_init user_umodes[] =
|
|
{
|
|
{'S', UMODE_SERVICES, 0, 0},
|
|
{'N', UMODE_NETADMIN, 0, 0},
|
|
{'a', UMODE_SADMIN, 0, 0},
|
|
{'A', UMODE_ADMIN, 0, 0},
|
|
{'C', UMODE_COADMIN, 0, 0},
|
|
{'O', UMODE_LOCOP, 0, 0},
|
|
{'r', UMODE_REGNICK, 0, 0},
|
|
{'w', UMODE_WALLOP, 0, 0},
|
|
{'g', UMODE_FAILOP, 0, 0},
|
|
{'h', UMODE_HELPOP, 0, 0},
|
|
{'s', UMODE_SERVNOTICE, 0, 0},
|
|
{'q', UMODE_KIX, 0, 0},
|
|
{'B', UMODE_BOT, 0, 0},
|
|
{'d', UMODE_DEAF, 0, 0},
|
|
{'R', UMODE_RGSTRONLY, 0, 0},
|
|
{'T', UMODE_NOCTCP, 0, 0},
|
|
{'V', UMODE_WEBTV, 0, 0},
|
|
{'p', UMODE_HIDEWHOIS, 0, 0},
|
|
{'H', UMODE_HIDEOPER, 0, 0},
|
|
{'G', UMODE_STRIPBADWORDS, 0, 0},
|
|
{'t', UMODE_SETHOST, 0, 0},
|
|
{'x', UMODE_HIDE, 0, 0},
|
|
/*{'b', UMODE_CHATOP, 0, 0},*/
|
|
{'W', UMODE_WHOIS, 0, 0},
|
|
{'z', UMODE_SECURE, 0, 0},
|
|
{'v', UMODE_VICTIM, 0, 0},
|
|
MODE_INIT_END()
|
|
};
|
|
|
|
static const char Base64[] =
|
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
static const char Pad64 = '=';
|
|
|
|
int b64_decode( char const *src, unsigned char *target, int targsize )
|
|
{
|
|
int tarindex, state, ch;
|
|
char *pos;
|
|
|
|
state = 0;
|
|
tarindex = 0;
|
|
|
|
while( ( ch = *src++ ) != '\0' )
|
|
{
|
|
if( isspace( ch ) ) /* Skip whitespace anywhere. */
|
|
continue;
|
|
|
|
if( ch == Pad64 )
|
|
break;
|
|
|
|
pos = strchr( Base64, ch );
|
|
if( pos == 0 ) /* A non-base64 character. */
|
|
return( -1 );
|
|
|
|
switch( state )
|
|
{
|
|
case 0:
|
|
if( target )
|
|
{
|
|
if( tarindex >= targsize )
|
|
return( -1 );
|
|
target[tarindex] = ( unsigned char )( pos - Base64 ) << 2;
|
|
}
|
|
state = 1;
|
|
break;
|
|
case 1:
|
|
if( target )
|
|
{
|
|
if( tarindex + 1 >= targsize )
|
|
return( -1 );
|
|
target[tarindex] |= ( pos - Base64 ) >> 4;
|
|
target[tarindex+1] = ( unsigned char )( ( pos - Base64 ) & 0x0f )
|
|
<< 4 ;
|
|
}
|
|
tarindex++;
|
|
state = 2;
|
|
break;
|
|
case 2:
|
|
if( target )
|
|
{
|
|
if( tarindex + 1 >= targsize )
|
|
return( -1 );
|
|
target[tarindex] |= ( pos - Base64 ) >> 2;
|
|
target[tarindex+1] = ( unsigned char )( ( pos - Base64 ) & 0x03 )
|
|
<< 6;
|
|
}
|
|
tarindex++;
|
|
state = 3;
|
|
break;
|
|
case 3:
|
|
if( target )
|
|
{
|
|
if( tarindex >= targsize )
|
|
return( -1 );
|
|
target[tarindex] |= ( pos - Base64 );
|
|
}
|
|
tarindex++;
|
|
state = 0;
|
|
break;
|
|
default:
|
|
abort();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* We are done decoding Base-64 chars. Let's see if we ended
|
|
* on a byte boundary, and/or with erroneous trailing characters.
|
|
*/
|
|
|
|
if( ch == Pad64 )
|
|
{ /* We got a pad char. */
|
|
ch = *src++; /* Skip it, get next. */
|
|
switch( state )
|
|
{
|
|
case 0: /* Invalid = in first position */
|
|
case 1: /* Invalid = in second position */
|
|
return( -1 );
|
|
|
|
case 2: /* Valid, means one byte of info */
|
|
/* Skip any number of spaces. */
|
|
for( ( void )NULL; ch != '\0'; ch = *src++ )
|
|
if( !isspace( ch ) )
|
|
break;
|
|
/* Make sure there is another trailing = sign. */
|
|
if( ch != Pad64 )
|
|
return( -1 );
|
|
ch = *src++; /* Skip the = */
|
|
/* Fall through to "single trailing =" case. */
|
|
/* FALLTHROUGH */
|
|
|
|
case 3: /* Valid, means two bytes of info */
|
|
/*
|
|
* We know this char is an =. Is there anything but
|
|
* whitespace after it?
|
|
*/
|
|
for( ( void )NULL; ch != '\0'; ch = *src++ )
|
|
if( !isspace( ch ) )
|
|
return( -1 );
|
|
|
|
/*
|
|
* Now make sure for cases 2 and 3 that the "extra"
|
|
* bits that slopped past the last full byte were
|
|
* zeros. If we don't check them, they become a
|
|
* subliminal channel.
|
|
*/
|
|
if( target && target[tarindex] != 0 )
|
|
return( -1 );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* We ended by seeing the end of the string. Make sure we
|
|
* have no partial bytes lying around.
|
|
*/
|
|
if( state != 0 )
|
|
return( -1 );
|
|
}
|
|
|
|
return( tarindex );
|
|
}
|
|
|
|
int decode_ip( const char *buf )
|
|
{
|
|
size_t len = strlen( buf );
|
|
char targ[25];
|
|
struct in_addr ia;
|
|
|
|
b64_decode( buf, (unsigned char *)targ, 25 );
|
|
ia = *( struct in_addr * )targ;
|
|
if( len == 8 ) /* IPv4 */
|
|
return ia.s_addr;
|
|
return 0;
|
|
}
|
|
|
|
void send_server_connect( const char *name, const int numeric, const char *infoline, const char *pass, const unsigned long tsboot, const unsigned long tslink )
|
|
{
|
|
/* PROTOCTL NOQUIT TOKEN NICKv2 SJOIN SJOIN2 UMODE2 VL SJ3 NS SJB64 TKLEXT NICKIP CHANMODES=be,kfL,l,psmntirRcOAQKVGCuzNSMT */
|
|
send_cmd( "%s TOKEN NICKv2 SJOIN SJOIN2 UMODE2 VL SJ3 NICKIP VHP", MSGTOK( PROTOCTL ) );
|
|
send_cmd( "%s %s", MSGTOK( PASS ), pass );
|
|
send_cmd( "%s %s %d :U0-*-%d %s", MSGTOK( SERVER ), name, 1, numeric, infoline );
|
|
}
|
|
|
|
void send_sjoin( const char *source, const char *target, const char *chan, const unsigned long ts )
|
|
{
|
|
send_cmd( ":%s %s %lu %s + :%s", source, MSGTOK( SJOIN ), ts, chan, target );
|
|
}
|
|
|
|
void send_nick( const char *nick, const unsigned long ts, const char *newmode, const char *ident, const char *host, const char *server, const char *realname )
|
|
{
|
|
send_cmd( "%s %s 1 %lu %s %s %s 0 %s * :%s", MSGTOK( NICK ), nick, ts, ident, host, server, newmode, realname );
|
|
}
|
|
|
|
void send_smo( const char *source, const char *umodetarget, const char *msg )
|
|
{
|
|
send_cmd( ":%s %s %s :%s", source, MSGTOK( SMO ), umodetarget, msg );
|
|
}
|
|
|
|
void send_swhois( const char *source, const char *target, const char *swhois )
|
|
{
|
|
send_cmd( "%s %s :%s", MSGTOK( SWHOIS ), target, swhois );
|
|
}
|
|
|
|
/* akill is gone in the latest Unreals, so we set Glines instead */
|
|
void send_akill( const char *source, const char *host, const char *ident, const char *setby, const unsigned long length, const char *reason, const unsigned long ts )
|
|
{
|
|
send_cmd( ":%s %s + G %s %s %s %lu %lu :%s", source, MSGTOK( TKL ), ident, host, setby, ( ts + length ), ts, reason );
|
|
}
|
|
|
|
void send_rakill( const char *source, const char *host, const char *ident )
|
|
{
|
|
send_cmd( ":%s %s - G %s %s %s", source, MSGTOK( TKL ), ident, host, source );
|
|
}
|
|
|
|
void send_svstime( const char *source, const unsigned long ts )
|
|
{
|
|
send_cmd( ":%s %s SVSTIME %lu", source, MSGTOK( TSCTL ), ts );
|
|
}
|
|
|
|
/** m_server
|
|
*
|
|
* process SERVER command
|
|
* RX:
|
|
* SERVER irc.foonet.com 1 :U2305-FinWXOoZE-1 FooNet Server
|
|
* Format:
|
|
* SERVER servername hopcount numeric :U<protocol>-flags-numeric serverdesc
|
|
*
|
|
* @param origin source of message (user/server)
|
|
* @param argv list of message parameters
|
|
* argv[0] = servername
|
|
* argv[1] = hopcount
|
|
* argv[2] = numeric
|
|
* argv[3] = serverinfo
|
|
* on old protocols, serverinfo is argv[2], and numeric is left out
|
|
* @param argc parameter count
|
|
* @param srv command flag
|
|
*
|
|
* @return none
|
|
*/
|
|
|
|
static void m_server( char *origin, char **argv, int argc, int srv )
|
|
{
|
|
char *s = argv[argc-1];
|
|
if( *origin== 0 )
|
|
{
|
|
/* server desc from uplink includes extra info so we need to
|
|
strip protocol, flags and numeric. We can use the first
|
|
space to do this*/
|
|
while( *s != ' ' )
|
|
s++;
|
|
/* Strip the now leading space */
|
|
s++;
|
|
}
|
|
if( argc > 3 )
|
|
{
|
|
do_server( argv[0], origin, argv[1], argv[2], s, srv );
|
|
}
|
|
else
|
|
{
|
|
do_server( argv[0], origin, argv[1], NULL, s, srv );
|
|
}
|
|
}
|
|
|
|
/** m_svsmode
|
|
*
|
|
* process SVSMODE command
|
|
* RX:
|
|
* TODO
|
|
* Format:
|
|
* TODO
|
|
*
|
|
* @param origin source of message (user/server)
|
|
* @param argv list of message parameters
|
|
* argv[0] - username to change mode for
|
|
* argv[1] - modes to change
|
|
* argv[2] - Service Stamp( if mode == d )
|
|
* @param argc parameter count
|
|
* @param srv command flag
|
|
*
|
|
* @return none
|
|
*/
|
|
|
|
static void m_svsmode( char *origin, char **argv, int argc, int srv )
|
|
{
|
|
if( argv[0][0] == '#' )
|
|
{
|
|
do_svsmode_channel( origin, argv, argc );
|
|
}
|
|
else
|
|
{
|
|
do_svsmode_user( argv[0], argv[1], argv[2] );
|
|
}
|
|
}
|
|
|
|
/** m_umode2
|
|
*
|
|
* process UMODE2 command
|
|
* RX:
|
|
* TODO
|
|
* Format:
|
|
* TODO
|
|
*
|
|
* @param origin source of message (user/server)
|
|
* @param argv list of message parameters
|
|
* argv[0] - modes to change
|
|
* @param argc parameter count
|
|
* @param srv command flag
|
|
*
|
|
* @return none
|
|
*/
|
|
|
|
static void m_umode2( char *origin, char **argv, int argc, int srv )
|
|
{
|
|
do_mode_user( origin, argv[0] );
|
|
}
|
|
|
|
/** m_nick
|
|
*
|
|
* process NICK command
|
|
* RX:
|
|
* NICK Mark 1 1089324634 mark 127.0.0.1 irc.foonet.com 0 +iowghaAxN F72CBABD.ABE021B4.D9E4BB78.IP fwAAAQ== :Mark
|
|
* NICK Mark 1 1089324634 mark 127.0.0.1 irc.foonet.com 0 +iowghaAxN F72CBABD.ABE021B4.D9E4BB78.IP :Mark
|
|
* Format:
|
|
* NICK nick hop TS user host uplink servicestamp umode vhost [base64 IP] :realname
|
|
*
|
|
* @param origin source of message (user/server)
|
|
* @param argv list of message parameters
|
|
* argv[0] = nickname
|
|
* if from new client
|
|
* argv[1] = nick password
|
|
* if from server:
|
|
* argv[1] = hopcount
|
|
* argv[2] = timestamp
|
|
* argv[3] = username
|
|
* argv[4] = hostname
|
|
* argv[5] = servername
|
|
* if NICK version 1:
|
|
* argv[6] = servicestamp
|
|
* argv[7] = info
|
|
* if NICK version 2:
|
|
* argv[6] = servicestamp
|
|
* argv[7] = umodes
|
|
* argv[8] = virthost, * if none
|
|
* argv[9] = info
|
|
* if NICKIP:
|
|
* argv[9] = ip
|
|
* argv[10] = info
|
|
* @param argc parameter count
|
|
* @param srv command flag
|
|
*
|
|
* @return none
|
|
*/
|
|
|
|
static void m_nick( char *origin, char **argv, int argc, int srv )
|
|
{
|
|
if( !srv )
|
|
{
|
|
if( ircd_srv.protocol & PROTOCOL_NICKv2 )
|
|
{
|
|
if( ircd_srv.protocol & PROTOCOL_NICKIP )
|
|
{
|
|
char ip[25];
|
|
|
|
ircsnprintf( ip, 25, "%d", ntohl( decode_ip( argv[9] ) ) );
|
|
do_nick( argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
|
|
ip, argv[6], argv[7], argv[8], argv[10], NULL, NULL );
|
|
}
|
|
else
|
|
{
|
|
do_nick( argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
|
|
NULL, argv[6], argv[7], argv[8], argv[9], NULL, NULL );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
do_nick( argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
|
|
NULL, argv[6], NULL, NULL, argv[9], NULL, NULL );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
do_nickchange( origin, argv[0], NULL );
|
|
}
|
|
}
|
|
|
|
/** m_eos
|
|
*
|
|
* process EOS command
|
|
* RX:
|
|
* :irc.foonet.com EOS
|
|
* Format:
|
|
* :origin EOS
|
|
*
|
|
* @param origin source of message (user/server)
|
|
* @param argv list of message parameters
|
|
* @param argc parameter count
|
|
* @param srv command flag
|
|
*
|
|
* @return none
|
|
*/
|
|
|
|
static void m_eos( char *origin, char **argv, int argc, int srv )
|
|
{
|
|
do_eos( origin );
|
|
}
|
|
|
|
/** m_sjoin
|
|
*
|
|
* process SJOIN command
|
|
* RX:
|
|
* SJOIN 1073861298 #services + <none> :Mark
|
|
* Format:
|
|
* SJOIN creationtime chname modebuf parabuf :member list
|
|
*
|
|
* @param origin source of message (user/server)
|
|
* @param argv list of message parameters
|
|
* argv[0] = channel timestamp
|
|
* char *argv[], pvar[MAXMODEPARAMS][MODEBUFLEN + 3];
|
|
* argv[1] = channel name
|
|
* "ts chname :"
|
|
* if( argc == 3 )
|
|
* argv[2] = nick names + modes - all in one parameter
|
|
* "ts chname modebuf :"
|
|
* "ts chname :"@/"""name" OPT_SJ3
|
|
* if( argc == 4 )
|
|
* argv[2] = channel modes
|
|
* argv[3] = nick names + modes - all in one parameter
|
|
* "ts chname modebuf parabuf :"
|
|
* if( argc > 4 )
|
|
* argv[2] = channel modes
|
|
* argv[3 to argc - 2] = mode parameters
|
|
* argv[argc - 1] = nick names + modes
|
|
* "ts parabuf :parv[parc - 1]" OPT_SJOIN | OPT_SJ3
|
|
* @param argc parameter count
|
|
* @param srv command flag
|
|
*
|
|
* @return none
|
|
*/
|
|
|
|
static void m_sjoin( char *origin, char **argv, int argc, int srv )
|
|
{
|
|
do_sjoin( argv[0], argv[1], ( ( argc >= 4 ) ? argv[2] : "" ), origin, argv, argc );
|
|
}
|
|
|
|
/** m_swhois
|
|
*
|
|
* process SWHOIS command
|
|
* RX:
|
|
* TODO
|
|
* Format:
|
|
* TODO
|
|
*
|
|
* @param origin source of message (user/server)
|
|
* @param argv list of message parameters
|
|
* argv[0] = nickname
|
|
* argv[1] = new swhois
|
|
* @param argc parameter count
|
|
* @param srv command flag
|
|
*
|
|
* @return none
|
|
*/
|
|
|
|
static void m_swhois( char *origin, char **argv, int argc, int srv )
|
|
{
|
|
do_swhois( argv[0], argv[1] );
|
|
}
|
|
|
|
/** m_smo
|
|
*
|
|
* process SMO command
|
|
* RX:
|
|
* :irc.foonet.com SMO o :(\1link\1) Link irc.foonet.com -> stats.neostats.net[@127.0.0.1.2722] established
|
|
* :irc.foonet.com SMO o :\1(sync)\1 Possible negative TS split at link stats.neostats.net (1128112841 - 1128112842 = -1)
|
|
* :irc.foonet.com SMO o :\1(sync)\1 Link stats.neostats.net -> irc.foonet.com is now synced [secs: 2 recv: 0.825 sent: 0.657]
|
|
* Format:
|
|
* :origin SMO ? :message
|
|
*
|
|
* @param origin source of message (user/server)
|
|
* @param argv list of message parameters
|
|
* @param argc parameter count
|
|
* @param srv command flag
|
|
*
|
|
* @return none
|
|
*/
|
|
|
|
static void m_smo( char *origin, char **argv, int argc, int srv )
|
|
{
|
|
/* TODO */
|
|
}
|
|
|
|
/** m_tkl
|
|
*
|
|
* process TKL command
|
|
* RX:
|
|
* TODO
|
|
* Format:
|
|
* :server BD + G * mask setter 1074811259 1074206459 :reason
|
|
* :server BD + Z * mask setter 0 1070062390 :reason
|
|
*
|
|
* @param origin source of message (user/server)
|
|
* @param argv list of message parameters
|
|
* argv[0] +|-
|
|
* argv[1] G
|
|
* argv[2] user
|
|
* argv[3] host
|
|
* argv[4] setby
|
|
* argv[5] expire_at
|
|
* argv[6] set_at
|
|
* argv[7] reason
|
|
* @param argc parameter count
|
|
* @param srv command flag
|
|
*
|
|
* @return none
|
|
*/
|
|
|
|
static void m_tkl( char *origin, char **argv, int argc, int srv )
|
|
{
|
|
do_tkl( argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7] );
|
|
}
|