2022-07-07 04:01:00 +02:00
|
|
|
package sstore
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2022-07-13 23:16:08 +02:00
|
|
|
"encoding/base64"
|
|
|
|
"fmt"
|
2022-07-07 04:01:00 +02:00
|
|
|
"os"
|
|
|
|
|
|
|
|
"github.com/scripthaus-dev/sh2-server/pkg/scbase"
|
|
|
|
)
|
|
|
|
|
2022-07-13 23:16:08 +02:00
|
|
|
const PosAppend = -1
|
|
|
|
|
|
|
|
// when calling with PosAppend, this is not multithread safe (since file could be modified).
|
|
|
|
// we need to know the real position of the write to send a proper pty update to the frontends
|
|
|
|
// in practice this is fine since we only use PosAppend in non-detached mode where
|
|
|
|
// we are reading/writing a stream in order with a single goroutine
|
|
|
|
func AppendToCmdPtyBlob(ctx context.Context, sessionId string, cmdId string, data []byte, pos int64) error {
|
2022-07-07 04:01:00 +02:00
|
|
|
ptyOutFileName, err := scbase.PtyOutFile(sessionId, cmdId)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-07-13 23:16:08 +02:00
|
|
|
var fd *os.File
|
|
|
|
var realPos int64
|
|
|
|
if pos == PosAppend {
|
|
|
|
fd, err = os.OpenFile(ptyOutFileName, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
finfo, err := fd.Stat()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
realPos = finfo.Size()
|
|
|
|
} else {
|
|
|
|
fd, err = os.OpenFile(ptyOutFileName, os.O_WRONLY|os.O_CREATE, 0600)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
realPos, err = fd.Seek(pos, 0)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if realPos != pos {
|
|
|
|
return fmt.Errorf("could not seek to pos:%d (realpos=%d)", pos, realPos)
|
|
|
|
}
|
2022-07-07 04:01:00 +02:00
|
|
|
}
|
2022-07-08 22:23:45 +02:00
|
|
|
defer fd.Close()
|
2022-07-08 06:39:25 +02:00
|
|
|
if len(data) == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
2022-07-07 04:01:00 +02:00
|
|
|
_, err = fd.Write(data)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-07-13 23:16:08 +02:00
|
|
|
data64 := base64.StdEncoding.EncodeToString(data)
|
|
|
|
update := &PtyDataUpdate{
|
|
|
|
SessionId: sessionId,
|
|
|
|
CmdId: cmdId,
|
|
|
|
PtyPos: realPos,
|
|
|
|
PtyData64: data64,
|
|
|
|
PtyDataLen: int64(len(data)),
|
|
|
|
}
|
|
|
|
MainBus.SendUpdate(sessionId, update)
|
2022-07-07 04:01:00 +02:00
|
|
|
return nil
|
|
|
|
}
|