2 * IRC - Internet Relay Chat, ircd/m_nick.c
3 * Copyright (C) 1990 Jarkko Oikarinen and
4 * University of Oulu, Computing Center
6 * See file AUTHORS in IRC package for additional names of
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 1, or (at your option)
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 * m_functions execute protocol messages on this server:
29 * cptr is always NON-NULL, pointing to a *LOCAL* client
30 * structure (with an open socket connected!). This
31 * identifies the physical socket where the message
32 * originated (or which caused the m_function to be
33 * executed--some m_functions may call others...).
35 * sptr is the source of the message, defined by the
36 * prefix part of the message if present. If not
37 * or prefix not found, then sptr==cptr.
39 * (!IsServer(cptr)) => (cptr == sptr), because
40 * prefixes are taken *only* from servers...
43 * (sptr == cptr) => the message didn't
46 * (sptr != cptr && IsServer(sptr) means
47 * the prefix specified servername. (?)
49 * (sptr != cptr && !IsServer(sptr) means
50 * that message originated from a remote
55 * (!IsServer(sptr)) means that, sptr can safely
56 * taken as defining the target structure of the
57 * message in this server.
59 * *Always* true (if 'parse' and others are working correct):
61 * 1) sptr->from == cptr (note: cptr->from == cptr)
63 * 2) MyConnect(sptr) <=> sptr == cptr (e.g. sptr
64 * *cannot* be a local connection, unless it's
65 * actually cptr!). [MyConnect(x) should probably
66 * be defined as (x == x->from) --msa ]
68 * parc number of variable parameter strings (if zero,
69 * parv is allowed to be NULL)
71 * parv a NULL terminated list of parameter pointers,
73 * parv[0], sender (prefix string), if not present
74 * this points to an empty string.
75 * parv[1]...parv[parc-1]
76 * pointers to additional parameters
77 * parv[parc] == NULL, *always*
79 * note: it is guaranteed that parv[0]..parv[parc-1] are all
84 * No need to include handlers.h here the signatures must match
85 * and we don't need to force a rebuild of all the handlers everytime
86 * we add a new one to the list. --Bleep
94 #include "ircd_chattr.h"
95 #include "ircd_reply.h"
96 #include "ircd_string.h"
110 * m_nick - message handler for local clients
111 * parv[0] = sender prefix
114 int m_nick(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
116 struct Client* acptr;
117 char nick[NICKLEN + 2];
120 const char* client_name;
123 assert(cptr == sptr);
126 * parv[0] will be empty for clients connecting for the first time
128 client_name = (*sptr->name) ? sptr->name : "*";
131 sendto_one(sptr, err_str(ERR_NONICKNAMEGIVEN), me.name, client_name);
135 * Don't let them send make us send back a really long string of
139 if (strlen(arg) > NICKLEN)
142 if ((s = strchr(arg, '~')))
148 * If do_nick_name() returns a null name OR if the server sent a nick
149 * name and do_nick_name() changed it in some way (due to rules of nick
150 * creation) then reject it. If from a server and we reject it,
151 * and KILL it. -avalon 4/4/92
153 if (0 == do_nick_name(nick)) {
154 sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name, client_name, arg);
159 * Check if this is a LOCAL user trying to use a reserved (Juped)
160 * nick, if so tell him that it's a nick in use...
162 if (isNickJuped(nick)) {
163 sendto_one(sptr, err_str(ERR_NICKNAMEINUSE), me.name, client_name, nick);
164 return 0; /* NICK message ignored */
167 if (!(acptr = FindClient(nick))) {
169 * No collisions, all clear...
171 return set_nick_name(cptr, sptr, nick, parc, parv);
173 if (IsServer(acptr)) {
174 sendto_one(sptr, err_str(ERR_NICKNAMEINUSE), me.name, client_name, nick);
175 return 0; /* NICK message ignored */
178 * If acptr == sptr, then we have a client doing a nick
179 * change between *equivalent* nicknames as far as server
180 * is concerned (user is changing the case of his/her
181 * nickname or somesuch)
185 * If acptr == sptr, then we have a client doing a nick
186 * change between *equivalent* nicknames as far as server
187 * is concerned (user is changing the case of his/her
188 * nickname or somesuch)
190 if (0 != strcmp(acptr->name, nick)) {
192 * Allows change of case in his/her nick
194 return set_nick_name(cptr, sptr, nick, parc, parv);
197 * This is just ':old NICK old' type thing.
198 * Just forget the whole thing here. There is
199 * no point forwarding it to anywhere,
200 * especially since servers prior to this
201 * version would treat it as nick collision.
206 * Note: From this point forward it can be assumed that
207 * acptr != sptr (point to different client structures).
209 assert(acptr != sptr);
211 * If the older one is "non-person", the new entry is just
212 * allowed to overwrite it. Just silently drop non-person,
213 * and proceed with the nick. This should take care of the
214 * "dormant nick" way of generating collisions...
216 * XXX - hmmm can this happen after one is registered?
218 if (IsUnknown(acptr) && MyConnect(acptr)) {
219 ++ServerStats->is_ref;
220 IPcheck_connect_fail(acptr->ip);
221 exit_client(cptr, acptr, &me, "Overridden by other sign on");
222 return set_nick_name(cptr, sptr, nick, parc, parv);
225 * NICK is coming from local client connection. Just
226 * send error reply and ignore the command.
228 sendto_one(sptr, err_str(ERR_NICKNAMEINUSE), me.name, client_name, nick);
229 return 0; /* NICK message ignored */
234 * ms_nick - server message handler for nicks
235 * parv[0] = sender prefix
238 * If from server, source is client:
239 * parv[2] = timestamp
243 * parv[3] = timestamp
246 * parv[6] = umode (optional)
247 * parv[parc-3] = IP# <- Only Protocol >= 10
248 * parv[parc-2] = YXX, numeric nick <- Only Protocol >= 10
249 * parv[parc-1] = info
252 int ms_nick(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
254 struct Client* acptr;
255 char nick[NICKLEN + 2];
261 assert(IsServer(cptr));
263 if ((IsServer(sptr) && parc < 8) || parc < 3) {
264 sendto_ops("bad NICK param count for %s from %s", parv[1], cptr->name);
265 return need_more_params(sptr, "NICK");
268 ircd_strncpy(nick, parv[1], NICKLEN);
269 nick[NICKLEN] = '\0';
271 if (!IsBurstOrBurstAck(sptr)) {
272 if (IsServer(sptr)) {
273 lastnick = atoi(parv[3]);
274 if (lastnick > OLDEST_TS)
275 sptr->serv->lag = TStime() - lastnick;
278 lastnick = atoi(parv[2]);
279 if (lastnick > OLDEST_TS)
280 sptr->user->server->serv->lag = TStime() - lastnick;
284 * If do_nick_name() returns a null name OR if the server sent a nick
285 * name and do_nick_name() changed it in some way (due to rules of nick
286 * creation) then reject it. If from a server and we reject it,
287 * and KILL it. -avalon 4/4/92
289 if (0 == do_nick_name(nick) || 0 != strcmp(nick, parv[1])) {
290 sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name, parv[0], parv[1]);
292 ++ServerStats->is_kill;
293 sendto_ops("Bad Nick: %s From: %s %s", parv[1], parv[0], cptr->name);
294 sendto_one(cptr, "%s " TOK_KILL " %s :%s (%s <- %s[%s])",
295 NumServ(&me), IsServer(sptr) ? parv[parc - 2] : parv[0], me.name,
296 parv[1], nick, cptr->name);
297 if (!IsServer(sptr)) {
301 sendto_highprot_butone(&me, 10, "%s " TOK_KILL " %s :%s (%s <- %s!%s@%s)",
302 NumServ(&me), parv[0], me.name, cptr->name,
303 parv[0], sptr->user ? sptr->username : "",
304 sptr->user ? sptr->user->server->name : cptr->name);
309 * Check against nick name collisions.
311 * Put this 'if' here so that the nesting goes nicely on the screen :)
312 * We check against server name list before determining if the nickname
313 * is present in the nicklist (due to the way the below for loop is
314 * constructed). -avalon
316 if (!(acptr = FindClient(nick))) {
318 * No collisions, all clear...
320 return set_nick_name(cptr, sptr, nick, parc, parv);
324 if (IsServer(acptr)) {
326 * We have a nickname trying to use the same name as
327 * a server. Send out a nick collision KILL to remove
328 * the nickname. As long as only a KILL is sent out,
329 * there is no danger of the server being disconnected.
330 * Ultimate way to jupiter a nick ? >;-). -avalon
332 sendto_ops("Nick collision on %s(%s <- %s)", sptr->name, acptr->from->name, cptr->name);
333 ++ServerStats->is_kill;
335 sendto_one(cptr, "%s " TOK_KILL " %s%s :%s (%s <- %s)",
336 NumServ(&me), NumNick(sptr), me.name, acptr->from->name,
339 sptr->flags |= FLAGS_KILLED;
341 * if sptr is a server it is exited here, nothing else to do
343 return exit_client(cptr, sptr, &me, "Nick/Server collision");
347 * If acptr == sptr, then we have a client doing a nick
348 * change between *equivalent* nicknames as far as server
349 * is concerned (user is changing the case of his/her
350 * nickname or somesuch)
353 if (strcmp(acptr->name, nick) != 0)
355 * Allows change of case in his/her nick
357 return set_nick_name(cptr, sptr, nick, parc, parv);
360 * This is just ':old NICK old' type thing.
361 * Just forget the whole thing here. There is
362 * no point forwarding it to anywhere,
363 * especially since servers prior to this
364 * version would treat it as nick collision.
366 return 0; /* NICK Message ignored */
370 * Note: From this point forward it can be assumed that
371 * acptr != sptr (point to different client structures).
373 assert(acptr != sptr);
375 * If the older one is "non-person", the new entry is just
376 * allowed to overwrite it. Just silently drop non-person,
377 * and proceed with the nick. This should take care of the
378 * "dormant nick" way of generating collisions...
380 if (IsUnknown(acptr) && MyConnect(acptr)) {
381 ++ServerStats->is_ref;
382 IPcheck_connect_fail(acptr->ip);
383 exit_client(cptr, acptr, &me, "Overridden by other sign on");
384 return set_nick_name(cptr, sptr, nick, parc, parv);
387 * Decide, we really have a nick collision and deal with it
390 * NICK was coming from a server connection.
391 * This means we have a race condition (two users signing on
392 * at the same time), or two net fragments reconnecting with the same nick.
393 * The latter can happen because two different users connected
394 * or because one and the same user switched server during a net break.
395 * If the TimeStamps are equal, we kill both (or only 'new'
396 * if it was a ":server NICK new ...").
397 * Otherwise we kill the youngest when user@host differ,
398 * or the oldest when they are the same.
399 * We treat user and ~user as different, because if it wasn't
400 * a faked ~user the AUTH wouldn't have added the '~'.
404 if (IsServer(sptr)) {
406 * A new NICK being introduced by a neighbouring
407 * server (e.g. message type ":server NICK new ..." received)
409 * compare IP address and username
411 differ = (acptr->ip.s_addr != htonl(base64toint(parv[parc - 3]))) ||
412 (0 != ircd_strcmp(acptr->user->username, parv[4]));
413 sendto_ops("Nick collision on %s (%s " TIME_T_FMT " <- %s " TIME_T_FMT
414 " (%s user@host))", acptr->name, acptr->from->name, acptr->lastnick,
415 cptr->name, lastnick, differ ? "Different" : "Same");
419 * A NICK change has collided (e.g. message type ":old NICK new").
421 * compare IP address and username
423 differ = (acptr->ip.s_addr != sptr->ip.s_addr) ||
424 (0 != ircd_strcmp(acptr->user->username, sptr->user->username));
425 sendto_ops("Nick change collision from %s to %s (%s " TIME_T_FMT " <- %s "
426 TIME_T_FMT ")", sptr->name, acptr->name, acptr->from->name,
427 acptr->lastnick, cptr->name, lastnick);
430 * Now remove (kill) the nick on our side if it is the youngest.
431 * If no timestamp was received, we ignore the incoming nick
432 * (and expect a KILL for our legit nick soon ):
433 * When the timestamps are equal we kill both nicks. --Run
434 * acptr->from != cptr should *always* be true (?).
436 * This exits the client sending the NICK message
438 if (acptr->from != cptr) {
439 if ((differ && lastnick >= acptr->lastnick) || (!differ && lastnick <= acptr->lastnick)) {
440 if (!IsServer(sptr)) {
441 ++ServerStats->is_kill;
442 sendto_highprot_butone(&me, 10, /* Kill old from outgoing servers */
443 "%s " TOK_KILL " %s%s :%s (%s <- %s (Nick collision))",
444 NumServ(&me), NumNick(sptr), me.name, acptr->from->name,
446 assert(!MyConnect(sptr));
452 sendto_one(cptr, "%s " TOK_KILL " %s%s :%s (Ghost 2)",
453 NumServ(&me), NumNick(sptr), me.name);
455 sptr->flags |= FLAGS_KILLED;
456 exit_client(cptr, sptr, &me, "Nick collision (you're a ghost)");
458 * we have killed sptr off, zero out it's pointer so if it's used
459 * again we'll know about it --Bleep
463 if (lastnick != acptr->lastnick)
464 return 0; /* Ignore the NICK */
466 sendto_one(acptr, err_str(ERR_NICKCOLLISION), me.name, acptr->name, nick);
469 ++ServerStats->is_kill;
470 acptr->flags |= FLAGS_KILLED;
472 * This exits the client we had before getting the NICK message
475 sendto_highprot_butone(&me, 10, /* Kill our old from outgoing servers */
476 "%s " TOK_KILL " %s%s :%s (%s <- %s (older nick overruled))",
477 NumServ(&me), NumNick(acptr), me.name, acptr->from->name,
479 if (MyConnect(acptr))
480 sendto_one(cptr, "%s%s " TOK_QUIT " :Local kill by %s (Ghost)",
481 NumNick(acptr), me.name);
482 exit_client(cptr, acptr, &me, "Nick collision (older nick overruled)");
485 sendto_highprot_butone(&me, 10, /* Kill our old from outgoing servers */
486 "%s " TOK_KILL " %s%s :%s (%s <- %s (nick collision from same user@host))",
487 NumServ(&me), NumNick(acptr), me.name, acptr->from->name,
489 if (MyConnect(acptr))
491 "%s%s " TOK_QUIT " :Local kill by %s (Ghost: switched servers too fast)",
492 NumNick(acptr), me.name);
493 exit_client(cptr, acptr, &me, "Nick collision (You collided yourself)");
495 if (lastnick == acptr->lastnick)
499 return set_nick_name(cptr, sptr, nick, parc, parv);
506 * parv[0] = sender prefix
509 * If from server, source is client:
510 * parv[2] = timestamp
514 * parv[3] = timestamp
517 * parv[6] = umode (optional)
518 * parv[parc-3] = IP# <- Only Protocol >= 10
519 * parv[parc-2] = YXX, numeric nick <- Only Protocol >= 10
520 * parv[parc-1] = info
523 int m_nick(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
525 struct Client* acptr;
526 char nick[NICKLEN + 2];
532 sendto_one(sptr, err_str(ERR_NONICKNAMEGIVEN), me.name, parv[0]);
535 else if ((IsServer(sptr) && parc < 8) || (IsServer(cptr) && parc < 3))
537 need_more_params(sptr, "NICK");
538 sendto_ops("bad NICK param count for %s from %s", parv[1], cptr->name);
541 if (MyConnect(sptr) && (s = strchr(parv[1], '~')))
543 ircd_strncpy(nick, parv[1], NICKLEN);
544 nick[NICKLEN] = '\0';
545 if (IsServer(cptr)) {
546 if (IsServer(sptr)) {
547 lastnick = atoi(parv[3]);
548 if (lastnick > OLDEST_TS)
549 sptr->serv->lag = TStime() - lastnick;
551 lastnick = atoi(parv[2]);
552 if (lastnick > OLDEST_TS)
553 sptr->user->server->serv->lag = TStime() - lastnick;
557 * If do_nick_name() returns a null name OR if the server sent a nick
558 * name and do_nick_name() changed it in some way (due to rules of nick
559 * creation) then reject it. If from a server and we reject it,
560 * and KILL it. -avalon 4/4/92
562 if (do_nick_name(nick) == 0 || (IsServer(cptr) && strcmp(nick, parv[1])))
564 sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name, parv[0], parv[1]);
568 ServerStats->is_kill++;
569 sendto_ops("Bad Nick: %s From: %s %s",
570 parv[1], parv[0], cptr->name);
571 sendto_one(cptr, "%s " TOK_KILL " %s :%s (%s <- %s[%s])",
572 NumServ(&me), IsServer(sptr) ? parv[parc - 2] : parv[0], me.name,
573 parv[1], nick, cptr->name);
574 if (!IsServer(sptr)) /* bad nick _change_ */
576 sendto_highprot_butone(&me, 10, "%s " TOK_KILL " %s :%s (%s <- %s!%s@%s)",
577 NumServ(&me), parv[0], me.name, cptr->name,
578 parv[0], sptr->user ? sptr->username : "",
579 sptr->user ? sptr->user->server->name : cptr->name);
586 * Check if this is a LOCAL user trying to use a reserved (Juped)
587 * nick, if so tell him that it's a nick in use...
589 if ((!IsServer(cptr)) && isNickJuped(nick))
591 sendto_one(sptr, err_str(ERR_NICKNAMEINUSE), me.name,
592 /* parv[0] is empty when connecting */
593 EmptyString(parv[0]) ? "*" : parv[0], nick);
594 return 0; /* NICK message ignored */
598 * Check against nick name collisions.
600 * Put this 'if' here so that the nesting goes nicely on the screen :)
601 * We check against server name list before determining if the nickname
602 * is present in the nicklist (due to the way the below for loop is
603 * constructed). -avalon
605 if ((acptr = FindServer(nick))) {
608 sendto_one(sptr, err_str(ERR_NICKNAMEINUSE), me.name,
609 EmptyString(parv[0]) ? "*" : parv[0], nick);
610 return 0; /* NICK message ignored */
613 * We have a nickname trying to use the same name as
614 * a server. Send out a nick collision KILL to remove
615 * the nickname. As long as only a KILL is sent out,
616 * there is no danger of the server being disconnected.
617 * Ultimate way to jupiter a nick ? >;-). -avalon
619 sendto_ops("Nick collision on %s(%s <- %s)",
620 sptr->name, acptr->from->name, cptr->name);
621 ServerStats->is_kill++;
622 sendto_one(cptr, "%s " TOK_KILL " %s%s :%s (%s <- %s)",
623 NumServ(&me), NumNick(sptr), me.name, acptr->from->name,
625 sptr->flags |= FLAGS_KILLED;
626 return exit_client(cptr, sptr, &me, "Nick/Server collision");
629 if (!(acptr = FindClient(nick)))
630 return set_nick_name(cptr, sptr, nick, parc, parv); /* No collisions, all clear... */
632 * If acptr == sptr, then we have a client doing a nick
633 * change between *equivalent* nicknames as far as server
634 * is concerned (user is changing the case of his/her
635 * nickname or somesuch)
639 if (strcmp(acptr->name, nick) != 0)
641 * Allows change of case in his/her nick
643 return set_nick_name(cptr, sptr, nick, parc, parv);
646 * This is just ':old NICK old' type thing.
647 * Just forget the whole thing here. There is
648 * no point forwarding it to anywhere,
649 * especially since servers prior to this
650 * version would treat it as nick collision.
652 return 0; /* NICK Message ignored */
656 * Note: From this point forward it can be assumed that
657 * acptr != sptr (point to different client structures).
660 * If the older one is "non-person", the new entry is just
661 * allowed to overwrite it. Just silently drop non-person,
662 * and proceed with the nick. This should take care of the
663 * "dormant nick" way of generating collisions...
665 if (IsUnknown(acptr) && MyConnect(acptr))
667 ++ServerStats->is_ref;
668 IPcheck_connect_fail(acptr->ip);
669 exit_client(cptr, acptr, &me, "Overridden by other sign on");
670 return set_nick_name(cptr, sptr, nick, parc, parv);
673 * Decide, we really have a nick collision and deal with it
678 * NICK is coming from local client connection. Just
679 * send error reply and ignore the command.
681 sendto_one(sptr, err_str(ERR_NICKNAMEINUSE), me.name,
682 /* parv[0] is empty when connecting */
683 EmptyString(parv[0]) ? "*" : parv[0], nick);
684 return 0; /* NICK message ignored */
687 * NICK was coming from a server connection.
688 * This means we have a race condition (two users signing on
689 * at the same time), or two net fragments reconnecting with the same nick.
690 * The latter can happen because two different users connected
691 * or because one and the same user switched server during a net break.
692 * If the TimeStamps are equal, we kill both (or only 'new'
693 * if it was a ":server NICK new ...").
694 * Otherwise we kill the youngest when user@host differ,
695 * or the oldest when they are the same.
696 * We treat user and ~user as different, because if it wasn't
697 * a faked ~user the AUTH wouldn't have added the '~'.
704 * A new NICK being introduced by a neighbouring
705 * server (e.g. message type ":server NICK new ..." received)
707 differ = (acptr->ip.s_addr != htonl(base64toint(parv[parc - 3]))) ||
708 (0 != ircd_strcmp(acptr->user->username, parv[4]));
709 sendto_ops("Nick collision on %s (%s " TIME_T_FMT " <- %s " TIME_T_FMT
710 " (%s user@host))", acptr->name, acptr->from->name, acptr->lastnick,
711 cptr->name, lastnick, differ ? "Different" : "Same");
716 * A NICK change has collided (e.g. message type ":old NICK new").
718 lastnick = atoi(parv[2]);
719 differ = (acptr->ip.s_addr != sptr->ip.s_addr) ||
720 (0 != ircd_strcmp(acptr->user->username, sptr->user->username));
721 sendto_ops("Nick change collision from %s to %s (%s " TIME_T_FMT " <- %s "
722 TIME_T_FMT ")", sptr->name, acptr->name, acptr->from->name,
723 acptr->lastnick, cptr->name, lastnick);
726 * Now remove (kill) the nick on our side if it is the youngest.
727 * If no timestamp was received, we ignore the incoming nick
728 * (and expect a KILL for our legit nick soon ):
729 * When the timestamps are equal we kill both nicks. --Run
730 * acptr->from != cptr should *always* be true (?).
732 if (acptr->from != cptr)
734 if ((differ && lastnick >= acptr->lastnick) ||
735 (!differ && lastnick <= acptr->lastnick))
739 ServerStats->is_kill++;
740 sendto_highprot_butone(cptr, 10, /* Kill old from outgoing servers */
741 "%s " TOK_KILL " %s%s :%s (%s <- %s (Nick collision))",
742 NumServ(&me), NumNick(sptr), me.name, acptr->from->name,
744 if (MyConnect(sptr) && IsServer(cptr) && Protocol(cptr) > 9)
745 sendto_one(cptr, "%s " TOK_KILL " %s%s :%s (Ghost2)",
746 NumServ(&me), NumNick(sptr), me.name);
747 sptr->flags |= FLAGS_KILLED;
748 exit_client(cptr, sptr, &me, "Nick collision (you're a ghost)");
750 if (lastnick != acptr->lastnick)
751 return 0; /* Ignore the NICK */
753 sendto_one(acptr, err_str(ERR_NICKCOLLISION), me.name, acptr->name, nick);
755 ServerStats->is_kill++;
756 acptr->flags |= FLAGS_KILLED;
759 sendto_highprot_butone(cptr, 10, /* Kill our old from outgoing servers */
760 "%s " TOK_KILL " %s%s :%s (%s <- %s (older nick overruled))",
761 NumServ(&me), NumNick(acptr), me.name, acptr->from->name,
763 if (MyConnect(acptr) && IsServer(cptr) && Protocol(cptr) > 9)
764 sendto_one(cptr, "%s%s " TOK_QUIT " :Local kill by %s (Ghost)",
765 NumNick(acptr), me.name);
766 exit_client(cptr, acptr, &me, "Nick collision (older nick overruled)");
770 sendto_highprot_butone(cptr, 10, /* Kill our old from outgoing servers */
771 "%s " TOK_KILL " %s%s :%s (%s <- %s (nick collision from same user@host))",
772 NumServ(&me), NumNick(acptr), me.name, acptr->from->name,
774 if (MyConnect(acptr) && IsServer(cptr) && Protocol(cptr) > 9)
776 "%s%s " TOK_QUIT " :Local kill by %s (Ghost: switched servers too fast)",
777 NumNick(acptr), me.name);
778 exit_client(cptr, acptr, &me, "Nick collision (You collided yourself)");
780 if (lastnick == acptr->lastnick)
783 return set_nick_name(cptr, sptr, nick, parc, parv);