|
|
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.