소스 검색

优化修改sshd模块代码,解决bug

niujiuru 2 주 전
부모
커밋
ae88896b06
2개의 변경된 파일53개의 추가작업 그리고 10개의 파일을 삭제
  1. 4 1
      sshd/client/client.go
  2. 49 9
      utils/shell/executor.go

+ 4 - 1
sshd/client/client.go

@@ -138,7 +138,10 @@ func term(pingState *atomic.Bool) {
 			fmt.Print(result.Stdout)
 		}
 		if result.Stderr != "" {
-			fmt.Fprint(os.Stderr, result.Stderr)
+			fmt.Fprintln(os.Stderr, result.Stderr)
+		}
+		if result.ExitCode == 124 {
+			fmt.Println("command timed out, try again later")
 		}
 
 		if result.Cwd != "" {

+ 49 - 9
utils/shell/executor.go

@@ -1,14 +1,25 @@
 package shell
 
 import (
+	"os"
 	"path/filepath"
 	"strings"
 	"syscall"
 )
 
 type Executor struct {
-	cwd string        // 当前目录
-	pg  *processGroup // --进程组
+	cwd     string        // 当前目录
+	prevCwd string        // 上次目录
+	pg      *processGroup // --进程组
+}
+
+type PathError struct {
+	Path string
+	Info string
+}
+
+func (e *PathError) Error() string {
+	return e.Info + ": " + e.Path
 }
 
 func NewExecutor() *Executor {
@@ -16,14 +27,15 @@ func NewExecutor() *Executor {
 }
 
 func (e *Executor) Exec(p ExecuteParams) (*ExecuteResult, error) {
-	if isCD(p.Cmd) {
-		dir, err := resolveCD(e.cwd, p.Cmd)
+	if e.isCD(p.Cmd) {
+		dir, err := e.resolveCD(e.cwd, p.Cmd)
 		if err != nil {
 			return &ExecuteResult{
-				Stderr:   err.Error() + "\n",
+				Stderr:   err.Error(),
 				ExitCode: 1,
 			}, nil
 		}
+		e.prevCwd = e.cwd
 		e.cwd = dir
 		return &ExecuteResult{ExitCode: 0, Cwd: e.cwd}, nil
 	}
@@ -49,23 +61,51 @@ func (e *Executor) Exec(p ExecuteParams) (*ExecuteResult, error) {
 	return result, err
 }
 
-func isCD(cmd string) bool {
+func (e *Executor) isCD(cmd string) bool {
 	s := strings.TrimSpace(cmd)
 	return s == "cd" || strings.HasPrefix(s, "cd ")
 }
 
-func resolveCD(cwd, cmd string) (string, error) {
+func (e *Executor) resolveCD(cwd, cmd string) (string, error) {
 	fields := strings.Fields(cmd)
 	if len(fields) == 1 { // 只有"cd", 没有参数
 		return "/", nil
 	}
 
 	path := fields[1]
+	switch path {
+	case "~":
+		home := os.Getenv("HOME")
+		if home == "" {
+			home = "/"
+		}
+		return home, nil
+	case "-":
+		if e.prevCwd == "" {
+			return cwd, nil
+		}
+		return e.prevCwd, nil
+	}
+
+	var target string
 	if filepath.IsAbs(path) { // 绝对路径
-		return filepath.Clean(path), nil
+		target = filepath.Clean(path)
+	} else { // 相对路径
+		target = filepath.Clean(filepath.Join(cwd, path))
+	}
+
+	info, err := os.Stat(target)
+	if err != nil {
+		if os.IsNotExist(err) {
+			return "", &PathError{Path: target, Info: "directory not exist"}
+		}
+		return "", err
+	}
+	if !info.IsDir() {
+		return "", &PathError{Path: target, Info: "not a directory"}
 	}
 
-	return filepath.Clean(filepath.Join(cwd, path)), nil // 相对路径
+	return target, nil
 }
 
 func (e *Executor) Interrupt() error {