53 |
|
static void ms_uid(struct Client *, struct Client *, int, char **); |
54 |
|
|
55 |
|
static void nick_from_server(struct Client *, struct Client *, int, char **, |
56 |
< |
time_t, char *, char *); |
56 |
> |
time_t, time_t, char *, char *); |
57 |
|
static void uid_from_server(struct Client *, struct Client *, int, char **, |
58 |
< |
time_t, char *, char *); |
58 |
> |
time_t, time_t, char *, char *); |
59 |
|
static int check_clean_nick(struct Client *client_p, struct Client *source_p, |
60 |
|
char *nick, struct Client *server_p); |
61 |
|
static int check_clean_user(struct Client *client_p, char *nick, char *user, |
66 |
|
static int clean_user_name(const char *); |
67 |
|
static int clean_host_name(const char *); |
68 |
|
static void perform_nick_collides(struct Client *, struct Client *, struct Client *, |
69 |
< |
int, char **, time_t, char *, char *, char *); |
69 |
> |
int, char **, time_t, time_t, char *, char *, char *); |
70 |
|
struct Message nick_msgtab = { |
71 |
|
"NICK", 0, 0, 0, MAXPARA, MFLG_SLOW, 0, |
72 |
|
{mr_nick, m_nick, ms_nick, m_ignore, m_nick, m_ignore} |
368 |
|
* - parv[1] = nickname |
369 |
|
* - parv[2] = TS when nick change |
370 |
|
* |
371 |
< |
* server introducing new nick |
371 |
> |
* server introducing new nick (without services support) |
372 |
|
* - parv[0] = sender prefix |
373 |
|
* - parv[1] = nickname |
374 |
|
* - parv[2] = hop count |
378 |
|
* - parv[6] = hostname |
379 |
|
* - parv[7] = server |
380 |
|
* - parv[8] = ircname |
381 |
+ |
* |
382 |
+ |
* server introducing new nick (with services support) |
383 |
+ |
* - parv[0] = sender prefix |
384 |
+ |
* - parv[1] = nickname |
385 |
+ |
* - parv[2] = hop count |
386 |
+ |
* - parv[3] = TS |
387 |
+ |
* - parv[4] = umode |
388 |
+ |
* - parv[5] = username |
389 |
+ |
* - parv[6] = hostname |
390 |
+ |
* - parv[7] = server |
391 |
+ |
* - parv[8] = services id (timestamp) |
392 |
+ |
* - parv[9] = ircname |
393 |
|
*/ |
394 |
|
static void |
395 |
|
ms_nick(struct Client *client_p, struct Client *source_p, |
397 |
|
{ |
398 |
|
struct Client *target_p = NULL; |
399 |
|
time_t newts = 0; |
400 |
+ |
time_t svsid = 0; |
401 |
|
|
402 |
|
if (parc < 2 || EmptyString(parv[1])) |
403 |
|
return; |
404 |
|
|
405 |
< |
if (parc == 9) |
405 |
> |
if (parc >= 9) |
406 |
|
{ |
407 |
|
struct Client *server_p = hash_find_server(parv[7]); |
408 |
|
|
423 |
|
|
424 |
|
if (IsServer(source_p)) |
425 |
|
newts = atol(parv[3]); |
426 |
+ |
if (IsServer(source_p) && parc == 10) |
427 |
+ |
svsid = atol(parv[8]); |
428 |
|
} |
429 |
|
else if (parc == 3) |
430 |
|
{ |
441 |
|
|
442 |
|
/* if the nick doesnt exist, allow it and process like normal */ |
443 |
|
if ((target_p = hash_find_client(parv[1])) == NULL) |
444 |
< |
nick_from_server(client_p, source_p, parc, parv, newts, parv[1], parv[8]); |
444 |
> |
nick_from_server(client_p, source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]); |
445 |
|
else if (IsUnknown(target_p)) |
446 |
|
{ |
447 |
|
/* we're not living in the past anymore, an unknown client is local only. */ |
448 |
|
exit_client(target_p, &me, "Overridden"); |
449 |
< |
nick_from_server(client_p, source_p, parc, parv, newts, parv[1], parv[8]); |
449 |
> |
nick_from_server(client_p, source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]); |
450 |
|
} |
451 |
|
else if (target_p == source_p) |
452 |
|
{ |
453 |
|
if (strcmp(target_p->name, parv[1])) |
454 |
< |
nick_from_server(client_p, source_p, parc, parv, newts, parv[1], parv[8]); |
454 |
> |
nick_from_server(client_p, source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]); |
455 |
|
} |
456 |
|
else |
457 |
|
perform_nick_collides(source_p, client_p, target_p, parc, parv, |
458 |
< |
newts, parv[1], parv[8], NULL); |
458 |
> |
newts, svsid, parv[1], parv[parc-1], NULL); |
459 |
|
} |
460 |
|
|
461 |
|
|
470 |
|
* pointers. |
471 |
|
* \note Valid arguments for this command are: |
472 |
|
* |
473 |
+ |
* server introducing new nick (without services support) |
474 |
|
* - parv[0] = sender prefix |
475 |
|
* - parv[1] = nickname |
476 |
|
* - parv[2] = hop count |
481 |
|
* - parv[7] = ip |
482 |
|
* - parv[8] = uid |
483 |
|
* - parv[9] = ircname (gecos) |
484 |
+ |
* |
485 |
+ |
* server introducing new nick (with services support) |
486 |
+ |
* - parv[ 0] = sender prefix |
487 |
+ |
* - parv[ 1] = nickname |
488 |
+ |
* - parv[ 2] = hop count |
489 |
+ |
* - parv[ 3] = TS |
490 |
+ |
* - parv[ 4] = umode |
491 |
+ |
* - parv[ 5] = username |
492 |
+ |
* - parv[ 6] = hostname |
493 |
+ |
* - parv[ 7] = ip |
494 |
+ |
* - parv[ 8] = uid |
495 |
+ |
* - parv[ 9] = services id (timestamp) |
496 |
+ |
* - parv[10] = ircname (gecos) |
497 |
|
*/ |
498 |
|
static void |
499 |
|
ms_uid(struct Client *client_p, struct Client *source_p, |
501 |
|
{ |
502 |
|
struct Client *target_p = NULL; |
503 |
|
time_t newts = 0; |
504 |
+ |
time_t svsid = 0; |
505 |
|
|
506 |
< |
if (parc != 10 || EmptyString(parv[9])) |
506 |
> |
if (parc < 10 || EmptyString(parv[parc-1])) |
507 |
|
return; |
508 |
|
|
509 |
|
if (check_clean_nick(client_p, source_p, parv[1], source_p) || |
512 |
|
return; |
513 |
|
|
514 |
|
newts = atol(parv[3]); |
515 |
+ |
svsid = parc == 11 ? atol(parv[9]) : 0; |
516 |
|
|
517 |
|
/* |
518 |
|
* if there is an ID collision, kill our client, and kill theirs. |
535 |
|
} |
536 |
|
|
537 |
|
if ((target_p = hash_find_client(parv[1])) == NULL) |
538 |
< |
uid_from_server(client_p, source_p, parc, parv, newts, parv[1], parv[9]); |
538 |
> |
uid_from_server(client_p, source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]); |
539 |
|
else if (IsUnknown(target_p)) |
540 |
|
{ |
541 |
|
exit_client(target_p, &me, "Overridden"); |
542 |
< |
uid_from_server(client_p, source_p, parc, parv, newts, parv[1], parv[9]); |
542 |
> |
uid_from_server(client_p, source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]); |
543 |
|
} |
544 |
|
else |
545 |
< |
perform_nick_collides(source_p, client_p, target_p, |
546 |
< |
parc, parv, newts, parv[1], parv[9], parv[8]); |
545 |
> |
perform_nick_collides(source_p, client_p, target_p, parc, parv, newts, svsid, parv[1], |
546 |
> |
parv[parc-1], parv[8]); |
547 |
|
} |
548 |
|
|
549 |
|
/* check_clean_nick() |
689 |
|
*/ |
690 |
|
static void |
691 |
|
nick_from_server(struct Client *client_p, struct Client *source_p, int parc, |
692 |
< |
char *parv[], time_t newts, char *nick, char *ngecos) |
692 |
> |
char *parv[], time_t newts, time_t svsid, char *nick, char *ngecos) |
693 |
|
{ |
694 |
|
int samenick = 0; |
695 |
|
|
709 |
|
ts_warn("Remote nick %s (%s) introduced without a TS", nick, parv[0]); |
710 |
|
} |
711 |
|
|
712 |
< |
strlcpy(source_p->info, parv[8], sizeof(source_p->info)); |
712 |
> |
source_p->servicestamp = svsid; |
713 |
> |
strlcpy(source_p->info, ngecos, sizeof(source_p->info)); |
714 |
|
/* copy the nick in place */ |
715 |
|
strlcpy(source_p->name, nick, sizeof(source_p->name)); |
716 |
|
hash_add_client(source_p); |
778 |
|
*/ |
779 |
|
static void |
780 |
|
uid_from_server(struct Client *client_p, struct Client *source_p, int parc, |
781 |
< |
char *parv[], time_t newts, char *nick, char *ugecos) |
781 |
> |
char *parv[], time_t newts, time_t svsid, char *nick, char *ugecos) |
782 |
|
{ |
783 |
|
const char *m = NULL; |
784 |
|
const char *servername = source_p->name; |
788 |
|
|
789 |
|
source_p->hopcount = atoi(parv[2]); |
790 |
|
source_p->tsinfo = newts; |
791 |
+ |
source_p->servicestamp = svsid; |
792 |
|
|
793 |
|
/* copy the nick in place */ |
794 |
|
strcpy(source_p->name, nick); |
795 |
|
strlcpy(source_p->id, parv[8], sizeof(source_p->id)); |
796 |
|
strlcpy(source_p->sockhost, parv[7], sizeof(source_p->sockhost)); |
797 |
< |
strlcpy(source_p->info, parv[9], sizeof(source_p->info)); |
797 |
> |
strlcpy(source_p->info, ugecos, sizeof(source_p->info)); |
798 |
|
|
799 |
|
hash_add_client(source_p); |
800 |
|
hash_add_id(source_p); |
813 |
|
} |
814 |
|
|
815 |
|
register_remote_user(source_p, parv[5], parv[6], |
816 |
< |
servername, parv[9]); |
816 |
> |
servername, ugecos); |
817 |
|
} |
818 |
|
|
819 |
|
static void |
820 |
|
perform_nick_collides(struct Client *source_p, struct Client *client_p, |
821 |
|
struct Client *target_p, int parc, char *parv[], |
822 |
< |
time_t newts, char *nick, char *gecos, char *uid) |
822 |
> |
time_t newts, time_t svsid, char *nick, char *gecos, char *uid) |
823 |
|
{ |
824 |
|
int sameuser; |
825 |
|
|
895 |
|
SetKilled(target_p); |
896 |
|
exit_client(target_p, &me, "Nick collision"); |
897 |
|
|
898 |
< |
if (parc == 9) |
899 |
< |
nick_from_server(client_p, source_p, parc, parv, newts, nick, gecos); |
900 |
< |
else if (parc == 10) |
901 |
< |
uid_from_server(client_p, source_p, parc, parv, newts, nick, gecos); |
898 |
> |
if (!uid && (parc == 9 || parc == 10)) |
899 |
> |
nick_from_server(client_p, source_p, parc, parv, newts, svsid, nick, gecos); |
900 |
> |
else if (uid && (parc == 10 || parc == 11)) |
901 |
> |
uid_from_server(client_p, source_p, parc, parv, newts, svsid, nick, gecos); |
902 |
|
|
903 |
|
return; |
904 |
|
} |
992 |
|
/* we should only ever call nick_from_server() here, as |
993 |
|
* this is a client changing nick, not a new client |
994 |
|
*/ |
995 |
< |
nick_from_server(client_p, source_p, parc, parv, newts, nick, gecos); |
995 |
> |
nick_from_server(client_p, source_p, parc, parv, newts, svsid, nick, gecos); |
996 |
|
} |