267 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			267 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package build
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"io"
 | 
						|
	"os"
 | 
						|
	"os/exec"
 | 
						|
	"strings"
 | 
						|
 | 
						|
	utils_lua "packets/internal/utils/lua"
 | 
						|
 | 
						|
	"github.com/spf13/afero"
 | 
						|
	lua "github.com/yuin/gopher-lua"
 | 
						|
)
 | 
						|
 | 
						|
func (container Container) lRemove(L *lua.LState) int {
 | 
						|
	filename := L.CheckString(1)
 | 
						|
 | 
						|
	err := container.FS.RemoveAll(filename)
 | 
						|
	if err != nil {
 | 
						|
		L.Push(lua.LFalse)
 | 
						|
		L.Push(lua.LString(err.Error()))
 | 
						|
		return 2
 | 
						|
	}
 | 
						|
	L.Push(lua.LTrue)
 | 
						|
	L.Push(lua.LNil)
 | 
						|
	return 2
 | 
						|
}
 | 
						|
 | 
						|
func (container Container) lRename(L *lua.LState) int {
 | 
						|
	oldname := L.CheckString(1)
 | 
						|
	newname := L.CheckString(2)
 | 
						|
 | 
						|
	if err := container.FS.Rename(oldname, newname); err != nil {
 | 
						|
		L.Push(lua.LFalse)
 | 
						|
		L.Push(lua.LString(err.Error()))
 | 
						|
		return 2
 | 
						|
	}
 | 
						|
 | 
						|
	L.Push(lua.LTrue)
 | 
						|
	return 1
 | 
						|
}
 | 
						|
 | 
						|
func (container Container) lCopy(L *lua.LState) int {
 | 
						|
	oldname := L.CheckString(1)
 | 
						|
	newname := L.CheckString(2)
 | 
						|
 | 
						|
	if err := container.copyContainer(oldname, newname); err != nil {
 | 
						|
		L.Push(lua.LFalse)
 | 
						|
		L.Push(lua.LString(err.Error()))
 | 
						|
		return 2
 | 
						|
	}
 | 
						|
 | 
						|
	L.Push(lua.LTrue)
 | 
						|
	L.Push(lua.LNil)
 | 
						|
	return 2
 | 
						|
}
 | 
						|
 | 
						|
