X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fchannels.cpp;h=9f1eafd0cb1f1e9654a8d3890310a46ac98af26a;hb=4e3d7a6e30eadf714483994681b8b2534229f4a8;hp=c265171b5ce85c6ced4e78d30a440a3ed4f8eb28;hpb=388e4ff40931dda5870ddef149e54bdcc6c5a711;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/channels.cpp b/src/channels.cpp index c265171b5..9f1eafd0c 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -31,12 +31,10 @@ Channel::Channel(const std::string &cname, time_t ts) { - chan_hash::iterator findchan = ServerInstance->chanlist->find(cname); - if (findchan != ServerInstance->chanlist->end()) + if (!ServerInstance->chanlist->insert(std::make_pair(cname, this)).second) throw CoreException("Cannot create duplicate channel " + cname); - (*(ServerInstance->chanlist))[cname.c_str()] = this; - this->name.assign(cname, 0, ServerInstance->Config->Limits.ChanMax); + this->name = cname; this->age = ts ? ts : ServerInstance->Time(); maxbans = topicset = 0; @@ -118,16 +116,8 @@ int Channel::SetTopic(User *u, std::string &ntopic, bool forceset) } this->topic.assign(ntopic, 0, ServerInstance->Config->Limits.MaxTopic); - if (u) - { - this->setby.assign(ServerInstance->Config->FullHostInTopic ? u->GetFullHost() : u->nick, 0, 128); - this->WriteChannel(u, "TOPIC %s :%s", this->name.c_str(), this->topic.c_str()); - } - else - { - this->setby.assign(ServerInstance->Config->ServerName); - this->WriteChannelWithServ(ServerInstance->Config->ServerName, "TOPIC %s :%s", this->name.c_str(), this->topic.c_str()); - } + this->setby.assign(ServerInstance->Config->FullHostInTopic ? u->GetFullHost() : u->nick, 0, 128); + this->WriteChannel(u, "TOPIC %s :%s", this->name.c_str(), this->topic.c_str()); this->topicset = ServerInstance->Time(); @@ -212,10 +202,18 @@ void Channel::SetDefaultModes() if (mode) { if (mode->GetNumParams(true)) + { list.GetToken(parameter); + // If the parameter begins with a ':' then it's invalid + if (parameter.c_str()[0] == ':') + continue; + } else parameter.clear(); + if ((mode->GetNumParams(true)) && (parameter.empty())) + continue; + mode->OnModeChange(ServerInstance->FakeClient, ServerInstance->FakeClient, this, parameter, true); } } @@ -231,7 +229,6 @@ Channel* Channel::JoinUser(User *user, const char* cn, bool override, const char if (!user || !cn || user->registered != REG_ALL) return NULL; - char cname[MAXBUF]; std::string privs; Channel *Ptr; @@ -264,7 +261,8 @@ Channel* Channel::JoinUser(User *user, const char* cn, bool override, const char } } - strlcpy(cname, cn, ServerInstance->Config->Limits.ChanMax); + std::string cname; + cname.assign(std::string(cn), 0, ServerInstance->Config->Limits.ChanMax); Ptr = ServerInstance->FindChan(cname); bool created_by_local = false; @@ -287,7 +285,7 @@ Channel* Channel::JoinUser(User *user, const char* cn, bool override, const char if (IS_LOCAL(user) && override == false) { ModResult MOD_RESULT; - FIRST_MOD_RESULT(OnUserPreJoin, MOD_RESULT, (user, NULL, cname, privs, key ? key : "")); + FIRST_MOD_RESULT(OnUserPreJoin, MOD_RESULT, (user, NULL, cname.c_str(), privs, key ? key : "")); if (MOD_RESULT == MOD_RES_DENY) return NULL; } @@ -307,7 +305,7 @@ Channel* Channel::JoinUser(User *user, const char* cn, bool override, const char if (IS_LOCAL(user) && override == false) { ModResult MOD_RESULT; - FIRST_MOD_RESULT(OnUserPreJoin, MOD_RESULT, (user, Ptr, cname, privs, key ? key : "")); + FIRST_MOD_RESULT(OnUserPreJoin, MOD_RESULT, (user, Ptr, cname.c_str(), privs, key ? key : "")); if (MOD_RESULT == MOD_RES_DENY) { return NULL; @@ -449,7 +447,7 @@ bool Channel::CheckBan(User* user, const std::string& mask) return (result == MOD_RES_DENY); // extbans were handled above, if this is one it obviously didn't match - if (mask[1] == ':') + if ((mask.length() <= 2) || (mask[1] == ':')) return false; std::string::size_type at = mask.find('@'); @@ -675,7 +673,6 @@ void Channel::WriteAllExcept(User* user, bool serversource, char status, CUList char tb[MAXBUF]; snprintf(tb,MAXBUF,":%s %s", serversource ? ServerInstance->Config->ServerName.c_str() : user->GetFullHost().c_str(), text.c_str()); - std::string out = tb; this->RawWriteAllExcept(user, serversource, status, except_list, std::string(tb)); } @@ -718,7 +715,7 @@ int Channel::CountInvisible() int count = 0; for (UserMembIter i = userlist.begin(); i != userlist.end(); i++) { - if (!(i->first->IsModeSet('i'))) + if (!i->first->quitting && !i->first->IsModeSet('i')) count++; } @@ -769,31 +766,39 @@ char* Channel::ChanModes(bool showkey) */ void Channel::UserList(User *user) { - char list[MAXBUF]; - size_t dlen, curlen; - if (!IS_LOCAL(user)) return; - if (this->IsModeSet('s') && !this->HasUser(user) && !user->HasPrivPermission("channels/auspex")) + bool has_privs = user->HasPrivPermission("channels/auspex"); + + if (this->IsModeSet('s') && !this->HasUser(user) && !has_privs) { user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel",user->nick.c_str(), this->name.c_str()); return; } - dlen = curlen = snprintf(list,MAXBUF,"%s %c %s :", user->nick.c_str(), this->IsModeSet('s') ? '@' : this->IsModeSet('p') ? '*' : '=', this->name.c_str()); + std::string list = user->nick; + list.push_back(' '); + list.push_back(this->IsModeSet('s') ? '@' : this->IsModeSet('p') ? '*' : '='); + list.push_back(' '); + list.append(this->name).append(" :"); + std::string::size_type pos = list.size(); - int numusers = 0; - char* ptr = list + dlen; + bool has_one = false; /* Improvement by Brain - this doesnt change in value, so why was it inside * the loop? */ bool has_user = this->HasUser(user); - for (UserMembIter i = userlist.begin(); i != userlist.end(); i++) + const size_t maxlen = MAXBUF - 10 - ServerInstance->Config->ServerName.size(); + std::string prefixlist; + std::string nick; + for (UserMembIter i = userlist.begin(); i != userlist.end(); ++i) { - if ((!has_user) && (i->first->IsModeSet('i'))) + if (i->first->quitting) + continue; + if ((!has_user) && (i->first->IsModeSet('i')) && (!has_privs)) { /* * user is +i, and source not on the channel, does not show @@ -802,8 +807,8 @@ void Channel::UserList(User *user) continue; } - std::string prefixlist = this->GetPrefixChar(i->first); - std::string nick = i->first->nick; + prefixlist = this->GetPrefixChar(i->first); + nick = i->first->nick; FOREACH_MOD(I_OnNamesListItem, OnNamesListItem(user, i->second, prefixlist, nick)); @@ -811,32 +816,25 @@ void Channel::UserList(User *user) if (nick.empty()) continue; - size_t ptrlen = 0; - - if (curlen + prefixlist.length() + nick.length() + 1 > 480) + if (list.size() + prefixlist.length() + nick.length() + 1 > maxlen) { /* list overflowed into multiple numerics */ - user->WriteNumeric(RPL_NAMREPLY, std::string(list)); + user->WriteNumeric(RPL_NAMREPLY, list); - /* reset our lengths */ - dlen = curlen = snprintf(list,MAXBUF,"%s %c %s :", user->nick.c_str(), this->IsModeSet('s') ? '@' : this->IsModeSet('p') ? '*' : '=', this->name.c_str()); - ptr = list + dlen; - - numusers = 0; + // Erase all nicks, keep the constant part + list.erase(pos); + has_one = false; } - ptrlen = snprintf(ptr, MAXBUF, "%s%s ", prefixlist.c_str(), nick.c_str()); - - curlen += ptrlen; - ptr += ptrlen; + list.append(prefixlist).append(nick).push_back(' '); - numusers++; + has_one = true; } /* if whats left in the list isnt empty, send it */ - if (numusers) + if (has_one) { - user->WriteNumeric(RPL_NAMREPLY, std::string(list)); + user->WriteNumeric(RPL_NAMREPLY, list); } user->WriteNumeric(RPL_ENDOFNAMES, "%s %s :End of /NAMES list.", user->nick.c_str(), this->name.c_str()); @@ -1013,7 +1011,8 @@ Invitation* Invitation::Find(Channel* c, LocalUser* u, bool check_expired) if ((check_expired) && (inv->expiry != 0) && (inv->expiry <= ServerInstance->Time())) { /* Expired invite, remove it. */ - ServerInstance->Logs->Log("INVITATION", DEBUG, "Invitation::Find ecountered expired entry: %p expired %s", (void*) inv, ServerInstance->TimeString(inv->expiry).c_str()); + std::string expiration = ServerInstance->TimeString(inv->expiry); + ServerInstance->Logs->Log("INVITATION", DEBUG, "Invitation::Find ecountered expired entry: %p expired %s", (void*) inv, expiration.c_str()); i = locallist.erase(i); inv->cull(); delete inv;