unarj_rs/
main_header.rs

1use crate::date_time::DosDateTime;
2
3#[repr(u8)]
4#[derive(Debug, PartialEq, Clone, Copy)]
5pub enum HostOS {
6    MsDos = 0,
7    PrimOS = 1,
8    Unix = 2,
9    Amiga = 3,
10    MacOs = 4,
11    OS2 = 5,
12    AppleGS = 6,
13    AtariST = 7,
14    NeXT = 8,
15    VaxVMS = 9,
16    Win95 = 10,
17    Win32 = 11,
18
19    Unknown(u8),
20}
21
22impl From<u8> for HostOS {
23    fn from(value: u8) -> Self {
24        match value {
25            0 => HostOS::MsDos,
26            1 => HostOS::PrimOS,
27            2 => HostOS::Unix,
28            3 => HostOS::Amiga,
29            4 => HostOS::MacOs,
30            5 => HostOS::OS2,
31            6 => HostOS::AppleGS,
32            7 => HostOS::AtariST,
33            8 => HostOS::NeXT,
34            9 => HostOS::VaxVMS,
35            10 => HostOS::Win95,
36            11 => HostOS::Win32,
37            _ => HostOS::Unknown(value),
38        }
39    }
40}
41
42pub struct MainHeader {
43    pub archiver_version_number: u8,
44    pub min_version_to_extract: u8,
45    pub host_os: HostOS,
46    pub flags: u8,
47    pub security_version: u8,
48    pub file_type: u8,
49
50    pub creation_date_time: DosDateTime,
51    pub compr_size: u32,
52    pub archive_size: u32,
53    /// file position
54    pub security_envelope: u32,
55    pub file_spec_position: u16,
56    pub security_envelope_length: u16,
57    pub encryption_version: u8,
58    pub last_chapter: u8,
59    pub arj_protection_factor: u8,
60    pub flags2: u8,
61    pub name: String,
62    pub comment: String,
63}
64const FIRST_HDR_SIZE: u8 = 34;
65impl MainHeader {
66    pub fn load_from(mut header_bytes: &[u8]) -> Self {
67        convert_u8!(header_size, header_bytes);
68        convert_u8!(archiver_version_number, header_bytes);
69        convert_u8!(min_version_to_extract, header_bytes);
70        convert_u8!(host_os, header_bytes);
71        convert_u8!(flags, header_bytes);
72        convert_u8!(security_version, header_bytes);
73        convert_u8!(file_type, header_bytes);
74        skip!(header_bytes, 1);
75        convert_u32!(creation_date_time, header_bytes);
76        convert_u32!(compr_size, header_bytes);
77        convert_u32!(archive_size, header_bytes);
78        convert_u32!(security_envelope, header_bytes);
79        convert_u16!(file_spec_position, header_bytes);
80        convert_u16!(security_envelope_length, header_bytes);
81
82        convert_u8!(encryption_version, header_bytes);
83        convert_u8!(last_chapter, header_bytes);
84
85        let mut arj_protection_factor = 0;
86        let mut flags2 = 0;
87
88        if header_size >= FIRST_HDR_SIZE {
89            convert_u8!(arj_protection_factor2, header_bytes);
90            convert_u8!(arj_flags22, header_bytes);
91            arj_protection_factor = arj_protection_factor2;
92            flags2 = arj_flags22;
93            skip!(header_bytes, 2);
94        }
95
96        convert_string!(name, header_bytes);
97        convert_string!(comment, header_bytes);
98        Self {
99            archiver_version_number,
100            min_version_to_extract,
101            host_os: host_os.into(),
102            flags,
103            security_version,
104            file_type,
105            creation_date_time: DosDateTime::new(creation_date_time),
106            compr_size,
107            archive_size,
108            security_envelope,
109            file_spec_position,
110            security_envelope_length,
111            encryption_version,
112            last_chapter,
113            arj_protection_factor,
114            flags2,
115            name,
116            comment,
117        }
118    }
119
120    pub fn is_gabled(&self) -> bool {
121        self.flags & 0x01 != 0
122    }
123
124    pub fn is_ansi_page(&self) -> bool {
125        self.flags & 0x02 != 0
126    }
127
128    pub fn is_volume(&self) -> bool {
129        self.flags & 0x04 != 0
130    }
131
132    pub fn is_arj_protected(&self) -> bool {
133        self.flags & 0x08 != 0
134    }
135
136    pub fn is_path_sym(&self) -> bool {
137        self.flags & 0x10 != 0
138    }
139
140    pub fn is_backup(&self) -> bool {
141        self.flags & 0x20 != 0
142    }
143
144    pub fn is_secured(&self) -> bool {
145        self.flags & 0x40 != 0
146    }
147
148    pub fn is_altname(&self) -> bool {
149        self.flags & 0x80 != 0
150    }
151}