busybox: fix setting the kernel timezone
[openwrt/svn-archive/archive.git] / package / utils / busybox / patches / 250-date-k-flag.patch
1 --- a/coreutils/date.c
2 +++ b/coreutils/date.c
3 @@ -123,6 +123,7 @@
4 //usage: IF_FEATURE_DATE_ISOFMT(
5 //usage: "\n -D FMT Use FMT for -d TIME conversion"
6 //usage: )
7 +//usage: "\n -k Set Kernel timezone from localtime and exit"
8 //usage: "\n"
9 //usage: "\nRecognized TIME formats:"
10 //usage: "\n hh:mm[:ss]"
11 @@ -138,9 +139,8 @@
12 //usage: "Wed Apr 12 18:52:41 MDT 2000\n"
13
14 #include "libbb.h"
15 -#if ENABLE_FEATURE_DATE_NANO
16 -# include <sys/syscall.h>
17 -#endif
18 +#include <sys/time.h>
19 +#include <sys/syscall.h>
20
21 enum {
22 OPT_RFC2822 = (1 << 0), /* R */
23 @@ -148,8 +148,9 @@ enum {
24 OPT_UTC = (1 << 2), /* u */
25 OPT_DATE = (1 << 3), /* d */
26 OPT_REFERENCE = (1 << 4), /* r */
27 - OPT_TIMESPEC = (1 << 5) * ENABLE_FEATURE_DATE_ISOFMT, /* I */
28 - OPT_HINT = (1 << 6) * ENABLE_FEATURE_DATE_ISOFMT, /* D */
29 + OPT_KERNELTZ = (1 << 5), /* k */
30 + OPT_TIMESPEC = (1 << 6) * ENABLE_FEATURE_DATE_ISOFMT, /* I */
31 + OPT_HINT = (1 << 7) * ENABLE_FEATURE_DATE_ISOFMT, /* D */
32 };
33
34 static void maybe_set_utc(int opt)
35 @@ -167,12 +168,15 @@ static const char date_longopts[] ALIGN1
36 /* "universal\0" No_argument "u" */
37 "date\0" Required_argument "d"
38 "reference\0" Required_argument "r"
39 + "set-kernel-tz\0" No_argument "k"
40 ;
41 #endif
42
43 int date_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
44 int date_main(int argc UNUSED_PARAM, char **argv)
45 {
46 + time_t tt;
47 + struct timezone tz;
48 struct timespec ts;
49 struct tm tm_time;
50 char buf_fmt_dt2str[64];
51 @@ -187,7 +191,7 @@ int date_main(int argc UNUSED_PARAM, cha
52 opt_complementary = "d--s:s--d"
53 IF_FEATURE_DATE_ISOFMT(":R--I:I--R");
54 IF_LONG_OPTS(applet_long_options = date_longopts;)
55 - opt = getopt32(argv, "Rs:ud:r:"
56 + opt = getopt32(argv, "Rs:ud:r:k"
57 IF_FEATURE_DATE_ISOFMT("I::D:"),
58 &date_str, &date_str, &filename
59 IF_FEATURE_DATE_ISOFMT(, &isofmt_arg, &fmt_str2dt));
60 @@ -244,6 +248,31 @@ int date_main(int argc UNUSED_PARAM, cha
61 if (*argv)
62 bb_show_usage();
63
64 + /* Setting of kernel timezone was requested */
65 + if (opt & OPT_KERNELTZ) {
66 + tt = time(NULL);
67 + localtime_r(&tt, &tm_time);
68 +
69 + /* workaround warp_clock() on first invocation */
70 + memset(&tz, 0, sizeof(tz));
71 + syscall(SYS_settimeofday, NULL, &tz);
72 +
73 + memset(&tz, 0, sizeof(tz));
74 +#ifdef __USE_MISC
75 + tz.tz_minuteswest = -(tm_time.tm_gmtoff / 60);
76 +#else
77 + tz.tz_minuteswest = -(tm_time.__tm_gmtoff / 60);
78 +#endif
79 +
80 + if (syscall(SYS_settimeofday, NULL, &tz))
81 + {
82 + bb_perror_msg("can't set kernel time zone");
83 + return EXIT_FAILURE;
84 + }
85 +
86 + return EXIT_SUCCESS;
87 + }
88 +
89 /* Now we have parsed all the information except the date format
90 * which depends on whether the clock is being set or read */
91