/*   stat.h -- extra-ANSI
 *
 *   Function, types and constants for determining device and file status.
 *           Copyright (c) 1990, MetaWare Incorporated
 */
#ifndef _STAT_H
#define _STAT_H
#pragma push_align_members(64);

#ifdef __CPLUSPLUS__
extern "C" {
#endif

#ifndef _UNICHAR_DEFINED
    typedef unsigned short _UNICHAR;
    #define _unichar _UNICHAR
    #define _UNICHAR_DEFINED
#endif

#ifndef _TIME_T_DEFINED
    #define _TIME_T_DEFINED
    typedef long time_t;
#endif

#ifdef __PENPOINT__
    typedef void *      _dev_t;
#else
    typedef short       _dev_t;
#endif
typedef unsigned short  _mode_t;
typedef unsigned short  _ino_t;
typedef long            _off_t;
typedef short           _nlink_t;
typedef short           _uid_t;
typedef short           _gid_t;
typedef short           _pid_t;

struct _stat {
    #ifdef __PENPOINT__
        _mode_t  st_mode;
        _ino_t   st_ino;
        _dev_t   st_dev;
        _nlink_t st_nlink;
        _uid_t   st_uid;
        _gid_t   st_gid;
    #else
        _dev_t   st_dev;
        _ino_t   st_ino;
        _mode_t  st_mode;
        _nlink_t st_nlink;
        _uid_t   st_uid;
        _gid_t   st_gid;
        _dev_t   st_rdev;
    #endif
        _off_t   st_size;
        time_t   st_atime;
        time_t   st_mtime;
        time_t   st_ctime;
        };

#if _MSDOS || _OS2 || _MSNT
    extern int _chmod(const char *, int);
    extern int _mkdir(const char *);
#else
    extern int _chmod(const char *, _mode_t);
    extern int _mkdir(const char *, int);
#endif
extern int _stat(const char * __path, struct _stat * __buffer);
extern int _fstat(int __handle, struct _stat * __buffer);
extern int _umask(int);

/* File type field in st_mode
 */
#ifdef __PENPOINT__
    #define _S_IFMT    0x3f000  /* file type mask */
    #define _S_IFREG   0x1000   /* regular */
    #define _S_IFDIR   0x2000   /* directory */
    #define _S_IFBLK   0x8000   /* block special */
    #define _S_IFCHR   0x4000   /* character special */
    #define _S_IFFIFO  0x10000  /* pipe or FIFO special */
#else
    #define _S_IFMT    0xf000   /* file type mask */
    #define _S_IFREG   0x8000   /* regular */
    #define _S_IFDIR   0x4000   /* directory */
    #define _S_IFBLK   0x6000   /* block special */
    #define _S_IFCHR   0x2000   /* character special */
    #define _S_IFFIFO  0x1000   /* pipe or FIFO special */
#endif

/* Owner permissions in st_mode
 */
#define _S_IREAD    0x100
#define _S_IWRITE    0x80
#define _S_IEXEC     0x40

#if __HIGHC__
    typedef _dev_t      dev_t;
    typedef _mode_t     mode_t;
    typedef _ino_t      ino_t;
    typedef _off_t      off_t;
    typedef _nlink_t    nlink_t;
    typedef _uid_t      uid_t;
    typedef _gid_t      gid_t;
    typedef _pid_t      pid_t;

    struct stat {
        #ifdef __PENPOINT__
            mode_t  st_mode;
            ino_t   st_ino;
            dev_t   st_dev;
            nlink_t st_nlink;
            uid_t   st_uid;
            gid_t   st_gid;
        #else
            dev_t   st_dev;
            ino_t   st_ino;
            mode_t  st_mode;
            nlink_t st_nlink;
            uid_t   st_uid;
            gid_t   st_gid;
            dev_t   st_rdev;
        #endif
            _off_t   st_size;
            time_t   st_atime;
            time_t   st_mtime;
            time_t   st_ctime;
            };

    extern int fstat(int __handle, struct stat * __buffer);
    #if _MSDOS || _OS2 || _MSNT
        extern int chmod(const char *, int);
        extern int mkdir(const char *);
    #else
        extern int chmod(const char *, mode_t);
        extern int mkdir(const char *, int);
    #endif
    extern int stat(const char * __path, struct stat * __buffer);
    extern int umask(int);

    #pragma alias(chmod, "_chmod", _DEFAULT_UNDERSCORE_PREFIXING);
    #pragma alias(fstat, "_fstat", _DEFAULT_UNDERSCORE_PREFIXING);
    #pragma alias(mkdir, "_mkdir", _DEFAULT_UNDERSCORE_PREFIXING);
    #pragma alias(stat, "_stat", _DEFAULT_UNDERSCORE_PREFIXING);
    #pragma alias(umask, "_umask", _DEFAULT_UNDERSCORE_PREFIXING);

    #define S_IFMT      _S_IFMT
    #define S_IFREG     _S_IFREG
    #define S_IFDIR     _S_IFDIR
    #define S_IFBLK     _S_IFBLK
    #define S_IFCHR     _S_IFCHR
    #define S_IFFIFO    _S_IFFIFO

    #define S_IREAD     _S_IREAD
    #define S_IWRITE    _S_IWRITE
    #define S_IEXEC     _S_IEXEC

    /* POSIX masks and bits for permission fields in st_mode
     */
    #define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)       /* owner permission */
        #define S_IRUSR 0x100
        #define S_IWUSR  0x80
        #define S_IXUSR  0x40
    #define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP)       /* group permission */
        #define S_IRGRP  0x20
        #define S_IWGRP  0x10
        #define S_IXGRP   0x8
    #define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH)       /* other permission */
        #define S_IROTH   0x4
        #define S_IWOTH   0x2
        #define S_IXOTH   0x1

    /* POSIX macros for testing file type in st_mode
     */
    #define S_ISREG(m)  (((m) & _S_IFMT) == _S_IFREG)
    #define S_ISDIR(m)  (((m) & _S_IFMT) == _S_IFDIR)
    #define S_ISBLK(m)  (((m) & _S_IFMT) == _S_IFBLK)
    #define S_ISCHR(m)  (((m) & _S_IFMT) == _S_IFCHR)
    #define S_ISFIFO(m) (((m) & _S_IFMT) == _S_IFFIFO)

#endif /* __HIGHC__ */

/* Unicode functions */

extern int _uchmod(const _unichar *, int);
extern int _umkdir(const _unichar *, int);

#if _HOBBIT && __HIGHC__
    extern int _ustat(const _unichar * __path, struct stat * __buffer);
#else
    extern int _ustat(const _unichar * __path, struct _stat * __buffer);
#endif

#ifdef __UNICODE__
    #define Uchmod _uchmod
    #define Umkdir _umkdir
    #define Ustat _ustat
#elif _MSDOS || _OS2 || _MSNT
    #define Uchmod _chmod
    #define Umkdir(f,m) _mkdir(f)
    #define Ustat _stat
#elif _HOBBIT && __HIGHC__
    #define Uchmod chmod
    #define Umkdir mkdir
    #define Ustat stat
#endif

#ifdef __CPLUSPLUS__
}
#endif
#pragma pop_align_members();
#endif /* _STAT_H */
