Extend ls2json reader
by also parsing the link target, permissions, group and owner.
This commit is contained in:
@ -114,12 +114,25 @@ type UpdateFileSystemRequest struct {
|
||||
// FilePath specifies the path of a file and is part of the UpdateFileSystemRequest.
|
||||
type FilePath string
|
||||
|
||||
// EntryType specifies the type of the object (file/link/directory/..)
|
||||
type EntryType string
|
||||
|
||||
// These are the common entry types. You find others in the man pages `info ls`.
|
||||
const (
|
||||
EntryTypeRegularFile EntryType = "-"
|
||||
EntryTypeLink EntryType = "l"
|
||||
)
|
||||
|
||||
// FileHeader specifies the information provided for listing a File.
|
||||
type FileHeader struct {
|
||||
Name FilePath `json:"name"`
|
||||
ObjectType string `json:"objectType"`
|
||||
Size int `json:"size"`
|
||||
ModificationTime int `json:"modificationTime"`
|
||||
Name FilePath `json:"name"`
|
||||
EntryType EntryType `json:"entryType"`
|
||||
LinkTarget FilePath `json:"linkTarget,omitempty"`
|
||||
Size int `json:"size"`
|
||||
ModificationTime int `json:"modificationTime"`
|
||||
Permissions string `json:"permissions"`
|
||||
Owner string `json:"owner"`
|
||||
Group string `json:"group"`
|
||||
}
|
||||
|
||||
// File is a DTO for transmitting file contents. It is part of the UpdateFileSystemRequest.
|
||||
|
@ -9,12 +9,13 @@ import (
|
||||
"io"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
log = logging.GetLogger("nullio")
|
||||
pathLineRegex = regexp.MustCompile(`(.*):$`)
|
||||
headerLineRegex = regexp.MustCompile(`([dl-])[-rwxXsS]{9} \d* .*? .*? +(\d+) (\d+) (.*)$`)
|
||||
headerLineRegex = regexp.MustCompile(`([-aAbcCdDlMnpPsw?])([-rwxXsStT]{9})([+ ])\d+ (.+?) (.+?) +(\d+) (\d+) (.*)$`)
|
||||
)
|
||||
|
||||
// Ls2JsonWriter implements io.Writer.
|
||||
@ -93,20 +94,9 @@ func (w *Ls2JsonWriter) writeLine(line []byte) (count int, err error) {
|
||||
|
||||
matches = headerLineRegex.FindSubmatch(line)
|
||||
if matches != nil {
|
||||
size, err1 := strconv.Atoi(string(matches[2]))
|
||||
timestamp, err2 := strconv.Atoi(string(matches[3]))
|
||||
if err1 != nil || err2 != nil {
|
||||
return 0, fmt.Errorf("could not parse file details: %w %+v", err1, err2)
|
||||
}
|
||||
|
||||
response, err1 := json.Marshal(dto.FileHeader{
|
||||
Name: dto.FilePath(append(w.latestPath, matches[4]...)),
|
||||
ObjectType: string(matches[1][0]),
|
||||
Size: size,
|
||||
ModificationTime: timestamp,
|
||||
})
|
||||
response, err1 := w.parseFileHeader(matches)
|
||||
if err1 != nil {
|
||||
return 0, fmt.Errorf("could not marshal file header: %w", err)
|
||||
return 0, err1
|
||||
}
|
||||
|
||||
// Skip the first leading comma
|
||||
@ -118,7 +108,7 @@ func (w *Ls2JsonWriter) writeLine(line []byte) (count int, err error) {
|
||||
|
||||
count, err1 = w.Target.Write(response)
|
||||
if err1 != nil {
|
||||
err = fmt.Errorf("could not write to target: %w", err)
|
||||
err = fmt.Errorf("could not write to target: %w", err1)
|
||||
} else if count == len(response) {
|
||||
count = len(line)
|
||||
}
|
||||
@ -126,3 +116,48 @@ func (w *Ls2JsonWriter) writeLine(line []byte) (count int, err error) {
|
||||
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (w *Ls2JsonWriter) parseFileHeader(matches [][]byte) ([]byte, error) {
|
||||
entryType := dto.EntryType(matches[1][0])
|
||||
permissions := string(matches[2])
|
||||
acl := string(matches[3])
|
||||
if acl == "+" {
|
||||
permissions += "+"
|
||||
}
|
||||
|
||||
owner := string(matches[4])
|
||||
group := string(matches[5])
|
||||
size, err1 := strconv.Atoi(string(matches[6]))
|
||||
timestamp, err2 := strconv.Atoi(string(matches[7]))
|
||||
if err1 != nil || err2 != nil {
|
||||
return nil, fmt.Errorf("could not parse file details: %w %+v", err1, err2)
|
||||
}
|
||||
|
||||
name := dto.FilePath(append(w.latestPath, matches[8]...))
|
||||
linkTarget := dto.FilePath("")
|
||||
if entryType == dto.EntryTypeLink {
|
||||
parts := strings.Split(string(name), " -> ")
|
||||
const NumberOfPartsInALink = 2
|
||||
if len(parts) == NumberOfPartsInALink {
|
||||
name = dto.FilePath(parts[0])
|
||||
linkTarget = dto.FilePath(parts[1])
|
||||
} else {
|
||||
log.Error("could not split link into name and target")
|
||||
}
|
||||
}
|
||||
|
||||
response, err := json.Marshal(dto.FileHeader{
|
||||
Name: name,
|
||||
EntryType: entryType,
|
||||
LinkTarget: linkTarget,
|
||||
Size: size,
|
||||
ModificationTime: timestamp,
|
||||
Permissions: permissions,
|
||||
Owner: owner,
|
||||
Group: group,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not marshal file header: %w", err)
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
@ -39,7 +39,8 @@ func (s *Ls2JsonTestSuite) TestLs2JsonWriter_WriteFile() {
|
||||
s.NoError(err)
|
||||
s.writer.Close()
|
||||
|
||||
s.Equal("{\"files\": [{\"name\":\"flag\",\"objectType\":\"-\",\"size\":0,\"modificationTime\":1660763446}]}",
|
||||
s.Equal("{\"files\": [{\"name\":\"flag\",\"entryType\":\"-\",\"size\":0,\"modificationTime\":1660763446"+
|
||||
",\"permissions\":\"rw-rw-r--\",\"owner\":\"kali\",\"group\":\"kali\"}]}",
|
||||
s.buf.String())
|
||||
}
|
||||
|
||||
@ -52,23 +53,40 @@ func (s *Ls2JsonTestSuite) TestLs2JsonWriter_WriteRecursive() {
|
||||
s.NoError(err)
|
||||
s.writer.Close()
|
||||
|
||||
s.Equal("{\"files\": [{\"name\":\"./dir\",\"objectType\":\"d\",\"size\":4096,\"modificationTime\":1660764411},"+
|
||||
"{\"name\":\"./flag\",\"objectType\":\"-\",\"size\":0,\"modificationTime\":1660763446},"+
|
||||
"{\"name\":\"./dir/another.txt\",\"objectType\":\"-\",\"size\":3,\"modificationTime\":1660764366}]}",
|
||||
s.Equal("{\"files\": ["+
|
||||
"{\"name\":\"./dir\",\"entryType\":\"d\",\"size\":4096,\"modificationTime\":1660764411,"+
|
||||
"\"permissions\":\"rwxrwxr-x\",\"owner\":\"kali\",\"group\":\"kali\"},"+
|
||||
"{\"name\":\"./flag\",\"entryType\":\"-\",\"size\":0,\"modificationTime\":1660763446,"+
|
||||
"\"permissions\":\"rw-rw-r--\",\"owner\":\"kali\",\"group\":\"kali\"},"+
|
||||
"{\"name\":\"./dir/another.txt\",\"entryType\":\"-\",\"size\":3,\"modificationTime\":1660764366,"+
|
||||
"\"permissions\":\"rw-rw-r--\",\"owner\":\"kali\",\"group\":\"kali\"}"+
|
||||
"]}",
|
||||
s.buf.String())
|
||||
}
|
||||
|
||||
func (s *Ls2JsonTestSuite) TestLs2JsonWriter_WriteRemaining() {
|
||||
input1 := "total 4\n-rw-rw-r-- 1 kali kali 3 1660764366 another.txt\n-rw-rw-r-- 1 kal"
|
||||
input1 := "total 4\n-rw-rw-r-- 1 kali kali 3 1660764366 an.txt\n-rw-rw-r-- 1 kal"
|
||||
_, err := s.writer.Write([]byte(input1))
|
||||
s.NoError(err)
|
||||
s.Equal("{\"files\": [{\"name\":\"another.txt\",\"objectType\":\"-\",\"size\":3,\"modificationTime\":1660764366}",
|
||||
s.buf.String())
|
||||
s.Equal("{\"files\": [{\"name\":\"an.txt\",\"entryType\":\"-\",\"size\":3,\"modificationTime\":1660764366,"+
|
||||
"\"permissions\":\"rw-rw-r--\",\"owner\":\"kali\",\"group\":\"kali\"}", s.buf.String())
|
||||
|
||||
input2 := "i kali 0 1660763446 flag\n"
|
||||
_, err = s.writer.Write([]byte(input2))
|
||||
s.NoError(err)
|
||||
s.writer.Close()
|
||||
s.Equal("{\"files\": [{\"name\":\"another.txt\",\"objectType\":\"-\",\"size\":3,\"modificationTime\":1660764366},"+
|
||||
"{\"name\":\"flag\",\"objectType\":\"-\",\"size\":0,\"modificationTime\":1660763446}]}", s.buf.String())
|
||||
s.Equal("{\"files\": [{\"name\":\"an.txt\",\"entryType\":\"-\",\"size\":3,\"modificationTime\":1660764366,"+
|
||||
"\"permissions\":\"rw-rw-r--\",\"owner\":\"kali\",\"group\":\"kali\"},"+
|
||||
"{\"name\":\"flag\",\"entryType\":\"-\",\"size\":0,\"modificationTime\":1660763446,"+
|
||||
"\"permissions\":\"rw-rw-r--\",\"owner\":\"kali\",\"group\":\"kali\"}]}", s.buf.String())
|
||||
}
|
||||
|
||||
func (s *Ls2JsonTestSuite) TestLs2JsonWriter_WriteLink() {
|
||||
input1 := "total 4\nlrw-rw-r-- 1 kali kali 3 1660764366 another.txt -> /bin/bash\n"
|
||||
_, err := s.writer.Write([]byte(input1))
|
||||
s.NoError(err)
|
||||
s.writer.Close()
|
||||
s.Equal("{\"files\": [{\"name\":\"another.txt\",\"entryType\":\"l\",\"linkTarget\":\"/bin/bash\",\"size\":3,"+
|
||||
"\"modificationTime\":1660764366,\"permissions\":\"rw-rw-r--\",\"owner\":\"kali\",\"group\":\"kali\"}]}",
|
||||
s.buf.String())
|
||||
}
|
||||
|
Reference in New Issue
Block a user