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