From 321db52148fe06954716ed39506933b4609ea53e Mon Sep 17 00:00:00 2001 From: catte Date: Wed, 22 May 2024 18:29:35 -0400 Subject: [PATCH 1/3] Include commit date in NetworkNode metadata not provided by built, so it needs to be retrieved manually --- Cargo.lock | 121 +++++++++++++++++++++--------- sable_network/Cargo.toml | 2 + sable_network/build.rs | 42 +++++++++++ sable_network/src/node/mod.rs | 13 ++++ sable_network/src/node/upgrade.rs | 1 + 5 files changed, 142 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca3b0a6c..e40d9965 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -110,7 +110,7 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time 0.3.36", + "time", ] [[package]] @@ -434,18 +434,17 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", - "time 0.1.45", "wasm-bindgen", - "winapi", + "windows-targets 0.52.5", ] [[package]] @@ -955,7 +954,7 @@ checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -1497,7 +1496,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys", ] @@ -1696,7 +1695,7 @@ dependencies = [ "libc", "redox_syscall 0.3.5", "smallvec", - "windows-targets", + "windows-targets 0.48.1", ] [[package]] @@ -2139,6 +2138,7 @@ dependencies = [ "chrono", "concurrent_log", "futures", + "git2", "hashers", "hex", "ipnet", @@ -2306,7 +2306,7 @@ dependencies = [ "serde", "serde_json", "serde_with_macros 2.3.3", - "time 0.3.36", + "time", ] [[package]] @@ -2600,17 +2600,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - [[package]] name = "time" version = "0.3.36" @@ -2837,7 +2826,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e" dependencies = [ "crossbeam-channel", - "time 0.3.36", + "time", "tracing-subscriber", ] @@ -3043,12 +3032,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -3169,7 +3152,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets", + "windows-targets 0.48.1", ] [[package]] @@ -3178,7 +3161,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.1", ] [[package]] @@ -3187,13 +3170,29 @@ version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -3202,42 +3201,90 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + [[package]] name = "windows_aarch64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + [[package]] name = "windows_i686_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + [[package]] name = "windows_i686_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + [[package]] name = "windows_x86_64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + [[package]] name = "winreg" version = "0.6.2" @@ -3262,7 +3309,7 @@ dependencies = [ "oid-registry", "rusticata-macros", "thiserror", - "time 0.3.36", + "time", ] [[package]] diff --git a/sable_network/Cargo.toml b/sable_network/Cargo.toml index 83c1083a..d43e7a49 100644 --- a/sable_network/Cargo.toml +++ b/sable_network/Cargo.toml @@ -11,6 +11,8 @@ debug = [] [build-dependencies] built = { version = "0.5", features = [ "git2" ] } +git2 = { version = "0.15", default-features = false } +chrono = "0.4" [dev-dependencies] tracing-subscriber = "0.3" diff --git a/sable_network/build.rs b/sable_network/build.rs index d8f91cb9..01398413 100644 --- a/sable_network/build.rs +++ b/sable_network/build.rs @@ -1,3 +1,45 @@ +use std::{env, fs, io::Write, path}; + +use chrono::DateTime; + fn main() { built::write_built_file().expect("Failed to acquire build-time information"); + + let root = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR"); + let out = path::Path::new(&env::var("OUT_DIR").expect("OUT_DIR not set")).join("built.rs"); + let _ = write_head_date(root, out); +} + +fn write_head_date(root: String, dest: path::PathBuf) -> Result<(), git2::Error> { + let mut f = fs::OpenOptions::new() + .append(true) + .open(dest) + .expect("could not append to built.rs"); + match git2::Repository::discover(root) { + Ok(repo) => { + let head = repo.head()?.peel_to_commit()?.time(); + let head_secs = head.seconds() + (head.offset_minutes() as i64 * 60); + let head_time = DateTime::from_timestamp(head_secs, 0).map(|dt| dt.to_rfc2822()); + f.write_all( + format!( + "\npub const GIT_COMMIT_TIME_UTC: Option<&str> = {:?};\n", + head_time + ) + .as_bytes(), + ) + .expect("could not write to built.rs"); + Ok(()) + } + Err(ref e) + if e.class() == git2::ErrorClass::Repository + && e.code() == git2::ErrorCode::NotFound => + { + f.write_all( + format!("\npub const GIT_COMMIT_TIME_UTC: Option<&str> = None;\n").as_bytes(), + ) + .expect("could not write to built.rs"); + Ok(()) + } + Err(e) => Err(e), + } } diff --git a/sable_network/src/node/mod.rs b/sable_network/src/node/mod.rs index cbc6f1cf..3d9eef08 100644 --- a/sable_network/src/node/mod.rs +++ b/sable_network/src/node/mod.rs @@ -41,6 +41,7 @@ where my_id: ServerId, name: ServerName, version: String, + commit_date: String, net: RwLock>, event_log: Arc, epoch: EpochId, @@ -90,6 +91,7 @@ impl NetworkNode { my_id: id, name, version: Self::build_version(), + commit_date: Self::get_commit_date(), net: RwLock::new(Arc::new(net)), epoch, event_log, @@ -194,6 +196,17 @@ impl NetworkNode { ) } + /// The server's HEAD commit date + pub fn commit_date(&self) -> &str { + &self.commit_date + } + + fn get_commit_date() -> String { + crate::build_data::GIT_COMMIT_TIME_UTC + .unwrap_or("unknown") + .to_string() + } + /// The server's build flags pub fn server_flags(&self) -> state::ServerFlags { let mut ret = state::ServerFlags::empty(); diff --git a/sable_network/src/node/upgrade.rs b/sable_network/src/node/upgrade.rs index b492847c..cc10b01c 100644 --- a/sable_network/src/node/upgrade.rs +++ b/sable_network/src/node/upgrade.rs @@ -44,6 +44,7 @@ impl NetworkNode { my_id: state.id, name: state.name, version: Self::build_version(), + commit_date: Self::get_commit_date(), net: RwLock::new(Arc::new(state.net)), epoch: state.epoch, id_generator: state.id_generator, From 519bbd98029fda0c9dee359223a6c555d552e6ed Mon Sep 17 00:00:00 2001 From: catte Date: Fri, 24 May 2024 12:23:34 -0400 Subject: [PATCH 2/3] fix deprecations from chrono update --- sable_ircd/src/utils/time_utils.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sable_ircd/src/utils/time_utils.rs b/sable_ircd/src/utils/time_utils.rs index a50f2cdf..f351661f 100644 --- a/sable_ircd/src/utils/time_utils.rs +++ b/sable_ircd/src/utils/time_utils.rs @@ -7,7 +7,7 @@ pub fn format_timestamp(ts: i64) -> String { } pub fn parse_timestamp(str: &str) -> Option { - Utc.datetime_from_str(str, "%+") - .map(|dt| dt.timestamp()) + NaiveDateTime::parse_from_str(str, "%+") + .map(|dt| dt.and_utc().timestamp()) .ok() } From d4cf83fcf729d2fc5358d121449151ee5ffe2b57 Mon Sep 17 00:00:00 2001 From: catte Date: Wed, 22 May 2024 18:31:58 -0400 Subject: [PATCH 3/3] Implement INFO command currently returns: - copyright info - author info - website and irc channel - version - commit datetime --- sable_ircd/info.txt | 16 ++++++++++++++++ sable_ircd/src/command/handlers/info.rs | 19 +++++++++++++++++++ sable_ircd/src/command/mod.rs | 1 + sable_ircd/src/messages/numeric.rs | 3 +++ sable_ircd/src/server/config.rs | 5 +++++ 5 files changed, 44 insertions(+) create mode 100644 sable_ircd/info.txt create mode 100644 sable_ircd/src/command/handlers/info.rs diff --git a/sable_ircd/info.txt b/sable_ircd/info.txt new file mode 100644 index 00000000..9817c34a --- /dev/null +++ b/sable_ircd/info.txt @@ -0,0 +1,16 @@ +Sable -- + +Copyright (c) 2021-2024 Sable Development Team + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Source code is available at: https://github.com/Libera-Chat/sable + +A list of contributors can be found in the git log. + +Visit the Sable website at: https://sable.chat/ +Visit us on IRC at irc.libera.chat #libera-dev + diff --git a/sable_ircd/src/command/handlers/info.rs b/sable_ircd/src/command/handlers/info.rs new file mode 100644 index 00000000..95a28c96 --- /dev/null +++ b/sable_ircd/src/command/handlers/info.rs @@ -0,0 +1,19 @@ +use super::*; + +#[command_handler("INFO")] +/// Syntax: INFO +fn info_handler(response: &dyn CommandResponse, server: &ClientServer) -> CommandResult { + let node = server.node(); + let version = node.version(); + let commit_date = node.commit_date(); + + for line in &server.info_strings.info { + response.numeric(make_numeric!(Info, line)); + } + response.numeric(make_numeric!(Info, &format!("Version: {version}"))); + response.numeric(make_numeric!(Info, &format!("Commit date: {commit_date}"))); + // TODO: send configuration info to opers + // see: https://github.com/solanum-ircd/solanum/blob/main/modules/m_info.c#L788 + response.numeric(make_numeric!(EndOfInfo)); + Ok(()) +} diff --git a/sable_ircd/src/command/mod.rs b/sable_ircd/src/command/mod.rs index eb63bcce..ea9a18ae 100644 --- a/sable_ircd/src/command/mod.rs +++ b/sable_ircd/src/command/mod.rs @@ -42,6 +42,7 @@ mod handlers { mod ban; mod cap; mod chathistory; + mod info; mod invite; mod join; mod kick; diff --git a/sable_ircd/src/messages/numeric.rs b/sable_ircd/src/messages/numeric.rs index 627a6134..aaf41d36 100644 --- a/sable_ircd/src/messages/numeric.rs +++ b/sable_ircd/src/messages/numeric.rs @@ -67,6 +67,9 @@ define_messages! { 381(YoureOper) => { () => "You are now an IRC operator" }, + 371(Info) => { (line: &str) => ":{line}" }, + 374(EndOfInfo) => { () => ":End of /INFO list" }, + 401(NoSuchTarget) => { (unknown: &str) => "{unknown} :No such nick/channel" }, 402(NoSuchServer) => { (server_name: &ServerName) => "{server_name} :No such server" }, diff --git a/sable_ircd/src/server/config.rs b/sable_ircd/src/server/config.rs index 0f32e31b..76fabc63 100644 --- a/sable_ircd/src/server/config.rs +++ b/sable_ircd/src/server/config.rs @@ -30,6 +30,7 @@ pub struct RawClientServerConfig { pub struct ServerInfoStrings { pub motd: Option>, // Linewise to not repeatedly split pub admin_info: Option, + pub info: Vec, } impl ServerInfoStrings { @@ -38,6 +39,10 @@ impl ServerInfoStrings { motd: Self::get_info(&raw_info.motd, "motd")? .map(|file| file.lines().map(|v| v.to_string()).collect()), admin_info: raw_info.admin.clone(), + info: include_str!("../../info.txt") + .lines() + .map(|v| v.to_string()) + .collect(), }) }