X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fhelperfuncs.cpp;h=6b7178e225b9f9b9b25f8bcd54e4cf15801531f5;hb=59b1a8955142935b02af6446005ab47fc7c3fc8c;hp=c2a323a7c64ea147c4da36d6e44f6fd42c619f80;hpb=37edb225d7de2592c0a229ce18654d2eb2992f72;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/helperfuncs.cpp b/src/helperfuncs.cpp index c2a323a7c..6b7178e22 100644 --- a/src/helperfuncs.cpp +++ b/src/helperfuncs.cpp @@ -2,7 +2,7 @@ * | Inspire Internet Relay Chat Daemon | * +------------------------------------+ * - * Inspire is copyright (C) 2002-2004 ChatSpike-Dev. + * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev. * E-mail: * * @@ -56,8 +56,8 @@ extern InspIRCd* ServerInstance; extern time_t TIME; extern char lowermap[255]; static char list[MAXBUF]; -extern userrec* fd_ref_table[65536]; -static char already_sent[65536]; +extern userrec* fd_ref_table[MAX_DESCRIPTORS]; +static char already_sent[MAX_DESCRIPTORS]; extern std::vector all_opers; extern user_hash clientlist; extern chan_hash chanlist; @@ -125,7 +125,7 @@ void readfile(file_cache &F, const char* fname) void Write_NoFormat(int sock, const char *text) { - if ((sock < 0) || (!text)) + if ((sock < 0) || (!text) || (sock > MAX_DESCRIPTORS)) return; char tb[MAXBUF]; @@ -135,7 +135,14 @@ void Write_NoFormat(int sock, const char *text) { if (Config->GetIOHook(fd_ref_table[sock]->port)) { - Config->GetIOHook(fd_ref_table[sock]->port)->OnRawSocketWrite(sock,tb,bytes); + try + { + Config->GetIOHook(fd_ref_table[sock]->port)->OnRawSocketWrite(sock,tb,bytes); + } + catch (ModuleException& modexcept) + { + log(DEBUG,"Module exception cought: %s",modexcept.GetReason()); \ + } } else { @@ -148,7 +155,7 @@ void Write_NoFormat(int sock, const char *text) void Write(int sock,char *text, ...) { - if (sock < 0) + if ((sock < 0) || (sock > MAX_DESCRIPTORS)) return; if (!text) { @@ -166,7 +173,14 @@ void Write(int sock,char *text, ...) { if (Config->GetIOHook(fd_ref_table[sock]->port)) { - Config->GetIOHook(fd_ref_table[sock]->port)->OnRawSocketWrite(sock,tb,bytes); + try + { + Config->GetIOHook(fd_ref_table[sock]->port)->OnRawSocketWrite(sock,tb,bytes); + } + catch (ModuleException& modexcept) + { + log(DEBUG,"Module exception cought: %s",modexcept.GetReason()); \ + } } else { @@ -179,7 +193,7 @@ void Write(int sock,char *text, ...) void WriteServ_NoFormat(int sock, const char* text) { - if ((sock < 0) || (!text)) + if ((sock < 0) || (!text) || (sock > MAX_DESCRIPTORS)) return; char tb[MAXBUF]; int bytes = snprintf(tb,MAXBUF,":%s %s\r\n",Config->ServerName,text); @@ -188,7 +202,14 @@ void WriteServ_NoFormat(int sock, const char* text) { if (Config->GetIOHook(fd_ref_table[sock]->port)) { - Config->GetIOHook(fd_ref_table[sock]->port)->OnRawSocketWrite(sock,tb,bytes); + try + { + Config->GetIOHook(fd_ref_table[sock]->port)->OnRawSocketWrite(sock,tb,bytes); + } + catch (ModuleException& modexcept) + { + log(DEBUG,"Module exception cought: %s",modexcept.GetReason()); \ + } } else { @@ -203,7 +224,7 @@ void WriteServ_NoFormat(int sock, const char* text) void WriteServ(int sock, char* text, ...) { - if (sock < 0) + if ((sock < 0) || (sock > MAX_DESCRIPTORS)) return; if (!text) { @@ -221,7 +242,14 @@ void WriteServ(int sock, char* text, ...) { if (Config->GetIOHook(fd_ref_table[sock]->port)) { - Config->GetIOHook(fd_ref_table[sock]->port)->OnRawSocketWrite(sock,tb,bytes); + try + { + Config->GetIOHook(fd_ref_table[sock]->port)->OnRawSocketWrite(sock,tb,bytes); + } + catch (ModuleException& modexcept) + { + log(DEBUG,"Module exception cought: %s",modexcept.GetReason()); \ + } } else { @@ -234,16 +262,23 @@ void WriteServ(int sock, char* text, ...) void WriteFrom_NoFormat(int sock, userrec *user, const char* text) { - if ((sock < 0) || (!text) || (!user)) + if ((sock < 0) || (!text) || (!user) || (sock > MAX_DESCRIPTORS)) return; char tb[MAXBUF]; - int bytes = snprintf(tb,MAXBUF,":%s!%s@%s %s\r\n",user->nick,user->ident,user->dhost,text); + int bytes = snprintf(tb,MAXBUF,":%s %s\r\n",user->GetFullHost(),text); chop(tb); if (fd_ref_table[sock]) { if (Config->GetIOHook(fd_ref_table[sock]->port)) { - Config->GetIOHook(fd_ref_table[sock]->port)->OnRawSocketWrite(sock,tb,bytes); + try + { + Config->GetIOHook(fd_ref_table[sock]->port)->OnRawSocketWrite(sock,tb,bytes); + } + catch (ModuleException& modexcept) + { + log(DEBUG,"Module exception cought: %s",modexcept.GetReason()); \ + } } else { @@ -258,7 +293,7 @@ void WriteFrom_NoFormat(int sock, userrec *user, const char* text) void WriteFrom(int sock, userrec *user,char* text, ...) { - if (sock < 0) + if ((sock < 0) || (sock > MAX_DESCRIPTORS)) return; if ((!text) || (!user)) { @@ -270,13 +305,20 @@ void WriteFrom(int sock, userrec *user,char* text, ...) char textbuffer[MAXBUF],tb[MAXBUF]; vsnprintf(textbuffer, MAXBUF, text, argsPtr); va_end(argsPtr); - int bytes = snprintf(tb,MAXBUF,":%s!%s@%s %s\r\n",user->nick,user->ident,user->dhost,textbuffer); + int bytes = snprintf(tb,MAXBUF,":%s %s\r\n",user->GetFullHost(),textbuffer); chop(tb); if (fd_ref_table[sock]) { if (Config->GetIOHook(fd_ref_table[sock]->port)) { - Config->GetIOHook(fd_ref_table[sock]->port)->OnRawSocketWrite(sock,tb,bytes); + try + { + Config->GetIOHook(fd_ref_table[sock]->port)->OnRawSocketWrite(sock,tb,bytes); + } + catch (ModuleException& modexcept) + { + log(DEBUG,"Module exception cought: %s",modexcept.GetReason()); \ + } } else { @@ -308,7 +350,7 @@ void WriteTo(userrec *source, userrec *dest,char *data, ...) // if no source given send it from the server. if (!source) { - WriteServ(dest->fd,":%s %s",Config->ServerName,textbuffer); + WriteServ_NoFormat(dest->fd,textbuffer); } else { @@ -322,7 +364,7 @@ void WriteTo_NoFormat(userrec *source, userrec *dest, const char *data) return; if (!source) { - WriteServ(dest->fd,":%s %s",Config->ServerName,data); + WriteServ_NoFormat(dest->fd,data); } else { @@ -346,11 +388,10 @@ void WriteChannel(chanrec* Ptr, userrec* user, char* text, ...) vsnprintf(textbuffer, MAXBUF, text, argsPtr); va_end(argsPtr); - std::vector *ulist = Ptr->GetUsers(); - unsigned int x = ulist->size(); - for (unsigned int j = 0; j < x; j++) + std::map *ulist= Ptr->GetUsers(); + for (std::map::iterator i = ulist->begin(); i != ulist->end(); i++) { - char* o = (*ulist)[j]; + char* o = i->second; userrec* otheruser = (userrec*)o; if (otheruser->fd != FD_MAGIC_NUMBER) WriteTo_NoFormat(user,otheruser,textbuffer); @@ -364,11 +405,10 @@ void WriteChannel_NoFormat(chanrec* Ptr, userrec* user, const char* text) log(DEFAULT,"*** BUG *** WriteChannel was given an invalid parameter"); return; } - std::vector *ulist = Ptr->GetUsers(); - unsigned int x = ulist->size(); - for (unsigned int j = 0; j < x; j++) + std::map *ulist= Ptr->GetUsers(); + for (std::map::iterator i = ulist->begin(); i != ulist->end(); i++) { - char* o = (*ulist)[j]; + char* o = i->second; userrec* otheruser = (userrec*)o; if (otheruser->fd != FD_MAGIC_NUMBER) WriteTo_NoFormat(user,otheruser,text); @@ -393,11 +433,10 @@ void WriteChannelLocal(chanrec* Ptr, userrec* user, char* text, ...) vsnprintf(textbuffer, MAXBUF, text, argsPtr); va_end(argsPtr); - std::vector *ulist = Ptr->GetUsers(); - unsigned int x = ulist->size(); - for (unsigned int j = 0; j < x; j++) + std::map *ulist= Ptr->GetUsers(); + for (std::map::iterator i = ulist->begin(); i != ulist->end(); i++) { - char* o = (*ulist)[j]; + char* o = i->second; userrec* otheruser = (userrec*)o; if ((otheruser->fd != FD_MAGIC_NUMBER) && (otheruser != user)) { @@ -420,11 +459,10 @@ void WriteChannelLocal_NoFormat(chanrec* Ptr, userrec* user, const char* text) log(DEFAULT,"*** BUG *** WriteChannel was given an invalid parameter"); return; } - std::vector *ulist = Ptr->GetUsers(); - unsigned int x = ulist->size(); - for (unsigned int j = 0; j < x; j++) + std::map *ulist= Ptr->GetUsers(); + for (std::map::iterator i = ulist->begin(); i != ulist->end(); i++) { - char* o = (*ulist)[j]; + char* o = i->second; userrec* otheruser = (userrec*)o; if ((otheruser->fd != FD_MAGIC_NUMBER) && (otheruser != user)) { @@ -456,11 +494,10 @@ void WriteChannelWithServ(char* ServName, chanrec* Ptr, char* text, ...) va_end(argsPtr); - std::vector *ulist = Ptr->GetUsers(); - unsigned int x = ulist->size(); - for (unsigned int j = 0; j < x; j++) + std::map *ulist= Ptr->GetUsers(); + for (std::map::iterator i = ulist->begin(); i != ulist->end(); i++) { - char* o = (*ulist)[j]; + char* o = i->second; userrec* otheruser = (userrec*)o; if (IS_LOCAL(otheruser)) WriteServ_NoFormat(otheruser->fd,textbuffer); @@ -474,11 +511,10 @@ void WriteChannelWithServ_NoFormat(char* ServName, chanrec* Ptr, const char* tex log(DEFAULT,"*** BUG *** WriteChannelWithServ was given an invalid parameter"); return; } - std::vector *ulist = Ptr->GetUsers(); - unsigned int x = ulist->size(); - for (unsigned int j = 0; j < x; j++) + std::map *ulist= Ptr->GetUsers(); + for (std::map::iterator i = ulist->begin(); i != ulist->end(); i++) { - char* o = (*ulist)[j]; + char* o = i->second; userrec* otheruser = (userrec*)o; if (IS_LOCAL(otheruser)) WriteServ_NoFormat(otheruser->fd,text); @@ -490,7 +526,7 @@ void WriteChannelWithServ_NoFormat(char* ServName, chanrec* Ptr, const char* tex /* write formatted text from a source user to all users on a channel except * for the sender (for privmsg etc) */ -void ChanExceptSender(chanrec* Ptr, userrec* user, char* text, ...) +void ChanExceptSender(chanrec* Ptr, userrec* user, char status, char* text, ...) { if ((!Ptr) || (!user) || (!text)) { @@ -503,29 +539,58 @@ void ChanExceptSender(chanrec* Ptr, userrec* user, char* text, ...) vsnprintf(textbuffer, MAXBUF, text, argsPtr); va_end(argsPtr); - std::vector *ulist = Ptr->GetUsers(); - unsigned int x = ulist->size(); - for (unsigned int j = 0; j < x; j++) + std::map *ulist; + switch (status) + { + case '@': + ulist = Ptr->GetOppedUsers(); + break; + case '%': + ulist = Ptr->GetHalfoppedUsers(); + break; + case '+': + ulist = Ptr->GetVoicedUsers(); + break; + default: + ulist = Ptr->GetUsers(); + break; + } + log(DEBUG,"%d users to write to",ulist->size()); + for (std::map::iterator i = ulist->begin(); i != ulist->end(); i++) { - char* o = (*ulist)[j]; + char* o = i->second; userrec* otheruser = (userrec*)o; if ((IS_LOCAL(otheruser)) && (user != otheruser)) WriteFrom_NoFormat(otheruser->fd,user,textbuffer); } } -void ChanExceptSender_NoFormat(chanrec* Ptr, userrec* user, const char* text) +void ChanExceptSender_NoFormat(chanrec* Ptr, userrec* user, char status, const char* text) { if ((!Ptr) || (!user) || (!text)) { log(DEFAULT,"*** BUG *** ChanExceptSender was given an invalid parameter"); return; } - std::vector *ulist = Ptr->GetUsers(); - unsigned int x = ulist->size(); - for (unsigned int j = 0; j < x; j++) - { - char* o = (*ulist)[j]; + std::map *ulist; + switch (status) + { + case '@': + ulist = Ptr->GetOppedUsers(); + break; + case '%': + ulist = Ptr->GetHalfoppedUsers(); + break; + case '+': + ulist = Ptr->GetVoicedUsers(); + break; + default: + ulist = Ptr->GetUsers(); + break; + } + for (std::map::iterator i = ulist->begin(); i != ulist->end(); i++) + { + char* o = i->second; userrec* otheruser = (userrec*)o; if ((IS_LOCAL(otheruser)) && (user != otheruser)) WriteFrom_NoFormat(otheruser->fd,user,text); @@ -578,11 +643,10 @@ void WriteCommon(userrec *u, char* text, ...) { if (u->chans[i].channel) { - std::vector *ulist = u->chans[i].channel->GetUsers(); - unsigned int x = ulist->size(); - for (unsigned int j = 0; j < x; j++) + std::map *ulist= u->chans[i].channel->GetUsers(); + for (std::map::iterator i = ulist->begin(); i != ulist->end(); i++) { - char* o = (*ulist)[j]; + char* o = i->second; userrec* otheruser = (userrec*)o; if ((otheruser->fd > -1) && (!already_sent[otheruser->fd])) { @@ -623,11 +687,10 @@ void WriteCommon_NoFormat(userrec *u, const char* text) { if (u->chans[i].channel) { - std::vector *ulist = u->chans[i].channel->GetUsers(); - unsigned int x = ulist->size(); - for (unsigned int j = 0; j < x; j++) + std::map *ulist= u->chans[i].channel->GetUsers(); + for (std::map::iterator i = ulist->begin(); i != ulist->end(); i++) { - char* o = (*ulist)[j]; + char* o = i->second; userrec* otheruser = (userrec*)o; if ((otheruser->fd > -1) && (!already_sent[otheruser->fd])) { @@ -647,7 +710,6 @@ void WriteCommon_NoFormat(userrec *u, const char* text) } - /* write a formatted string to all users who share at least one common * channel, NOT including the source user e.g. for use in QUIT */ @@ -665,11 +727,34 @@ void WriteCommonExcept(userrec *u, char* text, ...) } char textbuffer[MAXBUF]; + char oper_quit[MAXBUF]; + bool quit_munge = false; + va_list argsPtr; va_start (argsPtr, text); - vsnprintf(textbuffer, MAXBUF, text, argsPtr); + int total = vsnprintf(textbuffer, MAXBUF, text, argsPtr); va_end(argsPtr); + if ((Config->HideSplits) && (total > 6)) + { + /* Yeah yeah, this is ugly. But its fast, live with it. */ + char* check = textbuffer; + if ((*check++ == 'Q') && (*check++ == 'U') && (*check++ == 'I') && (*check++ == 'T') && (*check++ == ' ') && (*check++ == ':')) + { + std::stringstream split(check); + std::string server_one; + std::string server_two; + split >> server_one; + split >> server_two; + if ((FindServerName(server_one)) && (FindServerName(server_two))) + { + strlcpy(oper_quit,textbuffer,MAXBUF); + strlcpy(check,"*.net *.split",MAXQUIT); + quit_munge = true; + } + } + } + memset(&already_sent,0,MAX_DESCRIPTORS); unsigned int y = u->chans.size(); @@ -677,18 +762,28 @@ void WriteCommonExcept(userrec *u, char* text, ...) { if (u->chans[i].channel) { - std::vector *ulist = u->chans[i].channel->GetUsers(); - unsigned int x = ulist->size(); - for (unsigned int j = 0; j < x; j++) + std::map *ulist= u->chans[i].channel->GetUsers(); + for (std::map::iterator i = ulist->begin(); i != ulist->end(); i++) { - char* o = (*ulist)[j]; + char* o = i->second; userrec* otheruser = (userrec*)o; if (u != otheruser) { if ((otheruser->fd > -1) && (!already_sent[otheruser->fd])) { already_sent[otheruser->fd] = 1; - WriteFrom_NoFormat(otheruser->fd,u,textbuffer); + if (quit_munge) + { + if (*otheruser->oper) + { + WriteFrom_NoFormat(otheruser->fd,u,oper_quit); + } + else + { + WriteFrom_NoFormat(otheruser->fd,u,textbuffer); + } + } + else WriteFrom_NoFormat(otheruser->fd,u,textbuffer); } } } @@ -716,11 +811,10 @@ void WriteCommonExcept_NoFormat(userrec *u, const char* text) { if (u->chans[i].channel) { - std::vector *ulist = u->chans[i].channel->GetUsers(); - unsigned int x = ulist->size(); - for (unsigned int j = 0; j < x; j++) + std::map *ulist= u->chans[i].channel->GetUsers(); + for (std::map::iterator i = ulist->begin(); i != ulist->end(); i++) { - char* o = (*ulist)[j]; + char* o = i->second; userrec* otheruser = (userrec*)o; if (u != otheruser) { @@ -930,6 +1024,18 @@ userrec* Find(std::string nick) return iter->second; } +userrec* Find(const char* nick) +{ + if (!nick) + return NULL; + user_hash::iterator iter = clientlist.find(nick); + + if (iter == clientlist.end()) + return NULL; + + return iter->second; +} + /* find a channel record by channel name and return a pointer to it */ chanrec* FindChan(const char* chan) @@ -991,7 +1097,10 @@ void purge_empty_chans(userrec* u) { log(DEBUG,"del_channel: destroyed: %s",i2->second->name); if (i2->second) + { + FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(i2->second)); delete i2->second; + } chanlist.erase(i2); purge++; u->chans[i].channel = NULL; @@ -1009,7 +1118,7 @@ void purge_empty_chans(userrec* u) } -char* chanmodes(chanrec *chan) +char* chanmodes(chanrec *chan, bool showkey) { static char scratch[MAXBUF]; static char sparam[MAXBUF]; @@ -1041,7 +1150,9 @@ char* chanmodes(chanrec *chan) if (chan->binarymodes & CM_PRIVATE) *offset++ = 'p'; if (*chan->key) - snprintf(sparam,MAXBUF," %s",chan->key); + { + snprintf(sparam,MAXBUF," %s",showkey ? chan->key : ""); + } if (chan->limit) { char foo[24]; @@ -1082,10 +1193,10 @@ void userlist(userrec *user,chanrec *c) snprintf(list,MAXBUF,"353 %s = %s :", user->nick, c->name); - std::vector *ulist = c->GetUsers(); - for (unsigned int i = 0; i < ulist->size(); i++) + std::map *ulist= c->GetUsers(); + for (std::map::iterator i = ulist->begin(); i != ulist->end(); i++) { - char* o = (*ulist)[i]; + char* o = i->second; userrec* otheruser = (userrec*)o; if ((!has_channel(user,c)) && (strchr(otheruser->modes,'i'))) { @@ -1153,33 +1264,18 @@ int usercount(chanrec *c) // looks up a users password for their connection class (/ tags) -char* Passwd(userrec *user) +ConnectClass GetClass(userrec *user) { for (ClassVector::iterator i = Config->Classes.begin(); i != Config->Classes.end(); i++) { - if ((i->type == CC_ALLOW) && match(user->host,i->host.c_str())) + if (match(user->host,i->host.c_str())) { - return (char*)i->pass.c_str(); + return *i; } } - return ""; + return *(Config->Classes.begin()); } -bool IsDenied(userrec *user) -{ - for (ClassVector::iterator i = Config->Classes.begin(); i != Config->Classes.end(); i++) - { - if ((i->type == CC_DENY) && match(user->host,i->host.c_str())) - { - return true; - } - } - return false; -} - - - - /* sends out an error notice to all connected clients (not to be used * lightly!) */ @@ -1244,7 +1340,10 @@ int usercount_invisible(void) int usercount_opers(void) { - return all_opers.size(); + int c = 0; + for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++) + if (*i->second->oper) c++; + return c; } int usercount_unknown(void) @@ -1295,7 +1394,15 @@ void ShowMOTD(userrec *user) // only one write operation if (Config->GetIOHook(user->port)) { - Config->GetIOHook(user->port)->OnRawSocketWrite(user->fd,(char*)WholeMOTD.c_str(),WholeMOTD.length()); + try + { + Config->GetIOHook(user->port)->OnRawSocketWrite(user->fd,(char*)WholeMOTD.c_str(),WholeMOTD.length()); + } + catch (ModuleException& modexcept) + { + log(DEBUG,"Module exception cought: %s",modexcept.GetReason()); \ + } + } else { @@ -1397,3 +1504,59 @@ std::string GetFullProgDir(char** argv, int argc) return otherdir; } +int InsertMode(std::string &output, const char* mode, unsigned short section) +{ + unsigned short currsection = 1; + unsigned int pos = output.find("CHANMODES=", 0) + 10; // +10 for the length of "CHANMODES=" + + if(section > 4 || section == 0) + { + log(DEBUG, "InsertMode: CHANMODES doesn't have a section %dh :/", section); + return 0; + } + + for(; pos < output.size(); pos++) + { + if(section == currsection) + break; + + if(output[pos] == ',') + currsection++; + } + + output.insert(pos, mode); + return 1; +} + +bool IsValidChannelName(const char *chname) +{ + char *c; + + /* check for no name - don't check for !*chname, as if it is empty, it won't be '#'! */ + if (!chname || *chname != '#') + { + return false; + } + + c = (char *)chname + 1; + while (*c) + { + switch (*c) + { + case ' ': + case ',': + case 7: + return false; + } + + c++; + } + + /* too long a name - note funky pointer arithmetic here. */ + if ((c - chname) > CHANMAX) + { + return false; + } + + return true; +}