Added supper handle file handle_irc_common.cpp/h for all IRC based protocols

This commit is contained in:
Pelish 2007-08-12 20:18:14 +00:00
parent c361a084f7
commit b25ccaf642
11 changed files with 426 additions and 380 deletions

View file

@ -1,7 +1,7 @@
[Project]
FileName=PvPGN.dev
Name=PvPGN
UnitCount=272
UnitCount=274
Type=0
Ver=1
ObjFiles=
@ -2767,3 +2767,23 @@ Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit273]
FileName=..\src\bnetd\handle_irc_common.h
CompileCpp=1
Folder=bnetd/Header Files
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit274]
FileName=..\src\bnetd\handle_irc_common.cpp
CompileCpp=1
Folder=bnetd/Source Files
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=

View file

@ -1,7 +1,7 @@
[Project]
FileName=PvPGNConsole.dev
Name=PvPGNConsole
UnitCount=266
UnitCount=268
Type=1
Ver=1
ObjFiles=
@ -2707,3 +2707,23 @@ Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit267]
FileName=..\src\bnetd\handle_irc_common.h
CompileCpp=1
Folder=bnetd/Header Files
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit268]
FileName=..\src\bnetd\handle_irc_common.cpp
CompileCpp=1
Folder=bnetd/Source Files
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=

View file

@ -14,7 +14,7 @@ bnetd_SOURCES = account.cpp account_wrap.cpp adbanner.cpp alias_command.cpp anon
sql_mysql.cpp sql_odbc.cpp sql_pgsql.cpp sql_sqlite3.cpp storage.cpp \
storage_file.cpp storage_sql.cpp support.cpp team.cpp tick.cpp timer.cpp topic.cpp \
tournament.cpp tracker.cpp udptest_send.cpp versioncheck.cpp watch.cpp \
storage_sql2.cpp sql_common.cpp handle_wol.cpp
storage_sql2.cpp sql_common.cpp handle_wol.cpp handle_irc_common.cpp
bnetd_LDADD = $(top_builddir)/src/common/libcommon.a \
$(top_builddir)/src/compat/libcompat.a \
@ -33,4 +33,4 @@ noinst_HEADERS = account.h account_wrap.h adbanner.h alias_command.h \
sql_dbcreator.h sql_mysql.h sql_odbc.h sql_pgsql.h sql_sqlite3.h \
storage_file.h storage.h storage_sql.h support.h team.h tick.h \
timer.h topic.h tournament.h udptest_send.h versioncheck.h watch.h \
tracker.h storage_sql2.h sql_common.h handle_wol.h
tracker.h storage_sql2.h sql_common.h handle_wol.h handle_irc_common.h

View file

@ -70,6 +70,7 @@ typedef enum
conn_class_file,
conn_class_bot,
conn_class_telnet,
conn_class_ircinit, /* IRC based protocol INIT*/
conn_class_irc, /* Internet Relay Chat */
conn_class_wol, /* Westwood IRC */
conn_class_wserv, /* Westwood servserv */

View file

