mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 16:37:19 +09:00
time-util: add variant of timezone_is_valid() that returns errno
This will be useful for tests to skip missing time zones.
This commit is contained in:
@@ -1381,7 +1381,7 @@ int get_timezones(char ***ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool timezone_is_valid(const char *name, int log_level) {
|
||||
int verify_timezone(const char *name, int log_level) {
|
||||
bool slash = false;
|
||||
const char *p, *t;
|
||||
_cleanup_close_ int fd = -1;
|
||||
@@ -1389,26 +1389,26 @@ bool timezone_is_valid(const char *name, int log_level) {
|
||||
int r;
|
||||
|
||||
if (isempty(name))
|
||||
return false;
|
||||
return -EINVAL;
|
||||
|
||||
/* Always accept "UTC" as valid timezone, since it's the fallback, even if user has no timezones installed. */
|
||||
if (streq(name, "UTC"))
|
||||
return true;
|
||||
return 0;
|
||||
|
||||
if (name[0] == '/')
|
||||
return false;
|
||||
return -EINVAL;
|
||||
|
||||
for (p = name; *p; p++) {
|
||||
if (!(*p >= '0' && *p <= '9') &&
|
||||
!(*p >= 'a' && *p <= 'z') &&
|
||||
!(*p >= 'A' && *p <= 'Z') &&
|
||||
!IN_SET(*p, '-', '_', '+', '/'))
|
||||
return false;
|
||||
return -EINVAL;
|
||||
|
||||
if (*p == '/') {
|
||||
|
||||
if (slash)
|
||||
return false;
|
||||
return -EINVAL;
|
||||
|
||||
slash = true;
|
||||
} else
|
||||
@@ -1416,38 +1416,31 @@ bool timezone_is_valid(const char *name, int log_level) {
|
||||
}
|
||||
|
||||
if (slash)
|
||||
return false;
|
||||
return -EINVAL;
|
||||
|
||||
if (p - name >= PATH_MAX)
|
||||
return false;
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
t = strjoina("/usr/share/zoneinfo/", name);
|
||||
|
||||
fd = open(t, O_RDONLY|O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
log_full_errno(log_level, errno, "Failed to open timezone file '%s': %m", t);
|
||||
return false;
|
||||
}
|
||||
if (fd < 0)
|
||||
return log_full_errno(log_level, errno, "Failed to open timezone file '%s': %m", t);
|
||||
|
||||
r = fd_verify_regular(fd);
|
||||
if (r < 0) {
|
||||
log_full_errno(log_level, r, "Timezone file '%s' is not a regular file: %m", t);
|
||||
return false;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_full_errno(log_level, r, "Timezone file '%s' is not a regular file: %m", t);
|
||||
|
||||
r = loop_read_exact(fd, buf, 4, false);
|
||||
if (r < 0) {
|
||||
log_full_errno(log_level, r, "Failed to read from timezone file '%s': %m", t);
|
||||
return false;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_full_errno(log_level, r, "Failed to read from timezone file '%s': %m", t);
|
||||
|
||||
/* Magic from tzfile(5) */
|
||||
if (memcmp(buf, "TZif", 4) != 0) {
|
||||
log_full(log_level, "Timezone file '%s' has wrong magic bytes", t);
|
||||
return false;
|
||||
}
|
||||
if (memcmp(buf, "TZif", 4) != 0)
|
||||
return log_full_errno(log_level, SYNTHETIC_ERRNO(EIO),
|
||||
"Timezone file '%s' has wrong magic bytes", t);
|
||||
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool clock_boottime_supported(void) {
|
||||
|
||||
@@ -134,7 +134,10 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit);
|
||||
int parse_nsec(const char *t, nsec_t *nsec);
|
||||
|
||||
int get_timezones(char ***l);
|
||||
bool timezone_is_valid(const char *name, int log_level);
|
||||
int verify_timezone(const char *name, int log_level);
|
||||
static inline bool timezone_is_valid(const char *name, int log_level) {
|
||||
return verify_timezone(name, log_level) >= 0;
|
||||
}
|
||||
|
||||
bool clock_boottime_supported(void);
|
||||
bool clock_supported(clockid_t clock);
|
||||
|
||||
Reference in New Issue
Block a user