+++ /dev/null
-/*
- 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);
-}
+++ /dev/null
-/*
- 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 */
-}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- 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;
-}
+++ /dev/null
-/*
- 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;
-}
+++ /dev/null
-/*
- 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 */
-}
+++ /dev/null
-/*
- 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 */
- }
- }
-}
+++ /dev/null
-/*
- 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);
-}