@ -112,7 +112,7 @@ static const t_irc_command_table_row irc_log_command_table[] =
};
static int handle_irc_con_command(t_connection * conn, char const * command, int numparams, char ** params, char * text)
extern int handle_irc_con_command(t_connection * conn, char const * command, int numparams, char ** params, char * text)
{
t_irc_command_table_row const *p;
@ -125,7 +125,7 @@ static int handle_irc_con_command(t_connection * conn, char const * command, int
return -1;
}
static int handle_irc_log_command(t_connection * conn, char const * command, int numparams, char ** params, char * text)
extern int handle_irc_log_command(t_connection * conn, char const * command, int numparams, char ** params, char * text)
{
t_irc_command_table_row const *p;
@ -138,139 +138,6 @@ static int handle_irc_log_command(t_connection * conn, char const * command, int
return -1;
}
static int handle_irc_line(t_connection * conn, char const * ircline)
{
/* [:prefix] <command> [[param1] [param2] ... [paramN]] [:<text>] */
char * line; /* copy of ircline */
char * prefix = NULL; /* optional; mostly NULL */
char * command; /* mandatory */
char ** params = NULL; /* optional (array of params) */
char * text = NULL; /* optional */
char * bnet_command = NULL; /* amadeo: used for battle.net.commands */
int unrecognized_before = 0;
int linelen; /* amadeo: counter for stringlenghts */
int numparams = 0;
char * tempparams;
int i;
char paramtemp[MAX_IRC_MESSAGE_LEN*2];
int first = 1;
if (!conn) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
return -1;
}
if (!ircline) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL ircline");
return -1;
}
if (ircline[0] == '\0') {
eventlog(eventlog_level_error,__FUNCTION__,"got empty ircline");
return -1;
}
//amadeo: code was sent by some unknown fellow of pvpgn, prevents buffer-overflow for
// too long irc-lines
if (std::strlen(ircline)>254) {
char * tmp = (char *)ircline;
eventlog(eventlog_level_warn,__FUNCTION__,"line to long, truncation...");
tmp[254]='\0';
}
line = xstrdup(ircline);
/* split the message */
if (line[0] == ':') {
/* The prefix is optional and is rarely provided */
prefix = line;
if (!(command = std::strchr(line,' '))) {
eventlog(eventlog_level_warn,__FUNCTION__,"got malformed line (missing command)");
xfree(line);
return -1;
}
*command++ = '\0';
}
else {
/* In most cases command is the first thing on the line */
command = line;
}
tempparams = std::strchr(command,' ');
if (tempparams) {
*tempparams++ = '\0';
if (tempparams[0]==':') {
text = tempparams+1; /* theres just text, no params. skip the colon */
} else {
for (i=0;tempparams[i]!='\0';i++) {
if ((tempparams[i]==' ')&&(tempparams[i+1]==':')) {
text = tempparams+i;
*text++ = '\0';
text++; /* skip the colon */
break; /* text found, stop search */
}
}
params = irc_get_paramelems(tempparams);
}
}
if (params) {
/* count parameters */
for (numparams=0;params[numparams];numparams++);
}
std::memset(paramtemp,0,sizeof(paramtemp));
for (i=0;((numparams>0)&&(params[i]));i++) {
if (!first)
std::strcat(paramtemp," ");
std::strcat(paramtemp,"\"");
std::strcat(paramtemp,params[i]);
std::strcat(paramtemp,"\"");
first = 0;
}
eventlog(eventlog_level_debug,__FUNCTION__,"[%d] got \"%s\" \"%s\" [%s] \"%s\"",conn_get_socket(conn),((prefix)?(prefix):("")),command,paramtemp,((text)?(text):("")));
if (conn_get_state(conn)==conn_state_connected) {
t_timer_data temp;
conn_set_state(conn,conn_state_bot_username);
temp.n = prefs_get_irc_latency();
conn_test_latency(conn,std::time(NULL),temp);
}
if (handle_irc_con_command(conn, command, numparams, params, text)!=-1) {}
else if (conn_get_state(conn)!=conn_state_loggedin) {
char temp[MAX_IRC_MESSAGE_LEN+1];
if ((38+std::strlen(command)+16+1)<sizeof(temp)) {
snprintf(temp, sizeof(temp), ":Unrecognized command \"%s\" (before login)", command);
irc_send(conn,ERR_UNKNOWNCOMMAND,temp);
} else {
irc_send(conn,ERR_UNKNOWNCOMMAND,":Unrecognized command (before login)");
}
} else {
/* command is handled later */
unrecognized_before = 1;
}
/* --- The following should only be executable after login --- */
if ((conn_get_state(conn)==conn_state_loggedin)&&(unrecognized_before)) {
if (handle_irc_log_command(conn, command, numparams, params, text)!=-1) {}
else if ((strstart(command,"LAG")!=0)&&(strstart(command,"JOIN")!=0)){
linelen = std::strlen (ircline);
bnet_command = (char*)xmalloc(linelen + 2);
bnet_command[0]='/';
std::strcpy(bnet_command + 1, ircline);
handle_command(conn,bnet_command);
xfree((void*)bnet_command);
}
} /* loggedin */
if (params)
irc_unget_paramelems(params);
xfree(line);
return 0;
}
extern int handle_irc_welcome(t_connection * conn)
{
char temp[MAX_IRC_MESSAGE_LEN];
@ -341,55 +208,6 @@ extern int handle_irc_welcome(t_connection * conn)
return 0;
}
extern int handle_irc_packet(t_connection * conn, t_packet const * const packet)
{
unsigned int i;
char ircline[MAX_IRC_MESSAGE_LEN];
char const * data;
if (!packet) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
return -1;
}
if (conn_get_class(conn) != conn_class_irc) {
eventlog(eventlog_level_error,__FUNCTION__,"FIXME: handle_irc_packet without any reason (conn->class != conn_class_irc)");
return -1;
}
/* eventlog(eventlog_level_debug,__FUNCTION__,"got \"%s\"",packet_get_raw_data_const(packet,0)); */
std::memset(ircline,0,sizeof(ircline));
data = conn_get_ircline(conn); /* fetch current status */
if (data)
std::strcpy(ircline,data);
unsigned ircpos = std::strlen(ircline);
data = (const char *)packet_get_raw_data_const(packet,0);
for (i=0; i < packet_get_size(packet); i++) {
if ((data[i] == '\r')||(data[i] == '\0')) {
/* kindly ignore \r and NUL ... */
} else if (data[i] == '\n') {
/* end of line */
handle_irc_line(conn,ircline);
std::memset(ircline,0,sizeof(ircline));
ircpos = 0;
} else {
if (ircpos < MAX_IRC_MESSAGE_LEN-1)
ircline[ircpos++] = data[i];
else {
ircpos++; /* for the statistic :) */
eventlog(eventlog_level_warn,__FUNCTION__,"[%d] client exceeded maximum allowed message length by %d characters",conn_get_socket(conn),ircpos-MAX_IRC_MESSAGE_LEN);
if (ircpos > 100 + MAX_IRC_MESSAGE_LEN) {
/* automatic flood protection */
eventlog(eventlog_level_error,__FUNCTION__,"[%d] excess flood",conn_get_socket(conn));
return -1;
}
}
}
}
conn_set_ircline(conn,ircline); /* write back current status */
return 0;
}
static int _handle_user_command(t_connection * conn, int numparams, char ** params, char * text)
{
/* RFC 2812 says: */

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2001 Marco Ziech (mmz@gmx.net)
* Copyright (C) 2007 Pelish (pelish@gmail.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -31,7 +32,8 @@ namespace pvpgn
namespace bnetd
{
extern int handle_irc_packet(t_connection * conn,t_packet const * const packet);
extern int handle_irc_con_command(t_connection * conn, char const * command, int numparams, char ** params, char * text);
extern int handle_irc_log_command(t_connection * conn, char const * command, int numparams, char ** params, char * text);
extern int handle_irc_welcome(t_connection * conn);
}

View file

@ -0,0 +1,324 @@
/*
* Copyright (C) 2007 Pelish (pelish@gmail.com)
*
* 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.
*/
#include "common/setup_before.h"
#include "handle_irc_common.h"
#include <cstring>
#include <cctype>
#include <cstdlib>
#include "compat/strcasecmp.h"
#include "common/eventlog.h"
#include "common/util.h"
#include "common/irc_protocol.h"
#include "handle_irc.h"
#include "handle_wol.h"
#include "prefs.h"
#include "command.h"
#include "irc.h"
#include "common/setup_after.h"
namespace pvpgn
{
namespace bnetd
{
static int handle_irc_common_con_command(t_connection * conn, char const * command, int numparams, char ** params, char * text)
{
if (!conn) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
return -1;
}
switch (conn_get_class(conn)) {
case conn_class_irc:
return handle_irc_con_command(conn, command, numparams, params, text);
case conn_class_wol:
case conn_class_wserv:
case conn_class_wgameres:
return handle_wol_con_command(conn, command, numparams, params, text);
default:
return handle_irc_con_command(conn, command, numparams, params, text);
}
}
static int handle_irc_common_log_command(t_connection * conn, char const * command, int numparams, char ** params, char * text)
{
if (!conn) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
return -1;
}
switch (conn_get_class(conn)) {
case conn_class_irc:
return handle_irc_log_command(conn, command, numparams, params, text);
case conn_class_wol:
case conn_class_wserv:
case conn_class_wgameres:
return handle_wol_log_command(conn, command, numparams, params, text);
default:
return handle_irc_log_command(conn, command, numparams, params, text);
}
}
static int handle_irc_common_set_class(t_connection * conn, char const * command, int numparams, char ** params, char * text)
{
if (!conn) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
return -1;
}
if (conn_get_class(conn) != conn_class_ircinit) {
DEBUG0("FIXME: conn_get_class(conn) != conn_class_ircinit");
return -1;
}
else {
if (std::strcmp(command, "verchk") == 0) {
DEBUG0("Got WSERV packet");
conn_set_class(conn,conn_class_wserv);
return 0;
}
else if (std::strcmp(command, "CVERS") == 0) {
DEBUG0("Got WOL packet");
conn_set_class(conn,conn_class_wol);
return 0;
}
else if ((std::strcmp(command, "LISTSEARCH") == 0) ||
(std::strcmp(command, "RUNGSEARCH") == 0) ||
(std::strcmp(command, "HIGHSCORE") == 0)) {
DEBUG0("Got WOL Ladder packet");
conn_set_class(conn,conn_class_wol); /* is handled in handle_wol.* now */
return 0;
}
else if ((std::strcmp(command, "CRYPT") == 0) ||
(std::strcmp(command, "LOGIN") == 0)) {
DEBUG0("Got GameSpy packet");
conn_set_class(conn,conn_class_irc);
// conn_set_class(conn,conn_class_gspy_peerchat);
return 0;
}
else {
DEBUG0("Got IRC packet");
conn_set_class(conn,conn_class_irc);
return 0;
}
}
}
static int handle_irc_common_line(t_connection * conn, char const * ircline)
{
/* [:prefix] <command> [[param1] [param2] ... [paramN]] [:<text>] */
char * line; /* copy of ircline */
char * prefix = NULL; /* optional; mostly NULL */
char * command; /* mandatory */
char ** params = NULL; /* optional (array of params) */
char * text = NULL; /* optional */
char * bnet_command = NULL; /* amadeo: used for battle.net.commands */
int unrecognized_before = 0;
int linelen; /* amadeo: counter for stringlenghts */
int numparams = 0;
char * tempparams;
int i;
char paramtemp[MAX_IRC_MESSAGE_LEN*2];
int first = 1;
if (!conn) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
return -1;
}
if (!ircline) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL ircline");
return -1;
}
if (ircline[0] == '\0') {
eventlog(eventlog_level_error,__FUNCTION__,"got empty ircline");
return -1;
}
//amadeo: code was sent by some unknown fellow of pvpgn, prevents buffer-overflow for
// too long irc-lines
if (std::strlen(ircline)>254) {
char * tmp = (char *)ircline;
eventlog(eventlog_level_warn,__FUNCTION__,"line to long, truncation...");
tmp[254]='\0';
}
line = xstrdup(ircline);
/* split the message */
if (line[0] == ':') {
/* The prefix is optional and is rarely provided */
prefix = line;
if (!(command = std::strchr(line,' '))) {
eventlog(eventlog_level_warn,__FUNCTION__,"got malformed line (missing command)");
xfree(line);
return -1;
}
*command++ = '\0';
}
else {
/* In most cases command is the first thing on the line */
command = line;
}
tempparams = std::strchr(command,' ');
if (tempparams) {
*tempparams++ = '\0';
if (tempparams[0]==':') {
text = tempparams+1; /* theres just text, no params. skip the colon */
} else {
for (i=0;tempparams[i]!='\0';i++) {
if ((tempparams[i]==' ')&&(tempparams[i+1]==':')) {
text = tempparams+i;
*text++ = '\0';
text++; /* skip the colon */
break; /* text found, stop search */
}
}
params = irc_get_paramelems(tempparams);
}
}
if (params) {
/* count parameters */
for (numparams=0;params[numparams];numparams++);
}
std::memset(paramtemp,0,sizeof(paramtemp));
for (i=0;((numparams>0)&&(params[i]));i++) {
if (!first)
std::strcat(paramtemp," ");
std::strcat(paramtemp,"\"");
std::strcat(paramtemp,params[i]);
std::strcat(paramtemp,"\"");
first = 0;
}
eventlog(eventlog_level_debug,__FUNCTION__,"[%d] got \"%s\" \"%s\" [%s] \"%s\"",conn_get_socket(conn),((prefix)?(prefix):("")),command,paramtemp,((text)?(text):("")));
if (conn_get_state(conn)==conn_state_connected) {
t_timer_data temp;
conn_set_state(conn,conn_state_bot_username);
temp.n = prefs_get_irc_latency();
conn_test_latency(conn,std::time(NULL),temp);
}
if (conn_get_class(conn) == conn_class_ircinit) {
handle_irc_common_set_class(conn, command, numparams, params, text);
}
if (handle_irc_common_con_command(conn, command, numparams, params, text)!=-1) {}
else if (conn_get_state(conn)!=conn_state_loggedin) {
char temp[MAX_IRC_MESSAGE_LEN+1];
if ((38+std::strlen(command)+16+1)<sizeof(temp)) {
snprintf(temp, sizeof(temp), ":Unrecognized command \"%s\" (before login)", command);
irc_send(conn,ERR_UNKNOWNCOMMAND,temp);
} else {
irc_send(conn,ERR_UNKNOWNCOMMAND,":Unrecognized command (before login)");
}
} else {
/* command is handled later */
unrecognized_before = 1;
}
/* --- The following should only be executable after login --- */
if ((conn_get_state(conn)==conn_state_loggedin)&&(unrecognized_before)) {
if (handle_irc_common_log_command(conn, command, numparams, params, text)!=-1) {}
else if ((strstart(command,"LAG")!=0)&&(strstart(command,"JOIN")!=0)){
linelen = std::strlen (ircline);
bnet_command = (char*)xmalloc(linelen + 2);
bnet_command[0]='/';
std::strcpy(bnet_command + 1, ircline);
handle_command(conn,bnet_command);
xfree((void*)bnet_command);
}
} /* loggedin */
if (params)
irc_unget_paramelems(params);
xfree(line);
return 0;
}
extern int handle_irc_common_packet(t_connection * conn, t_packet const * const packet)
{
unsigned int i;
char ircline[MAX_IRC_MESSAGE_LEN];
char const * data;
char test[MAX_IRC_MESSAGE_LEN];
if (!packet) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
return -1;
}
if (conn_get_class(conn) != conn_class_ircinit &&
conn_get_class(conn) != conn_class_irc &&
conn_get_class(conn) != conn_class_wol &&
conn_get_class(conn) != conn_class_wserv &&
conn_get_class(conn) != conn_class_wgameres) {
eventlog(eventlog_level_error,__FUNCTION__,"FIXME: handle_irc_packet without any reason (conn->class != conn_class_irc/ircinit/wol/wserv...)");
return -1;
}
// eventlog(eventlog_level_debug,__FUNCTION__,"got \"%s\"",packet_get_raw_data_const(packet,0));
std::memset(ircline,0,sizeof(ircline));
data = conn_get_ircline(conn); /* fetch current status */
if (data)
std::strcpy(ircline,data);
unsigned ircpos = std::strlen(ircline);
data = (const char *)packet_get_raw_data_const(packet,0);
for (i=0; i < packet_get_size(packet); i++) {
if ((data[i] == '\r')||(data[i] == '\0')) {
/* kindly ignore \r and NUL ... */
}
else if (data[i] == '\n') {
/* end of line */
handle_irc_common_line(conn,ircline);
std::memset(ircline,0,sizeof(ircline));
ircpos = 0;
} else {
if (ircpos < MAX_IRC_MESSAGE_LEN-1)
ircline[ircpos++] = data[i];
else {
ircpos++; /* for the statistic :) */
eventlog(eventlog_level_warn,__FUNCTION__,"[%d] client exceeded maximum allowed message length by %d characters",conn_get_socket(conn),ircpos-MAX_IRC_MESSAGE_LEN);
if (ircpos > 100 + MAX_IRC_MESSAGE_LEN) {
/* automatic flood protection */
eventlog(eventlog_level_error,__FUNCTION__,"[%d] excess flood",conn_get_socket(conn));
return -1;
}
}
}
}
conn_set_ircline(conn,ircline); /* write back current status */
return 0;
}
}
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (C) 2007 Pelish (pelish@gmail.com)
*
* 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.
*/
/*****/
#ifndef JUST_NEED_TYPES
#ifndef INCLUDED_HANDLE_IRC_COMMON_PROTOS
#define INCLUDED_HANDLE_IRC_COMMON_PROTOS
#include "common/packet.h"
#include "connection.h"
namespace pvpgn
{
namespace bnetd
{
extern int handle_irc_common_packet(t_connection * conn, t_packet const * const packet);
}
}
#endif
#endif

