]> jfr.im git - irc/quakenet/newserv.git/blob - channel/channelindex.c
Sigh
[irc/quakenet/newserv.git] / channel / channelindex.c
1 /* channelindex.c */
2
3 #include "channel.h"
4 #include "../irc/irc_config.h"
5 #include "../lib/irc_string.h"
6 #include <stdio.h>
7 #include <string.h>
8
9 #define channelhash(x) (crc32i(x)%CHANNELHASHSIZE)
10
11 chanindex *chantable[CHANNELHASHSIZE];
12 sstring *extnames[MAXCHANNELEXTS];
13
14 unsigned int channelmarker;
15
16 void initchannelindex() {
17 memset(chantable,0,sizeof(chantable));
18 memset(extnames,0,sizeof(extnames));
19 channelmarker=0;
20 }
21
22 chanindex *findchanindex(const char *name) {
23 chanindex *cip;
24 int hash=channelhash(name);
25
26 for (cip=chantable[hash];cip;cip=cip->next) {
27 if (!ircd_strcmp(cip->name->content,name)) {
28 return cip;
29 }
30 }
31
32 return NULL;
33 }
34
35 chanindex *findorcreatechanindex(const char *name) {
36 chanindex *cip;
37 int hash=channelhash(name);
38 int i;
39
40 for (cip=chantable[hash];cip;cip=cip->next) {
41 if (!ircd_strcmp(cip->name->content,name)) {
42 return cip;
43 }
44 }
45
46 cip=getchanindex();
47
48 cip->name=getsstring(name,CHANNELLEN);
49 cip->channel=NULL;
50 cip->marker=0;
51 cip->next=chantable[hash];
52 chantable[hash]=cip;
53
54 for(i=0;i<MAXCHANNELEXTS;i++) {
55 cip->exts[i]=NULL;
56 }
57
58 return cip;
59 }
60
61 void releasechanindex(chanindex *cip) {
62 int i;
63 chanindex **cih;
64 int hash;
65
66 /* If any module is still using the channel, do nothing */
67 /* Same if the channel is still present on the network */
68
69 if (cip->channel!=NULL) {
70 return;
71 }
72
73 for (i=0;i<MAXCHANNELEXTS;i++) {
74 if (cip->exts[i]!=NULL) {
75 return;
76 }
77 }
78
79 /* Now remove the index record from the index. */
80 hash=channelhash(cip->name->content);
81
82 for(cih=&(chantable[hash]);*cih;cih=&((*cih)->next)) {
83 if (*cih==cip) {
84 (*cih)=cip->next;
85 freesstring(cip->name);
86 freechanindex(cip);
87 return;
88 }
89 }
90
91 Error("channel",ERR_ERROR,"Tried to release chanindex record for %s not found in hash",cip->name->content);
92 }
93
94 int registerchanext(const char *name) {
95 int i;
96
97 if (findchanext(name)!=-1) {
98 Error("channel",ERR_WARNING,"Tried to register duplicate extension %s",name);
99 return -1;
100 }
101
102 for (i=0;i<MAXCHANNELEXTS;i++) {
103 if (extnames[i]==NULL) {
104 extnames[i]=getsstring(name,100);
105 return i;
106 }
107 }
108
109 Error("channel",ERR_WARNING,"Tried to register too many extensions: %s",name);
110 return -1;
111 }
112
113 int findchanext(const char *name) {
114 int i;
115
116 for (i=0;i<MAXCHANNELEXTS;i++) {
117 if (extnames[i]!=NULL && !ircd_strcmp(name,extnames[i]->content)) {
118 return i;
119 }
120 }
121
122 return -1;
123 }
124
125 void releasechanext(int index) {
126 int i;
127 chanindex *cip,*ncip;
128
129 freesstring(extnames[index]);
130 extnames[index]=NULL;
131
132 for (i=0;i<CHANNELHASHSIZE;i++) {
133 for (cip=chantable[i];cip;cip=ncip) {
134 /* CAREFUL: deleting items from chains you're walking is bad */
135 ncip=cip->next;
136 if (cip->exts[index]!=NULL) {
137 cip->exts[index]=NULL;
138 releasechanindex(cip);
139 }
140 }
141 }
142 }
143
144 unsigned int nextchanmarker() {
145 int i;
146 chanindex *cip;
147
148 channelmarker++;
149 if (!channelmarker) {
150 /* If we wrapped to zero, zap the marker on all records */
151 for (i=0;i<CHANNELHASHSIZE;i++)
152 for (cip=chantable[i];cip;cip=cip->next)
153 cip->marker=0;
154 channelmarker++;
155 }
156
157 return channelmarker;
158 }