]> git.proxmox.com Git - pve-lxc-syscalld.git/blame - src/main.rs
bump to 0.9.0, experimental release
[pve-lxc-syscalld.git] / src / main.rs
CommitLineData
d54e9e5a 1use std::ffi::{OsStr, OsString};
9aa2a15a 2use std::future::Future;
8dd26985 3use std::io as StdIo;
d54e9e5a
WB
4use std::io::{stderr, stdout, Write};
5use std::os::unix::ffi::OsStrExt;
9cffeac4
WB
6
7use failure::{bail, format_err, Error};
8use nix::sys::socket::SockAddr;
9
9aa2a15a
WB
10#[macro_use]
11mod macros;
12
42f25756 13pub mod apparmor;
738dbfbe 14pub mod capability;
e420f6f9 15pub mod client;
d1b1deab 16pub mod error;
e420f6f9 17pub mod fork;
8dd26985 18pub mod io;
9cffeac4 19pub mod lxcseccomp;
e420f6f9 20pub mod nsfd;
a22aece0 21pub mod poll_fn;
3bbd1db0 22pub mod process;
9cffeac4 23pub mod seccomp;
e420f6f9 24pub mod sys_mknod;
3e69a521 25pub mod sys_quotactl;
c95be5f6 26pub mod syscall;
9cffeac4
WB
27pub mod tools;
28
8dd26985 29use crate::io::seq_packet::SeqPacketListener;
9aa2a15a 30
9aa2a15a 31pub fn spawn(fut: impl Future<Output = ()> + Send + 'static) {
5bd0c562 32 tokio::spawn(fut);
9aa2a15a
WB
33}
34
86ee36e8 35fn usage(status: i32, program: &OsStr, out: &mut dyn Write) -> ! {
d54e9e5a
WB
36 let _ = out.write_all("usage: ".as_bytes());
37 let _ = out.write_all(program.as_bytes());
38 let _ = out.write_all(
39 concat!(
40 "[options] SOCKET_PATH\n",
41 "options:\n",
42 " -h, --help show this help message\n",
43 " --system \
44 run as systemd daemon (use sd_notify() when ready to accept connections)\n",
86ee36e8
WB
45 )
46 .as_bytes(),
d54e9e5a
WB
47 );
48 std::process::exit(status);
49}
50
9aa2a15a 51fn main() {
d54e9e5a
WB
52 let mut args = std::env::args_os();
53 let program = args.next().unwrap(); // program name always exists
54
55 let mut use_sd_notify = false;
56 let mut path = None;
57
58 for arg in &mut args {
59 if arg == "-h" || arg == "--help" {
60 usage(0, &program, &mut stdout());
61 }
62
63 if arg == "--" {
64 break;
65 } else if arg == "--system" {
66 use_sd_notify = true;
67 } else {
68 let bytes = arg.as_bytes();
69 if bytes.starts_with(b"-") {
70 let _ = stderr().write_all(b"unexpected option: ");
71 let _ = stderr().write_all(arg.as_bytes());
72 usage(1, &program, &mut stderr());
73 }
74
75 if path.is_some() {
76 let _ = stderr().write_all(b"unexpected extra parameter: ");
77 let _ = stderr().write_all(arg.as_bytes());
78 usage(1, &program, &mut stderr());
79 }
80
81 path = Some(arg);
82 }
83 }
84
85 let path = match path {
86 Some(path) => path,
87 None => {
88 eprintln!("missing path");
89 usage(1, &program, &mut stderr());
90 }
91 };
92
5bd0c562 93 let mut rt = tokio::runtime::Runtime::new().expect("failed to spawn tokio runtime");
e420f6f9 94
d54e9e5a 95 if let Err(err) = rt.block_on(do_main(use_sd_notify, path)) {
9cffeac4
WB
96 eprintln!("error: {}", err);
97 std::process::exit(1);
98 }
99}
100
d54e9e5a 101async fn do_main(use_sd_notify: bool, socket_path: OsString) -> Result<(), Error> {
571dbe03 102 match std::fs::remove_file(&socket_path) {
9cffeac4 103 Ok(_) => (),
8dd26985 104 Err(ref e) if e.kind() == StdIo::ErrorKind::NotFound => (), // Ok
9cffeac4
WB
105 Err(e) => bail!("failed to remove previous socket: {}", e),
106 }
107
571dbe03
WB
108 let address =
109 SockAddr::new_unix(socket_path.as_os_str()).expect("cannot create struct sockaddr_un?");
9cffeac4 110
8dd26985 111 let mut listener = SeqPacketListener::bind(&address)
9cffeac4 112 .map_err(|e| format_err!("failed to create listening socket: {}", e))?;
d54e9e5a
WB
113
114 if use_sd_notify {
115 notify_systemd()?;
116 }
117
9cffeac4
WB
118 loop {
119 let client = listener.accept().await?;
e420f6f9 120 let client = client::Client::new(client);
9aa2a15a 121 spawn(client.main());
9cffeac4
WB
122 }
123}
d54e9e5a
WB
124
125#[link(name = "systemd")]
126extern "C" {
127 fn sd_notify(unset_environment: libc::c_int, state: *const libc::c_char) -> libc::c_int;
128}
129
130fn notify_systemd() -> StdIo::Result<()> {
131 let err = unsafe { sd_notify(0, c_str!("READY=1\n").as_ptr()) };
7bb69bd3 132 if err >= 0 {
d54e9e5a
WB
133 Ok(())
134 } else {
135 Err(StdIo::Error::from_raw_os_error(-err))
136 }
137}