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