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