use libc::{c_int, c_char}; use getopts::Options; use std::process::exit; mod radio; const COPYRIGHT: &'static str = "Copyright (C) 2018 Serge Vakulenko KK6ABQ"; const VERSION: Option<&'static str> = option_env!("VERSION"); extern { fn old_c_main(argc: c_int, argv: *const *const c_char) -> c_int; } #[no_mangle] pub extern "C" fn print_usage() { let version = VERSION.unwrap_or("-----"); print!("DMR Config, Version {}, {}", version, COPYRIGHT); let msg = r#" Usage: dmrconfig -r [-t] Read codeplug from the radio to a file 'device.img'. Save configuration to a text file 'device.conf'. dmrconfig -w [-t] file.img Write codeplug to the radio. dmrconfig -v [-t] file.conf Verify configuration script for the radio. dmrconfig -c [-t] file.conf Apply configuration script to the radio. dmrconfig -c file.img file.conf Apply configuration script to the codeplug image. Store modified copy to a file 'device.img'. dmrconfig file.img Display configuration from the codeplug image. dmrconfig -u [-t] file.csv Update contacts database from CSV file. Options: -r Read codeplug from the radio. -w Write codeplug to the radio. -c Configure the radio from a text script. -v Verify config file. -u Update contacts database. -l List all supported radios. -t Trace USB protocol."#; print!("{}", msg); exit(-1); } fn get_options() -> Options { let mut opts = Options::new(); opts.optflag("t", "", "Trace USB protocol."); opts.optflag("r", "", "Read codeplug from the radio to a file 'device.img'.\nSave configuration to a text file 'device.conf'."); opts.optflag("w", "", "Write codeplug to the radio."); opts.optflag("c", "", "Verify configuration script for the radio."); opts.optflag("u", "", "Update contacts database from CSV file."); opts.optflag("l", "", "List all supported radios."); opts.optflag("v", "", "Verify configuration script for the radio."); opts } #[no_mangle] pub extern "C" fn rust_main(argc: c_int, argv: *const *const c_char) -> c_int { let args = std::env::args().skip(1); let matches = match get_options().parse(args) { Ok(m) => m, Err(fail) => { eprintln!("{}", fail); exit(-1); } }; let list_flag = matches.opt_present("l"); let verify_flag = matches.opt_present("v"); let read_flag = matches.opt_present("r"); let write_flag = matches.opt_present("w"); let config_flag = matches.opt_present("c"); let csv_flag = matches.opt_present("u"); if list_flag { radio::list(); exit(0); } if [read_flag, write_flag, config_flag, csv_flag, verify_flag].iter().filter(|x| **x).count() > 1 { eprintln!("Only one of -r, -w, -c, -v or -u options is allowed."); print_usage(); } unsafe { old_c_main(argc, argv) } } #[cfg(test)] mod tests { #[test] fn it_works() { assert_eq!(2 + 2, 4); } }