|
|
1.1 root 1: /* @(#)test6.c 1.4 90/01/03 NFS Rev 2 Testsuite
2: * 1.4 Lachman ONC Test Suite source
3: *
4: * Test readdir
5: *
6: * Uses the following important system/library calls against the server:
7: *
8: * chdir()
9: * mkdir() (for initial directory creation if not -m)
10: * creat()
11: * unlink()
12: * opendir(), rewinddir(), readdir(), closedir()
13: */
14:
15: #include <sys/param.h>
16: #ifndef major
17: #include <sys/types.h>
18: #endif
19: #ifdef SVR3
20: #include <sys/fs/nfs/time.h>
21: #include <dirent.h>
22: #else
23: #include <sys/time.h>
24: #ifndef vax
25: #include <sys/dir.h>
26: #else
27: #include <dirent.h>
28: #endif
29: #endif
30: #include <stdio.h>
31: #include "tests.h"
32:
33: int Tflag = 0; /* print timing */
34: int Hflag = 0; /* print help message */
35: int Fflag = 0; /* test function only; set count to 1, negate -t */
36: int Nflag = 0; /* Suppress directory operations */
37: int Iflag = 0; /* Ignore non-test files dir entries */
38:
39: #define MAXFILES 512 /* maximum files allowed for this test */
40: #define BITMOD 8 /* bits per u_char */
41: #ifdef SVR3
42: unchar bitmap[MAXFILES / BITMOD];
43: #else
44: u_char bitmap[MAXFILES / BITMOD];
45: #endif
46: #define BIT(x) (bitmap[(x) / BITMOD] & (1 << ((x) % BITMOD)) )
47: #define SETBIT(x) (bitmap[(x) / BITMOD] |= (1 << ((x) % BITMOD)) )
48: #define CLRBIT(x) (bitmap[(x) / BITMOD] &= ~(1 << ((x) % BITMOD)) )
49:
50: usage()
51: {
52: fprintf(stdout, "usage: %s [-htfni] [files count fname]\n", Myname);
53: fprintf(stdout, " Flags: h Help - print this usage info\n");
54: fprintf(stdout, " t Print execution time statistics\n");
55: fprintf(stdout, " f Test function only (negate -t)\n");
56: fprintf(stdout, " n Suppress test directory create operations\n");
57: fprintf(stdout, " i Ignore non-test files dir entries\n");
58: }
59:
60: main(argc, argv)
61: int argc;
62: char *argv[];
63: {
64: #ifdef SVR3
65: struct dirent *dp;
66: #else
67: #ifndef vax
68: struct direct *dp;
69: #else
70: struct dirent *dp;
71: #endif
72: #endif
73: char *fname = FNAME;
74: int files = 200; /* number of files in each dir */
75: int fi;
76: int count = 200; /* times to read dir */
77: int ct;
78: int entries = 0;
79: int totfiles = 0;
80: int totdirs = 0;
81: DIR *dir;
82: struct timeval time;
83: char *p, str[MAXPATHLEN];
84: char *opts;
85: int err, i, dot, dotdot;
86: int nmoffset;
87:
88: umask(0);
89: setbuf(stdout, NULL);
90: Myname = *argv++;
91: argc--;
92: while (argc && **argv == '-') {
93: for (opts = &argv[0][1]; *opts; opts++) {
94: switch (*opts) {
95: case 'h': /* help */
96: usage();
97: exit(1);
98:
99: case 't': /* time */
100: Tflag++;
101: break;
102:
103: case 'f': /* funtionality */
104: Fflag++;
105: break;
106:
107: case 'n': /* No Test Directory create */
108: Nflag++;
109: break;
110:
111: case 'i': /* ignore spurious files */
112: Iflag++;
113: break;
114:
115: default:
116: error("unknown option '%c'", *opts);
117: usage();
118: exit(1);
119: }
120: }
121: argc--;
122: argv++;
123: }
124:
125: if (argc) {
126: files = getparm(*argv, 1, "files");
127: argv++;
128: argc--;
129: }
130: if (argc) {
131: count = getparm(*argv, 1, "count");
132: argv++;
133: argc--;
134: }
135: if (argc) {
136: fname = *argv;
137: argv++;
138: argc--;
139: }
140: if (argc) {
141: usage();
142: exit(1);
143: }
144:
145: nmoffset = strlen(fname);
146:
147: if (Fflag) {
148: Tflag = 0;
149: count = 1;
150: }
151:
152: if (count > files) {
153: error("count (%d) can't be greater than files (%d)",
154: count, files);
155: exit(1);
156: }
157:
158: if (files > MAXFILES) {
159: error("too many files requested (max is %d)", MAXFILES);
160: exit(1);
161: }
162:
163: fprintf(stdout, "%s: readdir\n", Myname);
164:
165: if (!Nflag)
166: testdir(NULL);
167: else
168: mtestdir(NULL);
169:
170: dirtree(1, files, 0, fname, DNAME, &totfiles, &totdirs);
171:
172: if (Tflag) {
173: starttime();
174: }
175:
176: if ((dir = opendir(".")) == NULL) {
177: error("can't opendir %s", ".");
178: exit(1);
179: }
180:
181: for (ct = 0; ct < count; ct++) {
182: rewinddir(dir);
183: dot = 0;
184: dotdot = 0;
185: err = 0;
186: for (i = 0; i < sizeof(bitmap); i++)
187: bitmap[i] = 0;
188: while ((dp = readdir(dir)) != NULL) {
189: entries++;
190: if (strcmp(".", dp->d_name) == 0) {
191: if (dot) {
192: /* already read dot */
193: error("'.' dir entry read twice");
194: exit(1);
195: }
196: dot++;
197: continue;
198: } else if (strcmp("..", dp->d_name) == 0) {
199: if (dotdot) {
200: /* already read dotdot */
201: error("'..' dir entry read twice");
202: exit(1);
203: }
204: dotdot++;
205: continue;
206: }
207:
208: /*
209: * at this point, should have entry of the form
210: * fname%d
211: */
212: /* If we don't have our own directory, ignore
213: such errors (if Iflag set). */
214: if (strncmp(dp->d_name, fname, nmoffset)) {
215: if (Iflag)
216: continue;
217: else {
218: error("unexpected dir entry '%s'",
219: dp->d_name);
220: exit(1);
221: }
222: }
223:
224: /* get ptr to numeric part of name */
225: p = dp->d_name + nmoffset;
226: fi = atoi(p);
227: if (fi < 0 || fi >= MAXFILES) {
228: error("unexpected dir entry '%s'",
229: dp->d_name);
230: exit(1);
231: }
232: if (BIT(fi)) {
233: error("duplicate '%s' dir entry read",
234: dp->d_name);
235: err++;
236: } else
237: SETBIT(fi);
238: } /* end readdir loop */
239: if (!dot) {
240: error("didn't read '.' dir entry, pass %d", ct);
241: err++;
242: }
243: if (!dotdot) {
244: error("didn't read '..' dir entry, pass %d", ct);
245: err++;
246: }
247: for (fi = 0; fi < ct; fi++) {
248: if (BIT(fi)) {
249: sprintf(str, "%s%d", fname, fi);
250: error("unlinked '%s' dir entry read pass %d",
251: str, ct);
252: err++;
253: }
254: }
255: for (fi = ct; fi < files; fi++) {
256: if (!BIT(fi)) {
257: sprintf(str, "%s%d", fname, fi);
258: error("\
259: didn't read expected '%s' dir entry, pass %d", str, ct);
260: err++;
261: }
262: }
263: if (err) {
264: error("Test failed with %d errors", err);
265: exit(1);
266: }
267: sprintf(str, "%s%d", fname, ct);
268: if (unlink(str) < 0) {
269: error("can't unlink %s", str);
270: exit(1);
271: }
272: }
273:
274: closedir(dir);
275:
276: if (Tflag) {
277: endtime(&time);
278: }
279: fprintf(stdout, "\t%d entries read, %d files",
280: entries, files);
281: if (Tflag) {
282: fprintf(stdout, " in %d.%-2d seconds",
283: time.tv_sec, time.tv_usec / 10000);
284: }
285: fprintf(stdout, "\n");
286: rmdirtree(1, files, 0, fname, DNAME, &totfiles, &totdirs, 1);
287: complete();
288: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.