/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* bos720 src/bos/kernel/sys/dir.h 1.38.4.2                               */
/*                                                                        */
/* Licensed Materials - Property of IBM                                   */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 1988,1994              */
/* All Rights Reserved                                                    */
/*                                                                        */
/* US Government Users Restricted Rights - Use, duplication or            */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.      */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/* @(#)68     1.38.4.2  src/bos/kernel/sys/dir.h, syslfs, bos720 4/25/13 13:43:26 */
/*
 * Copyright (c) 1982, 1986 Regents of the University of California.
 * All rights reserved.  The Berkeley software License Agreement
 * specifies the terms and conditions for redistribution.
 *
 */
/*
 * (c) Copyright 1990, 1991, 1992 OPEN SOFTWARE FOUNDATION, INC. 
 * ALL RIGHTS RESERVED 
 */
#ifdef	_SUN
/* 
 * Copyright (c) 1988 by Sun Microsystems, Inc.
 */
#endif	/* _SUN */

#ifndef _H_DIR
#define _H_DIR

#include <standards.h>

#include <sys/types.h>

#ifdef __cplusplus
extern "C" {
#endif



#ifdef _POSIX_SOURCE
/*
 * The POSIX standard way of returning directory entries is in directory entry
 * structures, which are of variable length.  Each directory entry has
 * a struct direct at the front of it, containing its inode number,
 * the length of the entry, and the length of the name contained in
 * the entry.  These are followed by the name padded to a 4 byte boundary
 * with null bytes.  All names are guaranteed null terminated.
 * The maximum length of a name in a directory is _D_NAME_MAX
 */
#define _D_NAME_MAX 255

struct	dirent {
	__ulong64_t	d_offset;	/* real off after this entry */
	ino_t		d_ino;		/* inode number of entry */
	ushort_t	d_reclen;	/* length of this record */
	ushort_t	d_namlen;	/* length of string in d_name */
	char	        d_name[_D_NAME_MAX+1];	/* name must be no longer than this */
					/* redefine w/#define when name decided */
};

/* This is a view of the 32-bit program dirent structure inside 64BK.
 */
#if defined(_KERNEL) && defined(__64BIT_KERNEL)
struct	dirent32 {
	uint		d_offset;	/* real off after this entry */
	ino32_t		d_ino;		/* inode number of entry */
	ushort_t	d_reclen;	/* length of this record */
	ushort_t	d_namlen;	/* length of string in d_name */
	char	        d_name[_D_NAME_MAX+1];	/* name no longer than this */
};
#endif /* _KERNEL && __64BIT_KERNEL */

#ifndef _KERNEL

/*
 * Definitions for library routines operating on directories.
 */
typedef struct _dirdesc {
#ifdef _ALL_SOURCE
	int	dd_fd;		/* file descriptor of directory */
	blksize_t dd_blksize;	/* this filesystem's block size */
	char	*dd_buf;	/* malloc'd buffer depending of fs bsize */
	long	dd_size;	/* size of buffer */
	long	dd_flag;	/* private flags for readdir, unused */
	off_t	dd_loc;		/* logical(dirent) offset in  directory */
	off_t	dd_curoff;	/* real offset in directory corresponding
				 * to dd_loc */
#else
	int	__dd_fd;		/* file descriptor of directory */
	blksize_t __dd_blksize;	/* this filesystem's block size */
	char	*__dd_buf;	/* malloc'd buffer depending of fs bsize */
	long	__dd_size;	/* size of buffer */
	long	__dd_flag;	/* private flags for readdir, unused */
	off_t	__dd_loc;	/* logical(dirent) offset in  directory */
	off_t	__dd_curoff;	/* real offset in directory corresponding
				 * to dd_loc */
#endif
#if defined(_THREAD_SAFE) && defined(_ALL_SOURCE)
	void	*dd_lock;	/* for inter-thread locking */
#endif

} DIR;


#ifdef _NO_PROTO
extern	DIR *opendir();
extern	struct dirent *readdir();
#if (_XOPEN_SOURCE >= 700)
extern  DIR *fdopendir();
extern  int  dirfd();
#endif

#if defined(_THREAD_SAFE) || (_XOPEN_SOURCE >= 500)
extern int readdir_r();
#endif
extern	int closedir();
extern  void rewinddir();

#else /* _NO_PROTO */

extern  DIR *opendir(const char *);
extern  struct dirent *readdir(DIR *);
#if (_XOPEN_SOURCE >= 700)
extern  DIR *fdopendir(int);
extern  int  dirfd(DIR *);
#endif

#if defined(_THREAD_SAFE) || (_XOPEN_SOURCE >= 500)

/* See comments in stdlib.h on _AIX32_THREADS */
#ifdef	_AIX32_THREADS
extern int readdir_r(DIR *dirp, struct dirent *entry);
#else	/* POSIX 1003.1c prototype */
extern int readdir_r(DIR *__restrict__, struct dirent *__restrict__, struct dirent **__restrict__);
#endif	/* _AIX32_THREADS or _XOPEN_SOURCE>=500 */

#endif	/* _THREAD_SAFE */

extern  int closedir(DIR *);
extern  void rewinddir(DIR *);

#endif /* _NO_PROTO */
#endif /* _KERNEL */

#endif /* _POSIX_SOURCE */

#ifdef _XOPEN_SOURCE
#ifndef _KERNEL
#ifdef _NO_PROTO 

extern	long telldir();
extern	void seekdir();

#else /* _NO_PROTO */

extern void seekdir(DIR *, long);
extern long telldir(DIR *);

#endif /* _NO_PROTO */
#endif /* _KERNEL */
#endif /* _XOPEN_SOURCE */

#ifdef _ALL_SOURCE

/* This dirent64 structure providing invariant 64-bit offset and inode number.
 */
struct	dirent64 {
	uint64_t	d_offset;	/* real off after this entry */
	ino64_t		d_ino;		/* inode number of entry */
	ushort_t	d_reclen;	/* length of this record */
	ushort_t	d_namlen;	/* length of string in d_name */
	char	        d_name[_D_NAME_MAX+1];	/* name no longer than this */
};

typedef struct _dirdesc64 {
	int	dd_fd;		/* file descriptor of directory */
	blksize_t dd_blksize;	/* this filesystem's block size */
	char	*dd_buf;	/* malloc'd buffer depending of fs bsize */
	long	dd_size;	/* size of buffer */
	long	dd_flag;	/* private flags for readdir, unused */
	offset_t dd_loc;	/* logical(dirent) offset in  directory */
	offset_t dd_curoff;	/* real offset in directory corresponding
				 * to dd_loc */
#ifdef _THREAD_SAFE
	void	*dd_lock;	/* for inter-thread locking */
#endif

} DIR64;


#ifdef _NO_PROTO 

extern int scandir(); 
extern int alphasort();
extern ssize_t getdirentries();

/* 64-bit interfaces */
extern	DIR64 *opendir64();
extern	struct dirent64 *readdir64();
#if (_XOPEN_SOURCE >= 700)
extern DIR64 *fdopendir64();
extern int dirfd64();
#endif
#ifdef _THREAD_SAFE
extern int readdir64_r();
#endif
extern	int closedir64();
extern  void rewinddir64();
extern	offset_t telldir64();
extern	void seekdir64();
extern int scandir64(); 
extern int alphasort64();

#else /* _NO_PROTO */

/* The scandir and alphasort prototypes Have been changed
Old Definitions were:
extern int scandir(const char *, struct dirent ***, int (*)(), int (*)());
extern int alphasort(struct dirent **, struct dirent **);
New Definitions are:
*/
#if (_XOPEN_SOURCE >= 700) 
extern int scandir(const char *, struct dirent ***,
					int (*)(const struct dirent *),
					int (*)(const struct dirent **, const struct dirent **));
extern int scandir64(const char *, struct dirent64 ***,
					int (*)(const struct dirent64 *),
					int (*)(const struct dirent64 **, const struct dirent64 **));
extern int alphasort(const struct dirent **, const struct dirent **);
extern int alphasort64(const struct dirent64**, const struct dirent64 **);
#else
extern int scandir(const char *, struct dirent ***,
                    int (*)(struct dirent *),
                    int (*)(void *, void *));
extern int scandir64(const char *, struct dirent64 ***,
                    int (*)(struct dirent64 *),
                    int (*)(void *, void *));

extern int alphasort(void *, void *);
extern int alphasort64(void *, void *);
#endif

extern ssize_t getdirentries(int, char *, size_t, off_t *);

#ifdef _LINUX_SOURCE_COMPAT
extern int __linux_scandir(const char *dirname, struct dirent ***namelist,
        int (*select)(const struct dirent *),
	int (*dcomp)(const struct dirent **, const struct dirent **));
extern int __linux_scandir64(const char *dirname, struct dirent64 ***namelist,
        int (*select)(const struct dirent64 *),
	int (*dcomp)(const struct dirent64 **, const struct dirent64 **));
#define scandir(a, b, c, d) __linux_scandir(a, b, c, d)
#define scandir64(a, b, c, d) __linux_scandir64(a, b, c, d)

extern int __linux_alphasort(const struct dirent **, const struct dirent **);
extern int __linux_alphasort64(const struct dirent64 **, const struct dirent64 **);
#define alphasort __linux_alphasort
#define alphasort64 __linux_alphasort64

extern int __linux_readdir_r(DIR *, struct dirent *, struct dirent **);
extern int __linux_readdir64_r(DIR64 *, struct dirent64 *, struct dirent64 **);
#define readdir_r __linux_readdir_r
#define readdir64_r __linux_readdir64_r
#endif	/* _LINUX_SOURCE_COMPAT */

/* 64-bit interfaces */
extern  DIR64 *opendir64(const char *);
extern int readdir64_r(DIR64 *, struct dirent64 *__restrict__, struct dirent64 **__restrict__);
extern  struct dirent64 *readdir64(DIR64 *);
extern  int closedir64(DIR64 *);
extern  void rewinddir64(DIR64 *);
extern void seekdir64(DIR64 *, offset_t);
extern offset_t telldir64(DIR64 *);
#if (_XOPEN_SOURCE >= 700)
extern  DIR64 *fdopendir64(int);
extern  int  dirfd64(DIR64 *);
#endif
#endif /* _NO_PROTO */
 

#include <sys/lkup.h>			/* for lookup flags */
/* <limits.h> has historically been included in <sys/dir.h>.  However,
   it is not allowed by Posix.1.  The include must remain in _ALL_SOURCE.
 */
#include <limits.h>

#define rewinddir(__dirp)	seekdir((__dirp), (long)0)
#define rewinddir64(__dirp)	seekdir64((__dirp), (offset_t)0)

#define NO_STAT		0
#define STAT		1

/* For BSD compatibility */
#define MAXNAMLEN	255

/*
 * A directory consists of some number of blocks of DIRBLKSIZ
 * bytes, where DIRBLKSIZ is chosen such that it can be transferred
 * to disk in a single atomic operation (e.g. 512 bytes on most machines).
 *
 * Each DIRBLKSIZ byte block contains some number of directory entry
 * structures, which are of variable length.  Each directory entry has
 * a struct direct at the front of it, containing its inode number,
 * the length of the entry, and the length of the name contained in
 * the entry.  These are followed by the name padded to a 4 byte boundary
 * with null bytes.  All names are guaranteed null terminated.
 * The maximum length of a name in a directory is _D_NAME_MAX.
 *
 * The macro DIRSIZ(dp) gives the amount of space required to represent
 * a directory entry.  Free space in a directory is represented by
 * entries which have dp->d_reclen > DIRSIZ(dp).  All DIRBLKSIZ bytes
 * in a directory block are claimed by the directory entries.  This
 * usually results in the last entry in a directory having a large
 * dp->d_reclen.  When entries are deleted from a directory, the
 * space is returned to the previous entry in the same directory
 * block by increasing its dp->d_reclen.  If the first entry of
 * a directory block is free, then its dp->d_ino is set to 0.
 * Entries other than the first in a directory do not normally have
 * dp->d_ino set to 0.
 */
#if !defined(DEV_BSIZE)
#define	DEV_BSIZE	512
#endif

#define	DIRBLKSIZ	512

/*
 * The DIRSIZ macro gives the minimum record length which will hold
 * the directory entry.  This requires the amount of space in struct dirent
 * without the d_name field, plus enough space for the name with a terminating
 * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
 */
#undef DIRSIZ
#define DIRSIZ(__dp) \
    ((sizeof (struct dirent) - (_D_NAME_MAX+1)) + (((__dp)->d_namlen+1 + 3) &~ 3))


/*
 * The DIRSIZ2 macro is similar, except it works for 64 and 32-bit
 * offset and inode numbers.  Also, the alignment is based on the
 * size of the d_ino field.  The argument needs to be a struct dirent
 * or struct dirent32.
 */

#define DIRSIZ2(__dp) \
	((((caddr_t)(__dp)->d_name - (caddr_t)(__dp)) + \
	(__dp)->d_namlen + (sizeof((__dp)->d_ino))) & \
	~((sizeof((__dp)->d_ino))-1))


#if defined( _KERNEL) || defined(_FSDBDIR)
# include	"jfs/dir.h"
#else /* _KERNEL || _FSDBDIR */

#ifdef _BSD
#define direct dirent
#else /* _BSD */

/* This structure is defined ONLY to ease porting of System V applications.
   It is NOT advisable to use it and the read() system call to read 
   directories.  Rather the readdir() system call should be used since it
   will work with all supported file systems and file name lengths.
   To maintain compatiblilty with Sys V, the d_ino field is hardcoded to 
   a short (not an ino_t).  The d_name field must be AIX_DIRSIZ (14) bytes long.
*/

/* to compensate for the sys V DIRSIZ */
#define AIX_DIRSIZ 14
struct	direct {
	ushort_t d_ino;			/* inode number of entry */
	char	d_name[AIX_DIRSIZ];	/* name must be no longer than this */
};
#endif /* _BSD */

#ifdef	_SUN
#define dd_bsize	dd_blksize	/* ala sun */
#define d_fileno	d_ino		/* ala sun */
#endif	/* _SUN */

#ifndef NULL
#define NULL 0
#endif
#endif /* _KERNEL || _FSDBDIR */

#endif /* _ALL_SOURCE */


/*
   This is in order to comply with UNIXv7 Standards where it is
   required to have prototypes for scandir() and alphasort() in
   the _XOPEN_SOURCE namespace.
 */
#if ( _XOPEN_SOURCE>=700)
        extern int scandir(const char *, struct dirent ***,
                                        int (*)(const struct dirent *),
                                        int (*)(const struct dirent **, const struct dirent **));
        extern int alphasort(const struct dirent **, const struct dirent **);
#endif /* _XOPEN_SOURCE >= 700 */



#ifdef __cplusplus
}
#endif

#endif /* _H_DIR */

