On Tue, Mar 24, 2015 at 3:24 PM, Zbigniew Jędrzejewski-Szmek <zbys...@in.waw.pl> wrote: > On Tue, Mar 24, 2015 at 07:04:11AM -0700, Kay Sievers wrote: >> Makefile.am | 2 >> src/shared/time-dst.c | 329 >> --------------------------------------------- >> src/shared/time-dst.h | 26 --- >> src/timedate/timedatectl.c | 56 ------- >> 4 files changed, 413 deletions(-) >> >> New commits: >> commit 16c6ea29348ddac73998f339166f863bee0dfef6 >> Author: Kay Sievers <k...@vrfy.org> >> Date: Tue Mar 24 13:52:04 2015 +0100 >> >> timedate: remove daylight saving time handling and tzfile parser >> >> We planned to support (the conceptually broken) daylight saving >> time/local time features in the kernel, SCSI, networking, FAT >> filesystem, but it turned out to be a race we cannot win and do >> not want to get involved. Systemd should not fiddle with daylight >> saving time or parse timezone information itself. >> >> Leave everything to glibc or tools like date(1) and do not make any >> promises or raise expectations that systemd should handle anything >> like this. > > That just doesn't make sense. This was *extremely* useful functionality.
Yeah, made me cry to see it go. However, I must admit I'm convinced by the argument that this really does not belong in timedatectl. Going down that road we could have displayed a ton of similar more-or-less useful information, but that really is not the job of such a low-level tool. >> >> diff --git a/Makefile.am b/Makefile.am >> index 29cfec5..93fdbc2 100644 >> --- a/Makefile.am >> +++ b/Makefile.am >> @@ -843,8 +843,6 @@ libsystemd_shared_la_SOURCES = \ >> src/shared/spawn-polkit-agent.h \ >> src/shared/clock-util.c \ >> src/shared/clock-util.h \ >> - src/shared/time-dst.c \ >> - src/shared/time-dst.h \ >> src/shared/calendarspec.c \ >> src/shared/calendarspec.h \ >> src/shared/fileio.c \ >> diff --git a/src/shared/time-dst.c b/src/shared/time-dst.c >> deleted file mode 100644 >> index 2797d1a..0000000 >> --- a/src/shared/time-dst.c >> +++ /dev/null >> @@ -1,329 +0,0 @@ >> -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ >> - >> -/*** >> - This file is part of systemd. >> - >> - Timezone file reading code from glibc 2.16. >> - >> - Copyright (C) 1991-2012 Free Software Foundation, Inc. >> - Copyright 2012 Kay Sievers >> - >> - systemd is free software; you can redistribute it and/or modify it >> - under the terms of the GNU Lesser General Public License as published by >> - the Free Software Foundation; either version 2.1 of the License, or >> - (at your option) any later version. >> - >> - systemd is distributed in the hope that it will be useful, but >> - WITHOUT ANY WARRANTY; without even the implied warranty of >> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> - Lesser General Public License for more details. >> - >> - You should have received a copy of the GNU Lesser General Public License >> - along with systemd; If not, see <http://www.gnu.org/licenses/>. >> -***/ >> -#include <errno.h> >> -#include <stddef.h> >> -#include <stdio.h> >> -#include <string.h> >> -#include <time.h> >> -#include <endian.h> >> -#include <stdint.h> >> -#include <stdbool.h> >> -#include <sys/stat.h> >> - >> -#include "time-dst.h" >> -#include "util.h" >> - >> -/* >> - * If tzh_version is '2' or greater, the above is followed by a second >> instance >> - * of tzhead and a second instance of the data in which each coded >> transition >> - * time uses 8 rather than 4 chars, then a >> POSIX-TZ-environment-variable-style >> - * string for use in handling instants after the last transition time >> stored in >> - * the file * (with nothing between the newlines if there is no POSIX >> - * representation for such instants). >> - */ >> -#define TZ_MAGIC "TZif" >> -struct tzhead { >> - char tzh_magic[4]; /* TZ_MAGIC */ >> - char tzh_version[1]; /* '\0' or '2' as of 2005 */ >> - char tzh_reserved[15]; /* reserved--must be zero */ >> - char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */ >> - char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ >> - char tzh_leapcnt[4]; /* coded number of leap seconds */ >> - char tzh_timecnt[4]; /* coded number of transition times */ >> - char tzh_typecnt[4]; /* coded number of local time types */ >> - char tzh_charcnt[4]; /* coded number of abbr. chars */ >> -}; >> - >> -struct ttinfo { >> - long int offset; /* Seconds east of GMT. */ >> - unsigned char isdst; /* Used to set tm_isdst. */ >> - unsigned char idx; /* Index into `zone_names'. */ >> - unsigned char isstd; /* Transition times are in standard time. >> */ >> - unsigned char isgmt; /* Transition times are in GMT. */ >> -}; >> - >> -struct leap { >> - time_t transition; /* Time the transition takes effect. */ >> - long int change; /* Seconds of correction to apply. */ >> -}; >> - >> -static inline int decode(const void *ptr) { >> - return be32toh(*(int *)ptr); >> -} >> - >> -static inline int64_t decode64(const void *ptr) { >> - return be64toh(*(int64_t *)ptr); >> -} >> - >> -int time_get_dst(time_t date, const char *tzfile, >> - time_t *switch_cur, char **zone_cur, bool *dst_cur, >> - time_t *switch_next, int *delta_next, char **zone_next, >> bool *dst_next) { >> - unsigned char *type_idxs = 0; >> - size_t num_types = 0; >> - struct ttinfo *types = NULL; >> - char *zone_names = NULL; >> - struct stat st; >> - size_t num_isstd, num_isgmt; >> - struct tzhead tzhead; >> - size_t chars; >> - size_t i; >> - size_t total_size; >> - size_t types_idx; >> - int trans_width = 4; >> - size_t tzspec_len; >> - size_t num_leaps; >> - size_t lo, hi; >> - size_t num_transitions = 0; >> - _cleanup_free_ time_t *transitions = NULL; >> - _cleanup_fclose_ FILE *f; >> - >> - f = fopen(tzfile, "re"); >> - if (f == NULL) >> - return -errno; >> - >> - if (fstat(fileno(f), &st) < 0) >> - return -errno; >> - >> -read_again: >> - if (fread((void *)&tzhead, sizeof(tzhead), 1, f) != 1 || >> - memcmp(tzhead.tzh_magic, TZ_MAGIC, sizeof(tzhead.tzh_magic)) != >> 0) >> - return -EINVAL; >> - >> - num_transitions = (size_t)decode(tzhead.tzh_timecnt); >> - num_types = (size_t)decode(tzhead.tzh_typecnt); >> - chars = (size_t)decode(tzhead.tzh_charcnt); >> - num_leaps = (size_t)decode(tzhead.tzh_leapcnt); >> - num_isstd = (size_t)decode(tzhead.tzh_ttisstdcnt); >> - num_isgmt = (size_t)decode(tzhead.tzh_ttisgmtcnt); >> - >> - /* For platforms with 64-bit time_t we use the new format if >> available. */ >> - if (sizeof(time_t) == 8 && trans_width == 4 && >> tzhead.tzh_version[0] != '\0') { >> - size_t to_skip; >> - >> - /* We use the 8-byte format. */ >> - trans_width = 8; >> - >> - /* Position the stream before the second header. */ >> - to_skip = (num_transitions * (4 + 1) >> - + num_types * 6 >> - + chars >> - + num_leaps * 8 + num_isstd + num_isgmt); >> - if (fseek(f, to_skip, SEEK_CUR) != 0) >> - return -EINVAL; >> - >> - goto read_again; >> - } >> - >> - if (num_transitions > ((SIZE_MAX - (__alignof__(struct ttinfo) - >> 1)) / (sizeof(time_t) + 1))) >> - return -EINVAL; >> - >> - total_size = num_transitions * (sizeof(time_t) + 1); >> - total_size = ((total_size + __alignof__(struct ttinfo) - 1) & >> ~(__alignof__(struct ttinfo) - 1)); >> - types_idx = total_size; >> - if (num_leaps > (SIZE_MAX - total_size) / sizeof(struct ttinfo)) >> - return -EINVAL; >> - >> - total_size += num_types * sizeof(struct ttinfo); >> - if (chars > SIZE_MAX - total_size) >> - return -EINVAL; >> - >> - total_size += chars; >> - if (__alignof__(struct leap) - 1 > SIZE_MAX - total_size) >> - return -EINVAL; >> - >> - total_size = ((total_size + __alignof__(struct leap) - 1) & >> ~(__alignof__(struct leap) - 1)); >> - if (num_leaps > (SIZE_MAX - total_size) / sizeof(struct leap)) >> - return -EINVAL; >> - >> - total_size += num_leaps * sizeof(struct leap); >> - tzspec_len = 0; >> - if (sizeof(time_t) == 8 && trans_width == 8) { >> - off_t rem = st.st_size - ftello(f); >> - >> - if (rem < 0 || (size_t) rem < (num_transitions * (8 + 1) + >> num_types * 6 + chars)) >> - return -EINVAL; >> - tzspec_len = (size_t) rem - (num_transitions * (8 + 1) + >> num_types * 6 + chars); >> - if (num_leaps > SIZE_MAX / 12 || tzspec_len < num_leaps * >> 12) >> - return -EINVAL; >> - tzspec_len -= num_leaps * 12; >> - if (tzspec_len < num_isstd) >> - return -EINVAL; >> - tzspec_len -= num_isstd; >> - if (tzspec_len == 0 || tzspec_len - 1 < num_isgmt) >> - return -EINVAL; >> - tzspec_len -= num_isgmt + 1; >> - if (SIZE_MAX - total_size < tzspec_len) >> - return -EINVAL; >> - } >> - >> - /* leave space for additional zone_names zero terminator */ >> - transitions = malloc0(total_size + tzspec_len + 1); >> - if (transitions == NULL) >> - return -EINVAL; >> - >> - type_idxs = (unsigned char *)transitions + (num_transitions >> - * sizeof(time_t)); >> - types = (struct ttinfo *)((char *)transitions + types_idx); >> - zone_names = (char *)types + num_types * sizeof(struct ttinfo); >> - >> - if (sizeof(time_t) == 4 || trans_width == 8) { >> - if (fread(transitions, trans_width + 1, num_transitions, f) >> != num_transitions) >> - return -EINVAL; >> - } else { >> - if (fread(transitions, 4, num_transitions, f) != >> num_transitions || >> - fread(type_idxs, 1, num_transitions, f) != >> num_transitions) >> - return -EINVAL; >> - } >> - >> - /* Check for bogus indices in the data file, so we can hereafter >> - safely use type_idxs[T] as indices into `types' and never crash. >> */ >> - for (i = 0; i < num_transitions; ++i) >> - if (type_idxs[i] >= num_types) >> - return -EINVAL; >> - >> - if (__BYTE_ORDER == __BIG_ENDIAN ? sizeof(time_t) == 8 && >> trans_width == 4 >> - : sizeof(time_t) == 4 || >> trans_width == 4) { >> - /* Decode the transition times, stored as 4-byte integers in >> - network (big-endian) byte order. We work from the end of >> - the array so as not to clobber the next element to be >> - processed when sizeof (time_t) > 4. */ >> - i = num_transitions; >> - while (i-- > 0) >> - transitions[i] = decode((char *)transitions + i * >> 4); >> - } else if (__BYTE_ORDER != __BIG_ENDIAN && sizeof(time_t) == 8) { >> - /* Decode the transition times, stored as 8-byte integers in >> - network (big-endian) byte order. */ >> - for (i = 0; i < num_transitions; ++i) >> - transitions[i] = decode64((char *)transitions + i * >> 8); >> - } >> - >> - for (i = 0; i < num_types; ++i) { >> - unsigned char x[4]; >> - int c; >> - >> - if (fread(x, 1, sizeof(x), f) != sizeof(x)) >> - return -EINVAL; >> - c = getc(f); >> - if ((unsigned int)c > 1u) >> - return -EINVAL; >> - types[i].isdst = c; >> - c = getc(f); >> - if ((size_t) c > chars) >> - /* Bogus index in data file. */ >> - return -EINVAL; >> - types[i].idx = c; >> - types[i].offset = (long int)decode(x); >> - } >> - >> - if (fread(zone_names, 1, chars, f) != chars) >> - return -EINVAL; >> - >> - zone_names[chars] = '\0'; >> - >> - for (i = 0; i < num_isstd; ++i) { >> - int c = getc(f); >> - if (c == EOF) >> - return -EINVAL; >> - types[i].isstd = c != 0; >> - } >> - >> - while (i < num_types) >> - types[i++].isstd = 0; >> - >> - for (i = 0; i < num_isgmt; ++i) { >> - int c = getc(f); >> - if (c == EOF) >> - return -EINVAL; >> - types[i].isgmt = c != 0; >> - } >> - >> - while (i < num_types) >> - types[i++].isgmt = 0; >> - >> - if (num_transitions == 0) >> - return -EINVAL; >> - >> - if (date < transitions[0] || date >= transitions[num_transitions - >> 1]) >> - return -EINVAL; >> - >> - /* Find the first transition after TIMER, and >> - then pick the type of the transition before it. */ >> - lo = 0; >> - hi = num_transitions - 1; >> - >> - /* Assume that DST is changing twice a year and guess initial >> - search spot from it. >> - Half of a gregorian year has on average 365.2425 * 86400 / 2 >> - = 15778476 seconds. */ >> - i = (transitions[num_transitions - 1] - date) / 15778476; >> - if (i < num_transitions) { >> - i = num_transitions - 1 - i; >> - if (date < transitions[i]) { >> - if (i < 10 || date >= transitions[i - 10]) { >> - /* Linear search. */ >> - while (date < transitions[i - 1]) >> - i--; >> - goto found; >> - } >> - hi = i - 10; >> - } else { >> - if (i + 10 >= num_transitions || date < >> transitions[i + 10]) { >> - /* Linear search. */ >> - while (date >= transitions[i]) >> - i++; >> - goto found; >> - } >> - lo = i + 10; >> - } >> - } >> - >> - /* Binary search. */ >> - while (lo + 1 < hi) { >> - i = (lo + hi) / 2; >> - if (date < transitions[i]) >> - hi = i; >> - else >> - lo = i; >> - } >> - i = hi; >> - >> -found: >> - if (switch_cur) >> - *switch_cur = transitions[i-1]; >> - if (zone_cur) >> - *zone_cur = strdup(&zone_names[types[type_idxs[i - >> 1]].idx]); >> - if (dst_cur) >> - *dst_cur = types[type_idxs[i-1]].isdst; >> - >> - if (switch_next) >> - *switch_next = transitions[i]; >> - if (delta_next) >> - *delta_next = (types[type_idxs[i]].offset - >> types[type_idxs[i-1]].offset) / 60; >> - if (zone_next) >> - *zone_next = strdup(&zone_names[types[type_idxs[i]].idx]); >> - if (dst_next) >> - *dst_next = types[type_idxs[i]].isdst; >> - >> - return 0; >> -} >> diff --git a/src/shared/time-dst.h b/src/shared/time-dst.h >> deleted file mode 100644 >> index 536b6bb..0000000 >> --- a/src/shared/time-dst.h >> +++ /dev/null >> @@ -1,26 +0,0 @@ >> -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ >> - >> -#pragma once >> - >> -/*** >> - This file is part of systemd. >> - >> - Copyright 2012 Kay Sievers >> - >> - systemd is free software; you can redistribute it and/or modify it >> - under the terms of the GNU Lesser General Public License as published by >> - the Free Software Foundation; either version 2.1 of the License, or >> - (at your option) any later version. >> - >> - systemd is distributed in the hope that it will be useful, but >> - WITHOUT ANY WARRANTY; without even the implied warranty of >> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> - Lesser General Public License for more details. >> - >> - You should have received a copy of the GNU Lesser General Public License >> - along with systemd; If not, see <http://www.gnu.org/licenses/>. >> -***/ >> - >> -int time_get_dst(time_t date, const char *tzfile, >> - time_t *switch_cur, char **zone_cur, bool *dst_cur, >> - time_t *switch_next, int *delta_next, char **zone_next, >> bool *dst_next); >> diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c >> index 44d329e..ab5c8a1 100644 >> --- a/src/timedate/timedatectl.c >> +++ b/src/timedate/timedatectl.c >> @@ -33,7 +33,6 @@ >> #include "build.h" >> #include "strv.h" >> #include "pager.h" >> -#include "time-dst.h" >> >> static bool arg_no_pager = false; >> static bool arg_ask_password = true; >> @@ -73,33 +72,12 @@ typedef struct StatusInfo { >> bool ntp_synced; >> } StatusInfo; >> >> -static const char *jump_str(int delta_minutes, char *s, size_t size) { >> - if (delta_minutes == 60) >> - return "one hour forward"; >> - if (delta_minutes == -60) >> - return "one hour backwards"; >> - if (delta_minutes < 0) { >> - snprintf(s, size, "%i minutes backwards", -delta_minutes); >> - return s; >> - } >> - if (delta_minutes > 0) { >> - snprintf(s, size, "%i minutes forward", delta_minutes); >> - return s; >> - } >> - return ""; >> -} >> - >> static void print_status_info(const StatusInfo *i) { >> char a[FORMAT_TIMESTAMP_MAX]; >> - char b[FORMAT_TIMESTAMP_MAX]; >> - char s[32]; >> struct tm tm; >> time_t sec; >> bool have_time = false; >> _cleanup_free_ char *zc = NULL, *zn = NULL; >> - time_t t, tc, tn; >> - int dn = 0; >> - bool is_dstc = false, is_dstn = false; >> int r; >> >> assert(i); >> @@ -158,40 +136,6 @@ static void print_status_info(const StatusInfo *i) { >> yes_no(i->ntp_synced), >> yes_no(i->rtc_local)); >> >> - if (have_time) { >> - r = time_get_dst(sec, "/etc/localtime", >> - &tc, &zc, &is_dstc, >> - &tn, &dn, &zn, &is_dstn); >> - if (r < 0) >> - printf(" DST active: %s\n", "n/a"); >> - else { >> - printf(" DST active: %s\n", yes_no(is_dstc)); >> - >> - t = tc - 1; >> - xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", >> localtime_r(&t, &tm)); >> - >> - xstrftime(b, "%a %Y-%m-%d %H:%M:%S %Z", >> localtime_r(&tc, &tm)); >> - printf(" Last DST change: DST %s at\n" >> - " %.*s\n" >> - " %.*s\n", >> - is_dstc ? "began" : "ended", >> - (int) sizeof(a), a, >> - (int) sizeof(b), b); >> - >> - t = tn - 1; >> - xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", >> localtime_r(&t, &tm)); >> - xstrftime(b, "%a %Y-%m-%d %H:%M:%S %Z", >> localtime_r(&tn, &tm)); >> - printf(" Next DST change: DST %s (the clock jumps >> %s) at\n" >> - " %.*s\n" >> - " %.*s\n", >> - is_dstn ? "begins" : "ends", >> - jump_str(dn, s, sizeof(s)), >> - (int) sizeof(a), a, >> - (int) sizeof(b), b); >> - } >> - } else >> - printf(" DST active: %s\n", yes_no(is_dstc)); >> - >> if (i->rtc_local) >> fputs("\n" ANSI_HIGHLIGHT_ON >> "Warning: The system is configured to read the RTC >> time in the local time zone. This\n" >> >> _______________________________________________ >> systemd-commits mailing list >> systemd-comm...@lists.freedesktop.org >> http://lists.freedesktop.org/mailman/listinfo/systemd-commits > _______________________________________________ > systemd-devel mailing list > systemd-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/systemd-devel _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel