Skip to content

Commit 0acc0f7

Browse files
committed
Added support for legacy compression formats.
ARC, ARJ, ZOO, SQ/SQ2/QQQ, SQZ and HYP
1 parent 9a05d1b commit 0acc0f7

File tree

4 files changed

+271
-2
lines changed

4 files changed

+271
-2
lines changed

crates/dizbase/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ regex = { workspace = true }
2121
zip = "2.2.0"
2222
delharc = "0.6.0"
2323
unrar = "0.5.7"
24+
unarc-rs = "0.4.3"
2425
twox-hash = { version="2.1.0", features=["xxhash3_64", "std"] }
2526

2627
icy_sauce = { git ="https://github.com/mkrueger/icy_tools" }

crates/dizbase/src/file_base_scanner/mod.rs

+152
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
use std::{
2+
ffi::OsStr,
23
fs,
34
io::{BufReader, Read, Seek, SeekFrom},
45
path::Path,
56
};
67

78
use codepages::{normalize_file, tables::get_utf8};
89
use icy_sauce::SauceInformation;
10+
use unarc_rs::{
11+
arc::arc_archive::ArcArchieve, arj::arj_archive::ArjArchieve, hyp::hyp_archive::HypArchieve, sq::sq_archive::SqArchieve, zoo::zoo_archive::ZooArchieve,
12+
};
913
use unrar::Archive;
1014

1115
use crate::file_base::{
@@ -38,6 +42,13 @@ pub fn scan_file(path: &Path) -> crate::Result<Vec<MetadataHeader>> {
3842
"RAR" => scan_rar(info, path),
3943
"EXE" | "COM" | "BAT" | "BMP" | "GIF" | "JPG" => Ok(info),
4044

45+
"ARJ" => scan_arj(info, path),
46+
"ARC" => scan_arc(info, path),
47+
"ZOO" => scan_zoo(info, path),
48+
"SQZ" => scan_sqz(info, path),
49+
"HYP" => scan_hyp(info, path),
50+
"SQ" | "SQ2" | "QQQ" => scan_sq(info, path),
51+
4152
_ext => Ok(info),
4253
}
4354
}
@@ -172,3 +183,144 @@ fn scan_rar(mut info: Vec<MetadataHeader>, path: &Path) -> crate::Result<Vec<Met
172183

