X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Finspircd.cpp;h=d69aa6a1e1e332818a396e9e3a7acb7a45a29f9e;hb=3d7312f8af1becdbe458392e14ea64c904ee7b92;hp=44b84979c2d26c3d61a858d658f4d0af6ec61f4b;hpb=f6f348468676e053037da8ebeebbef47351202b0;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 44b84979c..d69aa6a1e 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; @@ -191,6 +193,7 @@ char MyExecutable[1024]; int boundPortCount = 0; int portCount = 0, UDPportCount = 0, ports[MAXSOCKS]; int defaultRoute = 0; +char ModPath[MAXBUF]; connection C; @@ -317,7 +320,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 +378,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 +388,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 +424,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 +433,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); } @@ -447,6 +461,82 @@ void ReadConfig(bool bail, userrec* user) log(DEFAULT,"Applying K lines, Q lines and Z lines..."); apply_lines(); log(DEFAULT,"Done reading configuration file, InspIRCd is now running."); + if (!bail) + { + log(DEFAULT,"Adding and removing modules due to rehash..."); + + std::vector old_module_names, new_module_names, added_modules, removed_modules; + + // store the old module names + for (std::vector::iterator t = module_names.begin(); t != module_names.end(); t++) + { + old_module_names.push_back(*t); + } + + // get the new module names + for (int count2 = 0; count2 < ConfValueEnum("module",&config_f); count2++) + { + ConfValue("module","name",count2,Value,&config_f); + new_module_names.push_back(Value); + } + + // now create a list of new modules that are due to be loaded + // and a seperate list of modules which are due to be unloaded + for (std::vector::iterator _new = new_module_names.begin(); _new != new_module_names.end(); _new++) + { + bool added = true; + for (std::vector::iterator old = old_module_names.begin(); old != old_module_names.end(); old++) + { + if (*old == *_new) + added = false; + } + if (added) + added_modules.push_back(*_new); + } + for (std::vector::iterator oldm = old_module_names.begin(); oldm != old_module_names.end(); oldm++) + { + bool removed = true; + for (std::vector::iterator newm = new_module_names.begin(); newm != new_module_names.end(); newm++) + { + if (*newm == *oldm) + removed = false; + } + if (removed) + removed_modules.push_back(*oldm); + } + // now we have added_modules, a vector of modules to be loaded, and removed_modules, a vector of modules + // to be removed. + int rem = 0, add = 0; + if (!removed_modules.empty()) + for (std::vector::iterator removing = removed_modules.begin(); removing != removed_modules.end(); removing++) + { + if (UnloadModule(removing->c_str())) + { + WriteOpers("*** REHASH UNLOADED MODULE: %s",removing->c_str()); + WriteServ(user->fd,"973 %s %s :Module %s successfully unloaded.",user->nick, removing->c_str(), removing->c_str()); + rem++; + } + else + { + WriteServ(user->fd,"972 %s %s :Failed to unload module %s: %s",user->nick, removing->c_str(), removing->c_str(), ModuleError()); + } + } + if (!added_modules.empty()) + for (std::vector::iterator adding = added_modules.begin(); adding != added_modules.end(); adding++) + { + if (LoadModule(adding->c_str())) + { + WriteOpers("*** REHASH LOADED MODULE: %s",adding->c_str()); + WriteServ(user->fd,"975 %s %s :Module %s successfully loaded.",user->nick, adding->c_str(), adding->c_str()); + add++; + } + else + { + WriteServ(user->fd,"974 %s %s :Failed to load module %s: %s",user->nick, adding->c_str(), adding->c_str(), ModuleError()); + } + } + log(DEFAULT,"Successfully unloaded %d of %d modules and loaded %d of %d modules.",rem,removed_modules.size(),add,added_modules.size()); + } } /* write formatted text to a socket, in same format as printf */ @@ -825,6 +915,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) @@ -848,6 +942,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) @@ -867,6 +965,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) @@ -894,6 +996,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) @@ -916,6 +1022,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) @@ -2207,7 +2317,6 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip) strncpy(clientlist[tempnick]->ident, "unknown",9); 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); @@ -2222,10 +2331,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; @@ -2842,7 +2953,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); @@ -2873,6 +2984,24 @@ 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"))) { @@ -2971,7 +3100,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,""); @@ -2998,7 +3127,7 @@ void SetupCommandTable(void) createcommand("WHOWAS",handle_whowas,0,1,""); createcommand("CONNECT",handle_connect,'o',1,""); createcommand("SQUIT",handle_squit,'o',0,""); - createcommand("MODULES",handle_modules,'o',0,""); + createcommand("MODULES",handle_modules,0,0,""); createcommand("LINKS",handle_links,0,0,""); createcommand("MAP",handle_map,0,0,""); createcommand("KLINE",handle_kline,'o',1,""); @@ -3326,10 +3455,56 @@ bool UnloadModule(const char* filename) return false; } +bool DirValid(char* dirandfile) +{ + char work[MAXBUF]; + strlcpy(work,dirandfile,MAXBUF); + int p = strlen(work); + // we just want the dir + while (strlen(work)) + { + if (work[p] == '/') + { + work[p] = '\0'; + break; + } + work[p--] = '\0'; + } + log(DEBUG,"Dir valid: %s",work); + char buffer[MAXBUF], otherdir[MAXBUF]; + // Get the current working directory + if( getcwd( buffer, MAXBUF ) == NULL ) + return false; + chdir(work); + if( getcwd( otherdir, MAXBUF ) == NULL ) + return false; + chdir(buffer); + log(DEBUG,"Dir is really: %s",otherdir); + if (strlen(otherdir) >= strlen(work)) + { + otherdir[strlen(work)] = '\0'; + log(DEBUG,"Compare: '%s' -> '%s'",otherdir,work); + if (!strcmp(otherdir,work)) + { + log(DEBUG,"Match ok"); + return true; + } + log(DEBUG,"No match"); + return false; + } + else return false; +} + bool LoadModule(const char* filename) { char modfile[MAXBUF]; - snprintf(modfile,MAXBUF,"%s/%s",MOD_PATH,filename,&config_f); + snprintf(modfile,MAXBUF,"%s/%s",ModPath,filename); + if (!DirValid(modfile)) + { + log(DEFAULT,"Module %s is not within the modules directory.",modfile); + snprintf(MODERR,MAXBUF,"Module %s is not within the modules directory.",modfile); + return false; + } log(DEBUG,"Loading module: %s",modfile); if (FileExists(modfile)) { @@ -3651,8 +3826,9 @@ int InspIRCd(void) else NetSendToAllExcept(tcp_host,udp_msg); } - FOREACH_MOD OnPacketReceive(udp_msg); - handle_link_packet(udp_msg, tcp_host, me[x]); + std::string msg = udp_msg; + FOREACH_MOD OnPacketReceive(msg,tcp_host); + strlcpy(udp_msg,msg.c_str(),MAXBUF); } goto label; } @@ -3716,7 +3892,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++;