From cdf451e8d4bc163b6f8711c07db0f785e90f46e7 Mon Sep 17 00:00:00 2001 From: brain Date: Sat, 10 Apr 2004 01:12:53 +0000 Subject: Added server to server 'J' token git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@481 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/inspircd.h | 2 +- src/InspIRCd.layout | 18 ++--- src/inspircd.cpp | 225 +++++++++++++++++++++++++++++++++++++--------------- src/modules.cpp | 2 +- 4 files changed, 174 insertions(+), 73 deletions(-) diff --git a/include/inspircd.h b/include/inspircd.h index 442211ea1..51dd6fb93 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -107,7 +107,7 @@ bool ModeDefined(char c, int i); bool ModeDefinedOper(char c, int i); int ModeDefinedOn(char c, int i); int ModeDefinedOff(char c, int i); -chanrec* add_channel(userrec *user, const char* cn, const char* key); +chanrec* add_channel(userrec *user, const char* cn, const char* key, bool override); chanrec* del_channel(userrec *user, const char* cname, const char* reason); void force_nickchange(userrec* user,const char* newnick); void kill_link(userrec *user,const char* r); diff --git a/src/InspIRCd.layout b/src/InspIRCd.layout index 9f542b2a8..4ddebfc79 100644 --- a/src/InspIRCd.layout +++ b/src/InspIRCd.layout @@ -13,9 +13,9 @@ LeftChar=1 [Editor_1] Open=1 Top=1 -CursorCol=2 -CursorRow=5565 -TopLine=5517 +CursorCol=29 +CursorRow=636 +TopLine=619 LeftChar=1 [Editor_2] @@ -37,9 +37,9 @@ LeftChar=1 [Editor_4] Open=1 Top=0 -CursorCol=86 -CursorRow=335 -TopLine=293 +CursorCol=56 +CursorRow=159 +TopLine=133 LeftChar=1 [Editor_5] @@ -141,9 +141,9 @@ LeftChar=1 [Editor_17] Open=1 Top=0 -CursorCol=1 -CursorRow=115 -TopLine=51 +CursorCol=83 +CursorRow=110 +TopLine=60 LeftChar=1 [Editor_18] diff --git a/src/inspircd.cpp b/src/inspircd.cpp index afdb2f82b..214cc9981 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -609,6 +609,42 @@ void WriteChannel(chanrec* Ptr, userrec* user, char* 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 */ + +void WriteChannelLocal(chanrec* Ptr, userrec* user, char* text, ...) +{ + if ((!Ptr) || (!text)) + { + log(DEFAULT,"*** BUG *** WriteChannel was given an invalid parameter"); + return; + } + char textbuffer[MAXBUF]; + va_list argsPtr; + va_start (argsPtr, text); + vsnprintf(textbuffer, MAXBUF, text, argsPtr); + va_end(argsPtr); + for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++) + { + if (has_channel(i->second,Ptr)) + { + if (i->second->fd != -1) + { + if (!user) + { + WriteServ(i->second->fd,"%s",textbuffer); + } + else + { + WriteTo(user,i->second,"%s",textbuffer); + } + } + } + } +} + + void WriteChannelWithServ(char* ServerName, chanrec* Ptr, userrec* user, char* text, ...) { if ((!Ptr) || (!user) || (!text)) @@ -1330,7 +1366,7 @@ int usercount(chanrec *c) /* add a channel to a user, creating the record for it if needed and linking * it to the user record */ -chanrec* add_channel(userrec *user, const char* cn, const char* key) +chanrec* add_channel(userrec *user, const char* cn, const char* key, bool override) { if ((!user) || (!cn)) { @@ -1404,63 +1440,71 @@ chanrec* add_channel(userrec *user, const char* cn, const char* key) } log(DEBUG,"add_channel: joining to: %s",Ptr->name); - if (strcmp(Ptr->key,"")) + + // the override flag allows us to bypass channel modes + // and bans (used by servers) + if (!override) { - log(DEBUG,"add_channel: %s has key %s",Ptr->name,Ptr->key); - if (!key) - { - log(DEBUG,"add_channel: no key given in JOIN"); - WriteServ(user->fd,"475 %s %s :Cannot join channel (Requires key)",user->nick, Ptr->name); - return NULL; - } - else + + if (strcmp(Ptr->key,"")) { - log(DEBUG,"key at %p is %s",key,key); - if (strcasecmp(key,Ptr->key)) + log(DEBUG,"add_channel: %s has key %s",Ptr->name,Ptr->key); + if (!key) { - log(DEBUG,"add_channel: bad key given in JOIN"); - WriteServ(user->fd,"475 %s %s :Cannot join channel (Incorrect key)",user->nick, Ptr->name); + log(DEBUG,"add_channel: no key given in JOIN"); + WriteServ(user->fd,"475 %s %s :Cannot join channel (Requires key)",user->nick, Ptr->name); return NULL; } + else + { + log(DEBUG,"key at %p is %s",key,key); + if (strcasecmp(key,Ptr->key)) + { + log(DEBUG,"add_channel: bad key given in JOIN"); + WriteServ(user->fd,"475 %s %s :Cannot join channel (Incorrect key)",user->nick, Ptr->name); + return NULL; + } + } } - } - log(DEBUG,"add_channel: no key"); - - if (Ptr->inviteonly) - { - log(DEBUG,"add_channel: channel is +i"); - if (user->IsInvited(Ptr->name)) - { - /* user was invited to channel */ - /* there may be an optional channel NOTICE here */ - } - else + log(DEBUG,"add_channel: no key"); + + if (Ptr->inviteonly) { - WriteServ(user->fd,"473 %s %s :Cannot join channel (Invite only)",user->nick, Ptr->name); - return NULL; + log(DEBUG,"add_channel: channel is +i"); + if (user->IsInvited(Ptr->name)) + { + /* user was invited to channel */ + /* there may be an optional channel NOTICE here */ + } + else + { + WriteServ(user->fd,"473 %s %s :Cannot join channel (Invite only)",user->nick, Ptr->name); + return NULL; + } } - } - log(DEBUG,"add_channel: channel is not +i"); - - if (Ptr->limit) - { - if (usercount(Ptr) == Ptr->limit) + log(DEBUG,"add_channel: channel is not +i"); + + if (Ptr->limit) { - WriteServ(user->fd,"471 %s %s :Cannot join channel (Channel is full)",user->nick, Ptr->name); - return NULL; + if (usercount(Ptr) == Ptr->limit) + { + WriteServ(user->fd,"471 %s %s :Cannot join channel (Channel is full)",user->nick, Ptr->name); + return NULL; + } } - } - - log(DEBUG,"add_channel: about to walk banlist"); - - /* check user against the channel banlist */ - for (BanList::iterator i = Ptr->bans.begin(); i != Ptr->bans.end(); i++) - { - if (match(user->GetFullHost(),i->data)) + + log(DEBUG,"add_channel: about to walk banlist"); + + /* check user against the channel banlist */ + for (BanList::iterator i = Ptr->bans.begin(); i != Ptr->bans.end(); i++) { - WriteServ(user->fd,"474 %s %s :Cannot join channel (You're banned)",user->nick, Ptr->name); - return NULL; + if (match(user->GetFullHost(),i->data)) + { + WriteServ(user->fd,"474 %s %s :Cannot join channel (You're banned)",user->nick, Ptr->name); + return NULL; + } } + } log(DEBUG,"add_channel: bans checked"); @@ -3104,7 +3148,7 @@ void handle_join(char **parameters, int pcnt, userrec *user) return; if (parameters[0][0] == '#') { - Ptr = add_channel(user,parameters[0],parameters[1]); + Ptr = add_channel(user,parameters[0],parameters[1],false); } } @@ -3832,6 +3876,10 @@ char* chlist(userrec *user) } } } + if (strlen(lst)) + { + lst[strlen(lst)-1] = '\0'; // chop trailing space + } return lst; } @@ -5069,18 +5117,18 @@ void DoSync(serverrec* serv, char* udp_host,int udp_port, long MyKey) serv->SendPacket(data,udp_host,udp_port,MyKey); if (strcmp(chlist(u->second),"")) { - snprintf(data,MAXBUF,"J %s :%s",u->second->nick,chlist(u->second)); + snprintf(data,MAXBUF,"J %s %s",u->second->nick,chlist(u->second)); serv->SendPacket(data,udp_host,udp_port,MyKey); } } // send channel modes, topics etc... for (chan_hash::iterator c = chanlist.begin(); c != chanlist.end(); c++) { - snprintf(data,MAXBUF,"C %s %d %s :%s",c->second->name,c->second->created,c->second->setby,chanmodes(c->second)); + snprintf(data,MAXBUF,"C %s %d %s %s",c->second->name,c->second->created,c->second->setby,chanmodes(c->second)); serv->SendPacket(data,udp_host,udp_port,MyKey); if (strcmp(c->second->topic,"")) { - snprintf(data,MAXBUF,"T %d %s :%s",c->second->topicset,c->second->name,c->second->topic); + snprintf(data,MAXBUF,"T %d %s %s",c->second->topicset,c->second->name,c->second->topic); } serv->SendPacket(data,udp_host,udp_port,MyKey); // send current banlist @@ -5099,7 +5147,6 @@ void DoSync(serverrec* serv, char* udp_host,int udp_port, long MyKey) void handle_N(char token,char* params,serverrec* source,serverrec* reply, char* udp_host,int udp_port) { - log(DEBUG,"Sync: Received an 'N' packet, processing"); char* tm = strtok(params," "); char* nick = strtok(NULL," "); char* host = strtok(NULL," "); @@ -5113,9 +5160,15 @@ void handle_N(char token,char* params,serverrec* source,serverrec* reply, char* if (iter != clientlist.end()) { // nick collision - // TODO: make this work! WriteOpers("Nickname collision: %s@%s != %s@%s",nick,server,iter->second->nick,iter->second->server); - return; + if (TS >= iter->second->age) + { + char str[MAXBUF]; + snprintf(str,MAXBUF,"Killed (Nick Collision (%s@%s < %s@%s))",nick,server,iter->second->nick,iter->second->server); + WriteServ(iter->second->fd, "KILL %s :%s",iter->second->nick,str); + // client on remote server is older than the local user, kill the local user + kill_link(iter->second,str); + } } clientlist[nick] = new userrec(); // remote users have an fd of -1. This is so that our Write abstraction @@ -5127,18 +5180,66 @@ void handle_N(char token,char* params,serverrec* source,serverrec* reply, char* strncpy(clientlist[nick]->dhost, dhost,160); strncpy(clientlist[nick]->server, server,256); strncpy(clientlist[nick]->ident, ident,10); // +1 char to compensate for '~' + strncpy(clientlist[nick]->fullname, gecos,128); clientlist[nick]->signon = TS; clientlist[nick]->nping = 0; // this is ignored for a remote user anyway. clientlist[nick]->lastping = 1; clientlist[nick]->port = 0; // so is this... clientlist[nick]->registered = 7; // this however we need to set for them to receive messages and appear online - clientlist[nick]->idle_lastmsg = time(NULL); // this will have to update as they pm us, - // so a user wont need /WHOIS to find it - // but it may be slightly different over the net - // (a couple of seconds at most) - log(DEBUG,"Sync: Added %s",nick); + clientlist[nick]->idle_lastmsg = time(NULL); // this is unrealiable and wont actually be used locally } +void handle_J(char token,char* params,serverrec* source,serverrec* reply, char* udp_host,int udp_port) +{ + // IMPORTANT NOTE + // The J token currently has no timestamp - this needs looking at + // because it will allow splitriding. + char* nick = strtok(params," "); + char* channel = strtok(NULL," "); + userrec* user = Find(nick); + while (channel) + { + if ((user != NULL) && (strcmp(channel,""))) + { + char privilage = '\0'; + if (channel[0] != '#') + { + privilage = channel[0]; + channel++; + } + add_channel(user,channel,"",true); + + // now work out the privilages they should have on each channel + // and send the appropriate servermodes. + for (int i = 0; i != MAXCHANS; i++) + { + if (user->chans[i].channel) + { + if (!strcasecmp(user->chans[i].channel->name,channel)) + { + if (privilage == '@') + { + user->chans[i].uc_modes = user->chans[i].uc_modes | UCMODE_OP; + WriteChannelLocal(user->chans[i].channel, NULL, "MODE %s +o %s",channel,user->nick); + } + if (privilage == '%') + { + user->chans[i].uc_modes = user->chans[i].uc_modes | UCMODE_HOP; + WriteChannelLocal(user->chans[i].channel, NULL, "MODE %s +h %s",channel,user->nick); + } + if (privilage == '+') + { + user->chans[i].uc_modes = user->chans[i].uc_modes | UCMODE_VOICE; + WriteChannelLocal(user->chans[i].channel, NULL, "MODE %s +o %s",channel,user->nick); + } + } + } + } + + } + channel = strtok(NULL," "); + } +} void process_restricted_commands(char token,char* params,serverrec* source,serverrec* reply, char* udp_host,int udp_port) { @@ -5152,17 +5253,17 @@ void process_restricted_commands(char token,char* params,serverrec* source,serve // introduce remote client case 'N': handle_N(token,params,source,reply,udp_host,udp_port); - log(DEBUG,"Sync: exit 1"); break; - // J : + // J // Join user to channel list, merge channel permissions case 'J': + handle_J(token,params,source,reply,udp_host,udp_port); break; - // C : + // C // initialise channel (netburst only) case 'C': break; - // T : + // T // change channel topic (netburst only) case 'T': break; diff --git a/src/modules.cpp b/src/modules.cpp index 93e2d7850..9a66e957e 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -156,7 +156,7 @@ void Server::SendToModeMask(std::string modes, int flags, std::string text) chanrec* Server::JoinUserToChannel(userrec* user, std::string cname, std::string key) { - return add_channel(user,cname.c_str(),key.c_str()); + return add_channel(user,cname.c_str(),key.c_str(),true); } chanrec* Server::PartUserFromChannel(userrec* user, std::string cname, std::string reason) -- cgit v1.2.3