#ifndef DIRENT_H
#define DIRENT_H
#define DIRENT_H_INCLUDED
#if defined(MSDOS)
#elif defined(__MSDOS__)
# define MSDOS
#elif defined(__DOS__)
# define MSDOS
#endif
#if defined(WIN32)
#elif defined(__NT__)
# define WIN32
#elif defined(_WIN32)
# define WIN32
#elif defined(__WIN32__)
# define WIN32
#endif
#if !defined(HAVE_DIRENT_H) && !defined(HAVE_DIRECT_H) && !defined(HAVE_SYS_DIR_H) && !defined(HAVE_NDIR_H) && !defined(HAVE_SYS_NDIR_H) && !defined(HAVE_DIR_H)
# if defined(_MSC_VER)
# elif defined(__MINGW32__)
# elif defined(__BORLANDC__)
# define HAVE_DIRENT_H
# define VOID_CLOSEDIR
# elif defined(__TURBOC__)
# elif defined(__WATCOMC__)
# define HAVE_DIRECT_H
# elif defined(__apollo)
# define HAVE_SYS_DIR_H
# elif defined(__hpux)
# define HAVE_DIRENT_H
# elif (defined(__alpha) || defined(__alpha__)) && !defined(__linux__)
# error "not implemented"
# elif defined(__sgi)
# define HAVE_DIRENT_H
# elif defined(sun) || defined(__sun)
# define HAVE_DIRENT_H
# elif defined(__FreeBSD__)
# define HAVE_DIRENT_H
# elif defined(__linux__)
# define HAVE_DIRENT_H
# elif defined(__GNUC__)
# define HAVE_DIRENT_H
# else
# error "not implemented"
# endif
#endif
#if defined(HAVE_DIRENT_H)
# include <dirent.h>
# ifdef FREEBSD
# define NAMLEN(dp) ((int)((dp)->d_namlen))
# else
# define NAMLEN(dp) ((int)(strlen((dp)->d_name)))
# endif
#elif defined(HAVE_NDIR_H)
# include <ndir.h>
# define NAMLEN(dp) ((int)((dp)->d_namlen))
#elif defined(HAVE_SYS_NDIR_H)
# include <sys/ndir.h>
# define NAMLEN(dp) ((int)((dp)->d_namlen))
#elif defined(HAVE_DIRECT_H)
# include <direct.h>
# define NAMLEN(dp) ((int)((dp)->d_namlen))
#elif defined(HAVE_DIR_H)
# include <dir.h>
# define NAMLEN(dp) ((int)((dp)->d_namlen))
#elif defined(HAVE_SYS_DIR_H)
# include <sys/types.h>
# include <sys/dir.h>
# ifndef dirent
# define dirent direct
# endif
# define NAMLEN(dp) ((int)((dp)->d_namlen))
#elif defined(MSDOS) || defined(WIN32)
# if defined(WIN32)
# define DIRENT_WIN32_INTERFACE
# elif defined(MSDOS)
# define DIRENT_MSDOS_INTERFACE
# else
# error "missing native dirent interface"
# endif
# if defined(DIRENT_WIN32_INTERFACE)
# include <windows.h>
# if !defined(DIRENT_MAXNAMLEN)
# define DIRENT_MAXNAMLEN (MAX_PATH)
# endif
# elif defined(DIRENT_MSDOS_INTERFACE)
# include <dos.h>
# if defined(__BORLANDC__)
# include <dir.h>
# if !defined(DIRENT_MAXNAMLEN)
# define DIRENT_MAXNAMLEN ((MAXFILE)+(MAXEXT))
# endif
# if !defined(_find_t)
# define _find_t find_t
# endif
# elif defined(__TURBOC__)
# include <dir.h>
# if !defined(DIRENT_MAXNAMLEN)
# define DIRENT_MAXNAMLEN ((MAXFILE)+(MAXEXT))
# endif
# define DIRENT_USE_FFBLK
# elif defined(_MSC_VER)
# if !defined(DIRENT_MAXNAMLEN)
# define DIRENT_MAXNAMLEN (12)
# endif
# elif defined(__WATCOMC__)
# if !defined(DIRENT_MAXNAMLEN)
# if defined(__OS2__) || defined(__NT__)
# define DIRENT_MAXNAMLEN (255)
# else
# define DIRENT_MAXNAMLEN (12)
# endif
# endif
# endif
# endif
# if !defined(NAME_MAX) && defined(DIRENT_MAXNAMLEN)
# define NAME_MAX DIRENT_MAXNAMLEN
# endif
# if NAME_MAX < DIRENT_MAXNAMLEN
# error "assertion failed: NAME_MAX >= DIRENT_MAXNAMLEN"
# endif
typedef struct dirent {
char d_name[NAME_MAX + 1];
# if defined(DIRENT_WIN32_INTERFACE)
WIN32_FIND_DATA data;
# elif defined(DIRENT_MSDOS_INTERFACE)
# if defined(DIRENT_USE_FFBLK)
struct ffblk data;
# else
struct _find_t data;
# endif
# endif
} dirent;
typedef struct DIR {
char *dirname;
dirent current;
int dirent_filled;
# if defined(DIRENT_WIN32_INTERFACE)
HANDLE search_handle;
# elif defined(DIRENT_MSDOS_INTERFACE)
# endif
} DIR;
# ifdef __cplusplus
extern "C" {
# endif
static DIR *opendir(const char *dirname);
static struct dirent *readdir(DIR *dirp);
static int closedir(DIR *dirp);
#ifdef unused
static void rewinddir(DIR *dirp);
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#if defined(DIRENT_USE_FFBLK)
# define _A_ARCH (FA_ARCH)
# define _A_HIDDEN (FA_HIDDEN)
# define _A_NORMAL (0)
# define _A_RDONLY (FA_RDONLY)
# define _A_SUBDIR (FA_DIREC)
# define _A_SYSTEM (FA_SYSTEM)
# define _A_VOLID (FA_LABEL)
# define _dos_findnext(dest) findnext(dest)
# define _dos_findfirst(name,flags,dest) findfirst(name,dest,flags)
#endif
static int _initdir(DIR *p);
static const char *_getdirname(const struct dirent *dp);
static void _setdirname(struct DIR *dirp);
static DIR *opendir(const char *dirname)
{
DIR *dirp;
assert(dirname != NULL);
dirp = (DIR*)malloc(sizeof(struct DIR));
if (dirp != NULL) {
char *p;
dirp->dirname = (char*) malloc(strlen(dirname) + 1 + strlen("\\*.*"));
if (dirp->dirname == NULL) {
free(dirp);
return NULL;
}
strcpy(dirp->dirname, dirname);
p = strchr(dirp->dirname, '\0');
if (dirp->dirname < p &&
*(p - 1) != '\\' && *(p - 1) != '/' && *(p - 1) != ':') {
strcpy(p++, "\\");
}
# ifdef DIRENT_WIN32_INTERFACE
strcpy(p, "*");
# else
strcpy(p, "*.*");
# endif
if (_initdir(dirp) == 0) {
free(dirp->dirname);
free(dirp);
return NULL;
}
}
return dirp;
}
static struct dirent *
readdir(DIR *dirp)
{
assert(dirp != NULL);
if (dirp == NULL) {
errno = EBADF;
return NULL;
}
#if defined(DIRENT_WIN32_INTERFACE)
if (dirp->search_handle == INVALID_HANDLE_VALUE) {
errno = EBADF;
return NULL;
}
#endif
if (dirp->dirent_filled != 0) {
dirp->dirent_filled = 0;
} else {
#if defined(DIRENT_WIN32_INTERFACE)
if (FindNextFile(dirp->search_handle, &dirp->current.data) == FALSE) {
FindClose(dirp->search_handle);
dirp->search_handle = INVALID_HANDLE_VALUE;
errno = ENOENT;
return NULL;
}
# elif defined(DIRENT_MSDOS_INTERFACE)
if (_dos_findnext(&dirp->current.data) != 0) {
return NULL;
}
# endif
_setdirname(dirp);
assert(dirp->dirent_filled == 0);
}
return &dirp->current;
}
static int
closedir(DIR *dirp)
{
int retcode = 0;
assert(dirp != NULL);
if (dirp == NULL) {
errno = EBADF;
return -1;
}
if (dirp->dirname != NULL) {
free(dirp->dirname);
}
#if defined(DIRENT_WIN32_INTERFACE)
if (dirp->search_handle != INVALID_HANDLE_VALUE) {
if (FindClose(dirp->search_handle) == FALSE) {
retcode = -1;
errno = EBADF;
}
}
#endif
memset(dirp, 0, sizeof(*dirp));
# if defined(DIRENT_WIN32_INTERFACE)
dirp->search_handle = INVALID_HANDLE_VALUE;
# endif
free(dirp);
return retcode;
}
#ifdef unused
static void
rewinddir(DIR *dirp)
{
assert(dirp != NULL);
if (dirp == NULL) {
errno = EBADF;
return;
}
assert(dirp->dirname != NULL);
#if defined(DIRENT_WIN32_INTERFACE)
if (dirp->search_handle != INVALID_HANDLE_VALUE) {
if (FindClose(dirp->search_handle) == FALSE) {
errno = EBADF;
}
}
#endif
if (_initdir(dirp) == 0) {
;
}
}
#endif
static int
_initdir(DIR *dirp)
{
assert(dirp != NULL);
assert(dirp->dirname != NULL);
dirp->dirent_filled = 0;
# if defined(DIRENT_WIN32_INTERFACE)
dirp->search_handle = FindFirstFile(dirp->dirname, &dirp->current.data);
if (dirp->search_handle == INVALID_HANDLE_VALUE) {
errno = ENOENT;
return 0;
}
# elif defined(DIRENT_MSDOS_INTERFACE)
if (_dos_findfirst(dirp->dirname,
_A_SUBDIR | _A_RDONLY | _A_ARCH | _A_SYSTEM | _A_HIDDEN,
&dirp->current.data) != 0) {
return 0;
}
# endif
_setdirname(dirp);
dirp->dirent_filled = 1;
return 1;
}
static const char *
_getdirname(const struct dirent *dp)
{
#if defined(DIRENT_WIN32_INTERFACE)
return dp->data.cFileName;
#elif defined(DIRENT_USE_FFBLK)
return dp->data.ff_name;
#else
return dp->data.name;
#endif
}
static void
_setdirname(struct DIR *dirp)
{
assert(strlen(_getdirname(&dirp->current)) <= NAME_MAX);
strncpy(dirp->current.d_name,
_getdirname(&dirp->current),
NAME_MAX);
dirp->current.d_name[NAME_MAX] = '\0';
}
# ifdef __cplusplus
}
# endif
# define NAMLEN(dp) ((int)(strlen((dp)->d_name)))
#else
# error "missing dirent interface"
#endif
#endif