mirror of
https://github.com/wavetermdev/backup.git
synced 2026-04-22 15:26:58 -07:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 25259428ab | |||
| 15f6084db4 | |||
| 1dba3f2612 | |||
| 8e907066ad |
@@ -64,6 +64,8 @@ const (
|
||||
FileStatPacketStr = "filestat"
|
||||
LogPacketStr = "log" // logging packet (sent from waveshell back to server)
|
||||
ShellStatePacketStr = "shellstate"
|
||||
ListDirPacketStr = "listdir"
|
||||
SearchDirPacketStr = "searchdir"
|
||||
RpcInputPacketStr = "rpcinput" // rpc-followup
|
||||
SudoRequestPacketStr = "sudorequest"
|
||||
SudoResponsePacketStr = "sudoresponse"
|
||||
@@ -120,6 +122,8 @@ func init() {
|
||||
TypeStrToFactory[WriteFileDonePacketStr] = reflect.TypeOf(WriteFileDonePacketType{})
|
||||
TypeStrToFactory[LogPacketStr] = reflect.TypeOf(LogPacketType{})
|
||||
TypeStrToFactory[ShellStatePacketStr] = reflect.TypeOf(ShellStatePacketType{})
|
||||
TypeStrToFactory[ListDirPacketStr] = reflect.TypeOf(ListDirPacketType{})
|
||||
TypeStrToFactory[SearchDirPacketStr] = reflect.TypeOf(SearchDirPacketType{})
|
||||
TypeStrToFactory[FileStatPacketStr] = reflect.TypeOf(FileStatPacketType{})
|
||||
TypeStrToFactory[RpcInputPacketStr] = reflect.TypeOf(RpcInputPacketType{})
|
||||
TypeStrToFactory[SudoRequestPacketStr] = reflect.TypeOf(SudoRequestPacketType{})
|
||||
@@ -133,6 +137,8 @@ func init() {
|
||||
var _ RpcPacketType = (*ReInitPacketType)(nil)
|
||||
var _ RpcPacketType = (*StreamFilePacketType)(nil)
|
||||
var _ RpcPacketType = (*WriteFilePacketType)(nil)
|
||||
var _ RpcPacketType = (*ListDirPacketType)(nil)
|
||||
var _ RpcPacketType = (*SearchDirPacketType)(nil)
|
||||
|
||||
var _ RpcResponsePacketType = (*CmdStartPacketType)(nil)
|
||||
var _ RpcResponsePacketType = (*ResponsePacketType)(nil)
|
||||
@@ -449,8 +455,12 @@ func MakeFileStatPacketType() *FileStatPacketType {
|
||||
return &FileStatPacketType{Type: FileStatPacketStr}
|
||||
}
|
||||
|
||||
func MakeFileStatPacketFromFileInfo(finfo fs.FileInfo, err string, done bool) *FileStatPacketType {
|
||||
func MakeFileStatPacketFromFileInfo(listDirPk *ListDirPacketType, finfo fs.FileInfo, err string, done bool) *FileStatPacketType {
|
||||
resp := MakeFileStatPacketType()
|
||||
if listDirPk != nil {
|
||||
resp.RespId = listDirPk.ReqId
|
||||
resp.Path = listDirPk.Path
|
||||
}
|
||||
resp.Error = err
|
||||
resp.Done = done
|
||||
|
||||
@@ -464,6 +474,50 @@ func MakeFileStatPacketFromFileInfo(finfo fs.FileInfo, err string, done bool) *F
|
||||
return resp
|
||||
}
|
||||
|
||||
type ListDirPacketType struct {
|
||||
Type string `json:"type"`
|
||||
ReqId string `json:"reqid"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
func (*ListDirPacketType) GetType() string {
|
||||
return ListDirPacketStr
|
||||
}
|
||||
|
||||
func (p *ListDirPacketType) GetReqId() string {
|
||||
return p.ReqId
|
||||
}
|
||||
|
||||
func MakeListDirPacket() *ListDirPacketType {
|
||||
return &ListDirPacketType{Type: ListDirPacketStr}
|
||||
}
|
||||
|
||||
type SearchDirPacketType struct {
|
||||
Type string `json:"type"`
|
||||
ReqId string `json:"reqid"`
|
||||
Path string `json:"path"`
|
||||
SearchQuery string `json:"searchquery"`
|
||||
}
|
||||
|
||||
func (*SearchDirPacketType) GetType() string {
|
||||
return SearchDirPacketStr
|
||||
}
|
||||
|
||||
func (p *SearchDirPacketType) GetReqId() string {
|
||||
return p.ReqId
|
||||
}
|
||||
|
||||
func (p *SearchDirPacketType) ConvertToListDir() *ListDirPacketType {
|
||||
rtn := MakeListDirPacket()
|
||||
rtn.ReqId = p.ReqId
|
||||
rtn.Path = p.Path
|
||||
return rtn
|
||||
}
|
||||
|
||||
func MakeSearchDirPacket() *SearchDirPacketType {
|
||||
return &SearchDirPacketType{Type: SearchDirPacketStr}
|
||||
}
|
||||
|
||||
type StreamFilePacketType struct {
|
||||
Type string `json:"type"`
|
||||
ReqId string `json:"reqid"`
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -660,6 +661,97 @@ func (m *MServer) streamFile(pk *packet.StreamFilePacketType) {
|
||||
return
|
||||
}
|
||||
|
||||
func (m *MServer) writeListDirErrPacket(err error, reqId string) {
|
||||
resp := packet.MakeFileStatPacketType()
|
||||
resp.RespId = reqId
|
||||
resp.Error = fmt.Sprintf("Error in list dir: %v", err)
|
||||
resp.Done = true
|
||||
m.Sender.SendPacket(resp)
|
||||
}
|
||||
|
||||
func (m *MServer) ListDir(listDirPk *packet.ListDirPacketType) {
|
||||
dirEntries, err := os.ReadDir(listDirPk.Path)
|
||||
var readDirError string = ""
|
||||
if err != nil {
|
||||
readDirError = fmt.Sprintf("error in list dir: %v", err)
|
||||
}
|
||||
curDirStat, err := os.Stat(listDirPk.Path)
|
||||
if err != nil {
|
||||
m.writeListDirErrPacket(err, listDirPk.ReqId)
|
||||
}
|
||||
resp := packet.MakeFileStatPacketFromFileInfo(listDirPk, curDirStat, readDirError, false)
|
||||
resp.Name = "."
|
||||
m.Sender.SendPacket(resp)
|
||||
curDirStat, err = os.Stat(filepath.Join(listDirPk.Path, ".."))
|
||||
if err != nil {
|
||||
m.writeListDirErrPacket(err, listDirPk.ReqId)
|
||||
return
|
||||
}
|
||||
resp = packet.MakeFileStatPacketFromFileInfo(listDirPk, curDirStat, readDirError, len(dirEntries) == 0)
|
||||
resp.Name = ".."
|
||||
m.Sender.SendPacket(resp)
|
||||
|
||||
for index := 0; index < len(dirEntries); index++ {
|
||||
dirEntry := dirEntries[index]
|
||||
dirEntryFileInfo, err := dirEntry.Info()
|
||||
if err != nil {
|
||||
m.writeListDirErrPacket(err, listDirPk.ReqId)
|
||||
return
|
||||
}
|
||||
done := index == len(dirEntries)-1
|
||||
resp = packet.MakeFileStatPacketFromFileInfo(listDirPk, dirEntryFileInfo, readDirError, done)
|
||||
m.Sender.SendPacket(resp)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MServer) SearchDir(searchDirPk *packet.SearchDirPacketType) {
|
||||
searchEmpty := true
|
||||
foundRoot := false
|
||||
err := filepath.WalkDir(searchDirPk.Path, func(path string, dirEntry fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
errString := fmt.Sprintf("%v", err)
|
||||
if strings.Contains(errString, "operation not permitted") {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
}
|
||||
fileName := filepath.Base(path)
|
||||
match, err := regexp.MatchString(searchDirPk.SearchQuery, fileName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if match {
|
||||
base.Logf("matched file: %v %v", path, searchDirPk.SearchQuery)
|
||||
// special case where walkdir includes the current path, which messes up the stat pk
|
||||
rootName := filepath.Base(searchDirPk.Path)
|
||||
if !foundRoot && fileName == rootName {
|
||||
foundRoot = true
|
||||
return nil
|
||||
}
|
||||
dirEntryFileInfo, err := dirEntry.Info()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
searchEmpty = false
|
||||
resp := packet.MakeFileStatPacketFromFileInfo(searchDirPk.ConvertToListDir(), dirEntryFileInfo, "", false)
|
||||
m.Sender.SendPacket(resp)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
m.writeListDirErrPacket(err, searchDirPk.ReqId)
|
||||
} else {
|
||||
searchError := ""
|
||||
if searchEmpty {
|
||||
searchError = "none"
|
||||
}
|
||||
resp := packet.MakeFileStatPacketType()
|
||||
resp.Error = searchError
|
||||
resp.Done = true
|
||||
m.Sender.SendPacket(resp)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func int64Min(v1 int64, v2 int64) int64 {
|
||||
if v1 < v2 {
|
||||
return v1
|
||||
@@ -703,6 +795,14 @@ func (m *MServer) ProcessRpcPacket(pk packet.RpcPacketType) {
|
||||
go m.writeFile(writePk, wfc)
|
||||
return
|
||||
}
|
||||
if listDirPk, ok := pk.(*packet.ListDirPacketType); ok {
|
||||
go m.ListDir(listDirPk)
|
||||
return
|
||||
}
|
||||
if searchDirPk, ok := pk.(*packet.SearchDirPacketType); ok {
|
||||
go m.SearchDir(searchDirPk)
|
||||
return
|
||||
}
|
||||
m.Sender.SendErrorResponse(reqId, fmt.Errorf("invalid rpc type '%s'", pk.GetType()))
|
||||
}
|
||||
|
||||
|
||||
@@ -1033,7 +1033,7 @@ func configDirHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var files []*packet.FileStatPacketType
|
||||
for index := 0; index < len(entries); index++ {
|
||||
curEntry := entries[index]
|
||||
curFile := packet.MakeFileStatPacketFromFileInfo(curEntry, "", false)
|
||||
curFile := packet.MakeFileStatPacketFromFileInfo(nil, curEntry, "", false)
|
||||
files = append(files, curFile)
|
||||
}
|
||||
dirListJson, err := json.Marshal(files)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1522,6 +1522,14 @@ func (wsh *WaveshellProc) StreamFile(ctx context.Context, streamPk *packet.Strea
|
||||
return wsh.PacketRpcIter(ctx, streamPk)
|
||||
}
|
||||
|
||||
func (msh *WaveshellProc) ListDir(ctx context.Context, listDirPk *packet.ListDirPacketType) (*packet.RpcResponseIter, error) {
|
||||
return msh.PacketRpcIter(ctx, listDirPk)
|
||||
}
|
||||
|
||||
func (msh *WaveshellProc) SearchDir(ctx context.Context, searchDirPk *packet.SearchDirPacketType) (*packet.RpcResponseIter, error) {
|
||||
return msh.PacketRpcIter(ctx, searchDirPk)
|
||||
}
|
||||
|
||||
func addScVarsToState(state *packet.ShellState) *packet.ShellState {
|
||||
if state == nil {
|
||||
return nil
|
||||
@@ -2210,6 +2218,7 @@ func (wsh *WaveshellProc) PacketRpcIter(ctx context.Context, pk packet.RpcPacket
|
||||
if pk == nil {
|
||||
return nil, fmt.Errorf("PacketRpc passed nil packet")
|
||||
}
|
||||
log.Printf("sending packet: %v", pk)
|
||||
reqId := pk.GetReqId()
|
||||
wsh.ServerProc.Output.RegisterRpcSz(reqId, RpcIterChannelSize)
|
||||
err := wsh.ServerProc.Input.SendPacketCtx(ctx, pk)
|
||||
|
||||
Reference in New Issue
Block a user