X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Finspircd.cpp;h=6d664389d318d15230527dcf0a751a2cebed8baa;hb=ff3f693c894d2a7f689d3f85f5aa0efa47135df4;hp=62731ecf98f6c96d03375c60719dccce10a2ddaf;hpb=b05c15983a4331d7ea1faa190fdc95a028ba2223;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 62731ecf9..6d664389d 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -718,47 +718,64 @@ chanrec* add_channel(userrec *user, const char* cn, const char* key, bool overri for (unsigned int index =0; index < user->chans.size(); index++) { - log(DEBUG,"Check location %d",index); if (user->chans[index].channel == NULL) { - log(DEBUG,"Adding into their channel list at location %d",index); - - if (created == 2) - { - /* first user in is given ops */ - user->chans[index].uc_modes = UCMODE_OP; - } - else - { - user->chans[index].uc_modes = 0; - } - user->chans[index].channel = Ptr; - Ptr->AddUser((char*)user); - WriteChannel(Ptr,user,"JOIN :%s",Ptr->name); - - log(DEBUG,"Sent JOIN to client"); - - if (Ptr->topicset) - { - WriteServ(user->fd,"332 %s %s :%s", user->nick, Ptr->name, Ptr->topic); - WriteServ(user->fd,"333 %s %s %s %lu", user->nick, Ptr->name, Ptr->setby, (unsigned long)Ptr->topicset); - } - userlist(user,Ptr); - WriteServ(user->fd,"366 %s %s :End of /NAMES list.", user->nick, Ptr->name); - //WriteServ(user->fd,"324 %s %s +%s",user->nick, Ptr->name,chanmodes(Ptr)); - //WriteServ(user->fd,"329 %s %s %lu", user->nick, Ptr->name, (unsigned long)Ptr->created); - FOREACH_MOD OnUserJoin(user,Ptr); - return Ptr; + return ForceChan(Ptr,user->chans[index],user,created); } } /* XXX: If the user is an oper here, we can just extend their user->chans vector by one - * and put the channel in here. Otherwise, nope, youre boned. + * and put the channel in here. Same for remote users which are not bound by + * the channel limits. Otherwise, nope, youre boned. */ + if (strcasecmp(user->server,ServerName)) + { + ucrec a; + chanrec* c = ForceChan(Ptr,a,user,created); + user->chans.push_back(a); + return c; + } + else if (strchr(user->modes,'o')) + { + /* Oper allows extension up to the OPERMAXCHANS value */ + if (user->chans.size() < OPERMAXCHANS) + { + ucrec a; + chanrec* c = ForceChan(Ptr,a,user,created); + user->chans.push_back(a); + return c; + } + } log(DEBUG,"add_channel: user channel max exceeded: %s %s",user->nick,cname); WriteServ(user->fd,"405 %s %s :You are on too many channels",user->nick, cname); return NULL; } +chanrec* ForceChan(chanrec* Ptr,ucrec &a,userrec* user, int created) +{ + if (created == 2) + { + /* first user in is given ops */ + a.uc_modes = UCMODE_OP; + } + else + { + a.uc_modes = 0; + } + a.channel = Ptr; + Ptr->AddUser((char*)user); + WriteChannel(Ptr,user,"JOIN :%s",Ptr->name); + log(DEBUG,"Sent JOIN to client"); + if (Ptr->topicset) + { + WriteServ(user->fd,"332 %s %s :%s", user->nick, Ptr->name, Ptr->topic); + WriteServ(user->fd,"333 %s %s %s %lu", user->nick, Ptr->name, Ptr->setby, (unsigned long)Ptr->topicset); + } + userlist(user,Ptr); + WriteServ(user->fd,"366 %s %s :End of /NAMES list.", user->nick, Ptr->name); + FOREACH_MOD OnUserJoin(user,Ptr); + return Ptr; +} + /* remove a channel from a users record, and remove the record from memory * if the channel has become empty */ @@ -2309,11 +2326,14 @@ int InspIRCd(char** argv, int argc) bool expire_run = false; std::vector activefds; int incomingSockfd; + int in_port; userrec* cu = NULL; InspSocket* s = NULL; InspSocket* s_del = NULL; - char target[MAXBUF]; + char* target; unsigned int numberactive; + sockaddr_in sock_us; // our port number + socklen_t uslen; // length of our port number /* Beta 7 moved all this stuff out of the main function * into smaller sub-functions, much tidier -- Brain @@ -2458,7 +2478,6 @@ int InspIRCd(char** argv, int argc) * within it, making them 'fire and forget' * and independent of the mainloop. */ - log(DEBUG,"Got a ready socket of type X_ESTAB_DNS"); #ifndef THREADED_DNS dns_poll(activefds[activefd]); #endif @@ -2467,36 +2486,37 @@ int InspIRCd(char** argv, int argc) case X_LISTEN: /* It's a listener */ - for (int count = 0; count < boundPortCount; count++) + uslen = sizeof(sock_us); + length = sizeof(client); + incomingSockfd = accept (activefds[activefd],(struct sockaddr*)&client,&length); + if (!getsockname(incomingSockfd,(sockaddr*)&sock_us,&uslen)) { - if (activefds[activefd] == openSockfd[count]) + in_port = ntohs(sock_us.sin_port); + log(DEBUG,"Accepted socket %d",incomingSockfd); + target = (char*)inet_ntoa(client.sin_addr); + /* Years and years ago, we used to resolve here + * using gethostbyaddr(). That is sucky and we + * don't do that any more... + */ + if (incomingSockfd >= 0) { - length = sizeof (client); - incomingSockfd = accept (openSockfd[count], (struct sockaddr *) &client, &length); - log(DEBUG,"Accepted socket %d",incomingSockfd); - strlcpy (target, (char *) inet_ntoa (client.sin_addr), MAXBUF); - /* Years and years ago, we used to resolve here - * using gethostbyaddr(). That is sucky and we - * don't do that any more... - */ - if (incomingSockfd >= 0) - { - FOREACH_MOD OnRawSocketAccept(incomingSockfd, target, ports[count]); - statsAccept++; - AddClient(incomingSockfd, target, ports[count], false, inet_ntoa (client.sin_addr)); - log(DEBUG,"Adding client on port %lu fd=%lu",(unsigned long)ports[count],(unsigned long)incomingSockfd); - } - else - { - WriteOpers("*** WARNING: accept() failed on port %lu (%s)",(unsigned long)ports[count],target); - log(DEBUG,"accept failed: %lu",(unsigned long)ports[count]); - statsRefused++; - } - /* We've found out what port it belongs on, - * no need to iterate the rest - */ - break; + FOREACH_MOD OnRawSocketAccept(incomingSockfd, target, in_port); + statsAccept++; + AddClient(incomingSockfd, target, in_port, false, target); + log(DEBUG,"Adding client on port %lu fd=%lu",(unsigned long)in_port,(unsigned long)incomingSockfd); } + else + { + WriteOpers("*** WARNING: accept() failed on port %lu (%s)",(unsigned long)in_port,target); + log(DEBUG,"accept failed: %lu",(unsigned long)in_port); + statsRefused++; + } + } + else + { + log(DEBUG,"Couldnt look up the port number for fd %lu (OS BROKEN?!)",incomingSockfd); + shutdown(incomingSockfd,2); + close(incomingSockfd); } break;