00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
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
00173
00174
00175
00176
00177
00178 if (is_uline(this->server))
00179 return true;
00180
00181
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
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
00241
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
00282
00283
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
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
00308 tb += n_sent;
00309 this->sendq = tb;
00310
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
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
00386
00387 if (user->registered == 7) {
00388 purge_empty_chans(user);
00389
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
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
00484
00485
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
00495 if ((i->second->signon)<(TIME-(WHOWAS_STALE*3600)))
00496 {
00497
00498 if (i->second) delete i->second;
00499
00500 i->second = a;
00501 log(DEBUG,"added WHOWAS entry, purged an old record");
00502 return;
00503 }
00504 }
00505
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
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
00536
00537
00538
00539
00540
00541
00542 if (iter != clientlist.end())
00543 {
00544 userrec* goner = iter->second;
00545 delete goner;
00546 clientlist.erase(iter);
00547 }
00548
00549
00550
00551
00552
00553
00554
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
00573 unsigned long class_regtimeout = 90;
00574 int class_flood = 0;
00575 long class_threshold = 5;
00576 long class_sqmax = 262144;
00577 long class_rqmax = 4096;
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
00619
00620
00621
00622
00623
00624
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
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
00702
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
00722
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
00731 void ConnectUser(userrec *user)
00732 {
00733
00734 if ((user->dns_done) && (user->registered >= 3) && (AllModulesReportReady(user)))
00735 {
00736 FullConnectUser(user);
00737 }
00738 }
00739
00740
00741
00742
00743 userrec* ReHashNick(char* Old, char* New)
00744 {
00745
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;
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