diff --git a/main.c b/main.c index 50bbf17..0aa5f2b 100644 --- a/main.c +++ b/main.c @@ -49,128 +49,3 @@ void usage() { int main(int argc, char **argv) { return rust_main(argc, argv); } - -int old_c_main(int argc, char **argv) -{ - int read_flag = 0, write_flag = 0, config_flag = 0, csv_flag = 0; - int list_flag = 0, verify_flag = 0; - - trace_flag = 0; - for (;;) { - switch (getopt(argc, argv, "tcwrulv")) { - case 't': ++trace_flag; continue; - case 'r': ++read_flag; continue; - case 'w': ++write_flag; continue; - case 'c': ++config_flag; continue; - case 'u': ++csv_flag; continue; - case 'l': ++list_flag; continue; - case 'v': ++verify_flag; continue; - default: - usage(); - case EOF: - break; - } - break; - } - argc -= optind; - argv += optind; - /* - if (list_flag) { - radio_list(); - exit(0); - } - if (read_flag + write_flag + config_flag + csv_flag + verify_flag > 1) { - fprintf(stderr, "Only one of -r, -w, -c, -v or -u options is allowed.\n"); - usage(); - } - */ - setvbuf(stdout, 0, _IOLBF, 0); - setvbuf(stderr, 0, _IOLBF, 0); - - /* - if (write_flag) { - // Restore image file to device. - if (argc != 1) - usage(); - - radio_connect(); - radio_read_image(argv[0]); - radio_print_version(stdout); - radio_upload(0); - radio_disconnect(); - - } else */if (config_flag) { - if (argc != 1 && argc != 2) - usage(); - - if (argc == 2) { - // Apply text config to image file. - radio_read_image(argv[0]); - radio_print_version(stdout); - radio_parse_config(argv[1]); - radio_verify_config(); - radio_save_image("device.img"); - - } else { - // Update device from text config file. - radio_connect(); - radio_download(); - radio_print_version(stdout); - radio_save_image("backup.img"); - radio_parse_config(argv[0]); - radio_verify_config(); - radio_upload(1); - radio_disconnect(); - } - - } else if (verify_flag) { - if (argc != 1) - usage(); - - // Verify text config file. - radio_connect(); - radio_parse_config(argv[0]); - radio_verify_config(); - radio_disconnect(); - - } else if (read_flag) { - if (argc != 0) - usage(); - - // Dump device to image file. - radio_connect(); - radio_download(); - radio_print_version(stdout); - radio_disconnect(); - radio_save_image("device.img"); - - // Print configuration to file. - const char *filename = "device.conf"; - printf("Print configuration to file '%s'.\n", filename); - FILE *conf = fopen(filename, "w"); - if (!conf) { - perror(filename); - exit(-1); - } - radio_print_config(conf, 1); - fclose(conf); - - } else if (csv_flag) { - // Update contacts database on the device. - if (argc != 1) - usage(); - - radio_connect(); - radio_write_csv(argv[0]); - radio_disconnect(); - - } else { - if (argc != 1) - usage(); - - // Print configuration from image file. - radio_read_image(argv[0]); - radio_print_config(stdout, !isatty(1)); - } - return 0; -} diff --git a/src/lib.rs b/src/lib.rs index f341843..276df8f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,3 @@ -use std::ffi::CString; use libc::{c_int, c_char}; use getopts::Options; use std::process::exit; @@ -9,12 +8,11 @@ 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; fn radio_connect(); - fn radio_read_image(filename: *const c_char); - fn radio_print_version(stdout: *const libc::FILE); fn radio_upload(cont_flag: c_int); fn radio_disconnect(); + fn radio_verify_config(); + fn radio_download(); } #[no_mangle] @@ -100,18 +98,94 @@ pub extern "C" fn rust_main(argc: c_int, argv: *const *const c_char) -> c_int { } unsafe { radio_connect(); - let filename = CString::new(matches.free[0].clone()).unwrap(); - radio_read_image(filename.as_ptr()); - let mode = CString::new("w").unwrap(); - radio_print_version(libc::fdopen(libc::STDOUT_FILENO, mode.as_ptr())); + radio::read_image(&matches.free[0]); + radio::print_version(); radio_upload(0); radio_disconnect(); } + } else if config_flag { + let conf_args = matches.free.len(); + if !(conf_args == 1 || conf_args == 2) { + print_usage(); + } + let (config_filename, image_filename) = if conf_args == 2 { + (matches.free[1].clone(), Some(matches.free[0].clone())) + } else { + (matches.free[0].clone(), None) + }; + + if let Some(img) = image_filename { + // Apply text config to image file. + unsafe { + radio::read_image(&img); + radio::print_version(); + radio::parse_config(&config_filename); + radio_verify_config(); + radio::save_image("device.img"); + } + } else { + // Update device from text config file. + unsafe { + radio_connect(); + radio_download(); + radio::print_version(); + radio::save_image("device.img"); + radio::parse_config(&config_filename); + radio_verify_config(); + radio_upload(1); + radio_disconnect(); + } + } + } else if verify_flag { + if matches.free.len() != 1 { + print_usage(); + } + // Verify text config file. + unsafe { + radio_connect(); + radio::parse_config(&matches.free[0]); + radio_verify_config(); + radio_disconnect(); + } + } else if read_flag { + if matches.free.len() != 0 { + print_usage(); + } + + // Dump device to image file. + unsafe { + radio_connect(); + radio_download(); + radio::print_version(); + radio_disconnect(); + radio::save_image("device.img"); + } + + // Print configuration to file. + let filename = "device.conf"; + println!("Print configuration to file '{}.", filename); + + radio::print_config(filename); + + } else if csv_flag { + if matches.free.len() != 1 { + print_usage(); + } + + unsafe { + radio_connect(); + radio::write_csv(&matches.free[0]); + radio_disconnect(); + } + } else { + if matches.free.len() != 1 { + print_usage(); + } + radio::read_image(&matches.free[0]); + radio::print_config_to_stdout(); } - unsafe { - old_c_main(argc, argv) - } + exit(0); } #[cfg(test)] diff --git a/src/radio.rs b/src/radio.rs index fc9bdde..548d524 100644 --- a/src/radio.rs +++ b/src/radio.rs @@ -1,5 +1,15 @@ +use std::ffi::CString; +use libc::{c_char, c_int}; +use std::os::unix::io::AsRawFd; + extern { fn radio_list_c(); + fn radio_print_version(stdout: *const libc::FILE); + fn radio_print_config(file: *const libc::FILE, verbose: c_int); + fn radio_read_image(filename: *const c_char); + fn radio_save_image(filename: *const c_char); + fn radio_parse_config(filename: *const c_char); + fn radio_write_csv(filename: *const c_char); } pub fn list() { @@ -7,3 +17,62 @@ pub fn list() { radio_list_c(); } } + +pub fn read_image(filename: &str) { + let filename = CString::new(filename.to_string()).unwrap(); + unsafe { + radio_read_image(filename.as_ptr()); + } +} + +pub fn save_image(filename: &str) { + let filename = CString::new(filename.to_string()).unwrap(); + unsafe { + radio_save_image(filename.as_ptr()) + } +} + +pub fn parse_config(filename: &str) { + let filename = CString::new(filename.to_string()).unwrap(); + unsafe { + radio_parse_config(filename.as_ptr()) + } +} + +pub fn print_config(filename: &str) { + let file = std::fs::File::create(filename).unwrap(); + let fd = file.as_raw_fd(); + let mode = CString::new("w").unwrap(); + unsafe { + let file =libc::fdopen(fd, mode.as_ptr()); + radio_print_config(file, 1); + libc::fclose(file); + } +} + +pub fn print_config_to_stdout() { + let mode = CString::new("w").unwrap(); + unsafe { + let stdout = libc::fdopen(libc::STDOUT_FILENO, mode.as_ptr()); + let verbosity = if libc::isatty(libc::STDOUT_FILENO) == 1 { + 0 + } else { + 1 + }; + radio_print_config(stdout, verbosity); + } +} + +pub fn print_version() { + let mode = CString::new("w").unwrap(); + unsafe { + radio_print_version(libc::fdopen(libc::STDOUT_FILENO, mode.as_ptr())); + } +} + +pub fn write_csv(filename: &str) { + let filename = CString::new(filename.to_string()).unwrap(); + unsafe { + radio_write_csv(filename.as_ptr()); + } +}