From f62de63955ff77e800360eb140f108b5d2c6c075 Mon Sep 17 00:00:00 2001 From: brain Date: Mon, 19 Dec 2005 18:32:09 +0000 Subject: Design flaw my ass. git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@2580 e03df62e-2008-0410-955e-edbf42e46eb7 --- docs/module-doc/users_8cpp-source.html | 818 --------------------------------- 1 file changed, 818 deletions(-) delete mode 100644 docs/module-doc/users_8cpp-source.html (limited to 'docs/module-doc/users_8cpp-source.html') diff --git a/docs/module-doc/users_8cpp-source.html b/docs/module-doc/users_8cpp-source.html deleted file mode 100644 index 8b129741a..000000000 --- a/docs/module-doc/users_8cpp-source.html +++ /dev/null @@ -1,818 +0,0 @@ - - -InspIRCd: users.cpp Source File - - - -
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members
- -

users.cpp

Go to the documentation of this file.
00001 /*       +------------------------------------+
-00002  *       | Inspire Internet Relay Chat Daemon |
-00003  *       +------------------------------------+
-00004  *
-00005  *  Inspire is copyright (C) 2002-2004 ChatSpike-Dev.
-00006  *                       E-mail:
-00007  *                <brain@chatspike.net>
-00008  *                <Craig@chatspike.net>
-00009  *     
-00010  * Written by Craig Edwards, Craig McLure, and others.
-00011  * This program is free but copyrighted software; see
-00012  *            the file COPYING for details.
-00013  *
-00014  * ---------------------------------------------------
-00015  */
-00016 
-00017 using namespace std;
-00018 
-00019 #include "inspircd_config.h" 
-00020 #include "channels.h"
-00021 #include "connection.h"
-00022 #include "users.h"
-00023 #include "inspircd.h"
-00024 #include <stdio.h>
-00025 #ifdef THREADED_DNS
-00026 #include <pthread.h>
-00027 #include <signal.h>
-00028 #endif
-00029 #include "inspstring.h"
-00030 #include "commands.h"
-00031 #include "helperfuncs.h"
-00032 #include "typedefs.h"
-00033 #include "socketengine.h"
-00034 #include "hashcomp.h"
-00035 #include "message.h"
-00036 #include "wildcard.h"
-00037 #include "xline.h"
-00038 
-00039 extern InspIRCd* ServerInstance;
-00040 extern int WHOWAS_STALE;
-00041 extern int WHOWAS_MAX;
-00042 extern std::vector<Module*> modules;
-00043 extern std::vector<ircd_module*> factory;
-00044 extern std::vector<InspSocket*> module_sockets;
-00045 extern int MODCOUNT;
-00046 extern InspSocket* socket_ref[65535];
-00047 extern time_t TIME;
-00048 extern userrec* fd_ref_table[65536];
-00049 extern ServerConfig *Config;
-00050 extern user_hash clientlist;
-00051 extern whowas_hash whowas;
-00052 std::vector<userrec*> local_users;
-00053 
-00054 std::vector<userrec*> all_opers;
-00055 
-00056 template<typename T> inline string ConvToStr(const T &in)
-00057 {
-00058         stringstream tmp;
-00059         if (!(tmp << in)) return string();
-00060         return tmp.str();
-00061 }
-00062 
-00063 userrec::userrec()
-00064 {
-00065         // the PROPER way to do it, AVOID bzero at *ALL* costs
-00066         strcpy(nick,"");
-00067         strcpy(ip,"127.0.0.1");
-00068         timeout = 0;
-00069         strcpy(ident,"");
-00070         strcpy(host,"");
-00071         strcpy(dhost,"");
-00072         strcpy(fullname,"");
-00073         strcpy(modes,"");
-00074         server = (char*)FindServerNamePtr(Config->ServerName);
-00075         strcpy(awaymsg,"");
-00076         strcpy(oper,"");
-00077         reset_due = TIME;
-00078         lines_in = 0;
-00079         fd = lastping = signon = idle_lastmsg = nping = registered = 0;
-00080         flood = port = bytes_in = bytes_out = cmds_in = cmds_out = 0;
-00081         haspassed = false;
-00082         dns_done = false;
-00083         recvq = "";
-00084         sendq = "";
-00085         chans.clear();
-00086         invites.clear();
-00087 }
-00088 
-00089 userrec::~userrec()
-00090 {
-00091 }
-00092 
-00093 void userrec::CloseSocket()
-00094 {
-00095         shutdown(this->fd,2);
-00096         close(this->fd);
-00097 }
-00098  
-00099 char* userrec::GetFullHost()
-00100 {
-00101         static char result[MAXBUF];
-00102         snprintf(result,MAXBUF,"%s!%s@%s",nick,ident,dhost);
-00103         return result;
-00104 }
-00105 
-00106 int userrec::ReadData(void* buffer, size_t size)
-00107 {
-00108         if (this->fd > -1)
-00109         {
-00110                 return read(this->fd, buffer, size);
-00111         }
-00112         else return 0;
-00113 }
-00114 
-00115 
-00116 char* userrec::GetFullRealHost()
-00117 {
-00118         static char fresult[MAXBUF];
-00119         snprintf(fresult,MAXBUF,"%s!%s@%s",nick,ident,host);
-00120         return fresult;
-00121 }
-00122 
-00123 bool userrec::IsInvited(irc::string &channel)
-00124 {
-00125         for (InvitedList::iterator i = invites.begin(); i != invites.end(); i++)
-00126         {
-00127                 irc::string compare = i->channel;
-00128                 if (compare == channel)
-00129                 {
-00130                         return true;
-00131                 }
-00132         }
-00133         return false;
-00134 }
-00135 
-00136 InvitedList* userrec::GetInviteList()
-00137 {
-00138         return &invites;
-00139 }
-00140 
-00141 void userrec::InviteTo(irc::string &channel)
-00142 {
-00143         Invited i;
-00144         i.channel = channel;
-00145         invites.push_back(i);
-00146 }
-00147 
-00148 void userrec::RemoveInvite(irc::string &channel)
-00149 {
-00150         log(DEBUG,"Removing invites");
-00151         if (invites.size())
-00152         {
-00153                 for (InvitedList::iterator i = invites.begin(); i != invites.end(); i++)
-00154                 {
-00155                         irc::string compare = i->channel;
-00156                         if (compare == channel)
-00157                         {
-00158                                 invites.erase(i);
-00159                                 return;
-00160                         }
-00161                 }
-00162         }
-00163 }
-00164 
-00165 bool userrec::HasPermission(std::string &command)
-00166 {
-00167         char TypeName[MAXBUF],Classes[MAXBUF],ClassName[MAXBUF],CommandList[MAXBUF];
-00168         char* mycmd;
-00169         char* savept;
-00170         char* savept2;
-00171         
-00172         // users on u-lined servers can completely bypass
-00173         // all permissions based checks.
-00174         //
-00175         // of course, if this is sent to a remote server and this
-00176         // server is not ulined there, then that other server
-00177         // silently drops the command.
-00178         if (is_uline(this->server))
-00179                 return true;
-00180         
-00181         // are they even an oper at all?
-00182         if (strchr(this->modes,'o'))
-00183         {
-00184                 for (int j =0; j < Config->ConfValueEnum("type",&Config->config_f); j++)
-00185                 {
-00186                         Config->ConfValue("type","name",j,TypeName,&Config->config_f);
-00187                         if (!strcmp(TypeName,this->oper))
-00188                         {
-00189                                 Config->ConfValue("type","classes",j,Classes,&Config->config_f);
-00190                                 char* myclass = strtok_r(Classes," ",&savept);
-00191                                 while (myclass)
-00192                                 {
-00193                                         for (int k =0; k < Config->ConfValueEnum("class",&Config->config_f); k++)
-00194                                         {
-00195                                                 Config->ConfValue("class","name",k,ClassName,&Config->config_f);
-00196                                                 if (!strcmp(ClassName,myclass))
-00197                                                 {
-00198                                                         Config->ConfValue("class","commands",k,CommandList,&Config->config_f);
-00199                                                         mycmd = strtok_r(CommandList," ",&savept2);
-00200                                                         while (mycmd)
-00201                                                         {
-00202                                                                 if ((!strcasecmp(mycmd,command.c_str())) || (*mycmd == '*'))
-00203                                                                 {
-00204                                                                         return true;
-00205                                                                 }
-00206                                                                 mycmd = strtok_r(NULL," ",&savept2);
-00207                                                         }
-00208                                                 }
-00209                                         }
-00210                                         myclass = strtok_r(NULL," ",&savept);
-00211                                 }
-00212                         }
-00213                 }
-00214         }
-00215         return false;
-00216 }
-00217 
-00218 
-00219 bool userrec::AddBuffer(std::string a)
-00220 {
-00221         std::string b = "";
-00222         for (unsigned int i = 0; i < a.length(); i++)
-00223                 if ((a[i] != '\r') && (a[i] != '\0') && (a[i] != 7))
-00224                         b = b + a[i];
-00225         std::stringstream stream(recvq);
-00226         stream << b;
-00227         recvq = stream.str();
-00228         unsigned int i = 0;
-00229         // count the size of the first line in the buffer.
-00230         while (i < recvq.length())
-00231         {
-00232                 if (recvq[i++] == '\n')
-00233                         break;
-00234         }
-00235         if (recvq.length() > (unsigned)this->recvqmax)
-00236         {
-00237                 this->SetWriteError("RecvQ exceeded");
-00238                 WriteOpers("*** User %s RecvQ of %d exceeds connect class maximum of %d",this->nick,recvq.length(),this->recvqmax);
-00239         }
-00240         // return false if we've had more than 600 characters WITHOUT
-00241         // a carriage return (this is BAD, drop the socket)
-00242         return (i < 600);
-00243 }
-00244 
-00245 bool userrec::BufferIsReady()
-00246 {
-00247         for (unsigned int i = 0; i < recvq.length(); i++)
-00248                 if (recvq[i] == '\n')
-00249                         return true;
-00250         return false;
-00251 }
-00252 
-00253 void userrec::ClearBuffer()
-00254 {
-00255         recvq = "";
-00256 }
-00257 
-00258 std::string userrec::GetBuffer()
-00259 {
-00260         if (recvq == "")
-00261                 return "";
-00262         char* line = (char*)recvq.c_str();
-00263         std::string ret = "";
-00264         while ((*line != '\n') && (strlen(line)))
-00265         {
-00266                 ret = ret + *line;
-00267                 line++;
-00268         }
-00269         if ((*line == '\n') || (*line == '\r'))
-00270                 line++;
-00271         recvq = line;
-00272         return ret;
-00273 }
-00274 
-00275 void userrec::AddWriteBuf(std::string data)
-00276 {
-00277         if (this->GetWriteError() != "")
-00278                 return;
-00279         if (sendq.length() + data.length() > (unsigned)this->sendqmax)
-00280         {
-00281                 /* Fix by brain - Set the error text BEFORE calling writeopers, because
-00282                  * if we dont it'll recursively  call here over and over again trying
-00283                  * to repeatedly add the text to the sendq!
-00284                  */
-00285                 this->SetWriteError("SendQ exceeded");
-00286                 WriteOpers("*** User %s SendQ of %d exceeds connect class maximum of %d",this->nick,sendq.length() + data.length(),this->sendqmax);
-00287                 return;
-00288         }
-00289         std::stringstream stream;
-00290         stream << sendq << data;
-00291         sendq = stream.str();
-00292 }
-00293 
-00294 // send AS MUCH OF THE USERS SENDQ as we are able to (might not be all of it)
-00295 void userrec::FlushWriteBuf()
-00296 {
-00297         if (sendq.length())
-00298         {
-00299                 char* tb = (char*)this->sendq.c_str();
-00300                 int n_sent = write(this->fd,tb,this->sendq.length());
-00301                 if (n_sent == -1)
-00302                 {
-00303                         this->SetWriteError(strerror(errno));
-00304                 }
-00305                 else
-00306                 {
-00307                         // advance the queue
-00308                         tb += n_sent;
-00309                         this->sendq = tb;
-00310                         // update the user's stats counters
-00311                         this->bytes_out += n_sent;
-00312                         this->cmds_out++;
-00313                 }
-00314         }
-00315 }
-00316 
-00317 void userrec::SetWriteError(std::string error)
-00318 {
-00319         log(DEBUG,"Setting error string for %s to '%s'",this->nick,error.c_str());
-00320         // don't try to set the error twice, its already set take the first string.
-00321         if (this->WriteError == "")
-00322                 this->WriteError = error;
-00323 }
-00324 
-00325 std::string userrec::GetWriteError()
-00326 {
-00327         return this->WriteError;
-00328 }
-00329 
-00330 void AddOper(userrec* user)
-00331 {
-00332         log(DEBUG,"Oper added to optimization list");
-00333         all_opers.push_back(user);
-00334 }
-00335 
-00336 void DeleteOper(userrec* user)
-00337 {
-00338         for (std::vector<userrec*>::iterator a = all_opers.begin(); a < all_opers.end(); a++)
-00339         {
-00340                 if (*a == user)
-00341                 {
-00342                         log(DEBUG,"Oper removed from optimization list");
-00343                         all_opers.erase(a);
-00344                         return;
-00345                 }
-00346         }
-00347 }
-00348 
-00349 void kill_link(userrec *user,const char* r)
-00350 {
-00351         user_hash::iterator iter = clientlist.find(user->nick);
-00352 
-00353         char reason[MAXBUF];
-00354 
-00355         strncpy(reason,r,MAXBUF);
-00356 
-00357         if (strlen(reason)>MAXQUIT)
-00358         {
-00359                 reason[MAXQUIT-1] = '\0';
-00360         }
-00361 
-00362         log(DEBUG,"kill_link: %s '%s'",user->nick,reason);
-00363         Write(user->fd,"ERROR :Closing link (%s@%s) [%s]",user->ident,user->host,reason);
-00364         log(DEBUG,"closing fd %lu",(unsigned long)user->fd);
-00365 
-00366         if (user->registered == 7) {
-00367                 FOREACH_MOD OnUserQuit(user,reason);
-00368                 WriteCommonExcept(user,"QUIT :%s",reason);
-00369         }
-00370 
-00371         user->FlushWriteBuf();
-00372 
-00373         FOREACH_MOD OnUserDisconnect(user);
-00374 
-00375         if (user->fd > -1)
-00376         {
-00377                 if (Config->GetIOHook(user->port))
-00378                 {
-00379                         Config->GetIOHook(user->port)->OnRawSocketClose(user->fd);
-00380                 }
-00381                 ServerInstance->SE->DelFd(user->fd);
-00382                 user->CloseSocket();
-00383         }
-00384 
-00385         // this must come before the WriteOpers so that it doesnt try to fill their buffer with anything
-00386         // if they were an oper with +s.
-00387         if (user->registered == 7) {
-00388                 purge_empty_chans(user);
-00389                 // fix by brain: only show local quits because we only show local connects (it just makes SENSE)
-00390                 if (user->fd > -1)
-00391                         WriteOpers("*** Client exiting: %s!%s@%s [%s]",user->nick,user->ident,user->host,reason);
-00392                 AddWhoWas(user);
-00393         }
-00394 
-00395         if (iter != clientlist.end())
-00396         {
-00397                 log(DEBUG,"deleting user hash value %lu",(unsigned long)user);
-00398                 if (user->fd > -1)
-00399                 {
-00400                         fd_ref_table[user->fd] = NULL;
-00401                         if (find(local_users.begin(),local_users.end(),user) != local_users.end())
-00402                         {
-00403                                 local_users.erase(find(local_users.begin(),local_users.end(),user));
-00404                                 log(DEBUG,"Delete local user");
-00405                         }
-00406                 }
-00407                 clientlist.erase(iter);
-00408         }
-00409         delete user;
-00410 }
-00411 
-00412 void kill_link_silent(userrec *user,const char* r)
-00413 {
-00414         user_hash::iterator iter = clientlist.find(user->nick);
-00415 
-00416         char reason[MAXBUF];
-00417 
-00418         strncpy(reason,r,MAXBUF);
-00419 
-00420         if (strlen(reason)>MAXQUIT)
-00421         {
-00422                 reason[MAXQUIT-1] = '\0';
-00423         }
-00424 
-00425         log(DEBUG,"kill_link: %s '%s'",user->nick,reason);
-00426         Write(user->fd,"ERROR :Closing link (%s@%s) [%s]",user->ident,user->host,reason);
-00427         log(DEBUG,"closing fd %lu",(unsigned long)user->fd);
-00428 
-00429         user->FlushWriteBuf();
-00430 
-00431         if (user->registered == 7) {
-00432                 FOREACH_MOD OnUserQuit(user,reason);
-00433                 WriteCommonExcept(user,"QUIT :%s",reason);
-00434         }
-00435 
-00436         FOREACH_MOD OnUserDisconnect(user);
-00437 
-00438         if (user->fd > -1)
-00439         {
-00440                 if (Config->GetIOHook(user->port))
-00441                 {
-00442                         Config->GetIOHook(user->port)->OnRawSocketClose(user->fd);
-00443                 }
-00444                 ServerInstance->SE->DelFd(user->fd);
-00445                 user->CloseSocket();
-00446         }
-00447 
-00448         if (user->registered == 7) {
-00449                 purge_empty_chans(user);
-00450         }
-00451 
-00452         if (iter != clientlist.end())
-00453         {
-00454                 log(DEBUG,"deleting user hash value %lu",(unsigned long)user);
-00455                 if (user->fd > -1)
-00456                 {
-00457                         fd_ref_table[user->fd] = NULL;
-00458                         if (find(local_users.begin(),local_users.end(),user) != local_users.end())
-00459                         {
-00460                                 log(DEBUG,"Delete local user");
-00461                                 local_users.erase(find(local_users.begin(),local_users.end(),user));
-00462                         }
-00463                 }
-00464                 clientlist.erase(iter);
-00465         }
-00466         delete user;
-00467 }
-00468 
-00469 
-00470 /* adds or updates an entry in the whowas list */
-00471 void AddWhoWas(userrec* u)
-00472 {
-00473         whowas_hash::iterator iter = whowas.find(u->nick);
-00474         WhoWasUser *a = new WhoWasUser();
-00475         strlcpy(a->nick,u->nick,NICKMAX);
-00476         strlcpy(a->ident,u->ident,IDENTMAX);
-00477         strlcpy(a->dhost,u->dhost,160);
-00478         strlcpy(a->host,u->host,160);
-00479         strlcpy(a->fullname,u->fullname,MAXGECOS);
-00480         strlcpy(a->server,u->server,256);
-00481         a->signon = u->signon;
-00482 
-00483         /* MAX_WHOWAS:   max number of /WHOWAS items
-00484          * WHOWAS_STALE: number of hours before a WHOWAS item is marked as stale and
-00485          *               can be replaced by a newer one
-00486          */
-00487 
-00488         if (iter == whowas.end())
-00489         {
-00490                 if (whowas.size() >= (unsigned)WHOWAS_MAX)
-00491                 {
-00492                         for (whowas_hash::iterator i = whowas.begin(); i != whowas.end(); i++)
-00493                         {
-00494                                 // 3600 seconds in an hour ;)
-00495                                 if ((i->second->signon)<(TIME-(WHOWAS_STALE*3600)))
-00496                                 {
-00497                                         // delete the old one
-00498                                         if (i->second) delete i->second;
-00499                                         // replace with new one
-00500                                         i->second = a;
-00501                                         log(DEBUG,"added WHOWAS entry, purged an old record");
-00502                                         return;
-00503                                 }
-00504                         }
-00505                         // no space left and user doesnt exist. Don't leave ram in use!
-00506                         log(DEBUG,"Not able to update whowas (list at WHOWAS_MAX entries and trying to add new?), freeing excess ram");
-00507                         delete a;
-00508                 }
-00509                 else
-00510                 {
-00511                         log(DEBUG,"added fresh WHOWAS entry");
-00512                         whowas[a->nick] = a;
-00513                 }
-00514         }
-00515         else
-00516         {
-00517                 log(DEBUG,"updated WHOWAS entry");
-00518                 if (iter->second) delete iter->second;
-00519                 iter->second = a;
-00520         }
-00521 }
-00522 
-00523 /* add a client connection to the sockets list */
-00524 void AddClient(int socket, char* host, int port, bool iscached, char* ip)
-00525 {
-00526         string tempnick;
-00527         char tn2[MAXBUF];
-00528         user_hash::iterator iter;
-00529 
-00530         tempnick = ConvToStr(socket) + "-unknown";
-00531         sprintf(tn2,"%lu-unknown",(unsigned long)socket);
-00532 
-00533         iter = clientlist.find(tempnick);
-00534 
-00535         // fix by brain.
-00536         // as these nicknames are 'RFC impossible', we can be sure nobody is going to be
-00537         // using one as a registered connection. As theyre per fd, we can also safely assume
-00538         // that we wont have collisions. Therefore, if the nick exists in the list, its only
-00539         // used by a dead socket, erase the iterator so that the new client may reclaim it.
-00540         // this was probably the cause of 'server ignores me when i hammer it with reconnects'
-00541         // issue in earlier alphas/betas
-00542         if (iter != clientlist.end())
-00543         {
-00544                 userrec* goner = iter->second;
-00545                 delete goner;
-00546                 clientlist.erase(iter);
-00547         }
-00548 
-00549         /*
-00550          * It is OK to access the value here this way since we know
-00551          * it exists, we just created it above.
-00552          *
-00553          * At NO other time should you access a value in a map or a
-00554          * hash_map this way.
-00555          */
-00556         clientlist[tempnick] = new userrec();
-00557 
-00558         log(DEBUG,"AddClient: %lu %s %d %s",(unsigned long)socket,host,port,ip);
-00559 
-00560         clientlist[tempnick]->fd = socket;
-00561         strlcpy(clientlist[tempnick]->nick, tn2,NICKMAX);
-00562         strlcpy(clientlist[tempnick]->host, host,160);
-00563         strlcpy(clientlist[tempnick]->dhost, host,160);
-00564         clientlist[tempnick]->server = (char*)FindServerNamePtr(Config->ServerName);
-00565         strlcpy(clientlist[tempnick]->ident, "unknown",IDENTMAX);
-00566         clientlist[tempnick]->registered = 0;
-00567         clientlist[tempnick]->signon = TIME + Config->dns_timeout;
-00568         clientlist[tempnick]->lastping = 1;
-00569         clientlist[tempnick]->port = port;
-00570         strlcpy(clientlist[tempnick]->ip,ip,16);
-00571 
-00572         // set the registration timeout for this user
-00573         unsigned long class_regtimeout = 90;
-00574         int class_flood = 0;
-00575         long class_threshold = 5;
-00576         long class_sqmax = 262144;      // 256kb
-00577         long class_rqmax = 4096;        // 4k
-00578 
-00579         for (ClassVector::iterator i = Config->Classes.begin(); i != Config->Classes.end(); i++)
-00580         {
-00581                 if (match(clientlist[tempnick]->host,i->host) && (i->type == CC_ALLOW))
-00582                 {
-00583                         class_regtimeout = (unsigned long)i->registration_timeout;
-00584                         class_flood = i->flood;
-00585                         clientlist[tempnick]->pingmax = i->pingtime;
-00586                         class_threshold = i->threshold;
-00587                         class_sqmax = i->sendqmax;
-00588                         class_rqmax = i->recvqmax;
-00589                         break;
-00590                 }
-00591         }
-00592 
-00593         clientlist[tempnick]->nping = TIME+clientlist[tempnick]->pingmax + Config->dns_timeout;
-00594         clientlist[tempnick]->timeout = TIME+class_regtimeout;
-00595         clientlist[tempnick]->flood = class_flood;
-00596         clientlist[tempnick]->threshold = class_threshold;
-00597         clientlist[tempnick]->sendqmax = class_sqmax;
-00598         clientlist[tempnick]->recvqmax = class_rqmax;
-00599 
-00600         ucrec a;
-00601         a.channel = NULL;
-00602         a.uc_modes = 0;
-00603         for (int i = 0; i < MAXCHANS; i++)
-00604                 clientlist[tempnick]->chans.push_back(a);
-00605 
-00606         if (clientlist.size() > Config->SoftLimit)
-00607         {
-00608                 kill_link(clientlist[tempnick],"No more connections allowed");
-00609                 return;
-00610         }
-00611 
-00612         if (clientlist.size() >= MAXCLIENTS)
-00613         {
-00614                 kill_link(clientlist[tempnick],"No more connections allowed");
-00615                 return;
-00616         }
-00617 
-00618         // this is done as a safety check to keep the file descriptors within range of fd_ref_table.
-00619         // its a pretty big but for the moment valid assumption:
-00620         // file descriptors are handed out starting at 0, and are recycled as theyre freed.
-00621         // therefore if there is ever an fd over 65535, 65536 clients must be connected to the
-00622         // irc server at once (or the irc server otherwise initiating this many connections, files etc)
-00623         // which for the time being is a physical impossibility (even the largest networks dont have more
-00624         // than about 10,000 users on ONE server!)
-00625         if ((unsigned)socket > 65534)
-00626         {
-00627                 kill_link(clientlist[tempnick],"Server is full");
-00628                 return;
-00629         }
-00630         char* e = matches_exception(ip);
-00631         if (!e)
-00632         {
-00633                 char* r = matches_zline(ip);
-00634                 if (r)
-00635                 {
-00636                         char reason[MAXBUF];
-00637                         snprintf(reason,MAXBUF,"Z-Lined: %s",r);
-00638                         kill_link(clientlist[tempnick],reason);
-00639                         return;
-00640                 }
-00641         }
-00642         fd_ref_table[socket] = clientlist[tempnick];
-00643         local_users.push_back(clientlist[tempnick]);
-00644         ServerInstance->SE->AddFd(socket,true,X_ESTAB_CLIENT);
-00645 }
-00646 
-00647 void FullConnectUser(userrec* user)
-00648 {
-00649         ServerInstance->stats->statsConnects++;
-00650         user->idle_lastmsg = TIME;
-00651         log(DEBUG,"ConnectUser: %s",user->nick);
-00652 
-00653         if ((strcmp(Passwd(user),"")) && (!user->haspassed))
-00654         {
-00655                 kill_link(user,"Invalid password");
-00656                 return;
-00657         }
-00658         if (IsDenied(user))
-00659         {
-00660                 kill_link(user,"Unauthorised connection");
-00661                 return;
-00662         }
-00663 
-00664         char match_against[MAXBUF];
-00665         snprintf(match_against,MAXBUF,"%s@%s",user->ident,user->host);
-00666         char* e = matches_exception(match_against);
-00667         if (!e)
-00668         {
-00669                 char* r = matches_gline(match_against);
-00670                 if (r)
-00671                 {
-00672                         char reason[MAXBUF];
-00673                         snprintf(reason,MAXBUF,"G-Lined: %s",r);
-00674                         kill_link_silent(user,reason);
-00675                         return;
-00676                 }
-00677                 r = matches_kline(user->host);
-00678                 if (r)
-00679                 {
-00680                         char reason[MAXBUF];
-00681                         snprintf(reason,MAXBUF,"K-Lined: %s",r);
-00682                         kill_link_silent(user,reason);
-00683                         return;
-00684                 }
-00685         }
-00686 
-00687 
-00688         WriteServ(user->fd,"NOTICE Auth :Welcome to \002%s\002!",Config->Network);
-00689         WriteServ(user->fd,"001 %s :Welcome to the %s IRC Network %s!%s@%s",user->nick,Config->Network,user->nick,user->ident,user->host);
-00690         WriteServ(user->fd,"002 %s :Your host is %s, running version %s",user->nick,Config->ServerName,VERSION);
-00691         WriteServ(user->fd,"003 %s :This server was created %s %s",user->nick,__TIME__,__DATE__);
-00692         WriteServ(user->fd,"004 %s %s %s iowghraAsORVSxNCWqBzvdHtGI lvhopsmntikrRcaqOALQbSeKVfHGCuzN",user->nick,Config->ServerName,VERSION);
-00693         // the neatest way to construct the initial 005 numeric, considering the number of configure constants to go in it...
-00694         std::stringstream v;
-00695         v << "WALLCHOPS MODES=13 CHANTYPES=# PREFIX=(ohv)@%+ MAP SAFELIST MAXCHANNELS=" << MAXCHANS;
-00696         v << " MAXBANS=60 NICKLEN=" << NICKMAX;
-00697         v << " TOPICLEN=" << MAXTOPIC << " KICKLEN=" << MAXKICK << " MAXTARGETS=20 AWAYLEN=" << MAXAWAY << " CHANMODES=ohvb,k,l,psmnti NETWORK=";
-00698         v << Config->Network;
-00699         std::string data005 = v.str();
-00700         FOREACH_MOD On005Numeric(data005);
-00701         // anfl @ #ratbox, efnet reminded me that according to the RFC this cant contain more than 13 tokens per line...
-00702         // so i'd better split it :)
-00703         std::stringstream out(data005);
-00704         std::string token = "";
-00705         std::string line5 = "";
-00706         int token_counter = 0;
-00707         while (!out.eof())
-00708         {
-00709                 out >> token;
-00710                 line5 = line5 + token + " ";
-00711                 token_counter++;
-00712                 if ((token_counter >= 13) || (out.eof() == true))
-00713                 {
-00714                         WriteServ(user->fd,"005 %s %s:are supported by this server",user->nick,line5.c_str());
-00715                         line5 = "";
-00716                         token_counter = 0;
-00717                 }
-00718         }
-00719         ShowMOTD(user);
-00720 
-00721         // fix 3 by brain, move registered = 7 below these so that spurious modes and host changes dont go out
-00722         // onto the network and produce 'fake direction'
-00723         FOREACH_MOD OnUserConnect(user);
-00724         FOREACH_MOD OnGlobalConnect(user);
-00725         user->registered = 7;
-00726         WriteOpers("*** Client connecting on port %lu: %s!%s@%s [%s]",(unsigned long)user->port,user->nick,user->ident,user->host,user->ip);
-00727 }
-00728 
-00729 
-00730 /* shows the message of the day, and any other on-logon stuff */
-00731 void ConnectUser(userrec *user)
-00732 {
-00733         // dns is already done, things are fast. no need to wait for dns to complete just pass them straight on
-00734         if ((user->dns_done) && (user->registered >= 3) && (AllModulesReportReady(user)))
-00735         {
-00736                 FullConnectUser(user);
-00737         }
-00738 }
-00739 
-00740 /* re-allocates a nick in the user_hash after they change nicknames,
-00741  * returns a pointer to the new user as it may have moved */
-00742 
-00743 userrec* ReHashNick(char* Old, char* New)
-00744 {
-00745         //user_hash::iterator newnick;
-00746         user_hash::iterator oldnick = clientlist.find(Old);
-00747 
-00748         log(DEBUG,"ReHashNick: %s %s",Old,New);
-00749 
-00750         if (!strcasecmp(Old,New))
-00751         {
-00752                 log(DEBUG,"old nick is new nick, skipping");
-00753                 return oldnick->second;
-00754         }
-00755 
-00756         if (oldnick == clientlist.end()) return NULL; /* doesnt exist */
-00757 
-00758         log(DEBUG,"ReHashNick: Found hashed nick %s",Old);
-00759 
-00760         userrec* olduser = oldnick->second;
-00761         clientlist[New] = olduser;
-00762         clientlist.erase(oldnick);
-00763 
-00764         log(DEBUG,"ReHashNick: Nick rehashed as %s",New);
-00765 
-00766         return clientlist[New];
-00767 }
-00768 
-00769 void force_nickchange(userrec* user,const char* newnick)
-00770 {
-00771         char nick[MAXBUF];
-00772         int MOD_RESULT = 0;
-00773 
-00774         strcpy(nick,"");
-00775 
-00776         FOREACH_RESULT(OnUserPreNick(user,newnick));
-00777         if (MOD_RESULT) {
-00778                 ServerInstance->stats->statsCollisions++;
-00779                 kill_link(user,"Nickname collision");
-00780                 return;
-00781         }
-00782         if (matches_qline(newnick))
-00783         {
-00784                 ServerInstance->stats->statsCollisions++;
-00785                 kill_link(user,"Nickname collision");
-00786                 return;
-00787         }
-00788 
-00789         if (user)
-00790         {
-00791                 if (newnick)
-00792                 {
-00793                         strncpy(nick,newnick,MAXBUF);
-00794                 }
-00795                 if (user->registered == 7)
-00796                 {
-00797                         char* pars[1];
-00798                         pars[0] = nick;
-00799                         std::string cmd = "NICK";
-00800                         ServerInstance->Parser->CallHandler(cmd,pars,1,user);
-00801                 }
-00802         }
-00803 }
-00804 
-

Generated on Mon Dec 19 18:05:20 2005 for InspIRCd by  - -doxygen 1.4.4-20050815
- - -- cgit v1.2.3