Get zone name by stripping */zoneinfo/

This commit is contained in:
K 2022-05-10 10:50:17 +05:00 committed by Scott Lamb
parent 8e8b48b906
commit 0d2cda5c18
1 changed files with 17 additions and 20 deletions

View File

@ -43,18 +43,13 @@ pub struct Args {
// They seem to be correct for Linux and macOS at least. // They seem to be correct for Linux and macOS at least.
const LOCALTIME_PATH: &str = "/etc/localtime"; const LOCALTIME_PATH: &str = "/etc/localtime";
const TIMEZONE_PATH: &str = "/etc/timezone"; const TIMEZONE_PATH: &str = "/etc/timezone";
const ZONEINFO_PATHS: [&str; 2] = [
"/usr/share/zoneinfo/", // Linux, macOS < High Sierra
"/var/db/timezone/zoneinfo/", // macOS High Sierra
];
fn trim_zoneinfo(path: &str) -> &str { // Some well-known zone paths looks like the following:
for zp in &ZONEINFO_PATHS { // /usr/share/zoneinfo/* for Linux and macOS < High Sierra
if let Some(p) = path.strip_prefix(zp) { // /var/db/timezone/zoneinfo/* for macOS High Sierra
return p; // /etc/zoneinfo/* for NixOS
} fn zoneinfo_name(path: &str) -> Option<&str> {
} path.rsplit_once("/zoneinfo/").map(|(_, name)| name)
path
} }
/// Attempt to resolve the timezone of the server. /// Attempt to resolve the timezone of the server.
@ -72,11 +67,14 @@ fn resolve_zone() -> Result<String, Error> {
p = &p[1..]; p = &p[1..];
} }
p = trim_zoneinfo(p); if let Some(p) = zoneinfo_name(p) {
return Ok(p.to_owned());
}
if !p.starts_with('/') { if !p.starts_with('/') {
return Ok(p.to_owned()); return Ok(p.to_owned());
} }
if p != LOCALTIME_PATH { if p != LOCALTIME_PATH {
bail!("Unable to resolve env TZ={} to a timezone.", &tz); bail!("Unable to resolve env TZ={} to a timezone.", &tz);
} }
@ -90,16 +88,15 @@ fn resolve_zone() -> Result<String, Error> {
Some(d) => d, Some(d) => d,
None => bail!("{} symlink destination is invalid UTF-8", LOCALTIME_PATH), None => bail!("{} symlink destination is invalid UTF-8", LOCALTIME_PATH),
}; };
let p = trim_zoneinfo(localtime_dest); if let Some(p) = zoneinfo_name(localtime_dest) {
if p.starts_with('/') { return Ok(p.to_owned());
}
bail!( bail!(
"Unable to resolve {} symlink destination {} to a timezone.", "Unable to resolve {} symlink destination {} to a timezone.",
LOCALTIME_PATH, LOCALTIME_PATH,
&localtime_dest &localtime_dest
); );
} }
return Ok(p.to_owned());
}
Err(e) => { Err(e) => {
use ::std::io::ErrorKind; use ::std::io::ErrorKind;
if e.kind() != ErrorKind::NotFound && e.kind() != ErrorKind::InvalidInput { if e.kind() != ErrorKind::NotFound && e.kind() != ErrorKind::InvalidInput {