dd65c9
From add02d6e5934100f023b45584d0227be90a297e8 Mon Sep 17 00:00:00 2001
dd65c9
From: Jan Synacek <jsynacek@redhat.com>
dd65c9
Date: Thu, 19 Oct 2017 09:53:56 +0200
dd65c9
Subject: [PATCH] timedatectl: stop using xstrftime
dd65c9
MIME-Version: 1.0
dd65c9
Content-Type: text/plain; charset=UTF-8
dd65c9
Content-Transfer-Encoding: 8bit
dd65c9
dd65c9
When using strftime in arbitrary locales, we cannot really say how big the
dd65c9
buffer should be. Let's make the buffer "large", which will work fine pretty
dd65c9
much always, and just print n/a if the timestamp does not fit. strftime returns
dd65c9
0 if the buffer is too small and a NUL-terminated string otherwise, so we
dd65c9
can drop the size specifications in string formatting.
dd65c9
dd65c9
$ export LANG=fa_IR.UTF-8
dd65c9
$ date
dd65c9
چهارشنبه ۱۸ اكتبر ۱۷، ساعت ۱۰:۵۴:۲۴ (+0330)
dd65c9
$ timedatectl
dd65c9
Assertion 'xstrftime: a[] must be big enough' failed at ../src/timedate/timedatectl.c:105, function print_status_info(). Aborting.
dd65c9
dd65c9
now:
dd65c9
dd65c9
$ timedatectl
dd65c9
        Local time: چهارشنبه 2017-10-18 16:29:40 CEST
dd65c9
    Universal time: چهارشنبه 2017-10-18 14:29:40 UTC
dd65c9
          RTC time: چهارشنبه 2017-10-18 14:29:40
dd65c9
dd65c9
dd65c9
(cherry picked from commit 14ce0c25c28ba58e80084e28b4f23884199900e4)
dd65c9
Resolves: #1503942
dd65c9
---
dd65c9
 src/shared/time-util.h     |  2 --
23b3cf
 src/timedate/timedatectl.c | 49 ++++++++++++++++++++------------------
dd65c9
 2 files changed, 26 insertions(+), 25 deletions(-)
dd65c9
dd65c9
diff --git a/src/shared/time-util.h b/src/shared/time-util.h
dd65c9
index f2789142f..32e90902a 100644
dd65c9
--- a/src/shared/time-util.h
dd65c9
+++ b/src/shared/time-util.h
dd65c9
@@ -108,5 +108,3 @@ int get_timezones(char ***l);
dd65c9
 bool timezone_is_valid(const char *name);
dd65c9
 
dd65c9
 clockid_t clock_boottime_or_monotonic(void);
dd65c9
-
dd65c9
-#define xstrftime(buf, fmt, tm) assert_se(strftime(buf, ELEMENTSOF(buf), fmt, tm) > 0)
dd65c9
diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c
dd65c9
index 1accccb68..3e9b657bc 100644
dd65c9
--- a/src/timedate/timedatectl.c
dd65c9
+++ b/src/timedate/timedatectl.c
dd65c9
@@ -93,8 +93,8 @@ static const char *jump_str(int delta_minutes, char *s, size_t size) {
dd65c9
 }
dd65c9
 
