|
@@ -1,863 +1,901 @@
|
|
|
-package agi
|
|
|
-
|
|
|
-import (
|
|
|
- "crypto/md5"
|
|
|
- "encoding/hex"
|
|
|
- "encoding/json"
|
|
|
- "errors"
|
|
|
- "io"
|
|
|
- "io/fs"
|
|
|
- "log"
|
|
|
- "os"
|
|
|
- "path/filepath"
|
|
|
-
|
|
|
- "github.com/robertkrimen/otto"
|
|
|
- "imuslab.com/arozos/mod/filesystem/fssort"
|
|
|
- "imuslab.com/arozos/mod/filesystem/hidden"
|
|
|
- user "imuslab.com/arozos/mod/user"
|
|
|
-)
|
|
|
-
|
|
|
-/*
|
|
|
- AJGI File Processing Library
|
|
|
-
|
|
|
- This is a library for handling image related functionalities in agi scripts.
|
|
|
-
|
|
|
- By Alanyueng 2020 <- This person write shitty code that need me to tidy up (by tobychui)
|
|
|
- Complete rewrite by tobychui in Sept 2020
|
|
|
-*/
|
|
|
-
|
|
|
-func (g *Gateway) FileLibRegister() {
|
|
|
- err := g.RegisterLib("filelib", g.injectFileLibFunctions)
|
|
|
- if err != nil {
|
|
|
- log.Fatal(err)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func (g *Gateway) injectFileLibFunctions(vm *otto.Otto, u *user.User) {
|
|
|
-
|
|
|
- //Legacy File system API
|
|
|
- //writeFile(virtualFilepath, content) => return true/false when succeed / failed
|
|
|
- vm.Set("_filelib_writeFile", func(call otto.FunctionCall) otto.Value {
|
|
|
- vpath, err := call.Argument(0).ToString()
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Check for permission
|
|
|
- if !u.CanWrite(vpath) {
|
|
|
- panic(vm.MakeCustomError("PermissionDenied", "Path access denied: "+vpath))
|
|
|
- }
|
|
|
-
|
|
|
- content, err := call.Argument(1).ToString()
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Check if there is quota for the given length
|
|
|
- if !u.StorageQuota.HaveSpace(int64(len(content))) {
|
|
|
- //User have no remaining storage quota
|
|
|
- g.raiseError(errors.New("Storage Quota Fulled"))
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Translate the virtual path to realpath
|
|
|
- fsh, rpath, err := virtualPathToRealPath(vpath, u)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Check if file already exists.
|
|
|
- if fsh.FileSystemAbstraction.FileExists(rpath) {
|
|
|
- //Check if this user own this file
|
|
|
- isOwner := u.IsOwnerOfFile(fsh, vpath)
|
|
|
- if isOwner {
|
|
|
- //This user own this system. Remove this file from his quota
|
|
|
- u.RemoveOwnershipFromFile(fsh, vpath)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //Create and write to file using ioutil
|
|
|
- err = fsh.FileSystemAbstraction.WriteFile(rpath, []byte(content), 0755)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Add the filesize to user quota
|
|
|
- u.SetOwnerOfFile(fsh, vpath)
|
|
|
-
|
|
|
- reply, _ := vm.ToValue(true)
|
|
|
- return reply
|
|
|
- })
|
|
|
-
|
|
|
- vm.Set("_filelib_deleteFile", func(call otto.FunctionCall) otto.Value {
|
|
|
- vpath, err := call.Argument(0).ToString()
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Check for permission
|
|
|
- if !u.CanWrite(vpath) {
|
|
|
- panic(vm.MakeCustomError("PermissionDenied", "Path access denied: "+vpath))
|
|
|
- }
|
|
|
-
|
|
|
- //Translate the virtual path to realpath
|
|
|
- fsh, rpath, err := virtualPathToRealPath(vpath, u)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Check if file already exists.
|
|
|
- if fsh.FileSystemAbstraction.FileExists(rpath) {
|
|
|
- //Check if this user own this file
|
|
|
- isOwner := u.IsOwnerOfFile(fsh, vpath)
|
|
|
- if isOwner {
|
|
|
- //This user own this system. Remove this file from his quota
|
|
|
- u.RemoveOwnershipFromFile(fsh, vpath)
|
|
|
- }
|
|
|
- } else {
|
|
|
- g.raiseError(errors.New("File not exists"))
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Remove the file
|
|
|
- fsh.FileSystemAbstraction.Remove(rpath)
|
|
|
-
|
|
|
- reply, _ := vm.ToValue(true)
|
|
|
- return reply
|
|
|
- })
|
|
|
-
|
|
|
- //readFile(virtualFilepath) => return content in string
|
|
|
- vm.Set("_filelib_readFile", func(call otto.FunctionCall) otto.Value {
|
|
|
- vpath, err := call.Argument(0).ToString()
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Check for permission
|
|
|
- if !u.CanRead(vpath) {
|
|
|
- panic(vm.MakeCustomError("PermissionDenied", "Path access denied: "+vpath))
|
|
|
- }
|
|
|
-
|
|
|
- //Translate the virtual path to realpath
|
|
|
- fsh, rpath, err := virtualPathToRealPath(vpath, u)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Create and write to file using ioUtil
|
|
|
- content, err := fsh.FileSystemAbstraction.ReadFile(rpath)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
- reply, _ := vm.ToValue(string(content))
|
|
|
- return reply
|
|
|
- })
|
|
|
-
|
|
|
- //Listdir
|
|
|
- //readdir("user:/Desktop") => return filelist in array
|
|
|
- /*
|
|
|
- vm.Set("_filelib_readdir", func(call otto.FunctionCall) otto.Value {
|
|
|
- vpath, err := call.Argument(0).ToString()
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Translate the virtual path to realpath
|
|
|
- fsh, rpath, err := virtualPathToRealPath(vpath, u)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
- fshAbs := fsh.FileSystemAbstraction
|
|
|
-
|
|
|
- rpath = filepath.ToSlash(filepath.Clean(rpath)) + "/*"
|
|
|
- fileList, err := fshAbs.Glob(rpath)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Translate all paths to virtual paths
|
|
|
- results := []string{}
|
|
|
- for _, file := range fileList {
|
|
|
- isHidden, _ := hidden.IsHidden(file, true)
|
|
|
- if !isHidden {
|
|
|
- thisRpath, _ := fshAbs.RealPathToVirtualPath(file, u.Username)
|
|
|
- results = append(results, thisRpath)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- reply, _ := vm.ToValue(results)
|
|
|
- return reply
|
|
|
- })
|
|
|
- */
|
|
|
-
|
|
|
- //Usage
|
|
|
- //filelib.walk("user:/") => list everything recursively
|
|
|
- //filelib.walk("user:/", "folder") => list all folder recursively
|
|
|
- //filelib.walk("user:/", "file") => list all files recursively
|
|
|
- vm.Set("_filelib_walk", func(call otto.FunctionCall) otto.Value {
|
|
|
- vpath, err := call.Argument(0).ToString()
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
- mode, err := call.Argument(1).ToString()
|
|
|
- if err != nil {
|
|
|
- mode = "all"
|
|
|
- }
|
|
|
-
|
|
|
- fsh, rpath, err := virtualPathToRealPath(vpath, u)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
- results := []string{}
|
|
|
- fsh.FileSystemAbstraction.Walk(rpath, func(path string, info os.FileInfo, err error) error {
|
|
|
- if err != nil {
|
|
|
- //Ignore this error file and continue
|
|
|
- return nil
|
|
|
- }
|
|
|
- thisVpath, err := realpathToVirtualpath(fsh, path, u)
|
|
|
- if err != nil {
|
|
|
- return nil
|
|
|
- }
|
|
|
- if mode == "file" {
|
|
|
- if !info.IsDir() {
|
|
|
- results = append(results, thisVpath)
|
|
|
- }
|
|
|
- } else if mode == "folder" {
|
|
|
- if info.IsDir() {
|
|
|
- results = append(results, thisVpath)
|
|
|
- }
|
|
|
- } else {
|
|
|
- results = append(results, thisVpath)
|
|
|
- }
|
|
|
-
|
|
|
- return nil
|
|
|
- })
|
|
|
-
|
|
|
- reply, _ := vm.ToValue(results)
|
|
|
- return reply
|
|
|
- })
|
|
|
-
|
|
|
- //Glob
|
|
|
- //glob("user:/Desktop/*.mp3") => return fileList in array
|
|
|
- //glob("/") => return a list of root directories
|
|
|
- //glob("user:/Desktop/*", "mostRecent") => return fileList in mostRecent sorting mode
|
|
|
- //glob("user:/Desktop/*", "user") => return fileList in array in user prefered sorting method
|
|
|
- vm.Set("_filelib_glob", func(call otto.FunctionCall) otto.Value {
|
|
|
- regex, err := call.Argument(0).ToString()
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- userSortMode, err := call.Argument(1).ToString()
|
|
|
- if err != nil || userSortMode == "" || userSortMode == "undefined" {
|
|
|
- userSortMode = "default"
|
|
|
- }
|
|
|
-
|
|
|
- //Handle when regex = "." or "./" (listroot)
|
|
|
- if filepath.ToSlash(filepath.Clean(regex)) == "/" || filepath.Clean(regex) == "." {
|
|
|
- //List Root
|
|
|
- rootDirs := []string{}
|
|
|
- fileHandlers := u.GetAllFileSystemHandler()
|
|
|
- for _, fsh := range fileHandlers {
|
|
|
- if fsh.Hierarchy == "backup" {
|
|
|
-
|
|
|
- } else {
|
|
|
- rootDirs = append(rootDirs, fsh.UUID+":/")
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- reply, _ := vm.ToValue(rootDirs)
|
|
|
- return reply
|
|
|
- } else {
|
|
|
- //Check for permission
|
|
|
- if !u.CanRead(regex) {
|
|
|
- panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
- }
|
|
|
- //This function can only handle wildcard in filename but not in dir name
|
|
|
- vrootPath := filepath.Dir(regex)
|
|
|
- regexFilename := filepath.Base(regex)
|
|
|
-
|
|
|
- //Rewrite and validate the sort mode
|
|
|
- if userSortMode == "user" {
|
|
|
- //Use user sorting mode.
|
|
|
- if g.Option.UserHandler.GetDatabase().KeyExists("fs-sortpref", u.Username+"/"+filepath.ToSlash(filepath.Clean(vrootPath))) {
|
|
|
- g.Option.UserHandler.GetDatabase().Read("fs-sortpref", u.Username+"/"+filepath.ToSlash(filepath.Clean(vrootPath)), &userSortMode)
|
|
|
- } else {
|
|
|
- userSortMode = "default"
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if !fssort.SortModeIsSupported(userSortMode) {
|
|
|
- log.Println("[AGI] Sort mode: " + userSortMode + " not supported. Using default")
|
|
|
- userSortMode = "default"
|
|
|
- }
|
|
|
-
|
|
|
- //Translate the virtual path to realpath
|
|
|
- fsh, rrootPath, err := virtualPathToRealPath(vrootPath, u)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- suitableFiles, err := fsh.FileSystemAbstraction.Glob(filepath.Join(rrootPath, regexFilename))
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- fileList := []string{}
|
|
|
- fis := []fs.FileInfo{}
|
|
|
- for _, thisFile := range suitableFiles {
|
|
|
- fi, err := fsh.FileSystemAbstraction.Stat(thisFile)
|
|
|
- if err == nil {
|
|
|
- fileList = append(fileList, thisFile)
|
|
|
- fis = append(fis, fi)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //Sort the files
|
|
|
- newFilelist := fssort.SortFileList(fileList, fis, userSortMode)
|
|
|
-
|
|
|
- //Return the results in virtual paths
|
|
|
- results := []string{}
|
|
|
- for _, file := range newFilelist {
|
|
|
- isHidden, _ := hidden.IsHidden(file, true)
|
|
|
- if isHidden {
|
|
|
- //Hidden file. Skip this
|
|
|
- continue
|
|
|
- }
|
|
|
- thisVpath, _ := realpathToVirtualpath(fsh, file, u)
|
|
|
- results = append(results, thisVpath)
|
|
|
- }
|
|
|
- reply, _ := vm.ToValue(results)
|
|
|
- return reply
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- //Advance Glob using file system special Glob, cannot use to scan root dirs
|
|
|
- vm.Set("_filelib_aglob", func(call otto.FunctionCall) otto.Value {
|
|
|
- regex, err := call.Argument(0).ToString()
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- userSortMode, err := call.Argument(1).ToString()
|
|
|
- if err != nil || userSortMode == "" || userSortMode == "undefined" {
|
|
|
- userSortMode = "default"
|
|
|
- }
|
|
|
-
|
|
|
- if regex != "/" && !u.CanRead(regex) {
|
|
|
- panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
- }
|
|
|
-
|
|
|
- //This function can only handle wildcard in filename but not in dir name
|
|
|
- vrootPath := filepath.Dir(regex)
|
|
|
- regexFilename := filepath.Base(regex)
|
|
|
-
|
|
|
- //Rewrite and validate the sort mode
|
|
|
- if userSortMode == "user" {
|
|
|
- //Use user sorting mode.
|
|
|
- if g.Option.UserHandler.GetDatabase().KeyExists("fs-sortpref", u.Username+"/"+filepath.ToSlash(filepath.Clean(vrootPath))) {
|
|
|
- g.Option.UserHandler.GetDatabase().Read("fs-sortpref", u.Username+"/"+filepath.ToSlash(filepath.Clean(vrootPath)), &userSortMode)
|
|
|
- } else {
|
|
|
- userSortMode = "default"
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if !fssort.SortModeIsSupported(userSortMode) {
|
|
|
- log.Println("[AGI] Sort mode: " + userSortMode + " not supported. Using default")
|
|
|
- userSortMode = "default"
|
|
|
- }
|
|
|
-
|
|
|
- //Translate the virtual path to realpath
|
|
|
- fsh, err := u.GetFileSystemHandlerFromVirtualPath(vrootPath)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
- fshAbs := fsh.FileSystemAbstraction
|
|
|
- rrootPath, _ := fshAbs.VirtualPathToRealPath(vrootPath, u.Username)
|
|
|
- suitableFiles, err := fshAbs.Glob(filepath.Join(rrootPath, regexFilename))
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- fileList := []string{}
|
|
|
- fis := []fs.FileInfo{}
|
|
|
- for _, thisFile := range suitableFiles {
|
|
|
- fi, err := fsh.FileSystemAbstraction.Stat(thisFile)
|
|
|
- if err == nil {
|
|
|
- fileList = append(fileList, thisFile)
|
|
|
- fis = append(fis, fi)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //Sort the files
|
|
|
- newFilelist := fssort.SortFileList(fileList, fis, userSortMode)
|
|
|
-
|
|
|
- //Parse the results (Only extract the filepath)
|
|
|
- results := []string{}
|
|
|
- for _, filename := range newFilelist {
|
|
|
- isHidden, _ := hidden.IsHidden(filename, true)
|
|
|
- if isHidden {
|
|
|
- //Hidden file. Skip this
|
|
|
- continue
|
|
|
- }
|
|
|
- thisVpath, _ := realpathToVirtualpath(fsh, filename, u)
|
|
|
- results = append(results, thisVpath)
|
|
|
- }
|
|
|
- reply, _ := vm.ToValue(results)
|
|
|
- return reply
|
|
|
- })
|
|
|
-
|
|
|
- vm.Set("_filelib_readdir", func(call otto.FunctionCall) otto.Value {
|
|
|
- vpath, err := call.Argument(0).ToString()
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Check for permission
|
|
|
- if !u.CanRead(vpath) {
|
|
|
- panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
- }
|
|
|
-
|
|
|
- userSortMode, err := call.Argument(1).ToString()
|
|
|
- if err != nil || userSortMode == "" || userSortMode == "undefined" {
|
|
|
- userSortMode = "default"
|
|
|
- }
|
|
|
-
|
|
|
- //Rewrite and validate the sort mode
|
|
|
- if userSortMode == "user" {
|
|
|
- //Use user sorting mode.
|
|
|
- if g.Option.UserHandler.GetDatabase().KeyExists("fs-sortpref", u.Username+"/"+filepath.ToSlash(filepath.Clean(vpath))) {
|
|
|
- g.Option.UserHandler.GetDatabase().Read("fs-sortpref", u.Username+"/"+filepath.ToSlash(filepath.Clean(vpath)), &userSortMode)
|
|
|
- } else {
|
|
|
- userSortMode = "default"
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if !fssort.SortModeIsSupported(userSortMode) {
|
|
|
- log.Println("[AGI] Sort mode: " + userSortMode + " not supported. Using default")
|
|
|
- userSortMode = "default"
|
|
|
- }
|
|
|
-
|
|
|
- fsh, err := u.GetFileSystemHandlerFromVirtualPath(vpath)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
- fshAbs := fsh.FileSystemAbstraction
|
|
|
- rpath, err := fshAbs.VirtualPathToRealPath(vpath, u.Username)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- dirEntry, err := fshAbs.ReadDir(rpath)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- type fileInfo struct {
|
|
|
- Filename string
|
|
|
- Filepath string
|
|
|
- Ext string
|
|
|
- Filesize int64
|
|
|
- Modtime int64
|
|
|
- IsDir bool
|
|
|
- }
|
|
|
-
|
|
|
- //Sort the dirEntry by file info, a bit slow :(
|
|
|
- if userSortMode != "default" {
|
|
|
- //Prepare the data structure for sorting
|
|
|
- newDirEntry := fssort.SortDirEntryList(dirEntry, userSortMode)
|
|
|
- dirEntry = newDirEntry
|
|
|
- }
|
|
|
-
|
|
|
- results := []fileInfo{}
|
|
|
- for _, de := range dirEntry {
|
|
|
- isHidden, _ := hidden.IsHidden(de.Name(), false)
|
|
|
- if isHidden {
|
|
|
- continue
|
|
|
- }
|
|
|
- fstat, _ := de.Info()
|
|
|
- vpath, _ := realpathToVirtualpath(fsh, filepath.ToSlash(filepath.Join(rpath, de.Name())), u)
|
|
|
- thisInfo := fileInfo{
|
|
|
- Filename: de.Name(),
|
|
|
- Filepath: vpath,
|
|
|
- Ext: filepath.Ext(de.Name()),
|
|
|
- Filesize: fstat.Size(),
|
|
|
- Modtime: fstat.ModTime().Unix(),
|
|
|
- IsDir: de.IsDir(),
|
|
|
- }
|
|
|
-
|
|
|
- results = append(results, thisInfo)
|
|
|
- }
|
|
|
-
|
|
|
- js, _ := json.Marshal(results)
|
|
|
- r, _ := vm.ToValue(string(js))
|
|
|
- return r
|
|
|
- })
|
|
|
-
|
|
|
- //filesize("user:/Desktop/test.txt")
|
|
|
- vm.Set("_filelib_filesize", func(call otto.FunctionCall) otto.Value {
|
|
|
- vpath, err := call.Argument(0).ToString()
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Check for permission
|
|
|
- if !u.CanRead(vpath) {
|
|
|
- panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
- }
|
|
|
-
|
|
|
- fsh, err := u.GetFileSystemHandlerFromVirtualPath(vpath)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
- fshAbs := fsh.FileSystemAbstraction
|
|
|
- rpath, err := fshAbs.VirtualPathToRealPath(vpath, u.Username)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Get filesize of file
|
|
|
- rawsize := fshAbs.GetFileSize(rpath)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- reply, _ := vm.ToValue(rawsize)
|
|
|
- return reply
|
|
|
- })
|
|
|
-
|
|
|
- //fileExists("user:/Desktop/test.txt") => return true / false
|
|
|
- vm.Set("_filelib_fileExists", func(call otto.FunctionCall) otto.Value {
|
|
|
- vpath, err := call.Argument(0).ToString()
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Check for permission
|
|
|
- if !u.CanRead(vpath) {
|
|
|
- panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
- }
|
|
|
-
|
|
|
- fsh, err := u.GetFileSystemHandlerFromVirtualPath(vpath)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
- fshAbs := fsh.FileSystemAbstraction
|
|
|
- rpath, err := fshAbs.VirtualPathToRealPath(vpath, u.Username)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- if fshAbs.FileExists(rpath) {
|
|
|
- return otto.TrueValue()
|
|
|
- } else {
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- //fileExists("user:/Desktop/test.txt") => return true / false
|
|
|
- vm.Set("_filelib_isDir", func(call otto.FunctionCall) otto.Value {
|
|
|
- vpath, err := call.Argument(0).ToString()
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Check for permission
|
|
|
- if !u.CanRead(vpath) {
|
|
|
- panic(vm.MakeCustomError("PermissionDenied", "Path access denied: "+vpath))
|
|
|
- }
|
|
|
-
|
|
|
- //Translate the virtual path to realpath
|
|
|
- fsh, rpath, err := virtualPathToRealPath(vpath, u)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- if _, err := fsh.FileSystemAbstraction.Stat(rpath); os.IsNotExist(err) {
|
|
|
- //File not exists
|
|
|
- panic(vm.MakeCustomError("File Not Exists", "Required path not exists"))
|
|
|
- }
|
|
|
-
|
|
|
- if fsh.FileSystemAbstraction.IsDir(rpath) {
|
|
|
- return otto.TrueValue()
|
|
|
- } else {
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- //Make directory command
|
|
|
- vm.Set("_filelib_mkdir", func(call otto.FunctionCall) otto.Value {
|
|
|
- vdir, err := call.Argument(0).ToString()
|
|
|
- if err != nil {
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Check for permission
|
|
|
- if !u.CanWrite(vdir) {
|
|
|
- panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
- }
|
|
|
-
|
|
|
- //Translate the path to realpath
|
|
|
- fsh, rdir, err := virtualPathToRealPath(vdir, u)
|
|
|
- if err != nil {
|
|
|
- log.Println(err.Error())
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Create the directory at rdir location
|
|
|
- err = fsh.FileSystemAbstraction.MkdirAll(rdir, 0755)
|
|
|
- if err != nil {
|
|
|
- log.Println(err.Error())
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- return otto.TrueValue()
|
|
|
- })
|
|
|
-
|
|
|
- //Get MD5 of the given filepath, not implemented
|
|
|
- vm.Set("_filelib_md5", func(call otto.FunctionCall) otto.Value {
|
|
|
- vpath, err := call.Argument(0).ToString()
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Check for permission
|
|
|
- if !u.CanRead(vpath) {
|
|
|
- panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
- }
|
|
|
-
|
|
|
- fsh, err := u.GetFileSystemHandlerFromVirtualPath(vpath)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
- fshAbs := fsh.FileSystemAbstraction
|
|
|
- rpath, err := fshAbs.VirtualPathToRealPath(vpath, u.Username)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- f, err := fshAbs.ReadStream(rpath)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- defer f.Close()
|
|
|
- h := md5.New()
|
|
|
- if _, err := io.Copy(h, f); err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- md5Sum := hex.EncodeToString(h.Sum(nil))
|
|
|
- result, _ := vm.ToValue(md5Sum)
|
|
|
- return result
|
|
|
- })
|
|
|
-
|
|
|
- //Get the root name of the given virtual path root
|
|
|
- vm.Set("_filelib_rname", func(call otto.FunctionCall) otto.Value {
|
|
|
- //Get virtual path from the function input
|
|
|
- vpath, err := call.Argument(0).ToString()
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Get fs handler from the vpath
|
|
|
- fsHandler, err := u.GetFileSystemHandlerFromVirtualPath(vpath)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Return the name of the fsHandler
|
|
|
- name, _ := vm.ToValue(fsHandler.Name)
|
|
|
- return name
|
|
|
-
|
|
|
- })
|
|
|
-
|
|
|
- vm.Set("_filelib_mtime", func(call otto.FunctionCall) otto.Value {
|
|
|
- vpath, err := call.Argument(0).ToString()
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Check for permission
|
|
|
- if !u.CanRead(vpath) {
|
|
|
- panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
- }
|
|
|
-
|
|
|
- parseToUnix, err := call.Argument(1).ToBoolean()
|
|
|
- if err != nil {
|
|
|
- parseToUnix = false
|
|
|
- }
|
|
|
-
|
|
|
- fsh, rpath, err := virtualPathToRealPath(vpath, u)
|
|
|
- if err != nil {
|
|
|
- log.Println(err.Error())
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- info, err := fsh.FileSystemAbstraction.Stat(rpath)
|
|
|
- if err != nil {
|
|
|
- log.Println(err.Error())
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- modTime := info.ModTime()
|
|
|
- if parseToUnix {
|
|
|
- result, _ := otto.ToValue(modTime.Unix())
|
|
|
- return result
|
|
|
- } else {
|
|
|
- result, _ := otto.ToValue(modTime.Format("2006-01-02 15:04:05"))
|
|
|
- return result
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- //ArozOS v2.0 New features
|
|
|
- //Reading or writing from hex to target virtual filepath
|
|
|
-
|
|
|
- //Write binary from hex string
|
|
|
- vm.Set("_filelib_writeBinaryFile", func(call otto.FunctionCall) otto.Value {
|
|
|
- vpath, err := call.Argument(0).ToString()
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Check for permission
|
|
|
- if !u.CanWrite(vpath) {
|
|
|
- panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
- }
|
|
|
-
|
|
|
- hexContent, err := call.Argument(1).ToString()
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Get the target vpath
|
|
|
- fsh, rpath, err := virtualPathToRealPath(vpath, u)
|
|
|
- if err != nil {
|
|
|
- log.Println(err.Error())
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Decode the hex content to bytes
|
|
|
- hexContentInByte, err := hex.DecodeString(hexContent)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Write the file to target file
|
|
|
- err = fsh.FileSystemAbstraction.WriteFile(rpath, hexContentInByte, 0775)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.FalseValue()
|
|
|
- }
|
|
|
-
|
|
|
- return otto.TrueValue()
|
|
|
-
|
|
|
- })
|
|
|
-
|
|
|
- //Read file from external fsh. Small file only
|
|
|
- vm.Set("_filelib_readBinaryFile", func(call otto.FunctionCall) otto.Value {
|
|
|
- vpath, err := call.Argument(0).ToString()
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.NullValue()
|
|
|
- }
|
|
|
-
|
|
|
- //Check for permission
|
|
|
- if !u.CanRead(vpath) {
|
|
|
- panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
- }
|
|
|
-
|
|
|
- //Get the target vpath
|
|
|
- fsh, rpath, err := virtualPathToRealPath(vpath, u)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.NullValue()
|
|
|
- }
|
|
|
-
|
|
|
- if !fsh.FileSystemAbstraction.FileExists(rpath) {
|
|
|
- //Check if the target file exists
|
|
|
- g.raiseError(err)
|
|
|
- return otto.NullValue()
|
|
|
- }
|
|
|
-
|
|
|
- content, err := fsh.FileSystemAbstraction.ReadFile(rpath)
|
|
|
- if err != nil {
|
|
|
- g.raiseError(err)
|
|
|
- return otto.NullValue()
|
|
|
- }
|
|
|
-
|
|
|
- hexifiedContent := hex.EncodeToString(content)
|
|
|
- val, _ := vm.ToValue(hexifiedContent)
|
|
|
- return val
|
|
|
-
|
|
|
- })
|
|
|
-
|
|
|
- //Other file operations, wip
|
|
|
-
|
|
|
- //Wrap all the native code function into an imagelib class
|
|
|
- vm.Run(`
|
|
|
- var filelib = {};
|
|
|
- filelib.writeFile = _filelib_writeFile;
|
|
|
- filelib.readFile = _filelib_readFile;
|
|
|
- filelib.deleteFile = _filelib_deleteFile;
|
|
|
- filelib.walk = _filelib_walk;
|
|
|
- filelib.glob = _filelib_glob;
|
|
|
- filelib.aglob = _filelib_aglob;
|
|
|
- filelib.filesize = _filelib_filesize;
|
|
|
- filelib.fileExists = _filelib_fileExists;
|
|
|
- filelib.isDir = _filelib_isDir;
|
|
|
- filelib.md5 = _filelib_md5;
|
|
|
- filelib.mkdir = _filelib_mkdir;
|
|
|
- filelib.mtime = _filelib_mtime;
|
|
|
- filelib.rootName = _filelib_rname;
|
|
|
-
|
|
|
- filelib.readdir = function(path, sortmode){
|
|
|
- var s = _filelib_readdir(path, sortmode);
|
|
|
- return JSON.parse(s);
|
|
|
- };
|
|
|
- `)
|
|
|
-}
|
|
|
+package agi
|
|
|
+
|
|
|
+import (
|
|
|
+ "crypto/md5"
|
|
|
+ "encoding/hex"
|
|
|
+ "encoding/json"
|
|
|
+ "errors"
|
|
|
+ "io"
|
|
|
+ "io/fs"
|
|
|
+ "log"
|
|
|
+ "os"
|
|
|
+ "path/filepath"
|
|
|
+
|
|
|
+ "github.com/robertkrimen/otto"
|
|
|
+ "imuslab.com/arozos/mod/filesystem"
|
|
|
+ "imuslab.com/arozos/mod/filesystem/fssort"
|
|
|
+ "imuslab.com/arozos/mod/filesystem/hidden"
|
|
|
+ user "imuslab.com/arozos/mod/user"
|
|
|
+)
|
|
|
+
|
|
|
+/*
|
|
|
+ AJGI File Processing Library
|
|
|
+
|
|
|
+ This is a library for handling image related functionalities in agi scripts.
|
|
|
+
|
|
|
+ By Alanyueng 2020 <- This person write shitty code that need me to tidy up (by tobychui)
|
|
|
+ Complete rewrite by tobychui in Sept 2020
|
|
|
+*/
|
|
|
+
|
|
|
+func (g *Gateway) FileLibRegister() {
|
|
|
+ err := g.RegisterLib("filelib", g.injectFileLibFunctions)
|
|
|
+ if err != nil {
|
|
|
+ log.Fatal(err)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func (g *Gateway) injectFileLibFunctions(vm *otto.Otto, u *user.User, scriptFsh *filesystem.FileSystemHandler, scriptPath string) {
|
|
|
+ //writeFile(virtualFilepath, content) => return true/false when succeed / failed
|
|
|
+ vm.Set("_filelib_writeFile", func(call otto.FunctionCall) otto.Value {
|
|
|
+ vpath, err := call.Argument(0).ToString()
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Rewrite the vpath if it is relative
|
|
|
+ vpath = relativeVpathRewrite(scriptFsh, vpath, vm, u)
|
|
|
+
|
|
|
+ //Check for permission
|
|
|
+ if !u.CanWrite(vpath) {
|
|
|
+ panic(vm.MakeCustomError("PermissionDenied", "Path access denied: "+vpath))
|
|
|
+ }
|
|
|
+
|
|
|
+ content, err := call.Argument(1).ToString()
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Check if there is quota for the given length
|
|
|
+ if !u.StorageQuota.HaveSpace(int64(len(content))) {
|
|
|
+ //User have no remaining storage quota
|
|
|
+ g.raiseError(errors.New("Storage Quota Fulled"))
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Translate the virtual path to realpath
|
|
|
+ fsh, rpath, err := virtualPathToRealPath(vpath, u)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Check if file already exists.
|
|
|
+ if fsh.FileSystemAbstraction.FileExists(rpath) {
|
|
|
+ //Check if this user own this file
|
|
|
+ isOwner := u.IsOwnerOfFile(fsh, vpath)
|
|
|
+ if isOwner {
|
|
|
+ //This user own this system. Remove this file from his quota
|
|
|
+ u.RemoveOwnershipFromFile(fsh, vpath)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //Create and write to file using ioutil
|
|
|
+ err = fsh.FileSystemAbstraction.WriteFile(rpath, []byte(content), 0755)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Add the filesize to user quota
|
|
|
+ u.SetOwnerOfFile(fsh, vpath)
|
|
|
+
|
|
|
+ reply, _ := vm.ToValue(true)
|
|
|
+ return reply
|
|
|
+ })
|
|
|
+
|
|
|
+ vm.Set("_filelib_deleteFile", func(call otto.FunctionCall) otto.Value {
|
|
|
+ vpath, err := call.Argument(0).ToString()
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Rewrite the vpath if it is relative
|
|
|
+ vpath = relativeVpathRewrite(scriptFsh, vpath, vm, u)
|
|
|
+
|
|
|
+ //Check for permission
|
|
|
+ if !u.CanWrite(vpath) {
|
|
|
+ panic(vm.MakeCustomError("PermissionDenied", "Path access denied: "+vpath))
|
|
|
+ }
|
|
|
+
|
|
|
+ //Translate the virtual path to realpath
|
|
|
+ fsh, rpath, err := virtualPathToRealPath(vpath, u)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Check if file already exists.
|
|
|
+ if fsh.FileSystemAbstraction.FileExists(rpath) {
|
|
|
+ //Check if this user own this file
|
|
|
+ isOwner := u.IsOwnerOfFile(fsh, vpath)
|
|
|
+ if isOwner {
|
|
|
+ //This user own this system. Remove this file from his quota
|
|
|
+ u.RemoveOwnershipFromFile(fsh, vpath)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ g.raiseError(errors.New("File not exists"))
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Remove the file
|
|
|
+ fsh.FileSystemAbstraction.Remove(rpath)
|
|
|
+
|
|
|
+ reply, _ := vm.ToValue(true)
|
|
|
+ return reply
|
|
|
+ })
|
|
|
+
|
|
|
+ //readFile(virtualFilepath) => return content in string
|
|
|
+ vm.Set("_filelib_readFile", func(call otto.FunctionCall) otto.Value {
|
|
|
+ vpath, err := call.Argument(0).ToString()
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Rewrite the vpath if it is relative
|
|
|
+ vpath = relativeVpathRewrite(scriptFsh, vpath, vm, u)
|
|
|
+
|
|
|
+ //Check for permission
|
|
|
+ if !u.CanRead(vpath) {
|
|
|
+ panic(vm.MakeCustomError("PermissionDenied", "Path access denied: "+vpath))
|
|
|
+ }
|
|
|
+
|
|
|
+ //Translate the virtual path to realpath
|
|
|
+ fsh, rpath, err := virtualPathToRealPath(vpath, u)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Create and write to file using ioUtil
|
|
|
+ content, err := fsh.FileSystemAbstraction.ReadFile(rpath)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+ reply, _ := vm.ToValue(string(content))
|
|
|
+ return reply
|
|
|
+ })
|
|
|
+
|
|
|
+ //Listdir
|
|
|
+ //readdir("user:/Desktop") => return filelist in array
|
|
|
+ /*
|
|
|
+ vm.Set("_filelib_readdir", func(call otto.FunctionCall) otto.Value {
|
|
|
+ vpath, err := call.Argument(0).ToString()
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Translate the virtual path to realpath
|
|
|
+ fsh, rpath, err := virtualPathToRealPath(vpath, u)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+ fshAbs := fsh.FileSystemAbstraction
|
|
|
+
|
|
|
+ rpath = filepath.ToSlash(filepath.Clean(rpath)) + "/*"
|
|
|
+ fileList, err := fshAbs.Glob(rpath)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Translate all paths to virtual paths
|
|
|
+ results := []string{}
|
|
|
+ for _, file := range fileList {
|
|
|
+ isHidden, _ := hidden.IsHidden(file, true)
|
|
|
+ if !isHidden {
|
|
|
+ thisRpath, _ := fshAbs.RealPathToVirtualPath(file, u.Username)
|
|
|
+ results = append(results, thisRpath)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ reply, _ := vm.ToValue(results)
|
|
|
+ return reply
|
|
|
+ })
|
|
|
+ */
|
|
|
+
|
|
|
+ //Usage
|
|
|
+ //filelib.walk("user:/") => list everything recursively
|
|
|
+ //filelib.walk("user:/", "folder") => list all folder recursively
|
|
|
+ //filelib.walk("user:/", "file") => list all files recursively
|
|
|
+ vm.Set("_filelib_walk", func(call otto.FunctionCall) otto.Value {
|
|
|
+ vpath, err := call.Argument(0).ToString()
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+ mode, err := call.Argument(1).ToString()
|
|
|
+ if err != nil {
|
|
|
+ mode = "all"
|
|
|
+ }
|
|
|
+
|
|
|
+ //Rewrite the vpath if it is relative
|
|
|
+ vpath = relativeVpathRewrite(scriptFsh, vpath, vm, u)
|
|
|
+
|
|
|
+ fsh, rpath, err := virtualPathToRealPath(vpath, u)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+ results := []string{}
|
|
|
+ fsh.FileSystemAbstraction.Walk(rpath, func(path string, info os.FileInfo, err error) error {
|
|
|
+ if err != nil {
|
|
|
+ //Ignore this error file and continue
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ thisVpath, err := realpathToVirtualpath(fsh, path, u)
|
|
|
+ if err != nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ if mode == "file" {
|
|
|
+ if !info.IsDir() {
|
|
|
+ results = append(results, thisVpath)
|
|
|
+ }
|
|
|
+ } else if mode == "folder" {
|
|
|
+ if info.IsDir() {
|
|
|
+ results = append(results, thisVpath)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ results = append(results, thisVpath)
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+ })
|
|
|
+
|
|
|
+ reply, _ := vm.ToValue(results)
|
|
|
+ return reply
|
|
|
+ })
|
|
|
+
|
|
|
+ //Glob
|
|
|
+ //glob("user:/Desktop/*.mp3") => return fileList in array
|
|
|
+ //glob("/") => return a list of root directories
|
|
|
+ //glob("user:/Desktop/*", "mostRecent") => return fileList in mostRecent sorting mode
|
|
|
+ //glob("user:/Desktop/*", "user") => return fileList in array in user prefered sorting method
|
|
|
+ vm.Set("_filelib_glob", func(call otto.FunctionCall) otto.Value {
|
|
|
+ regex, err := call.Argument(0).ToString()
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ userSortMode, err := call.Argument(1).ToString()
|
|
|
+ if err != nil || userSortMode == "" || userSortMode == "undefined" {
|
|
|
+ userSortMode = "default"
|
|
|
+ }
|
|
|
+
|
|
|
+ //Handle when regex = "." or "./" (listroot)
|
|
|
+ if filepath.ToSlash(filepath.Clean(regex)) == "/" || filepath.Clean(regex) == "." {
|
|
|
+ //List Root
|
|
|
+ rootDirs := []string{}
|
|
|
+ fileHandlers := u.GetAllFileSystemHandler()
|
|
|
+ for _, fsh := range fileHandlers {
|
|
|
+ if fsh.Hierarchy == "backup" {
|
|
|
+
|
|
|
+ } else {
|
|
|
+ rootDirs = append(rootDirs, fsh.UUID+":/")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ reply, _ := vm.ToValue(rootDirs)
|
|
|
+ return reply
|
|
|
+ } else {
|
|
|
+ //Check for permission
|
|
|
+ if !u.CanRead(regex) {
|
|
|
+ panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
+ }
|
|
|
+ //This function can only handle wildcard in filename but not in dir name
|
|
|
+ vrootPath := filepath.Dir(regex)
|
|
|
+ regexFilename := filepath.Base(regex)
|
|
|
+
|
|
|
+ //Rewrite and validate the sort mode
|
|
|
+ if userSortMode == "user" {
|
|
|
+ //Use user sorting mode.
|
|
|
+ if g.Option.UserHandler.GetDatabase().KeyExists("fs-sortpref", u.Username+"/"+filepath.ToSlash(filepath.Clean(vrootPath))) {
|
|
|
+ g.Option.UserHandler.GetDatabase().Read("fs-sortpref", u.Username+"/"+filepath.ToSlash(filepath.Clean(vrootPath)), &userSortMode)
|
|
|
+ } else {
|
|
|
+ userSortMode = "default"
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if !fssort.SortModeIsSupported(userSortMode) {
|
|
|
+ log.Println("[AGI] Sort mode: " + userSortMode + " not supported. Using default")
|
|
|
+ userSortMode = "default"
|
|
|
+ }
|
|
|
+
|
|
|
+ //Translate the virtual path to realpath
|
|
|
+ fsh, rrootPath, err := virtualPathToRealPath(vrootPath, u)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ suitableFiles, err := fsh.FileSystemAbstraction.Glob(filepath.Join(rrootPath, regexFilename))
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ fileList := []string{}
|
|
|
+ fis := []fs.FileInfo{}
|
|
|
+ for _, thisFile := range suitableFiles {
|
|
|
+ fi, err := fsh.FileSystemAbstraction.Stat(thisFile)
|
|
|
+ if err == nil {
|
|
|
+ fileList = append(fileList, thisFile)
|
|
|
+ fis = append(fis, fi)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //Sort the files
|
|
|
+ newFilelist := fssort.SortFileList(fileList, fis, userSortMode)
|
|
|
+
|
|
|
+ //Return the results in virtual paths
|
|
|
+ results := []string{}
|
|
|
+ for _, file := range newFilelist {
|
|
|
+ isHidden, _ := hidden.IsHidden(file, true)
|
|
|
+ if isHidden {
|
|
|
+ //Hidden file. Skip this
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ thisVpath, _ := realpathToVirtualpath(fsh, file, u)
|
|
|
+ results = append(results, thisVpath)
|
|
|
+ }
|
|
|
+ reply, _ := vm.ToValue(results)
|
|
|
+ return reply
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ //Advance Glob using file system special Glob, cannot use to scan root dirs
|
|
|
+ vm.Set("_filelib_aglob", func(call otto.FunctionCall) otto.Value {
|
|
|
+ regex, err := call.Argument(0).ToString()
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ userSortMode, err := call.Argument(1).ToString()
|
|
|
+ if err != nil || userSortMode == "" || userSortMode == "undefined" {
|
|
|
+ userSortMode = "default"
|
|
|
+ }
|
|
|
+
|
|
|
+ if regex != "/" && !u.CanRead(regex) {
|
|
|
+ panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
+ }
|
|
|
+
|
|
|
+ //This function can only handle wildcard in filename but not in dir name
|
|
|
+ vrootPath := filepath.Dir(regex)
|
|
|
+ regexFilename := filepath.Base(regex)
|
|
|
+
|
|
|
+ //Rewrite and validate the sort mode
|
|
|
+ if userSortMode == "user" {
|
|
|
+ //Use user sorting mode.
|
|
|
+ if g.Option.UserHandler.GetDatabase().KeyExists("fs-sortpref", u.Username+"/"+filepath.ToSlash(filepath.Clean(vrootPath))) {
|
|
|
+ g.Option.UserHandler.GetDatabase().Read("fs-sortpref", u.Username+"/"+filepath.ToSlash(filepath.Clean(vrootPath)), &userSortMode)
|
|
|
+ } else {
|
|
|
+ userSortMode = "default"
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if !fssort.SortModeIsSupported(userSortMode) {
|
|
|
+ log.Println("[AGI] Sort mode: " + userSortMode + " not supported. Using default")
|
|
|
+ userSortMode = "default"
|
|
|
+ }
|
|
|
+
|
|
|
+ //Translate the virtual path to realpath
|
|
|
+ fsh, err := u.GetFileSystemHandlerFromVirtualPath(vrootPath)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+ fshAbs := fsh.FileSystemAbstraction
|
|
|
+ rrootPath, _ := fshAbs.VirtualPathToRealPath(vrootPath, u.Username)
|
|
|
+ suitableFiles, err := fshAbs.Glob(filepath.Join(rrootPath, regexFilename))
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ fileList := []string{}
|
|
|
+ fis := []fs.FileInfo{}
|
|
|
+ for _, thisFile := range suitableFiles {
|
|
|
+ fi, err := fsh.FileSystemAbstraction.Stat(thisFile)
|
|
|
+ if err == nil {
|
|
|
+ fileList = append(fileList, thisFile)
|
|
|
+ fis = append(fis, fi)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //Sort the files
|
|
|
+ newFilelist := fssort.SortFileList(fileList, fis, userSortMode)
|
|
|
+
|
|
|
+ //Parse the results (Only extract the filepath)
|
|
|
+ results := []string{}
|
|
|
+ for _, filename := range newFilelist {
|
|
|
+ isHidden, _ := hidden.IsHidden(filename, true)
|
|
|
+ if isHidden {
|
|
|
+ //Hidden file. Skip this
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ thisVpath, _ := realpathToVirtualpath(fsh, filename, u)
|
|
|
+ results = append(results, thisVpath)
|
|
|
+ }
|
|
|
+ reply, _ := vm.ToValue(results)
|
|
|
+ return reply
|
|
|
+ })
|
|
|
+
|
|
|
+ vm.Set("_filelib_readdir", func(call otto.FunctionCall) otto.Value {
|
|
|
+ vpath, err := call.Argument(0).ToString()
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Rewrite the vpath if it is relative
|
|
|
+ vpath = relativeVpathRewrite(scriptFsh, vpath, vm, u)
|
|
|
+
|
|
|
+ //Check for permission
|
|
|
+ if !u.CanRead(vpath) {
|
|
|
+ panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
+ }
|
|
|
+
|
|
|
+ userSortMode, err := call.Argument(1).ToString()
|
|
|
+ if err != nil || userSortMode == "" || userSortMode == "undefined" {
|
|
|
+ userSortMode = "default"
|
|
|
+ }
|
|
|
+
|
|
|
+ //Rewrite and validate the sort mode
|
|
|
+ if userSortMode == "user" {
|
|
|
+ //Use user sorting mode.
|
|
|
+ if g.Option.UserHandler.GetDatabase().KeyExists("fs-sortpref", u.Username+"/"+filepath.ToSlash(filepath.Clean(vpath))) {
|
|
|
+ g.Option.UserHandler.GetDatabase().Read("fs-sortpref", u.Username+"/"+filepath.ToSlash(filepath.Clean(vpath)), &userSortMode)
|
|
|
+ } else {
|
|
|
+ userSortMode = "default"
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if !fssort.SortModeIsSupported(userSortMode) {
|
|
|
+ log.Println("[AGI] Sort mode: " + userSortMode + " not supported. Using default")
|
|
|
+ userSortMode = "default"
|
|
|
+ }
|
|
|
+
|
|
|
+ fsh, err := u.GetFileSystemHandlerFromVirtualPath(vpath)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+ fshAbs := fsh.FileSystemAbstraction
|
|
|
+ rpath, err := fshAbs.VirtualPathToRealPath(vpath, u.Username)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ dirEntry, err := fshAbs.ReadDir(rpath)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ type fileInfo struct {
|
|
|
+ Filename string
|
|
|
+ Filepath string
|
|
|
+ Ext string
|
|
|
+ Filesize int64
|
|
|
+ Modtime int64
|
|
|
+ IsDir bool
|
|
|
+ }
|
|
|
+
|
|
|
+ //Sort the dirEntry by file info, a bit slow :(
|
|
|
+ if userSortMode != "default" {
|
|
|
+ //Prepare the data structure for sorting
|
|
|
+ newDirEntry := fssort.SortDirEntryList(dirEntry, userSortMode)
|
|
|
+ dirEntry = newDirEntry
|
|
|
+ }
|
|
|
+
|
|
|
+ results := []fileInfo{}
|
|
|
+ for _, de := range dirEntry {
|
|
|
+ isHidden, _ := hidden.IsHidden(de.Name(), false)
|
|
|
+ if isHidden {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ fstat, _ := de.Info()
|
|
|
+ vpath, _ := realpathToVirtualpath(fsh, filepath.ToSlash(filepath.Join(rpath, de.Name())), u)
|
|
|
+ thisInfo := fileInfo{
|
|
|
+ Filename: de.Name(),
|
|
|
+ Filepath: vpath,
|
|
|
+ Ext: filepath.Ext(de.Name()),
|
|
|
+ Filesize: fstat.Size(),
|
|
|
+ Modtime: fstat.ModTime().Unix(),
|
|
|
+ IsDir: de.IsDir(),
|
|
|
+ }
|
|
|
+
|
|
|
+ results = append(results, thisInfo)
|
|
|
+ }
|
|
|
+
|
|
|
+ js, _ := json.Marshal(results)
|
|
|
+ r, _ := vm.ToValue(string(js))
|
|
|
+ return r
|
|
|
+ })
|
|
|
+
|
|
|
+ //filesize("user:/Desktop/test.txt")
|
|
|
+ vm.Set("_filelib_filesize", func(call otto.FunctionCall) otto.Value {
|
|
|
+ vpath, err := call.Argument(0).ToString()
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Rewrite the vpath if it is relative
|
|
|
+ vpath = relativeVpathRewrite(scriptFsh, vpath, vm, u)
|
|
|
+
|
|
|
+ //Check for permission
|
|
|
+ if !u.CanRead(vpath) {
|
|
|
+ panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
+ }
|
|
|
+
|
|
|
+ fsh, err := u.GetFileSystemHandlerFromVirtualPath(vpath)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+ fshAbs := fsh.FileSystemAbstraction
|
|
|
+ rpath, err := fshAbs.VirtualPathToRealPath(vpath, u.Username)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Get filesize of file
|
|
|
+ rawsize := fshAbs.GetFileSize(rpath)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ reply, _ := vm.ToValue(rawsize)
|
|
|
+ return reply
|
|
|
+ })
|
|
|
+
|
|
|
+ //fileExists("user:/Desktop/test.txt") => return true / false
|
|
|
+ vm.Set("_filelib_fileExists", func(call otto.FunctionCall) otto.Value {
|
|
|
+ vpath, err := call.Argument(0).ToString()
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Rewrite the vpath if it is relative
|
|
|
+ vpath = relativeVpathRewrite(scriptFsh, vpath, vm, u)
|
|
|
+
|
|
|
+ //Check for permission
|
|
|
+ if !u.CanRead(vpath) {
|
|
|
+ panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
+ }
|
|
|
+
|
|
|
+ fsh, err := u.GetFileSystemHandlerFromVirtualPath(vpath)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+ fshAbs := fsh.FileSystemAbstraction
|
|
|
+ rpath, err := fshAbs.VirtualPathToRealPath(vpath, u.Username)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ if fshAbs.FileExists(rpath) {
|
|
|
+ return otto.TrueValue()
|
|
|
+ } else {
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ //fileExists("user:/Desktop/test.txt") => return true / false
|
|
|
+ vm.Set("_filelib_isDir", func(call otto.FunctionCall) otto.Value {
|
|
|
+ vpath, err := call.Argument(0).ToString()
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Rewrite the vpath if it is relative
|
|
|
+ vpath = relativeVpathRewrite(scriptFsh, vpath, vm, u)
|
|
|
+
|
|
|
+ //Check for permission
|
|
|
+ if !u.CanRead(vpath) {
|
|
|
+ panic(vm.MakeCustomError("PermissionDenied", "Path access denied: "+vpath))
|
|
|
+ }
|
|
|
+
|
|
|
+ //Translate the virtual path to realpath
|
|
|
+ fsh, rpath, err := virtualPathToRealPath(vpath, u)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ if _, err := fsh.FileSystemAbstraction.Stat(rpath); os.IsNotExist(err) {
|
|
|
+ //File not exists
|
|
|
+ panic(vm.MakeCustomError("File Not Exists", "Required path not exists"))
|
|
|
+ }
|
|
|
+
|
|
|
+ if fsh.FileSystemAbstraction.IsDir(rpath) {
|
|
|
+ return otto.TrueValue()
|
|
|
+ } else {
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ //Make directory command
|
|
|
+ vm.Set("_filelib_mkdir", func(call otto.FunctionCall) otto.Value {
|
|
|
+ vdir, err := call.Argument(0).ToString()
|
|
|
+ if err != nil {
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Check for permission
|
|
|
+ if !u.CanWrite(vdir) {
|
|
|
+ panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
+ }
|
|
|
+
|
|
|
+ //Translate the path to realpath
|
|
|
+ fsh, rdir, err := virtualPathToRealPath(vdir, u)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err.Error())
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Create the directory at rdir location
|
|
|
+ err = fsh.FileSystemAbstraction.MkdirAll(rdir, 0755)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err.Error())
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ return otto.TrueValue()
|
|
|
+ })
|
|
|
+
|
|
|
+ //Get MD5 of the given filepath, not implemented
|
|
|
+ vm.Set("_filelib_md5", func(call otto.FunctionCall) otto.Value {
|
|
|
+ vpath, err := call.Argument(0).ToString()
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Rewrite the vpath if it is relative
|
|
|
+ vpath = relativeVpathRewrite(scriptFsh, vpath, vm, u)
|
|
|
+
|
|
|
+ //Check for permission
|
|
|
+ if !u.CanRead(vpath) {
|
|
|
+ panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
+ }
|
|
|
+
|
|
|
+ fsh, err := u.GetFileSystemHandlerFromVirtualPath(vpath)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+ fshAbs := fsh.FileSystemAbstraction
|
|
|
+ rpath, err := fshAbs.VirtualPathToRealPath(vpath, u.Username)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ f, err := fshAbs.ReadStream(rpath)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ defer f.Close()
|
|
|
+ h := md5.New()
|
|
|
+ if _, err := io.Copy(h, f); err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ md5Sum := hex.EncodeToString(h.Sum(nil))
|
|
|
+ result, _ := vm.ToValue(md5Sum)
|
|
|
+ return result
|
|
|
+ })
|
|
|
+
|
|
|
+ //Get the root name of the given virtual path root
|
|
|
+ vm.Set("_filelib_rname", func(call otto.FunctionCall) otto.Value {
|
|
|
+ //Get virtual path from the function input
|
|
|
+ vpath, err := call.Argument(0).ToString()
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Rewrite the vpath if it is relative
|
|
|
+ vpath = relativeVpathRewrite(scriptFsh, vpath, vm, u)
|
|
|
+
|
|
|
+ //Get fs handler from the vpath
|
|
|
+ fsHandler, err := u.GetFileSystemHandlerFromVirtualPath(vpath)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Return the name of the fsHandler
|
|
|
+ name, _ := vm.ToValue(fsHandler.Name)
|
|
|
+ return name
|
|
|
+
|
|
|
+ })
|
|
|
+
|
|
|
+ vm.Set("_filelib_mtime", func(call otto.FunctionCall) otto.Value {
|
|
|
+ vpath, err := call.Argument(0).ToString()
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Rewrite the vpath if it is relative
|
|
|
+ vpath = relativeVpathRewrite(scriptFsh, vpath, vm, u)
|
|
|
+
|
|
|
+ //Check for permission
|
|
|
+ if !u.CanRead(vpath) {
|
|
|
+ panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
+ }
|
|
|
+
|
|
|
+ parseToUnix, err := call.Argument(1).ToBoolean()
|
|
|
+ if err != nil {
|
|
|
+ parseToUnix = false
|
|
|
+ }
|
|
|
+
|
|
|
+ fsh, rpath, err := virtualPathToRealPath(vpath, u)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err.Error())
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ info, err := fsh.FileSystemAbstraction.Stat(rpath)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err.Error())
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ modTime := info.ModTime()
|
|
|
+ if parseToUnix {
|
|
|
+ result, _ := otto.ToValue(modTime.Unix())
|
|
|
+ return result
|
|
|
+ } else {
|
|
|
+ result, _ := otto.ToValue(modTime.Format("2006-01-02 15:04:05"))
|
|
|
+ return result
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ //ArozOS v2.0 New features
|
|
|
+ //Reading or writing from hex to target virtual filepath
|
|
|
+
|
|
|
+ //Write binary from hex string
|
|
|
+ vm.Set("_filelib_writeBinaryFile", func(call otto.FunctionCall) otto.Value {
|
|
|
+ vpath, err := call.Argument(0).ToString()
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Rewrite the vpath if it is relative
|
|
|
+ vpath = relativeVpathRewrite(scriptFsh, vpath, vm, u)
|
|
|
+
|
|
|
+ //Check for permission
|
|
|
+ if !u.CanWrite(vpath) {
|
|
|
+ panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
+ }
|
|
|
+
|
|
|
+ hexContent, err := call.Argument(1).ToString()
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Get the target vpath
|
|
|
+ fsh, rpath, err := virtualPathToRealPath(vpath, u)
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err.Error())
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Decode the hex content to bytes
|
|
|
+ hexContentInByte, err := hex.DecodeString(hexContent)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Write the file to target file
|
|
|
+ err = fsh.FileSystemAbstraction.WriteFile(rpath, hexContentInByte, 0775)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.FalseValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ return otto.TrueValue()
|
|
|
+
|
|
|
+ })
|
|
|
+
|
|
|
+ //Read file from external fsh. Small file only
|
|
|
+ vm.Set("_filelib_readBinaryFile", func(call otto.FunctionCall) otto.Value {
|
|
|
+ vpath, err := call.Argument(0).ToString()
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.NullValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ //Rewrite the vpath if it is relative
|
|
|
+ vpath = relativeVpathRewrite(scriptFsh, vpath, vm, u)
|
|
|
+
|
|
|
+ //Check for permission
|
|
|
+ if !u.CanRead(vpath) {
|
|
|
+ panic(vm.MakeCustomError("PermissionDenied", "Path access denied"))
|
|
|
+ }
|
|
|
+
|
|
|
+ //Get the target vpath
|
|
|
+ fsh, rpath, err := virtualPathToRealPath(vpath, u)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.NullValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ if !fsh.FileSystemAbstraction.FileExists(rpath) {
|
|
|
+ //Check if the target file exists
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.NullValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ content, err := fsh.FileSystemAbstraction.ReadFile(rpath)
|
|
|
+ if err != nil {
|
|
|
+ g.raiseError(err)
|
|
|
+ return otto.NullValue()
|
|
|
+ }
|
|
|
+
|
|
|
+ hexifiedContent := hex.EncodeToString(content)
|
|
|
+ val, _ := vm.ToValue(hexifiedContent)
|
|
|
+ return val
|
|
|
+
|
|
|
+ })
|
|
|
+
|
|
|
+ //Other file operations, wip
|
|
|
+
|
|
|
+ //Wrap all the native code function into an imagelib class
|
|
|
+ vm.Run(`
|
|
|
+ var filelib = {};
|
|
|
+ filelib.writeFile = _filelib_writeFile;
|
|
|
+ filelib.readFile = _filelib_readFile;
|
|
|
+ filelib.deleteFile = _filelib_deleteFile;
|
|
|
+ filelib.walk = _filelib_walk;
|
|
|
+ filelib.glob = _filelib_glob;
|
|
|
+ filelib.aglob = _filelib_aglob;
|
|
|
+ filelib.filesize = _filelib_filesize;
|
|
|
+ filelib.fileExists = _filelib_fileExists;
|
|
|
+ filelib.isDir = _filelib_isDir;
|
|
|
+ filelib.md5 = _filelib_md5;
|
|
|
+ filelib.mkdir = _filelib_mkdir;
|
|
|
+ filelib.mtime = _filelib_mtime;
|
|
|
+ filelib.rootName = _filelib_rname;
|
|
|
+
|
|
|
+ filelib.readdir = function(path, sortmode){
|
|
|
+ var s = _filelib_readdir(path, sortmode);
|
|
|
+ return JSON.parse(s);
|
|
|
+ };
|
|
|
+ `)
|
|
|
+}
|