feat: Allow reading & writing appended tar archives

This commit is contained in:
Felicitas Pojtinger
2021-11-16 02:16:51 +01:00
parent 562e733236
commit 7a9caae5a8
2 changed files with 23 additions and 5 deletions

View File

@@ -49,7 +49,19 @@ func main() {
break
}
panic(err)
// Seek one block backwards (half into the trailer) into trailer
if _, err := f.Seek((int64(*recordSize)*blockSize*record)+block*blockSize, io.SeekStart); err == nil {
tr = tar.NewReader(f)
hdr, err = tr.Next()
if err != nil {
panic(err)
}
} else {
panic(err)
}
// TODO: Seek with matching syscall (`mt seek (int64(*recordSize)*record)+1`)
}
// TODO: Do `tell` on tape drive instead, which returns the block - but how do we get the current block? Maybe we have to use the old, iterating method and call.Next after we found the correct record & block.

View File

@@ -38,12 +38,17 @@ type Operation struct {
Count int32 // Operation count
}
const (
blockSize = 512
)
func main() {
file := flag.String("file", "/dev/nst0", "File (tape drive or tar file) to open")
dir := flag.String("dir", ".", "Directory to add to the file")
flag.Parse()
seekBackwards := int64(-blockSize) // Seek back one block (half a trailer) so we can detect the invalid trailer in `tvf` and seek accordingly
isRegular := true
stat, err := os.Stat(*file)
if err == nil {
@@ -63,6 +68,8 @@ func main() {
if err := tw.Close(); err != nil {
panic(err)
}
seekBackwards = -(blockSize * 2) // Overwrite the file completely the first time
} else {
panic(err)
}
@@ -75,8 +82,8 @@ func main() {
panic(err)
}
// Seek backwards two blocks from end (to overwrite the trailer)
if _, err := f.Seek(-1024, io.SeekEnd); err != nil {
// Seek backwards into header
if _, err := f.Seek(seekBackwards, io.SeekEnd); err != nil {
panic(err)
}
} else {
@@ -92,8 +99,7 @@ func main() {
)),
)
// TODO: Seek backwards 2 blocks (1024 bytes) with the matching syscall
// TODO: Seek backwards into header with the matching syscall (`mt bsr 1`/`mt bsr 2`)
f, err = os.OpenFile(*file, os.O_APPEND|os.O_WRONLY, os.ModeCharDevice)
if err != nil {
panic(err)