xref: /netbsd-src/external/gpl2/xcvs/dist/contrib/dirfns.shar (revision a7c918477dd5f12c1da816ba05caf44eab2d06d6)
1*a7c91847Schristosecho 'directory.3':
2*a7c91847Schristossed 's/^X//' >'directory.3' <<'!'
3*a7c91847SchristosX.TH DIRECTORY 3 imported
4*a7c91847SchristosX.DA 9 Oct 1985
5*a7c91847SchristosX.SH NAME
6*a7c91847SchristosXopendir, readdir, telldir, seekdir, rewinddir, closedir \- high-level directory operations
7*a7c91847SchristosX.SH SYNOPSIS
8*a7c91847SchristosX.B #include <sys/types.h>
9*a7c91847SchristosX.br
10*a7c91847SchristosX.B #include <ndir.h>
11*a7c91847SchristosX.PP
12*a7c91847SchristosX.SM
13*a7c91847SchristosX.B DIR
14*a7c91847SchristosX.B *opendir(filename)
15*a7c91847SchristosX.br
16*a7c91847SchristosX.B char *filename;
17*a7c91847SchristosX.PP
18*a7c91847SchristosX.SM
19*a7c91847SchristosX.B struct direct
20*a7c91847SchristosX.B *readdir(dirp)
21*a7c91847SchristosX.br
22*a7c91847SchristosX.B DIR *dirp;
23*a7c91847SchristosX.PP
24*a7c91847SchristosX.SM
25*a7c91847SchristosX.B long
26*a7c91847SchristosX.B telldir(dirp)
27*a7c91847SchristosX.br
28*a7c91847SchristosX.B DIR *dirp;
29*a7c91847SchristosX.PP
30*a7c91847SchristosX.SM
31*a7c91847SchristosX.B seekdir(dirp, loc)
32*a7c91847SchristosX.br
33*a7c91847SchristosX.B DIR *dirp;
34*a7c91847SchristosX.br
35*a7c91847SchristosX.B long loc;
36*a7c91847SchristosX.PP
37*a7c91847SchristosX.SM
38*a7c91847SchristosX.B rewinddir(dirp)
39*a7c91847SchristosX.br
40*a7c91847SchristosX.B DIR *dirp;
41*a7c91847SchristosX.PP
42*a7c91847SchristosX.SM
43*a7c91847SchristosX.B closedir(dirp)
44*a7c91847SchristosX.br
45*a7c91847SchristosX.B DIR *dirp;
46*a7c91847SchristosX.SH DESCRIPTION
47*a7c91847SchristosXThis library provides high-level primitives for directory scanning,
48*a7c91847SchristosXsimilar to those available for 4.2BSD's (very different) directory system.
49*a7c91847SchristosX.\"The purpose of this library is to simulate
50*a7c91847SchristosX.\"the new flexible length directory names of 4.2bsd UNIX
51*a7c91847SchristosX.\"on top of the old directory structure of v7.
52*a7c91847SchristosXIt incidentally provides easy portability to and from 4.2BSD (insofar
53*a7c91847SchristosXas such portability is not compromised by other 4.2/VAX dependencies).
54*a7c91847SchristosX.\"It allows programs to be converted immediately
55*a7c91847SchristosX.\"to the new directory access interface,
56*a7c91847SchristosX.\"so that they need only be relinked
57*a7c91847SchristosX.\"when moved to 4.2bsd.
58*a7c91847SchristosX.\"It is obtained with the loader option
59*a7c91847SchristosX.\".BR \-lndir .
60*a7c91847SchristosX.PP
61*a7c91847SchristosX.I Opendir
62*a7c91847SchristosXopens the directory named by
63*a7c91847SchristosX.I filename
64*a7c91847SchristosXand associates a
65*a7c91847SchristosX.I directory stream
66*a7c91847SchristosXwith it.
67*a7c91847SchristosX.I Opendir
68*a7c91847SchristosXreturns a pointer to be used to identify the
69*a7c91847SchristosX.I directory stream
70*a7c91847SchristosXin subsequent operations.
71*a7c91847SchristosXThe pointer
72*a7c91847SchristosX.SM
73*a7c91847SchristosX.B NULL
74*a7c91847SchristosXis returned if
75*a7c91847SchristosX.I filename
76*a7c91847SchristosXcannot be accessed or is not a directory.
77*a7c91847SchristosX.PP
78*a7c91847SchristosX.I Readdir
79*a7c91847SchristosXreturns a pointer to the next directory entry.
80*a7c91847SchristosXIt returns
81*a7c91847SchristosX.B NULL
82*a7c91847SchristosXupon reaching the end of the directory or detecting
83*a7c91847SchristosXan invalid
84*a7c91847SchristosX.I seekdir
85*a7c91847SchristosXoperation.
86*a7c91847SchristosX.PP
87*a7c91847SchristosX.I Telldir
88*a7c91847SchristosXreturns the current location associated with the named
89*a7c91847SchristosX.I directory stream.
90*a7c91847SchristosX.PP
91*a7c91847SchristosX.I Seekdir
92*a7c91847SchristosXsets the position of the next
93*a7c91847SchristosX.I readdir
94*a7c91847SchristosXoperation on the
95*a7c91847SchristosX.I directory stream.
96*a7c91847SchristosXThe new position reverts to the one associated with the
97*a7c91847SchristosX.I directory stream
98*a7c91847SchristosXwhen the
99*a7c91847SchristosX.I telldir
100*a7c91847SchristosXoperation was performed.
101*a7c91847SchristosXValues returned by
102*a7c91847SchristosX.I telldir
103*a7c91847SchristosXare good only for the lifetime of the DIR pointer from
104*a7c91847SchristosXwhich they are derived.
105*a7c91847SchristosXIf the directory is closed and then reopened,
106*a7c91847SchristosXthe
107*a7c91847SchristosX.I telldir
108*a7c91847SchristosXvalue may be invalidated
109*a7c91847SchristosXdue to undetected directory compaction in 4.2BSD.
110*a7c91847SchristosXIt is safe to use a previous
111*a7c91847SchristosX.I telldir
112*a7c91847SchristosXvalue immediately after a call to
113*a7c91847SchristosX.I opendir
114*a7c91847SchristosXand before any calls to
115*a7c91847SchristosX.I readdir.
116*a7c91847SchristosX.PP
117*a7c91847SchristosX.I Rewinddir
118*a7c91847SchristosXresets the position of the named
119*a7c91847SchristosX.I directory stream
120*a7c91847SchristosXto the beginning of the directory.
121*a7c91847SchristosX.PP
122*a7c91847SchristosX.I Closedir
123*a7c91847SchristosXcauses the named
124*a7c91847SchristosX.I directory stream
125*a7c91847SchristosXto be closed,
126*a7c91847SchristosXand the structure associated with the DIR pointer to be freed.
127*a7c91847SchristosX.PP
128*a7c91847SchristosXA
129*a7c91847SchristosX.I direct
130*a7c91847SchristosXstructure is as follows:
131*a7c91847SchristosX.PP
132*a7c91847SchristosX.RS
133*a7c91847SchristosX.nf
134*a7c91847SchristosXstruct	direct {
135*a7c91847SchristosX	/* unsigned */ long	d_ino;	/* inode number of entry */
136*a7c91847SchristosX	unsigned short	d_reclen;	/* length of this record */
137*a7c91847SchristosX	unsigned short	d_namlen;	/* length of string in d_name */
138*a7c91847SchristosX	char	d_name[MAXNAMLEN + 1];	/* name must be no longer than this */
139*a7c91847SchristosX};
140*a7c91847SchristosX.fi
141*a7c91847SchristosX.RE
142*a7c91847SchristosX.PP
143*a7c91847SchristosXThe
144*a7c91847SchristosX.I d_reclen
145*a7c91847SchristosXfield is meaningless in non-4.2BSD systems and should be ignored.
146*a7c91847SchristosXThe use of a
147*a7c91847SchristosX.I long
148*a7c91847SchristosXfor
149*a7c91847SchristosX.I d_ino
150*a7c91847SchristosXis also a 4.2BSDism;
151*a7c91847SchristosX.I ino_t
152*a7c91847SchristosX(see
153*a7c91847SchristosX.IR types (5))
154*a7c91847SchristosXshould be used elsewhere.
155*a7c91847SchristosXThe macro
156*a7c91847SchristosX.I DIRSIZ(dp)
157*a7c91847SchristosXgives the minimum memory size needed to hold the
158*a7c91847SchristosX.I direct
159*a7c91847SchristosXvalue pointed to by
160*a7c91847SchristosX.IR dp ,
161*a7c91847SchristosXwith the minimum necessary allocation for
162*a7c91847SchristosX.IR d_name .
163*a7c91847SchristosX.PP
164*a7c91847SchristosXThe preferred way to search the current directory for entry ``name'' is:
165*a7c91847SchristosX.PP
166*a7c91847SchristosX.RS
167*a7c91847SchristosX.nf
168*a7c91847SchristosX	len = strlen(name);
169*a7c91847SchristosX	dirp = opendir(".");
170*a7c91847SchristosX	if (dirp == NULL) {
171*a7c91847SchristosX		fprintf(stderr, "%s: can't read directory .\\n", argv[0]);
172*a7c91847SchristosX		return NOT_FOUND;
173*a7c91847SchristosX	}
174*a7c91847SchristosX	while ((dp = readdir(dirp)) != NULL)
175*a7c91847SchristosX		if (dp->d_namlen == len && strcmp(dp->d_name, name) == 0) {
176*a7c91847SchristosX			closedir(dirp);
177*a7c91847SchristosX			return FOUND;
178*a7c91847SchristosX		}
179*a7c91847SchristosX	closedir(dirp);
180*a7c91847SchristosX	return NOT_FOUND;
181*a7c91847SchristosX.RE
182*a7c91847SchristosX.\".SH LINKING
183*a7c91847SchristosX.\"This library is accessed by specifying ``-lndir'' as the
184*a7c91847SchristosX.\"last argument to the compile line, e.g.:
185*a7c91847SchristosX.\".PP
186*a7c91847SchristosX.\"	cc -I/usr/include/ndir -o prog prog.c -lndir
187*a7c91847SchristosX.SH "SEE ALSO"
188*a7c91847SchristosXopen(2),
189*a7c91847SchristosXclose(2),
190*a7c91847SchristosXread(2),
191*a7c91847SchristosXlseek(2)
192*a7c91847SchristosX.SH HISTORY
193*a7c91847SchristosXWritten by
194*a7c91847SchristosXKirk McKusick at Berkeley (ucbvax!mckusick).
195*a7c91847SchristosXMiscellaneous bug fixes from elsewhere.
196*a7c91847SchristosXThe size of the data structure has been decreased to avoid excessive
197*a7c91847SchristosXspace waste under V7 (where filenames are 14 characters at most).
198*a7c91847SchristosXFor obscure historical reasons, the include file is also available
199*a7c91847SchristosXas
200*a7c91847SchristosX.IR <ndir/sys/dir.h> .
201*a7c91847SchristosXThe Berkeley version lived in a separate library (\fI\-lndir\fR),
202*a7c91847SchristosXwhereas ours is
203*a7c91847SchristosXpart of the C library, although the separate library is retained to
204*a7c91847SchristosXmaximize compatibility.
205*a7c91847SchristosX.PP
206*a7c91847SchristosXThis manual page has been substantially rewritten to be informative in
207*a7c91847SchristosXthe absence of a 4.2BSD manual.
208*a7c91847SchristosX.SH BUGS
209*a7c91847SchristosXThe
210*a7c91847SchristosX.I DIRSIZ
211*a7c91847SchristosXmacro actually wastes a bit of space due to some padding requirements
212*a7c91847SchristosXthat are an artifact of 4.2BSD.
213*a7c91847SchristosX.PP
214*a7c91847SchristosXThe returned value of
215*a7c91847SchristosX.I readdir
216*a7c91847SchristosXpoints to a static area that will be overwritten by subsequent calls.
217*a7c91847SchristosX.PP
218*a7c91847SchristosXThere are some unfortunate name conflicts with the \fIreal\fR V7
219*a7c91847SchristosXdirectory structure definitions.
220*a7c91847Schristos!
221*a7c91847Schristosecho 'dir.h':
222*a7c91847Schristossed 's/^X//' >'dir.h' <<'!'
223*a7c91847SchristosX/*	dir.h	4.4	82/07/25	*/
224*a7c91847SchristosX
225*a7c91847SchristosX/*
226*a7c91847SchristosX * A directory consists of some number of blocks of DIRBLKSIZ
227*a7c91847SchristosX * bytes, where DIRBLKSIZ is chosen such that it can be transferred
228*a7c91847SchristosX * to disk in a single atomic operation (e.g. 512 bytes on most machines).
229*a7c91847SchristosX *
230*a7c91847SchristosX * Each DIRBLKSIZ byte block contains some number of directory entry
231*a7c91847SchristosX * structures, which are of variable length.  Each directory entry has
232*a7c91847SchristosX * a struct direct at the front of it, containing its inode number,
233*a7c91847SchristosX * the length of the entry, and the length of the name contained in
234*a7c91847SchristosX * the entry.  These are followed by the name padded to a 4 byte boundary
235*a7c91847SchristosX * with null bytes.  All names are guaranteed null terminated.
236*a7c91847SchristosX * The maximum length of a name in a directory is MAXNAMLEN.
237*a7c91847SchristosX *
238*a7c91847SchristosX * The macro DIRSIZ(dp) gives the amount of space required to represent
239*a7c91847SchristosX * a directory entry.  Free space in a directory is represented by
240*a7c91847SchristosX * entries which have dp->d_reclen >= DIRSIZ(dp).  All DIRBLKSIZ bytes
241*a7c91847SchristosX * in a directory block are claimed by the directory entries.  This
242*a7c91847SchristosX * usually results in the last entry in a directory having a large
243*a7c91847SchristosX * dp->d_reclen.  When entries are deleted from a directory, the
244*a7c91847SchristosX * space is returned to the previous entry in the same directory
245*a7c91847SchristosX * block by increasing its dp->d_reclen.  If the first entry of
246*a7c91847SchristosX * a directory block is free, then its dp->d_ino is set to 0.
247*a7c91847SchristosX * Entries other than the first in a directory do not normally have
248*a7c91847SchristosX * dp->d_ino set to 0.
249*a7c91847SchristosX */
250*a7c91847SchristosX#define DIRBLKSIZ	512
251*a7c91847SchristosX#ifdef VMUNIX
252*a7c91847SchristosX#define	MAXNAMLEN	255
253*a7c91847SchristosX#else
254*a7c91847SchristosX#define	MAXNAMLEN	14
255*a7c91847SchristosX#endif
256*a7c91847SchristosX
257*a7c91847SchristosXstruct	direct {
258*a7c91847SchristosX	/* unsigned */ long	d_ino;	/* inode number of entry */
259*a7c91847SchristosX	unsigned short	d_reclen;	/* length of this record */
260*a7c91847SchristosX	unsigned short	d_namlen;	/* length of string in d_name */
261*a7c91847SchristosX	char	d_name[MAXNAMLEN + 1];	/* name must be no longer than this */
262*a7c91847SchristosX};
263*a7c91847SchristosX
264*a7c91847SchristosX/*
265*a7c91847SchristosX * The DIRSIZ macro gives the minimum record length which will hold
266*a7c91847SchristosX * the directory entry.  This requires the amount of space in struct direct
267*a7c91847SchristosX * without the d_name field, plus enough space for the name with a terminating
268*a7c91847SchristosX * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
269*a7c91847SchristosX */
270*a7c91847SchristosX#undef DIRSIZ
271*a7c91847SchristosX#define DIRSIZ(dp) \
272*a7c91847SchristosX    ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
273*a7c91847SchristosX
274*a7c91847SchristosX#ifndef KERNEL
275*a7c91847SchristosX/*
276*a7c91847SchristosX * Definitions for library routines operating on directories.
277*a7c91847SchristosX */
278*a7c91847SchristosXtypedef struct _dirdesc {
279*a7c91847SchristosX	int	dd_fd;
280*a7c91847SchristosX	long	dd_loc;
281*a7c91847SchristosX	long	dd_size;
282*a7c91847SchristosX	char	dd_buf[DIRBLKSIZ];
283*a7c91847SchristosX} DIR;
284*a7c91847SchristosX#ifndef NULL
285*a7c91847SchristosX#define NULL 0
286*a7c91847SchristosX#endif
287*a7c91847SchristosXextern	DIR *opendir();
288*a7c91847SchristosXextern	struct direct *readdir();
289*a7c91847SchristosXextern	long telldir();
290*a7c91847SchristosX#ifdef void
291*a7c91847SchristosXextern	void seekdir();
292*a7c91847SchristosXextern	void closedir();
293*a7c91847SchristosX#endif
294*a7c91847SchristosX#define rewinddir(dirp)	seekdir((dirp), (long)0)
295*a7c91847SchristosX#endif KERNEL
296*a7c91847Schristos!
297*a7c91847Schristosecho 'makefile':
298*a7c91847Schristossed 's/^X//' >'makefile' <<'!'
299*a7c91847SchristosXDIR = closedir.o opendir.o readdir.o seekdir.o telldir.o
300*a7c91847SchristosXCFLAGS=-O -I. -Dvoid=int
301*a7c91847SchristosXDEST=..
302*a7c91847SchristosX
303*a7c91847SchristosXall:	$(DIR)
304*a7c91847SchristosX
305*a7c91847SchristosXmv:	$(DIR)
306*a7c91847SchristosX	mv $(DIR) $(DEST)
307*a7c91847SchristosX
308*a7c91847SchristosXcpif:	dir.h
309*a7c91847SchristosX	cp dir.h /usr/include/ndir.h
310*a7c91847SchristosX
311*a7c91847SchristosXclean:
312*a7c91847SchristosX	rm -f *.o
313*a7c91847Schristos!
314*a7c91847Schristosecho 'closedir.c':
315*a7c91847Schristossed 's/^X//' >'closedir.c' <<'!'
316*a7c91847SchristosXstatic char sccsid[] = "@(#)closedir.c 4.2 3/10/82";
317*a7c91847SchristosX
318*a7c91847SchristosX#include <sys/types.h>
319*a7c91847SchristosX#include <dir.h>
320*a7c91847SchristosX
321*a7c91847SchristosX/*
322*a7c91847SchristosX * close a directory.
323*a7c91847SchristosX */
324*a7c91847SchristosXvoid
325*a7c91847SchristosXclosedir(dirp)
326*a7c91847SchristosX	register DIR *dirp;
327*a7c91847SchristosX{
328*a7c91847SchristosX	close(dirp->dd_fd);
329*a7c91847SchristosX	dirp->dd_fd = -1;
330*a7c91847SchristosX	dirp->dd_loc = 0;
331*a7c91847SchristosX	free((char *)dirp);
332*a7c91847SchristosX}
333*a7c91847Schristos!
334*a7c91847Schristosecho 'opendir.c':
335*a7c91847Schristossed 's/^X//' >'opendir.c' <<'!'
336*a7c91847SchristosX/* Copyright (c) 1982 Regents of the University of California */
337*a7c91847SchristosX
338*a7c91847SchristosXstatic char sccsid[] = "@(#)opendir.c 4.4 11/12/82";
339*a7c91847SchristosX
340*a7c91847SchristosX#include <sys/types.h>
341*a7c91847SchristosX#include <sys/stat.h>
342*a7c91847SchristosX#include <dir.h>
343*a7c91847SchristosX
344*a7c91847SchristosX/*
345*a7c91847SchristosX * open a directory.
346*a7c91847SchristosX */
347*a7c91847SchristosXDIR *
348*a7c91847SchristosXopendir(name)
349*a7c91847SchristosX	char *name;
350*a7c91847SchristosX{
351*a7c91847SchristosX	register DIR *dirp;
352*a7c91847SchristosX	register int fd;
353*a7c91847SchristosX	struct stat statbuf;
354*a7c91847SchristosX	char *malloc();
355*a7c91847SchristosX
356*a7c91847SchristosX	if ((fd = open(name, 0)) == -1)
357*a7c91847SchristosX		return NULL;
358*a7c91847SchristosX	if (fstat(fd, &statbuf) == -1 || !(statbuf.st_mode & S_IFDIR)) {
359*a7c91847SchristosX		close(fd);
360*a7c91847SchristosX		return NULL;
361*a7c91847SchristosX	}
362*a7c91847SchristosX	if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
363*a7c91847SchristosX		close (fd);
364*a7c91847SchristosX		return NULL;
365*a7c91847SchristosX	}
366*a7c91847SchristosX	dirp->dd_fd = fd;
367*a7c91847SchristosX	dirp->dd_loc = 0;
368*a7c91847SchristosX	dirp->dd_size = 0;	/* so that telldir will work before readdir */
369*a7c91847SchristosX	return dirp;
370*a7c91847SchristosX}
371*a7c91847Schristos!
372*a7c91847Schristosecho 'readdir.c':
373*a7c91847Schristossed 's/^X//' >'readdir.c' <<'!'
374*a7c91847SchristosX/* Copyright (c) 1982 Regents of the University of California */
375*a7c91847SchristosX
376*a7c91847SchristosXstatic char sccsid[] = "@(#)readdir.c 4.3 8/8/82";
377*a7c91847SchristosX
378*a7c91847SchristosX#include <sys/types.h>
379*a7c91847SchristosX#include <dir.h>
380*a7c91847SchristosX
381*a7c91847SchristosX/*
382*a7c91847SchristosX * read an old stlye directory entry and present it as a new one
383*a7c91847SchristosX */
384*a7c91847SchristosX#define	ODIRSIZ	14
385*a7c91847SchristosX
386*a7c91847SchristosXstruct	olddirect {
387*a7c91847SchristosX	ino_t	od_ino;
388*a7c91847SchristosX	char	od_name[ODIRSIZ];
389*a7c91847SchristosX};
390*a7c91847SchristosX
391*a7c91847SchristosX/*
392*a7c91847SchristosX * get next entry in a directory.
393*a7c91847SchristosX */
394*a7c91847SchristosXstruct direct *
395*a7c91847SchristosXreaddir(dirp)
396*a7c91847SchristosX	register DIR *dirp;
397*a7c91847SchristosX{
398*a7c91847SchristosX	register struct olddirect *dp;
399*a7c91847SchristosX	static struct direct dir;
400*a7c91847SchristosX
401*a7c91847SchristosX	for (;;) {
402*a7c91847SchristosX		if (dirp->dd_loc == 0) {
403*a7c91847SchristosX			dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf,
404*a7c91847SchristosX			    DIRBLKSIZ);
405*a7c91847SchristosX			if (dirp->dd_size <= 0) {
406*a7c91847SchristosX				dirp->dd_size = 0;
407*a7c91847SchristosX				return NULL;
408*a7c91847SchristosX			}
409*a7c91847SchristosX		}
410*a7c91847SchristosX		if (dirp->dd_loc >= dirp->dd_size) {
411*a7c91847SchristosX			dirp->dd_loc = 0;
412*a7c91847SchristosX			continue;
413*a7c91847SchristosX		}
414*a7c91847SchristosX		dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
415*a7c91847SchristosX		dirp->dd_loc += sizeof(struct olddirect);
416*a7c91847SchristosX		if (dp->od_ino == 0)
417*a7c91847SchristosX			continue;
418*a7c91847SchristosX		dir.d_ino = dp->od_ino;
419*a7c91847SchristosX		strncpy(dir.d_name, dp->od_name, ODIRSIZ);
420*a7c91847SchristosX		dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
421*a7c91847SchristosX		dir.d_namlen = strlen(dir.d_name);
422*a7c91847SchristosX		dir.d_reclen = DIRBLKSIZ;
423*a7c91847SchristosX		return (&dir);
424*a7c91847SchristosX	}
425*a7c91847SchristosX}
426*a7c91847Schristos!
427*a7c91847Schristosecho 'seekdir.c':
428*a7c91847Schristossed 's/^X//' >'seekdir.c' <<'!'
429*a7c91847SchristosXstatic char sccsid[] = "@(#)seekdir.c 4.9 3/25/83";
430*a7c91847SchristosX
431*a7c91847SchristosX#include <sys/param.h>
432*a7c91847SchristosX#include <dir.h>
433*a7c91847SchristosX
434*a7c91847SchristosX/*
435*a7c91847SchristosX * seek to an entry in a directory.
436*a7c91847SchristosX * Only values returned by "telldir" should be passed to seekdir.
437*a7c91847SchristosX */
438*a7c91847SchristosXvoid
439*a7c91847SchristosXseekdir(dirp, loc)
440*a7c91847SchristosX	register DIR *dirp;
441*a7c91847SchristosX	long loc;
442*a7c91847SchristosX{
443*a7c91847SchristosX	long curloc, base, offset;
444*a7c91847SchristosX	struct direct *dp;
445*a7c91847SchristosX	extern long lseek();
446*a7c91847SchristosX
447*a7c91847SchristosX	curloc = telldir(dirp);
448*a7c91847SchristosX	if (loc == curloc)
449*a7c91847SchristosX		return;
450*a7c91847SchristosX	base = loc & ~(DIRBLKSIZ - 1);
451*a7c91847SchristosX	offset = loc & (DIRBLKSIZ - 1);
452*a7c91847SchristosX	(void) lseek(dirp->dd_fd, base, 0);
453*a7c91847SchristosX	dirp->dd_size = 0;
454*a7c91847SchristosX	dirp->dd_loc = 0;
455*a7c91847SchristosX	while (dirp->dd_loc < offset) {
456*a7c91847SchristosX		dp = readdir(dirp);
457*a7c91847SchristosX		if (dp == NULL)
458*a7c91847SchristosX			return;
459*a7c91847SchristosX	}
460*a7c91847SchristosX}
461*a7c91847Schristos!
462*a7c91847Schristosecho 'telldir.c':
463*a7c91847Schristossed 's/^X//' >'telldir.c' <<'!'
464*a7c91847SchristosXstatic char sccsid[] = "@(#)telldir.c 4.1 2/21/82";
465*a7c91847SchristosX
466*a7c91847SchristosX#include <sys/types.h>
467*a7c91847SchristosX#include <dir.h>
468*a7c91847SchristosX
469*a7c91847SchristosX/*
470*a7c91847SchristosX * return a pointer into a directory
471*a7c91847SchristosX */
472*a7c91847SchristosXlong
473*a7c91847SchristosXtelldir(dirp)
474*a7c91847SchristosX	DIR *dirp;
475*a7c91847SchristosX{
476*a7c91847SchristosX	long lseek();
477*a7c91847SchristosX
478*a7c91847SchristosX	return (lseek(dirp->dd_fd, 0L, 1) - dirp->dd_size + dirp->dd_loc);
479*a7c91847SchristosX}
480*a7c91847Schristos!
481*a7c91847Schristosecho done
482