|
|
1.1 ! root 1: /* Copyright (c) 1982 Regents of the University of California */ ! 2: /* and modified by pjw in 1986 and 1987, dmg in 1989 */ ! 3: ! 4: #include <sys/types.h> /* only for ino_t */ ! 5: #include "ndir.h" ! 6: #include <ctype.h> ! 7: ! 8: /* ! 9: * get next entry in a directory. ! 10: * ! 11: * subtlety: ! 12: * ino_t is still a 16-bit type, ! 13: * but i-numbers returned by dirread or pdirread may be larger. ! 14: * stat returns an ino_t in st_ino. ! 15: * d_ino is a long. ! 16: * if d_ino has 32 significant bits, programs like pwd may fail. ! 17: * if it is truncated to 16, information is lost. ! 18: * it would be helpful to fix stat, but it wouldn't be a magic cure; ! 19: * the i-number from dirread may have more than 32 bits! ! 20: * truncate for now, via dir.d_ino = (ino_t) ... ! 21: * ! 22: * most of the tedious code below is error checking ! 23: */ ! 24: struct direct * ! 25: readdir(dirp) ! 26: register DIR *dirp; ! 27: { ! 28: static struct direct dir; ! 29: register char *p; ! 30: register int i; ! 31: ! 32: loop: ! 33: if (dirp->dd_size <= 0 || dirp->dd_loc >= dirp->dd_size) { ! 34: dirp->dd_offset++; /* see seekdir.c */ ! 35: dirp->dd_size = dirread(dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ-1); ! 36: if(dirp->dd_size < 0) ! 37: dirp->dd_size = pdirread(dirp->dd_fd, dirp->dd_buf, ! 38: DIRBLKSIZ-1); ! 39: if(dirp->dd_size <= 0) ! 40: return(0); ! 41: dirp->dd_loc = 0; ! 42: dirp->dd_buf[dirp->dd_size] = 0; /* sentinel */ ! 43: } ! 44: p = dirp->dd_buf + dirp->dd_loc; ! 45: dir.d_ino = 0; ! 46: while (isdigit(*p)) ! 47: dir.d_ino = dir.d_ino*10 + *p++ - '0'; ! 48: dir.d_ino = (ino_t)dir.d_ino; ! 49: while (*p != '\t') /* in case we add fields someday */ ! 50: if (*p++ == 0) { /* badly formed */ ! 51: dirp->dd_loc = p - dirp->dd_buf; ! 52: goto loop; ! 53: } ! 54: p++; ! 55: for (i = 0; i < MAXNAMLEN; i++) ! 56: if ((dir.d_name[i] = *p++) == 0) ! 57: break; ! 58: if (i >= MAXNAMLEN && *p++ != 0) { /* name too long */ ! 59: while (*p++) ! 60: ; ! 61: dirp->dd_loc = p - dirp->dd_buf; ! 62: goto loop; ! 63: } ! 64: dir.d_name[i] = 0; ! 65: dir.d_namlen = i; ! 66: dir.d_reclen = sizeof(dir); /* bogus, but who cares? */ ! 67: dirp->dd_loc = p - dirp->dd_buf; ! 68: if (dirp->dd_loc > dirp->dd_size) /* hit the sentinel */ ! 69: goto loop; ! 70: return (&dir); ! 71: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.