]>
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 channelhash(x) (crc32i(x)%CHANNELHASHSIZE)
17 chanindex
*chantable
[CHANNELHASHSIZE
];
18 sstring
*extnames
[MAXCHANNELEXTS
];
20 unsigned int channelmarker
;
23 memset(chantable
,0,sizeof(chantable
));
24 memset(extnames
,0,sizeof(extnames
));
29 nsfreeall(POOL_CHANINDEX
);
32 chanindex
*getchanindex() {
33 return nsmalloc(POOL_CHANINDEX
, sizeof(chanindex
));
36 void freechanindex(chanindex
*cip
) {
37 nsfree(POOL_CHANINDEX
, cip
);
40 chanindex
*findchanindex(const char *name
) {
42 int hash
=channelhash(name
);
44 for (cip
=chantable
[hash
];cip
;cip
=cip
->next
) {
45 if (!ircd_strcmp(cip
->name
->content
,name
)) {
53 chanindex
*findorcreatechanindex(const char *name
) {
55 int hash
=channelhash(name
);
58 for (cip
=chantable
[hash
];cip
;cip
=cip
->next
) {
59 if (!ircd_strcmp(cip
->name
->content
,name
)) {
66 cip
->name
=getsstring(name
,CHANNELLEN
);
69 cip
->next
=chantable
[hash
];
72 for(i
=0;i
<MAXCHANNELEXTS
;i
++) {
79 void releasechanindex(chanindex
*cip
) {
84 /* If any module is still using the channel, do nothing */
85 /* Same if the channel is still present on the network */
87 if (cip
->channel
!=NULL
) {
91 for (i
=0;i
<MAXCHANNELEXTS
;i
++) {
92 if (cip
->exts
[i
]!=NULL
) {
97 /* Now remove the index record from the index. */
98 hash
=channelhash(cip
->name
->content
);
100 for(cih
=&(chantable
[hash
]);*cih
;cih
=&((*cih
)->next
)) {
103 freesstring(cip
->name
);
109 Error("channel",ERR_ERROR
,"Tried to release chanindex record for %s not found in hash",cip
->name
->content
);
112 int registerchanext(const char *name
) {
115 if (findchanext(name
)!=-1) {
116 Error("channel",ERR_WARNING
,"Tried to register duplicate extension %s",name
);
120 for (i
=0;i
<MAXCHANNELEXTS
;i
++) {
121 if (extnames
[i
]==NULL
) {
122 extnames
[i
]=getsstring(name
,100);
127 Error("channel",ERR_WARNING
,"Tried to register too many extensions: %s",name
);
131 int findchanext(const char *name
) {
134 for (i
=0;i
<MAXCHANNELEXTS
;i
++) {
135 if (extnames
[i
]!=NULL
&& !ircd_strcmp(name
,extnames
[i
]->content
)) {
143 void releasechanext(int index
) {
145 chanindex
*cip
,*ncip
;
147 freesstring(extnames
[index
]);
148 extnames
[index
]=NULL
;
150 for (i
=0;i
<CHANNELHASHSIZE
;i
++) {
151 for (cip
=chantable
[i
];cip
;cip
=ncip
) {
152 /* CAREFUL: deleting items from chains you're walking is bad */
154 if (cip
->exts
[index
]!=NULL
) {
155 cip
->exts
[index
]=NULL
;
156 releasechanindex(cip
);
162 unsigned int nextchanmarker() {
167 if (!channelmarker
) {
168 /* If we wrapped to zero, zap the marker on all records */
169 for (i
=0;i
<CHANNELHASHSIZE
;i
++)
170 for (cip
=chantable
[i
];cip
;cip
=cip
->next
)
175 return channelmarker
;