package commands import ( "fmt" "log" "strings" "git.snorba.art/hugo/nssh/storage" ) type CommandHandler struct { shell *Shell filestore storage.Filestore } func NewCommandHandler(shell *Shell, filestore storage.Filestore) *CommandHandler { return &CommandHandler{ shell: shell, filestore: filestore, } } func (h *CommandHandler) Handle(comm *Command) error { if strings.Contains(comm.Name, "=") { ApplyEnvIfPresent(h.shell, comm) return nil } switch comm.Name { case "exec": ApplyEnvIfPresent(h.shell, comm) case "(cd": h.shell.WriteOutput([]byte("tramp_exit_status 0\n")) case "echo": (&EchoCommand{}).Execute(h.shell, comm.Arguments) case "(echo": if strings.Join(comm.Arguments, " ") == "foo ; echo bar)" { log.Println("Handling tramp's foobar test") h.shell.WriteOutputString("foo\nbar\n") } case "stty": return (&SttyCommand{}).Execute(h.shell, comm.Arguments) case "set": log.Println("Ignoring \"set\" command") case "locale": if len(comm.Arguments) > 0 { if comm.Arguments[0] == "-a" { locales := []string{"C", "C.UTF-8", "POSIX", "en_US.utf8"} log.Println("Tramp requested locale, returning fake values: ", locales) h.shell.WriteOutputString( strings.Join(locales, "\n") + "\n", ) return nil } } log.Println("Ignoring \"locale\" command with unsupported parameters: ", comm.Arguments) case "getconf": return (&GetConfCommand{}).Execute(h.shell, comm.Arguments) case "test", "/bin/test": return (&TestCommand{filestore: h.filestore}).Execute(h.shell, comm.Arguments) case "while": if len(comm.Arguments) > 6 { var err error log.Printf("Pointing tramp to executable for \"%s\"", comm.Arguments[6]) switch comm.Arguments[6] { case "$d/ls": _, err = h.shell.WriteOutputString("tramp_executable " + lsExecutable) case "$d/test": _, err = h.shell.WriteOutputString("tramp_executable " + testExecutable) case "$d/stat": _, err = h.shell.WriteOutputString("tramp_executable " + statExecutable) } return err } case "ls", "/bin/ls": if len(comm.Arguments) > 2 && comm.Arguments[1] == "-al" && comm.Arguments[2] == "/dev/null" { _, err := h.shell.WriteOutputString( fmt.Sprintf( "crw-rw-rw- 1 root root 1, 3 May 5 00:05 /dev/null\n%s", trampSuccess, ), ) return err } if len(comm.Arguments) > 1 && comm.Arguments[0] == "-lnd" { _, err := h.shell.WriteOutputString( fmt.Sprintf( "drwxrwxr-x 3 1000 1000 28 Apr 28 14:04 %s\n%s", comm.Arguments[1], trampSuccess, ), ) return err } // should handle "--color=never --help 2>&1 | grep -iq busybox" so that we // can pretend to have busybox ls. The assumption is that this is easier // to emulate than the --dired flag of ls if len(comm.Arguments) > 7 && comm.Arguments[4] == "grep" && comm.Arguments[6] == "busybox" { _, err := h.shell.WriteOutputString(trampSuccess) return err } _, err := h.shell.WriteOutputString(trampFailure) return err case "mkdir": return (&MkdirCommand{filestore: h.filestore}).Execute(comm.Arguments) default: log.Printf("Error: Received unexpected command %s", comm.Name) } return nil }