2022-07-07 04:01:00 +02:00
|
|
|
package sstore
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2022-07-13 23:16:08 +02:00
|
|
|
"encoding/base64"
|
|
|
|
"fmt"
|
2022-09-20 23:15:20 +02:00
|
|
|
"os"
|
|
|
|
"path"
|
2022-07-07 04:01:00 +02:00
|
|
|
|
2022-09-20 23:15:20 +02:00
|
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/scripthaus-dev/mshell/pkg/base"
|
2022-08-19 22:23:00 +02:00
|
|
|
"github.com/scripthaus-dev/mshell/pkg/cirfile"
|
2022-07-07 04:01:00 +02:00
|
|
|
"github.com/scripthaus-dev/sh2-server/pkg/scbase"
|
|
|
|
)
|
|
|
|
|
2022-08-19 22:23:00 +02:00
|
|
|
func CreateCmdPtyFile(ctx context.Context, sessionId string, cmdId string, maxSize int64) error {
|
2022-07-07 04:01:00 +02:00
|
|
|
ptyOutFileName, err := scbase.PtyOutFile(sessionId, cmdId)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-08-19 22:23:00 +02:00
|
|
|
f, err := cirfile.CreateCirFile(ptyOutFileName, maxSize)
|
2022-08-12 22:59:31 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-08-19 22:23:00 +02:00
|
|
|
return f.Close()
|
|
|
|
}
|
|
|
|
|
2022-09-05 23:49:23 +02:00
|
|
|
func AppendToCmdPtyBlob(ctx context.Context, sessionId string, cmdId string, data []byte, pos int64) (*PtyDataUpdate, error) {
|
2022-08-19 22:23:00 +02:00
|
|
|
if pos < 0 {
|
2022-09-05 23:49:23 +02:00
|
|
|
return nil, fmt.Errorf("invalid seek pos '%d' in AppendToCmdPtyBlob", pos)
|
2022-08-19 22:23:00 +02:00
|
|
|
}
|
|
|
|
ptyOutFileName, err := scbase.PtyOutFile(sessionId, cmdId)
|
2022-08-12 22:59:31 +02:00
|
|
|
if err != nil {
|
2022-09-05 23:49:23 +02:00
|
|
|
return nil, err
|
2022-08-12 22:59:31 +02:00
|
|
|
}
|
2022-08-19 22:23:00 +02:00
|
|
|
f, err := cirfile.OpenCirFile(ptyOutFileName)
|
|
|
|
if err != nil {
|
2022-09-05 23:49:23 +02:00
|
|
|
return nil, err
|
2022-07-08 06:39:25 +02:00
|
|
|
}
|
2022-08-19 22:23:00 +02:00
|
|
|
defer f.Close()
|
|
|
|
err = f.WriteAt(ctx, data, pos)
|
2022-07-07 04:01:00 +02:00
|
|
|
if err != nil {
|
2022-09-05 23:49:23 +02:00
|
|
|
return nil, err
|
2022-07-07 04:01:00 +02:00
|
|
|
}
|
2022-07-13 23:16:08 +02:00
|
|
|
data64 := base64.StdEncoding.EncodeToString(data)
|
|
|
|
update := &PtyDataUpdate{
|
|
|
|
SessionId: sessionId,
|
|
|
|
CmdId: cmdId,
|
2022-08-19 22:23:00 +02:00
|
|
|
PtyPos: pos,
|
2022-07-13 23:16:08 +02:00
|
|
|
PtyData64: data64,
|
|
|
|
PtyDataLen: int64(len(data)),
|
|
|
|
}
|
2022-09-05 23:49:23 +02:00
|
|
|
return update, nil
|
2022-07-07 04:01:00 +02:00
|
|
|
}
|
2022-08-19 22:23:00 +02:00
|
|
|
|
2022-09-04 08:57:05 +02:00
|
|
|
// returns (offset, data, err)
|
2022-08-19 22:23:00 +02:00
|
|
|
func ReadFullPtyOutFile(ctx context.Context, sessionId string, cmdId string) (int64, []byte, error) {
|
|
|
|
ptyOutFileName, err := scbase.PtyOutFile(sessionId, cmdId)
|
|
|
|
if err != nil {
|
|
|
|
return 0, nil, err
|
|
|
|
}
|
|
|
|
f, err := cirfile.OpenCirFile(ptyOutFileName)
|
|
|
|
if err != nil {
|
|
|
|
return 0, nil, err
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
return f.ReadAll(ctx)
|
|
|
|
}
|
2022-09-20 23:15:20 +02:00
|
|
|
|
|
|
|
type SessionDiskSizeType struct {
|
|
|
|
NumFiles int
|
|
|
|
TotalSize int64
|
|
|
|
ErrorCount int
|
|
|
|
}
|
|
|
|
|
|
|
|
func directorySize(dirName string) (SessionDiskSizeType, error) {
|
|
|
|
var rtn SessionDiskSizeType
|
|
|
|
entries, err := os.ReadDir(dirName)
|
|
|
|
if err != nil {
|
|
|
|
return rtn, err
|
|
|
|
}
|
|
|
|
for _, entry := range entries {
|
|
|
|
if entry.IsDir() {
|
|
|
|
rtn.ErrorCount++
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
finfo, err := entry.Info()
|
|
|
|
if err != nil {
|
|
|
|
rtn.ErrorCount++
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
rtn.NumFiles++
|
|
|
|
rtn.TotalSize += finfo.Size()
|
|
|
|
}
|
|
|
|
return rtn, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func SessionDiskSize(sessionId string) (SessionDiskSizeType, error) {
|
|
|
|
sessionDir, err := base.EnsureSessionDir(sessionId)
|
|
|
|
if err != nil {
|
|
|
|
return SessionDiskSizeType{}, err
|
|
|
|
}
|
|
|
|
return directorySize(sessionDir)
|
|
|
|
}
|
|
|
|
|
|
|
|
func FullSessionDiskSize() (map[string]SessionDiskSizeType, error) {
|
|
|
|
sdir := base.GetSessionsDir()
|
|
|
|
entries, err := os.ReadDir(sdir)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
rtn := make(map[string]SessionDiskSizeType)
|
|
|
|
for _, entry := range entries {
|
|
|
|
if !entry.IsDir() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
name := entry.Name()
|
|
|
|
_, err = uuid.Parse(name)
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
diskSize, err := directorySize(path.Join(sdir, name))
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
rtn[name] = diskSize
|
|
|
|
}
|
|
|
|
return rtn, nil
|
|
|
|
}
|
2022-12-22 02:45:40 +01:00
|
|
|
|
|
|
|
func DeletePtyOutFile(ctx context.Context, sessionId string, cmdId string) error {
|
|
|
|
ptyOutFileName, err := scbase.PtyOutFile(sessionId, cmdId)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return os.Remove(ptyOutFileName)
|
|
|
|
}
|
2022-12-27 01:09:21 +01:00
|
|
|
|
|
|
|
func DeleteSessionDir(ctx context.Context, sessionId string) error {
|
|
|
|
sessionDir, err := base.EnsureSessionDir(sessionId)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error getting sessiondir: %w", err)
|
|
|
|
}
|
|
|
|
return os.RemoveAll(sessionDir)
|
|
|
|
}
|