From 73398099636eb658c306d7cd4ff020bae59bf377 Mon Sep 17 00:00:00 2001 From: neo_1993 Date: Sat, 1 Aug 2026 23:12:59 +0200 Subject: [PATCH] binpkg and constants libportage modules --- Cargo.lock | 45 +++++++ Cargo.toml | 7 ++ libportage/binpkg.rs | 50 ++++++++ libportage/consts.rs | 273 +++++++++++++++++++++++++++++++++++++++++++ libportage/lib.rs | 6 + libportage/types.rs | 17 +++ 6 files changed, 398 insertions(+) create mode 100644 libportage/binpkg.rs create mode 100644 libportage/consts.rs create mode 100644 libportage/types.rs diff --git a/Cargo.lock b/Cargo.lock index 74240ae..696b338 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + [[package]] name = "anstream" version = "1.0.0" @@ -116,6 +125,12 @@ version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + [[package]] name = "once_cell_polyfill" version = "1.70.2" @@ -140,12 +155,42 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "regex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + [[package]] name = "ruport" version = "0.1.0" dependencies = [ "clap", "log", + "regex", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 3a4692b..db0eecd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -100,6 +100,13 @@ required-features = ["drop-in"] [dependencies] clap = { version="4.6", features=["derive"] } log = "0.4.33" +regex = { version="1.13" } + +[profile.dev] +opt-level = "s" +debug = true +strip = false +lto = false [profile.release] opt-level = "z" diff --git a/libportage/binpkg.rs b/libportage/binpkg.rs new file mode 100644 index 0000000..ad831bd --- /dev/null +++ b/libportage/binpkg.rs @@ -0,0 +1,50 @@ +use std::fs::File; +use std::io::{Result,BufReader,Read,Seek,SeekFrom}; +use std::os::unix::ffi::OsStrExt; +use std::path::PathBuf; +use log::warn; + +use crate::consts::GentooBinpkgFormats; + +fn get_binpkg_format(binpkg: PathBuf, check_file: Option, remote: Option) -> Option { + let check_file = check_file.unwrap_or(false); + let remote = remote.unwrap_or(false); + + let extension = &binpkg.extension().ok_or(0).unwrap(); + let extension = extension.to_str().unwrap(); + let file_ext_format = if GentooBinpkgFormats::XPAK.get_extension().unwrap().contains(&extension) { + Some(GentooBinpkgFormats::XPAK) + } else if GentooBinpkgFormats::GPKG.get_extension().unwrap().contains(&extension) { + Some(GentooBinpkgFormats::GPKG) + } else { + None + }; + + let mut file_format: Option = if file_ext_format.is_some() && !check_file { + file_ext_format + } else { + let binpkg_file = File::open(&binpkg).expect(format!("unable to open binary file {}", &binpkg.display()).as_str()); + let mut reader = BufReader::new(binpkg_file); + let mut buf = [0;100]; + + let _ = reader.read(&mut buf).expect(format!("cannot read file: {}", &binpkg.display()).as_str()); + if buf.starts_with(b"/gpkg-1\x00") { + Some(GentooBinpkgFormats::GPKG) + } else { + reader.seek(SeekFrom::End(-16)); + let mut tail = [0;16]; + reader.read_exact(&mut tail); + if tail[0..8].starts_with(b"XPAKSTOP") && tail[12..16].ends_with(b"STOP") { + Some(GentooBinpkgFormats::XPAK) + } else { + None + } + } + }; + + if file_format.is_some() && file_ext_format.unwrap() != file_format.unwrap() { + warn!("File {} binpkg format mismatch, actial format: {}", binpkg.display(), file_format.unwrap()); + } + + return file_format; +} \ No newline at end of file diff --git a/libportage/consts.rs b/libportage/consts.rs new file mode 100644 index 0000000..eaaf28e --- /dev/null +++ b/libportage/consts.rs @@ -0,0 +1,273 @@ +use std::ffi::OsStr; +use std::path::PathBuf; +use std::sync::LazyLock; +use std::io::Result; + +use crate::types::Atom; + +/** + * There are two types of variables here whcih can easily be confused, + * resulting in arbitrary bugs, mainly exposed with an offset + * installation (Prefix). The two types relate to the useage of + * config_root or target_root. + * The first, config_root (PORTAGE_CONFIGROOT), can be a path somewhere, + * from which all derived paths need to be relative (e.g. USER_CONFIG_PATH) + * without EPREFIX prepended in Prefix. This means + * config_root cann for instance be set to "$HOME/my/config". Obviously, + * in such case it is not appropriate to prepend EPREFIX to derived + * constants. The default value of config_root is EPREFIX (in non-Prefix + * the empty String) -- overriding the value loses the EPREFXXI as one + * would expect. + * Second here is target_root (ROOT) which is used to install somewhere + * completely else, in Prefix of limited use. Because this is an offset + * always given, the EPREFIX should always be applied in it, hence the + * code always prefixes them with ERROT. + * The variables in this file are grouped by config_root, target_root. + */ + +// variables used with config_root (these need to be relative) +static USER_CONFIG_PATH: LazyLock = + LazyLock::new(|| PathBuf::from("etc/portage")); +static BINREPOS_CONF_FILE: LazyLock = + LazyLock::new(|| USER_CONFIG_PATH.join("binrepos.conf")); +static MAKE_CONF_FILE: LazyLock = + LazyLock::new(|| USER_CONFIG_PATH.join("make.conf")); +static MODULES_FILE_PATH: LazyLock = + LazyLock::new(|| USER_CONFIG_PATH.join("modules")); +static CUSTOM_PROFILE_PATH: LazyLock = + LazyLock::new(|| USER_CONFIG_PATH.join("profile")); +static USER_VIRTUAL_FILE: LazyLock = + LazyLock::new(|| USER_CONFIG_PATH.join("virtuals")); +static EBUILD_SH_ENV_FILE: LazyLock = + LazyLock::new(|| USER_CONFIG_PATH.join("bashrc")); +static EBUILD_SH_ENV_DIR: LazyLock = + LazyLock::new(|| USER_CONFIG_PATH.join("env")); +static CUSTOM_MIRRORS_FILE: LazyLock = + LazyLock::new(|| USER_CONFIG_PATH.join("mirrors")); +static COLOR_MAP_FILE: LazyLock = + LazyLock::new(|| USER_CONFIG_PATH.join("color.map")); +static PROFILE_PATH: LazyLock = + LazyLock::new(|| USER_CONFIG_PATH.join("make.profile")); +static MAKE_DEFAULTS_FILE: LazyLock = + LazyLock::new(|| PROFILE_PATH.join("make.defaults")); +static DEPRECATED_PROFILE_FILE: LazyLock = + LazyLock::new(|| PROFILE_PATH.join("deprecated")); + +// variables used with targetroot (these need to be absolute, but not +// have a leading '/' since they are used directly with path.join on EROOT) +static VDB_PATH: LazyLock = + LazyLock::new(|| PathBuf::from("var/db/pkg")); +static CACHE_PATH: LazyLock = + LazyLock::new(|| PathBuf::from("var/cache/edb")); +static PRIVATE_PATH: LazyLock = + LazyLock::new(|| PathBuf::from("var/lib/portage")); +static WORLD_FILE: LazyLock = + LazyLock::new(|| PRIVATE_PATH.join("world")); +static WORLD_SETS_FILE: LazyLock = + LazyLock::new(|| PRIVATE_PATH.join("world_sets")); +static CONFIG_MEMORY_FILE: LazyLock = + LazyLock::new(|| PRIVATE_PATH.join("config")); +static REPO_REVISIONS: LazyLock = + LazyLock::new(|| PRIVATE_PATH.join("repo_revisions")); +static NEWS_LIB_PATH: LazyLock = + LazyLock::new(|| PathBuf::from("var/lib/gentoo")); + +/* these variables get EPREFIX prepended automagically when they are + * translated into their lowercase variants */ +static DEPCACHE_PATH: LazyLock = + LazyLock::new(|| CACHE_PATH.join("dep")); + +static PORTAGE_PACKAGE_ATOM: LazyLock = LazyLock::new(|| Atom::new("sys-apps/portage")); +static LIBC_PACKAGE_ATOM: LazyLock = LazyLock::new(|| Atom::new("virtual/libc")); +static OS_HEADERS_PACKAGE_ATOM: LazyLock = LazyLock::new(|| Atom::new("virtual/os-headers")); +static CVS_PACKAGE_ATOM: LazyLock = LazyLock::new(|| Atom::new("dev-vcs/cvs")); +static GIT_PACKAGE_ATOM: LazyLock = LazyLock::new(|| Atom::new("dev-vcs/git")); +static HG_PACKAGE_ATOM: LazyLock = LazyLock::new(|| Atom::new("dev-vcs/mercurial")); +static RSYNC_PACKAGE_ATOM: LazyLock = LazyLock::new(|| Atom::new("net-misc/rsync")); + +const INCREMENTALS: &'static [&'static str] = &[ + "ACCEPT_KEYWORDS", + "CONFIG_PROTECT", + "CONFIG_PROTECT_MASK", + "ENV_UNSET", + "FEATURES", + "IUSE_IMPLICIT", + "PRELINK_PATH", + "PRELINK_PATH_MASK", + "PROFILE_ONLY_VARIABLES", + "USE", + "USE_EXPAND", + "USE_EXPAND_HIDDEN", + "USE_EXPAND_IMPLICIT", + "USE_EXPAND_UNPREFIXED", +]; + +const SUPPORTED_FEATURES: &'static [&'static str] = &[ + "assume-digest", + "binpkg-docompress", + "binpkg-dostrip", + "binpkg-ignore-signature", + "binpkg-logs", + "binpkg-multi-instance", + "binpkg-request-signature", + "binpkg-signing", + "buildpkg", + "buildpkg-live", + "buildpkg-proactive", + "buildsyspkg", + "candy", + "case-insensitive-fs", + "ccache", + "chflags", + "clean-logs", + "collision-protect", + "compress-build-logs", + "compressdebug", + "compress-index", + "config-protect-if-modified", + "dedupdebug", + "digest", + "distcc", + "distlocks", + "downgrade-backup", + "ebuild-locks", + "fail-clean", + "fakeroot", + "fixlafiles", + "force-mirror", + "getbinpkg", + "gpg-keepalive", + "home-dir-template-copy", + "icecream", + "installsources", + "ipc-sandbox", + "jobserver-token", + "keeptemp", + "keepwork", + "lmirror", + "merge-sync", + "merge-wait", + "metadata-transfer", + "mirror", + "mount-sandbox", + "multilib-strict", + "network-sandbox", + "network-sandbox-proxy", + "news", + "noauto", + "noclean", + "nodoc", + "noinfo", + "noman", + "nostrip", + "notitles", + "packdebug", + "parallel-fetch", + "parallel-install", + "pid-sandbox", + "pkgdir-index-trusted", + "prelink-checksums", + "preserve-libs", + "protect-owned", + "python-trace", + "qa-unresolved-soname-deps", + "sandbox", + "selinux", + "sesandbox", + "sfperms", + "sign", + "skiprocheck", + "splitdebug", + "split-elog", + "split-log", + "strict", + "strict-keepdir", + "stricter", + "suidctl", + "test", + "test-fail-continue", + "unknown-features-filter", + "unknown-features-warn", + "unmerge-backup", + "unmerge-logs", + "unmerge-orphans", + "unprivileged", + "userfetch", + "userpriv", + "usersandbox", + "usersync", + "warn-on-large-env", + "webrsync-gpg", + "xattr", +]; + + +const EAPI: usize = 9; + +const HASHING_BLOCKSIZE: usize = 32768; + +#[derive(Default)] +enum Manifest2HashDefaults { + #[default] + Blake2B, + SHA512, +} + +const VCS_DIRS: &'static [&'static str] = &[ + "CVS", + "RCS", + "SCCS", + ".bzr", + ".git", + ".hg", + ".svn" +]; + +const LIVE_ECLASS: &'static [&'static str] = &[ + "bzr", + "cvs", + "darcs", + "git-2", + "git-r3", + "golang-vcs", + "mercurial", + "subversion", +]; + +enum BinpkgFormats { + Tar, + Rpm, +} +#[derive(Debug,Clone,Copy,Eq,PartialEq)] +pub(crate) enum GentooBinpkgFormats { + XPAK, + GPKG, +} +impl GentooBinpkgFormats { + pub fn to_str(self) -> &'static str { + match self { + Self::XPAK => "xpak", + Self::GPKG => "gpkg", + } + } + pub fn get_extension(&self) -> Result> { + match self { + Self::XPAK => return Ok(vec![".tbz2", ".xpak"]), + Self::GPKG => return Ok(vec![".gpkg.tar"]), + } + } + pub fn contains(&self, pat: &str) -> bool { + let extensions= self.get_extension().unwrap(); + + if extensions.contains(&pat) { + true + } else { + false + } + } +} +impl std::fmt::Display for GentooBinpkgFormats { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.to_str()) + } +} diff --git a/libportage/lib.rs b/libportage/lib.rs index 73cfcea..6491e69 100644 --- a/libportage/lib.rs +++ b/libportage/lib.rs @@ -1,6 +1,12 @@ +#![allow(unused)] use std::{env, path::{Path,PathBuf}}; use std::io::Result; +mod binpkg; +mod consts; + +mod types; + fn getwcd() -> Result { let cwd = match env::current_dir() { Ok(p) => p, diff --git a/libportage/types.rs b/libportage/types.rs new file mode 100644 index 0000000..74ec639 --- /dev/null +++ b/libportage/types.rs @@ -0,0 +1,17 @@ + + +pub(crate) struct Atom { + category: String, + packet: String +} + +impl Atom { + pub fn new(atom: &str) -> Self { + let parts: Vec<&str> = atom.split('/').collect(); + + Self { + category: String::from(parts[0]), + packet: String::from(parts[1]), + } + } +} \ No newline at end of file