...

Source file src/github.com/vbatts/tar-split/concept/main.go

Documentation: github.com/vbatts/tar-split/concept

     1  //go:build ignore
     2  // +build ignore
     3  
     4  package main
     5  
     6  import (
     7  	"flag"
     8  	"fmt"
     9  	"io"
    10  	"log"
    11  	"os"
    12  
    13  	"github.com/vbatts/tar-split/archive/tar"
    14  )
    15  
    16  func main() {
    17  	flag.Parse()
    18  	log.SetOutput(os.Stderr)
    19  	for _, arg := range flag.Args() {
    20  		func() {
    21  			// Open the tar archive
    22  			fh, err := os.Open(arg)
    23  			if err != nil {
    24  				log.Fatal(err, arg)
    25  			}
    26  			defer fh.Close()
    27  
    28  			output, err := os.Create(fmt.Sprintf("%s.out", arg))
    29  			if err != nil {
    30  				log.Fatal(err)
    31  			}
    32  			defer output.Close()
    33  			log.Printf("writing %q to %q", fh.Name(), output.Name())
    34  
    35  			fi, err := fh.Stat()
    36  			if err != nil {
    37  				log.Fatal(err, fh.Name())
    38  			}
    39  			size := fi.Size()
    40  			var sum int64
    41  			tr := tar.NewReader(fh)
    42  			tr.RawAccounting = true
    43  			for {
    44  				hdr, err := tr.Next()
    45  				if err != nil {
    46  					if err != io.EOF {
    47  						log.Println(err)
    48  					}
    49  					// even when an EOF is reached, there is often 1024 null bytes on
    50  					// the end of an archive. Collect them too.
    51  					post := tr.RawBytes()
    52  					output.Write(post)
    53  					sum += int64(len(post))
    54  
    55  					fmt.Printf("EOF padding: %d\n", len(post))
    56  					break
    57  				}
    58  
    59  				pre := tr.RawBytes()
    60  				output.Write(pre)
    61  				sum += int64(len(pre))
    62  
    63  				var i int64
    64  				if i, err = io.Copy(output, tr); err != nil {
    65  					log.Println(err)
    66  					break
    67  				}
    68  				sum += i
    69  
    70  				fmt.Println(hdr.Name, "pre:", len(pre), "read:", i)
    71  			}
    72  
    73  			// it is allowable, and not uncommon that there is further padding on the
    74  			// end of an archive, apart from the expected 1024 null bytes
    75  			remainder, err := io.ReadAll(fh)
    76  			if err != nil && err != io.EOF {
    77  				log.Fatal(err, fh.Name())
    78  			}
    79  			output.Write(remainder)
    80  			sum += int64(len(remainder))
    81  			fmt.Printf("Remainder: %d\n", len(remainder))
    82  
    83  			if size != sum {
    84  				fmt.Printf("Size: %d; Sum: %d; Diff: %d\n", size, sum, size-sum)
    85  				fmt.Printf("Compare like `cmp -bl %s %s | less`\n", fh.Name(), output.Name())
    86  			} else {
    87  				fmt.Printf("Size: %d; Sum: %d\n", size, sum)
    88  			}
    89  		}()
    90  	}
    91  }
    92  

View as plain text