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 /util-linux | |
parent | 19e695ebadda206d1e0fbefa59ed8fabee0d0f64 (diff) | |
download | busybox-179e88bec91cfe58096900dc5509a080ff37b083.tar.gz |
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>
Diffstat (limited to 'util-linux')
-rw-r--r-- | util-linux/rdate.c | 33 |
1 files changed, 27 insertions, 6 deletions
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; |