use std::str::FromStr; use std::io::{Read,BufRead,BufReader}; use postgres; use crate::archive; use crate::open; use crate::pkg; // https://git.alpinelinux.org/apk-tools/tree/doc/apk-repositories.5.scd // https://git.alpinelinux.org/apk-tools/tree/src/package.c#n874 (apk_pkg_write_index_entry) pub fn read_index(pg: &mut T, sys: i32, mirror: &str, repo: &str, lst: R) { let rd = BufReader::new(lst); let mut name = None; let mut version = None; let mut builddate = None; let mut arch = None; let mut lineno: u32 = 0; for line in rd.lines() { lineno += 1; let line = match line { Err(e) => { error!("Can't read package index: {}", e); return }, Ok(x) => x, }; if line.starts_with("P:") { name = Some(line[2..].to_string()); } else if line.starts_with("V:") { version = Some(line[2..].to_string()); } else if line.starts_with("t:") { builddate = i64::from_str(&line[2..]).ok(); } else if line.starts_with("A:") { arch = Some(line[2..].to_string()); } if line != "" { continue; } if name.is_none() || version.is_none() { warn!("Package without name or version on line {}", lineno); return; } let pname = name.as_ref().unwrap(); let pver = version.as_ref().unwrap(); if pname == "man-pages" || pname.ends_with("-doc") { let p = format!("{}/{}/x86_64/{}-{}.apk", mirror, repo, pname, pver); pkg::pkg(pg, pkg::PkgOpt{ force: false, sys: sys, pkg: pname, ver: pver, date: builddate.map(pkg::Date::Found).unwrap_or(pkg::Date::Max), arch: arch.as_deref(), file: open::Path{ path: &p, cache: false, canbelocal: false, }, }); } name = None; version = None; builddate = None; arch = None; } } pub fn sync(pg: &mut T, sys: i32, mirror: &str, repo: &str) { info!("Reading packages from {} {}", mirror, repo); let path = format!("{}/{}/x86_64/APKINDEX.tar.gz", mirror, repo); let path = open::Path{ path: &path, cache: true, canbelocal: false }; let mut index = match path.open() { Err(e) => { error!("Can't read package index: {}", e); return }, Ok(x) => x, }; let ent = match archive::Archive::open_archive(&mut index) { Err(e) => { error!("Can't read package index: {}", e); return }, Ok(x) => x, }; let r = archive::walk(ent, |x| { if x.path() == Some("APKINDEX") { read_index(pg, sys, mirror, repo, x); } Ok(true) }); if let Err(e) = r { error!("Error reading package index: {}", e); } }