From 8ca6740d01fa6e324d1a9f1cc4c332da78500656 Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Fri, 26 Apr 2024 00:50:35 +0200 Subject: zip: New module Only support for finding and reading central directory yet. --- src/main.rs | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 81 insertions(+), 11 deletions(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index de2ebb2..c68f26a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,8 @@ mod args; +mod zip; +use std::fs::File; +use std::io; use std::process::ExitCode; fn guess_parser(args: &mut dyn Iterator) -> Box { @@ -13,7 +16,14 @@ fn guess_parser(args: &mut dyn Iterator) -> Box Box::new(args::LongOnlyParser::new()) } -fn parse_args() -> Result { +struct Program { + classname: String, + args: Vec, + classpath: String, + verbose: bool, +} + +fn parse_args() -> Result, String> { let mut options = args::Options::new(); let help_idx = options.push( args::OptionBuilder::default() @@ -38,6 +48,22 @@ fn parse_args() -> Result { .build() .unwrap(), ); + let cp_idx = options.push( + args::OptionBuilder::default() + .long("cp") + .description("class search path of directories and zip/jar files") + .value(args::ValueRequirement::Required("CLASSPATH")) + .build() + .unwrap(), + ); + let classpath_idx = options.push( + args::OptionBuilder::default() + .long("classpath") + .description("class search path of directories and zip/jar files") + .value(args::ValueRequirement::Required("CLASSPATH")) + .build() + .unwrap(), + ); let parser = guess_parser(&mut std::env::args()); let maybe_args = parser.run(&mut options, &mut std::env::args()); @@ -46,33 +72,77 @@ fn parse_args() -> Result { let help = &options[help_idx]; if help.is_set() { parser.print_help(&options); - return Ok(true); + return Ok(None); } let args = maybe_args?; let version = &options[version_idx]; if version.is_set() { println!("Version is 0.0.1"); - return Ok(true); + return Ok(None); } let verbose = &options[verbose_idx]; - println!("verbose: {}", verbose.is_set()); - println!("args: {:?}", args.args); - Ok(false) + let cp = &options[cp_idx]; + let classpath = &options[classpath_idx]; + let actual_classpath: &str; + if cp.is_set() { + if classpath.is_set() { + return Err("Both -cp and -classpath set, pick one.".to_string()); + } + actual_classpath = cp.value().as_ref().unwrap(); + } else if classpath.is_set() { + actual_classpath = classpath.value().as_ref().unwrap(); + } else { + actual_classpath = ""; + } + + let mut run_args = args.args.iter(); + if let Some(classname) = run_args.next() { + Ok(Some(Program { + classname: classname.clone(), + args: run_args.map(|s| s.clone()).collect(), + classpath: actual_classpath.to_string(), + verbose: verbose.is_set(), + })) + } else { + Err("Missing class name".to_string()) + } +} + +fn run(program: Program) -> io::Result { + let mut paths = program.classpath.split(':'); + let mut file = File::open(paths.next().unwrap())?; + let layout = zip::Layout::new(&mut file)?; + for (name, idx) in layout.names() { + let entry = &layout.entries()[*idx]; + println!( + "{name}: {} {}", + entry.compressed_size(), + entry.uncompressed_size() + ); + } + return Ok(ExitCode::SUCCESS); } fn main() -> ExitCode { match parse_args() { - Ok(exit) => { - if exit { + Ok(maybe_program) => match maybe_program { + Some(program) => match run(program) { + Ok(exit_code) => { + return exit_code; + } + Err(err) => { + eprintln!("{}", err); + return ExitCode::FAILURE; + } + }, + None => { return ExitCode::SUCCESS; } - } + }, Err(msg) => { eprintln!("{}", msg); return ExitCode::FAILURE; } } - - ExitCode::SUCCESS } -- cgit v1.2.3-70-g09d2