]>
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"
12 #define ALLOCUNIT 1000
14 #define channelhash(x) (crc32i(x)%CHANNELHASHSIZE)
16 chanindex
*chantable
[CHANNELHASHSIZE
];
17 sstring
*extnames
[MAXCHANNELEXTS
];
18 chanindex
*freechanindices
;
20 unsigned int channelmarker
;
23 memset(chantable
,0,sizeof(chantable
));
24 memset(extnames
,0,sizeof(extnames
));
30 nsfreeall(POOL_CHANINDEX
);
33 chanindex
*getchanindex() {
37 if (freechanindices
==NULL
) {
38 freechanindices
=(chanindex
*)nsmalloc(POOL_CHANINDEX
, ALLOCUNIT
*sizeof(chanindex
));
39 for(i
=0;i
<ALLOCUNIT
-1;i
++) {
40 freechanindices
[i
].next
=&(freechanindices
[i
+1]);
42 freechanindices
[ALLOCUNIT
-1].next
=NULL
;
46 freechanindices
=cip
->next
;
51 void freechanindex(chanindex
*cip
) {
52 cip
->next
=freechanindices
;
56 chanindex
*findchanindex(const char *name
) {
58 int hash
=channelhash(name
);
60 for (cip
=chantable
[hash
];cip
;cip
=cip
->next
) {
61 if (!ircd_strcmp(cip
->name
->content
,name
)) {
69 chanindex
*findorcreatechanindex(const char *name
) {
71 int hash
=channelhash(name
);
74 for (cip
=chantable
[hash
];cip
;cip
=cip
->next
) {
75 if (!ircd_strcmp(cip
->name
->content
,name
)) {
82 cip
->name
=getsstring(name
,CHANNELLEN
);
85 cip
->next
=chantable
[hash
];
88 for(i
=0;i
<MAXCHANNELEXTS
;i
++) {
95 void releasechanindex(chanindex
*cip
) {
100 /* If any module is still using the channel, do nothing */
101 /* Same if the channel is still present on the network */
103 if (cip
->channel
!=NULL
) {
107 for (i
=0;i
<MAXCHANNELEXTS
;i
++) {
108 if (cip
->exts
[i
]!=NULL
) {
113 /* Now remove the index record from the index. */
114 hash
=channelhash(cip
->name
->content
);
116 for(cih
=&(chantable
[hash
]);*cih
;cih
=&((*cih
)->next
)) {
119 freesstring(cip
->name
);
125 Error("channel",ERR_ERROR
,"Tried to release chanindex record for %s not found in hash",cip
->name
->content
);
128 int registerchanext(const char *name
) {
131 if (findchanext(name
)!=-1) {
132 Error("channel",ERR_WARNING
,"Tried to register duplicate extension %s",name
);
136 for (i
=0;i
<MAXCHANNELEXTS
;i
++) {
137 if (extnames
[i
]==NULL
) {
138 extnames
[i
]=getsstring(name
,100);
143 Error("channel",ERR_WARNING
,"Tried to register too many extensions: %s",name
);
147 int findchanext(const char *name
) {
150 for (i
=0;i
<MAXCHANNELEXTS
;i
++) {
151 if (extnames
[i
]!=NULL
&& !ircd_strcmp(name
,extnames
[i
]->content
)) {
159 void releasechanext(int index
) {
161 chanindex
*cip
,*ncip
;
163 freesstring(extnames
[index
]);
164 extnames
[index
]=NULL
;
166 for (i
=0;i
<CHANNELHASHSIZE
;i
++) {
167 for (cip
=chantable
[i
];cip
;cip
=ncip
) {
168 /* CAREFUL: deleting items from chains you're walking is bad */
170 if (cip
->exts
[index
]!=NULL
) {
171 cip
->exts
[index
]=NULL
;
172 releasechanindex(cip
);
178 unsigned int nextchanmarker() {
183 if (!channelmarker
) {
184 /* If we wrapped to zero, zap the marker on all records */
185 for (i
=0;i
<CHANNELHASHSIZE
;i
++)
186 for (cip
=chantable
[i
];cip
;cip
=cip
->next
)
191 return channelmarker
;