use std::env; use std::fs; use std::os::unix::fs::PermissionsExt; use std::path::PathBuf; use std::process; use bxcore::instance; use inferproxy::{Limits, serve}; fn main() { // `args_os`, because `args` panics on an argument that is not UTF-8. let args: Vec = match env::args_os().map(|a| a.into_string()).collect() { Ok(args) => args, Err(_) => usage(), }; let mut listen: Option = None; let mut upstream: Option = None; let mut i = 1; while i < args.len() { match args[i].as_str() { "--listen" => { i += 1; listen = args.get(i).cloned(); } "--upstream" => { i += 1; upstream = args.get(i).cloned(); } _ => usage(), } i += 1; } let listen = match listen { Some(p) => p, None => usage(), }; let upstream = match upstream { Some(p) => p, None => usage(), }; let path: PathBuf = listen.into(); // One inferproxy per socket (M5b spec, section 9a): the lock beside the socket comes before // the stale socket is removed, so a second copy never takes the socket of the one that runs. // Held until the process ends; `process::exit` leaves it to the system to release. let mut lock_path = path.clone().into_os_string(); lock_path.push(".lock"); let lock_path = PathBuf::from(lock_path); let _instance = match instance::lock(&lock_path) { Ok(held) => held, Err(e) => { eprintln!("{}", e.line("inferproxy", &lock_path)); process::exit(1); } }; match fs::remove_file(&path) { Ok(()) => {} Err(e) if e.kind() == std::io::ErrorKind::NotFound => {} Err(e) => { eprintln!("inferproxy: cannot remove stale socket: {e}"); process::exit(1); } } let listener = match std::os::unix::net::UnixListener::bind(&path) { Ok(l) => l, Err(e) => { eprintln!("inferproxy: bind failed: {e}"); process::exit(1); } }; let perms = fs::Permissions::from_mode(0o600); if let Err(e) = fs::set_permissions(&path, perms) { eprintln!("inferproxy: chmod failed: {e}"); process::exit(1); } eprintln!("inferproxy: {} -> {}", path.display(), upstream); if let Err(e) = serve(listener, upstream, Limits::default()) { eprintln!("inferproxy: {e}"); process::exit(1); } } fn usage() -> ! { eprintln!("usage: inferproxy --listen --upstream "); process::exit(2); }