111 lines
2.1 KiB
Go
111 lines
2.1 KiB
Go
package command
|
|
|
|
import (
|
|
"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)
|
|
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
|
|
}
|