soar_core/package/formats/
mod.rs

1use 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}