//! Reads a zone file. use std::env; use std::fs::File; use std::process::exit; use std::time::SystemTime; use domain::zonefile::inplace::Entry; use domain::zonefile::inplace::Zonefile; fn main() { let mut args = env::args(); let prog_name = args.next().unwrap(); // SAFETY: O/S always passes our name as the first argument. let zone_files: Vec<_> = args.collect(); if zone_files.is_empty() { eprintln!("Usage: {prog_name} [, , , , , ...]"); exit(2); } for zone_file in zone_files { print!("Processing {zone_file}: "); let start = SystemTime::now(); let mut reader = Zonefile::load(&mut File::open(&zone_file).unwrap()).unwrap(); println!( "Data loaded ({:.03}s).", start.elapsed().unwrap().as_secs_f32() ); let mut i = 0; let mut last_entry = None; loop { match reader.next_entry() { Ok(entry) if entry.is_some() => { last_entry = entry; } Ok(_) => break, // EOF Err(err) => { eprintln!( "\nAn error occurred while reading {zone_file}:" ); eprintln!(" Error: {err}"); if let Some(entry) = &last_entry { if let Entry::Record(record) = &entry { eprintln!( "\nThe last record read was:\n{record}." ); } else { eprintln!("\nThe last record read was:\n{last_entry:#?}."); } eprintln!("\nTry commenting out the line after that record with a leading ; (semi-colon) character.") } exit(1); } } i += 1; if i % 100_000_000 == 0 { println!( "Processed {}M records ({:.03}s)", i / 1_000_000, start.elapsed().unwrap().as_secs_f32() ); } } println!( "Complete with {} records ({:.03}s)\n", i, start.elapsed().unwrap().as_secs_f32() ); } }