X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Finspircd.cpp;h=3e70d27f543eeaecca9f4ffe747ce4272ef1beed;hb=dcb36d77333ce02a792075b6dc51937445bc9852;hp=c0cebd522f86cabc7a4b95575c50e8bccd8ddbb3;hpb=034c2c65df4fad4efe08f2a3f332b5772d59c607;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/inspircd.cpp b/src/inspircd.cpp index c0cebd522..3e70d27f5 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -89,6 +89,8 @@ extern int MaxWhoResults; time_t nb_start = 0; int dns_timeout = 5; +char DisabledCommands[MAXBUF]; + bool AllowHalfop = true; bool AllowProtect = true; bool AllowFounder = true; @@ -101,6 +103,7 @@ std::vector fd_reap; extern int MODCOUNT; int openSockfd[MAXSOCKS]; bool nofork = false; +bool unlimitcore = false; time_t TIME = time(NULL); @@ -191,6 +194,7 @@ char MyExecutable[1024]; int boundPortCount = 0; int portCount = 0, UDPportCount = 0, ports[MAXSOCKS]; int defaultRoute = 0; +char ModPath[MAXBUF]; connection C; @@ -317,7 +321,7 @@ void readfile(file_cache &F, const char* fname) void ReadConfig(bool bail, userrec* user) { char dbg[MAXBUF],pauseval[MAXBUF],Value[MAXBUF],timeout[MAXBUF],NB[MAXBUF],flood[MAXBUF],MW[MAXBUF]; - char AH[MAXBUF],AP[MAXBUF],AF[MAXBUF],DNT[MAXBUF]; + char AH[MAXBUF],AP[MAXBUF],AF[MAXBUF],DNT[MAXBUF],pfreq[MAXBUF]; ConnectClass c; std::stringstream errstr; @@ -375,6 +379,9 @@ void ReadConfig(bool bail, userrec* user) ConfValue("options","allowfounder",0,AF,&config_f); ConfValue("dns","server",0,DNSServer,&config_f); ConfValue("dns","timeout",0,DNT,&config_f); + ConfValue("options","moduledir",0,ModPath,&config_f); + ConfValue("disabled","commands",0,DisabledCommands,&config_f); + NetBufferSize = atoi(NB); MaxWhoResults = atoi(MW); dns_timeout = atoi(DNT); @@ -382,6 +389,8 @@ void ReadConfig(bool bail, userrec* user) dns_timeout = 5; if (!strcmp(DNSServer,"")) strlcpy(DNSServer,"127.0.0.1",MAXBUF); + if (!strcmp(ModPath,"")) + strlcpy(ModPath,MOD_PATH,MAXBUF); AllowHalfop = ((!strcasecmp(AH,"true")) || (!strcasecmp(AH,"1")) || (!strcasecmp(AH,"yes"))); AllowProtect = ((!strcasecmp(AP,"true")) || (!strcasecmp(AP,"1")) || (!strcasecmp(AP,"yes"))); AllowFounder = ((!strcasecmp(AF,"true")) || (!strcasecmp(AF,"1")) || (!strcasecmp(AF,"yes"))); @@ -416,6 +425,7 @@ void ReadConfig(bool bail, userrec* user) ConfValue("connect","allow",i,Value,&config_f); ConfValue("connect","timeout",i,timeout,&config_f); ConfValue("connect","flood",i,flood,&config_f); + ConfValue("connect","pingfreq",i,pfreq,&config_f); if (strcmp(Value,"")) { strlcpy(c.host,Value,MAXBUF); @@ -424,11 +434,16 @@ void ReadConfig(bool bail, userrec* user) ConfValue("connect","password",i,Value,&config_f); strlcpy(c.pass,Value,MAXBUF); c.registration_timeout = 90; // default is 2 minutes + c.pingtime = 120; c.flood = atoi(flood); if (atoi(timeout)>0) { c.registration_timeout = atoi(timeout); } + if (atoi(pfreq)>0) + { + c.pingtime = atoi(pfreq); + } Classes.push_back(c); log(DEBUG,"Read connect class type ALLOW, host=%s password=%s timeout=%d flood=%d",c.host,c.pass,c.registration_timeout,c.flood); } @@ -529,6 +544,8 @@ void ReadConfig(bool bail, userrec* user) void Write(int sock,char *text, ...) { + if (sock == FD_MAGIC_NUMBER) + return; if (!text) { log(DEFAULT,"*** BUG *** Write was given an invalid parameter"); @@ -553,6 +570,8 @@ void Write(int sock,char *text, ...) void WriteServ(int sock, char* text, ...) { + if (sock == FD_MAGIC_NUMBER) + return; if (!text) { log(DEFAULT,"*** BUG *** WriteServ was given an invalid parameter"); @@ -576,6 +595,8 @@ void WriteServ(int sock, char* text, ...) void WriteFrom(int sock, userrec *user,char* text, ...) { + if (sock == FD_MAGIC_NUMBER) + return; if ((!text) || (!user)) { log(DEFAULT,"*** BUG *** WriteFrom was given an invalid parameter"); @@ -604,6 +625,8 @@ void WriteTo(userrec *source, userrec *dest,char *data, ...) log(DEFAULT,"*** BUG *** WriteTo was given an invalid parameter"); return; } + if (dest->fd == FD_MAGIC_NUMBER) + return; char textbuffer[MAXBUF],tb[MAXBUF]; va_list argsPtr; va_start (argsPtr, data); @@ -641,7 +664,8 @@ void WriteChannel(chanrec* Ptr, userrec* user, char* text, ...) { if (has_channel(i->second,Ptr)) { - WriteTo(user,i->second,"%s",textbuffer); + if (i->second->fd != FD_MAGIC_NUMBER) + WriteTo(user,i->second,"%s",textbuffer); } } } @@ -666,7 +690,7 @@ void WriteChannelLocal(chanrec* Ptr, userrec* user, char* text, ...) { if (has_channel(i->second,Ptr)) { - if (i->second->fd != -1) + if ((i->second->fd != -1) && (i->second->fd != FD_MAGIC_NUMBER)) { if (!user) { @@ -698,7 +722,7 @@ void WriteChannelWithServ(char* ServerName, chanrec* Ptr, userrec* user, char* t { if (i->second) { - if (has_channel(i->second,Ptr)) + if ((has_channel(i->second,Ptr)) && (i->second->fd != FD_MAGIC_NUMBER)) { WriteServ(i->second->fd,"%s",textbuffer); } @@ -727,7 +751,7 @@ void ChanExceptSender(chanrec* Ptr, userrec* user, char* text, ...) { if (i->second) { - if (has_channel(i->second,Ptr) && (user != i->second)) + if ((has_channel(i->second,Ptr)) && (user != i->second) && (i->second->fd != FD_MAGIC_NUMBER)) { WriteTo(user,i->second,"%s",textbuffer); } @@ -783,7 +807,7 @@ void WriteCommon(userrec *u, char* text, ...) { if (i->second) { - if (common_channels(u,i->second) && (i->second != u)) + if ((common_channels(u,i->second) && (i->second != u)) && (i->second->fd != FD_MAGIC_NUMBER)) { WriteFrom(i->second->fd,u,"%s",textbuffer); } @@ -841,7 +865,7 @@ void WriteOpers(char* text, ...) for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++) { - if (i->second) + if ((i->second) && (i->second->fd != FD_MAGIC_NUMBER)) { if (strchr(i->second->modes,'o')) { @@ -901,6 +925,10 @@ void NetSendToCommon(userrec* u, char* s) log(DEBUG,"NetSendToCommon: '%s' '%s'",u->nick,s); + std::string msg = buffer; + FOREACH_MOD OnPacketTransmit(msg,s); + strlcpy(buffer,msg.c_str(),MAXBUF); + for (int j = 0; j < 32; j++) { if (me[j] != NULL) @@ -924,6 +952,10 @@ void NetSendToAll(char* s) log(DEBUG,"NetSendToAll: '%s'",s); + std::string msg = buffer; + FOREACH_MOD OnPacketTransmit(msg,s); + strlcpy(buffer,msg.c_str(),MAXBUF); + for (int j = 0; j < 32; j++) { if (me[j] != NULL) @@ -943,6 +975,10 @@ void NetSendToAllAlive(char* s) log(DEBUG,"NetSendToAllAlive: '%s'",s); + std::string msg = buffer; + FOREACH_MOD OnPacketTransmit(msg,s); + strlcpy(buffer,msg.c_str(),MAXBUF); + for (int j = 0; j < 32; j++) { if (me[j] != NULL) @@ -970,6 +1006,10 @@ void NetSendToOne(char* target,char* s) log(DEBUG,"NetSendToOne: '%s' '%s'",target,s); + std::string msg = buffer; + FOREACH_MOD OnPacketTransmit(msg,s); + strlcpy(buffer,msg.c_str(),MAXBUF); + for (int j = 0; j < 32; j++) { if (me[j] != NULL) @@ -992,6 +1032,10 @@ void NetSendToAllExcept(const char* target,char* s) log(DEBUG,"NetSendToAllExcept: '%s' '%s'",target,s); + std::string msg = buffer; + FOREACH_MOD OnPacketTransmit(msg,s); + strlcpy(buffer,msg.c_str(),MAXBUF); + for (int j = 0; j < 32; j++) { if (me[j] != NULL) @@ -1024,7 +1068,7 @@ void WriteMode(const char* modes, int flags, const char* text, ...) for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++) { - if (i->second) + if ((i->second) && (i->second->fd != FD_MAGIC_NUMBER)) { bool send_to_user = false; @@ -1079,7 +1123,7 @@ void WriteWallOps(userrec *source, bool local_only, char* text, ...) for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++) { - if (i->second) + if ((i->second) && (i->second->fd != FD_MAGIC_NUMBER)) { if (strchr(i->second->modes,'w')) { @@ -1191,7 +1235,8 @@ void purge_empty_chans(void) if (i != chanlist.end()) { log(DEBUG,"del_channel: destroyed: %s",i->second->name); - if (i->second) delete i->second; + if (i->second) + delete i->second; chanlist.erase(i); go_again = 1; purge++; @@ -1522,7 +1567,7 @@ chanrec* add_channel(userrec *user, const char* cn, const char* key, bool overri if (Ptr->limit) { - if (usercount(Ptr) == Ptr->limit) + if (usercount(Ptr) >= Ptr->limit) { WriteServ(user->fd,"471 %s %s :Cannot join channel (Channel is full)",user->nick, Ptr->name); return NULL; @@ -1735,7 +1780,6 @@ void kick_channel(userrec *src,userrec *user, chanrec *Ptr, char* reason) int MOD_RESULT = 0; FOREACH_RESULT(OnAccessCheck(src,user,Ptr,AC_KICK)); - if (MOD_RESULT == ACR_DENY) return; @@ -1755,7 +1799,14 @@ void kick_channel(userrec *src,userrec *user, chanrec *Ptr, char* reason) return; } } - + + MOD_RESULT = 0; + FOREACH_RESULT(OnUserPreKick(src,user,Ptr,reason)); + if (MOD_RESULT) + return; + + FOREACH_MOD OnUserKick(src,user,Ptr,reason); + for (int i =0; i != MAXCHANS; i++) { /* zap it from the channel list of the user */ @@ -1769,7 +1820,7 @@ void kick_channel(userrec *src,userrec *user, chanrec *Ptr, char* reason) break; } } - + /* if there are no users left on the channel */ if (!usercount(Ptr)) { @@ -2007,7 +2058,7 @@ void kill_link(userrec *user,const char* r) if (user->registered == 7) { purge_empty_chans(); } - user = NULL; + //user = NULL; } void kill_link_silent(userrec *user,const char* r) @@ -2147,6 +2198,9 @@ int main(int argc, char **argv) if (!strcmp(argv[i],"-wait")) { sleep(6); } + if (!strcmp(argv[i],"-nolimit")) { + unlimitcore = true; + } } } strlcpy(MyExecutable,argv[0],MAXBUF); @@ -2280,10 +2334,9 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip) strncpy(clientlist[tempnick]->host, host,160); strncpy(clientlist[tempnick]->dhost, host,160); strncpy(clientlist[tempnick]->server, ServerName,256); - strncpy(clientlist[tempnick]->ident, "unknown",9); + strncpy(clientlist[tempnick]->ident, "unknown",12); clientlist[tempnick]->registered = 0; clientlist[tempnick]->signon = TIME+dns_timeout; - clientlist[tempnick]->nping = TIME+240+dns_timeout; clientlist[tempnick]->lastping = 1; clientlist[tempnick]->port = port; strncpy(clientlist[tempnick]->ip,ip,32); @@ -2298,10 +2351,12 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip) { class_regtimeout = (unsigned long)i->registration_timeout; class_flood = i->flood; + clientlist[tempnick]->pingmax = i->pingtime; break; } } + clientlist[tempnick]->nping = TIME+clientlist[tempnick]->pingmax+dns_timeout; clientlist[tempnick]->timeout = TIME+class_regtimeout; clientlist[tempnick]->flood = class_flood; @@ -2526,11 +2581,26 @@ void FullConnectUser(userrec* user) NetSendToAll(buffer); } + +// this returns 1 when all modules are satisfied that the user should be allowed onto the irc server +// (until this returns true, a user will block in the waiting state, waiting to connect up to the +// registration timeout maximum seconds) +bool AllModulesReportReady(userrec* user) +{ + for (int i = 0; i <= MODCOUNT; i++) + { + int res = modules[i]->OnCheckReady(user); + if (!res) + return false; + } + return true; +} + /* shows the message of the day, and any other on-logon stuff */ void ConnectUser(userrec *user) { // dns is already done, things are fast. no need to wait for dns to complete just pass them straight on - if ((user->dns_done) && (user->registered >= 3)) + if ((user->dns_done) && (user->registered >= 3) && (AllModulesReportReady(user))) { FullConnectUser(user); } @@ -2778,17 +2848,17 @@ void process_command(userrec *user, char* cmd) total_params++; } } - + // another phidjit bug... if (total_params > 126) { - //kill_link(user,"Protocol violation (1)"); - WriteServ(user->fd,"421 %s * :Unknown command",user->nick); + *(strchr(cmd,' ')) = '\0'; + WriteServ(user->fd,"421 %s %s :Too many parameters given",user->nick,cmd); return; } - - strlcpy(temp,cmd,MAXBUF); + strlcpy(temp,cmd,MAXBUF); + std::string tmp = cmd; for (int i = 0; i <= MODCOUNT; i++) { @@ -2866,8 +2936,7 @@ void process_command(userrec *user, char* cmd) if (strlen(command)>MAXCOMMAND) { - //kill_link(user,"Protocol violation (2)"); - WriteServ(user->fd,"421 %s * :Unknown command",user->nick); + WriteServ(user->fd,"421 %s %s :Command too long",user->nick,command); return; } @@ -2879,8 +2948,7 @@ void process_command(userrec *user, char* cmd) { if (strchr("@!\"$%^&*(){}[]_=+;:'#~,<>/?\\|`",command[x])) { - //kill_link(user,"Protocol violation (3)"); - WriteServ(user->fd,"421 %s * :Unknown command",user->nick); + WriteServ(user->fd,"421 %s %s :Unknown command",user->nick,command); return; } } @@ -2918,7 +2986,7 @@ void process_command(userrec *user, char* cmd) log(DEBUG,"Processing command"); /* activity resets the ping pending timer */ - user->nping = TIME + 120; + user->nping = TIME + user->pingmax; if ((items) < cmdlist[i].min_params) { log(DEBUG,"process_command: not enough parameters: %s %s",user->nick,command); @@ -2949,12 +3017,31 @@ void process_command(userrec *user, char* cmd) WriteServ(user->fd,"451 %s :You have not registered",command); return; } + } + if ((user->registered == 7) && (!strchr(user->modes,'o'))) + { + char* mycmd; + char* savept2; + mycmd = strtok_r(DisabledCommands," ",&savept2); + while (mycmd) + { + if (!strcasecmp(mycmd,command)) + { + // command is disabled! + WriteServ(user->fd,"421 %s %s :This command has been disabled.",user->nick,command); + return; + } + mycmd = strtok_r(NULL," ",&savept2); + } + + } if ((user->registered == 7) || (!strcmp(command,"USER")) || (!strcmp(command,"NICK")) || (!strcmp(command,"PASS"))) { log(DEBUG,"process_command: handler: %s %s %d",user->nick,command,items); if (cmdlist[i].handler_function) { + /* ikky /stats counters */ if (temp) { @@ -2969,6 +3056,12 @@ void process_command(userrec *user, char* cmd) cmdlist[i].total_bytes+=strlen(temp); } + int MOD_RESULT = 0; + FOREACH_RESULT(OnPreCommand(command,command_p,items,user)); + if (MOD_RESULT == 1) { + return; + } + /* WARNING: nothing may come after the * command handler call, as the handler * may free the user structure! */ @@ -3047,7 +3140,7 @@ void SetupCommandTable(void) createcommand("WALLOPS",handle_wallops,'o',1,""); createcommand("NOTICE",handle_notice,0,2,""); createcommand("JOIN",handle_join,0,1,""); - createcommand("NAMES",handle_names,0,1,""); + createcommand("NAMES",handle_names,0,0,""); createcommand("PART",handle_part,0,1,""); createcommand("KICK",handle_kick,0,2,""); createcommand("MODE",handle_mode,0,1,""); @@ -3339,6 +3432,48 @@ char* ModuleError() return MODERR; } +void erase_factory(int j) +{ + int v = 0; + for (std::vector::iterator t = factory.begin(); t != factory.end(); t++) + { + if (v == j) + { + factory.erase(t); + factory.push_back(NULL); + return; + } + v++; + } +} + +void erase_module(int j) +{ + int v = 0; + for (std::vector::iterator m = modules.begin(); m!= modules.end(); m++) + { + if (v == j) + { + delete *m; + modules.erase(m); + modules.push_back(NULL); + break; + } + v++; + } + int v2 = 0; + for (std::vector::iterator v = module_names.begin(); v != module_names.end(); v++) + { + if (v2 == j) + { + module_names.erase(v); + break; + } + v2++; + } + +} + bool UnloadModule(const char* filename) { for (int j = 0; j != module_names.size(); j++) @@ -3353,43 +3488,9 @@ bool UnloadModule(const char* filename) } // found the module log(DEBUG,"Deleting module..."); - delete modules[j]; - modules[j] = NULL; - log(DEBUG,"Deleting module factory pointer..."); - delete factory[j]->factory; - log(DEBUG,"Deleting module factory..."); - delete factory[j]; + erase_module(j); log(DEBUG,"Erasing module entry..."); - factory[j] = NULL; - // here we should locate ALL resources claimed by this module... and release them - // for example commands - log(DEBUG,"Erasing module vector..."); - for (std::vector::iterator t = factory.begin(); t != factory.end(); t++) - { - if (*t == NULL) - { - factory.erase(t); - break; - } - } - log(DEBUG,"Erasing module name vector..."); - for (std::vector::iterator v = module_names.begin(); v != module_names.end(); v++) - { - if (*v == std::string(filename)) - { - module_names.erase(v); - break; - } - } - log(DEBUG,"Erasing module pointer..."); - for (std::vector::iterator m = modules.begin(); m!= modules.end(); m++) - { - if (*m == NULL) - { - modules.erase(m); - break; - } - } + erase_factory(j); log(DEBUG,"Removing dependent commands..."); removecommands(filename); log(DEFAULT,"Module %s unloaded",filename); @@ -3445,7 +3546,7 @@ bool DirValid(char* dirandfile) bool LoadModule(const char* filename) { char modfile[MAXBUF]; - snprintf(modfile,MAXBUF,"%s/%s",MOD_PATH,filename); + snprintf(modfile,MAXBUF,"%s/%s",ModPath,filename); if (!DirValid(modfile)) { log(DEFAULT,"Module %s is not within the modules directory.",modfile); @@ -3464,7 +3565,8 @@ bool LoadModule(const char* filename) return false; } } - factory[MODCOUNT+1] = new ircd_module(modfile); + ircd_module* a = new ircd_module(modfile); + factory[MODCOUNT+1] = a; if (factory[MODCOUNT+1]->LastError()) { log(DEFAULT,"Unable to load %s: %s",modfile,factory[MODCOUNT+1]->LastError()); @@ -3474,7 +3576,8 @@ bool LoadModule(const char* filename) } if (factory[MODCOUNT+1]->factory) { - modules[MODCOUNT+1] = factory[MODCOUNT+1]->factory->CreateModule(); + Module* m = factory[MODCOUNT+1]->factory->CreateModule(); + modules[MODCOUNT+1] = m; /* save the module and the module's classfactory, if * this isnt done, random crashes can occur :/ */ module_names.push_back(filename); @@ -3681,14 +3784,14 @@ int InspIRCd(void) // we only read time() once per iteration rather than tons of times! TIME = time(NULL); - user_hash::iterator count2 = clientlist.begin(); - // *FIX* Instead of closing sockets in kill_link when they receive the ERROR :blah line, we should queue // them in a list, then reap the list every second or so. if (((TIME % 5) == 0) && (!expire_run)) { expire_lines(); + FOREACH_MOD OnBackgroundTimer(TIME); expire_run = true; + continue; } if ((TIME % 5) == 1) expire_run = false; @@ -3698,16 +3801,20 @@ int InspIRCd(void) { for( int n = 0; n < fd_reap.size(); n++) { - //Blocking(fd_reap[n]); - close(fd_reap[n]); - shutdown (fd_reap[n],2); - //NonBlocking(fd_reap[n]); + if ((fd_reap[n] > -1)) + { + close(fd_reap[n]); + shutdown (fd_reap[n],2); + } } } fd_reap.clear(); reap_counter=0; } reap_counter++; + + // fix by brain - this must be below any manipulation of the hashmap by modules + user_hash::iterator count2 = clientlist.begin(); FD_ZERO(&serverfds); @@ -3720,6 +3827,7 @@ int InspIRCd(void) // serverFds timevals went here tvs.tv_usec = 7000L; + tvs.tv_sec = 0; int servresult = select(32767, &serverfds, NULL, NULL, &tvs); if (servresult > 0) { @@ -3755,6 +3863,7 @@ int InspIRCd(void) { char udp_msg[MAXBUF]; strlcpy(udp_msg,msgs[ctr].c_str(),MAXBUF); + log(DEBUG,"Processing: %s",udp_msg); if (strlen(udp_msg)<1) { log(DEBUG,"Invalid string from %s [route%d]",tcp_host,x); @@ -3773,7 +3882,9 @@ int InspIRCd(void) else NetSendToAllExcept(tcp_host,udp_msg); } - FOREACH_MOD OnPacketReceive(udp_msg); + std::string msg = udp_msg; + FOREACH_MOD OnPacketReceive(msg,tcp_host); + strlcpy(udp_msg,msg.c_str(),MAXBUF); handle_link_packet(udp_msg, tcp_host, me[x]); } goto label; @@ -3790,7 +3901,7 @@ int InspIRCd(void) user_hash::iterator endingiter = count2; if (count2 == clientlist.end()) break; - + if (count2->second) if (count2->second->fd != 0) { @@ -3804,7 +3915,7 @@ int InspIRCd(void) if (count2 != clientlist.end()) { // we don't check the state of remote users. - if (count2->second->fd > 0) + if ((count2->second->fd != -1) && (count2->second->fd != FD_MAGIC_NUMBER)) { FD_SET (count2->second->fd, &sfd); @@ -3816,14 +3927,16 @@ int InspIRCd(void) kill_link(count2->second,"Registration timeout"); goto label; } - if ((TIME > count2->second->signon) && (count2->second->registered == 3)) + if ((TIME > count2->second->signon) && (count2->second->registered == 3) && (AllModulesReportReady(count2->second))) { - count2->second->dns_done = true; - FullConnectUser(count2->second); - goto label; + log(DEBUG,"signon exceed, registered=3, and modules ready, OK"); + count2->second->dns_done = true; + FullConnectUser(count2->second); + goto label; } - if ((count2->second->dns_done) && (count2->second->registered == 3)) // both NICK and USER... and DNS + if ((count2->second->dns_done) && (count2->second->registered == 3) && (AllModulesReportReady(count2->second))) // both NICK and USER... and DNS { + log(DEBUG,"dns done, registered=3, and modules ready, OK"); FullConnectUser(count2->second); goto label; } @@ -3838,7 +3951,7 @@ int InspIRCd(void) Write(count2->second->fd,"PING :%s",ServerName); log(DEBUG,"InspIRCd: pinging: %s",count2->second->nick); count2->second->lastping = 0; - count2->second->nping = TIME+120; + count2->second->nping = TIME+count2->second->pingmax; // was hard coded to 120 } } count2++; @@ -3867,13 +3980,21 @@ int InspIRCd(void) #endif result = EAGAIN; - if ((count2a->second->fd != -1) && (FD_ISSET (count2a->second->fd, &sfd))) + if ((count2a->second->fd != FD_MAGIC_NUMBER) && (count2a->second->fd != -1) && (FD_ISSET (count2a->second->fd, &sfd))) { memset(data, 0, 10240); result = read(count2a->second->fd, data, 10240); if (result) { + // perform a check on the raw buffer as an array (not a string!) to remove + // characters 0 and 7 which are illegal in the RFC - replace them with spaces. + // hopefully this should stop even more people whining about "Unknown command: *" + for (int checker = 0; checker < result; checker++) + { + if ((data[checker] == 0) || (data[checker] == 7)) + data[checker] = ' '; + } userrec* current = count2a->second; int currfd = current->fd; char* l = strtok(data,"\n"); @@ -4004,7 +4125,7 @@ int InspIRCd(void) } } label: - if(0) {}; // "Label must be followed by a statement"... so i gave it one. + if (0) {}; } /* not reached */ close (incomingSockfd);