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