173184
Ok(info)
174185
}
186+
187+
fn scan_arj(mut info: Vec<MetadataHeader>, path: &Path) -> crate::Result<Vec<MetadataHeader>> {
188+
let file = fs::File::open(path)?;
189+
let mut short_descr = Vec::new();
190+
let mut last_prio = -1;
191+
192+
let mut archieve = ArjArchieve::new(file)?;
193+
while let Ok(Some(header)) = archieve.get_next_entry() {
194+
if let Some(prio) = is_short_desc(OsStr::new(&header.name)) {
195+
if prio <= last_prio {
196+
continue;
197+
}
198+
last_prio = prio;
199+
short_descr = archieve.read(&header)?;
200+
}
201+
}
202+
203+
if !short_descr.is_empty() {
204+
info.push(MetadataHeader::new(MetadataType::FileID, get_file_id(short_descr).as_bytes().to_vec()));
205+
}
206+
207+
Ok(info)
208+
}
209+
210+
fn scan_arc(mut info: Vec<MetadataHeader>, path: &Path) -> crate::Result<Vec<MetadataHeader>> {
211+
let file = fs::File::open(path)?;
212+
let mut short_descr = Vec::new();
213+
let mut last_prio = -1;
214+
215+
let mut archieve = ArcArchieve::new(file)?;
216+
while let Ok(Some(header)) = archieve.get_next_entry() {
217+
if let Some(prio) = is_short_desc(OsStr::new(&header.name)) {
218+
if prio <= last_prio {
219+
continue;
220+
}
221+
last_prio = prio;
222+
short_descr = archieve.read(&header)?;
223+
}
224+
}
225+
226+
if !short_descr.is_empty() {
227+
info.push(MetadataHeader::new(MetadataType::FileID, get_file_id(short_descr).as_bytes().to_vec()));
228+
}
229+
230+
Ok(info)
231+
}
232+
233+
fn scan_zoo(mut info: Vec<MetadataHeader>, path: &Path) -> crate::Result<Vec<MetadataHeader>> {
234+
let file = fs::File::open(path)?;
235+
let mut short_descr = Vec::new();
236+
let mut last_prio = -1;
237+
238+
let mut archieve = ZooArchieve::new(file)?;
239+
while let Ok(Some(header)) = archieve.get_next_entry() {
240+
if let Some(prio) = is_short_desc(OsStr::new(&header.name)) {
241+
if prio <= last_prio {
242+
continue;
243+
}
244+
last_prio = prio;
245+
short_descr = archieve.read(&header)?;
246+
}
247+
}
248+
249+
if !short_descr.is_empty() {
250+
info.push(MetadataHeader::new(MetadataType::FileID, get_file_id(short_descr).as_bytes().to_vec()));
251+
}
252+
253+
Ok(info)
254+
}
255+
256+
fn scan_sqz(mut info: Vec<MetadataHeader>, path: &Path) -> crate::Result<Vec<MetadataHeader>> {
257+
let file = fs::File::open(path)?;
258+
let mut short_descr = Vec::new();
259+
let mut last_prio = -1;
260+
261+
let mut archieve = ZooArchieve::new(file)?;
262+
while let Ok(Some(header)) = archieve.get_next_entry() {
263+
if let Some(prio) = is_short_desc(OsStr::new(&header.name)) {
264+
if prio <= last_prio {
265+
continue;
266+
}
267+
last_prio = prio;
268+
short_descr = archieve.read(&header)?;
269+
}
270+
}
271+
272+
if !short_descr.is_empty() {
273+
info.push(MetadataHeader::new(MetadataType::FileID, get_file_id(short_descr).as_bytes().to_vec()));
274+
}
275+
276+
Ok(info)
277+
}
278+
279+
fn scan_sq(mut info: Vec<MetadataHeader>, path: &Path) -> crate::Result<Vec<MetadataHeader>> {
280+
let file = fs::File::open(path)?;
281+
let mut short_descr = Vec::new();
282+
let mut last_prio = -1;
283+
284+
let mut archieve = SqArchieve::new(file)?;
285+
while let Ok(Some(header)) = archieve.get_next_entry() {
286+
if let Some(prio) = is_short_desc(OsStr::new(&header.name)) {
287+
if prio <= last_prio {
288+
continue;
289+
}
290+
last_prio = prio;
291+
short_descr = archieve.read(&header)?;
292+
}
293+
}
294+
295+
if !short_descr.is_empty() {
296+
info.push(MetadataHeader::new(MetadataType::FileID, get_file_id(short_descr).as_bytes().to_vec()));
297+
}
298+
299+
Ok(info)
300+
}
301+
302+
fn scan_hyp(mut info: Vec<MetadataHeader>, path: &Path) -> crate::Result<Vec<MetadataHeader>> {
303+
let file = fs::File::open(path)?;
304+
let mut short_descr = Vec::new();
305+
let mut last_prio = -1;
306+
307+
let mut archieve = HypArchieve::new(file)?;
308+
while let Ok(Some(header)) = archieve.get_next_entry() {
309+
if let Some(prio) = is_short_desc(OsStr::new(&header.name)) {
310+
// only uncompressed files are supported, so it's likely to fail.
311+
if let Ok(buffer) = archieve.read(&header) {
312+
if prio <= last_prio {
313+
continue;
314+
}
315+
last_prio = prio;
316+
short_descr = buffer;
317+
}
318+
}
319+
}
320+
321+
if !short_descr.is_empty() {
322+
info.push(MetadataHeader::new(MetadataType::FileID, get_file_id(short_descr).as_bytes().to_vec()));
323+
}
324+
325+
Ok(info)
326+
}

crates/dizbase/src/lib.rs

+117-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
use std::{fs, io::BufReader, path::Path};
22

3+
use unarc_rs::{
4+
arc::arc_archive::ArcArchieve, arj::arj_archive::ArjArchieve, hyp::hyp_archive::HypArchieve, sq::sq_archive::SqArchieve, sqz::sqz_archive::SqzArchieve,
5+
zoo::zoo_archive::ZooArchieve,
6+
};
37
use unrar::Archive;
48
use zip::DateTime;
59

@@ -27,8 +31,13 @@ pub fn scan_file_contents(path: &std::path::PathBuf) -> crate::Result<Vec<FileIn
2731
match extension.as_str() {
2832
"ZIP" => scan_zip(path),
2933
"LHA" | "LZH" => scan_lha(path),
30-
3134
"RAR" => scan_rar(path),
35+
"ARJ" => scan_arj(path),
36+
"ARC" => scan_arc(path),
37+
"ZOO" => scan_zoo(path),
38+
"SQZ" => scan_sqz(path),
39+
"HYP" => scan_hyp(path),
40+
"SQ" | "SQ2" | "QQQ" => scan_sq(path),
3241

3342
ext => {
3443
println!("Unknown extension {:?}", ext);
@@ -37,6 +46,113 @@ pub fn scan_file_contents(path: &std::path::PathBuf) -> crate::Result<Vec<FileIn
3746
}
3847
}
3948

