// Fetch updates information about repository func (repo *RemoteRepo) Fetch(d utils.Downloader) error { // Download release file to temporary URL release, err := utils.DownloadTemp(d, repo.ReleaseURL().String()) if err != nil { return err } defer release.Close() paras, err := debc.Parse(release) if err != nil { return err } if len(paras) != 1 { return fmt.Errorf("wrong number of parts in Release file") } para := paras[0] architectures := strings.Split(para["Architectures"], " ") if len(repo.Architectures) == 0 { repo.Architectures = architectures } else { err = utils.StringsIsSubset(repo.Architectures, architectures, fmt.Sprintf("architecture %%s not available in repo %s", repo)) if err != nil { return err } } components := strings.Split(para["Components"], " ") if len(repo.Components) == 0 { repo.Components = components } else { err = utils.StringsIsSubset(repo.Components, components, fmt.Sprintf("component %%s not available in repo %s", repo)) if err != nil { return err } } delete(para, "MD5Sum") delete(para, "SHA1") delete(para, "SHA256") repo.Meta = para return nil }
// Fetch updates information about repository func (repo *RemoteRepo) Fetch(d utils.Downloader, verifier utils.Verifier) error { var ( release *os.File err error ) if verifier == nil { // 0. Just download release file to temporary URL release, err = utils.DownloadTemp(d, repo.ReleaseURL("Release").String()) if err != nil { return err } } else { // 1. try InRelease file inrelease, err := utils.DownloadTemp(d, repo.ReleaseURL("InRelease").String()) if err != nil { goto splitsignature } defer inrelease.Close() release, err = verifier.VerifyClearsigned(inrelease) if err != nil { goto splitsignature } goto ok splitsignature: // 2. try Release + Release.gpg release, err = utils.DownloadTemp(d, repo.ReleaseURL("Release").String()) if err != nil { return err } releasesig, err := utils.DownloadTemp(d, repo.ReleaseURL("Release.gpg").String()) if err != nil { return err } err = verifier.VerifyDetachedSignature(releasesig, release) if err != nil { return err } _, err = release.Seek(0, 0) if err != nil { return err } } ok: defer release.Close() sreader := NewControlFileReader(release) stanza, err := sreader.ReadStanza() if err != nil { return err } if !repo.IsFlat() { architectures := strings.Split(stanza["Architectures"], " ") if len(repo.Architectures) == 0 { repo.Architectures = architectures } else { err = utils.StringsIsSubset(repo.Architectures, architectures, fmt.Sprintf("architecture %%s not available in repo %s", repo)) if err != nil { return err } } components := strings.Split(stanza["Components"], " ") if len(repo.Components) == 0 { repo.Components = components } else { err = utils.StringsIsSubset(repo.Components, components, fmt.Sprintf("component %%s not available in repo %s", repo)) if err != nil { return err } } } repo.ReleaseFiles = make(map[string]utils.ChecksumInfo) parseSums := func(field string, setter func(sum *utils.ChecksumInfo, data string)) error { for _, line := range strings.Split(stanza[field], "\n") { line = strings.TrimSpace(line) if line == "" { continue } parts := strings.Fields(line) if len(parts) != 3 { return fmt.Errorf("unparseable hash sum line: %#v", line) } size, err := strconv.ParseInt(parts[1], 10, 64) if err != nil { return fmt.Errorf("unable to parse size: %s", err) } sum := repo.ReleaseFiles[parts[2]] sum.Size = size setter(&sum, parts[0]) repo.ReleaseFiles[parts[2]] = sum } delete(stanza, field) return nil } err = parseSums("MD5Sum", func(sum *utils.ChecksumInfo, data string) { sum.MD5 = data }) if err != nil { return err } err = parseSums("SHA1", func(sum *utils.ChecksumInfo, data string) { sum.SHA1 = data }) if err != nil { return err } err = parseSums("SHA256", func(sum *utils.ChecksumInfo, data string) { sum.SHA256 = data }) if err != nil { return err } repo.Meta = stanza return nil }