//debGetContents just lists the contents of a tar.gz file within the archive func debGetContents(rdr io.Reader, topLevelFilename string) ([]string, error) { ret := []string{} fileNotFound := true arr, err := ar.NewReader(rdr) if err != nil { return nil, err } for { hdr, err := arr.Next() if err == io.EOF { // end of ar archive break } if err != nil { return nil, err } if hdr.Name == topLevelFilename { fileNotFound = false tgzr, err := targz.NewReader(arr) if err != nil { e := tgzr.Close() if e != nil { //log it here? } return nil, err } for { thdr, err := tgzr.Next() if err == io.EOF { // end of tar.gz archive break } if err != nil { e := tgzr.Close() if e != nil { //log it here? } return nil, err } ret = append(ret, thdr.Name) } } } if fileNotFound { return nil, fmt.Errorf("File not found") } return ret, nil }
//NextTar gets next tar header (for supported tar archive types - initially just tar.gz) func (drdr *Reader) NextTar() (string, *tar.Reader, error) { for { hdr, err := drdr.ArReader.Next() if err != nil { return "", nil, err } if hdr.Name == "debian-binary" { drdr.HasDebianVersion = true continue } if strings.HasSuffix(hdr.Name, ".tar.gz") { tgzr, err := targz.NewReader(drdr.ArReader) return hdr.Name, tgzr.Reader, err } // else return error return hdr.Name, nil, fmt.Errorf("Unsuported file type: %s", hdr.Name) } }
//debExtractFileL2 extracts a file from a tar.gz within the archive. func debExtractFileL2(rdr io.Reader, topLevelFilename string, secondLevelFilename string, destination io.Writer) error { arr, err := ar.NewReader(rdr) if err != nil { return err } for { hdr, err := arr.Next() if err == io.EOF { // end of ar archive break } if err != nil { return err } if hdr.Name == topLevelFilename { tgzr, err := targz.NewReader(arr) if err != nil { tgzr.Close() return err } for { thdr, err := tgzr.Next() if err == io.EOF { // end of tar.gz archive break } if err != nil { tgzr.Close() return err } if thdr.Name == secondLevelFilename { _, err = io.Copy(destination, tgzr) tgzr.Close() return nil } // else skip this file log.Printf("File %s", thdr.Name) } tgzr.Close() } } return fmt.Errorf("File not found") }
func Test_fs(t *testing.T) { // Create a buffer to write our archive to. wtr := writer() // Create a new ar archive. tgzw := targz.NewWriter(wtr) // Add some files to the archive. var files = []struct { Name, Body string }{ {"readme.txt", "This archive contains some text files."}, {"gopher.txt", "Gopher names:\nGeorge\nGeoffrey\nGonzo"}, {"todo.txt", "Get animal handling licence."}, } for _, file := range files { hdr := &tar.Header{ Name: file.Name, Size: int64(len(file.Body)), } if err := tgzw.WriteHeader(hdr); err != nil { log.Fatalln(err) } if _, err := tgzw.Write([]byte(file.Body)); err != nil { log.Fatalln(err) } } // Make sure to check the error on Close. if err := tgzw.Close(); err != nil { log.Fatalln(err) } rdr := reader(wtr) tgzr, err := targz.NewReader(rdr) if err != nil { log.Fatalln(err) } // Iterate through the files in the archive. for { hdr, err := tgzr.Next() if err == io.EOF { // end of ar archive break } if err != nil { log.Fatalln(err) } fmt.Printf("Contents of %s:\n", hdr.Name) if _, err := io.Copy(os.Stdout, tgzr); err != nil { log.Fatalln(err) } fmt.Println() } // Output: // Contents of readme.txt: // This archive contains some text files. // Contents of gopher.txt: // Gopher names: // George // Geoffrey // Gonzo // Contents of todo.txt: // Get animal handling licence. }
// ParseDebMetadata reads an artifact's contents. func ParseDebMetadata(rdr io.Reader) (*Control, error) { arr, err := ar.NewReader(rdr) if err != nil { return nil, err } var pkg *Control pkg = nil hasDataArchive := false hasControlArchive := false hasControlFile := false hasDebianBinaryFile := false // Iterate through the files in the archive. for { hdr, err := arr.Next() if err == io.EOF { // end of ar archive break } if err != nil { return nil, err } // t.Logf("File %s:\n", hdr.Name) if hdr.Name == BinaryDataArchiveNameDefault { // SKIP! hasDataArchive = true } else if hdr.Name == BinaryControlArchiveNameDefault { // Find control file hasControlArchive = true tgzr, err := targz.NewReader(arr) if err != nil { return nil, err } for { thdr, err := tgzr.Next() if err == io.EOF { // end of tar.gz archive break } if err != nil { return nil, err } if thdr.Name == "control" { hasControlFile = true dscr := NewControlFileReader(tgzr) pkg, err = dscr.Parse() if err != nil { return nil, err } } else { //SKIP log.Printf("File %s", thdr.Name) } } } else if hdr.Name == "debian-binary" { b, err := ioutil.ReadAll(arr) if err != nil { return nil, err } hasDebianBinaryFile = true if string(b) != "2.0\n" { return nil, fmt.Errorf("Binary version not valid: %s", string(b)) } } else { return nil, fmt.Errorf("Unsupported file %s", hdr.Name) } } if !hasDebianBinaryFile { return nil, fmt.Errorf("No debian-binary file in .deb archive") } if !hasDataArchive { return nil, fmt.Errorf("No data.tar.gz file in .deb archive") } if !hasControlArchive { return nil, fmt.Errorf("No control.tar.gz file in .deb archive") } if !hasControlFile { return nil, fmt.Errorf("No debian/control file in control.tar.gz") } return pkg, nil }