Пример #1
0
// member(arMember, tarMember) returns the content of the given tar member of
// the given ar member tar.
//
// Confused? look at ControlMember and MetaMember, which this generalises.
func (d *ClickDeb) member(arMember, tarMember string) (content []byte, err error) {

	if _, err := d.file.Seek(0, 0); err != nil {
		return nil, err
	}

	arReader := ar.NewReader(d.file)
	dataReader, err := skipToArMember(arReader, arMember)
	if err != nil {
		return nil, err
	}

	found := false
	err = helpers.TarIterate(dataReader, func(tr *tar.Reader, hdr *tar.Header) error {
		if filepath.Clean(hdr.Name) == tarMember {
			found = true
			content, err = ioutil.ReadAll(tr)
			if err != nil {
				return err
			}
		}

		return nil
	})

	if !found {
		return nil, ErrMemberNotFound
	}

	if err != nil {
		return nil, err
	}

	return content, nil
}
Пример #2
0
func inspectPackage(filename string) (string, error) {
	f, err := os.Open(filename)
	if err != nil {
		return "", fmt.Errorf("error opening package file %s: %s", filename, err)
	}

	arReader := ar.NewReader(f)
	defer f.Close()
	var controlBuf bytes.Buffer

	for {
		header, err := arReader.Next()

		if err == io.EOF {
			break
		}

		if err != nil {
			return "", fmt.Errorf("error in inspectPackage loop: %s", err)
		}

		if header.Name == "control.tar.gz" {
			io.Copy(&controlBuf, arReader)
			return inspectPackageControl(controlBuf)
		}

	}
	return "", nil
}
Пример #3
0
// extract 'control' file from 'reader'. the contents of a 'control' file
// is a set of key-value pairs as described in
// https://www.debian.org/doc/debian-policy/ch-controlfields.html
func extractControlFromIpk(reader io.Reader) (string, error) {

	var (
		arReader  *ar.Reader
		tarReader *tar.Reader
		gzReader  *gzip.Reader
	)

	arReader = ar.NewReader(reader)
	for {
		header, err := arReader.Next()
		if err != nil && err != io.EOF {
			return "", fmt.Errorf("extracting contents: %v", err)
		} else if header == nil {
			break
		}

		// NOTE: strangeley the name of the files end with a "/" ... content error?
		if header.Name == "control.tar.gz/" || header.Name == "control.tar.gz" {
			gzReader, err = gzip.NewReader(arReader)
			if err != nil {
				return "", fmt.Errorf("analyzing control.tar.gz: %v", err)
			}
			break
		}
	}

	if gzReader == nil {
		return "", fmt.Errorf("missing control.tar.gz entry")
	}
	defer gzReader.Close()

	buffer := bytes.NewBuffer(nil)
	tarReader = tar.NewReader(gzReader)
	for {
		header, err := tarReader.Next()
		if err != nil && err != io.EOF {
			return "", fmt.Errorf("extracting control.tar.gz: %v", err)
		} else if header == nil {
			break
		}
		if header.Name != "./control" {
			continue
		}

		io.Copy(buffer, tarReader)
		break
	}

	if buffer.Len() == 0 {
		return "", fmt.Errorf("missing or empty 'control' file inside 'control.tar.gz'")
	}
	return buffer.String(), nil
}
Пример #4
0
func (t *AddDebTask) Run(b *BuildContext) error {
	in, err := t.Source.Open()
	if err != nil {
		return fmt.Errorf("error reading source deb (%s): %v", t.Source.Name(), err)
	}
	defer loggedClose(in, t.Source.Name())

	reader := ar.NewReader(in)

	foundData := false

	for {
		header, err := reader.Next()
		if err == io.EOF {
			break
		}

		if err != nil {
			return fmt.Errorf("error reading deb file (%s): %v", t.Source.Name(), err)
		}

		glog.Infof("ar entry: %s", header.Name)

		if header.Name == "data.tar.xz" || header.Name == "data.tar.xz/" {
			foundData = true
			xz := &XZByteSource{Inner: NewOnceByteSource(ioutil.NopCloser(reader), t.Source.Name())}
			tarTask := AddTarTask{Source: xz, DestPath: t.DestPath}
			err = tarTask.Run(b)
			if err != nil {
				return err
			}
		} else if header.Name == "data.tar.gz" || header.Name == "data.tar.gz/" {
			foundData = true
			src := &GZIPByteSource{Inner: NewOnceByteSource(ioutil.NopCloser(reader), t.Source.Name())}
			tarTask := AddTarTask{Source: src, DestPath: t.DestPath}
			err = tarTask.Run(b)
			if err != nil {
				return err
			}
		} else {
			_, err = io.Copy(ioutil.Discard, reader)
			if err != nil {
				return fmt.Errorf("error reading deb file entry (%s): %v", t.Source.Name(), err)
			}
		}
	}

	if !foundData {
		return fmt.Errorf("unable to find data segment in %s", t.Source.Name())
	}

	return nil
}
Пример #5
0
// UnpackAll unpacks the data.tar.{gz,bz2,xz} into the given target directory
// with click specific verification, i.e. no files will be extracted outside
// of the targetdir (no ".." inside the data.tar is allowed)
func (d *ClickDeb) UnpackAll(targetDir string) error {
	if _, err := d.file.Seek(0, 0); err != nil {
		return err
	}

	arReader := ar.NewReader(d.file)
	dataReader, err := skipToArMember(arReader, "data.tar")
	if err != nil {
		return err
	}

	// and unpack
	return helpers.UnpackTar(dataReader, targetDir, clickVerifyContentFn)
}
Пример #6
0
func readDebControlFile(reader io.Reader) (string, error) {
	archiveReader := ar.NewReader(reader)

	for {
		header, err := archiveReader.Next()

		if err == io.EOF {
			break
		}
		if err != nil {
			panic(err)
		}

		if strings.HasPrefix(header.Name, "control.tar") {
			var controlReader *tar.Reader

			if strings.HasSuffix(header.Name, "gz") {
				gzipStream, err := gzip.NewReader(archiveReader)
				if err != nil {
					panic(err)
				}
				controlReader = tar.NewReader(gzipStream)
			} else {
				return "", errors.New("Compression type not supported")
			}

			for {
				header, err := controlReader.Next()

				if err == io.EOF {
					break
				}
				if err != nil {
					panic(err)
				}

				if strings.HasSuffix(header.Name, "control") {
					var buffer bytes.Buffer
					_, err := io.Copy(bufio.NewWriter(&buffer), controlReader)
					if err != nil {
						panic(err)
					}
					return buffer.String(), nil
				}
			}
		}
	}

	return "", errors.New("Couldn't find control file in package")
}