feat: «Здесь» from a machine's file pane opens the terminal in that pane's folder (the agent starts the shell there; an older agent, or a folder gone, at home)
This commit is contained in:
1 parent
4fb26a9652
commit
57c2f1338f
10 files changed
+143
-12
No files matched your search
@@ -4,6 +4,8 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
@@ -41,8 +43,12 @@ func CloseTerminals() {
|
||||
// StartPTY launches a login shell attached to a new PTY. With user empty (or
|
||||
// equal to the agent's own user) it is the agent's shell - root by default,
|
||||
// since the agent runs as a root systemd service. Any other user is entered via
|
||||
// `su -l`, which only a root agent can do without a password.
|
||||
func StartPTY(user string) (*PTY, error) {
|
||||
// `su -l`, which only a root agent can do without a password. dir, when it
|
||||
// is a folder, is where the shell starts instead of home.
|
||||
func StartPTY(user, dir string) (*PTY, error) {
|
||||
if dir != "" && (!filepath.IsAbs(dir) || strings.ContainsAny(dir, "\x00\r\n") || !isDir(dir)) {
|
||||
dir = ""
|
||||
}
|
||||
var cmd *exec.Cmd
|
||||
env := append(os.Environ(), "TERM=xterm-256color")
|
||||
if user == "" || user == currentUser() {
|
||||
@@ -54,6 +60,9 @@ func StartPTY(user string) (*PTY, error) {
|
||||
cmd.Dir = home
|
||||
env = append(env, "HOME="+home)
|
||||
}
|
||||
if dir != "" {
|
||||
cmd.Dir = dir
|
||||
}
|
||||
} else {
|
||||
if !validUserName(user) {
|
||||
return nil, fmt.Errorf("недопустимое имя пользователя %q", user)
|
||||
@@ -69,6 +78,11 @@ func StartPTY(user string) (*PTY, error) {
|
||||
return nil, fmt.Errorf("su не найден: %w", err)
|
||||
}
|
||||
cmd = exec.Command(su, "-l", user)
|
||||
// su -l always goes home; to start elsewhere, its shell changes
|
||||
// directory first and becomes the login shell (sh and csh alike).
|
||||
if dir != "" {
|
||||
cmd = exec.Command(su, "-l", user, "-c", "cd "+shQuote(dir)+"; exec \"$SHELL\" -l")
|
||||
}
|
||||
// su -l goes to the user's home; starting there too keeps the shell
|
||||
// out of "/" should it not.
|
||||
if home := homeDir(user); isDir(home) {
|
||||
@@ -126,3 +140,9 @@ func (p *PTY) Close() error {
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// shQuote puts s in single quotes for sh and csh alike, closing and
|
||||
// reopening them around each quote inside.
|
||||
func shQuote(s string) string {
|
||||
return "'" + strings.ReplaceAll(s, "'", `'\''`) + "'"
|
||||
}
|
||||
Reference in new issue
Block a user