[systemd-devel] [systemd-commits] Makefile.am src/shared src/timedate

Tom Gundersen teg at jklm.no
Tue Mar 24 07:31:49 PDT 2015


On Tue, Mar 24, 2015 at 3:24 PM, Zbigniew Jędrzejewski-Szmek
<zbyszek at 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 <kay at 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-commits at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/systemd-commits
> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel


More information about the systemd-devel mailing list