diff --git a/cmd/stfs-seek-tape/main.go b/cmd/stfs-seek-tape/main.go index 9d575e2..5b4658f 100644 --- a/cmd/stfs-seek-tape/main.go +++ b/cmd/stfs-seek-tape/main.go @@ -39,17 +39,7 @@ func main() { } defer f.Close() - if _, _, err := syscall.Syscall( - syscall.SYS_IOCTL, - f.Fd(), - MTIOCTOP, - uintptr(unsafe.Pointer( - &Operation{ - Op: MTSEEK, - Count: int32(*record), - }, - )), - ); err != 0 { + if err := seekToRecordOnTape(f, int32(*record)); err != nil { panic(err) } @@ -67,3 +57,21 @@ func main() { 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-tvf-simple/main.go b/cmd/stfs-tvf-simple/main.go index f0f554c..88c8f73 100644 --- a/cmd/stfs-tvf-simple/main.go +++ b/cmd/stfs-tvf-simple/main.go @@ -7,8 +7,6 @@ import ( "io" "log" "os" - "syscall" - "unsafe" ) // See https://github.com/benmcclelland/mtio @@ -32,6 +30,24 @@ type Operation struct { Count int32 // Operation count } +type Counter struct { + reader io.Reader + + bytesRead int +} + +func (r *Counter) Read(p []byte) (n int, err error) { + n, err = r.reader.Read(p) + + r.bytesRead += n + + return n, err +} + +func (r *Counter) GetBytesRead() int { + return r.bytesRead +} + 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") @@ -119,54 +135,28 @@ func main() { } } else { br := bufio.NewReaderSize(f, blockSize**recordSize) + counter := &Counter{reader: br} + + record := int64(0) + block := int64(0) - currentRecord := 0 - o: for { - for currentBlock := 0; currentBlock < *recordSize; currentBlock++ { - if currentRecord%4096 == 0 { - tell, err := getCurrentRecordFromTape(f) - if err != nil { - panic(err) - } - - if tell < int64(currentRecord) { - // EOD - - break o - } - } - - tr := tar.NewReader(br) - hdr, err := tr.Next() - if err != nil { - continue - } - - if hdr.Format == tar.FormatUnknown { - continue - } - - log.Println("Record:", currentRecord, "Block:", currentBlock, "Header:", hdr) - - // TODO: Seek to (curr + hdr.Size)/blockSize if recordToSeekTo != currentRecord, re-write `br` + tr := tar.NewReader(counter) + hdr, err := tr.Next() + if err != nil { + continue } - currentRecord++ + if hdr.Format == tar.FormatUnknown { + continue + } + + log.Println("Record:", record, "Block:", block, "Header:", hdr) + + nextBytes := int64(counter.GetBytesRead()) + hdr.Size + blockSize - 1 + + record = nextBytes / (blockSize * int64(*recordSize)) + block = (nextBytes - (record * int64(*recordSize) * blockSize)) / blockSize } } } - -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 -}