#ifndef _CORE_STAT_H_
#define _CORE_STAT_H_

/****************************************************************************************************************/

#include <core/types.h>
#include <core/time.h>

/****************************************************************************************************************
 *
 * This is the stat structure from OpenBSD.
 * It contains a lot of fields not supported by Core4.
 *
 */
struct stat {
  dev_t         st_dev;      /* device						*/
  ino_t         st_ino;      /* inode						*/
  mode_t        st_mode;     /* protection					*/
  nlink_t       st_nlink;    /* number of hard links				*/
  uid_t         st_uid;      /* user ID of owner				*/
  gid_t         st_gid;      /* group ID of owner				*/
  dev_t         st_rdev;     /* device type (if inode device)			*/
  int32_t       st_lspare0;

#ifdef __BSD_VISIBLE
  struct timespec st_atimespec;		/* time of last access			*/
  struct timespec st_mtimespec;		/* time of last data modification	*/
  struct timespec st_ctimespec;		/* time of last file status change	*/
#else
  time_t        st_atime;		/* time of last access			*/
  long          st_atimensec;		/* nsec of last access			*/
  time_t        st_mtime;		/* time of last data modification	*/
  long	        st_mtimensec;		/* nsec of last data modification	*/
  time_t	st_ctime;		/* time of last file status change	*/
  long	        st_ctimensec;		/* nsec of last file status change	*/
#endif

  off64_t       st_size;     /* total size, in bytes				*/
  blkcnt_t      st_blocks;   /* number of blocks allocated			*/
  blksize_t     st_blksize;  /* blocksize for filesystem I/O			*/
  u_int32_t	st_flags;    /* User defined flags				*/
  u_int32_t     st_gen;	     /* file generation number				*/
  int32_t       st_lspare1;

#ifdef __BSD_VISIBLE
  struct timespec __st_birthtimespec;	/* time of file creation		*/
#else
  time_t	  __st_birthtime;	/* time of file creation		*/
  long	          __st_birthtimensec;	/* nsec of file creation		*/
#endif

  int64_t       st_qspare[2];
};

#ifdef __BSD_VISIBLE
#define	st_atime	st_atimespec.tv_sec
#define	st_atimensec	st_atimespec.tv_nsec
#define	st_mtime	st_mtimespec.tv_sec
#define	st_mtimensec	st_mtimespec.tv_nsec
#define	st_ctime	st_ctimespec.tv_sec
#define	st_ctimensec	st_ctimespec.tv_nsec
#endif

/****************************************************************************************************************/

#define S_IFMT   0xF000
#define S_IFSOCK 0xC000
#define S_IFLNK  0xA000
#define S_IFREG  0x8000
#define S_IFBLK  0x6000
#define S_IFDIR  0x4000
#define S_IFCHR  0x2000
#define S_IFIFO  0x1000

#define S_ISLNK(m)      (((m) & S_IFMT) == S_IFLNK)
#define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)
#define S_ISDIR(m)      (((m) & S_IFMT) == S_IFDIR)
#define S_ISCHR(m)      (((m) & S_IFMT) == S_IFCHR)
#define S_ISBLK(m)      (((m) & S_IFMT) == S_IFBLK)
#define S_ISFIFO(m)     (((m) & S_IFMT) == S_IFIFO)
#define S_ISSOCK(m)     (((m) & S_IFMT) == S_IFSOCK)

#define S_ISUID  0x0800
#define S_ISGID  0x0400
#define S_ISVTX  0x0200
#define S_ISTXT  S_ISVTX

#define S_IRWXU 0x01C0
#define S_IRUSR 0x0100
#define S_IWUSR 0x0080
#define S_IXUSR 0x0040

#define S_IRWXG 0x0038
#define S_IRGRP 0x0020
#define S_IWGRP 0x0010
#define S_IXGRP 0x0008

#define S_IRWXO 0x0007
#define S_IROTH 0x0004
#define S_IWOTH 0x0002
#define S_IXOTH 0x0001

#define ACCESSPERMS     (S_IRWXU|S_IRWXG|S_IRWXO)				/* 00777 */
#define ALLPERMS        (S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO)	/* 07777 */
#define DEFFILEMODE     (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)	/* 00666 */

/****************************************************************************************************************/
#endif
