]> jfr.im git - irc/quakenet/newserv.git/blob - nick/nickhelpers.c
r595@blue (orig r485): slug | 2006-05-04 18:02:24 +0100
[irc/quakenet/newserv.git] / nick / nickhelpers.c
1 /* nickhelpers.c */
2
3 #include "nick.h"
4 #include "../lib/flags.h"
5 #include "../lib/irc_string.h"
6 #include "../irc/irc_config.h"
7 #include "../core/error.h"
8 #include "../lib/sstring.h"
9
10 #include <string.h>
11
12 #define hosthash(x) ((crc32i(x))%HOSTHASHSIZE)
13 #define realnamehash(x) ((crc32(x))%REALNAMEHASHSIZE)
14
15 unsigned int hostmarker;
16 unsigned int realnamemarker;
17 unsigned int nickmarker;
18
19 host *hosttable[HOSTHASHSIZE];
20 realname *realnametable[REALNAMEHASHSIZE];
21
22 void initnickhelpers() {
23 memset(hosttable,0,sizeof(hosttable));
24 memset(realnametable,0,sizeof(realnametable));
25 }
26
27 host *findhost(const char *hostname) {
28 host *hp;
29 for (hp=hosttable[hosthash(hostname)];hp;hp=(host *)hp->next) {
30 if (!ircd_strcmp(hostname,hp->name->content))
31 return hp;
32 }
33 return NULL;
34 }
35
36 host *findorcreatehost(const char *hostname) {
37 host *hp;
38 unsigned long thehash=hosthash(hostname);
39
40 for (hp=hosttable[thehash];hp;hp=(host *)hp->next)
41 if (!ircd_strcmp(hostname,hp->name->content)) {
42 hp->clonecount++;
43 return hp;
44 }
45
46 hp=newhost();
47 hp->name=getsstring(hostname,HOSTLEN);
48 hp->clonecount=1;
49 hp->marker=0;
50 hp->nicks=NULL;
51 hp->next=(struct host *)hosttable[thehash];
52 hosttable[thehash]=hp;
53
54 return hp;
55 }
56
57 void releasehost(host *hp) {
58 host **mhp;
59 if (--(hp->clonecount)==0) {
60 for(mhp=&(hosttable[hosthash(hp->name->content)]);*mhp;mhp=(host **)&((*mhp)->next)) {
61 if ((*mhp)==hp) {
62 (*mhp)=(host *)hp->next;
63 freesstring(hp->name);
64 freehost(hp);
65 return;
66 }
67 }
68 Error("nick",ERR_ERROR,"Unable to remove host %s from hashtable",hp->name->content);
69 }
70 }
71
72 realname *findrealname(const char *name) {
73 realname *rnp;
74
75 for (rnp=realnametable[realnamehash(name)];rnp;rnp=(realname *)rnp->next)
76 if (!strcmp(name,rnp->name->content))
77 return rnp;
78
79 return NULL;
80 }
81
82 realname *findorcreaterealname(const char *name) {
83 realname *rnp;
84 unsigned int thehash=realnamehash(name);
85
86 for (rnp=realnametable[thehash];rnp;rnp=(realname *)rnp->next)
87 if (!strcmp(name,rnp->name->content)) {
88 rnp->usercount++;
89 return rnp;
90 }
91
92 rnp=newrealname();
93 rnp->name=getsstring(name,REALLEN);
94 rnp->usercount=1;
95 rnp->marker=0;
96 rnp->nicks=NULL;
97 rnp->next=(struct realname *)realnametable[thehash];
98 realnametable[thehash]=rnp;
99
100 return rnp;
101 }
102
103 void releaserealname(realname *rnp) {
104 realname **mrnp;
105 if (--(rnp->usercount)==0) {
106 for(mrnp=&(realnametable[realnamehash(rnp->name->content)]);*mrnp;mrnp=(realname **)&((*mrnp)->next)) {
107 if ((*mrnp)==rnp) {
108 (*mrnp)=(realname *)rnp->next;
109 freesstring(rnp->name);
110 freerealname(rnp);
111 return;
112 }
113 }
114 Error("nick",ERR_ERROR,"Unable to remove realname %s from hashtable",rnp->name->content);
115 }
116 }
117
118 unsigned int nexthostmarker() {
119 int i;
120 host *hp;
121
122 hostmarker++;
123 if (!hostmarker) {
124 /* If we wrapped to zero, zap the marker on all hosts */
125 for (i=0;i<HOSTHASHSIZE;i++)
126 for (hp=hosttable[i];hp;hp=hp->next)
127 hp->marker=0;
128 hostmarker++;
129 }
130
131 return hostmarker;
132 }
133
134 unsigned int nextrealnamemarker() {
135 int i;
136 realname *rnp;
137
138 realnamemarker++;
139 if (!realnamemarker) {
140 /* If we wrapped to zero, zap the marker on all records */
141 for (i=0;i<REALNAMEHASHSIZE;i++)
142 for (rnp=realnametable[i];rnp;rnp=rnp->next)
143 rnp->marker=0;
144 realnamemarker++;
145 }
146
147 return realnamemarker;
148 }
149
150 unsigned int nextnickmarker() {
151 int i;
152 nick *np;
153
154 nickmarker++;
155
156 if (!nickmarker) {
157 /* If we wrapped to zero, zap the marker on all records */
158 for (i=0;i<NICKHASHSIZE;i++)
159 for (np=nicktable[i];np;np=np->next)
160 np->marker=0;
161 nickmarker++;
162 }
163
164 return nickmarker;
165 }