diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 79083a0..94a25f7 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -2,8 +2,5 @@
-
-
-
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
index 5d2f1b6..0d8dcc3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -44,12 +44,52 @@ dependencies = [
"rustc-demangle",
]
+[[package]]
+name = "block-buffer"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
+dependencies = [
+ "block-padding",
+ "generic-array",
+]
+
+[[package]]
+name = "block-padding"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
+
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+[[package]]
+name = "cpuid-bool"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
+
+[[package]]
+name = "crc32fast"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "digest"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+dependencies = [
+ "generic-array",
+]
+
[[package]]
name = "failure"
version = "0.1.8"
@@ -72,12 +112,40 @@ dependencies = [
"synstructure",
]
+[[package]]
+name = "flate2"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0"
+dependencies = [
+ "cfg-if",
+ "crc32fast",
+ "libc",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
[[package]]
name = "gimli"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
+[[package]]
+name = "keccak"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7"
+
[[package]]
name = "libc"
version = "0.2.90"
@@ -90,7 +158,10 @@ version = "0.0.2-placeholder"
dependencies = [
"failure",
"maplit",
+ "object",
"regex",
+ "sha2",
+ "sha3",
]
[[package]]
@@ -120,6 +191,16 @@ name = "object"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4"
+dependencies = [
+ "flate2",
+ "wasmparser",
+]
+
+[[package]]
+name = "opaque-debug"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "pkg6depotd"
@@ -174,6 +255,31 @@ version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232"
+[[package]]
+name = "sha2"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa827a14b29ab7f44778d14a88d3cb76e949c45083f7dbfa507d0cb699dc12de"
+dependencies = [
+ "block-buffer",
+ "cfg-if",
+ "cpuid-bool",
+ "digest",
+ "opaque-debug",
+]
+
+[[package]]
+name = "sha3"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809"
+dependencies = [
+ "block-buffer",
+ "digest",
+ "keccak",
+ "opaque-debug",
+]
+
[[package]]
name = "syn"
version = "1.0.64"
@@ -197,8 +303,26 @@ dependencies = [
"unicode-xid",
]
+[[package]]
+name = "typenum"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
+
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
+
+[[package]]
+name = "version_check"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
+
+[[package]]
+name = "wasmparser"
+version = "0.57.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32fddd575d477c6e9702484139cf9f23dcd554b06d185ed0f56c857dd3a47aa6"
diff --git a/libips/Cargo.toml b/libips/Cargo.toml
index 06d4314..6d64750 100644
--- a/libips/Cargo.toml
+++ b/libips/Cargo.toml
@@ -18,4 +18,7 @@ keywords = ["packaging", "illumos"]
[dependencies]
regex = "1.3.7"
failure = "0.1.8"
-maplit = "0.1.6"
\ No newline at end of file
+maplit = "0.1.6"
+object = "0.23.0"
+sha2 = "0.9.3"
+sha3 = "0.9.1"
\ No newline at end of file
diff --git a/libips/src/actions/mod.rs b/libips/src/actions/mod.rs
index f867530..fc78623 100644
--- a/libips/src/actions/mod.rs
+++ b/libips/src/actions/mod.rs
@@ -15,8 +15,9 @@ use crate::payload::Payload;
use std::clone::Clone;
use crate::digest::Digest;
use std::str::FromStr;
+use std::path::{Path, PathBuf};
-trait FacetedAction {
+pub trait FacetedAction {
// Add a facet to the action if the facet is already present the function returns false.
fn add_facet(&mut self, facet: Facet) -> bool;
@@ -33,7 +34,7 @@ pub struct Action {
}
impl Action {
- fn new(kind: ActionKind) -> Action{
+ pub fn new(kind: ActionKind) -> Action{
Action{
kind,
payload: Payload::default(),
@@ -90,6 +91,21 @@ pub struct File {
pub facets: HashSet,
}
+impl File {
+ pub fn read_from_path(p: &Path) -> Result {
+ let mut f = File::default();
+ f.payload = Payload::compute_payload(p)?;
+ match p.to_str() {
+ Some(str) => f.path = str.to_string(),
+ None => return Err(FileError::FilePathIsNoStringError)?,
+ }
+
+ //TODO group owner mode
+
+ Ok(f)
+ }
+}
+
impl FacetedAction for File {
fn add_facet(&mut self, facet: Facet) -> bool {
return self.facets.insert(facet)
@@ -100,6 +116,12 @@ impl FacetedAction for File {
}
}
+#[derive(Debug, Fail)]
+pub enum FileError {
+ #[fail(display = "file path is not a string")]
+ FilePathIsNoStringError,
+}
+
//TODO implement multiple FMRI for require-any
#[derive(Debug, Default)]
pub struct Dependency {
@@ -157,10 +179,14 @@ impl Manifest {
dependencies: Vec::new(),
};
}
+
+ pub fn add_file(&mut self, f: File) {
+ self.files.push(f);
+ }
}
#[derive(Debug)]
-enum ActionKind {
+pub enum ActionKind {
Attr,
Dir,
File,
diff --git a/libips/src/digest/mod.rs b/libips/src/digest/mod.rs
index bcd7ad7..92b3327 100644
--- a/libips/src/digest/mod.rs
+++ b/libips/src/digest/mod.rs
@@ -4,6 +4,10 @@
// obtain one at https://mozilla.org/MPL/2.0/.
use std::str::FromStr;
+use sha2::{Digest as Sha2Digest};
+use sha3::{Digest as Sha3Digest};
+
+static DEFAULT_ALGORITHM: DigestAlgorithm = DigestAlgorithm::SHA512;
#[derive(Debug, PartialEq)]
pub enum DigestAlgorithm {
@@ -85,6 +89,35 @@ impl FromStr for Digest {
}
}
+impl Digest {
+ pub fn from_bytes(b: &[u8], algo: DigestAlgorithm, src: DigestSource) -> Result {
+ let hash = match algo {
+ DigestAlgorithm::SHA256=> {
+ format!("{:x}", sha2::Sha256::digest(b))
+ }
+ DigestAlgorithm::SHA512Half => {
+ format!("{:x}", sha2::Sha512Trunc256::digest(b))
+ }
+ DigestAlgorithm::SHA512 => {
+ format!("{:x}", sha2::Sha512::digest(b))
+ }
+ DigestAlgorithm::SHA3512Half | DigestAlgorithm::SHA3256 => {
+ format!("{:x}", sha3::Sha3_256::digest(b))
+ }
+ DigestAlgorithm::SHA3512 | _ => {
+ format!("{:x}", sha3::Sha3_512::digest(b))
+ }
+ };
+
+
+ Ok(Digest{
+ source: src,
+ algorithm: algo,
+ hash,
+ })
+ }
+}
+
#[derive(Debug, Fail)]
pub enum DigestError {
#[fail(display = "hashing algorithm {} is not known by this library", algorithm)]
diff --git a/libips/src/lib.rs b/libips/src/lib.rs
index eeef24a..e5ec93e 100644
--- a/libips/src/lib.rs
+++ b/libips/src/lib.rs
@@ -3,9 +3,9 @@
// MPL was not distributed with this file, You can
// obtain one at https://mozilla.org/MPL/2.0/.
-mod actions;
-mod digest;
-mod payload;
+pub mod actions;
+pub mod digest;
+pub mod payload;
#[macro_use] extern crate failure;
#[macro_use] extern crate maplit;
diff --git a/libips/src/payload/mod.rs b/libips/src/payload/mod.rs
index b150e2d..77ab258 100644
--- a/libips/src/payload/mod.rs
+++ b/libips/src/payload/mod.rs
@@ -3,19 +3,22 @@
// MPL was not distributed with this file, You can
// obtain one at https://mozilla.org/MPL/2.0/.
-use crate::digest::Digest;
+use crate::digest::{Digest, DigestAlgorithm, DigestSource};
+use failure::Error;
+use object::Object;
+use std::path::Path;
-#[derive(Debug)]
+#[derive(Debug, PartialEq)]
pub enum PayloadCompressionAlgorithm {
Gzip,
LZ4
}
impl Default for PayloadCompressionAlgorithm {
- fn default() -> Self { PayloadCompressionAlgorithm::Gzip }
+ fn default() -> Self { PayloadCompressionAlgorithm::LZ4 }
}
-#[derive(Debug)]
+#[derive(Debug, PartialEq)]
pub enum PayloadBits {
Independent,
Bits32,
@@ -26,7 +29,7 @@ impl Default for PayloadBits {
fn default() -> Self { PayloadBits::Independent }
}
-#[derive(Debug)]
+#[derive(Debug, PartialEq)]
pub enum PayloadArchitecture {
NOARCH,
I386,
@@ -46,4 +49,45 @@ pub struct Payload {
pub compression_algorithm: PayloadCompressionAlgorithm,
pub bitness: PayloadBits,
pub architecture: PayloadArchitecture,
+}
+
+impl Payload {
+ pub fn is_elf(&self) -> bool {
+ self.architecture == PayloadArchitecture::NOARCH && self.bitness == PayloadBits::Independent
+ }
+
+ pub fn compute_payload(path: &Path) -> Result {
+ let f = std::fs::read(path)?;
+
+ let (bitness, architecture) = match object::File::parse(f.as_slice()) {
+ Ok(bin) => {
+ let bitness = if bin.is_64() {
+ PayloadBits::Bits64
+ } else {
+ PayloadBits::Bits32
+ };
+
+ let architecture = match bin.architecture() {
+ object::Architecture::X86_64 | object::Architecture::I386 => {
+ PayloadArchitecture::I386
+ }
+ object::Architecture::Aarch64 | object::Architecture::Arm => {
+ PayloadArchitecture::ARM
+ }
+ _ => PayloadArchitecture::NOARCH,
+ };
+
+ (bitness, architecture)
+ }
+ Err(_) => (PayloadBits::Independent, PayloadArchitecture::NOARCH),
+ };
+
+ Ok(Payload{
+ primary_identifier:Digest::from_bytes(f.as_slice(), DigestAlgorithm::SHA3512, DigestSource::PrimaryPayloadHash)?,
+ additional_identifiers: Vec::::new(),
+ compression_algorithm: PayloadCompressionAlgorithm::default(),
+ bitness,
+ architecture
+ })
+ }
}
\ No newline at end of file