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