archivescanner

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 14, 2026 License: GPL-3.0 Imports: 13 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DetectFormat

func DetectFormat(ctx context.Context, bsdtarPath, archivePath string) (format, compression string, err error)

DetectFormat runs bsdtar -tvvf on the given archive and returns the "Archive Format: ..., Compression: ..." trailer line. This can be used to determine the appropriate file extension for a blob that has no original filename recorded.

func ScanOne

func ScanOne(
	ctx context.Context,
	sqldb *sql.DB,
	queries *dbq.Queries,
	store blobstore.Store,
	scanner Scanner,
	archiveSha256 string,
	logger *slog.Logger,
) error

ScanOne scans a single archive by sha256 and commits its inventory in a single transaction. If the archive has already been inventoried it is a no-op. Returns an error only if the scan or commit fails - the caller is responsible for deciding how loudly to surface that.

Types

type Entry

type Entry struct {
	// Position is the zero-based index of this entry in the archive listing
	// Used as the canonical key since archives may contain duplicate paths
	Position int

	// RawPath is the path as it appears in the archive, unmodified
	RawPath string

	// Type is the entry type derived from the permission string
	Type EntryType

	// SizeBytes is the uncompressed size as reported by the archive header
	// Zero for directories; may be zero for symlinks
	SizeBytes int64

	// LinkTarget is the symlink destination, only set when Type == EntryTypeSymlink
	LinkTarget string

	// ParseError is non-empty if this line could not be fully parsed.
	// The entry is still recorded with whatever fields were extractable,
	// and Type will be EntryTypeOther
	ParseError string
}

Entry represents a single entry parsed from `bsdtar -tvvf` output. It reflects the raw archive contents before any remap rules are applied. Paths are not normalized or validated here - that is the planner's job.

func Parse

func Parse(r io.Reader) ([]Entry, error)

Parse reads the output of `bsdtar -tvvf <archive>` and returns one Entry per line. It never returns an error for individual bad lines - those are recorded in Entry.ParseError so the caller gets a complete picture of the archive. A non-nil error return means the reader itself failed.

bsdtar -tvvf produces lines like:

-rw-r--r--  0 0      0      123456 Jan  1 00:00 path/to/file
lrwxrwxrwx  0 0      0           0 Jan  1 00:00 link -> target
drwxr-xr-x  0 0      0           0 Jan  1 00:00 some/dir/

bsdtar prints a summary trailer as the final line, e.g.:

"Archive Format: POSIX ustar format,  Compression: gzip"
"Archive Format: RAR,  Compression: none"
"Archive Format: 7-Zip,  Compression: none"

This line is skipped and does not produce an Entry.

type EntryType

type EntryType string

EntryType represents the type of an entry within an archive, as reported by bsdtar.

const (
	EntryTypeFile    EntryType = "file"
	EntryTypeDir     EntryType = "dir"
	EntryTypeSymlink EntryType = "symlink"
	EntryTypeOther   EntryType = "other"
)

type ScanAllResult

type ScanAllResult struct {
	Scanned int
	Failed  int
}

ScanAllResult summarizes the outcome of a ScanAll run

func ScanAll

func ScanAll(
	ctx context.Context,
	sqldb *sql.DB,
	queries *dbq.Queries,
	store blobstore.Store,
	scanner Scanner,
	logger *slog.Logger,
) (ScanAllResult, error)

ScanAll scans all archives that have not yet had their inventory populated Each archive is scanned and committed in its own transaction so progress is saved as we go - a failure on one archive does not affect others Individual archive failures are logged but do not abort the run

type ScanResult

type ScanResult struct {
	Entries []Entry
	// Warnings contains any output bsdtar wrote to stderr. A non-empty
	// Warnings does not indicate failure - the scan succeeded but bsdtar
	// had something to say (e.g. unsupported extended attributes).
	Warnings string
}

ScanResult is the output of a successful scan

type Scanner

type Scanner struct {
	// BsdtarPath is the path to the bsdtar binary. If empty, "bsdtar" is
	// looked up via PATH
	BsdtarPath string
}

Scanner invokes bsdtar to list archive contents

func (Scanner) Scan

func (s Scanner) Scan(ctx context.Context, archivePath string) (ScanResult, error)

Scan runs `bsdtar -tvvf <archivePath>` and returns the parsed entries A non-zero exit from bsdtar is treated as a hard error; the stderr output is included in the returned error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL