seafile_recovery/fs.go

109 lines
2.3 KiB
Go

package main
import(
"compress/zlib"
"fmt"
"log"
"os"
"encoding/json"
"syscall"
"path/filepath"
)
// Imported from https://github.com/haiwen/seafile-server/blob/master/fileserver/fsmgr/fsmgr.go
// License AGPLv3
//SeafDir is a dir object
type DirElem struct {
Version int `json:"version"`
DirType int `json:"type,omitempty"`
DirID string `json:"dir_id,omitempty"`
Entries []*DirEnt `json:"dirents"`
}
// SeafDirent is a dir entry object
type DirEnt struct {
Mode uint32 `json:"mode"`
Id string `json:"id"`
Name string `json:"name"`
Mtime int64 `json:"mtime"`
Modifier string `json:"modifier"`
Size int64 `json:"size"`
}
type FileElem struct {
Version int `json:"version"`
FileType int `json:"type,omitempty"`
FileID string `json:"file_id,omitempty"`
FileSize uint64 `json:"size"`
BlkIDs []string `json:"block_ids"`
}
type DirNode struct {
Id string
Folders *DirNode
Files []FileElem
Elem DirElem
}
type RepoFs struct {
Config configCollect
Path *DirNode
}
func NewRepoFs(config configCollect) *RepoFs {
rf := new(RepoFs)
rf.Config = config
rf.Path = NewDirNode(filepath.Join(config.Storage, "fs", config.RepoId), config.PathId)
return rf
}
func (rf* RepoFs) String() string {
return fmt.Sprintf("%#v", rf)
}
func NewDirNode(base string, id string) *DirNode {
dn := new(DirNode)
dn.Id = id
path := filepath.Join(base, id[:2], id[2:])
file, err := os.Open(path)
if err != nil { log.Fatal(err) }
defer file.Close()
zfile, err := zlib.NewReader(file)
if err != nil { log.Fatal(err) }
jdec := json.NewDecoder(zfile)
err = jdec.Decode(&dn.Elem)
if err != nil { log.Fatal(err) }
return dn
}
/*func (rf* RepoFs) Walk() {
qPathIds := make([]string, 0)
qPathIds = append(qPathIds, rf.PathId)
for limit := 0 ; limit < 20000 && len(pathIds) > 0 ; limit++ {
pathId := qPathIds[0]
qPathIds = qPathIds[1:]
NewDirNode(filepath.Join(rf.Config.Storage, "fs", rf.Config.RepoId), pathId)
}
}*/
// IsDir check if the mode is dir.
func IsDir(m uint32) bool {
return (m & syscall.S_IFMT) == syscall.S_IFDIR
}
// IsRegular Check if the mode is regular.
func IsRegular(m uint32) bool {
return (m & syscall.S_IFMT) == syscall.S_IFREG
}