diff --git a/include/h.h b/include/h.h index d1f87e29b..b319086f4 100644 --- a/include/h.h +++ b/include/h.h @@ -365,6 +365,8 @@ extern void clear_client_hash_table(); extern void clear_watch_hash_table(); extern int add_to_client_hash_table(char *, aClient *); extern int del_from_client_hash_table(char *, aClient *); +extern int add_to_id_hash_table(char *, aClient *); +extern int del_from_id_hash_table(char *, aClient *); extern int add_to_channel_hash_table(char *, aChannel *); extern int del_from_channel_hash_table(char *, aChannel *); extern int add_to_watch_hash_table(char *, aClient *, int); @@ -375,6 +377,7 @@ extern void count_watch_memory(int *, u_long *); extern aWatch *hash_get_watch(char *); extern aChannel *hash_get_chan_bucket(unsigned int); extern aClient *hash_find_client(char *, aClient *); +extern aClient *hash_find_id(char *, aClient *); extern aClient *hash_find_nickserver(char *, aClient *); extern aClient *hash_find_server(char *, aClient *); extern char *find_by_aln(char *); diff --git a/include/numeric.h b/include/numeric.h index 5477f3ff7..a52b422c4 100644 --- a/include/numeric.h +++ b/include/numeric.h @@ -36,6 +36,7 @@ #define RPL_ISUPPORT 005 #define RPL_REDIR 10 +#define RPL_YOURID 42 #define RPL_REMOTEISUPPORT 105 diff --git a/include/struct.h b/include/struct.h index e2f28ef09..3354f6eaa 100644 --- a/include/struct.h +++ b/include/struct.h @@ -940,6 +940,7 @@ typedef struct { struct Client { struct list_head client_node; /* for global client list (client_list) */ struct list_head client_hash; /* for clientTable */ + struct list_head id_hash; /* for idTable */ anUser *user; /* ...defined, if this is a User */ aServer *serv; /* ...defined, if this is a server */ diff --git a/src/hash.c b/src/hash.c index c881c7821..6b73e8034 100644 --- a/src/hash.c +++ b/src/hash.c @@ -31,6 +31,7 @@ ID_Copyright("(C) 1991 Darren Reed"); ID_Notes("2.10 7/3/93"); static struct list_head clientTable[U_MAX]; +static struct list_head idTable[U_MAX]; static aHashEntry channelTable[CH_MAX]; /* @@ -164,6 +165,9 @@ void clear_client_hash_table(void) for (i = 0; i < U_MAX; i++) INIT_LIST_HEAD(&clientTable[i]); + + for (i = 0; i < U_MAX; i++) + INIT_LIST_HEAD(&idTable[i]); } void clear_channel_hash_table(void) @@ -197,6 +201,18 @@ int add_to_client_hash_table(char *name, aClient *cptr) list_add(&cptr->client_hash, &clientTable[hashv]); return 0; } + +/* + * add_to_client_hash_table + */ +int add_to_id_hash_table(char *name, aClient *cptr) +{ + unsigned int hashv; + hashv = hash_nick_name(name); + list_add(&cptr->id_hash, &idTable[hashv]); + return 0; +} + /* * add_to_channel_hash_table */ @@ -221,6 +237,15 @@ int del_from_client_hash_table(char *name, aClient *cptr) return 0; } + +int del_from_id_hash_table(char *name, aClient *cptr) +{ + if (!list_empty(&cptr->id_hash)) + list_del(&cptr->id_hash); + + return 0; +} + /* * del_from_channel_hash_table */ @@ -269,19 +294,21 @@ aClient *hash_find_client(char *name, aClient *cptr) } return (cptr); - /* - * If the member of the hashtable we found isnt at the top of its - * chain, put it there. This builds a most-frequently used order - * into the chains of the hash table, giving speedier lookups on - * those nicks which are being used currently. This same block of - * code is also used for channels and servers for the same - * performance reasons. - * - * I don't believe it does.. it only wastes CPU, lets try it and - * see.... - * - * - Dianora - */ +} + +aClient *hash_find_id(char *name, aClient *cptr) +{ + aClient *tmp; + unsigned int hashv; + + hashv = hash_nick_name(name); + list_for_each_entry(tmp, &idTable[hashv], id_hash) + { + if (smycmp(name, tmp->id) == 0) + return (tmp); + } + + return (cptr); } /* diff --git a/src/ircd.c b/src/ircd.c index 20a671320..0fdf27eff 100644 --- a/src/ircd.c +++ b/src/ircd.c @@ -1466,6 +1466,7 @@ int InitwIRCD(int argc, char *argv[]) timeofday = time(NULL); me.lasttime = me.since = me.firsttime = TStime(); (void)add_to_client_hash_table(me.name, &me); + (void)add_to_id_hash_table(me.id, &me); list_add(&me.client_node, &global_server_list); #if !defined(_AMIGA) && !defined(_WIN32) && !defined(NO_FORKING) if (!(bootopt & BOOT_NOFORK)) diff --git a/src/modules/m_nick.c b/src/modules/m_nick.c index c88298a15..8945569e2 100644 --- a/src/modules/m_nick.c +++ b/src/modules/m_nick.c @@ -843,6 +843,7 @@ int _register_user(aClient *cptr, aClient *sptr, char *nick, char *username, cha { ConfigItem_ban *bconf; char *parv[3], *tmpstr; + const char *id; #ifdef HOSTILENAME char stripuser[USERLEN + 1], *u1 = stripuser, *u2, olduser[USERLEN + 1], userbad[USERLEN * 2 + 1], *ubad = userbad, noident = 0; @@ -1065,6 +1066,11 @@ int _register_user(aClient *cptr, aClient *sptr, char *nick, char *username, cha list_move(&sptr->lclient_node, &lclient_list); + while (hash_find_id((id = uid_get()), NULL) != NULL) + ; + strlcpy(sptr->id, id, sizeof sptr->id); + (void)add_to_id_hash_table(sptr->id, sptr); + IRCstats.unknown--; IRCstats.me_clients++; if (IsHidden(sptr)) @@ -1091,6 +1097,9 @@ int _register_user(aClient *cptr, aClient *sptr, char *nick, char *username, cha for (i = 0; IsupportStrings[i]; i++) sendto_one(sptr, rpl_str(RPL_ISUPPORT), me.name, nick, IsupportStrings[i]); } + + sendto_one(sptr, rpl_str(RPL_YOURID), me.name, nick, sptr->id); + #ifdef USE_SSL if (sptr->flags & FLAGS_SSL) if (sptr->ssl) diff --git a/src/s_err.c b/src/s_err.c index cdf0a11ac..75d4af0f7 100644 --- a/src/s_err.c +++ b/src/s_err.c @@ -71,7 +71,7 @@ static char *replies[] = { /* 039 */ NULL, /* 040 */ NULL, /* 041 */ NULL, -/* 042 */ NULL, /* ircnet */ +/* 042 RPL_YOURID */ ":%s 042 %s %s :your unique ID", /* 043 */ NULL, /* ircnet */ /* 044 */ NULL, /* 045 */ NULL, diff --git a/src/s_misc.c b/src/s_misc.c index 79f43d53d..f8734f62b 100644 --- a/src/s_misc.c +++ b/src/s_misc.c @@ -773,6 +773,8 @@ static void exit_one_client(aClient *cptr, aClient *sptr, aClient *from, char *c } /* Remove sptr from the client list */ + if (*sptr->id) + del_from_id_hash_table(sptr->id, sptr); if (del_from_client_hash_table(sptr->name, sptr) != 1) Debug((DEBUG_ERROR, "%#x !in tab %s[%s] %#x %#x %#x %d %d %#x", sptr, sptr->name,