49+
fn scan_arj(path: &std::path::PathBuf) -> crate::Result<Vec<FileInfo>> {
50+
let file = fs::File::open(path)?;
51+
let mut archieve = ArjArchieve::new(file)?;
52+
let mut info = Vec::new();
53+
54+
while let Ok(Some(header)) = archieve.get_next_entry() {
55+
let (date, time) = header.date_time_modified.into();
56+
info.push(FileInfo {
57+
name: header.name.clone(),
58+
size: header.original_size as u64,
59+
compressed_size: header.compressed_size as u64,
60+
date: unsafe { DateTime::from_msdos_unchecked(date, time) },
61+
});
62+
}
63+
64+
Ok(info)
65+
}
66+
67+
fn scan_arc(path: &std::path::PathBuf) -> crate::Result<Vec<FileInfo>> {
68+
let file = fs::File::open(path)?;
69+
let mut archieve = ArcArchieve::new(file)?;
70+
let mut info = Vec::new();
71+
72+
while let Ok(Some(header)) = archieve.get_next_entry() {
73+
let (date, time) = header.date_time.into();
74+
info.push(FileInfo {
75+
name: header.name.clone(),
76+
size: header.original_size as u64,
77+
compressed_size: header.compressed_size as u64,
78+
date: unsafe { DateTime::from_msdos_unchecked(date, time) },
79+
});
80+
}
81+
82+
Ok(info)
83+
}
84+
85+
fn scan_zoo(path: &std::path::PathBuf) -> crate::Result<Vec<FileInfo>> {
86+
let file = fs::File::open(path)?;
87+
let mut archieve = ZooArchieve::new(file)?;
88+
let mut info = Vec::new();
89+
90+
while let Ok(Some(header)) = archieve.get_next_entry() {
91+
let (date, time) = header.date_time.into();
92+
info.push(FileInfo {
93+
name: header.name.clone(),
94+
size: header.org_size as u64,
95+
compressed_size: header.size_now as u64,
96+
date: unsafe { DateTime::from_msdos_unchecked(date, time) },
97+
});
98+
}
99+
100+
Ok(info)
101+
}
102+
103+
fn scan_sqz(path: &std::path::PathBuf) -> crate::Result<Vec<FileInfo>> {
104+
let file = fs::File::open(path)?;
105+
let mut archieve = SqzArchieve::new(file)?;
106+
let mut info = Vec::new();
107+
108+
while let Ok(Some(header)) = archieve.get_next_entry() {
109+
let (date, time) = header.date_time.into();
110+
info.push(FileInfo {
111+
name: header.name.clone(),
112+
size: header.original_size as u64,
113+
compressed_size: header.compressed_size as u64,
114+
date: unsafe { DateTime::from_msdos_unchecked(date, time) },
115+
});
116+
}
117+
118+
Ok(info)
119+
}
120+
121+
fn scan_sq(path: &std::path::PathBuf) -> crate::Result<Vec<FileInfo>> {
122+
let file = fs::File::open(path)?;
123+
let mut archieve = SqArchieve::new(file)?;
124+
let mut info = Vec::new();
125+
126+
while let Ok(Some(header)) = archieve.get_next_entry() {
127+
info.push(FileInfo {
128+
name: header.name.clone(),
129+
size: 0,
130+
compressed_size: 0,
131+
date: unsafe { DateTime::from_msdos_unchecked(0, 0) },
132+
});
133+
}
134+
135+
Ok(info)
136+
}
137+
138+
fn scan_hyp(path: &std::path::PathBuf) -> crate::Result<Vec<FileInfo>> {
139+
let file = fs::File::open(path)?;
140+
let mut archieve = HypArchieve::new(file)?;
141+
let mut info = Vec::new();
142+
143+
while let Ok(Some(header)) = archieve.get_next_entry() {
144+
let (date, time) = header.date_time.into();
145+
info.push(FileInfo {
146+
name: header.name.clone(),
147+
size: header.original_size as u64,
148+
compressed_size: header.compressed_size as u64,
149+
date: unsafe { DateTime::from_msdos_unchecked(date, time) },
150+
});
151+
}
152+
153+
Ok(info)
154+
}
155+
40156
fn scan_zip(path: &Path) -> crate::Result<Vec<FileInfo>> {
41157
let file = fs::File::open(path)?;
42158
let reader = BufReader::new(file);

crates/icy_board_engine/src/icy_board/state/user_commands/mods/fileview/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl IcyBoardState {
6767
let sav = self.session.disp_options.in_file_list.take();
6868
self.session.disp_options.abort_printout = false;
6969
let mut len = 0;
70-
let colors = self.get_board().await.config.color_configuration.clone();
70+
let colors: crate::icy_board::icb_config::ColorConfiguration = self.get_board().await.config.color_configuration.clone();
7171
self.set_color(TerminalTarget::Both, colors.file_head.clone()).await?;
7272
self.println(TerminalTarget::Both, &format!(" Archive: {}", file.file_name().unwrap().to_string_lossy()))
7373
.await?;

0 commit comments

Comments
 (0)