func NewDebReader(rdr io.Reader) (*DebReader, error) { drdr := &DebReader{Reader: rdr, HasDebianVersion: false} arr, err := ar.NewReader(rdr) if err != nil { return nil, err } drdr.ArReader = arr return drdr, err }
//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 }
//Reading an ar archive ... func XTest_learning_reading_ar(t *testing.T) { rdr, err := os.Open(filepath.Join(deb.DistDirDefault, "testpkg_0.0.2_amd64.deb")) if err != nil { t.Fatalf("%v", err) } arr, err := ar.NewReader(rdr) if err != nil { t.Fatalf("%v", err) } // Iterate through the files in the archive. for { hdr, err := arr.Next() if err == io.EOF { // end of ar archive break } if err != nil { t.Fatalf("%v", err) } t.Logf("File %s:\n", hdr.Name) if strings.HasSuffix(hdr.Name, ".tar.gz") { // TODO } else if strings.HasSuffix(hdr.Name, ".tar") { // TODO } else if hdr.Name == "debian-binary" { b, err := ioutil.ReadAll(arr) if err != nil { t.Fatalf("%v", err) } t.Logf("Debian binary contents: %s", string(b)) } else { t.Logf("Unsupported file %s:\n", hdr.Name) } /* if _, err := io.Copy(os.Stdout, arr); err != nil { t.Fatalf("%v", err) } */ } }
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 log.Printf("File %s", thdr.Name) } } tgzr.Close() } } return fmt.Errorf("File not found") }
// ParseDebMetadata reads an artifact's contents. func DebParseMetadata(rdr io.Reader) (*Package, error) { arr, err := ar.NewReader(rdr) if err != nil { return nil, err } var pkg *Package 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 path.Base(thdr.Name) == "control" { hasControlFile = true dscr := NewDscReader(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 }
func validatePlatToolchainPackageVersion(dest platforms.Platform, goroot string, verbose bool) error { platPkgFileRuntime := filepath.Join(goroot, "pkg", dest.Os+"_"+dest.Arch, "runtime.a") nr, err := os.Open(platPkgFileRuntime) if err != nil { log.Printf("Could not validate toolchain version: %v", err) } tr, err := ar.NewReader(nr) if err != nil { log.Printf("Could not validate toolchain version: %v", err) } for { h, err := tr.Next() if err != nil { if err == io.EOF { log.Printf("Could not validate toolchain version: %v", err) return nil } log.Printf("Could not validate toolchain version: %v", err) return err } //log.Printf("Header: %+v", h) if h.Name == "__.PKGDEF" { firstLine, err := tr.NextString(50) if err != nil { log.Printf("failed to read first line of PKGDEF: %v", err) return nil } //log.Printf("pkgdef first part: '%s'", firstLine) expectedPrefix := "go object " + dest.Os + " " + dest.Arch + " " if !strings.HasPrefix(firstLine, expectedPrefix) { log.Printf("first line of __.PKGDEF does not match expected pattern: %v", expectedPrefix) return nil } parts := strings.Split(firstLine, " ") compiledVersion := parts[4] //runtimeVersion := runtime.Version() //log.Printf("Runtime version: %s", runtimeVersion) cmdPath := filepath.Join(goroot, "bin", "go") cmd := exec.Command(cmdPath) args := []string{"version"} err = executils.PrepareCmd(cmd, ".", args, []string{}, false) if err != nil { log.Printf("`go version` failed: %v", err) return nil } goVersionOutput, err := cmd.Output() if err != nil { log.Printf("`go version` failed: %v", err) return nil } //log.Printf("output: %s", string(out)) goVersionOutputParts := strings.Split(string(goVersionOutput), " ") goVersion := goVersionOutputParts[2] if compiledVersion != goVersion { return errors.New("static library version '" + compiledVersion + "' does NOT match `go version` '" + goVersion + "'!") } if verbose { log.Printf("Toolchain version '%s' verified against 'go %s' for %v", compiledVersion, goVersion, dest) } return nil } } }
func Example() { // Create a buffer to write our archive to. wtr := new(bytes.Buffer) // Create a new ar archive. aw := ar.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 := &ar.Header{ Name: file.Name, Size: int64(len(file.Body)), } if err := aw.WriteHeader(hdr); err != nil { log.Fatalln(err) } if _, err := aw.Write([]byte(file.Body)); err != nil { log.Fatalln(err) } } // Make sure to check the error on Close. if err := aw.Close(); err != nil { log.Fatalln(err) } // Open the ar archive for reading. rdr := bytes.NewReader(wtr.Bytes()) arr, err := ar.NewReader(rdr) if err != nil { log.Fatalln(err) } // Iterate through the files in the archive. for { hdr, err := arr.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, arr); 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. }