diff --git a/debian/deb.go b/debian/deb.go new file mode 100644 index 00000000..194eac41 --- /dev/null +++ b/debian/deb.go @@ -0,0 +1,59 @@ +package debian + +import ( + "archive/tar" + "compress/gzip" + "fmt" + "github.com/mkrautz/goar" + "io" + "os" +) + +// GetControlFileFromDeb read control file from deb package +func GetControlFileFromDeb(packageFile string) (Stanza, error) { + file, err := os.Open(packageFile) + if err != nil { + return nil, err + } + defer file.Close() + + library := ar.NewReader(file) + for { + header, err := library.Next() + if err == io.EOF { + return nil, fmt.Errorf("unable to find control.tar.gz part") + } + if err != nil { + return nil, fmt.Errorf("unable to read .deb archive: %s", err) + } + + if header.Name == "control.tar.gz" { + ungzip, err := gzip.NewReader(library) + if err != nil { + return nil, fmt.Errorf("unable to ungzip: %s", err) + } + defer ungzip.Close() + + untar := tar.NewReader(ungzip) + for { + tarHeader, err := untar.Next() + if err == io.EOF { + return nil, fmt.Errorf("unable to find control file") + } + if err != nil { + return nil, fmt.Errorf("unable to read .tar archive: %s", err) + } + + if tarHeader.Name == "./control" { + reader := NewControlFileReader(untar) + stanza, err := reader.ReadStanza() + if err != nil { + return nil, err + } + + return stanza, nil + } + } + } + } +} diff --git a/debian/deb_test.go b/debian/deb_test.go new file mode 100644 index 00000000..d3fb7e33 --- /dev/null +++ b/debian/deb_test.go @@ -0,0 +1,32 @@ +package debian + +import ( + . "launchpad.net/gocheck" + "path/filepath" + "runtime" +) + +type DebSuite struct { + debFile string +} + +var _ = Suite(&DebSuite{}) + +func (s *DebSuite) SetUpSuite(c *C) { + _, __file__, _, _ := runtime.Caller(0) + s.debFile = filepath.Join(filepath.Dir(__file__), "../system/files/libboost-program-options-dev_1.49.0.1_i386.deb") +} + +func (s *DebSuite) TestGetControlFileFromDeb(c *C) { + _, err := GetControlFileFromDeb("/no/such/file") + c.Check(err, ErrorMatches, ".*no such file or directory") + + _, __file__, _, _ := runtime.Caller(0) + _, err = GetControlFileFromDeb(__file__) + c.Check(err, ErrorMatches, "unable to read .deb archive: ar: missing global header") + + st, err := GetControlFileFromDeb(s.debFile) + c.Check(err, IsNil) + c.Check(st["Version"], Equals, "1.49.0.1") + c.Check(st["Package"], Equals, "libboost-program-options-dev") +} diff --git a/system/files/libboost-program-options-dev_1.49.0.1_i386.deb b/system/files/libboost-program-options-dev_1.49.0.1_i386.deb new file mode 100644 index 00000000..a69ba17b Binary files /dev/null and b/system/files/libboost-program-options-dev_1.49.0.1_i386.deb differ