X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fcommands.cpp;h=5db288ffaa4745f9109f2216e19ad09f1fe64c5f;hb=e66fefe4310264f8f11b5035b174fc8cb9287149;hp=c5529501dc01f986aef6bfa3f5abdab997bd6ee0;hpb=858b28bd2e46d827fd7178aa7cc99a19f9af6a61;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/commands.cpp b/src/commands.cpp index c5529501d..5db288ffa 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -24,17 +24,6 @@ using namespace std; #include #include #include - -#ifdef USE_KQUEUE -#include -#include -#include -#endif - -#ifdef USE_EPOLL -#include -#endif - #include #include #include @@ -71,82 +60,30 @@ using namespace std; #include "dnsqueue.h" #include "helperfuncs.h" #include "hashcomp.h" +#include "socketengine.h" +#include "typedefs.h" -#ifdef USE_KQUEUE -extern int kq; -#endif - -#ifdef USE_EPOLL -int ep; -#endif +extern SocketEngine* SE; +extern ServerConfig* Config; extern int MODCOUNT; extern std::vector modules; extern std::vector factory; - -extern int LogLevel; -extern char ServerName[MAXBUF]; -extern char Network[MAXBUF]; -extern char ServerDesc[MAXBUF]; -extern char AdminName[MAXBUF]; -extern char AdminEmail[MAXBUF]; -extern char AdminNick[MAXBUF]; -extern char diepass[MAXBUF]; -extern char restartpass[MAXBUF]; -extern char motd[MAXBUF]; -extern char rules[MAXBUF]; -extern char list[MAXBUF]; -extern char PrefixQuit[MAXBUF]; -extern char DieValue[MAXBUF]; - -extern int debugging; extern int WHOWAS_STALE; extern int WHOWAS_MAX; -extern int DieDelay; extern time_t startup_time; -extern int NetBufferSize; -extern int MaxWhoResults; -extern time_t nb_start; - -extern bool nofork; - extern time_t TIME; -extern std::vector module_names; - -extern char MyExecutable[1024]; -extern int boundPortCount; -extern int portCount; - -extern int ports[MAXSOCKS]; - -extern std::stringstream config_f; - - - -extern FILE *log_file; - -extern ClassVector Classes; - const long duration_m = 60; const long duration_h = duration_m * 60; const long duration_d = duration_h * 24; const long duration_w = duration_d * 7; const long duration_y = duration_w * 52; -typedef nspace::hash_map, irc::StrHashComp> user_hash; -typedef nspace::hash_map, irc::StrHashComp> chan_hash; -typedef nspace::hash_map, irc::InAddr_HashComp> address_cache; -typedef nspace::hash_map, irc::StrHashComp> whowas_hash; -typedef std::deque command_table; - - extern user_hash clientlist; extern chan_hash chanlist; extern whowas_hash whowas; extern command_table cmdlist; -extern file_cache MOTD; -extern file_cache RULES; extern address_cache IP; extern std::vector all_opers; @@ -156,7 +93,7 @@ extern std::vector all_opers; // by an integer, meaning there is no need for a scan/search operation. extern userrec* fd_ref_table[65536]; -extern int statsAccept,statsRefused,statsUnknown,statsCollisions,statsDns,statsDnsGood,statsDnsBad,statsConnects,statsSent,statsRecv; +extern serverstats* stats; void handle_join(char **parameters, int pcnt, userrec *user) { @@ -262,10 +199,10 @@ void handle_unloadmodule(char **parameters, int pcnt, userrec *user) void handle_die(char **parameters, int pcnt, userrec *user) { log(DEBUG,"die: %s",user->nick); - if (!strcmp(parameters[0],diepass)) + if (!strcmp(parameters[0],Config->diepass)) { WriteOpers("*** DIE command from %s!%s@%s, terminating...",user->nick,user->ident,user->host); - sleep(DieDelay); + sleep(Config->DieDelay); Exit(ERROR); } else @@ -278,13 +215,13 @@ void handle_restart(char **parameters, int pcnt, userrec *user) { char *argv[32]; log(DEFAULT,"Restart: %s",user->nick); - if (!strcmp(parameters[0],restartpass)) + if (!strcmp(parameters[0],Config->restartpass)) { WriteOpers("*** RESTART command from %s!%s@%s, restarting server.",user->nick,user->ident,user->host); - argv[0] = MyExecutable; + argv[0] = Config->MyExecutable; argv[1] = "-wait"; - if (nofork) + if (Config->nofork) { argv[2] = "-nofork"; } @@ -304,7 +241,7 @@ void handle_restart(char **parameters, int pcnt, userrec *user) } sleep(2); - execv(MyExecutable,argv); + execv(Config->MyExecutable,argv); exit(0); } @@ -330,11 +267,11 @@ void handle_kill(char **parameters, int pcnt, userrec *user) return; } - if (strcmp(ServerName,u->server)) + if (u->fd < 0) { // remote kill WriteOpers("*** Remote kill by %s: %s!%s@%s (%s)",user->nick,u->nick,u->ident,u->host,parameters[1]); - snprintf(killreason,MAXBUF,"[%s] Killed (%s (%s))",ServerName,user->nick,parameters[1]); + snprintf(killreason,MAXBUF,"[%s] Killed (%s (%s))",Config->ServerName,user->nick,parameters[1]); WriteCommonExcept(u,"QUIT :%s",killreason); FOREACH_MOD OnRemoteKill(user,u,killreason); @@ -356,8 +293,8 @@ void handle_kill(char **parameters, int pcnt, userrec *user) else { // local kill - log(DEFAULT,"LOCAL KILL: %s :%s!%s!%s (%s)", u->nick, ServerName,user->dhost,user->nick,parameters[1]); - WriteTo(user, u, "KILL %s :%s!%s!%s (%s)", u->nick, ServerName,user->dhost,user->nick,parameters[1]); + log(DEFAULT,"LOCAL KILL: %s :%s!%s!%s (%s)", u->nick, Config->ServerName,user->dhost,user->nick,parameters[1]); + WriteTo(user, u, "KILL %s :%s!%s!%s (%s)", u->nick, Config->ServerName,user->dhost,user->nick,parameters[1]); WriteOpers("*** Local Kill by %s: %s!%s@%s (%s)",user->nick,u->nick,u->ident,u->host,parameters[1]); snprintf(killreason,MAXBUF,"Killed (%s (%s))",user->nick,parameters[1]); kill_link(u,killreason); @@ -521,7 +458,7 @@ void handle_topic(char **parameters, int pcnt, userrec *user) topic[MAXTOPIC] = '\0'; } - if (!strcasecmp(user->server,ServerName)) + if (user->fd > -1) { int MOD_RESULT = 0; FOREACH_RESULT(OnLocalTopicChange(user,Ptr,topic)); @@ -533,7 +470,7 @@ void handle_topic(char **parameters, int pcnt, userrec *user) strlcpy(Ptr->setby,user->nick,NICKMAX); Ptr->topicset = TIME; WriteChannel(Ptr,user,"TOPIC %s :%s",Ptr->name, Ptr->topic); - if (!strcasecmp(user->server,ServerName)) + if (user->fd > -1) { FOREACH_MOD OnPostLocalTopicChange(user,Ptr,topic); } @@ -589,7 +526,7 @@ void handle_privmsg(char **parameters, int pcnt, userrec *user) // notice to server mask char* servermask = parameters[0]; servermask++; - if (match(ServerName,servermask)) + if (match(Config->ServerName,servermask)) { ServerPrivmsgAll("%s",parameters[1]); } @@ -636,12 +573,10 @@ void handle_privmsg(char **parameters, int pcnt, userrec *user) } return; } - - log(DEBUG,"*** PRIVMSG HANDLER"); + dest = Find(parameters[0]); if (dest) { - log(DEBUG,"*** FOUND NICK %s",dest->nick); if (strcmp(dest->awaymsg,"")) { /* auto respond with aweh msg */ @@ -657,10 +592,9 @@ void handle_privmsg(char **parameters, int pcnt, userrec *user) } parameters[1] = (char*)temp.c_str(); - if (!strcmp(dest->server,ServerName)) + if (dest->fd > -1) { // direct write, same server - log(DEBUG,"*** CALL WRITETO"); WriteTo(user, dest, "PRIVMSG %s :%s", dest->nick, parameters[1]); } @@ -687,7 +621,7 @@ void handle_notice(char **parameters, int pcnt, userrec *user) // notice to server mask char* servermask = parameters[0]; servermask++; - if (match(ServerName,servermask)) + if (match(Config->ServerName,servermask)) { NoticeAll(user, true, "%s",parameters[1]); } @@ -748,7 +682,7 @@ void handle_notice(char **parameters, int pcnt, userrec *user) } parameters[1] = (char*)temp.c_str(); - if (!strcmp(dest->server,ServerName)) + if (dest->fd > -1) { // direct write, same server WriteTo(user, dest, "NOTICE %s :%s", dest->nick, parameters[1]); @@ -815,70 +749,109 @@ void handle_time(char **parameters, int pcnt, userrec *user) time_t rawtime; struct tm * timeinfo; - time ( &rawtime ); - timeinfo = localtime ( &rawtime ); - WriteServ(user->fd,"391 %s %s :%s",user->nick,ServerName, asctime (timeinfo) ); + time(&rawtime); + timeinfo = localtime(&rawtime); + WriteServ(user->fd,"391 %s %s :%s",user->nick,Config->ServerName,asctime(timeinfo)); } void handle_whois(char **parameters, int pcnt, userrec *user) { userrec *dest; - - if (loop_call(handle_whois,parameters,pcnt,user,0,pcnt-1,0)) - return; + if (loop_call(handle_whois,parameters,pcnt,user,0,pcnt-1,0)) + return; dest = Find(parameters[0]); if (dest) { - // bug found by phidjit - were able to whois an incomplete connection if it had sent a NICK or USER - if (dest->registered == 7) + do_whois(user,dest,0,0,parameters[0]); + } + else + { + /* no such nick/channel */ + WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]); + WriteServ(user->fd,"318 %s %s :End of /WHOIS list.",user->nick, parameters[0]); + } +} + +void split_chlist(userrec* user, userrec* dest, std::string &cl) +{ + std::stringstream channels(cl); + std::string line = ""; + std::string cname = ""; + while (!channels.eof()) + { + channels >> cname; + line = line + cname + " "; + if (line.length() > 400) + { + WriteServ(user->fd,"319 %s %s :%s",user->nick, dest->nick, line.c_str()); + line = ""; + } + } + if (line.length()) + { + WriteServ(user->fd,"319 %s %s :%s",user->nick, dest->nick, line.c_str()); + } +} + +void do_whois(userrec* user, userrec* dest,unsigned long signon, unsigned long idle, char* nick) +{ + // bug found by phidjit - were able to whois an incomplete connection if it had sent a NICK or USER + if (dest->registered == 7) + { + WriteServ(user->fd,"311 %s %s %s %s * :%s",user->nick, dest->nick, dest->ident, dest->dhost, dest->fullname); + if ((user == dest) || (strchr(user->modes,'o'))) + { + WriteServ(user->fd,"378 %s %s :is connecting from *@%s %s",user->nick, dest->nick, dest->host, dest->ip); + } + std::string cl = chlist(dest,user); + if (cl.length()) { - WriteServ(user->fd,"311 %s %s %s %s * :%s",user->nick, dest->nick, dest->ident, dest->dhost, dest->fullname); - if ((user == dest) || (strchr(user->modes,'o'))) + if (cl.length() > 400) { - WriteServ(user->fd,"378 %s %s :is connecting from *@%s %s",user->nick, dest->nick, dest->host, dest->ip); + split_chlist(user,dest,cl); } - char* cl = chlist(dest,user); - if (*cl) + else { - WriteServ(user->fd,"319 %s %s :%s",user->nick, dest->nick, cl); + WriteServ(user->fd,"319 %s %s :%s",user->nick, dest->nick, cl.c_str()); } - WriteServ(user->fd,"312 %s %s %s :%s",user->nick, dest->nick, dest->server, GetServerDescription(dest->server).c_str()); - if (*dest->awaymsg) + } + WriteServ(user->fd,"312 %s %s %s :%s",user->nick, dest->nick, dest->server, GetServerDescription(dest->server).c_str()); + if (*dest->awaymsg) + { + WriteServ(user->fd,"301 %s %s :%s",user->nick, dest->nick, dest->awaymsg); + } + if (strchr(dest->modes,'o')) + { + if (*dest->oper) { - WriteServ(user->fd,"301 %s %s :%s",user->nick, dest->nick, dest->awaymsg); + WriteServ(user->fd,"313 %s %s :is %s %s on %s",user->nick, dest->nick, (strchr("aeiou",dest->oper[0]) ? "an" : "a"),dest->oper, Config->Network); } - if (strchr(dest->modes,'o')) + else { - if (*dest->oper) - { - WriteServ(user->fd,"313 %s %s :is %s %s on %s",user->nick, dest->nick, (strchr("aeiou",dest->oper[0]) ? "an" : "a"),dest->oper, Network); - } - else - { - WriteServ(user->fd,"313 %s %s :is opered but has an unknown type",user->nick, dest->nick); - } + WriteServ(user->fd,"313 %s %s :is opered but has an unknown type",user->nick, dest->nick); } + } + if ((!signon) && (!idle)) + { FOREACH_MOD OnWhois(user,dest); - if (!strcasecmp(user->server,dest->server)) - { - // idle time and signon line can only be sent if youre on the same server (according to RFC) - WriteServ(user->fd,"317 %s %s %d %d :seconds idle, signon time",user->nick, dest->nick, abs((dest->idle_lastmsg)-TIME), dest->signon); - } - - WriteServ(user->fd,"318 %s %s :End of /WHOIS list.",user->nick, dest->nick); + } + if (!strcasecmp(user->server,dest->server)) + { + // idle time and signon line can only be sent if youre on the same server (according to RFC) + WriteServ(user->fd,"317 %s %s %d %d :seconds idle, signon time",user->nick, dest->nick, abs((dest->idle_lastmsg)-TIME), dest->signon); } else { - WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]); - WriteServ(user->fd,"318 %s %s :End of /WHOIS list.",user->nick, parameters[0]); + if ((idle) || (signon)) + WriteServ(user->fd,"317 %s %s %d %d :seconds idle, signon time",user->nick, dest->nick, idle, signon); } + WriteServ(user->fd,"318 %s %s :End of /WHOIS list.",user->nick, dest->nick); } else { - /* no such nick/channel */ - WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]); - WriteServ(user->fd,"318 %s %s :End of /WHOIS list.",user->nick, parameters[0]); + WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, nick); + WriteServ(user->fd,"318 %s %s :End of /WHOIS list.",user->nick, nick); } } @@ -906,19 +879,18 @@ void handle_quit(char **parameters, int pcnt, userrec *user) /* We should only prefix the quit for a local user. Remote users have * already been prefixed, where neccessary, by the upstream server. */ - if (!strcasecmp(user->server,ServerName)) + if (user->fd > -1) { - Write(user->fd,"ERROR :Closing link (%s@%s) [%s%s]",user->ident,user->host,PrefixQuit,parameters[0]); - WriteOpers("*** Client exiting: %s!%s@%s [%s%s]",user->nick,user->ident,user->host,PrefixQuit,parameters[0]); - WriteCommonExcept(user,"QUIT :%s%s",PrefixQuit,parameters[0]); + Write(user->fd,"ERROR :Closing link (%s@%s) [%s%s]",user->ident,user->host,Config->PrefixQuit,parameters[0]); + WriteOpers("*** Client exiting: %s!%s@%s [%s%s]",user->nick,user->ident,user->host,Config->PrefixQuit,parameters[0]); + WriteCommonExcept(user,"QUIT :%s%s",Config->PrefixQuit,parameters[0]); } else { - Write(user->fd,"ERROR :Closing link (%s@%s) [%s]",user->ident,user->host,parameters[0]); - WriteOpers("*** Client exiting: %s!%s@%s [%s]",user->nick,user->ident,user->host,parameters[0]); + WriteOpers("*** Client exiting at %s: %s!%s@%s [%s]",user->server,user->nick,user->ident,user->host,parameters[0]); WriteCommonExcept(user,"QUIT :%s",parameters[0]); } - FOREACH_MOD OnUserQuit(user,std::string(PrefixQuit)+std::string(parameters[0])); + FOREACH_MOD OnUserQuit(user,std::string(Config->PrefixQuit)+std::string(parameters[0])); } else @@ -937,25 +909,7 @@ void handle_quit(char **parameters, int pcnt, userrec *user) /* push the socket on a stack of sockets due to be closed at the next opportunity */ if (user->fd > -1) { -#ifdef USE_KQUEUE - struct kevent ke; - EV_SET(&ke, user->fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); - int i = kevent(kq, &ke, 1, 0, 0, NULL); - if (i == -1) - { - log(DEBUG,"kqueue: Failed to remove user from queue!"); - } -#endif -#ifdef USE_EPOLL - struct epoll_event ev; - ev.events = EPOLLIN | EPOLLET; - ev.data.fd = user->fd; - int i = epoll_ctl(ep, EPOLL_CTL_DEL, user->fd, &ev); - if (i < 0) - { - log(DEBUG,"epoll: List deletion failure!"); - } -#endif + SE->DelFd(user->fd); user->CloseSocket(); } @@ -982,7 +936,7 @@ void handle_who(char **parameters, int pcnt, userrec *user) { if ((!strcmp(parameters[0],"0")) || (!strcmp(parameters[0],"*"))) { - if (user->chans[0].channel) + if ((user->chans.size()) && (user->chans[0].channel)) { int n_list = 0; for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++) @@ -1001,7 +955,7 @@ void handle_who(char **parameters, int pcnt, userrec *user) if (strchr(i->second->modes,'o')) { strlcat(tmp, "*", 9); } WriteServ(user->fd,"352 %s %s %s %s %s %s %s :0 %s",user->nick, Ptr ? Ptr->name : "*", i->second->ident, i->second->dhost, i->second->server, i->second->nick, tmp, i->second->fullname); n_list++; - if (n_list > MaxWhoResults) + if (n_list > Config->MaxWhoResults) { WriteServ(user->fd,"523 %s WHO :Command aborted: More results than configured limit",user->nick); break; @@ -1040,7 +994,7 @@ void handle_who(char **parameters, int pcnt, userrec *user) strlcat(tmp, cmode(i->second, Ptr),5); WriteServ(user->fd,"352 %s %s %s %s %s %s %s :0 %s",user->nick, Ptr->name, i->second->ident, i->second->dhost, i->second->server, i->second->nick, tmp, i->second->fullname); n_list++; - if (n_list > MaxWhoResults) + if (n_list > Config->MaxWhoResults) { WriteServ(user->fd,"523 %s WHO :Command aborted: More results than configured limit",user->nick); break; @@ -1068,7 +1022,7 @@ void handle_who(char **parameters, int pcnt, userrec *user) strlcat(tmp, "H" ,9); } if (strchr(u->modes,'o')) { strlcat(tmp, "*" ,9); } - WriteServ(user->fd,"352 %s %s %s %s %s %s %s :0 %s",user->nick, u->chans[0].channel ? u->chans[0].channel->name + WriteServ(user->fd,"352 %s %s %s %s %s %s %s :0 %s",user->nick, u->chans.size() ? u->chans[0].channel->name : "*", u->ident, u->dhost, u->server, u->nick, tmp, u->fullname); } WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]); @@ -1089,7 +1043,7 @@ void handle_who(char **parameters, int pcnt, userrec *user) } else { strlcat(tmp, "H" ,9); } - WriteServ(user->fd,"352 %s %s %s %s %s %s %s* :0 %s", user->nick, oper->chans[0].channel ? oper->chans[0].channel->name + WriteServ(user->fd,"352 %s %s %s %s %s %s %s* :0 %s", user->nick, oper->chans.size() ? oper->chans[0].channel->name : "*", oper->ident, oper->dhost, oper->server, oper->nick, tmp, oper->fullname); } WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]); @@ -1130,7 +1084,7 @@ void handle_rehash(char **parameters, int pcnt, userrec *user) else { WriteOpers("%s is rehashing config file %s",user->nick,CleanFilename(CONFIG_FILE)); - ReadConfig(false,user); + Config->Read(false,user); } FOREACH_MOD OnRehash(parameter); } @@ -1148,15 +1102,15 @@ void handle_lusers(char **parameters, int pcnt, userrec *user) void handle_admin(char **parameters, int pcnt, userrec *user) { - WriteServ(user->fd,"256 %s :Administrative info for %s",user->nick,ServerName); - WriteServ(user->fd,"257 %s :Name - %s",user->nick,AdminName); - WriteServ(user->fd,"258 %s :Nickname - %s",user->nick,AdminNick); - WriteServ(user->fd,"258 %s :E-Mail - %s",user->nick,AdminEmail); + WriteServ(user->fd,"256 %s :Administrative info for %s",user->nick,Config->ServerName); + WriteServ(user->fd,"257 %s :Name - %s",user->nick,Config->AdminName); + WriteServ(user->fd,"258 %s :Nickname - %s",user->nick,Config->AdminNick); + WriteServ(user->fd,"258 %s :E-Mail - %s",user->nick,Config->AdminEmail); } void handle_ping(char **parameters, int pcnt, userrec *user) { - WriteServ(user->fd,"PONG %s :%s",ServerName,parameters[0]); + WriteServ(user->fd,"PONG %s :%s",Config->ServerName,parameters[0]); } void handle_pong(char **parameters, int pcnt, userrec *user) @@ -1317,7 +1271,7 @@ void handle_trace(char **parameters, int pcnt, userrec *user) void handle_modules(char **parameters, int pcnt, userrec *user) { - for (unsigned int i = 0; i < module_names.size(); i++) + for (unsigned int i = 0; i < Config->module_names.size(); i++) { Version V = modules[i]->GetVersion(); char modulename[MAXBUF]; @@ -1333,7 +1287,7 @@ void handle_modules(char **parameters, int pcnt, userrec *user) strlcat(flagstate,", service provider",MAXBUF); if (!flagstate[0]) strcpy(flagstate," "); - strlcpy(modulename,module_names[i].c_str(),256); + strlcpy(modulename,Config->module_names[i].c_str(),256); if (strchr(user->modes,'o')) { WriteServ(user->fd,"900 %s :0x%08lx %d.%d.%d.%d %s (%s)",user->nick,modules[i],V.Major,V.Minor,V.Revision,V.Build,CleanFilename(modulename),flagstate+2); @@ -1369,9 +1323,9 @@ void handle_stats(char **parameters, int pcnt, userrec *user) if (*parameters[0] == 'i') { int idx = 0; - for (ClassVector::iterator i = Classes.begin(); i != Classes.end(); i++) + for (ClassVector::iterator i = Config->Classes.begin(); i != Config->Classes.end(); i++) { - WriteServ(user->fd,"215 %s I * * * %d %d %s *",user->nick,MAXCLIENTS,idx,ServerName); + WriteServ(user->fd,"215 %s I * * * %d %d %s *",user->nick,MAXCLIENTS,idx,Config->ServerName); idx++; } } @@ -1379,7 +1333,7 @@ void handle_stats(char **parameters, int pcnt, userrec *user) if (*parameters[0] == 'y') { int idx = 0; - for (ClassVector::iterator i = Classes.begin(); i != Classes.end(); i++) + for (ClassVector::iterator i = Config->Classes.begin(); i != Config->Classes.end(); i++) { WriteServ(user->fd,"218 %s Y %d %d 0 %d %d",user->nick,idx,120,i->flood,i->registration_timeout); idx++; @@ -1389,9 +1343,9 @@ void handle_stats(char **parameters, int pcnt, userrec *user) if (*parameters[0] == 'U') { char ulined[MAXBUF]; - for (int i = 0; i < ConfValueEnum("uline",&config_f); i++) + for (int i = 0; i < Config->ConfValueEnum("uline",&Config->config_f); i++) { - ConfValue("uline","server",i,ulined,&config_f); + Config->ConfValue("uline","server",i,ulined,&Config->config_f); WriteServ(user->fd,"248 %s U %s",user->nick,ulined); } } @@ -1459,7 +1413,7 @@ void handle_stats(char **parameters, int pcnt, userrec *user) WriteServ(user->fd,"249 %s :Users(HASH_MAP) %d (%d bytes, %d buckets)",user->nick,clientlist.size(),clientlist.size()*sizeof(userrec),clientlist.bucket_count()); WriteServ(user->fd,"249 %s :Channels(HASH_MAP) %d (%d bytes, %d buckets)",user->nick,chanlist.size(),chanlist.size()*sizeof(chanrec),chanlist.bucket_count()); WriteServ(user->fd,"249 %s :Commands(VECTOR) %d (%d bytes)",user->nick,cmdlist.size(),cmdlist.size()*sizeof(command_t)); - WriteServ(user->fd,"249 %s :MOTD(VECTOR) %d, RULES(VECTOR) %d",user->nick,MOTD.size(),RULES.size()); + WriteServ(user->fd,"249 %s :MOTD(VECTOR) %d, RULES(VECTOR) %d",user->nick,Config->MOTD.size(),Config->RULES.size()); WriteServ(user->fd,"249 %s :address_cache(HASH_MAP) %d (%d buckets)",user->nick,IP.size(),IP.bucket_count()); WriteServ(user->fd,"249 %s :Modules(VECTOR) %d (%d)",user->nick,modules.size(),modules.size()*sizeof(Module)); WriteServ(user->fd,"249 %s :ClassFactories(VECTOR) %d (%d)",user->nick,factory.size(),factory.size()*sizeof(ircd_module)); @@ -1476,25 +1430,25 @@ void handle_stats(char **parameters, int pcnt, userrec *user) if (*parameters[0] == 'T') { - WriteServ(user->fd,"249 Brain :accepts %d refused %d",statsAccept,statsRefused); - WriteServ(user->fd,"249 Brain :unknown commands %d",statsUnknown); - WriteServ(user->fd,"249 Brain :nick collisions %d",statsCollisions); - WriteServ(user->fd,"249 Brain :dns requests %d succeeded %d failed %d",statsDns,statsDnsGood,statsDnsBad); - WriteServ(user->fd,"249 Brain :connections %d",statsConnects); - WriteServ(user->fd,"249 Brain :bytes sent %dK recv %dK",(statsSent / 1024),(statsRecv / 1024)); + WriteServ(user->fd,"249 Brain :accepts %d refused %d",stats->statsAccept,stats->statsRefused); + WriteServ(user->fd,"249 Brain :unknown commands %d",stats->statsUnknown); + WriteServ(user->fd,"249 Brain :nick collisions %d",stats->statsCollisions); + WriteServ(user->fd,"249 Brain :dns requests %d succeeded %d failed %d",stats->statsDns,stats->statsDnsGood,stats->statsDnsBad); + WriteServ(user->fd,"249 Brain :connections %d",stats->statsConnects); + WriteServ(user->fd,"249 Brain :bytes sent %dK recv %dK",(stats->statsSent / 1024),(stats->statsRecv / 1024)); } /* stats o */ if (*parameters[0] == 'o') { - for (int i = 0; i < ConfValueEnum("oper",&config_f); i++) + for (int i = 0; i < Config->ConfValueEnum("oper",&Config->config_f); i++) { char LoginName[MAXBUF]; char HostName[MAXBUF]; char OperType[MAXBUF]; - ConfValue("oper","name",i,LoginName,&config_f); - ConfValue("oper","host",i,HostName,&config_f); - ConfValue("oper","type",i,OperType,&config_f); + Config->ConfValue("oper","name",i,LoginName,&Config->config_f); + Config->ConfValue("oper","host",i,HostName,&Config->config_f); + Config->ConfValue("oper","type",i,OperType,&Config->config_f); WriteServ(user->fd,"243 %s O %s * %s %s 0",user->nick,HostName,LoginName,OperType); } } @@ -1553,7 +1507,7 @@ void handle_squit(char **parameters, int pcnt, userrec *user) void handle_links(char **parameters, int pcnt, userrec *user) { - WriteServ(user->fd,"364 %s %s %s :0 %s",user->nick,ServerName,ServerName,ServerDesc); + WriteServ(user->fd,"364 %s %s %s :0 %s",user->nick,Config->ServerName,Config->ServerName,Config->ServerDesc); WriteServ(user->fd,"365 %s * :End of /LINKS list.",user->nick); } @@ -1562,7 +1516,7 @@ void handle_map(char **parameters, int pcnt, userrec *user) // as with /LUSERS this does nothing without a linking // module to override its behaviour and display something // better. - WriteServ(user->fd,"006 %s :%s",user->nick,ServerName); + WriteServ(user->fd,"006 %s :%s",user->nick,Config->ServerName); WriteServ(user->fd,"007 %s :End of /MAP",user->nick); } @@ -1575,9 +1529,9 @@ bool is_uline(const char* server) if (!(*server)) return true; - for (int i = 0; i < ConfValueEnum("uline",&config_f); i++) + for (int i = 0; i < Config->ConfValueEnum("uline",&Config->config_f); i++) { - ConfValue("uline","server",i,ServName,&config_f); + Config->ConfValue("uline","server",i,ServName,&Config->config_f); if (!strcasecmp(server,ServName)) { return true; @@ -1612,23 +1566,23 @@ void handle_oper(char **parameters, int pcnt, userrec *user) snprintf(TheHost,MAXBUF,"%s@%s",user->ident,user->host); - for (int i = 0; i < ConfValueEnum("oper",&config_f); i++) + for (int i = 0; i < Config->ConfValueEnum("oper",&Config->config_f); i++) { - ConfValue("oper","name",i,LoginName,&config_f); - ConfValue("oper","password",i,Password,&config_f); - ConfValue("oper","type",i,OperType,&config_f); - ConfValue("oper","host",i,HostName,&config_f); + Config->ConfValue("oper","name",i,LoginName,&Config->config_f); + Config->ConfValue("oper","password",i,Password,&Config->config_f); + Config->ConfValue("oper","type",i,OperType,&Config->config_f); + Config->ConfValue("oper","host",i,HostName,&Config->config_f); if ((!strcmp(LoginName,parameters[0])) && (!operstrcmp(Password,parameters[1])) && (match(TheHost,HostName))) { fail2 = true; - for (j =0; j < ConfValueEnum("type",&config_f); j++) + for (j =0; j < Config->ConfValueEnum("type",&Config->config_f); j++) { - ConfValue("type","name",j,TypeName,&config_f); + Config->ConfValue("type","name",j,TypeName,&Config->config_f); if (!strcmp(TypeName,OperType)) { /* found this oper's opertype */ - ConfValue("type","host",j,HostName,&config_f); + Config->ConfValue("type","host",j,HostName,&Config->config_f); if (*HostName) ChangeDisplayedHost(user,HostName); strlcpy(user->oper,TypeName,NICKMAX); @@ -1852,11 +1806,93 @@ long duration(const char* str) return total; } +/* All other ircds when doing this check usually just look for a string of *@* or *. We're smarter than that, though. */ + +bool host_matches_everyone(std::string mask, userrec* user) +{ + char insanemasks[MAXBUF]; + char buffer[MAXBUF]; + char itrigger[MAXBUF]; + Config->ConfValue("insane","hostmasks",0,insanemasks,&Config->config_f); + Config->ConfValue("insane","trigger",0,itrigger,&Config->config_f); + if (*itrigger == 0) + strlcpy(itrigger,"95.5",MAXBUF); + if ((*insanemasks == 'y') || (*insanemasks == 't') || (*insanemasks == '1')) + return false; + long matches = 0; + for (user_hash::iterator u = clientlist.begin(); u != clientlist.end(); u++) + { + strlcpy(buffer,u->second->ident,MAXBUF); + strlcat(buffer,"@",MAXBUF); + strlcat(buffer,u->second->host,MAXBUF); + if (match(buffer,mask.c_str())) + matches++; + } + float percent = ((float)matches / (float)clientlist.size()) * 100; + if (percent > (float)atof(itrigger)) + { + WriteOpers("*** \2WARNING\2: %s tried to set a G/K/E line mask of %s, which covers %.2f%% of the network!",user->nick,mask.c_str(),percent); + return true; + } + return false; +} + +bool ip_matches_everyone(std::string ip, userrec* user) +{ + char insanemasks[MAXBUF]; + char itrigger[MAXBUF]; + Config->ConfValue("insane","ipmasks",0,insanemasks,&Config->config_f); + Config->ConfValue("insane","trigger",0,itrigger,&Config->config_f); + if (*itrigger == 0) + strlcpy(itrigger,"95.5",MAXBUF); + if ((*insanemasks == 'y') || (*insanemasks == 't') || (*insanemasks == '1')) + return false; + long matches = 0; + for (user_hash::iterator u = clientlist.begin(); u != clientlist.end(); u++) + { + if (match(u->second->ip,ip.c_str())) + matches++; + } + float percent = ((float)matches / (float)clientlist.size()) * 100; + if (percent > (float)atof(itrigger)) + { + WriteOpers("*** \2WARNING\2: %s tried to set a Z line mask of %s, which covers %.2f%% of the network!",user->nick,ip.c_str(),percent); + return true; + } + return false; +} + +bool nick_matches_everyone(std::string nick, userrec* user) +{ + char insanemasks[MAXBUF]; + char itrigger[MAXBUF]; + Config->ConfValue("insane","nickmasks",0,insanemasks,&Config->config_f); + Config->ConfValue("insane","trigger",0,itrigger,&Config->config_f); + if (*itrigger == 0) + strlcpy(itrigger,"95.5",MAXBUF); + if ((*insanemasks == 'y') || (*insanemasks == 't') || (*insanemasks == '1')) + return false; + long matches = 0; + for (user_hash::iterator u = clientlist.begin(); u != clientlist.end(); u++) + { + if (match(u->second->nick,nick.c_str())) + matches++; + } + float percent = ((float)matches / (float)clientlist.size()) * 100; + if (percent > (float)atof(itrigger)) + { + WriteOpers("*** \2WARNING\2: %s tried to set a Q line mask of %s, which covers %.2f%% of the network!",user->nick,nick.c_str(),percent); + return true; + } + return false; +} void handle_kline(char **parameters, int pcnt, userrec *user) { if (pcnt >= 3) { + if (host_matches_everyone(parameters[0],user)) + return; add_kline(duration(parameters[1]),user->nick,parameters[2],parameters[0]); FOREACH_MOD OnAddKLine(duration(parameters[1]), user, parameters[2], parameters[0]); if (!duration(parameters[1])) @@ -1867,6 +1903,7 @@ void handle_kline(char **parameters, int pcnt, userrec *user) { WriteOpers("*** %s added timed K-line for %s, expires in %d seconds.",user->nick,parameters[0],duration(parameters[1])); } + apply_lines(APPLY_KLINES); } else { @@ -1880,13 +1917,14 @@ void handle_kline(char **parameters, int pcnt, userrec *user) WriteServ(user->fd,"NOTICE %s :*** K-Line %s not found in list, try /stats k.",user->nick,parameters[0]); } } - apply_lines(); } void handle_eline(char **parameters, int pcnt, userrec *user) { if (pcnt >= 3) { + if (host_matches_everyone(parameters[0],user)) + return; add_eline(duration(parameters[1]),user->nick,parameters[2],parameters[0]); FOREACH_MOD OnAddELine(duration(parameters[1]), user, parameters[2], parameters[0]); if (!duration(parameters[1])) @@ -1917,6 +1955,8 @@ void handle_gline(char **parameters, int pcnt, userrec *user) { if (pcnt >= 3) { + if (host_matches_everyone(parameters[0],user)) + return; add_gline(duration(parameters[1]),user->nick,parameters[2],parameters[0]); FOREACH_MOD OnAddGLine(duration(parameters[1]), user, parameters[2], parameters[0]); if (!duration(parameters[1])) @@ -1927,6 +1967,7 @@ void handle_gline(char **parameters, int pcnt, userrec *user) { WriteOpers("*** %s added timed G-line for %s, expires in %d seconds.",user->nick,parameters[0],duration(parameters[1])); } + apply_lines(APPLY_GLINES); } else { @@ -1940,13 +1981,19 @@ void handle_gline(char **parameters, int pcnt, userrec *user) WriteServ(user->fd,"NOTICE %s :*** G-Line %s not found in list, try /stats g.",user->nick,parameters[0]); } } - apply_lines(); } void handle_zline(char **parameters, int pcnt, userrec *user) { if (pcnt >= 3) { + if (strchr(parameters[0],'@')) + { + WriteServ(user->fd,"NOTICE %s :*** You cannot include a username in a zline, a zline must ban only an IP mask",user->nick); + return; + } + if (ip_matches_everyone(parameters[0],user)) + return; add_zline(duration(parameters[1]),user->nick,parameters[2],parameters[0]); FOREACH_MOD OnAddZLine(duration(parameters[1]), user, parameters[2], parameters[0]); if (!duration(parameters[1])) @@ -1957,6 +2004,7 @@ void handle_zline(char **parameters, int pcnt, userrec *user) { WriteOpers("*** %s added timed Z-line for %s, expires in %d seconds.",user->nick,parameters[0],duration(parameters[1])); } + apply_lines(APPLY_ZLINES); } else { @@ -1970,13 +2018,14 @@ void handle_zline(char **parameters, int pcnt, userrec *user) WriteServ(user->fd,"NOTICE %s :*** Z-Line %s not found in list, try /stats Z.",user->nick,parameters[0]); } } - apply_lines(); } void handle_qline(char **parameters, int pcnt, userrec *user) { if (pcnt >= 3) { + if (nick_matches_everyone(parameters[0],user)) + return; add_qline(duration(parameters[1]),user->nick,parameters[2],parameters[0]); FOREACH_MOD OnAddQLine(duration(parameters[1]), user, parameters[2], parameters[0]); if (!duration(parameters[1])) @@ -1987,6 +2036,7 @@ void handle_qline(char **parameters, int pcnt, userrec *user) { WriteOpers("*** %s added timed Q-line for %s, expires in %d seconds.",user->nick,parameters[0],duration(parameters[1])); } + apply_lines(APPLY_QLINES); } else { @@ -1997,10 +2047,9 @@ void handle_qline(char **parameters, int pcnt, userrec *user) } else { - WriteServ(user->fd,"NOTICE %s :*** Q-Line %s not found in list, try /stats k.",user->nick,parameters[0]); + WriteServ(user->fd,"NOTICE %s :*** Q-Line %s not found in list, try /stats q.",user->nick,parameters[0]); } } - apply_lines(); }