|
|
1.1 ! root 1: # To unbundle, sh this file ! 2: echo closedir.c 1>&2 ! 3: sed 's/.//' >closedir.c <<'//GO.SYSIN DD closedir.c' ! 4: -/* Copyright (c) 1982 Regents of the University of California */ ! 5: - ! 6: - ! 7: -#include <ndir.h> ! 8: - ! 9: -/* ! 10: - * close a directory. ! 11: - */ ! 12: -void ! 13: -closedir(dirp) ! 14: - register DIR *dirp; ! 15: -{ ! 16: - close(dirp->dd_fd); ! 17: - free(dirp); ! 18: -} ! 19: //GO.SYSIN DD closedir.c ! 20: echo ndir.h 1>&2 ! 21: sed 's/.//' >ndir.h <<'//GO.SYSIN DD ndir.h' ! 22: -/* Copyright (c) 1982 Regents of the University of California */ ! 23: -/* and modified by pjw in 1986 */ ! 24: - ! 25: -/* ! 26: - * this must be a power of 2 and a multiple of all the ones in the system ! 27: - */ ! 28: -#define DIRBLKSIZ 512 ! 29: - ! 30: -/* ! 31: - * This limits the directory name length. Its main constraint ! 32: - * is that it appears twice in the user structure. (u. area) in bsd systems ! 33: - */ ! 34: -#define MAXNAMLEN 255 ! 35: - ! 36: -struct direct { ! 37: - unsigned long d_ino; ! 38: - short d_reclen; ! 39: - short d_namlen; ! 40: - char d_name[MAXNAMLEN + 1]; ! 41: - /* typically shorter */ ! 42: -}; ! 43: - ! 44: -struct _dirdesc { ! 45: - int dd_fd; ! 46: - long dd_loc; /* where we left off in dd_buf */ ! 47: - long dd_size; /* bytes back from system */ ! 48: - long dd_offset; /* lseek at beginning of dd_buf */ ! 49: - char dd_buf[DIRBLKSIZ]; ! 50: -}; ! 51: - ! 52: -/* ! 53: - * useful macros. ! 54: - */ ! 55: -#define NDIRSIZ(dp) \ ! 56: - ((sizeof(struct direct) - MAXNAMLEN + (dp)->d_namlen + sizeof(ino_t) - 1) &\ ! 57: - ~(sizeof(ino_t) - 1)) ! 58: -typedef struct _dirdesc DIR; ! 59: -#ifndef NULL ! 60: -#define NULL 0 ! 61: -#endif ! 62: - ! 63: -/* ! 64: - * functions defined on directories ! 65: - */ ! 66: -extern DIR *opendir(); ! 67: -extern struct direct *readdir(); ! 68: -extern long telldir(); ! 69: -extern void seekdir(); ! 70: -#define rewinddir(dirp) seekdir((dirp), 0) ! 71: -extern void closedir(); ! 72: //GO.SYSIN DD ndir.h ! 73: echo opendir.c 1>&2 ! 74: sed 's/.//' >opendir.c <<'//GO.SYSIN DD opendir.c' ! 75: -/* Copyright (c) 1982 Regents of the University of California and pjw*/ ! 76: - ! 77: - ! 78: -#include "errno.h" ! 79: -#include "ndir.h" ! 80: - ! 81: -/* ! 82: - * open a directory. ! 83: - */ ! 84: -DIR * ! 85: -opendir(name) ! 86: - char *name; ! 87: -{ ! 88: - register DIR *dirp; ! 89: - ! 90: - dirp = (DIR *)malloc(sizeof(DIR)); ! 91: - if(!dirp) { ! 92: - errno = ENOSPC; ! 93: - return(0); ! 94: - } ! 95: - dirp->dd_fd = open(name, 0); ! 96: - if (dirp->dd_fd == -1) { ! 97: - free(dirp); ! 98: - return NULL; ! 99: - } ! 100: - dirp->dd_loc = 0; ! 101: - dirp->dd_offset = 0; ! 102: - dirp->dd_size = 0; ! 103: - return dirp; ! 104: -} ! 105: //GO.SYSIN DD opendir.c ! 106: echo pdirread.c 1>&2 ! 107: sed 's/.//' >pdirread.c <<'//GO.SYSIN DD pdirread.c' ! 108: -/* simulate new system call */ ! 109: -/* output is up to cnt bytes (up to some max) ! 110: - * each directory entry gets a string which is ! 111: - * the ascii representation of the inode number, a tab, and the ! 112: - * zero-terminated file name. these zero-terminated strings are packed together ! 113: - * This implementation freely returns short reads. End of directory ! 114: - * is a 0 length read, -1 and ENOSPC indicate that cnt couldn't hold ! 115: - * even the next entry ! 116: - */ ! 117: -#include "sys/types.h" ! 118: -#include "sys/dir.h" ! 119: -#include "errno.h" ! 120: - ! 121: -char mb[4096], ncnv[23]; ! 122: -pdirread(fd, buf, cnt) ! 123: -char *buf; ! 124: -{ int n, m, j, loc; ! 125: - char *p, *lp; ! 126: - struct direct *d; ! 127: - ! 128: - loc = lseek(fd, 0, 1); ! 129: - n = read(fd, mb, sizeof(mb)); ! 130: - if(n <= 0) ! 131: - return(n); ! 132: - lp = p = buf; ! 133: - d = (struct direct *) mb; ! 134: -loop: ! 135: - if(d->d_ino == 0) ! 136: - goto incr; ! 137: - for(m = d->d_ino, j = 22; m; j--) { ! 138: - ncnv[j] = m % 10 + '0'; ! 139: - m /= 10; ! 140: - } ! 141: - for(++j; j < 23 && p < buf + cnt; ) ! 142: - *p++ = ncnv[j++]; ! 143: - if(j != 23 || p >= buf + cnt) ! 144: - goto early; ! 145: - *p++ = '\t'; ! 146: - for(j = 0; d->d_name[j] && j < DIRSIZ && p < buf + cnt; j++) ! 147: - *p++ = d->d_name[j]; ! 148: - if(p >= buf + cnt) ! 149: - goto early; ! 150: - *p++ = 0; ! 151: -incr: ! 152: - lp = p; ! 153: - n -= sizeof(*d); ! 154: - d++; ! 155: - if(lp < buf + cnt && n > 0) ! 156: - goto loop; ! 157: -done: ! 158: - lseek(fd, loc + (char *)d - mb, 0); ! 159: - return(lp - buf); ! 160: -early: ! 161: - *lp = 0; ! 162: - if((char *)d != mb) ! 163: - goto done; ! 164: - errno = ENOSPC; ! 165: - return(-1); ! 166: -} ! 167: //GO.SYSIN DD pdirread.c ! 168: echo readdir.c 1>&2 ! 169: sed 's/.//' >readdir.c <<'//GO.SYSIN DD readdir.c' ! 170: -/* Copyright (c) 1982 Regents of the University of California */ ! 171: -/* and modified by pjw in 1986 and 1987, dmg in 1989 */ ! 172: - ! 173: -#include <sys/types.h> /* only for ino_t */ ! 174: -#include "ndir.h" ! 175: -#include <ctype.h> ! 176: - ! 177: -/* ! 178: - * get next entry in a directory. ! 179: - * ! 180: - * subtlety: ! 181: - * ino_t is still a 16-bit type, ! 182: - * but i-numbers returned by dirread or pdirread may be larger. ! 183: - * stat returns an ino_t in st_ino. ! 184: - * d_ino is a long. ! 185: - * if d_ino has 32 significant bits, programs like pwd may fail. ! 186: - * if it is truncated to 16, information is lost. ! 187: - * it would be helpful to fix stat, but it wouldn't be a magic cure; ! 188: - * the i-number from dirread may have more than 32 bits! ! 189: - * truncate for now, via dir.d_ino = (ino_t) ... ! 190: - * ! 191: - * most of the tedious code below is error checking ! 192: - */ ! 193: -struct direct * ! 194: -readdir(dirp) ! 195: -register DIR *dirp; ! 196: -{ ! 197: - static struct direct dir; ! 198: - register char *p; ! 199: - register int i; ! 200: - ! 201: -loop: ! 202: - if (dirp->dd_size <= 0 || dirp->dd_loc >= dirp->dd_size) { ! 203: - dirp->dd_offset++; /* see seekdir.c */ ! 204: - dirp->dd_size = dirread(dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ-1); ! 205: - if(dirp->dd_size < 0) ! 206: - dirp->dd_size = pdirread(dirp->dd_fd, dirp->dd_buf, ! 207: - DIRBLKSIZ-1); ! 208: - if(dirp->dd_size <= 0) ! 209: - return(0); ! 210: - dirp->dd_loc = 0; ! 211: - dirp->dd_buf[dirp->dd_size] = 0; /* sentinel */ ! 212: - } ! 213: - p = dirp->dd_buf + dirp->dd_loc; ! 214: - dir.d_ino = 0; ! 215: - while (isdigit(*p)) ! 216: - dir.d_ino = dir.d_ino*10 + *p++ - '0'; ! 217: - dir.d_ino = (ino_t)dir.d_ino; ! 218: - while (*p != '\t') /* in case we add fields someday */ ! 219: - if (*p++ == 0) { /* badly formed */ ! 220: - dirp->dd_loc = p - dirp->dd_buf; ! 221: - goto loop; ! 222: - } ! 223: - p++; ! 224: - for (i = 0; i < MAXNAMLEN; i++) ! 225: - if ((dir.d_name[i] = *p++) == 0) ! 226: - break; ! 227: - if (i >= MAXNAMLEN && *p++ != 0) { /* name too long */ ! 228: - while (*p++) ! 229: - ; ! 230: - dirp->dd_loc = p - dirp->dd_buf; ! 231: - goto loop; ! 232: - } ! 233: - dir.d_name[i] = 0; ! 234: - dir.d_namlen = i; ! 235: - dir.d_reclen = sizeof(dir); /* bogus, but who cares? */ ! 236: - dirp->dd_loc = p - dirp->dd_buf; ! 237: - if (dirp->dd_loc > dirp->dd_size) /* hit the sentinel */ ! 238: - goto loop; ! 239: - return (&dir); ! 240: -} ! 241: //GO.SYSIN DD readdir.c ! 242: echo seekdir.c 1>&2 ! 243: sed 's/.//' >seekdir.c <<'//GO.SYSIN DD seekdir.c' ! 244: -/* Copyright (c) 1982 Regents of the University of California ! 245: - * and modified by pjw in 1987 */ ! 246: - ! 247: -#include "ndir.h" ! 248: - ! 249: -/* ! 250: - * seek to an entry in a directory. ! 251: - * ! 252: - * offset `told' is interpreted in a non-obvious way: ! 253: - * telldir computes it as dd_offset*DIRBLKSIZ + dd_loc ! 254: - * dd_loc is the byte offset into the current dd_buf contents; ! 255: - * dd_offset is the number of times dirread(fd, buf, DIRBLKSIZ) ! 256: - * must be called to reproduce the same buffer. ! 257: - * ! 258: - * Why not just use lseek? Because told isn't a seek offset, ! 259: - * and cannot conveniently be turned into one: the byte count ! 260: - * in dd_loc is unrelated to the seek offset required to reach ! 261: - * lseek(fd, 0L, 1)+dd_loc, because the seek offset refers to the raw ! 262: - * directory, but dirread has reformatted the data. ! 263: - * One might let dd_offset be the seek offset to the the beginning ! 264: - * of dd_buf, compute told the same way, and let seekdir become ! 265: - * lseek(fd, told/DIRBLKSIZ, 0); dirp->dd_loc = told%DIRBLKSIZ; ! 266: - * but a somewhat strident prior implementor worries that this unfairly ! 267: - * constrains the size of directories. This is probably a silly worry ! 268: - * (will any real system have directories a megabyte long?) but it ! 269: - * doesn't matter much except in programs that use seekdir a lot. ! 270: - */ ! 271: -void ! 272: -seekdir(dirp, told) ! 273: -register DIR *dirp; ! 274: -long told; ! 275: -{ long offset; ! 276: - ! 277: - offset = told / DIRBLKSIZ; ! 278: - dirp->dd_loc = told % DIRBLKSIZ; ! 279: - if (offset < dirp->dd_offset) ! 280: - lseek(dirp->dd_fd, dirp->dd_offset = 0L, 0); ! 281: - if(offset > dirp->dd_offset) { ! 282: - do { ! 283: - dirp->dd_size = dirread(dirp->dd_fd, dirp->dd_buf, ! 284: - DIRBLKSIZ); ! 285: - if(dirp->dd_size < 0) ! 286: - dirp->dd_size = pdirread(dirp->dd_fd, ! 287: - dirp->dd_buf, DIRBLKSIZ); ! 288: - } ! 289: - while(++dirp->dd_offset < offset); ! 290: - } ! 291: -} ! 292: //GO.SYSIN DD seekdir.c ! 293: echo telldir.c 1>&2 ! 294: sed 's/.//' >telldir.c <<'//GO.SYSIN DD telldir.c' ! 295: -/* Copyright (c) 1982 Regents of the University of California ! 296: - * and modified by pjw in 1987 */ ! 297: - ! 298: -#include "ndir.h" ! 299: - ! 300: -/* ! 301: - * return a pointer into a directory ! 302: - * see seekdir.c for an explanation of the return value ! 303: - */ ! 304: -long ! 305: -telldir(dirp) ! 306: - DIR *dirp; ! 307: -{ ! 308: - return(DIRBLKSIZ * dirp->dd_offset + dirp->dd_loc); ! 309: -} ! 310: //GO.SYSIN DD telldir.c
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.