diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-20 16:03:48 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-20 16:03:48 +0100 |
commit | 179e88bec91cfe58096900dc5509a080ff37b083 (patch) | |
tree | 069b8a997ea753191155630a2c4f8568e14df915 | |
parent | 19e695ebadda206d1e0fbefa59ed8fabee0d0f64 (diff) |
rdate: make it do something remotely sane, facing 32-bit time overflow
function old new delta
rdate_main 251 254 +3
packed_usage 31029 31023 -6
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | networking/inetd.c | 2 | ||||
-rw-r--r-- | util-linux/rdate.c | 33 |
2 files changed, 28 insertions, 7 deletions
diff --git a/networking/inetd.c b/networking/inetd.c index 4d0ab2e0d..612284e76 100644 --- a/networking/inetd.c +++ b/networking/inetd.c @@ -1677,7 +1677,7 @@ static uint32_t machtime(void) struct timeval tv; gettimeofday(&tv, NULL); - return htonl((uint32_t)(tv.tv_sec + 2208988800)); + return htonl((uint32_t)(tv.tv_sec + 2208988800U)); } /* ARGSUSED */ static void FAST_FUNC machtime_stream(int s, servtab_t *sep UNUSED_PARAM) diff --git a/util-linux/rdate.c b/util-linux/rdate.c index 8dd784d3d..a62591914 100644 --- a/util-linux/rdate.c +++ b/util-linux/rdate.c @@ -21,11 +21,11 @@ //kbuild:lib-$(CONFIG_RDATE) += rdate.o //usage:#define rdate_trivial_usage -//usage: "[-sp] HOST" +//usage: "[-s/-p] HOST" //usage:#define rdate_full_usage "\n\n" -//usage: "Get and possibly set system time from a remote HOST\n" -//usage: "\n -s Set system time (default)" -//usage: "\n -p Print time" +//usage: "Set and print time from HOST using RFC 868\n" +//usage: "\n -s Only set system time" +//usage: "\n -p Only print time" #include "libbb.h" @@ -58,8 +58,22 @@ static time_t askremotedate(const char *host) * the RFC 868 time 2,208,988,800 corresponds to 00:00 1 Jan 1970 GMT * Subtract the RFC 868 time to get Linux epoch. */ - - return ntohl(nett) - RFC_868_BIAS; + nett = ntohl(nett) - RFC_868_BIAS; + + if (sizeof(time_t) > 4) { + /* Now we have 32-bit lsb of a wider time_t + * Imagine that nett = 0x00000001, + * current time cur = 0x123ffffffff. + * Assuming our time is not some 40 years off, + * remote time must be 0x12400000001. + * Need to adjust out time by (int32_t)(nett - cur). + */ + time_t cur = time(NULL); + int32_t adjust = (int32_t)(nett - (uint32_t)cur); + return cur + adjust; + } + /* This is not going to work, but what can we do */ + return (time_t)nett; } int rdate_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; @@ -73,6 +87,13 @@ int rdate_main(int argc UNUSED_PARAM, char **argv) remote_time = askremotedate(argv[optind]); + /* Manpages of various Unixes are confusing. What happens is: + * (no opts) set and print time + * -s: set time ("do not print the time") + * -p: print time ("do not set, just print the remote time") + * -sp: print time (that's what we do, not sure this is right) + */ + if (!(flags & 2)) { /* no -p (-s may be present) */ time_t current_time; |