main.rs
1 use anyhow::Context; 2 use clap::Parser; 3 4 mod avahi; 5 6 #[derive(Parser, Debug)] 7 #[command(version)] 8 struct Args { 9 #[arg(long, default_value_t = 120)] 10 ttl: u32, 11 #[arg(long)] 12 fqdn: Option<String>, 13 #[arg(short, long)] 14 subdomain: Vec<String>, 15 } 16 17 fn main() -> anyhow::Result<()> { 18 let args = Args::parse(); 19 20 if args.subdomain.is_empty() { 21 println!("no subdomains specified"); 22 return Ok(()); 23 } 24 25 let conn = zbus::blocking::Connection::system().context("error connecting to system buss")?; 26 let server = 27 avahi::ServerProxyBlocking::new(&conn).context("error connecting to avahi-daemon")?; 28 let fqdn = if let Some(fqdn) = args.fqdn { 29 fqdn 30 } else { 31 server 32 .get_host_name_fqdn() 33 .context("error getting hostname fqdn from avahi-daemon")? 34 }; 35 36 let rdata = { 37 let mut rdata = Vec::new(); 38 for label in fqdn.split(".") { 39 rdata.push(label.len() as u8); 40 rdata.extend(label.as_bytes()); 41 } 42 rdata.push(0); 43 rdata 44 }; 45 46 let entry_group = server.entry_group_new()?; 47 for name in args.subdomain { 48 entry_group 49 .add_record(-1, -1, 0, &format!("{name}.{fqdn}"), 1, 5, args.ttl, &rdata) 50 .context("error adding cname record to entry group")?; 51 } 52 entry_group 53 .commit() 54 .context("error commiting entry group")?; 55 56 let dbus_proxy = zbus::blocking::fdo::DBusProxy::new(&conn)?; 57 for signal in dbus_proxy.receive_name_owner_changed()? { 58 let args = signal.args()?; 59 if args.name() == "org.freedesktop.Avahi" 60 && args.new_owner().as_deref().unwrap_or("").is_empty() 61 { 62 println!("avahi-daemon exited; stopping"); 63 break; 64 } 65 } 66 Ok(()) 67 }