X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fhelperfuncs.cpp;h=6b7178e225b9f9b9b25f8bcd54e4cf15801531f5;hb=59b1a8955142935b02af6446005ab47fc7c3fc8c;hp=c358b4bf55688579ae7f30a0c103ed6d47e34a4b;hpb=5e62a8399f1a7a1e9b0bd02a8df6b1a506d0b203;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/helperfuncs.cpp b/src/helperfuncs.cpp index c358b4bf5..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; @@ -123,9 +123,9 @@ void readfile(file_cache &F, const char* fname) log(DEBUG,"readfile: loaded %s, %lu lines",fname,(unsigned long)F.size()); } -void Write_NoFormat(int sock,char *text) +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,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,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 { @@ -177,9 +191,9 @@ void Write(int sock,char *text, ...) else log(DEFAULT,"ERROR! attempted write to a user with no fd_ref_table entry!!!"); } -void WriteServ_NoFormat(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, 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, 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 { @@ -232,18 +260,25 @@ void WriteServ(int sock, char* text, ...) else log(DEFAULT,"ERROR! attempted write to a user with no fd_ref_table entry!!!"); } -void WriteFrom_NoFormat(int sock, userrec *user,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,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 { @@ -316,13 +358,13 @@ void WriteTo(userrec *source, userrec *dest,char *data, ...) } } -void WriteTo_NoFormat(userrec *source, userrec *dest,char *data) +void WriteTo_NoFormat(userrec *source, userrec *dest, const char *data) { if ((!dest) || (!data)) return; if (!source) { - WriteServ(dest->fd,":%s %s",Config->ServerName,data); + WriteServ_NoFormat(dest->fd,data); } else { @@ -346,17 +388,34 @@ 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); } } +void WriteChannel_NoFormat(chanrec* Ptr, userrec* user, const char* text) +{ + if ((!Ptr) || (!user) || (!text)) + { + log(DEFAULT,"*** BUG *** WriteChannel was given an invalid parameter"); + return; + } + std::map *ulist= Ptr->GetUsers(); + for (std::map::iterator i = ulist->begin(); i != ulist->end(); i++) + { + char* o = i->second; + userrec* otheruser = (userrec*)o; + if (otheruser->fd != FD_MAGIC_NUMBER) + WriteTo_NoFormat(user,otheruser,text); + } +} + + /* write formatted text from a source user to all users on a channel * including the sender (NOT for privmsg, notice etc!) doesnt send to * users on remote servers */ @@ -374,13 +433,12 @@ 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->fd != -1) && (otheruser != user)) + if ((otheruser->fd != FD_MAGIC_NUMBER) && (otheruser != user)) { if (!user) { @@ -394,6 +452,34 @@ void WriteChannelLocal(chanrec* Ptr, userrec* user, char* text, ...) } } +void WriteChannelLocal_NoFormat(chanrec* Ptr, userrec* user, const char* text) +{ + if ((!Ptr) || (!text)) + { + log(DEFAULT,"*** BUG *** WriteChannel was given an invalid parameter"); + return; + } + std::map *ulist= Ptr->GetUsers(); + for (std::map::iterator i = ulist->begin(); i != ulist->end(); i++) + { + char* o = i->second; + userrec* otheruser = (userrec*)o; + if ((otheruser->fd != FD_MAGIC_NUMBER) && (otheruser != user)) + { + if (!user) + { + WriteServ_NoFormat(otheruser->fd,text); + } + else + { + WriteTo_NoFormat(user,otheruser,text); + } + } + } +} + + + void WriteChannelWithServ(char* ServName, chanrec* Ptr, char* text, ...) { if ((!Ptr) || (!text)) @@ -408,21 +494,39 @@ 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); } } +void WriteChannelWithServ_NoFormat(char* ServName, chanrec* Ptr, const char* text) +{ + if ((!Ptr) || (!text)) + { + log(DEFAULT,"*** BUG *** WriteChannelWithServ was given an invalid parameter"); + return; + } + std::map *ulist= Ptr->GetUsers(); + for (std::map::iterator i = ulist->begin(); i != ulist->end(); i++) + { + char* o = i->second; + userrec* otheruser = (userrec*)o; + if (IS_LOCAL(otheruser)) + WriteServ_NoFormat(otheruser->fd,text); + } +} + + + /* 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)) { @@ -435,17 +539,64 @@ 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, char status, const char* text) +{ + if ((!Ptr) || (!user) || (!text)) + { + log(DEFAULT,"*** BUG *** ChanExceptSender was given an invalid parameter"); + return; + } + 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); + } +} + std::string GetServerDescription(char* servername) { std::string description = ""; @@ -492,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])) { @@ -511,10 +661,55 @@ void WriteCommon(userrec *u, char* text, ...) // receives their OWN message for WriteCommon if (!sent_to_at_least_one) { - WriteFrom(u->fd,u,"%s",textbuffer); + WriteFrom_NoFormat(u->fd,u,textbuffer); } } +void WriteCommon_NoFormat(userrec *u, const char* text) +{ + if (!u) + { + log(DEFAULT,"*** BUG *** WriteCommon was given an invalid parameter"); + return; + } + + if (u->registered != 7) { + log(DEFAULT,"*** BUG *** WriteCommon on an unregistered user"); + return; + } + // FIX: Stops a message going to the same person more than once + memset(&already_sent,0,MAX_DESCRIPTORS); + + bool sent_to_at_least_one = false; + + unsigned int y = u->chans.size(); + for (unsigned int i = 0; i < y; i++) + { + if (u->chans[i].channel) + { + std::map *ulist= u->chans[i].channel->GetUsers(); + for (std::map::iterator i = ulist->begin(); i != ulist->end(); i++) + { + char* o = i->second; + userrec* otheruser = (userrec*)o; + if ((otheruser->fd > -1) && (!already_sent[otheruser->fd])) + { + already_sent[otheruser->fd] = 1; + WriteFrom_NoFormat(otheruser->fd,u,text); + sent_to_at_least_one = true; + } + } + } + } + // if the user was not in any channels, no users will receive the text. Make sure the user + // receives their OWN message for WriteCommon + if (!sent_to_at_least_one) + { + WriteFrom_NoFormat(u->fd,u,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 */ @@ -532,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(); @@ -544,18 +762,66 @@ 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 = i->second; + userrec* otheruser = (userrec*)o; + if (u != otheruser) + { + if ((otheruser->fd > -1) && (!already_sent[otheruser->fd])) + { + already_sent[otheruser->fd] = 1; + 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); + } + } + } + } + } +} + +void WriteCommonExcept_NoFormat(userrec *u, const char* text) +{ + if (!u) + { + log(DEFAULT,"*** BUG *** WriteCommon was given an invalid parameter"); + return; + } + + if (u->registered != 7) { + log(DEFAULT,"*** BUG *** WriteCommon on an unregistered user"); + return; + } + + memset(&already_sent,0,MAX_DESCRIPTORS); + + unsigned int y = u->chans.size(); + for (unsigned int i = 0; i < y; i++) + { + if (u->chans[i].channel) + { + 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); + WriteFrom_NoFormat(otheruser->fd,u,text); } } } @@ -563,6 +829,8 @@ void WriteCommonExcept(userrec *u, char* text, ...) } } + + void WriteOpers(char* text, ...) { if (!text) @@ -756,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) @@ -817,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; @@ -835,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]; @@ -867,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]; @@ -908,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'))) { @@ -926,14 +1211,14 @@ void userlist(userrec *user,chanrec *c) { /* list overflowed into * multiple numerics */ - WriteServ(user->fd,"%s",list); + WriteServ_NoFormat(user->fd,list); snprintf(list,MAXBUF,"353 %s = %s :", user->nick, c->name); } } /* if whats left in the list isnt empty, send it */ if (list[strlen(list)-1] != ':') { - WriteServ(user->fd,"%s",list); + WriteServ_NoFormat(user->fd,list); } } @@ -979,33 +1264,18 @@ int usercount(chanrec *c) // looks up a users password for their connection class (/ tags) -char* Passwd(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())) - { - return (char*)i->pass.c_str(); - } - } - return ""; -} - -bool IsDenied(userrec *user) +ConnectClass GetClass(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())) + if (match(user->host,i->host.c_str())) { - return true; + return *i; } } - return false; + return *(Config->Classes.begin()); } - - - /* sends out an error notice to all connected clients (not to be used * lightly!) */ @@ -1070,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) @@ -1121,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 { @@ -1223,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; +}