|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #if defined(LIBC_SCCS) && !defined(lint) ! 21: static char sccsid[] = "@(#)telldir.c 5.8 (Berkeley) 6/1/90"; ! 22: #endif /* LIBC_SCCS and not lint */ ! 23: ! 24: #include <sys/param.h> ! 25: #include <dirent.h> ! 26: ! 27: /* ! 28: * The option SINGLEUSE may be defined to say that a telldir ! 29: * cookie may be used only once before it is freed. This option ! 30: * is used to avoid having memory usage grow without bound. ! 31: */ ! 32: #define SINGLEUSE ! 33: ! 34: /* ! 35: * One of these structures is malloced to describe the current directory ! 36: * position each time telldir is called. It records the current magic ! 37: * cookie returned by getdirentries and the offset within the buffer ! 38: * associated with that return value. ! 39: */ ! 40: struct ddloc { ! 41: struct ddloc *loc_next;/* next structure in list */ ! 42: long loc_index; /* key associated with structure */ ! 43: long loc_seek; /* magic cookie returned by getdirentries */ ! 44: long loc_loc; /* offset of entry in buffer */ ! 45: }; ! 46: ! 47: #define NDIRHASH 32 /* Num of hash lists, must be a power of 2 */ ! 48: #define LOCHASH(i) ((i)&(NDIRHASH-1)) ! 49: ! 50: static long dd_loccnt; /* Index of entry for sequential readdir's */ ! 51: static struct ddloc *dd_hash[NDIRHASH]; /* Hash list heads for ddlocs */ ! 52: ! 53: /* ! 54: * return a pointer into a directory ! 55: */ ! 56: long ! 57: telldir(dirp) ! 58: DIR *dirp; ! 59: { ! 60: register int index; ! 61: register struct ddloc *lp; ! 62: ! 63: if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL) ! 64: return (-1); ! 65: index = dd_loccnt++; ! 66: lp->loc_index = index; ! 67: lp->loc_seek = dirp->dd_seek; ! 68: lp->loc_loc = dirp->dd_loc; ! 69: lp->loc_next = dd_hash[LOCHASH(index)]; ! 70: dd_hash[LOCHASH(index)] = lp; ! 71: return (index); ! 72: } ! 73: ! 74: /* ! 75: * seek to an entry in a directory. ! 76: * Only values returned by "telldir" should be passed to seekdir. ! 77: */ ! 78: void ! 79: _seekdir(dirp, loc) ! 80: register DIR *dirp; ! 81: long loc; ! 82: { ! 83: register struct ddloc *lp; ! 84: register struct ddloc **prevlp; ! 85: struct dirent *dp; ! 86: extern long lseek(); ! 87: ! 88: prevlp = &dd_hash[LOCHASH(loc)]; ! 89: lp = *prevlp; ! 90: while (lp != NULL) { ! 91: if (lp->loc_index == loc) ! 92: break; ! 93: prevlp = &lp->loc_next; ! 94: lp = lp->loc_next; ! 95: } ! 96: if (lp == NULL) ! 97: return; ! 98: if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek) ! 99: goto found; ! 100: (void) lseek(dirp->dd_fd, lp->loc_seek, 0); ! 101: dirp->dd_seek = lp->loc_seek; ! 102: dirp->dd_loc = 0; ! 103: while (dirp->dd_loc < lp->loc_loc) { ! 104: dp = readdir(dirp); ! 105: if (dp == NULL) ! 106: break; ! 107: } ! 108: found: ! 109: #ifdef SINGLEUSE ! 110: *prevlp = lp->loc_next; ! 111: free((caddr_t)lp); ! 112: #endif ! 113: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.