View file

@ -176,7 +176,7 @@ static const t_wol_command_table_row wol_log_command_table[] =
{ NULL , NULL }
};
static int handle_wol_con_command(t_connection * conn, char const * command, int numparams, char ** params, char * text)
extern int handle_wol_con_command(t_connection * conn, char const * command, int numparams, char ** params, char * text)
{
t_wol_command_table_row const *p;
@ -189,7 +189,7 @@ static int handle_wol_con_command(t_connection * conn, char const * command, int
return -1;
}
static int handle_wol_log_command(t_connection * conn, char const * command, int numparams, char ** params, char * text)
extern int handle_wol_log_command(t_connection * conn, char const * command, int numparams, char ** params, char * text)
{
t_wol_command_table_row const *p;
@ -202,131 +202,6 @@ static int handle_wol_log_command(t_connection * conn, char const * command, int
return -1;
}
static int handle_wol_line(t_connection * conn, char const * wolline)
{
/* [:prefix] <command> [[param1] [param2] ... [paramN]] [:<text>] */
char * line; /* copy of wolline */
char * prefix = NULL; /* optional; mostly NULL */
char * command; /* mandatory */
char ** params = NULL; /* optional (array of params) */
char * text = NULL; /* optional */
char * bnet_command = NULL; /* amadeo: used for battle.net.commands */
int unrecognized_before = 0;
int linelen; /* amadeo: counter for stringlenghts */
int numparams = 0;
char * tempparams;
int i;
char paramtemp[MAX_IRC_MESSAGE_LEN*2];
int first = 1;
if (!conn) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
return -1;
}
if (!wolline) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL wolline");
return -1;
}
if (wolline[0] == '\0') {
eventlog(eventlog_level_error,__FUNCTION__,"got empty wolline");
return -1;
}
//amadeo: code was sent by some unknown fellow of pvpgn, prevents buffer-overflow for
// too long wol-lines
if (std::strlen(wolline)>254) {
char * tmp = (char *)wolline;
eventlog(eventlog_level_warn,__FUNCTION__,"line to long, truncation...");
tmp[254]='\0';
}
line = xstrdup(wolline);
/* split the message */
if (line[0] == ':') {
/* The prefix is optional and is rarely provided */
prefix = line;
if (!(command = std::strchr(line,' '))) {
eventlog(eventlog_level_warn,__FUNCTION__,"got malformed line (missing command)");
xfree(line);
return -1;
}
*command++ = '\0';
}
else {
/* In most cases command is the first thing on the line */
command = line;
}
tempparams = std::strchr(command,' ');
if (tempparams) {
*tempparams++ = '\0';
if (tempparams[0]==':') {
text = tempparams+1; /* theres just text, no params. skip the colon */
} else {
for (i=0;tempparams[i]!='\0';i++) {
if ((tempparams[i]==' ')&&(tempparams[i+1]==':')) {
text = tempparams+i;
*text++ = '\0';
text++; /* skip the colon */
break; /* text found, stop search */
}
}
params = irc_get_paramelems(tempparams);
}
}
if (params) {
/* count parameters */
for (numparams=0;params[numparams];numparams++);
}
std::memset(paramtemp,0,sizeof(paramtemp));
for (i=0;((numparams>0)&&(params[i]));i++) {
if (!first)
std::strcat(paramtemp," ");
std::strcat(paramtemp,"\"");
std::strcat(paramtemp,params[i]);
std::strcat(paramtemp,"\"");
first = 0;
}
eventlog(eventlog_level_debug,__FUNCTION__,"[%d] got \"%s\" \"%s\" [%s] \"%s\"",conn_get_socket(conn),((prefix)?(prefix):("")),command,paramtemp,((text)?(text):("")));
if (conn_get_state(conn)==conn_state_connected) {
t_timer_data temp;
conn_set_state(conn,conn_state_bot_username);
temp.n = prefs_get_irc_latency();
conn_test_latency(conn,std::time(NULL),temp);
}
if (handle_wol_con_command(conn, command, numparams, params, text)!=-1) {}
else if (conn_get_state(conn)!=conn_state_loggedin) {
} else {
/* command is handled later */
unrecognized_before = 1;
}
/* --- The following should only be executable after login --- */
if ((conn_get_state(conn)==conn_state_loggedin)&&(unrecognized_before)) {
if (handle_wol_log_command(conn, command, numparams, params, text)!=-1) {}
else if ((strstart(command,"LAG")!=0)&&(strstart(command,"JOIN")!=0)){
linelen = std::strlen (wolline);
bnet_command = (char*)xmalloc(linelen + 2);
bnet_command[0]='/';
std::strcpy(bnet_command + 1, wolline);
handle_command(conn,bnet_command);
xfree((void*)bnet_command);
}
} /* loggedin */
if (params)
irc_unget_paramelems(params);
xfree(line);
return 0;
}
extern int handle_wol_welcome(t_connection * conn)
{
/* This function need rewrite */
@ -350,55 +225,6 @@ extern int handle_wol_welcome(t_connection * conn)
return 0;
}
extern int handle_wol_packet(t_connection * conn, t_packet const * const packet)
{
unsigned int i;
char wolline[MAX_IRC_MESSAGE_LEN];
char const * data;
if (!packet) {
eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
return -1;
}
if (conn_get_class(conn) != conn_class_wol && conn_get_class(conn) != conn_class_wserv && conn_get_class(conn) != conn_class_wgameres) {
eventlog(eventlog_level_error,__FUNCTION__,"FIXME: handle_wol_packet without any reason (conn->class != conn_class_wol && conn->class != conn_class_wserv)");
return -1;
}
/* eventlog(eventlog_level_debug,__FUNCTION__,"got \"%s\"",packet_get_raw_data_const(packet,0)); */
std::memset(wolline,0,sizeof(wolline));
data = conn_get_ircline(conn); /* fetch current status */
if (data)
std::strcpy(wolline,data);
unsigned wolpos = std::strlen(wolline);
data = (const char *)packet_get_raw_data_const(packet,0);
for (i=0; i < packet_get_size(packet); i++) {
if ((data[i] == '\r')||(data[i] == '\0')) {
/* kindly ignore \r and NUL ... */
} else if (data[i] == '\n') {
/* end of line */
handle_wol_line(conn,wolline);
std::memset(wolline,0,sizeof(wolline));
wolpos = 0;
} else {
if (wolpos < MAX_IRC_MESSAGE_LEN-1)
wolline[wolpos++] = data[i];
else {
wolpos++; /* for the statistic :) */
eventlog(eventlog_level_warn,__FUNCTION__,"[%d] client exceeded maximum allowed message length by %d characters",conn_get_socket(conn),wolpos-MAX_IRC_MESSAGE_LEN);
if (wolpos > 100 + MAX_IRC_MESSAGE_LEN) {
/* automatic flood protection */
eventlog(eventlog_level_error,__FUNCTION__,"[%d] excess flood",conn_get_socket(conn));
return -1;
}
}
}
}
conn_set_ircline(conn,wolline); /* write back current status */
return 0;
}
static int _handle_user_command(t_connection * conn, int numparams, char ** params, char * text)
{ /* In WOL isnt used user command (only by byckwar compatibility) */
/* RFC 2812 says: */

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2006 Pelish (pelish@gmail.com)
* Copyright (C) 2006,2007 Pelish (pelish@gmail.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -31,7 +31,8 @@ namespace pvpgn
namespace bnetd
{
extern int handle_wol_packet(t_connection * conn,t_packet const * const packet);
extern int handle_wol_con_command(t_connection * conn, char const * command, int numparams, char ** params, char * text);
extern int handle_wol_log_command(t_connection * conn, char const * command, int numparams, char ** params, char * text);
extern int handle_wol_welcome(t_connection * conn);
}

View file

@ -59,8 +59,7 @@
#include "handle_file.h"
#include "handle_init.h"
#include "handle_d2cs.h"
#include "handle_irc.h"
#include "handle_wol.h"
#include "handle_irc_common.h"
#include "handle_udp.h"
#include "anongame.h"
#include "clan.h"
@ -341,15 +340,9 @@ static int sd_accept(t_addr const * curr_laddr, t_laddr_info const * laddr_info,
switch (laddr_info->type)
{
case laddr_type_irc:
conn_set_class(c,conn_class_irc);
conn_set_state(c,conn_state_connected);
break;
case laddr_type_wol:
conn_set_class(c,conn_class_wol);
conn_set_state(c,conn_state_connected);
break;
case laddr_type_wserv:
conn_set_class(c,conn_class_wserv);
conn_set_class(c,conn_class_ircinit);
conn_set_state(c,conn_state_connected);
break;
case laddr_type_wgameres:
@ -525,6 +518,7 @@ static int sd_tcpinput(t_connection * c)
}
break;
case conn_class_bot:
case conn_class_ircinit:
case conn_class_irc:
case conn_class_wol:
case conn_class_wserv:
@ -640,13 +634,12 @@ static int sd_tcpinput(t_connection * c)
case conn_class_file:
ret = handle_file_packet(c,packet);
break;
case conn_class_ircinit:
case conn_class_irc:
ret = handle_irc_packet(c,packet);
break;
case conn_class_wgameres:
case conn_class_wserv:
case conn_class_wol:
ret = handle_wol_packet(c,packet);
case conn_class_wgameres: /* NOTICE: Will be handled in other file */
ret = handle_irc_common_packet(c,packet);
break;
case conn_class_w3route:
ret = handle_w3route_packet(c,packet);