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