]>
jfr.im git - irc/quakenet/newserv.git/blob - chanindex/chanindex.c
4 #include "../irc/irc_config.h"
5 #include "../lib/irc_string.h"
6 #include "../core/error.h"
7 #include "../core/nsmalloc.h"
8 #include "../lib/version.h"
15 #define ALLOCUNIT 1000
17 #define channelhash(x) (crc32i(x)%CHANNELHASHSIZE)
19 chanindex
*chantable
[CHANNELHASHSIZE
];
20 sstring
*extnames
[MAXCHANNELEXTS
];
21 chanindex
*freechanindices
;
23 unsigned int channelmarker
;
26 memset(chantable
,0,sizeof(chantable
));
27 memset(extnames
,0,sizeof(extnames
));
33 nsfreeall(POOL_CHANINDEX
);
36 chanindex
*getchanindex() {
40 if (freechanindices
==NULL
) {
41 freechanindices
=(chanindex
*)nsmalloc(POOL_CHANINDEX
, ALLOCUNIT
*sizeof(chanindex
));
42 for(i
=0;i
<ALLOCUNIT
-1;i
++) {
43 freechanindices
[i
].next
=&(freechanindices
[i
+1]);
45 freechanindices
[ALLOCUNIT
-1].next
=NULL
;
49 freechanindices
=cip
->next
;
54 void freechanindex(chanindex
*cip
) {
55 cip
->next
=freechanindices
;
59 chanindex
*findchanindex(const char *name
) {
61 int hash
=channelhash(name
);
63 for (cip
=chantable
[hash
];cip
;cip
=cip
->next
) {
64 if (!ircd_strcmp(cip
->name
->content
,name
)) {
72 chanindex
*findorcreatechanindex(const char *name
) {
74 int hash
=channelhash(name
);
77 for (cip
=chantable
[hash
];cip
;cip
=cip
->next
) {
78 if (!ircd_strcmp(cip
->name
->content
,name
)) {
85 cip
->name
=getsstring(name
,CHANNELLEN
);
88 cip
->next
=chantable
[hash
];
91 for(i
=0;i
<MAXCHANNELEXTS
;i
++) {
98 void releasechanindex(chanindex
*cip
) {
103 /* If any module is still using the channel, do nothing */
104 /* Same if the channel is still present on the network */
106 if (cip
->channel
!=NULL
) {
110 for (i
=0;i
<MAXCHANNELEXTS
;i
++) {
111 if (cip
->exts
[i
]!=NULL
) {
116 /* Now remove the index record from the index. */
117 hash
=channelhash(cip
->name
->content
);
119 for(cih
=&(chantable
[hash
]);*cih
;cih
=&((*cih
)->next
)) {
122 freesstring(cip
->name
);
128 Error("channel",ERR_ERROR
,"Tried to release chanindex record for %s not found in hash",cip
->name
->content
);
131 int registerchanext(const char *name
) {
134 if (findchanext(name
)!=-1) {
135 Error("channel",ERR_WARNING
,"Tried to register duplicate extension %s",name
);
139 for (i
=0;i
<MAXCHANNELEXTS
;i
++) {
140 if (extnames
[i
]==NULL
) {
141 extnames
[i
]=getsstring(name
,100);
146 Error("channel",ERR_WARNING
,"Tried to register too many extensions: %s",name
);
150 int findchanext(const char *name
) {
153 for (i
=0;i
<MAXCHANNELEXTS
;i
++) {
154 if (extnames
[i
]!=NULL
&& !ircd_strcmp(name
,extnames
[i
]->content
)) {
162 void releasechanext(int index
) {
164 chanindex
*cip
,*ncip
;
166 freesstring(extnames
[index
]);
167 extnames
[index
]=NULL
;
169 for (i
=0;i
<CHANNELHASHSIZE
;i
++) {
170 for (cip
=chantable
[i
];cip
;cip
=ncip
) {
171 /* CAREFUL: deleting items from chains you're walking is bad */
173 if (cip
->exts
[index
]!=NULL
) {
174 cip
->exts
[index
]=NULL
;
175 releasechanindex(cip
);
181 unsigned int nextchanmarker() {
186 if (!channelmarker
) {
187 /* If we wrapped to zero, zap the marker on all records */
188 for (i
=0;i
<CHANNELHASHSIZE
;i
++)
189 for (cip
=chantable
[i
];cip
;cip
=cip
->next
)
194 return channelmarker
;