diff options
Diffstat (limited to 'util-linux/rdate.c')
-rw-r--r-- | util-linux/rdate.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/util-linux/rdate.c b/util-linux/rdate.c new file mode 100644 index 000000000..12105953d --- /dev/null +++ b/util-linux/rdate.c | |||
@@ -0,0 +1,86 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * The Rdate command will ask a time server for the RFC 868 time | ||
4 | * and optionally set the system time. | ||
5 | * | ||
6 | * by Sterling Huxley <sterling@europa.com> | ||
7 | * | ||
8 | * Licensed under GPL v2 or later, see file License for details. | ||
9 | */ | ||
10 | |||
11 | #include <sys/types.h> | ||
12 | #include <sys/socket.h> | ||
13 | #include <netinet/in.h> | ||
14 | #include <netdb.h> | ||
15 | #include <stdio.h> | ||
16 | #include <string.h> | ||
17 | #include <time.h> | ||
18 | #include <stdlib.h> | ||
19 | #include <unistd.h> | ||
20 | #include <signal.h> | ||
21 | |||
22 | #include "busybox.h" | ||
23 | |||
24 | |||
25 | static const int RFC_868_BIAS = 2208988800UL; | ||
26 | |||
27 | static void socket_timeout(int sig) | ||
28 | { | ||
29 | bb_error_msg_and_die("timeout connecting to time server"); | ||
30 | } | ||
31 | |||
32 | static time_t askremotedate(const char *host) | ||
33 | { | ||
34 | unsigned long nett; | ||
35 | struct sockaddr_in s_in; | ||
36 | int fd; | ||
37 | |||
38 | bb_lookup_host(&s_in, host); | ||
39 | s_in.sin_port = bb_lookup_port("time", "tcp", 37); | ||
40 | |||
41 | /* Add a timeout for dead or inaccessible servers */ | ||
42 | alarm(10); | ||
43 | signal(SIGALRM, socket_timeout); | ||
44 | |||
45 | fd = xconnect_tcp_v4(&s_in); | ||
46 | |||
47 | if (safe_read(fd, (void *)&nett, 4) != 4) /* read time from server */ | ||
48 | bb_error_msg_and_die("%s did not send the complete time", host); | ||
49 | close(fd); | ||
50 | |||
51 | /* convert from network byte order to local byte order. | ||
52 | * RFC 868 time is the number of seconds | ||
53 | * since 00:00 (midnight) 1 January 1900 GMT | ||
54 | * the RFC 868 time 2,208,988,800 corresponds to 00:00 1 Jan 1970 GMT | ||
55 | * Subtract the RFC 868 time to get Linux epoch | ||
56 | */ | ||
57 | |||
58 | return ntohl(nett) - RFC_868_BIAS; | ||
59 | } | ||
60 | |||
61 | int rdate_main(int argc, char **argv) | ||
62 | { | ||
63 | time_t remote_time; | ||
64 | unsigned long flags; | ||
65 | |||
66 | opt_complementary = "-1"; | ||
67 | flags = getopt32(argc, argv, "sp"); | ||
68 | |||
69 | remote_time = askremotedate(argv[optind]); | ||
70 | |||
71 | if ((flags & 2) == 0) { | ||
72 | time_t current_time; | ||
73 | |||
74 | time(¤t_time); | ||
75 | if (current_time == remote_time) | ||
76 | bb_error_msg("current time matches remote time"); | ||
77 | else | ||
78 | if (stime(&remote_time) < 0) | ||
79 | bb_perror_msg_and_die("cannot set time of day"); | ||
80 | } | ||
81 | |||
82 | if ((flags & 1) == 0) | ||
83 | printf("%s", ctime(&remote_time)); | ||
84 | |||
85 | return EXIT_SUCCESS; | ||
86 | } | ||