diff --git a/cmd/go-unsquashfs/main.go b/cmd/go-unsquashfs/main.go index 9915b0a..fe4ce13 100644 --- a/cmd/go-unsquashfs/main.go +++ b/cmd/go-unsquashfs/main.go @@ -6,14 +6,33 @@ import ( "io/fs" "os" "path/filepath" + "strings" "time" "github.com/CalebQ42/squashfs" ) +func printEntry(root, path string, d fs.DirEntry) { + fi, _ := d.Info() + sfi := fi.(squashfs.FileInfo) + owner := fmt.Sprintf("%d/%d", + sfi.Uid(), + sfi.Gid()) + link := "" + if sfi.IsSymlink() { + link = " -> " + sfi.SymlinkPath() + } + fmt.Printf("%s %s %*d %s %s%s\n", + strings.ToLower(fi.Mode().String()), + owner, 26-len(owner), fi.Size(), + fi.ModTime().Format("2006-01-02 15:04"), + filepath.Join(root, path), link) +} + func main() { verbose := flag.Bool("v", false, "Verbose") list := flag.Bool("l", false, "List") + long := flag.Bool("ll", false, "List with attributes") ignore := flag.Bool("ip", false, "Ignore Permissions and extract all files/folders with 0755") flag.Parse() if len(flag.Args()) < 2 { @@ -28,13 +47,17 @@ func main() { if err != nil { panic(err) } - if *list { + if *list || *long { root := flag.Arg(1) fs.WalkDir(r, ".", func(path string, d fs.DirEntry, err error) error { if err != nil { panic(err) } - fmt.Println(filepath.Join(root, path)) + if *long { + printEntry(root, path, d) + } else { + fmt.Println(filepath.Join(root, path)) + } return nil }) return diff --git a/file_info.go b/file_info.go index 06f90c7..6c00017 100644 --- a/file_info.go +++ b/file_info.go @@ -11,6 +11,7 @@ import ( type FileInfo struct { name string size int64 + target string perm uint32 modTime uint32 fileType uint16 @@ -26,15 +27,21 @@ func (r Reader) newFileInfo(e directory.Entry) (FileInfo, error) { func newFileInfo(name string, i *inode.Inode) FileInfo { var size int64 + var target string switch i.Type { case inode.Fil: size = int64(i.Data.(inode.File).Size) case inode.EFil: size = int64(i.Data.(inode.EFile).Size) + case inode.Sym: + target = string(i.Data.(inode.Symlink).Target) + case inode.ESym: + target = string(i.Data.(inode.ESymlink).Target) } return FileInfo{ name: name, size: size, + target: target, perm: uint32(i.Perm), modTime: i.ModTime, fileType: i.Type, @@ -49,6 +56,10 @@ func (f FileInfo) Size() int64 { return f.size } +func (f FileInfo) SymlinkPath() string { + return f.target +} + func (f FileInfo) Mode() fs.FileMode { switch f.fileType { case inode.Dir, inode.EDir: