bbash/command/command.go
2025-01-13 17:58:00 +01:00

114 lines
2.2 KiB
Go

package command
import (
"bbash/command/brainrot"
"bbash/command/cat"
"bbash/command/cd"
"bbash/command/cp"
"bbash/command/echo"
"bbash/command/head"
"bbash/command/help"
"bbash/command/ls"
"bbash/command/man"
"bbash/command/mv"
"bbash/command/pwd"
"bbash/command/rm"
"bbash/command/tail"
"bbash/command/touch"
"bbash/environment"
"bbash/input_parser"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
)
var path_command map[string]string
func Init(env *environment.Env) {
path_command = make(map[string]string)
init_path(env)
}
func Run_command(in input_parser.Input, env *environment.Env) {
switch in.Instruction {
case "pwd":
pwd.Pwd(in, env)
case "echo":
echo.Echo(in, env)
case "ls":
ls.Ls(in, env)
case "cd":
cd.Cd(in, env)
case "man":
man.Man(in, env)
case "cat":
cat.Cat(in, env)
case "head":
head.Head(in, env)
case "touch":
touch.Touch(in, env)
case "rm":
rm.Rm(in, env)
case "cp":
cp.Cp(in, env)
case "mv":
mv.Mv(in, env)
case "help":
help.Help(in, env)
case "tail":
tail.Tail(in, env)
case "brainrot":
brainrot.Brainrot(in, env)
default:
if !run_by_path(in, env) {
fmt.Println(fmt.Sprintf("No such command! (%s)", in.Instruction))
}
}
}
// Returns if anything was run or not
func run_by_path(in input_parser.Input, env *environment.Env) bool {
instr, errB := path_command[in.Instruction]
if !errB {
return false
}
cmd := exec.Command(instr, strings.Fields(in.Args_raw)...)
output, _ := cmd.CombinedOutput()
print(string(output))
return true
}
func init_path(env *environment.Env) {
path := strings.Split(env.Env["PATH"], ":")
for _, a_path := range path {
recursive_executable_finder(a_path)
}
}
func recursive_executable_finder(path string) {
dir, err := os.ReadDir(path)
if err != nil {
return
}
for _, f := range dir {
if f.IsDir() {
recursive_executable_finder(f.Name())
continue
}
if !is_executable(f.Name()) {
continue
}
path_command[f.Name()] = filepath.Join(path, f.Name())
}
}
func is_executable(name string) bool {
return true
stat, _ := os.Stat(name)
mode := stat.Mode()
return mode&(1<<0) != 0 || // Others' execute bit
mode&(1<<3) != 0 || // Group's execute bit
mode.Perm()&(1<<6) != 0 // Owner's execute bit
}