func IsDir(path string) bool {
	if path == "" {
		return false
	}
	path = PATH.Clean(path)
	mode := getMode(path)
	if mode == 0 {
		return false
	}
	return mode&_IFMT == _IFDIR
}
IsDir returns true if the given object is a directory
package fsutil
import (
	"errors"
	"fmt"
	"os"
	"strings"
	"syscall"
	"time"
	PATH "pkg.re/essentialkaos/ek.v12/path"
	"pkg.re/essentialkaos/ek.v12/system"
)
const (
	_IFMT   = 0XF000
	_IFSOCK = 0XC000
	_IFREG  = 0x8000
	_IFBLK  = 0x6000
	_IFDIR  = 0x4000
	_IFCHR  = 0x2000
	_IRUSR  = 0x100
	_IWUSR  = 0x80
	_IXUSR  = 0x40
	_IRGRP  = 0x20
	_IWGRP  = 0x10
	_IXGRP  = 0x8
	_IROTH  = 0x4
	_IWOTH  = 0x2
	_IXOTH  = 0x1
)
var ErrEmptyPath = errors.New("Path is empty")
func CheckPerms(props, path string) bool {
	if props == "" || path == "" {
		return false
	}
	path = PATH.Clean(path)
	props = strings.ToUpper(props)
	var stat = &syscall.Stat_t{}
	err := syscall.Stat(path, stat)
	if err != nil {
		return false
	}
	user, err := getCurrentUser()
	if err != nil {
		return false
	}
	for _, k := range props {
		switch k {
		case 'F':
			if stat.Mode&_IFMT != _IFREG {
				return false
			}
		case 'D':
			if stat.Mode&_IFMT != _IFDIR {
				return false
			}
		case 'B':
			if stat.Mode&_IFMT != _IFBLK {
				return false
			}
		case 'C':
			if stat.Mode&_IFMT != _IFCHR {
				return false
			}
		case 'L':
			if !IsLink(path) {
				return false
			}
		case 'X':
			if !isExecutableStat(stat, user.UID, getGIDList(user)) {
				return false
			}
		case 'W':
			if !isWritableStat(stat, user.UID, getGIDList(user)) {
				return false
			}
		case 'R':
			if !isReadableStat(stat, user.UID, getGIDList(user)) {
				return false
			}
		case 'S':
			if stat.Size == 0 {
				return false
			}
		}
	}
	return true
}
func ValidatePerms(props, path string) error {
	if props == "" || path == "" {
		return errors.New("Props or path to object is empty")
	}
	path = PATH.Clean(path)
	props = strings.ToUpper(props)
	var stat = &syscall.Stat_t{}
	err := syscall.Stat(path, stat)
	if err != nil {
		return fmt.Errorf("Object %s doesn't exist or not accessible", path)
	}
	user, err := getCurrentUser()
	if err != nil {
		return errors.New("Can't get information about the current user")
	}
	for _, k := range props {
		switch k {
		case 'F':
			if stat.Mode&_IFMT != _IFREG {
				return fmt.Errorf("%s is not a file", path)
			}
		case 'D':
			if stat.Mode&_IFMT != _IFDIR {
				return fmt.Errorf("%s is not a directory", path)
			}
		case 'B':
			if stat.Mode&_IFMT != _IFBLK {
				return fmt.Errorf("%s is not a block device", path)
			}
		case 'C':
			if stat.Mode&_IFMT != _IFCHR {
				return fmt.Errorf("%s is not a character device", path)
			}
		case 'L':
			if !IsLink(path) {
				return fmt.Errorf("%s is not a link", path)
			}
		case 'X':
			if !isExecutableStat(stat, user.UID, getGIDList(user)) {
				return fmt.Errorf("%s is not executable", path)
			}
		case 'W':
			if !isWritableStat(stat, user.UID, getGIDList(user)) {
				return fmt.Errorf("%s is not writable", path)
			}
		case 'R':
			if !isReadableStat(stat, user.UID, getGIDList(user)) {
				return fmt.Errorf("%s is not readable", path)
			}
		case 'S':
			if stat.Size == 0 {
				return fmt.Errorf("%s is empty", path)
			}
		}
	}
	return nil
}
func ProperPath(props string, paths []string) string {
	for _, path := range paths {
		path = PATH.Clean(path)
		if CheckPerms(props, path) {
			return path
		}
	}
	return ""
}
func IsExist(path string) bool {
	if path == "" {
		return false
	}
	path = PATH.Clean(path)
	return syscall.Access(path, syscall.F_OK) == nil
}
func IsRegular(path string) bool {
	if path == "" {
		return false
	}
	path = PATH.Clean(path)
	mode := getMode(path)
	if mode == 0 {
		return false
	}
	return mode&_IFMT == _IFREG
}
func IsSocket(path string) bool {
	if path == "" {
		return false
	}
	path = PATH.Clean(path)
	mode := getMode(path)
	if mode == 0 {
		return false
	}
	return mode&_IFMT == _IFSOCK
}
func IsBlockDevice(path string) bool {
	if path == "" {
		return false
	}
	path = PATH.Clean(path)
	mode := getMode(path)
	if mode == 0 {
		return false
	}
	return mode&_IFMT == _IFBLK
}
func IsCharacterDevice(path string) bool {
	if path == "" {
		return false
	}
	path = PATH.Clean(path)
	mode := getMode(path)
	if mode == 0 {
		return false
	}
	return mode&_IFMT == _IFCHR
}