diff --git a/bin/darkirc/src/irc/client.rs b/bin/darkirc/src/irc/client.rs index c7b2bfdef..10d698822 100644 --- a/bin/darkirc/src/irc/client.rs +++ b/bin/darkirc/src/irc/client.rs @@ -119,7 +119,7 @@ impl IrcClient { self.irc_config.channels.extend(new_config.channels); self.irc_config.contacts.extend(new_config.contacts); - self.irc_config.password = new_config.password; + self.irc_config.pass = new_config.pass; if self.on_receive_join(self.irc_config.channels.keys().cloned().collect()).await.is_err() { warn!("Error to join updated channels"); @@ -253,7 +253,7 @@ impl IrcClient { { debug!("Initializing peer connection"); let register_reply = - format!(":darkfi 001 {} :Let there be dark\r\n", self.irc_config.nickname); + format!(":darkfi 001 {} :Let there be dark\r\n", self.irc_config.nick); self.reply(®ister_reply).await?; self.irc_config.is_registered = true; @@ -288,8 +288,8 @@ impl IrcClient { Ok(()) } - async fn on_receive_pass(&mut self, password: &str) -> Result<()> { - if self.irc_config.password == password { + async fn on_receive_pass(&mut self, pass: &str) -> Result<()> { + if self.irc_config.pass == pass { self.irc_config.is_pass_init = true } else { // Close the connection @@ -336,28 +336,20 @@ impl IrcClient { let chan_info = self.irc_config.channels.get_mut(channel).unwrap(); chan_info.topic = Some(topic.to_string()); - let topic_reply = format!( - ":{}!anon@dark.fi TOPIC {} :{}\r\n", - self.irc_config.nickname, channel, topic - ); + let topic_reply = + format!(":{}!anon@dark.fi TOPIC {} :{}\r\n", self.irc_config.nick, channel, topic); self.reply(&topic_reply).await?; } else { // Client is asking or the topic let chan_info = self.irc_config.channels.get(channel).unwrap(); let topic_reply = if let Some(topic) = &chan_info.topic { - format!( - "{} {} {} :{}\r\n", - RPL::Topic as u32, - self.irc_config.nickname, - channel, - topic - ) + format!("{} {} {} :{}\r\n", RPL::Topic as u32, self.irc_config.nick, channel, topic) } else { const TOPIC: &str = "No topic is set"; format!( "{} {} {} :{}\r\n", RPL::NoTopic as u32, - self.irc_config.nickname, + self.irc_config.nick, channel, TOPIC ) @@ -375,14 +367,14 @@ impl IrcClient { async fn on_receive_cap(&mut self, line: &str, subcommand: &str) -> Result<()> { self.irc_config.is_cap_end = false; - let capabilities_keys: Vec = self.irc_config.capabilities.keys().cloned().collect(); + let caps_keys: Vec = self.irc_config.caps.keys().cloned().collect(); match subcommand { "LS" => { let cap_ls_reply = format!( ":{}!anon@dark.fi CAP * LS :{}\r\n", - self.irc_config.nickname, - capabilities_keys.join(" ") + self.irc_config.nick, + caps_keys.join(" ") ); self.reply(&cap_ls_reply).await?; } @@ -400,8 +392,8 @@ impl IrcClient { let mut nak_list = vec![]; for c in cap { - if self.irc_config.capabilities.contains_key(c) { - self.irc_config.capabilities.insert(c.to_string(), true); + if self.irc_config.caps.contains_key(c) { + self.irc_config.caps.insert(c.to_string(), true); ack_list.push(c); } else { nak_list.push(c); @@ -410,13 +402,13 @@ impl IrcClient { let cap_ack_reply = format!( ":{}!anon@dark.fi CAP * ACK :{}\r\n", - self.irc_config.nickname, + self.irc_config.nick, ack_list.join(" ") ); let cap_nak_reply = format!( ":{}!anon@dark.fi CAP * NAK :{}\r\n", - self.irc_config.nickname, + self.irc_config.nick, nak_list.join(" ") ); @@ -425,9 +417,9 @@ impl IrcClient { } "LIST" => { - let enabled_capabilities: Vec = self + let enabled_caps: Vec = self .irc_config - .capabilities + .caps .clone() .into_iter() .filter(|(_, v)| *v) @@ -436,8 +428,8 @@ impl IrcClient { let cap_list_reply = format!( ":{}!anon@dark.fi CAP * LIST :{}\r\n", - self.irc_config.nickname, - enabled_capabilities.join(" ") + self.irc_config.nick, + enabled_caps.join(" ") ); self.reply(&cap_list_reply).await?; } @@ -464,7 +456,7 @@ impl IrcClient { let names_reply = format!( ":{}!anon@dark.fi {} = {} : {}\r\n", - self.irc_config.nickname, + self.irc_config.nick, RPL::NameReply as u32, chan, chan_info.names() @@ -475,7 +467,7 @@ impl IrcClient { let end_of_names = format!( ":DarkFi {:03} {} {} :End of NAMES list\r\n", RPL::EndOfNames as u32, - self.irc_config.nickname, + self.irc_config.nick, chan ); @@ -498,7 +490,7 @@ impl IrcClient { let mut privmsg = PrivMsgEvent::new(); - privmsg.nick = self.irc_config.nickname.clone(); + privmsg.nick = self.irc_config.nick.clone(); privmsg.target = target.to_string(); privmsg.msg = message.clone(); @@ -541,31 +533,32 @@ impl IrcClient { if !chan.starts_with('#') { continue } + if !self.irc_config.channels.contains_key(chan) { let mut chan_info = ChannelInfo::new()?; chan_info.topic = Some("n/a".to_string()); self.irc_config.channels.insert(chan.to_string(), chan_info); } - let chan_info = self.irc_config.channels.get_mut(chan).unwrap(); - if chan_info.joined { + if !self.channels_joined.insert(chan.to_string()) { return Ok(()) } - chan_info.joined = true; + + let chan_info = self.irc_config.channels.get_mut(chan).unwrap(); let topic = if let Some(topic) = chan_info.topic.clone() { topic } else { "n/a".to_string() }; chan_info.topic = Some(topic.to_string()); { - let j = format!(":{}!anon@dark.fi JOIN {}\r\n", self.irc_config.nickname, chan); + let j = format!(":{}!anon@dark.fi JOIN {}\r\n", self.irc_config.nick, chan); let t = format!(":DarkFi TOPIC {} :{}\r\n", chan, topic); self.reply(&j).await?; self.reply(&t).await?; } } - if *self.irc_config.capabilities.get("no-history").unwrap() { + if *self.irc_config.caps.get("no-history").unwrap() { return Ok(()) } diff --git a/bin/darkirc/src/irc/mod.rs b/bin/darkirc/src/irc/mod.rs index e5320a67b..023892636 100644 --- a/bin/darkirc/src/irc/mod.rs +++ b/bin/darkirc/src/irc/mod.rs @@ -44,9 +44,9 @@ pub struct IrcConfig { pub is_pass_init: bool, // user config - pub nickname: String, - pub password: String, - pub capabilities: HashMap, + pub nick: String, + pub pass: String, + pub caps: HashMap, // channels and contacts pub auto_channels: Vec, @@ -56,7 +56,7 @@ pub struct IrcConfig { impl IrcConfig { pub fn new(settings: &Args) -> Result { - let password = settings.password.as_ref().unwrap_or(&String::new()).clone(); + let pass = settings.password.as_ref().unwrap_or(&String::new()).clone(); let mut auto_channels = settings.autojoin.clone(); auto_channels.retain(|chan| chan.len() <= MAXIMUM_LENGTH_OF_NICK_CHAN_CNT); @@ -67,8 +67,8 @@ impl IrcConfig { let channels = parse_configured_channels(&toml_contents)?; let contacts = parse_configured_contacts(&toml_contents)?; - let mut capabilities = HashMap::new(); - capabilities.insert("no-history".to_string(), false); + let mut caps = HashMap::new(); + caps.insert("no-history".to_string(), false); Ok(Self { is_nick_init: false, @@ -76,12 +76,12 @@ impl IrcConfig { is_registered: false, is_cap_end: true, is_pass_init: false, - nickname: "anon".to_string(), - password, + nick: "anon".to_string(), + pass, auto_channels, channels, contacts, - capabilities, + caps, }) } } diff --git a/bin/darkirc/src/main.rs b/bin/darkirc/src/main.rs index 63d0d4fe0..e47d4c8cc 100644 --- a/bin/darkirc/src/main.rs +++ b/bin/darkirc/src/main.rs @@ -57,6 +57,41 @@ use crate::{ settings::{Args, ChannelInfo, CONFIG_FILE, CONFIG_FILE_CONTENTS}, }; +async fn parse_signals( + sighup_sub: SubscriberPtr, + client_sub: SubscriberPtr, +) -> Result<()> { + debug!("Started signal parsing handler"); + let subscription = sighup_sub.subscribe().await; + loop { + let args = subscription.receive().await; + let new_config = IrcConfig::new(&args)?; + client_sub.notify(ClientSubMsg::Config(new_config)).await; + } +} + +async fn reset_root(model: ModelPtr) { + loop { + let now = Utc::now(); + + // clocks are valid, safe to unwrap + let next_midnight = (now + Duration::days(1)).date_naive().and_hms_opt(0, 0, 0).unwrap(); + + let duration = next_midnight.signed_duration_since(now.naive_utc()).to_std().unwrap(); + + // make sure the root is the same as everyone else's at + // startup by passing today's date 00:00 AM UTC as + // timestamp to root_event + let now_datetime = now.date_naive().and_hms_opt(0, 0, 0).unwrap(); + let timestamp = now_datetime.timestamp() as u64; + + model.lock().await.reset_root(Timestamp(timestamp)); + + sleep(duration.as_secs()).await; + info!("Resetting root"); + } +} + async_daemonize!(realmain); async fn realmain(settings: Args, executor: Arc>) -> Result<()> { // Signal handling for config reload and graceful termination. @@ -168,38 +203,3 @@ async fn realmain(settings: Args, executor: Arc>) -> Result<( p2p2.stop().await; Ok(()) } - -async fn parse_signals( - sighup_sub: SubscriberPtr, - client_sub: SubscriberPtr, -) -> Result<()> { - debug!("Started signal parsing handler"); - let subscription = sighup_sub.subscribe().await; - loop { - let args = subscription.receive().await; - let new_config = IrcConfig::new(&args)?; - client_sub.notify(ClientSubMsg::Config(new_config)).await; - } -} - -async fn reset_root(model: ModelPtr) { - loop { - let now = Utc::now(); - - // clocks are valid, safe to unwrap - let next_midnight = (now + Duration::days(1)).date_naive().and_hms_opt(0, 0, 0).unwrap(); - - let duration = next_midnight.signed_duration_since(now.naive_utc()).to_std().unwrap(); - - // make sure the root is the same as everyone else's at - // startup by passing today's date 00:00 AM UTC as - // timestamp to root_event - let now_datetime = now.date_naive().and_hms_opt(0, 0, 0).unwrap(); - let timestamp = now_datetime.timestamp() as u64; - - model.lock().await.reset_root(Timestamp(timestamp)); - - sleep(duration.as_secs()).await; - info!("Resetting root"); - } -}