}
-void WriteChannelWithServ(char* ServName, chanrec* Ptr, userrec* user, char* text, ...)
+void WriteChannelWithServ(char* ServName, chanrec* Ptr, char* text, ...)
{
- if ((!Ptr) || (!user) || (!text))
+ if ((!Ptr) || (!text))
{
log(DEFAULT,"*** BUG *** WriteChannelWithServ was given an invalid parameter");
return;
vsnprintf(textbuffer, MAXBUF, text, argsPtr);
va_end(argsPtr);
- WriteFrom(u->fd,u,"%s",textbuffer);
+ // FIX: Stops a message going to the same person more than once
+ std::vector<int> already_sent;
for (int i = 0; i < MAXCHANS; i++)
{
{
char* o = (*ulist)[j];
userrec* otheruser = (userrec*)o;
- WriteFrom(otheruser->fd,u,"%s",textbuffer);
+ bool do_send = true;
+ for (int t = 0; t < already_sent.size(); t++)
+ {
+ if (already_sent[t] == otheruser->fd)
+ {
+ do_send = false;
+ break;
+ }
+ }
+ if (do_send)
+ {
+ already_sent.push_back(otheruser->fd);
+ WriteFrom(otheruser->fd,u,"%s",textbuffer);
+ }
}
}
}
+ // if the user was not in any channels, no users will receive the text. Make sure the user
+ // receives their OWN message for WriteCommon
+ if (!already_sent.size())
+ {
+ WriteFrom(u->fd,u,"%s",textbuffer);
+ }
}
/* write a formatted string to all users who share at least one common
vsnprintf(textbuffer, MAXBUF, text, argsPtr);
va_end(argsPtr);
+ std::vector<int> already_sent;
+
for (int i = 0; i < MAXCHANS; i++)
{
if (u->chans[i].channel)
char* o = (*ulist)[j];
userrec* otheruser = (userrec*)o;
if (u != otheruser)
- WriteFrom(otheruser->fd,u,"%s",textbuffer);
+ {
+ bool do_send = true;
+ for (int t = 0; t < already_sent.size(); t++)
+ {
+ if (already_sent[t] == otheruser->fd)
+ {
+ do_send = false;
+ break;
+ }
+ }
+ if (do_send)
+ {
+ already_sent.push_back(otheruser->fd);
+ WriteFrom(otheruser->fd,u,"%s",textbuffer);
+ }
+ }
}
}
}
AddWhoWas(user);
}
+ if (user->registered == 7) {
+ purge_empty_chans(user);
+ }
+
if (iter != clientlist.end())
{
log(DEBUG,"deleting user hash value %lu",(unsigned long)iter->second);
}
clientlist.erase(iter);
}
-
- if (user->registered == 7) {
- purge_empty_chans(user);
- }
- //user = NULL;
}
void kill_link_silent(userrec *user,const char* r)
shutdown(user->fd,2);
close(user->fd);
}
+
+ if (user->registered == 7) {
+ purge_empty_chans(user);
+ }
if (iter != clientlist.end())
{
}
clientlist.erase(iter);
}
-
- if (user->registered == 7) {
- purge_empty_chans(user);
- }
}
}
}
-void handle_version(char **parameters, int pcnt, userrec *user)
+std::string GetVersionString()
{
- char Revision[] = "$Revision$";
+ char Revision[] = "$Revision$";
+ char versiondata[MAXBUF];
+ char *s1 = Revision;
+ char *savept;
+ char *v2 = strtok_r(s1," ",&savept);
+ s1 = savept;
+ v2 = strtok_r(s1," ",&savept);
+ s1 = savept;
+ snprintf(versiondata,MAXBUF,"%s Rev. %s %s :%s (O=%lu)",VERSION,v2,ServerName,SYSTEM,(unsigned long)OPTIMISATION);
+ return versiondata;
+}
- char *s1 = Revision;
- char *savept;
- char *v2 = strtok_r(s1," ",&savept);
- s1 = savept;
- v2 = strtok_r(s1," ",&savept);
- s1 = savept;
-
- WriteServ(user->fd,"351 %s :%s Rev. %s %s :%s (O=%lu)",user->nick,VERSION,v2,ServerName,SYSTEM,(unsigned long)OPTIMISATION);
+void handle_version(char **parameters, int pcnt, userrec *user)
+{
+ if (!pcnt)
+ {
+ WriteServ(user->fd,"351 %s :%s",user->nick,GetVersionString().c_str());
+ }
+ else
+ {
+ for (int j = 0; j < 32; j++)
+ {
+ if (me[j] != NULL)
+ {
+ for (int x = 0; x < me[j]->connectors.size(); x++)
+ {
+ if (match(me[j]->connectors[x].GetServerName().c_str(),parameters[0]))
+ {
+ WriteServ(user->fd,"351 %s :%s",user->nick,me[j]->connectors[x].GetVersionString().c_str());
+ return;
+ }
+ }
+ }
+ }
+ WriteServ(user->fd,"402 %s %s :No such server",user->nick,parameters[0]);
+ }
+ return;
}
{
if (strlen(command)>=(strlen(cmdlist[i].command))) if (!strncmp(command, cmdlist[i].command,MAXCOMMAND))
{
- log(DEBUG,"Found matching command");
-
if (parameters)
{
if (parameters[0])
if (user)
{
- log(DEBUG,"Processing command");
-
/* activity resets the ping pending timer */
user->nping = TIME + user->pingmax;
if ((items) < cmdlist[i].min_params)
}
if ((user->registered == 7) || (!strncmp(command,"USER",4)) || (!strncmp(command,"NICK",4)) || (!strncmp(command,"PASS",4)))
{
- log(DEBUG,"process_command: handler: %s %s %lu",user->nick,command,(unsigned long)items);
if (cmdlist[i].handler_function)
{
}
else
{
- log(DEBUG,"process_command: not registered: %s %s",user->nick,command);
WriteServ(user->fd,"451 %s :You have not registered",command);
return;
}
}
if ((!cmd_found) && (user))
{
- log(DEBUG,"process_command: not in table: %s %s",user->nick,command);
WriteServ(user->fd,"421 %s %s :Unknown command",user->nick,command);
}
}
{
return;
}
- log(DEBUG,"InspIRCd: processing: %s %s",user->nick,cmd);
+ log(DEBUG,"CMDIN: %s %s",user->nick,cmd);
tidystring(cmd);
if ((user) && (cmd))
{
snprintf(data,MAXBUF,"Y %lu",(unsigned long)TIME);
serv->SendPacket(data,tcp_host);
// send users and channels
+
+ NetSendMyRoutingTable();
+
+ // send all routing table and uline voodoo. The ordering of these commands is IMPORTANT!
+ for (int j = 0; j < 32; j++)
+ {
+ if (me[j] != NULL)
+ {
+ for (int k = 0; k < me[j]->connectors.size(); k++)
+ {
+ if (is_uline(me[j]->connectors[k].GetServerName().c_str()))
+ {
+ snprintf(data,MAXBUF,"H %s",me[j]->connectors[k].GetServerName().c_str());
+ serv->SendPacket(data,tcp_host);
+ }
+ }
+ }
+ }
+
+ // send our version for the remote side to cache
+ snprintf(data,MAXBUF,"v %s %s",ServerName,GetVersionString().c_str());
+ serv->SendPacket(data,tcp_host);
+
+ // sync the users and channels, give the modules a look-in.
for (user_hash::iterator u = clientlist.begin(); u != clientlist.end(); u++)
{
snprintf(data,MAXBUF,"N %lu %s %s %s %s +%s %s %s :%s",(unsigned long)u->second->age,u->second->nick,u->second->host,u->second->dhost,u->second->ident,u->second->modes,u->second->ip,u->second->server,u->second->fullname);
// sync global zlines, glines, etc
sync_xlines(serv,tcp_host);
- for (int j = 0; j < 32; j++)
- {
- if (me[j] != NULL)
- {
- for (int k = 0; k < me[j]->connectors.size(); k++)
- {
- if (is_uline(me[j]->connectors[k].GetServerName().c_str()))
- {
- snprintf(data,MAXBUF,"H %s",me[j]->connectors[k].GetServerName().c_str());
- serv->SendPacket(data,tcp_host);
- NetSendMyRoutingTable();
- }
- }
- }
- }
-
snprintf(data,MAXBUF,"F %lu",(unsigned long)TIME);
serv->SendPacket(data,tcp_host);
log(DEBUG,"Sent sync");
}
work[p--] = '\0';
}
- log(DEBUG,"Dir valid: %s",work);
char buffer[MAXBUF], otherdir[MAXBUF];
// Get the current working directory
if( getcwd( buffer, MAXBUF ) == NULL )
if( getcwd( otherdir, MAXBUF ) == NULL )
return false;
chdir(buffer);
- log(DEBUG,"Dir is really: %s",otherdir);
if (strlen(otherdir) >= strlen(work))
{
otherdir[strlen(work)] = '\0';
- log(DEBUG,"Compare: '%s' -> '%s'",otherdir,work);
if (!strcmp(otherdir,work))
{
- log(DEBUG,"Match ok");
return true;
}
- log(DEBUG,"No match");
return false;
}
else return false;
Exit(ERROR);
}
- log(DEBUG,"InspIRCd: startup: begin");
- log(DEBUG,"$Id$");
+ log(DEFAULT,"$Id$");
if (geteuid() == 0)
{
printf("WARNING!!! You are running an irc server as ROOT!!! DO NOT DO THIS!!!\n\n");
printf("Loading module... \033[1;32m%s\033[0m\n",configToken);
if (!LoadModule(configToken))
{
- log(DEBUG,"Exiting due to a module loader error.");
+ log(DEFAULT,"Exiting due to a module loader error.");
printf("\nThere was an error loading a module: %s\n\nYou might want to do './inspircd start' instead of 'bin/inspircd'\n\n",ModuleError());
Exit(0);
}
}
- log(DEBUG,"Total loaded modules: %lu",(unsigned long)MODCOUNT+1);
+ log(DEFAULT,"Total loaded modules: %lu",(unsigned long)MODCOUNT+1);
startup_time = time(NULL);
fd_set serverfds;
timeval tvs;
- tvs.tv_usec = 7000L;
+ tvs.tv_usec = 10000L;
tvs.tv_sec = 0;
tv.tv_sec = 0;
- tv.tv_usec = 7000L;
- char data[10240];
+ tv.tv_usec = 10000L;
+ char data[65535];
timeval tval;
fd_set sfd;
- tval.tv_usec = 7000L;
+ tval.tv_usec = 10000L;
tval.tv_sec = 0;
int total_in_this_set = 0;
int v = 0;
// serverFds timevals went here
- tvs.tv_usec = 7000L;
+ tvs.tv_usec = 30000L;
tvs.tv_sec = 0;
int servresult = select(32767, &serverfds, NULL, NULL, &tvs);
if (servresult > 0)
}
}
- for (int cycle = 0; cycle < 4; cycle++) for (int x = 0; x < UDPportCount; x++)
+ for (int x = 0; x < UDPportCount; x++)
{
std::deque<std::string> msgs;
msgs.clear();
// tvals defined here
- tval.tv_usec = 7000L;
+ tval.tv_usec = 1000L;
selectResult2 = select(65535, &sfd, NULL, NULL, &tval);
// now loop through all of the items in this pool if any are waiting
result = EAGAIN;
if ((count2a->second->fd != FD_MAGIC_NUMBER) && (count2a->second->fd != -1) && (FD_ISSET (count2a->second->fd, &sfd)))
{
- memset(data, 0, 10240);
- result = read(count2a->second->fd, data, 10240);
-
+ result = read(count2a->second->fd, data, 65535);
if (result)
{
// perform a check on the raw buffer as an array (not a string!) to remove
if ((data[checker] == 0) || (data[checker] == 7))
data[checker] = ' ';
}
+ if (result > 0)
+ data[result] = '\0';
userrec* current = count2a->second;
int currfd = current->fd;
- char* l = strtok(data,"\n");
int floodlines = 0;
- while (l)
+ current->AddBuffer(data);
+ if (current->recvq.length() > NetBufferSize)
{
- floodlines++;
- if ((floodlines > current->flood) && (current->flood != 0))
+ if (current->registered == 7)
{
- log(DEFAULT,"Excess flood from: %s!%s@%s",current->nick,current->ident,current->host);
- WriteOpers("*** Excess flood from: %s!%s@%s",current->nick,current->ident,current->host);
- kill_link(current,"Excess flood");
- goto label;
+ kill_link(current,"RecvQ exceeded");
+ }
+ else
+ {
+ add_zline(120,ServerName,"Flood from unregistered connection",current->ip);
+ apply_lines();
}
- char sanitized[NetBufferSize];
- memset(sanitized, 0, NetBufferSize);
- int ptt = 0;
- for (int pt = 0; pt < strlen(l); pt++)
+ goto label;
+ }
+ // while there are complete lines to process...
+ while (current->BufferIsReady())
+ {
+ floodlines++;
+ if ((floodlines > current->flood) && (current->flood != 0))
{
- if (l[pt] != '\r')
+ if (current->registered == 7)
+ {
+ log(DEFAULT,"Excess flood from: %s!%s@%s",current->nick,current->ident,current->host);
+ WriteOpers("*** Excess flood from: %s!%s@%s",current->nick,current->ident,current->host);
+ kill_link(current,"Excess flood");
+ }
+ else
{
- sanitized[ptt++] = l[pt];
+ add_zline(120,ServerName,"Flood from unregistered connection",current->ip);
+ apply_lines();
}
+ goto label;
}
- sanitized[ptt] = '\0';
+ char sanitized[MAXBUF];
+ // use GetBuffer to copy single lines into the sanitized string
+ strlcpy(sanitized,current->GetBuffer().c_str(),MAXBUF);
if (*sanitized)
{
-
-
// we're gonna re-scan to check if the nick is gone, after every
// command - if it has, we're gonna bail
bool find_again = false;
process_buffer(sanitized,current);
-
// look for the user's record in case it's changed
for (user_hash::iterator c2 = clientlist.begin(); c2 != clientlist.end(); c2++)
{
goto label;
}
- l = strtok(NULL,"\n");
}
goto label;
}
}
for (int q = 0; q < total_in_this_set; q++)
{
- // there is no iterator += operator :(
- //if (count2 != clientlist.end())
- //{
- count2++;
- //}
+ count2++;
}
}
+
+#ifdef _POSIX_PRIORITY_SCHEDULING
+ sched_yield();
+#endif
// set up select call
for (count = 0; count < boundPortCount; count++)
FD_SET (openSockfd[count], &selectFds);
}
- tv.tv_usec = 7000L;
+ tv.tv_usec = 30000L;
selectResult = select(MAXSOCKS, &selectFds, NULL, NULL, &tv);
/* select is reporting a waiting socket. Poll them all to find out which */
}
label:
if (0) {};
+#ifdef _POSIX_PRIORITY_SCHEDULING
+ sched_yield();
+#endif
}
/* not reached */
close (incomingSockfd);