From 179e88bec91cfe58096900dc5509a080ff37b083 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 20 Jan 2017 16:03:48 +0100 Subject: 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 --- util-linux/rdate.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'util-linux/rdate.c') 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; -- cgit v1.2.3