func modeFlags(mode string) int {
 | 
						|
	switch mode {
 | 
						|
	case "r", "rb":
 | 
						|
		return os.O_RDONLY
 | 
						|
	case "w", "wb":
 | 
						|
		return os.O_CREATE | os.O_WRONLY | os.O_TRUNC
 | 
						|
	case "a", "ab":
 | 
						|
		return os.O_CREATE | os.O_WRONLY | os.O_APPEND
 | 
						|
	case "r+", "r+b", "rb+", "br+":
 | 
						|
		return os.O_RDWR
 | 
						|
	case "w+", "w+b", "wb+", "bw+":
 | 
						|
		return os.O_CREATE | os.O_RDWR | os.O_TRUNC
 | 
						|
	case "a+", "a+b", "ab+", "ba+":
 | 
						|
		return os.O_CREATE | os.O_RDWR | os.O_APPEND
 | 
						|
	default:
 | 
						|
		return os.O_RDONLY
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (container Container) lOpen(L *lua.LState) int {
 | 
						|
	path := L.CheckString(1)
 | 
						|
	mode := L.OptString(2, "r")
 | 
						|
 | 
						|
	file, err := container.FS.OpenFile(path, modeFlags(mode), 0o644)
 | 
						|
	if err != nil {
 | 
						|
		L.Push(lua.LNil)
 | 
						|
		L.Push(lua.LString(err.Error()))
 | 
						|
		return 2
 | 
						|
	}
 | 
						|
 | 
						|
	ud := L.NewUserData()
 | 
						|
	ud.Value = file
 | 
						|
	L.SetMetatable(ud, L.GetTypeMetatable("file"))
 | 
						|
	L.Push(ud)
 | 
						|
	L.Push(lua.LNil)
 | 
						|
	return 2
 | 
						|
}
 | 
						|
 | 
						|
func (container Container) lMkdir(L *lua.LState) int {
 | 
						|
	path := L.CheckString(1)
 | 
						|
	perm := L.CheckInt(2)
 | 
						|
 | 
						|
	if err := container.FS.MkdirAll(path, os.FileMode(perm)); err != nil {
 | 
						|
		L.Push(lua.LFalse)
 | 
						|
		L.Push(lua.LString(err.Error()))
 | 
						|
		return 2
 | 
						|
	}
 | 
						|
 | 
						|
	L.Push(lua.LTrue)
 | 
						|
	L.Push(lua.LNil)
 | 
						|
	return 2
 | 
						|
}
 | 
						|
 | 
						|
func (container Container) lexecute(L *lua.LState) int {
 | 
						|
	cmdString := L.CheckString(1)
 | 
						|
 | 
						|
	cmdSlice := strings.Fields(cmdString)
 | 
						|
 | 
						|
	files, err := afero.ReadDir(container.FS, BinDir)
 | 
						|
	if err != nil {
 | 
						|
		L.Push(lua.LFalse)
 | 
						|
		L.Push(lua.LString("exit"))
 | 
						|
		L.Push(lua.LNumber(127))
 | 
						|
		return 3
 | 
						|
	}
 | 
						|
 | 
						|
	for _, file := range files {
 | 
						|
		if !file.IsDir() && file.Name() == cmdSlice[0] {
 | 
						|
			err := exec.Command(cmdSlice[0], cmdSlice[1:]...).Run()
 | 
						|
			if err != nil {
 | 
						|
				if errr := err.(*exec.ExitError); errr != nil {
 | 
						|
					L.Push(lua.LFalse)
 | 
						|
 | 
						|
					if err.(*exec.ExitError).Exited() {
 | 
						|
						L.Push(lua.LString("exit"))
 | 
						|
					} else {
 | 
						|
						L.Push(lua.LString("signal"))
 | 
						|
					}
 | 
						|
 | 
						|
					L.Push(lua.LNumber(err.(*exec.ExitError).ExitCode()))
 | 
						|
					return 3
 | 
						|
				}
 | 
						|
			}
 | 
						|
			L.Push(lua.LTrue)
 | 
						|
			L.Push(lua.LString("exit"))
 | 
						|
			L.Push(lua.LNumber(0))
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	L.Push(lua.LFalse)
 | 
						|
	L.Push(lua.LString("exit"))
 | 
						|
	L.Push(lua.LNumber(127))
 | 
						|
	return 3
 | 
						|
}
 | 
						|
 | 
						|
func (container Container) lpopen(L *lua.LState) int {
 | 
						|
	cmdString := L.CheckString(1)
 | 
						|
	mode := L.CheckString(2)
 | 
						|
 | 
						|
	cmdSlice := strings.Fields(cmdString)
 | 
						|
 | 
						|
	files, err := afero.ReadDir(container.FS, BinDir)
 | 
						|
	if err != nil {
 | 
						|
		L.Push(lua.LNil)
 | 
						|
		L.Push(lua.LString("can't find executable"))
 | 
						|
		return 2
 | 
						|
	}
 | 
						|
 | 
						|
	for _, file := range files {
 | 
						|
		if !file.IsDir() && file.Name() == cmdSlice[0] {
 | 
						|
			cmd := exec.Command(cmdSlice[0], cmdSlice[1:]...)
 | 
						|
			output, _ := cmd.CombinedOutput()
 | 
						|
 | 
						|
			switch mode {
 | 
						|
			case "r":
 | 
						|
				ud := L.NewUserData()
 | 
						|
				ud.Value = string(output)
 | 
						|
				L.SetMetatable(ud, L.GetTypeMetatable("file"))
 | 
						|
				L.Push(ud)
 | 
						|
				L.Push(lua.LNil)
 | 
						|
			case "w":
 | 
						|
				ud := L.NewUserData()
 | 
						|
				ud.Value = string(output)
 | 
						|
				os.Stdout.Write(output)
 | 
						|
				L.SetMetatable(ud, L.GetTypeMetatable("file"))
 | 
						|
				L.Push(ud)
 | 
						|
				L.Push(lua.LNil)
 | 
						|
			default:
 | 
						|
				L.Push(lua.LNil)
 | 
						|
				L.Push(lua.LString(fmt.Sprintf("%s: Invalid argument", cmdString)))
 | 
						|
			}
 | 
						|
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	L.Push(lua.LNil)
 | 
						|
	L.Push(lua.LString("can't find any executable"))
 | 
						|
	return 2
 | 
						|
}
 | 
						|
 | 
						|
func (container Container) lGet(L *lua.LState) int {
 | 
						|
	src := L.CheckString(1)
 | 
						|
	dest := L.CheckString(2)
 | 
						|
 | 
						|
	file, err := container.FS.Open(src)
 | 
						|
	if err != nil {
 | 
						|
		L.Push(lua.LFalse)
 | 
						|
		L.Push(lua.LString(err.Error()))
 | 
						|
		return 2
 | 
						|
	}
 | 
						|
	defer file.Close()
 | 
						|
 | 
						|
	info, err := file.Stat()
 | 
						|
	if err != nil {
 | 
						|
		L.Push(lua.LFalse)
 | 
						|
		L.Push(lua.LString(err.Error()))
 | 
						|
		return 2
 | 
						|
	}
 | 
						|
 | 
						|
	fileBlob, err := io.ReadAll(file)
 | 
						|
	if err != nil {
 | 
						|
		L.Push(lua.LFalse)
 | 
						|
		L.Push(lua.LString(err.Error()))
 | 
						|
		return 2
 | 
						|
	}
 | 
						|
 | 
						|
	if err := os.WriteFile(dest, fileBlob, info.Mode()); err != nil {
 | 
						|
		L.Push(lua.LFalse)
 | 
						|
		L.Push(lua.LString(err.Error()))
 | 
						|
		return 2
 | 
						|
	}
 | 
						|
 | 
						|
	L.Push(lua.LTrue)
 | 
						|
	L.Push(lua.LNil)
 | 
						|
	return 2
 | 
						|
}
 | 
						|
 | 
						|
func (container Container) lCopyToContainer(L *lua.LState) int {
 | 
						|
 | 
						|
	if err := container.CopyHostToContainer(L.CheckString(1), L.CheckString(2)); err != nil {
 | 
						|
		L.Push(lua.LFalse)
 | 
						|
		L.Push(lua.LString(err.Error()))
 | 
						|
		return 2
 | 
						|
	}
 | 
						|
	L.Push(lua.LTrue)
 | 
						|
	L.Push(lua.LNil)
 | 
						|
	return 2
 | 
						|
}
 | 
						|
 | 
						|
func (container Container) GetLuaState() {
 | 
						|
 | 
						|
	L := lua.NewState()
 | 
						|
	osObject := L.GetGlobal("os").(*lua.LTable)
 | 
						|
	ioObject := L.GetGlobal("io").(*lua.LTable)
 | 
						|
 | 
						|
	L.SetGlobal("path_join", L.NewFunction(utils_lua.Ljoin))
 | 
						|
 | 
						|
	osObject.RawSetString("remove", L.NewFunction(container.lRemove))
 | 
						|
	osObject.RawSetString("rename", L.NewFunction(container.lRename))
 | 
						|
	osObject.RawSetString("copy", L.NewFunction(container.lCopy))
 | 
						|
 | 
						|
	osObject.RawSetString("mkdir", L.NewFunction(container.lMkdir))
 | 
						|
 | 
						|
	ioObject.RawSetString("popen", L.NewFunction(container.lpopen))
 | 
						|
	ioObject.RawSetString("open", L.NewFunction(container.lOpen))
 | 
						|
 | 
						|
	container.LuaState = *L
 | 
						|
}
 |