1 use std
::mem
::{self, MaybeUninit}
;
3 use chrono
::prelude
::*;
5 use serde_json
::{json, Value}
;
7 use proxmox
::api
::{api, Router, Permission}
;
8 use proxmox
::tools
::fs
::{file_read_firstline, replace_file, CreateOptions}
;
10 use crate::api2
::types
::*;
12 fn read_etc_localtime() -> Result
<String
, Error
> {
14 if let Ok(line
) = file_read_firstline("/etc/timezone") {
15 return Ok(line
.trim().to_owned());
18 // otherwise guess from the /etc/localtime symlink
19 let mut buf
= MaybeUninit
::<[u8; 64]>::uninit();
22 "/etc/localtime".as_ptr() as *const _
,
23 buf
.as_mut_ptr() as *mut _
,
24 mem
::size_of_val(&buf
),
28 bail
!("failed to guess timezone");
30 let len
= len
as usize;
32 (*buf
.as_mut_ptr())[len
] = 0;
35 let link
= std
::str::from_utf8(&buf
[..len
])?
;
36 match link
.rfind("/zoneinfo/") {
37 Some(pos
) => Ok(link
[(pos
+ 10)..].to_string()),
38 None
=> Ok(link
.to_string()),
51 description
: "Returns server time and timezone.",
54 schema
: TIME_ZONE_SCHEMA
,
58 description
: "Seconds since 1970-01-01 00:00:00 UTC.",
59 minimum
: 1_297_163_644,
63 description
: "Seconds since 1970-01-01 00:00:00 UTC. (local time)",
64 minimum
: 1_297_163_644,
69 permission
: &Permission
::Anybody
,
72 /// Read server time and time zone settings.
73 fn get_time(_param
: Value
) -> Result
<Value
, Error
> {
74 let datetime
= Local
::now();
75 let offset
= datetime
.offset();
76 let time
= datetime
.timestamp();
77 let localtime
= time
+ (offset
.fix().local_minus_utc() as i64);
80 "timezone": read_etc_localtime()?
,
82 "localtime": localtime
,
88 reload_timezone
: true,
95 schema
: TIME_ZONE_SCHEMA
,
104 ) -> Result
<Value
, Error
> {
105 let path
= std
::path
::PathBuf
::from(format
!("/usr/share/zoneinfo/{}", timezone
));
108 bail
!("No such timezone.");
111 replace_file("/etc/timezone", timezone
.as_bytes(), CreateOptions
::new())?
;
113 let _
= std
::fs
::remove_file("/etc/localtime");
115 use std
::os
::unix
::fs
::symlink
;
116 symlink(path
, "/etc/localtime")?
;
121 pub const ROUTER
: Router
= Router
::new()
122 .get(&API_METHOD_GET_TIME
)
123 .put(&API_METHOD_SET_TIMEZONE
);