Files
boxmaker/crates/inferproxy/src/main.rs
T

87 lines
2.6 KiB
Rust

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<String> = match env::args_os().map(|a| a.into_string()).collect() {
Ok(args) => args,
Err(_) => usage(),
};
let mut listen: Option<String> = None;
let mut upstream: Option<String> = 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 <socket path> --upstream <host:port>");
process::exit(2);
}