123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- package localfs
- import (
- "io"
- "io/fs"
- "os"
- "path/filepath"
- "strings"
- "time"
- "imuslab.com/arozos/mod/filesystem/arozfs"
- "imuslab.com/arozos/mod/utils"
- )
- /*
- filesystemAbstraction.go
- This file contains all the abstraction funtion of a local file system.
- */
- type LocalFileSystemAbstraction struct {
- UUID string
- Rootpath string
- Hierarchy string
- ReadOnly bool
- }
- func NewLocalFileSystemAbstraction(uuid, root, hierarchy string, readonly bool) LocalFileSystemAbstraction {
- return LocalFileSystemAbstraction{
- UUID: uuid,
- Rootpath: root,
- Hierarchy: hierarchy,
- ReadOnly: readonly,
- }
- }
- func (l LocalFileSystemAbstraction) Chmod(filename string, mode os.FileMode) error {
- return os.Chmod(filename, mode)
- }
- func (l LocalFileSystemAbstraction) Chown(filename string, uid int, gid int) error {
- return os.Chown(filename, uid, gid)
- }
- func (l LocalFileSystemAbstraction) Chtimes(filename string, atime time.Time, mtime time.Time) error {
- return os.Chtimes(filename, atime, mtime)
- }
- func (l LocalFileSystemAbstraction) Create(filename string) (arozfs.File, error) {
- return os.Create(filename)
- }
- func (l LocalFileSystemAbstraction) Mkdir(filename string, mode os.FileMode) error {
- return os.Mkdir(filename, mode)
- }
- func (l LocalFileSystemAbstraction) MkdirAll(filename string, mode os.FileMode) error {
- return os.MkdirAll(filename, mode)
- }
- func (l LocalFileSystemAbstraction) Name() string {
- return ""
- }
- func (l LocalFileSystemAbstraction) Open(filename string) (arozfs.File, error) {
- return os.Open(filename)
- }
- func (l LocalFileSystemAbstraction) OpenFile(filename string, flag int, perm os.FileMode) (arozfs.File, error) {
- return os.OpenFile(filename, flag, perm)
- }
- func (l LocalFileSystemAbstraction) Remove(filename string) error {
- return os.Remove(filename)
- }
- func (l LocalFileSystemAbstraction) RemoveAll(path string) error {
- return os.RemoveAll(path)
- }
- func (l LocalFileSystemAbstraction) Rename(oldname, newname string) error {
- return os.Rename(oldname, newname)
- }
- func (l LocalFileSystemAbstraction) Stat(filename string) (os.FileInfo, error) {
- return os.Stat(filename)
- }
- func (l LocalFileSystemAbstraction) Close() error {
- return nil
- }
- /*
- Abstraction Utilities
- */
- func (l LocalFileSystemAbstraction) VirtualPathToRealPath(subpath string, username string) (string, error) {
- subpath = filepath.ToSlash(subpath)
- if strings.HasPrefix(subpath, l.UUID+":") {
- //This is full virtual path. Trim the uuid and correct the subpath
- subpath = subpath[len(l.UUID+":"):]
- }
- if l.Hierarchy == "user" {
- return filepath.ToSlash(filepath.Join(l.Rootpath, "users", username, subpath)), nil
- } else if l.Hierarchy == "public" {
- return filepath.ToSlash(filepath.Join(l.Rootpath, subpath)), nil
- }
- return "", arozfs.ErrVpathResolveFailed
- }
- func (l LocalFileSystemAbstraction) RealPathToVirtualPath(fullpath string, username string) (string, error) {
- /*
- thisStorageRootAbs, err := filepath.Abs(l.Rootpath)
- if err != nil {
- //Fail to abs this path. Maybe this is a emulated file system?
- thisStorageRootAbs = l.Rootpath
- }
- thisStorageRootAbs = filepath.ToSlash(filepath.Clean(thisStorageRootAbs))
- subPath := ""
- if len(fullpath) > len(l.Rootpath) && filepath.ToSlash(fullpath[:len(l.Rootpath)]) == filepath.ToSlash(l.Rootpath) {
- //This realpath is in contained inside this storage root
- subtractionPath := l.Rootpath
- if l.Hierarchy == "user" {
- //Check if this file is belongs to this user
- startOffset := len(filepath.Clean(l.Rootpath) + "/users/")
- if len(fullpath) < startOffset+len(username) {
- //This file is not owned by this user
- return "", errors.New("File not owned by this user")
- } else {
- userNameMatch := fullpath[startOffset : startOffset+len(username)]
- if userNameMatch != username {
- //This file is not owned by this user
- return "", errors.New("File not owned by this user")
- }
- }
- //Generate subtraction path
- subtractionPath = filepath.ToSlash(filepath.Clean(filepath.Join(l.Rootpath, "users", username)))
- }
- if len(subtractionPath) < len(fullpath) {
- subPath = fullpath[len(subtractionPath):]
- }
- } else if len(fullpath) > len(thisStorageRootAbs) && filepath.ToSlash(fullpath[:len(thisStorageRootAbs)]) == filepath.ToSlash(thisStorageRootAbs) {
- //The realpath contains the absolute path of this storage root
- subtractionPath := thisStorageRootAbs
- if l.Hierarchy == "user" {
- subtractionPath = thisStorageRootAbs + "/users/" + username + "/"
- }
- if len(subtractionPath) < len(fullpath) {
- subPath = fullpath[len(subtractionPath):]
- }
- } else if filepath.ToSlash(fullpath) == filepath.ToSlash(l.Rootpath) {
- //Storage Root's root
- subPath = ""
- }
- if len(subPath) > 1 && subPath[:1] == "/" {
- subPath = subPath[1:]
- }
- */
- fullpath = filepath.ToSlash(fullpath)
- if strings.HasPrefix(fullpath, l.UUID+":") && !utils.FileExists(fullpath) {
- return "", arozfs.ErrRpathResolveFailed
- }
- prefix := filepath.ToSlash(filepath.Join(l.Rootpath, "users", username))
- if l.Hierarchy == "public" {
- prefix = filepath.ToSlash(l.Rootpath)
- }
- fullpath = filepath.ToSlash(filepath.Clean(fullpath))
- subPath := strings.TrimPrefix(fullpath, prefix)
- if !strings.HasPrefix(subPath, "/") {
- subPath = "/" + subPath
- }
- return l.UUID + ":" + filepath.ToSlash(subPath), nil
- }
- func (l LocalFileSystemAbstraction) FileExists(realpath string) bool {
- return utils.FileExists(realpath)
- }
- func (l LocalFileSystemAbstraction) IsDir(realpath string) bool {
- if !l.FileExists(realpath) {
- return false
- }
- fi, err := l.Stat(realpath)
- if err != nil {
- return false
- }
- switch mode := fi.Mode(); {
- case mode.IsDir():
- return true
- case mode.IsRegular():
- return false
- }
- return false
- }
- func (l LocalFileSystemAbstraction) Glob(realpathWildcard string) ([]string, error) {
- return filepath.Glob(realpathWildcard)
- }
- func (l LocalFileSystemAbstraction) GetFileSize(realpath string) int64 {
- fi, err := os.Stat(realpath)
- if err != nil {
- return 0
- }
- // get the size
- return fi.Size()
- }
- func (l LocalFileSystemAbstraction) GetModTime(realpath string) (int64, error) {
- f, err := os.Open(realpath)
- if err != nil {
- return -1, err
- }
- statinfo, err := f.Stat()
- if err != nil {
- return -1, err
- }
- f.Close()
- return statinfo.ModTime().Unix(), nil
- }
- func (l LocalFileSystemAbstraction) WriteFile(filename string, content []byte, mode os.FileMode) error {
- return os.WriteFile(filename, content, mode)
- }
- func (l LocalFileSystemAbstraction) ReadFile(filename string) ([]byte, error) {
- return os.ReadFile(filename)
- }
- func (l LocalFileSystemAbstraction) ReadDir(filename string) ([]fs.DirEntry, error) {
- return os.ReadDir(filename)
- }
- func (l LocalFileSystemAbstraction) WriteStream(filename string, stream io.Reader, mode os.FileMode) error {
- f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, mode)
- if err != nil {
- return err
- }
- _, err = io.Copy(f, stream)
- f.Close()
- return err
- }
- func (l LocalFileSystemAbstraction) ReadStream(filename string) (io.ReadCloser, error) {
- f, err := os.OpenFile(filename, os.O_RDONLY, 0644)
- if err != nil {
- return nil, err
- }
- return f, nil
- }
- func (l LocalFileSystemAbstraction) Walk(root string, walkFn filepath.WalkFunc) error {
- return filepath.Walk(root, walkFn)
- }
- func (l LocalFileSystemAbstraction) Heartbeat() error {
- return nil
- }
|