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