dd65c9
 static void print_status_info(const StatusInfo *i) {
dd65c9
-        char a[FORMAT_TIMESTAMP_MAX];
dd65c9
-        char b[FORMAT_TIMESTAMP_MAX];
dd65c9
+        char a[LINE_MAX];
dd65c9
+        char b[LINE_MAX];
dd65c9
         char s[32];
dd65c9
         struct tm tm;
dd65c9
         time_t sec;
dd65c9
@@ -104,6 +104,7 @@ static void print_status_info(const StatusInfo *i) {
dd65c9
         int dn = 0;
dd65c9
         bool is_dstc = false, is_dstn = false;
dd65c9
         int r;
dd65c9
+        size_t n;
dd65c9
 
dd65c9
         assert(i);
dd65c9
 
dd65c9
@@ -123,11 +124,11 @@ static void print_status_info(const StatusInfo *i) {
dd65c9
                 fprintf(stderr, "Warning: Could not get time from timedated and not operating locally.\n\n");
dd65c9
 
dd65c9
         if (have_time) {
dd65c9
-                xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm));
dd65c9
-                printf("      Local time: %.*s\n", (int) sizeof(a), a);
dd65c9
+                n = strftime(a, sizeof a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm));
dd65c9
+                printf("      Local time: %s\n", n > 0 ? a : "n/a");
dd65c9
 
dd65c9
-                xstrftime(a, "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm));
dd65c9
-                printf("  Universal time: %.*s\n", (int) sizeof(a), a);
dd65c9
+                n = strftime(a, sizeof a, "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm));
dd65c9
+                printf("  Universal time: %s\n", n > 0 ? a : "n/a");
dd65c9
         } else {
dd65c9
                 printf("      Local time: %s\n", "n/a");
dd65c9
                 printf("  Universal time: %s\n", "n/a");
dd65c9
@@ -137,24 +138,26 @@ static void print_status_info(const StatusInfo *i) {
dd65c9
                 time_t rtc_sec;
dd65c9
 
dd65c9
                 rtc_sec = (time_t)(i->rtc_time / USEC_PER_SEC);
dd65c9
-                xstrftime(a, "%a %Y-%m-%d %H:%M:%S", gmtime_r(&rtc_sec, &tm));
dd65c9
-                printf("        RTC time: %.*s\n", (int) sizeof(a), a);
dd65c9
+                n = strftime(a, sizeof a, "%a %Y-%m-%d %H:%M:%S", gmtime_r(&rtc_sec, &tm));
dd65c9
+                printf("        RTC time: %s\n", n > 0 ? a : "n/a");
dd65c9
         } else
dd65c9
                 printf("        RTC time: %s\n", "n/a");
dd65c9
 
dd65c9
         if (have_time)
dd65c9
-                xstrftime(a, "%Z, %z", localtime_r(&sec, &tm));
dd65c9
+                n = strftime(a, sizeof a, "%Z, %z", localtime_r(&sec, &tm));
dd65c9
 
dd65c9
-        printf("       Time zone: %s (%.*s)\n"
dd65c9
+        printf("       Time zone: %s (%s)\n"
dd65c9
                "     NTP enabled: %s\n"
dd65c9
                "NTP synchronized: %s\n"
dd65c9
                " RTC in local TZ: %s\n",
dd65c9
-               strna(i->timezone), (int) sizeof(a), have_time ? a : "n/a",
dd65c9
+               strna(i->timezone), have_time && n > 0 ? a : "n/a",
dd65c9
                i->ntp_capable ? yes_no(i->ntp_enabled) : "n/a",
dd65c9
                yes_no(i->ntp_synced),
dd65c9
                yes_no(i->rtc_local));
dd65c9
 
dd65c9
         if (have_time) {
dd65c9
+                size_t m;
dd65c9
+
dd65c9
                 r = time_get_dst(sec, "/etc/localtime",
dd65c9
                                  &tc, &zc, &is_dstc,
dd65c9
                                  &tn, &dn, &zn, &is_dstn);
dd65c9
@@ -164,26 +167,26 @@ static void print_status_info(const StatusInfo *i) {
dd65c9
                         printf("      DST active: %s\n", yes_no(is_dstc));
dd65c9
 
dd65c9
                         t = tc - 1;
dd65c9
-                        xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm));
dd65c9
+                        n = strftime(a, sizeof a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm));
dd65c9
 
dd65c9
-                        xstrftime(b, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tc, &tm));
dd65c9
+                        m = strftime(b, sizeof b, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tc, &tm));
dd65c9
                         printf(" Last DST change: DST %s at\n"
dd65c9
-                               "                  %.*s\n"
dd65c9
-                               "                  %.*s\n",
dd65c9
+                               "                  %s\n"
dd65c9
+                               "                  %s\n",
dd65c9
                                is_dstc ? "began" : "ended",
dd65c9
-                               (int) sizeof(a), a,
dd65c9
-                               (int) sizeof(b), b);
dd65c9
+                               n > 0 ? a : "n/a",
dd65c9
+                               m > 0 ? b : "n/a");
dd65c9
 
dd65c9
                         t = tn - 1;
dd65c9
-                        xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm));
dd65c9
-                        xstrftime(b, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tn, &tm));
dd65c9
+                        n = strftime(a, sizeof a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm));
dd65c9
+                        m = strftime(b, sizeof b, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tn, &tm));
dd65c9
                         printf(" Next DST change: DST %s (the clock jumps %s) at\n"
dd65c9
-                               "                  %.*s\n"
dd65c9
-                               "                  %.*s\n",
dd65c9
+                               "                  %s\n"
dd65c9
+                               "                  %s\n",
dd65c9
                                is_dstn ? "begins" : "ends",
dd65c9
                                jump_str(dn, s, sizeof(s)),
dd65c9
-                               (int) sizeof(a), a,
dd65c9
-                               (int) sizeof(b), b);
dd65c9
+                               n > 0 ? a : "n/a",
dd65c9
+                               m > 0 ? b : "n/a");
dd65c9
                 }
dd65c9
         } else
dd65c9
                 printf("      DST active: %s\n", yes_no(is_dstc));