purge #if sun's
[unix-history] / usr / src / old / dcheck / dcheck.c
CommitLineData
dbe5fd32 1static char *sccsid = "@(#)dcheck.c 2.3 (Berkeley) %G%";
e19a5dd5
KM
2/*
3 * dcheck - check directory consistency
4 */
5#define NB 10
c312eebd 6#define MAXNINDIR (MAXBSIZE / sizeof (daddr_t))
e19a5dd5 7
45eb394d
KM
8#ifndef SIMFS
9#include <sys/param.h>
10#include <sys/inode.h>
11#include <sys/fs.h>
dbe5fd32 12#include <dir.h>
45eb394d 13#else
e19a5dd5
KM
14#include "../h/param.h"
15#include "../h/inode.h"
e19a5dd5 16#include "../h/fs.h"
dbe5fd32 17#include "../h/ndir.h"
45eb394d 18#endif
5086d197 19#include <stdio.h>
e19a5dd5
KM
20
21union {
22 struct fs fs;
b6407c9d 23 char pad[MAXBSIZE];
e19a5dd5
KM
24} fsun;
25#define sblock fsun.fs
26
5086d197
KM
27struct dirstuff {
28 int loc;
29 struct dinode *ip;
30 char dbuf[MAXBSIZE];
31};
32
e19a5dd5 33struct dinode itab[MAXIPG];
56d45dcd 34struct dinode *gip;
e19a5dd5
KM
35ino_t ilist[NB];
36
37int fi;
38ino_t ino;
39ino_t *ecount;
40int headpr;
41int nfiles;
42
43int nerror;
44daddr_t bmap();
45long atol();
46char *malloc();
47
48main(argc, argv)
49char *argv[];
50{
51 register i;
52 long n;
53
54 while (--argc) {
55 argv++;
56 if (**argv=='-')
57 switch ((*argv)[1]) {
58
59 case 'i':
60 for(i=0; i<NB; i++) {
61 n = atol(argv[1]);
62 if(n == 0)
63 break;
64 ilist[i] = n;
65 argv++;
66 argc--;
67 }
68 ilist[i] = 0;
69 continue;
70
71 default:
72 printf("Bad flag %c\n", (*argv)[1]);
73 nerror++;
74 }
75 check(*argv);
76 }
77 return(nerror);
78}
79
80check(file)
81char *file;
82{
83 register i, j, c;
84
85 fi = open(file, 0);
86 if(fi < 0) {
87 printf("cannot open %s\n", file);
88 nerror++;
89 return;
90 }
91 headpr = 0;
92 printf("%s:\n", file);
93 sync();
c312eebd 94 bread(SBLOCK, (char *)&sblock, SBSIZE);
e19a5dd5
KM
95 if (sblock.fs_magic != FS_MAGIC) {
96 printf("%s: not a file system\n", file);
97 nerror++;
98 return;
99 }
100 nfiles = sblock.fs_ipg * sblock.fs_ncg;
e19a5dd5
KM
101 ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount));
102 if (ecount == 0) {
103 printf("%s: not enough core for %d files\n", file, nfiles);
104 exit(04);
105 }
106 for (i = 0; i<=nfiles; i++)
107 ecount[i] = 0;
108 ino = 0;
109 for (c = 0; c < sblock.fs_ncg; c++) {
6994bf5d 110 bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
e19a5dd5
KM
111 sblock.fs_ipg * sizeof (struct dinode));
112 for (j = 0; j < sblock.fs_ipg; j++) {
113 pass1(&itab[j]);
114 ino++;
115 }
116 }
117 ino = 0;
118 for (c = 0; c < sblock.fs_ncg; c++) {
6994bf5d 119 bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
e19a5dd5
KM
120 sblock.fs_ipg * sizeof (struct dinode));
121 for (j = 0; j < sblock.fs_ipg; j++) {
122 pass2(&itab[j]);
123 ino++;
124 }
125 }
126 free(ecount);
127}
128
129pass1(ip)
5086d197 130 register struct dinode *ip;
e19a5dd5 131{
5086d197
KM
132 register struct direct *dp;
133 struct dirstuff dirp;
e19a5dd5 134 int k;
e19a5dd5
KM
135
136 if((ip->di_mode&IFMT) != IFDIR)
137 return;
5086d197
KM
138 dirp.loc = 0;
139 dirp.ip = ip;
56d45dcd 140 gip = ip;
5086d197
KM
141 for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
142 if(dp->d_ino == 0)
143 continue;
144 if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) {
145 printf("%d bad; %d/%s\n",
146 dp->d_ino, ino, dp->d_name);
147 nerror++;
148 continue;
149 }
150 for (k = 0; ilist[k] != 0; k++)
151 if (ilist[k] == dp->d_ino) {
152 printf("%d arg; %d/%s\n",
153 dp->d_ino, ino, dp->d_name);
e19a5dd5 154 nerror++;
e19a5dd5 155 }
5086d197 156 ecount[dp->d_ino]++;
e19a5dd5
KM
157 }
158}
159
160pass2(ip)
161register struct dinode *ip;
162{
163 register i;
164
165 i = ino;
166 if ((ip->di_mode&IFMT)==0 && ecount[i]==0)
167 return;
168 if (ip->di_nlink==ecount[i] && ip->di_nlink!=0)
169 return;
170 if (headpr==0) {
171 printf(" entries link cnt\n");
172 headpr++;
173 }
174 printf("%u\t%d\t%d\n", ino,
175 ecount[i], ip->di_nlink);
176}
177
5086d197
KM
178/*
179 * get next entry in a directory.
180 */
181struct direct *
182readdir(dirp)
183 register struct dirstuff *dirp;
184{
185 register struct direct *dp;
186 daddr_t lbn, d;
187
188 for(;;) {
189 if (dirp->loc >= dirp->ip->di_size)
190 return NULL;
3352e84a 191 if ((lbn = lblkno(&sblock, dirp->loc)) == 0) {
5086d197
KM
192 d = bmap(lbn);
193 if(d == 0)
194 return NULL;
195 bread(fsbtodb(&sblock, d), dirp->dbuf,
196 dblksize(&sblock, dirp->ip, lbn));
197 }
198 dp = (struct direct *)
3352e84a 199 (dirp->dbuf + blkoff(&sblock, dirp->loc));
5086d197
KM
200 dirp->loc += dp->d_reclen;
201 if (dp->d_ino == 0)
202 continue;
203 return (dp);
204 }
205}
206
e19a5dd5
KM
207bread(bno, buf, cnt)
208daddr_t bno;
209char *buf;
210{
211 register i;
212
b6407c9d 213 lseek(fi, bno * DEV_BSIZE, 0);
e19a5dd5
KM
214 if (read(fi, buf, cnt) != cnt) {
215 printf("read error %d\n", bno);
b6407c9d 216 for(i=0; i < cnt; i++)
e19a5dd5
KM
217 buf[i] = 0;
218 }
219}
220
221daddr_t
222bmap(i)
223{
b6407c9d 224 daddr_t ibuf[MAXNINDIR];
e19a5dd5
KM
225
226 if(i < NDADDR)
56d45dcd 227 return(gip->di_db[i]);
e19a5dd5 228 i -= NDADDR;
b6407c9d 229 if(i > NINDIR(&sblock)) {
e19a5dd5
KM
230 printf("%u - huge directory\n", ino);
231 return((daddr_t)0);
232 }
b6407c9d 233 bread(fsbtodb(&sblock, gip->di_ib[0]), (char *)ibuf, sizeof(ibuf));
e19a5dd5
KM
234 return(ibuf[i]);
235}