X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fhelperfuncs.cpp;h=6b7178e225b9f9b9b25f8bcd54e4cf15801531f5;hb=59b1a8955142935b02af6446005ab47fc7c3fc8c;hp=456b6b5b11da1fe8a7f363ed27c9acf453cf2969;hpb=1383dba43e463f292aea094d01f62f355946049d;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/helperfuncs.cpp b/src/helperfuncs.cpp index 456b6b5b1..6b7178e22 100644 --- a/src/helperfuncs.cpp +++ b/src/helperfuncs.cpp @@ -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 { @@ -484,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)) { @@ -497,7 +539,23 @@ void ChanExceptSender(chanrec* Ptr, userrec* user, char* text, ...) vsnprintf(textbuffer, MAXBUF, text, argsPtr); va_end(argsPtr); - std::map *ulist= Ptr->GetUsers(); + 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 = i->second; @@ -507,14 +565,29 @@ void ChanExceptSender(chanrec* Ptr, userrec* user, char* text, ...) } } -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::map *ulist= Ptr->GetUsers(); + 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; @@ -637,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 */ @@ -655,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,7 +772,18 @@ void WriteCommonExcept(userrec *u, char* text, ...) 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); } } } @@ -918,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) @@ -979,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; @@ -997,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]; @@ -1029,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]; @@ -1217,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) @@ -1268,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 { @@ -1370,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; +}