diff --git a/src/api2/node/time.rs b/src/api2/node/time.rs index aab051b1..0d202e2b 100644 --- a/src/api2/node/time.rs +++ b/src/api2/node/time.rs @@ -28,20 +28,54 @@ fn get_time(_param: Value, _info: &ApiMethod) -> Result { })) } +extern "C" { fn tzset(); } + +// Note:: this needs root rights ?? + +fn set_timezone(param: Value, _info: &ApiMethod) -> Result { + + let timezone = tools::required_string_param(¶m, "timezone")?; + + let path = std::path::PathBuf::from(format!("/usr/share/zoneinfo/{}", timezone)); + + if !path.exists() { + bail!("No such timezone."); + } + + tools::file_set_contents("/etc/timezone", timezone.as_bytes(), None); + + let _ = std::fs::remove_file("/etc/localtime"); + + use std::os::unix::fs::symlink; + symlink(path, "/etc/localtime")?; + + unsafe { tzset() }; + + Ok(Value::Null) +} + pub fn router() -> Router { let route = Router::new() .get( ApiMethod::new( - get_time, ObjectSchema::new("Read server time and time zone settings.")) - .returns( - ObjectSchema::new("Returns server time and timezone.") - .required("timezone", StringSchema::new("Time zone")) - .required("time", IntegerSchema::new("Seconds since 1970-01-01 00:00:00 UTC.") - .minimum(1297163644)) - .required("localtime", IntegerSchema::new("Seconds since 1970-01-01 00:00:00 UTC. (local time)") - .minimum(1297163644)) - ) + get_time, + ObjectSchema::new("Read server time and time zone settings.") + ).returns( + ObjectSchema::new("Returns server time and timezone.") + .required("timezone", StringSchema::new("Time zone")) + .required("time", IntegerSchema::new("Seconds since 1970-01-01 00:00:00 UTC.") + .minimum(1297163644)) + .required("localtime", IntegerSchema::new("Seconds since 1970-01-01 00:00:00 UTC. (local time)") + .minimum(1297163644)) + ) + ) + .put( + ApiMethod::new( + set_timezone, + ObjectSchema::new("Set time zone.") + .required("timezone", StringSchema::new("Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names.")) + ) );