soar_core/package/formats/
mod.rs1use std::io::{BufReader, Read, Seek, SeekFrom};
2
3use crate::{
4 constants::{
5 APPIMAGE_MAGIC_BYTES, ELF_MAGIC_BYTES, FLATIMAGE_MAGIC_BYTES, RUNIMAGE_MAGIC_BYTES,
6 WRAPPE_MAGIC_BYTES,
7 },
8 error::SoarError,
9 SoarResult,
10};
11
12pub mod appimage;
13pub mod common;
14pub mod wrappe;
15
16#[derive(Debug, PartialEq, Eq)]
17pub enum PackageFormat {
18 AppImage,
19 FlatImage,
20 RunImage,
21 Wrappe,
22 ELF,
23 Unknown,
24}
25
26pub fn get_file_type<T>(file: &mut BufReader<T>) -> SoarResult<PackageFormat>
27where
28 T: Read + Seek,
29{
30 let mut magic_bytes = [0u8; 12];
31 file.read_exact(&mut magic_bytes)
32 .map_err(|_| SoarError::Custom("Error reading magic bytes".into()))?;
33
34 if magic_bytes[8..] == APPIMAGE_MAGIC_BYTES {
35 return Ok(PackageFormat::AppImage);
36 }
37 if magic_bytes[8..] == FLATIMAGE_MAGIC_BYTES {
38 return Ok(PackageFormat::FlatImage);
39 }
40 if magic_bytes[8..] == RUNIMAGE_MAGIC_BYTES {
41 return Ok(PackageFormat::RunImage);
42 }
43
44 let start = file
45 .seek(SeekFrom::End(0))
46 .map_err(|_| SoarError::Custom("Error seeking to end of file".into()))?
47 .wrapping_sub(801);
48 file.rewind()
49 .map_err(|_| SoarError::Custom("Error rewinding file".into()))?;
50
51 if file.seek(SeekFrom::Start(start)).is_ok() {
52 let mut magic_bytes = [0u8; 8];
53 file.read_exact(&mut magic_bytes)
54 .map_err(|_| SoarError::Custom("Error reading magic bytes".into()))?;
55 file.rewind()
56 .map_err(|_| SoarError::Custom("Error rewinding file".into()))?;
57 if magic_bytes[0..8] == WRAPPE_MAGIC_BYTES {
58 return Ok(PackageFormat::Wrappe);
59 }
60 }
61
62 if magic_bytes[..4] == ELF_MAGIC_BYTES {
63 return Ok(PackageFormat::ELF);
64 }
65
66 Ok(PackageFormat::Unknown)
67}