]> jfr.im git - irc/quakenet/newserv.git/blame - fsck/fsck.c
longtoduration formats 0 and 1 back to how they were.
[irc/quakenet/newserv.git] / fsck / fsck.c
CommitLineData
c86edd1d
Q
1/* fsck.c - check some internal structures */
2
3#include "../control/control.h"
4#include "../nick/nick.h"
5#include "../channel/channel.h"
6#include "../server/server.h"
7
8int dofsck(void *source, int cargc, char **cargv);
9
10void _init() {
3e3692bf 11 registercontrolhelpcmd("fsck",NO_DEVELOPER,0,dofsck, "Usage: fsck\nRuns internal structure check.");
c86edd1d
Q
12}
13
14void _fini() {
15 deregistercontrolcmd("fsck",dofsck);
16}
17
18int dofsck(void *source, int cargc, char **cargv) {
19 int i,j;
20 nick *sender=source, *np, *np2;
21 host *hp;
22 realname *rnp;
23 unsigned int nickmarker;
24 int errors=0;
4d306551 25 unsigned int nummask,mnum;
c86edd1d
Q
26
27 /* Start off with strict nick consistency checks.. */
28
29 controlreply(sender,"- Performing nickname checks");
30
31 nickmarker=nextnickmarker();
32
33 for(i=0;i<HOSTHASHSIZE;i++)
34 for(hp=hosttable[i];hp;hp=hp->next)
35 hp->marker=0;
36
37 for(i=0;i<REALNAMEHASHSIZE;i++)
38 for(rnp=realnametable[i];rnp;rnp=rnp->next)
39 rnp->marker=0;
40
41 controlreply(sender," - Scanning nick hash table");
42
43 for (i=0;i<NICKHASHSIZE;i++) {
44 for(np=nicktable[i];np;np=np->next) {
387ae2f3 45 if (np->marker==nickmarker) {
46 controlreply(sender, "ERROR: bumped into the same nick %s/%s twice in hash table.",longtonumeric(np->numeric,5),np->nick);
47 errors++;
48 }
49
c86edd1d
Q
50 /* Mark this nick so we can check we found them all */
51 np->marker=nickmarker;
52
53 /* Check that we can find this nick with the lookup functions */
54 if (getnickbynick(np->nick) != np) {
55 controlreply(sender, "ERROR: can't find %s/%s using getnickbynick().",
56 longtonumeric(np->numeric,5),np->nick);
57 errors++;
58 }
59
60 if (getnickbynumeric(np->numeric) != np) {
61 controlreply(sender, "ERROR: can't find %s/%s using getnickbynumeric().",
62 longtonumeric(np->numeric,5),np->nick);
63 errors++;
64 }
65
66 /* Check that the nick appears in the list of nicks using its host */
67 if (findhost(np->host->name->content) != np->host) {
68 controlreply(sender, "ERROR: can't find %s/%s's host (%s) using findhost().",
69 longtonumeric(np->numeric,5),np->nick,np->host->name->content);
70 errors++;
71 }
72
73 for(np2=np->host->nicks;np2;np2=np2->nextbyhost)
74 if (np2==np)
75 break;
76
77 if (!np2) {
78 controlreply(sender, "ERROR: can't find %s/%s (host=%s) on the host users list.",
79 longtonumeric(np->numeric,5),np->nick,np->host->name->content);
80 errors++;
81 }
82
83 np->host->marker++;
84
85 /* Same for realnames */
86 if (findrealname(np->realname->name->content) != np->realname) {
87 controlreply(sender, "ERROR: can't find %s/%s's realname (%s) using findrealname().",
88 longtonumeric(np->numeric,5),np->nick,np->realname->name->content);
89 errors++;
90 }
91
92 for(np2=np->realname->nicks;np2;np2=np2->nextbyrealname)
93 if (np2==np)
94 break;
95
96 if (!np2) {
97 controlreply(sender,
98 "ERROR: can't find %s/%s (realname=%s) on the realname users list.",
99 longtonumeric(np->numeric,5),np->nick,np->realname->name->content);
100 errors++;
101 }
102
103 np->realname->marker++;
104
105 if (IsAccount(np) && !np->authname[0]) {
106 controlreply(sender, "ERROR: nick %s/%s is +r but no authname stored.",
107 longtonumeric(np->numeric,5),np->nick);
108 errors++;
109 }
110
111/*
112 if (!IsAccount(np) && np->authname[0]) {
113 controlreply(sender, "ERROR: nick %s/%s is -r but carries authname '%s'.",
114 longtonumeric(np->numeric,5),np->nick,np->authname);
115 errors++;
116 }
117*/
118
119 if (IsSetHost(np) && (!np->sethost || !np->shident)) {
120 controlreply(sender, "ERROR: nick %s/%s is +h but nick or hostname not set.",
121 longtonumeric(np->numeric,5),np->nick);
122 errors++;
123 }
124
125 if (!IsSetHost(np) && (np->sethost || np->shident)) {
126 controlreply(sender, "ERROR: nick %s/%s is -h but has nick or hostname set.",
127 longtonumeric(np->numeric,5),np->nick);
128 errors++;
129 }
130
131 }
132 }
133
134 controlreply(sender," - Scanning server user tables");
135
136 for(i=0;i<MAXSERVERS;i++) {
137 if (serverlist[i].linkstate != LS_INVALID) {
4d306551 138 nummask=((MAXSERVERS-1)<<18) | serverlist[i].maxusernum;
c86edd1d
Q
139 for (j=0;j<=serverlist[i].maxusernum;j++) {
140 if ((np=servernicks[i][j])) {
4d306551 141 mnum=(i<<18) | j;
142 if ((np->numeric & nummask) != mnum) {
143 controlreply(sender, "ERROR: nick %s/%s has wrong masked numeric.",longtonumeric(np->numeric,5),np->nick);
144 errors++;
145 }
c86edd1d
Q
146 if (np->marker != nickmarker) {
147 controlreply(sender, "ERROR: nick %s/%s in server user table but not hash!",
148 longtonumeric(np->numeric,5),np->nick);
149 errors++;
150 }
387ae2f3 151 np->marker=0;
c86edd1d
Q
152 }
153 }
154 }
155 }
156
157 controlreply(sender," - Scanning host and realname tables");
158
159 for (i=0;i<HOSTHASHSIZE;i++) {
160 for (hp=hosttable[i];hp;hp=hp->next) {
161
162 /* Check that the user counts match up */
163 if (hp->clonecount != hp->marker) {
164 controlreply(sender,
165 "ERROR: host %s has inconsistent clone count (stored=%d, measured=%u)",
166 hp->name->content,hp->clonecount,hp->marker);
167 errors++;
168 }
169
170 for (np=hp->nicks;np;np=np->nextbyhost) {
171 if (np->host != hp) {
172 controlreply(sender,
173 "ERROR: nick %s/%s is in list for wrong host "
174 "(in list for %s, actual host %s).",
175 longtonumeric(np->numeric,5),np->nick,hp->name->content,
176 np->host->name->content);
177 errors++;
178 }
179 }
180
181 hp->marker=0;
182 }
183 }
184
185 for (i=0;i<REALNAMEHASHSIZE;i++) {
186 for (rnp=realnametable[i];rnp;rnp=rnp->next) {
187 if (rnp->usercount != rnp->marker) {
188 controlreply(sender,
189 "ERROR: realname '%s' has inconsistent clone count "
190 "(stored=%d, measured=%d).",
191 rnp->name->content,rnp->usercount,rnp->marker);
192 errors++;
193 }
194
195 for (np=rnp->nicks;np;np=np->nextbyrealname) {
196 if (np->realname != rnp) {
197 controlreply(sender,
198 "ERROR: nick %s/%s is in list for wrong realname "
199 "(in list for '%s', actual realname '%s').",
200 longtonumeric(np->numeric,5),np->nick,
201 rnp->name->content, np->realname->name->content);
202 errors++;
203 }
204 }
205
206 rnp->marker=0;
207 }
208 }
209
210 if (errors)
211 controlreply(sender,"All checks complete. %d errors found.",errors);
212 else
213 controlreply(sender,"All checks complete. No errors found.");
214
215 return CMD_OK;
216}
217