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