From 621cc0b055ce34015526b0a577ffa4b6d2c09a3c Mon Sep 17 00:00:00 2001 From: Felicitas Pojtinger Date: Fri, 19 Nov 2021 00:10:13 +0100 Subject: [PATCH] feat: Make `seek` command universal --- cmd/stfs-seek-tape/main.go | 77 -------------------------------------- cmd/stfs-seek/main.go | 72 ++++++++++------------------------- 2 files changed, 20 insertions(+), 129 deletions(-) delete mode 100644 cmd/stfs-seek-tape/main.go diff --git a/cmd/stfs-seek-tape/main.go b/cmd/stfs-seek-tape/main.go deleted file mode 100644 index 5b4658f..0000000 --- a/cmd/stfs-seek-tape/main.go +++ /dev/null @@ -1,77 +0,0 @@ -package main - -import ( - "archive/tar" - "bufio" - "flag" - "log" - "os" - "syscall" - "unsafe" -) - -// See https://github.com/benmcclelland/mtio -const ( - MTIOCTOP = 0x40086d01 // Do magnetic tape operation - MTSEEK = 22 // Seek to block - - blockSize = 512 -) - -// Operation is struct for MTIOCTOP -type Operation struct { - Op int16 // Operation ID - Pad int16 // Padding to match C structures - Count int32 // Operation count -} - -func main() { - file := flag.String("file", "/dev/nst0", "File (tape drive or tar file) to open") - recordSize := flag.Int("recordSize", 20, "Amount of 512-bit blocks per record") - record := flag.Int("record", 0, "Record to seek too") - block := flag.Int("block", 0, "Block in record to seek too") - - flag.Parse() - - f, err := os.OpenFile(*file, os.O_RDONLY, os.ModeCharDevice) - if err != nil { - panic(err) - } - defer f.Close() - - if err := seekToRecordOnTape(f, int32(*record)); err != nil { - panic(err) - } - - br := bufio.NewReaderSize(f, blockSize**recordSize) - if _, err := br.Read(make([]byte, *block*blockSize)); err != nil { - panic(err) - } - - tr := tar.NewReader(br) - - hdr, err := tr.Next() - if err != nil { - panic(err) - } - - log.Println(hdr) -} - -func seekToRecordOnTape(f *os.File, record int32) error { - if _, _, err := syscall.Syscall( - syscall.SYS_IOCTL, - f.Fd(), - MTIOCTOP, - uintptr(unsafe.Pointer( - &Operation{ - Op: MTSEEK, - Count: record, - }, - )), - ); err != 0 { - return err - } - - return nil -} diff --git a/cmd/stfs-seek/main.go b/cmd/stfs-seek/main.go index 29eb810..e1be816 100644 --- a/cmd/stfs-seek/main.go +++ b/cmd/stfs-seek/main.go @@ -4,7 +4,6 @@ import ( "archive/tar" "bufio" "flag" - "io" "log" "os" "syscall" @@ -51,60 +50,43 @@ func main() { if err != nil { panic(err) } - - // Seek to record & block - if _, err := f.Seek(int64((*recordSize*blockSize**record)+*block*blockSize), 0); err != nil { - panic(err) - } } else { f, err = os.OpenFile(*file, os.O_RDONLY, os.ModeCharDevice) if err != nil { panic(err) } - - // Seek to record (we can't seek to block on tape) - // TODO: Seek to next header here too; currently this only works for the start of each archive/after a filemark - if err := seekToRecordOnTape(f, int32(*record)); err != nil { - panic(err) - } } defer f.Close() var tr *tar.Reader if fileDescription.Mode().IsRegular() { - tr = tar.NewReader(f) - } else { - br := bufio.NewReaderSize(f, blockSize**recordSize) - tr = tar.NewReader(br) - } - - for { - hdr, err := tr.Next() - if err != nil { + // Seek to record and block + if _, err := f.Seek(int64((*recordSize*blockSize**record)+*block*blockSize), 0); err != nil { panic(err) } - log.Println(hdr) - - currentRecord := int64(0) - if fileDescription.Mode().IsRegular() { - curr, err := f.Seek(0, io.SeekCurrent) - if err != nil { - panic(err) - } - - currentRecord = ((curr + hdr.Size) / blockSize) / int64(*recordSize) - } else { - currentRecord, err = getCurrentRecordFromTape(f) - if err != nil { - panic(err) - } + tr = tar.NewReader(f) + } else { + // Seek to record + if err := seekToRecordOnTape(f, int32(*record)); err != nil { + panic(err) } - if currentRecord > int64(*record) { - break + // Seek to block + br := bufio.NewReaderSize(f, blockSize**recordSize) + if _, err := br.Read(make([]byte, *block*blockSize)); err != nil { + panic(err) } + + tr = tar.NewReader(br) } + + hdr, err := tr.Next() + if err != nil { + panic(err) + } + + log.Println(hdr) } func seekToRecordOnTape(f *os.File, record int32) error { @@ -124,17 +106,3 @@ func seekToRecordOnTape(f *os.File, record int32) error { return nil } - -func getCurrentRecordFromTape(f *os.File) (int64, error) { - pos := &Position{} - if _, _, err := syscall.Syscall( - syscall.SYS_IOCTL, - f.Fd(), - MTIOCPOS, - uintptr(unsafe.Pointer(pos)), - ); err != 0 { - return 0, err - } - - return pos.BlkNo, nil -}