Remove the attic.
This commit is contained in:
parent
59dbdea48a
commit
fd94e219d4
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
closedir -- close a directory stream
|
||||
|
||||
last edit: 11-Nov-1988 D A Gwyn
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
typedef void* pointer; /* (void *) if you have it */
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
int _close(int d);
|
||||
|
||||
int closedir(register DIR* dirp) /* stream from opendir */
|
||||
{
|
||||
register int fd;
|
||||
|
||||
if (dirp == NULL || dirp->dd_buf == NULL)
|
||||
{
|
||||
errno = EFAULT;
|
||||
return -1; /* invalid pointer */
|
||||
}
|
||||
|
||||
fd = dirp->dd_fd; /* bug fix thanks to R. Salz */
|
||||
free((pointer)dirp->dd_buf);
|
||||
free((pointer)dirp);
|
||||
return _close(fd);
|
||||
}
|
|
@ -1,292 +0,0 @@
|
|||
/*
|
||||
getdents -- get directory entries in a file system independent format
|
||||
(SVR3 system call emulation)
|
||||
|
||||
last edit: 06-Jul-1987 D A Gwyn
|
||||
|
||||
This single source file supports several different methods of
|
||||
getting directory entries from the operating system. Define
|
||||
whichever one of the following describes your system:
|
||||
|
||||
UFS original UNIX filesystem (14-character name limit)
|
||||
BFS 4.2BSD (also 4.3BSD) native filesystem (long names)
|
||||
NFS getdirentries() system call
|
||||
|
||||
Also define any of the following that are pertinent:
|
||||
|
||||
ATT_SPEC check user buffer address for longword alignment
|
||||
BSD_SYSV BRL UNIX System V emulation environment on 4.nBSD
|
||||
UNK have _getdents() system call, but kernel may not
|
||||
support it
|
||||
|
||||
If your C library has a getdents() system call interface, but you
|
||||
can't count on all kernels on which your application binaries may
|
||||
run to support it, change the system call interface name to
|
||||
_getdents() and define "UNK" to enable the system-call validity
|
||||
test in this "wrapper" around _getdents().
|
||||
|
||||
If your system has a getdents() system call that is guaranteed
|
||||
to always work, you shouldn't be using this source file at all.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef BSD_SYSV
|
||||
#include <sys/_dir.h> /* BSD flavor, not System V */
|
||||
#else
|
||||
#if defined(UFS)
|
||||
#define DIRSIZ 14 /* 14 char filename in Version 7 */
|
||||
#endif
|
||||
#define MAXNAMLEN 255
|
||||
struct direct
|
||||
{
|
||||
off_t d_off; /* offset of next disk directory entry */
|
||||
u_long d_fileno; /* file number of entry */
|
||||
u_short d_reclen; /* length of this record */
|
||||
u_short d_namlen; /* length of string in d_name */
|
||||
char d_name[MAXNAMLEN + 1]; /* name (up to MAXNAMLEN + 1) */
|
||||
};
|
||||
#undef MAXNAMLEN /* avoid conflict with SVR3 */
|
||||
|
||||
#define d_ino d_fileno /* compatability */
|
||||
|
||||
#ifdef d_ino /* 4.3BSD/NFS using d_fileno */
|
||||
#undef d_ino /* (not absolutely necessary) */
|
||||
#else
|
||||
#define d_fileno d_ino /* (struct direct) member */
|
||||
#endif
|
||||
#endif
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef UNK
|
||||
#ifndef UFS
|
||||
#error UNK applies only to UFS
|
||||
/* One could do something similar for getdirentries(), but I didn't bother. */
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#if defined(UFS) + defined(BFS) + defined(NFS) != 1 /* sanity check */
|
||||
#error exactly one of UFS, BFS, or NFS must be defined
|
||||
#endif
|
||||
|
||||
#ifdef UFS
|
||||
#define RecLen(dp) (sizeof(struct direct)) /* fixed-length entries */
|
||||
#else /* BFS || NFS */
|
||||
#define RecLen(dp) ((dp)->d_reclen) /* variable-length entries */
|
||||
#endif
|
||||
|
||||
#ifdef NFS
|
||||
#ifdef BSD_SYSV
|
||||
#define getdirentries _getdirentries /* package hides this system call */
|
||||
#endif
|
||||
extern int getdirentries(int fd, char* buf, int nbytes, long* basep);
|
||||
static long dummy; /* getdirentries() needs basep */
|
||||
#define GetBlock(fd, buf, n) getdirentries(fd, buf, (unsigned)n, &dummy)
|
||||
#else /* UFS || BFS */
|
||||
#ifdef BSD_SYSV
|
||||
#define read _read /* avoid emulation overhead */
|
||||
#endif
|
||||
extern int read();
|
||||
#define GetBlock(fd, buf, n) read(fd, buf, (unsigned)n)
|
||||
#endif
|
||||
|
||||
#ifdef UNK
|
||||
extern int _getdents(); /* actual system call */
|
||||
#endif
|
||||
|
||||
extern int _fstat(int fd, struct stat* buf);
|
||||
extern off_t _lseek(int d, int offset, int whence);
|
||||
|
||||
#ifndef DIRBLKSIZ
|
||||
#define DIRBLKSIZ 4096 /* directory file read buffer size */
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_CUR
|
||||
#define SEEK_CUR 1
|
||||
#endif
|
||||
|
||||
#ifndef S_ISDIR /* macro to test for directory file */
|
||||
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
#ifdef UFS
|
||||
|
||||
/*
|
||||
The following routine is necessary to handle DIRSIZ-long entry names.
|
||||
Thanks to Richard Todd for pointing this out.
|
||||
*/
|
||||
|
||||
static int
|
||||
NameLen(char name[]) /* return # chars in embedded name */
|
||||
/* -> name embedded in struct direct */
|
||||
{
|
||||
register char* s; /* -> name[.] */
|
||||
register char* stop = &name[DIRSIZ]; /* -> past end of name field */
|
||||
|
||||
for (s = &name[1]; /* (empty names are impossible) */
|
||||
*s != '\0' /* not NUL terminator */
|
||||
&& ++s < stop; /* < DIRSIZ characters scanned */
|
||||
)
|
||||
;
|
||||
|
||||
return s - name; /* # valid characters in name */
|
||||
}
|
||||
|
||||
#else /* BFS || NFS */
|
||||
|
||||
#define NameLen(name) strlen(name) /* names are always NUL-terminated */
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef UNK
|
||||
static enum { maybe,
|
||||
no,
|
||||
yes } state
|
||||
= maybe;
|
||||
/* does _getdents() work? */
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
sig_catch(int sig) /* sig must be SIGSYS */
|
||||
{
|
||||
state = no; /* attempted _getdents() faulted */
|
||||
}
|
||||
#endif
|
||||
|
||||
int getdents(int fildes, char* buf, unsigned nbyte) /* returns # bytes read;
|
||||
0 on EOF, -1 on error */
|
||||
/* fildes == directory file descriptor */
|
||||
/* *buf == where to put the (struct dirent)s */
|
||||
/* nbyte == size of buf[] */
|
||||
{
|
||||
int serrno; /* entry errno */
|
||||
off_t offset; /* initial directory file offset */
|
||||
struct stat statb; /* fstat() info */
|
||||
union {
|
||||
char dblk[DIRBLKSIZ];
|
||||
/* directory file block buffer */
|
||||
struct direct dummy; /* just for alignment */
|
||||
} u; /* (avoids having to malloc()) */
|
||||
register struct direct* dp; /* -> u.dblk[.] */
|
||||
register struct dirent* bp; /* -> buf[.] */
|
||||
|
||||
#ifdef UNK
|
||||
switch (state)
|
||||
{
|
||||
void (*shdlr)(); /* entry SIGSYS handler */
|
||||
register int retval; /* return from _getdents() if any */
|
||||
|
||||
case yes: /* _getdents() is known to work */
|
||||
return _getdents(fildes, buf, nbyte);
|
||||
|
||||
case maybe: /* first time only */
|
||||
shdlr = signal(SIGSYS, sig_catch);
|
||||
retval = _getdents(fildes, buf, nbyte); /* try it */
|
||||
(void)signal(SIGSYS, shdlr);
|
||||
|
||||
if (state == maybe) /* SIGSYS did not occur */
|
||||
{
|
||||
state = yes; /* so _getdents() must have worked */
|
||||
return retval;
|
||||
}
|
||||
/* else fall through into emulation */
|
||||
|
||||
/* case no:*/ /* fall through into emulation */
|
||||
}
|
||||
#endif
|
||||
|
||||
if (buf == NULL
|
||||
#ifdef ATT_SPEC
|
||||
|| (unsigned long)buf % sizeof(long) != 0 /* ugh */
|
||||
#endif
|
||||
)
|
||||
{
|
||||
errno = EFAULT; /* invalid pointer */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_fstat(fildes, &statb) != 0)
|
||||
return -1; /* errno set by fstat() */
|
||||
|
||||
if (!S_ISDIR(statb.st_mode))
|
||||
{
|
||||
errno = ENOTDIR; /* not a directory */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((offset = _lseek(fildes, (off_t)0, SEEK_CUR)) < 0)
|
||||
return -1; /* errno set by lseek() */
|
||||
|
||||
#ifdef BFS /* no telling what remote hosts do */
|
||||
if ((unsigned long)offset % DIRBLKSIZ != 0)
|
||||
{
|
||||
errno = ENOENT; /* file pointer probably misaligned */
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
serrno = errno; /* save entry errno */
|
||||
|
||||
for (bp = (struct dirent*)buf; bp == (struct dirent*)buf;)
|
||||
{ /* convert next directory block */
|
||||
int size;
|
||||
|
||||
do
|
||||
size = GetBlock(fildes, u.dblk, DIRBLKSIZ);
|
||||
while (size == -1 && errno == EINTR);
|
||||
|
||||
if (size <= 0)
|
||||
return size; /* EOF or error (EBADF) */
|
||||
|
||||
for (dp = (struct direct*)u.dblk;
|
||||
(char*)dp < &u.dblk[size];
|
||||
dp = (struct direct*)((char*)dp + RecLen(dp)))
|
||||
{
|
||||
#ifndef UFS
|
||||
if (dp->d_reclen <= 0)
|
||||
{
|
||||
errno = EIO; /* corrupted directory */
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dp->d_fileno != 0)
|
||||
{ /* non-empty; copy to user buffer */
|
||||
register int reclen = DIRENTSIZ(NameLen(dp->d_name));
|
||||
|
||||
if ((char*)bp + reclen > &buf[nbyte])
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1; /* buf too small */
|
||||
}
|
||||
|
||||
bp->d_ino = dp->d_fileno;
|
||||
bp->d_off = offset + ((char*)dp - u.dblk);
|
||||
bp->d_reclen = reclen;
|
||||
(void)strncpy(bp->d_name, dp->d_name,
|
||||
reclen - DIRENTBASESIZ); /* adds NUL padding */
|
||||
|
||||
bp = (struct dirent*)((char*)bp + reclen);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BFS /* 4.2BSD screwed up; fixed in 4.3BSD */
|
||||
if ((char*)dp > &u.dblk[size])
|
||||
{
|
||||
errno = EIO; /* corrupted directory */
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
errno = serrno; /* restore entry errno */
|
||||
return (char*)bp - buf; /* return # bytes read */
|
||||
}
|
|
@ -1,134 +0,0 @@
|
|||
/*
|
||||
* getgrent - get entry form group file
|
||||
*
|
||||
* Author: Patrick van Kleef
|
||||
*/
|
||||
/* $Id$ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <grp.h>
|
||||
|
||||
#define O_RDONLY 0
|
||||
|
||||
int open(const char* path, int flags);
|
||||
|
||||
#if defined(__BSD4_2)
|
||||
typedef int off_t; /* see lseek(2) */
|
||||
#else
|
||||
typedef long off_t;
|
||||
#endif
|
||||
|
||||
off_t _lseek(int d, off_t offset, int whence);
|
||||
int _read(int d, char* buf, int nbytes);
|
||||
int _close(int d);
|
||||
|
||||
#define RBUFSIZE 1024
|
||||
static char _gr_file[] = "/etc/group";
|
||||
static char _grbuf[256];
|
||||
static char _buffer[RBUFSIZE];
|
||||
static char* _pnt;
|
||||
static char* _buf;
|
||||
static int _gfd = -1;
|
||||
static int _bufcnt;
|
||||
static struct group grp;
|
||||
|
||||
int setgrent(void)
|
||||
{
|
||||
if (_gfd >= 0)
|
||||
_lseek(_gfd, 0L, 0);
|
||||
else
|
||||
_gfd = open(_gr_file, O_RDONLY);
|
||||
|
||||
_bufcnt = 0;
|
||||
return _gfd;
|
||||
}
|
||||
|
||||
void endgrent(void)
|
||||
{
|
||||
if (_gfd >= 0)
|
||||
_close(_gfd);
|
||||
|
||||
_gfd = -1;
|
||||
_bufcnt = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
getline(void)
|
||||
{
|
||||
if (_gfd < 0 && setgrent() < 0)
|
||||
return 0;
|
||||
|
||||
_buf = _grbuf;
|
||||
do
|
||||
{
|
||||
if (--_bufcnt <= 0)
|
||||
{
|
||||
if ((_bufcnt = _read(_gfd, _buffer, RBUFSIZE)) <= 0)
|
||||
return 0;
|
||||
else
|
||||
_pnt = _buffer;
|
||||
}
|
||||
*_buf++ = *_pnt++;
|
||||
} while (*_pnt != '\n');
|
||||
_pnt++;
|
||||
_bufcnt--;
|
||||
*_buf = 0;
|
||||
_buf = _grbuf;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
skip_period(void)
|
||||
{
|
||||
while (*_buf && *_buf != ':')
|
||||
_buf++;
|
||||
*_buf++ = '\0';
|
||||
}
|
||||
|
||||
struct group*
|
||||
getgrent(void)
|
||||
{
|
||||
if (getline() == 0)
|
||||
return 0;
|
||||
|
||||
grp.gr_name = _buf;
|
||||
skip_period();
|
||||
grp.gr_passwd = _buf;
|
||||
skip_period();
|
||||
grp.gr_gid = atoi(_buf);
|
||||
skip_period();
|
||||
return &grp;
|
||||
}
|
||||
|
||||
struct group*
|
||||
getgrnam(const char* name)
|
||||
{
|
||||
struct group* g;
|
||||
|
||||
setgrent();
|
||||
while ((g = getgrent()) != 0)
|
||||
if (!strcmp(g->gr_name, name))
|
||||
break;
|
||||
endgrent();
|
||||
if (g != 0)
|
||||
return g;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct group*
|
||||
getgrgid(int gid)
|
||||
{
|
||||
struct group* g;
|
||||
|
||||
setgrent();
|
||||
while ((g = getgrent()) != 0)
|
||||
if (g->gr_gid == gid)
|
||||
break;
|
||||
endgrent();
|
||||
if (g != 0)
|
||||
return g;
|
||||
else
|
||||
return 0;
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
opendir -- open a directory stream
|
||||
|
||||
last edit: 16-Jun-1987 D A Gwyn
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
|
||||
typedef void* pointer; /* (void *) if you have it */
|
||||
|
||||
extern int _open(const char* path, int flags, int mode);
|
||||
extern int _close(int d);
|
||||
extern int _fstat(int fd, struct stat* buf);
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef O_RDONLY
|
||||
#define O_RDONLY 0
|
||||
#endif
|
||||
|
||||
#ifndef S_ISDIR /* macro to test for directory file */
|
||||
#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
DIR* opendir(const char* dirname) /* name of directory */
|
||||
{
|
||||
register DIR* dirp; /* -> malloc'ed storage */
|
||||
register int fd; /* file descriptor for read */
|
||||
struct stat sbuf; /* result of fstat() */
|
||||
|
||||
if ((fd = _open(dirname, O_RDONLY, 0)) < 0)
|
||||
return NULL; /* errno set by open() */
|
||||
|
||||
if (_fstat(fd, &sbuf) != 0 || !S_ISDIR(sbuf.st_mode))
|
||||
{
|
||||
(void)_close(fd);
|
||||
errno = ENOTDIR;
|
||||
return NULL; /* not a directory */
|
||||
}
|
||||
|
||||
if ((dirp = (DIR*)malloc(sizeof(DIR))) == NULL
|
||||
|| (dirp->dd_buf = (char*)malloc((unsigned)DIRBUF)) == NULL)
|
||||
{
|
||||
register int serrno = errno;
|
||||
/* errno set to ENOMEM by sbrk() */
|
||||
|
||||
if (dirp != NULL)
|
||||
free((pointer)dirp);
|
||||
|
||||
(void)_close(fd);
|
||||
errno = serrno;
|
||||
return NULL; /* not enough memory */
|
||||
}
|
||||
|
||||
dirp->dd_fd = fd;
|
||||
dirp->dd_loc = dirp->dd_size = 0; /* refill needed */
|
||||
|
||||
return dirp;
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
readdir -- read next entry from a directory stream
|
||||
|
||||
last edit: 25-Apr-1987 D A Gwyn
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
/* SVR3 system call, or emulation for getdents() */
|
||||
extern int getdents(int fildes, char* buf, unsigned nbyte);
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
struct dirent*
|
||||
readdir(register DIR* dirp)
|
||||
{
|
||||
register struct dirent* dp; /* -> directory data */
|
||||
|
||||
if (dirp == NULL || dirp->dd_buf == NULL)
|
||||
{
|
||||
errno = EFAULT;
|
||||
return NULL; /* invalid pointer */
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (dirp->dd_loc >= dirp->dd_size) /* empty or obsolete */
|
||||
dirp->dd_loc = dirp->dd_size = 0;
|
||||
|
||||
if (dirp->dd_size == 0 /* need to refill buffer */
|
||||
&& (dirp->dd_size = getdents(dirp->dd_fd, dirp->dd_buf, (unsigned)DIRBUF)) <= 0)
|
||||
return NULL; /* EOF or error */
|
||||
|
||||
dp = (struct dirent*)&dirp->dd_buf[dirp->dd_loc];
|
||||
dirp->dd_loc += dp->d_reclen;
|
||||
} while (dp->d_ino == 0L); /* don't rely on getdents() */
|
||||
|
||||
return dp;
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
rewinddir -- rewind a directory stream
|
||||
|
||||
last edit: 25-Apr-1987 D A Gwyn
|
||||
|
||||
This is not simply a call to seekdir(), because seekdir()
|
||||
will use the current buffer whenever possible and we need
|
||||
rewinddir() to forget about buffered data.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
extern off_t _lseek(int d, int offset, int whence);
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET
|
||||
#define SEEK_SET 0
|
||||
#endif
|
||||
|
||||
void rewinddir(register DIR* dirp)
|
||||
{
|
||||
if (dirp == NULL || dirp->dd_buf == NULL)
|
||||
{
|
||||
errno = EFAULT;
|
||||
return; /* invalid pointer */
|
||||
}
|
||||
|
||||
dirp->dd_loc = dirp->dd_size = 0; /* invalidate buffer */
|
||||
(void)_lseek(dirp->dd_fd, (off_t)0, SEEK_SET); /* may set errno */
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
/*
|
||||
seekdir -- reposition a directory stream
|
||||
|
||||
last edit: 24-May-1987 D A Gwyn
|
||||
|
||||
An unsuccessful seekdir() will in general alter the current
|
||||
directory position; beware.
|
||||
|
||||
NOTE: 4.nBSD directory compaction makes seekdir() & telldir()
|
||||
practically impossible to do right. Avoid using them!
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
extern off_t _lseek(int d, int offset, int whence);
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET
|
||||
#define SEEK_SET 0
|
||||
#endif
|
||||
|
||||
typedef int bool; /* Boolean data type */
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
||||
void seekdir(register DIR* dirp, register off_t loc)
|
||||
/* loc == position from telldir() */
|
||||
{
|
||||
register bool rewind; /* "start over when stymied" flag */
|
||||
|
||||
if (dirp == NULL || dirp->dd_buf == NULL)
|
||||
{
|
||||
errno = EFAULT;
|
||||
return; /* invalid pointer */
|
||||
}
|
||||
|
||||
/* A (struct dirent)'s d_off is an invented quantity on 4.nBSD
|
||||
NFS-supporting systems, so it is not safe to lseek() to it. */
|
||||
|
||||
/* Monotonicity of d_off is heavily exploited in the following. */
|
||||
|
||||
/* This algorithm is tuned for modest directory sizes. For
|
||||
huge directories, it might be more efficient to read blocks
|
||||
until the first d_off is too large, then back up one block,
|
||||
or even to use binary search on the directory blocks. I
|
||||
doubt that the extra code for that would be worthwhile. */
|
||||
|
||||
if (dirp->dd_loc >= dirp->dd_size /* invalid index */
|
||||
|| ((struct dirent*)&dirp->dd_buf[dirp->dd_loc])->d_off > loc
|
||||
/* too far along in buffer */
|
||||
)
|
||||
dirp->dd_loc = 0; /* reset to beginning of buffer */
|
||||
/* else save time by starting at current dirp->dd_loc */
|
||||
|
||||
for (rewind = true;;)
|
||||
{
|
||||
register struct dirent* dp;
|
||||
|
||||
/* See whether the matching entry is in the current buffer. */
|
||||
|
||||
if ((dirp->dd_loc < dirp->dd_size /* valid index */
|
||||
|| readdir(dirp) != NULL /* next buffer read */
|
||||
&& (dirp->dd_loc = 0, true) /* beginning of buffer set */
|
||||
)
|
||||
&& (dp = (struct dirent*)&dirp->dd_buf[dirp->dd_loc])->d_off
|
||||
<= loc /* match possible in this buffer */
|
||||
)
|
||||
{
|
||||
for (/* dp initialized above */;
|
||||
(char*)dp < &dirp->dd_buf[dirp->dd_size];
|
||||
dp = (struct dirent*)((char*)dp + dp->d_reclen))
|
||||
if (dp->d_off == loc)
|
||||
{ /* found it! */
|
||||
dirp->dd_loc = (char*)dp - dirp->dd_buf;
|
||||
return;
|
||||
}
|
||||
|
||||
rewind = false; /* no point in backing up later */
|
||||
dirp->dd_loc = dirp->dd_size; /* set end of buffer */
|
||||
}
|
||||
else /* whole buffer past matching entry */
|
||||
if (!rewind)
|
||||
{ /* no point in searching further */
|
||||
errno = EINVAL;
|
||||
return; /* no entry at specified loc */
|
||||
}
|
||||
else
|
||||
{ /* rewind directory and start over */
|
||||
rewind = false; /* but only once! */
|
||||
|
||||
dirp->dd_loc = dirp->dd_size = 0;
|
||||
|
||||
if (_lseek(dirp->dd_fd, (off_t)0, SEEK_SET)
|
||||
!= 0)
|
||||
return; /* errno already set (EBADF) */
|
||||
|
||||
if (loc == 0)
|
||||
return; /* save time */
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
telldir -- report directory stream position
|
||||
|
||||
last edit: 25-Apr-1987 D A Gwyn
|
||||
|
||||
NOTE: 4.nBSD directory compaction makes seekdir() & telldir()
|
||||
practically impossible to do right. Avoid using them!
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
extern off_t _lseek(int d, int offset, int whence);
|
||||
|
||||
#ifndef SEEK_CUR
|
||||
#define SEEK_CUR 1
|
||||
#endif
|
||||
|
||||
off_t telldir(register DIR* dirp) /* return offset of next entry */
|
||||
{
|
||||
if (dirp == NULL || dirp->dd_buf == NULL)
|
||||
{
|
||||
errno = EFAULT;
|
||||
return -1; /* invalid pointer */
|
||||
}
|
||||
|
||||
if (dirp->dd_loc < dirp->dd_size) /* valid index */
|
||||
return ((struct dirent*)&dirp->dd_buf[dirp->dd_loc])->d_off;
|
||||
else /* beginning of next directory block */
|
||||
return _lseek(dirp->dd_fd, (off_t)0, SEEK_CUR);
|
||||
}
|
Loading…
Reference in a new issue