This commit is contained in:
tux
2026-11-03 22:13:16 +01:00
parent 158e115242
commit 8012e912ec
19 changed files with 975 additions and 208 deletions
+38 -33
View File
@@ -22,19 +22,20 @@ use std::os::unix::fs::OpenOptionsExt;
use std::os::unix::io::FromRawFd;
use std::path::Path;
const MANUAL: &str = r#"cdparanoia III release 10.2 (September 11, 2008)
const MANUAL: &str = r#"cdrustanoia 26.0.1 (2026-11-03)
based on the great cdparanoia by Monty <monty@xiph.org> and Xiph.Org
(C) 2008 Monty <monty@xiph.org> and Xiph.Org
(C) 2026 Martin Wohlert <martin.wohlert@b-root-force.de>
Report bugs to martin.wohlert@b-root-force.de
Report bugs to paranoia@xiph.org
http://www.xiph.org/paranoia/
USAGE:
cdparanoia [options] <span> [outfile]
cdrustanoia [options] <span> [outfile]
OPTIONS:
-A --analyze-drive : run and log a complete analysis of drive
caching, timing and reading behavior;
verifies that cdparanoia is correctly
verifies that cdrustanoia is correctly
modelling a sprcific drive's cache and
read behavior. Implies -vQL
-v --verbose : extra verbose operation
@@ -42,10 +43,10 @@ OPTIONS:
-e --stderr-progress : force output of progress information to
stderr (for wrapper scripts)
-l --log-summary [<file>] : save result summary to file, default
filename cdparanoia.log
filename cdrustanoia.log
-L --log-debug [<file>] : save detailed device autosense and
debugging output to file, default
filename cdparanoia.log
filename cdrustanoia.log
-V --version : print version info and quit
-Q --query : autosense drive, query disc and quit
-B --batch : 'batch' mode (saves each track to a
@@ -77,7 +78,7 @@ OPTIONS:
force use of the old SG kernel
interface. -g cannot be used with -k.
-S --force-read-speed <n> : read from device at specified speed; by
default, cdparanoia sets drive to full
default, cdrustanoia sets drive to full
speed.
-t --toc-offset <n> : Add <n> sectors to the values reported
when addressing tracks. May be negative
@@ -154,16 +155,14 @@ the shell...
A few examples, protected from the shell:
A) query only with exhaustive search for a drive and full reporting
of autosense:
cdparanoia -vsQ
cdrustanoia -vsQ
B) extract up to and including track 3, putting each track in a seperate
file:
cdparanoia -B -- "-3"
cdrustanoia -B -- "-3"
C) extract from track 1, time 0:30.12 to 1:10.00:
cdparanoia "1[:30.12]-1[1:10]"
Submit bug reports to paranoia@xiph.org
cdrustanoia "1[:30.12]-1[1:10]"
"#;
@@ -283,17 +282,6 @@ fn display_toc(d: &dyn Drive, log: &mut Log) {
log.report(format_args!(" "));
}
fn read_sector(
p: &mut Paranoia,
progress: &mut Progress,
log: &mut Log,
max_retries: i32,
) -> Option<Vec<i16>> {
let mut callback = |pos: i64, func: i32| progress.callback(pos, func, log);
p.read_limited(&mut callback, max_retries)
.map(|s| s.to_vec())
}
fn samples_as_bytes(samples: &[i16]) -> &[u8] {
unsafe {
std::slice::from_raw_parts(
@@ -708,7 +696,11 @@ of the machine.\n\nMore information about /dev/cdrom:"
progress.skipped_flag = false;
while cursor <= batch_last {
let sector = match read_sector(&mut p, &mut progress, &mut log, args.max_retries) {
let sector = {
let mut callback = |pos: i64, func: i32| progress.callback(pos, func, &mut log);
p.read_limited(&mut callback, args.max_retries)
};
let data = match sector {
Some(s) => s,
None => {
progress.skipped_flag = true;
@@ -725,23 +717,32 @@ of the machine.\n\nMore information about /dev/cdrom:"
progress.skipped_flag = false;
cursor += 1;
let mut data = sector;
if target_big != host_big {
for s in &mut data {
for s in data.iter_mut() {
*s = swap16(*s);
}
}
progress.callback(cursor * 1176 - 1, -2, &mut log);
let data_bytes = samples_as_bytes(&data);
let data_bytes = samples_as_bytes(data);
if let Err(e) = out.write_all(&data_bytes[offset_skip.min(data_bytes.len())..]) {
log.report(format_args!("Error writing output: {}", e));
return 1;
}
offset_skip = 0;
if target_big != host_big {
for s in data.iter_mut() {
*s = swap16(*s);
}
}
if sample_offset != 0 && cursor > batch_last {
let extra = match read_sector(&mut p, &mut progress, &mut log, args.max_retries) {
let extra = {
let mut callback = |pos: i64, func: i32| progress.callback(pos, func, &mut log);
p.read_limited(&mut callback, args.max_retries)
};
let extra = match extra {
Some(s) => s,
None => {
progress.skipped_flag = true;
@@ -756,14 +757,18 @@ of the machine.\n\nMore information about /dev/cdrom:"
break;
}
progress.skipped_flag = false;
let mut extra = extra;
if target_big != host_big {
for s in &mut extra {
for s in extra.iter_mut() {
*s = swap16(*s);
}
}
let eb = samples_as_bytes(&extra);
let eb = samples_as_bytes(extra);
offset_buffer[..eb.len().min(2352)].copy_from_slice(&eb[..eb.len().min(2352)]);
if target_big != host_big {
for s in extra.iter_mut() {
*s = swap16(*s);
}
}
offset_buffer_used = (sample_offset as usize * 4).min(2352);
progress.callback(cursor * 1176, -2, &mut log);
if let Err(e) = out.write_all(&offset_buffer[..offset_buffer_used]) {