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