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 */
bool expire_run = false;
std::vector<int> 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
* 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
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;