]> jfr.im git - irc/quakenet/newserv.git/blame - channel/channelindex.c
Cleanup old svn tags and add proper build id's.
[irc/quakenet/newserv.git] / channel / channelindex.c
CommitLineData
c86edd1d
Q
1/* channelindex.c */
2
3#include "channel.h"
4#include "../irc/irc_config.h"
5#include "../lib/irc_string.h"
6#include <stdio.h>
4ad1cf7a 7#include <string.h>
c86edd1d
Q
8
9#define channelhash(x) (crc32i(x)%CHANNELHASHSIZE)
10
11chanindex *chantable[CHANNELHASHSIZE];
12sstring *extnames[MAXCHANNELEXTS];
13
14unsigned int channelmarker;
15
16void initchannelindex() {
17 memset(chantable,0,sizeof(chantable));
18 memset(extnames,0,sizeof(extnames));
19 channelmarker=0;
20}
21
22chanindex *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
35chanindex *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
61void 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
94int 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
113int 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
125void 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
144unsigned 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}