diff --git a/include/common.h b/include/common.h index 1b4cb0861..8b1e735e7 100644 --- a/include/common.h +++ b/include/common.h @@ -47,7 +47,7 @@ #endif #include "ircsprintf.h" - +#include "list.h" #ifdef DEVELOP_CVS #define ID_Copyright(x) static char id_copyright[] = x diff --git a/include/h.h b/include/h.h index eefd504b6..9aa2f21e9 100644 --- a/include/h.h +++ b/include/h.h @@ -38,7 +38,7 @@ extern char *getreply(int); extern MODVAR Member *freemember; extern MODVAR Membership *freemembership; extern MODVAR MembershipL *freemembershipL; -extern MODVAR aClient *client, me, *local[]; +extern MODVAR aClient me, *local[]; extern MODVAR aChannel *channel; extern MODVAR struct stats *ircstp; extern MODVAR int bootopt; @@ -151,6 +151,7 @@ extern MODVAR int R_do_dns, R_fin_dns, R_fin_dnsc, R_fail_dns, R_do_id, R_fin_id, R_fail_id; #endif +extern struct list_head client_list; extern inline aCommand *find_Command(char *cmd, short token, int flags); extern aCommand *find_Command_simple(char *cmd); extern aChannel *find_channel(char *, aChannel *); diff --git a/include/struct.h b/include/struct.h index 569b1b19c..af98f776e 100644 --- a/include/struct.h +++ b/include/struct.h @@ -993,7 +993,8 @@ typedef struct { #define SSLFLAG_NOSTARTTLS 0x8 struct Client { - struct Client *next, *prev, *hnext; + struct list_head client_list; + struct list_head client_hash; anUser *user; /* ...defined, if this is a User */ aServer *serv; /* ...defined, if this is a server */ TS lastnick; /* TimeStamp on nick */ diff --git a/src/hash.c b/src/hash.c index b7efd9928..554656304 100644 --- a/src/hash.c +++ b/src/hash.c @@ -30,7 +30,7 @@ ID_Copyright("(C) 1991 Darren Reed"); ID_Notes("2.10 7/3/93"); -static aHashEntry clientTable[U_MAX]; +static struct list_head clientTable[U_MAX]; static aHashEntry channelTable[CH_MAX]; /* @@ -160,7 +160,10 @@ unsigned int hash_whowas_name(char *name) */ void clear_client_hash_table(void) { - memset((char *)clientTable, '\0', sizeof(aHashEntry) * U_MAX); + int i; + + for (i = 0; i < U_MAX; i++) + INIT_LIST_HEAD(&clientTable[i]); } void clear_channel_hash_table(void) @@ -191,10 +194,7 @@ int add_to_client_hash_table(char *name, aClient *cptr) if (loop.tainted) return 0; hashv = hash_nick_name(name); - cptr->hnext = (aClient *)clientTable[hashv].list; - clientTable[hashv].list = (void *)cptr; - clientTable[hashv].links++; - clientTable[hashv].hits++; + list_add(&cptr->client_hash, &clientTable[hashv]); return 0; } /* @@ -216,33 +216,13 @@ int add_to_channel_hash_table(char *name, aChannel *chptr) */ int del_from_client_hash_table(char *name, aClient *cptr) { - aClient *tmp, *prev = NULL; - unsigned int hashv; - - hashv = hash_nick_name(name); - for (tmp = (aClient *)clientTable[hashv].list; tmp; tmp = tmp->hnext) + if (!list_empty(&cptr->client_hash)) { - if (tmp == cptr) - { - if (prev) - prev->hnext = tmp->hnext; - else - clientTable[hashv].list = (void *)tmp->hnext; - tmp->hnext = NULL; - if (clientTable[hashv].links > 0) - { - clientTable[hashv].links--; - return 1; - } - else - /* - * Should never actually return from here and if we do it - * is an error/inconsistency in the hash table. - */ - return -1; - } - prev = tmp; + ircd_log(LOG_ERROR, "cptr->client_hash.next %p .prev %p", + cptr->client_hash.next, cptr->client_hash.prev); + list_del(&cptr->client_hash); } + return 0; } /* @@ -283,19 +263,15 @@ int del_from_channel_hash_table(char *name, aChannel *chptr) aClient *hash_find_client(char *name, aClient *cptr) { aClient *tmp; - aHashEntry *tmp3; unsigned int hashv; hashv = hash_nick_name(name); - tmp3 = &clientTable[hashv]; - /* - * Got the bucket, now search the chain. - */ - for (tmp = (aClient *)tmp3->list; tmp; tmp = tmp->hnext) + list_for_each_entry(tmp, &clientTable[hashv], client_hash) + { if (smycmp(name, tmp->name) == 0) - { return (tmp); - } + } + return (cptr); /* * If the member of the hashtable we found isnt at the top of its @@ -318,24 +294,25 @@ aClient *hash_find_client(char *name, aClient *cptr) aClient *hash_find_nickserver(char *name, aClient *cptr) { aClient *tmp; - aHashEntry *tmp3; unsigned int hashv; char *serv; serv = (char *)strchr(name, '@'); *serv++ = '\0'; hashv = hash_nick_name(name); - tmp3 = &clientTable[hashv]; + /* * Got the bucket, now search the chain. */ - for (tmp = (aClient *)tmp3->list; tmp; tmp = tmp->hnext) + list_for_each_entry(tmp, &clientTable[hashv], client_hash) + { if (smycmp(name, tmp->name) == 0 && tmp->user && smycmp(serv, tmp->user->server) == 0) { *--serv = '\0'; return (tmp); } + } *--serv = '\0'; return (cptr); @@ -346,18 +323,10 @@ aClient *hash_find_nickserver(char *name, aClient *cptr) aClient *hash_find_server(char *server, aClient *cptr) { aClient *tmp; -#if 0 - char *t; - char ch; -#endif - aHashEntry *tmp3; - unsigned int hashv; hashv = hash_nick_name(server); - tmp3 = &clientTable[hashv]; - - for (tmp = (aClient *)tmp3->list; tmp; tmp = tmp->hnext) + list_for_each_entry(tmp, &clientTable[hashv], client_hash) { if (!IsServer(tmp) && !IsMe(tmp)) continue; @@ -367,42 +336,6 @@ aClient *hash_find_server(char *server, aClient *cptr) } } - /* - * Whats happening in this next loop ? Well, it takes a name like - * foo.bar.edu and proceeds to earch for *.edu and then *.bar.edu. - * This is for checking full server names against masks although it - * isnt often done this way in lieu of using matches(). - */ - - /* why in god's name would we ever want to do something like this? - * commented out, probably to be removed sooner or later - lucas - */ - -#if 0 - t = ((char *)server + strlen(server)); - - for (;;) - { - t--; - for (; t > server; t--) - if (*(t + 1) == '.') - break; - if (*t == '*' || t == server) - break; - ch = *t; - *t = '*'; - /* - * Dont need to check IsServer() here since nicknames cant have - * *'s in them anyway. - */ - if (((tmp = hash_find_client(t, cptr))) != cptr) - { - *t = ch; - return (tmp); - } - *t = ch; - } -#endif return (cptr); } diff --git a/src/ircd.c b/src/ircd.c index 88a4abbcf..42a11199f 100644 --- a/src/ircd.c +++ b/src/ircd.c @@ -104,7 +104,6 @@ char REPORT_DO_DNS[256], REPORT_FIN_DNS[256], REPORT_FIN_DNSC[256], extern ircstats IRCstats; aClient me; /* That's me */ MODVAR char *me_hash; -aClient *client = &me; /* Pointer to beginning of Client list */ extern char backupbuf[8192]; #ifdef _WIN32 extern void CleanUpSegv(int sig); @@ -1493,7 +1492,6 @@ int InitwIRCD(int argc, char *argv[]) strlcpy(me.name, me.sockhost, sizeof(me.name)); me.hopcount = 0; me.authfd = -1; - me.next = NULL; me.user = NULL; me.from = &me; me.class = (ConfigItem_class *) conf_listen; @@ -1504,6 +1502,7 @@ int InitwIRCD(int argc, char *argv[]) me_hash = find_or_add(me.name); me.serv->up = me_hash; me.serv->numeric = conf_me->numeric; + add_client_to_list(&me); add_server_to_table(&me); timeofday = time(NULL); me.lasttime = me.since = me.firsttime = TStime(); diff --git a/src/list.c b/src/list.c index 01f76b921..5b1571f39 100644 --- a/src/list.c +++ b/src/list.c @@ -70,6 +70,7 @@ MODVAR Member *freemember = NULL; MODVAR Membership *freemembership = NULL; MODVAR MembershipL *freemembershipL = NULL; MODVAR int numclients = 0; +MODVAR struct list_head client_list; void initlists(void) { @@ -81,6 +82,8 @@ void initlists(void) bzero((char *)&links, sizeof(links)); bzero((char *)&classs, sizeof(classs)); #endif + + INIT_LIST_HEAD(&client_list); } void outofmemory(void) @@ -125,14 +128,14 @@ aClient *make_client(aClient *from, aClient *servr) /* Note: structure is zero (calloc) */ cptr->from = from ? from : cptr; /* 'from' of local client is self! */ - cptr->next = NULL; /* For machines with NON-ZERO NULL pointers >;) */ - cptr->prev = NULL; - cptr->hnext = NULL; cptr->user = NULL; cptr->serv = NULL; cptr->srvptr = servr; cptr->status = STAT_UNKNOWN; - + + INIT_LIST_HEAD(&cptr->client_list); + INIT_LIST_HEAD(&cptr->client_hash); + (void)strcpy(cptr->username, "unknown"); if (size == CLIENT_LOCAL_SIZE) { @@ -296,17 +299,8 @@ void remove_client_from_list(aClient *cptr) #endif ) IRCstats.unknown--; + list_del(&cptr->client_list); checklist(); - if (cptr->prev) - cptr->prev->next = cptr->next; - else - { - client = cptr->next; - if (client) - client->prev = NULL; - } - if (cptr->next) - cptr->next->prev = cptr->prev; if (IsPerson(cptr)) /* Only persons can have been added before */ { add_history(cptr, 0); @@ -343,15 +337,7 @@ void remove_client_from_list(aClient *cptr) */ void add_client_to_list(aClient *cptr) { - /* - * since we always insert new clients to the top of the list, - * this should mean the "me" is the bottom most item in the list. - */ - cptr->next = client; - client = cptr; - if (cptr->next) - cptr->next->prev = cptr; - return; + list_add(&cptr->client_list, &client_list); } /* diff --git a/src/modules/m_sasl.c b/src/modules/m_sasl.c index 94987fc7d..dae716f05 100644 --- a/src/modules/m_sasl.c +++ b/src/modules/m_sasl.c @@ -94,7 +94,7 @@ ModuleHeader MOD_HEADER(m_sasl) */ static aClient *decode_puid(char *puid) { - aClient *client; + aClient *cptr; char *it, *it2; unsigned int slot; int cookie = 0; @@ -118,12 +118,12 @@ static aClient *decode_puid(char *puid) if (slot >= MAXCONNECTIONS) return NULL; - client = local[slot]; + cptr = local[slot]; - if (cookie && client->sasl_cookie != cookie) + if (cookie && cptr->sasl_cookie != cookie) return NULL; - return client; + return cptr; } /* diff --git a/src/modules/m_server.c b/src/modules/m_server.c index 7811a7e1c..434229321 100644 --- a/src/modules/m_server.c +++ b/src/modules/m_server.c @@ -830,7 +830,8 @@ int m_server_synch(aClient *cptr, long numeric, ConfigItem_link *aconf) cptr->name, cptr->info); } } - for (acptr = &me; acptr; acptr = acptr->prev) + + list_for_each_entry_reverse(acptr, &client_list, client_list) { /* acptr->from == acptr for acptr == cptr */ if (acptr->from == cptr) @@ -880,7 +881,7 @@ int m_server_synch(aClient *cptr, long numeric, ConfigItem_link *aconf) } } /* Synching nick information */ - for (acptr = &me; acptr; acptr = acptr->prev) + list_for_each_entry_reverse(acptr, &client_list, client_list) { /* acptr->from == acptr for acptr == cptr */ if (acptr->from == cptr) diff --git a/src/modules/m_squit.c b/src/modules/m_squit.c index 868be4219..63db0b1d0 100644 --- a/src/modules/m_squit.c +++ b/src/modules/m_squit.c @@ -106,15 +106,10 @@ CMD_FUNC(m_squit) { server = parv[1]; - /* - ** The following allows wild cards in SQUIT. Only usefull - ** when the command is issued by an oper. + /* We used to allow wildcards here, but this wasn't really a good + * idea because it made the behaviour of SQUIT unpredictable. --nenolod */ - for (acptr = client; - (acptr = next_client(acptr, server)); - acptr = acptr->next) - if (IsServer(acptr) || IsMe(acptr)) - break; + acptr = find_client(server, NULL); if (acptr && IsMe(acptr)) { acptr = cptr; diff --git a/src/modules/m_stats.c b/src/modules/m_stats.c index 34b1875dc..42c0953bd 100644 --- a/src/modules/m_stats.c +++ b/src/modules/m_stats.c @@ -534,7 +534,7 @@ int stats_links(aClient *sptr, char *para) link_p->leafmask, link_p->servername, link_p->leafdepth); } #ifdef DEBUGMODE - for (acptr = client; acptr; acptr = acptr->next) + list_for_each_entry(acptr, &client_list, client_list) if (MyConnect(acptr) && acptr->serv && !IsMe(acptr)) { if (!acptr->serv->conf) @@ -893,7 +893,7 @@ int stats_mem(aClient *sptr, char *para) count_watch_memory(&wlh, &wlhm); wwm = sizeof(aName) * NICKNAMEHISTORYLENGTH; - for (acptr = client; acptr; acptr = acptr->next) + list_for_each_entry(acptr, &client_list, client_list) { if (MyConnect(acptr)) { @@ -1647,7 +1647,7 @@ int stats_linkinfoint(aClient *sptr, char *para, int all) #endif } #ifdef DEBUGMODE - for (acptr = client; acptr; acptr = acptr->next) + list_for_each_entry(acptr, &client_list, client_list) { if (IsServer(acptr)) sendto_one(sptr, ":%s NOTICE %s :Server %s is %s", diff --git a/src/modules/m_svsnoop.c b/src/modules/m_svsnoop.c index 91f9b62e1..2d3f87b5b 100644 --- a/src/modules/m_svsnoop.c +++ b/src/modules/m_svsnoop.c @@ -97,7 +97,7 @@ long oldumodes; { SVSNOOP = 1; sendto_ops("This server has been placed in NOOP mode"); - for (acptr = &me; acptr; acptr = acptr->prev) + list_for_each_entry(acptr, &client_list, client_list) { if (MyClient(acptr) && IsAnOper(acptr)) { diff --git a/src/modules/m_tkl.c b/src/modules/m_tkl.c index c430dfab5..314ab447c 100644 --- a/src/modules/m_tkl.c +++ b/src/modules/m_tkl.c @@ -1490,7 +1490,7 @@ char spamfilter_user[NICKLEN + USERLEN + HOSTLEN + REALLEN + 64]; /* n!u@h:r */ int matches = 0; aClient *acptr; - for (acptr = client; acptr; acptr = acptr->next) + list_for_each_entry(acptr, &client_list, client_list) if (IsPerson(acptr)) { spamfilter_build_user_string(spamfilter_user, acptr->name, acptr); diff --git a/src/modules/m_trace.c b/src/modules/m_trace.c index 641684edc..a01c7896e 100644 --- a/src/modules/m_trace.c +++ b/src/modules/m_trace.c @@ -128,7 +128,7 @@ DLLFUNC CMD_FUNC(m_trace) { aClient *ac2ptr; - ac2ptr = next_client(client, tname); + ac2ptr = find_client(tname, NULL); sendto_one(sptr, rpl_str(RPL_TRACELINK), me.name, parv[0], version, debugmode, tname, ac2ptr->from->name); return 0; @@ -148,7 +148,7 @@ DLLFUNC CMD_FUNC(m_trace) if (doall) { - for (acptr = client; acptr; acptr = acptr->next) + list_for_each_entry(acptr, &client_list, client_list) #ifdef SHOW_INVISIBLE_LUSERS if (IsPerson(acptr)) link_u[acptr->from->slot]++; diff --git a/src/modules/m_who.c b/src/modules/m_who.c index a9fe3eabd..deb3996a6 100644 --- a/src/modules/m_who.c +++ b/src/modules/m_who.c @@ -660,7 +660,7 @@ int oper = IsAnOper(sptr); aClient *acptr; who_flags |= WF_WILDCARD; - for (acptr = client; acptr; acptr = acptr->next) + list_for_each_entry(acptr, &client_list, client_list) { int cansee; char status[20]; diff --git a/src/modules/webtv.c b/src/modules/webtv.c index 8d3b41979..2408131fe 100644 --- a/src/modules/webtv.c +++ b/src/modules/webtv.c @@ -172,8 +172,8 @@ int w_whois(aClient *cptr, aClient *sptr, int parc, char *parv[]) if (wilds) continue; - for (acptr = client; (acptr = next_client(acptr, nick)); - acptr = acptr->next) + acptr = find_client(nick, NULL); + { if (IsServer(acptr)) continue; diff --git a/src/parse.c b/src/parse.c index 052221656..95bf7f9ab 100644 --- a/src/parse.c +++ b/src/parse.c @@ -116,7 +116,7 @@ aClient inline *find_name(char *name, aClient *cptr) return (c2ptr); if (!index(name, '*')) return c2ptr; - for (c2ptr = client; c2ptr; c2ptr = c2ptr->next) + list_for_each_entry(c2ptr, &client_list, client_list) { if (!IsServer(c2ptr) && !IsMe(c2ptr)) continue; diff --git a/src/s_misc.c b/src/s_misc.c index e62a01788..3ba9810f5 100644 --- a/src/s_misc.c +++ b/src/s_misc.c @@ -633,9 +633,8 @@ int exit_client(aClient *cptr, aClient *sptr, aClient *from, char *comment) /* * First, remove the clients on the server itself. */ - for (acptr = client; acptr; acptr = next) + list_for_each_entry_safe(acptr, next, &client_list, client_list) { - next = acptr->next; if (IsClient(acptr) && (acptr->srvptr == sptr)) exit_one_client(NULL, acptr, &me, comment1, 1); @@ -646,9 +645,8 @@ int exit_client(aClient *cptr, aClient *sptr, aClient *from, char *comment) * the one we just lost. */ recurse++; - for (acptr = client; acptr; acptr = next) + list_for_each_entry_safe(acptr, next, &client_list, client_list) { - next = acptr->next; if (IsServer(acptr) && acptr->srvptr == sptr) exit_client(sptr, acptr, sptr, comment1); /* RECURSION */ /* @@ -853,7 +851,7 @@ int counted = 0; aClient *acptr; char text[2048]; - for (acptr = client; acptr; acptr = acptr->next) + list_for_each_entry(acptr, &client_list, client_list) { if (IsOper(acptr) && !IsHideOper(acptr)) counted++; diff --git a/src/s_serv.c b/src/s_serv.c index f87235e40..65d582333 100644 --- a/src/s_serv.c +++ b/src/s_serv.c @@ -1275,7 +1275,10 @@ aClient *find_match_server(char *mask) if (BadPtr(mask)) return NULL; - for (acptr = client, collapse(mask); acptr; acptr = acptr->next) + + collapse(mask); + + list_for_each_entry(acptr, &client_list, client_list) { if (!IsServer(acptr) && !IsMe(acptr)) continue; @@ -1283,6 +1286,7 @@ aClient *find_match_server(char *mask) break; continue; } + return acptr; } diff --git a/src/s_user.c b/src/s_user.c index 9d4ee2092..46d5cf873 100644 --- a/src/s_user.c +++ b/src/s_user.c @@ -206,15 +206,18 @@ aClient *next_client(aClient *next, char *ch) aClient *tmp = next; next = find_client(ch, tmp); - if (tmp && tmp->prev == next) + if (tmp && list_empty(&next->client_list)) return NULL; if (next != tmp) return next; - for (; next; next = next->next) + + tmp = next; + list_for_each_entry(next, &next->client_list, client_list) { if (!match(ch, next->name) || !match(next->name, ch)) break; } + return next; } @@ -262,9 +265,7 @@ int hunt_server(aClient *cptr, aClient *sptr, char *command, int server, int pa if (acptr->from == sptr->from && !MyConnect(acptr)) acptr = NULL; if (!acptr) - for (acptr = client, (void)collapse(parv[server]); - (acptr = next_client(acptr, parv[server])); - acptr = acptr->next) + list_for_each_entry(acptr, &client_list, client_list) { if (acptr->from == sptr->from && !MyConnect(acptr)) continue; @@ -341,9 +342,7 @@ int hunt_server_token(aClient *cptr, aClient *sptr, char *command, char *token, if (acptr->from == sptr->from && !MyConnect(acptr)) acptr = NULL; if (!acptr) - for (acptr = client, (void)collapse(parv[server]); - (acptr = next_client(acptr, parv[server])); - acptr = acptr->next) + list_for_each_entry(acptr, &acptr->client_list, client_list) { if (acptr->from == sptr->from && !MyConnect(acptr)) continue; @@ -407,9 +406,7 @@ int hunt_server_token_quiet(aClient *cptr, aClient *sptr, char *command, char * if (acptr->from == sptr->from && !MyConnect(acptr)) acptr = NULL; if (!acptr) - for (acptr = client, (void)collapse(parv[server]); - (acptr = next_client(acptr, parv[server])); - acptr = acptr->next) + list_for_each_entry(acptr, &client_list, client_list) { if (acptr->from == sptr->from && !MyConnect(acptr)) continue; diff --git a/src/send.c b/src/send.c index 28081f189..1789be73a 100644 --- a/src/send.c +++ b/src/send.c @@ -1321,7 +1321,7 @@ void sendto_match_butone(aClient *one, aClient *from, char *mask, int what, { if (!cansendglobal) continue; - for (acptr = client; acptr; acptr = acptr->next) + list_for_each_entry(acptr, &client_list, client_list) if (IsRegisteredUser(acptr) && match_it(acptr, mask, what) && acptr->from == cptr) @@ -1676,7 +1676,7 @@ void sendto_ops_butone(aClient *one, aClient *from, char *pattern, ...) va_start(vl, pattern); ++sentalong_marker; - for (cptr = client; cptr; cptr = cptr->next) + list_for_each_entry(cptr, &client_list, client_list) { if (!SendWallops(cptr)) continue; @@ -1710,7 +1710,7 @@ void sendto_opers_butone(aClient *one, aClient *from, char *pattern, ...) va_start(vl, pattern); ++sentalong_marker; - for (cptr = client; cptr; cptr = cptr->next) + list_for_each_entry(cptr, &client_list, client_list) { if (!IsAnOper(cptr)) continue; @@ -1741,7 +1741,7 @@ void sendto_ops_butme(aClient *from, char *pattern, ...) va_start(vl, pattern); ++sentalong_marker; - for (cptr = client; cptr; cptr = cptr->next) + list_for_each_entry(cptr, &client_list, client_list) { if (!SendWallops(cptr)) continue; diff --git a/src/umodes.c b/src/umodes.c index a956b8aac..ddd7163d4 100644 --- a/src/umodes.c +++ b/src/umodes.c @@ -262,7 +262,7 @@ void UmodeDel(Umode *umode) else { aClient *cptr; - for (cptr = client; cptr; cptr = cptr->next) + list_for_each_entry(cptr, &client_list, client_list) { long oldumode = 0; if (!IsPerson(cptr)) @@ -410,7 +410,7 @@ void unload_all_unused_umodes() } if (!removed_umode) /* Nothing was unloaded */ return; - for (cptr = client; cptr; cptr = cptr->next) + list_for_each_entry(cptr, &client_list, client_list) { long oldumode = 0; if (!IsPerson(cptr))