diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2023-03-17 23:54:56 -0400 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2023-03-17 23:54:56 -0400 |
commit | 0f96c9ce920875babd4cd23819a2fb2960dc0cc6 (patch) | |
tree | f50d5a547f354413f45b9a9d497af77a31a7d10b /cmd/btrfs-rec/inspect_lsfiles.go | |
parent | 0f85e72d1331b49b52925d6cc5ad083a0376104c (diff) | |
parent | 3fea600da8e033abb7e415694e53aaf0787ed95c (diff) |
Merge branch 'lukeshu/api-cleanup'
Diffstat (limited to 'cmd/btrfs-rec/inspect_lsfiles.go')
-rw-r--r-- | cmd/btrfs-rec/inspect_lsfiles.go | 228 |
1 files changed, 4 insertions, 224 deletions
diff --git a/cmd/btrfs-rec/inspect_lsfiles.go b/cmd/btrfs-rec/inspect_lsfiles.go index a2b46ab..04b5ec5 100644 --- a/cmd/btrfs-rec/inspect_lsfiles.go +++ b/cmd/btrfs-rec/inspect_lsfiles.go @@ -6,23 +6,14 @@ package main import ( "bufio" - "errors" - "fmt" - "io" "os" - "path" - "strings" - "github.com/datawire/dlib/derror" "github.com/datawire/ocibuild/pkg/cliutil" "github.com/spf13/cobra" + "git.lukeshu.com/btrfs-progs-ng/cmd/btrfs-rec/inspect/lsfiles" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs" - "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsitem" - "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsprim" "git.lukeshu.com/btrfs-progs-ng/lib/btrfsutil" - "git.lukeshu.com/btrfs-progs-ng/lib/maps" - "git.lukeshu.com/btrfs-progs-ng/lib/textui" ) func init() { @@ -37,221 +28,10 @@ func init() { err = _err } }() - defer func() { - if _err := derror.PanicToError(recover()); _err != nil { - textui.Fprintf(out, "\n\n%+v\n", _err) - err = _err - } - }() - ctx := cmd.Context() - printSubvol(out, "", true, "/", &btrfs.Subvolume{ - FS: btrfsutil.NewOldRebuiltForrest(ctx, fs), - TreeID: btrfsprim.FS_TREE_OBJECTID, - }) - - return nil + return lsfiles.LsFiles( + out, + btrfsutil.NewOldRebuiltForrest(cmd.Context(), fs)) }), }) } - -const ( - tS = " " - tl = "│ " - tT = "├── " - tL = "└── " -) - -func printText(out io.Writer, prefix string, isLast bool, name, text string) { - first, rest := tT, tl - if isLast { - first, rest = tL, tS - } - for i, line := range strings.Split(textui.Sprintf("%q %s", name, text), "\n") { - _, _ = io.WriteString(out, prefix) - if i == 0 { - _, _ = io.WriteString(out, first) - } else { - _, _ = io.WriteString(out, rest) - } - _, _ = io.WriteString(out, line) - _, _ = io.WriteString(out, "\n") - } -} - -func printSubvol(out io.Writer, prefix string, isLast bool, name string, subvol *btrfs.Subvolume) { - rootInode, err := subvol.GetRootInode() - if err != nil { - printText(out, prefix, isLast, name+"/", textui.Sprintf("subvol_id=%v err=%v", - subvol.TreeID, fmtErr(err))) - return - } - dir, err := subvol.LoadDir(rootInode) - if err != nil { - printText(out, prefix, isLast, name+"/", textui.Sprintf("subvol_id=%v err=%v", - subvol.TreeID, fmtErr(err))) - return - } - if name == "/" { - printDir(out, prefix, isLast, name, dir) - return - } - printText(out, prefix, isLast, name+"/", textui.Sprintf("subvol_id=%v", subvol.TreeID)) - if isLast { - prefix += tS - } else { - prefix += tl - } - printDir(out, prefix, true, name, dir) -} - -func fmtErr(err error) string { - errStr := err.Error() - if strings.Contains(errStr, "\n") { - errStr = "\\\n" + errStr - } - return errStr -} - -func fmtInode(inode btrfs.BareInode) string { - var mode btrfsitem.StatMode - if inode.InodeItem == nil { - inode.Errs = append(inode.Errs, errors.New("missing INODE_ITEM")) - } else { - mode = inode.InodeItem.Mode - } - ret := textui.Sprintf("ino=%v mode=%v", inode.Inode, mode) - if len(inode.Errs) > 0 { - ret += " err=" + fmtErr(inode.Errs) - } - return ret -} - -func printDir(out io.Writer, prefix string, isLast bool, name string, dir *btrfs.Dir) { - printText(out, prefix, isLast, name+"/", fmtInode(dir.BareInode)) - if isLast { - prefix += tS - } else { - prefix += tl - } - for i, childName := range maps.SortedKeys(dir.ChildrenByName) { - printDirEntry( - out, - prefix, - i == len(dir.ChildrenByName)-1, - dir.SV, - path.Join(name, childName), - dir.ChildrenByName[childName]) - } -} - -func printDirEntry(out io.Writer, prefix string, isLast bool, subvol *btrfs.Subvolume, name string, entry btrfsitem.DirEntry) { - if len(entry.Data) != 0 { - panic(fmt.Errorf("TODO: I don't know how to handle dirent.data: %q", name)) - } - switch entry.Type { - case btrfsitem.FT_DIR: - switch entry.Location.ItemType { - case btrfsitem.INODE_ITEM_KEY: - dir, err := subvol.LoadDir(entry.Location.ObjectID) - if err != nil { - printText(out, prefix, isLast, name, textui.Sprintf("%v err=%v", entry.Type, fmtErr(err))) - return - } - printDir(out, prefix, isLast, name, dir) - case btrfsitem.ROOT_ITEM_KEY: - printSubvol(out, prefix, isLast, name, &btrfs.Subvolume{ - FS: subvol.FS, - TreeID: entry.Location.ObjectID, - }) - default: - panic(fmt.Errorf("TODO: I don't know how to handle an FT_DIR with location.ItemType=%v: %q", - entry.Location.ItemType, name)) - } - case btrfsitem.FT_SYMLINK: - if entry.Location.ItemType != btrfsitem.INODE_ITEM_KEY { - panic(fmt.Errorf("TODO: I don't know how to handle an FT_SYMLINK with location.ItemType=%v: %q", - entry.Location.ItemType, name)) - } - file, err := subvol.LoadFile(entry.Location.ObjectID) - if err != nil { - printText(out, prefix, isLast, name, textui.Sprintf("%v err=%v", entry.Type, fmtErr(err))) - return - } - printSymlink(out, prefix, isLast, name, file) - case btrfsitem.FT_REG_FILE: - if entry.Location.ItemType != btrfsitem.INODE_ITEM_KEY { - panic(fmt.Errorf("TODO: I don't know how to handle an FT_REG_FILE with location.ItemType=%v: %q", - entry.Location.ItemType, name)) - } - file, err := subvol.LoadFile(entry.Location.ObjectID) - if err != nil { - printText(out, prefix, isLast, name, textui.Sprintf("%v err=%v", entry.Type, fmtErr(err))) - return - } - printFile(out, prefix, isLast, name, file) - case btrfsitem.FT_SOCK: - if entry.Location.ItemType != btrfsitem.INODE_ITEM_KEY { - panic(fmt.Errorf("TODO: I don't know how to handle an FT_SOCK with location.ItemType=%v: %q", - entry.Location.ItemType, name)) - } - file, err := subvol.LoadFile(entry.Location.ObjectID) - if err != nil { - printText(out, prefix, isLast, name, textui.Sprintf("%v err=%v", entry.Type, fmtErr(err))) - return - } - printSocket(out, prefix, isLast, name, file) - case btrfsitem.FT_FIFO: - if entry.Location.ItemType != btrfsitem.INODE_ITEM_KEY { - panic(fmt.Errorf("TODO: I don't know how to handle an FT_FIFO with location.ItemType=%v: %q", - entry.Location.ItemType, name)) - } - file, err := subvol.LoadFile(entry.Location.ObjectID) - if err != nil { - printText(out, prefix, isLast, name, textui.Sprintf("%v err=%v", entry.Type, fmtErr(err))) - return - } - printPipe(out, prefix, isLast, name, file) - default: - panic(fmt.Errorf("TODO: I don't know how to handle a fileType=%v: %q", - entry.Type, name)) - } -} - -func printSymlink(out io.Writer, prefix string, isLast bool, name string, file *btrfs.File) { - var tgt []byte - if file.InodeItem != nil { - var err error - tgt, err = io.ReadAll(io.NewSectionReader(file, 0, file.InodeItem.Size)) - if err != nil { - file.Errs = append(file.Errs, err) - } - } - printText(out, prefix, isLast, name, textui.Sprintf( - "-> %q : %s", - tgt, - fmtInode(file.BareInode))) -} - -func printFile(out io.Writer, prefix string, isLast bool, name string, file *btrfs.File) { - if file.InodeItem != nil { - if _, err := io.Copy(io.Discard, io.NewSectionReader(file, 0, file.InodeItem.Size)); err != nil { - file.Errs = append(file.Errs, err) - } - } - printText(out, prefix, isLast, name, fmtInode(file.BareInode)) -} - -func printSocket(out io.Writer, prefix string, isLast bool, name string, file *btrfs.File) { - if file.InodeItem != nil && file.InodeItem.Size > 0 { - panic(fmt.Errorf("TODO: I don't know how to handle a socket with size>0: %q", name)) - } - printText(out, prefix, isLast, name, fmtInode(file.BareInode)) -} - -func printPipe(out io.Writer, prefix string, isLast bool, name string, file *btrfs.File) { - if file.InodeItem != nil && file.InodeItem.Size > 0 { - panic(fmt.Errorf("TODO: I don't know how to handle a pipe with size>0: %q", name)) - } - printText(out, prefix, isLast, name, fmtInode(file.BareInode)) -} |