2022-07-01 02:02:19 +02:00
|
|
|
package scbase
|
|
|
|
|
|
|
|
import (
|
2022-07-07 04:01:00 +02:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"io/fs"
|
2022-07-01 02:02:19 +02:00
|
|
|
"os"
|
|
|
|
"path"
|
2022-07-07 04:01:00 +02:00
|
|
|
"sync"
|
2022-07-08 01:29:14 +02:00
|
|
|
|
2022-07-08 06:39:25 +02:00
|
|
|
"github.com/scripthaus-dev/mshell/pkg/base"
|
2022-07-08 01:29:14 +02:00
|
|
|
"golang.org/x/sys/unix"
|
2022-07-01 02:02:19 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
const HomeVarName = "HOME"
|
|
|
|
const ScHomeVarName = "SCRIPTHAUS_HOME"
|
2022-07-07 04:01:00 +02:00
|
|
|
const SessionsDirBaseName = "sessions"
|
|
|
|
const RemotesDirBaseName = "remotes"
|
2022-07-08 01:29:14 +02:00
|
|
|
const SCLockFile = "sh2.lock"
|
2022-07-07 04:01:00 +02:00
|
|
|
|
|
|
|
var SessionDirCache = make(map[string]string)
|
|
|
|
var BaseLock = &sync.Mutex{}
|
2022-07-01 02:02:19 +02:00
|
|
|
|
|
|
|
func GetScHomeDir() string {
|
|
|
|
scHome := os.Getenv(ScHomeVarName)
|
|
|
|
if scHome == "" {
|
|
|
|
homeVar := os.Getenv(HomeVarName)
|
|
|
|
if homeVar == "" {
|
|
|
|
homeVar = "/"
|
|
|
|
}
|
|
|
|
scHome = path.Join(homeVar, "scripthaus")
|
|
|
|
}
|
|
|
|
return scHome
|
|
|
|
}
|
2022-07-07 04:01:00 +02:00
|
|
|
|
2022-07-08 01:29:14 +02:00
|
|
|
func AcquireSCLock() (*os.File, error) {
|
|
|
|
homeDir := GetScHomeDir()
|
|
|
|
lockFileName := path.Join(homeDir, SCLockFile)
|
|
|
|
fd, err := os.Create(lockFileName)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
err = unix.Flock(int(fd.Fd()), unix.LOCK_EX|unix.LOCK_NB)
|
|
|
|
if err != nil {
|
|
|
|
fd.Close()
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return fd, nil
|
|
|
|
}
|
|
|
|
|
2022-07-07 04:01:00 +02:00
|
|
|
func EnsureSessionDir(sessionId string) (string, error) {
|
|
|
|
BaseLock.Lock()
|
|
|
|
sdir, ok := SessionDirCache[sessionId]
|
|
|
|
BaseLock.Unlock()
|
|
|
|
if ok {
|
|
|
|
return sdir, nil
|
|
|
|
}
|
|
|
|
scHome := GetScHomeDir()
|
|
|
|
sdir = path.Join(scHome, SessionsDirBaseName, sessionId)
|
|
|
|
err := ensureDir(sdir)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
BaseLock.Lock()
|
|
|
|
SessionDirCache[sessionId] = sdir
|
|
|
|
BaseLock.Unlock()
|
|
|
|
return sdir, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func ensureDir(dirName string) error {
|
|
|
|
info, err := os.Stat(dirName)
|
|
|
|
if errors.Is(err, fs.ErrNotExist) {
|
|
|
|
err = os.MkdirAll(dirName, 0700)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
info, err = os.Stat(dirName)
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if !info.IsDir() {
|
|
|
|
return fmt.Errorf("'%s' must be a directory", dirName)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func PtyOutFile(sessionId string, cmdId string) (string, error) {
|
|
|
|
sdir, err := EnsureSessionDir(sessionId)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
2022-08-19 22:23:00 +02:00
|
|
|
return fmt.Sprintf("%s/%s.ptyout.cf", sdir, cmdId), nil
|
2022-07-07 04:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func RunOutFile(sessionId string, cmdId string) (string, error) {
|
|
|
|
sdir, err := EnsureSessionDir(sessionId)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return fmt.Sprintf("%s/%s.runout", sdir, cmdId), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func RemotePtyOut(remoteId string) (string, error) {
|
|
|
|
scHome := GetScHomeDir()
|
|
|
|
rdir := path.Join(scHome, RemotesDirBaseName)
|
|
|
|
err := ensureDir(rdir)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
2022-08-19 22:23:00 +02:00
|
|
|
return fmt.Sprintf("%s/%s.ptyout.cf", rdir, remoteId), nil
|
2022-07-07 04:01:00 +02:00
|
|
|
}
|
2022-07-08 06:39:25 +02:00
|
|
|
|
|
|
|
type ScFileNameGenerator struct {
|
|
|
|
ScHome string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g ScFileNameGenerator) PtyOutFile(ck base.CommandKey) string {
|
|
|
|
return path.Join(g.ScHome, SessionsDirBaseName, ck.GetSessionId(), ck.GetCmdId()+".ptyout")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g ScFileNameGenerator) RunOutFile(ck base.CommandKey) string {
|
|
|
|
return path.Join(g.ScHome, SessionsDirBaseName, ck.GetSessionId(), ck.GetCmdId()+".runout")
|
|
|
|
}
|