aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griebl <griebl@gmx.de>2002-07-21 16:50:49 +0000
committerRobert Griebl <griebl@gmx.de>2002-07-21 16:50:49 +0000
commit1cd044549531ef1c4016ec3c60652dad95b1617f (patch)
treed552f7d94cac8240a89a5e498b73c0c60299de2c
parentfc78b795758ad04caeadfbb2bbb75e6cefa03785 (diff)
downloadbusybox-w32-1cd044549531ef1c4016ec3c60652dad95b1617f.tar.gz
busybox-w32-1cd044549531ef1c4016ec3c60652dad95b1617f.tar.bz2
busybox-w32-1cd044549531ef1c4016ec3c60652dad95b1617f.zip
Initial checkin of a very primitive hwclock replacement
-rw-r--r--include/applets.h3
-rw-r--r--include/usage.h11
-rw-r--r--util-linux/Makefile.in1
-rw-r--r--util-linux/config.in4
-rw-r--r--util-linux/hwclock.c229
5 files changed, 248 insertions, 0 deletions
diff --git a/include/applets.h b/include/applets.h
index b6397a656..6b8bce7e0 100644
--- a/include/applets.h
+++ b/include/applets.h
@@ -218,6 +218,9 @@
218#ifdef CONFIG_HUSH 218#ifdef CONFIG_HUSH
219 APPLET_NOUSAGE("hush", hush_main, _BB_DIR_BIN, _BB_SUID_NEVER) 219 APPLET_NOUSAGE("hush", hush_main, _BB_DIR_BIN, _BB_SUID_NEVER)
220#endif 220#endif
221#ifdef CONFIG_HWCLOCK
222 APPLET(hwclock, hwclock_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
223#endif
221#ifdef CONFIG_ID 224#ifdef CONFIG_ID
222 APPLET(id, id_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) 225 APPLET(id, id_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
223#endif 226#endif
diff --git a/include/usage.h b/include/usage.h
index 87678f5e9..b7b1ac65d 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -700,6 +700,17 @@
700 "$ hostname\n" \ 700 "$ hostname\n" \
701 "sage \n" 701 "sage \n"
702 702
703#define hwclock_trivial_usage \
704 "[-r|--show] [-s|--hctosys] [-w|--systohc] [-l|--localtime] [-u|--utc]"
705#define hwclock_full_usage \
706 "Query and set the hardware clock (RTC)\n\n" \
707 "Options:\n" \
708 "\t-r\tread hardware clock and print result\n" \
709 "\t-s\tset the system time from the hardware clock\n" \
710 "\t-w\tset the hardware clock to the current system time\n" \
711 "\t-u\tthe hardware clock is kept in coordinated universal time\n" \
712 "\t-l\tthe hardware clock is kept in local time"
713
703#define id_trivial_usage \ 714#define id_trivial_usage \
704 "[OPTIONS]... [USERNAME]" 715 "[OPTIONS]... [USERNAME]"
705#define id_full_usage \ 716#define id_full_usage \
diff --git a/util-linux/Makefile.in b/util-linux/Makefile.in
index fbe075ded..03012fb6e 100644
--- a/util-linux/Makefile.in
+++ b/util-linux/Makefile.in
@@ -30,6 +30,7 @@ UTILLINUX-$(CONFIG_FREERAMDISK) += freeramdisk.o
30UTILLINUX-$(CONFIG_FSCK_MINIX) += fsck_minix.o 30UTILLINUX-$(CONFIG_FSCK_MINIX) += fsck_minix.o
31UTILLINUX-$(CONFIG_GETOPT) += getopt.o 31UTILLINUX-$(CONFIG_GETOPT) += getopt.o
32UTILLINUX-$(CONFIG_HEXDUMP) += hexdump.o 32UTILLINUX-$(CONFIG_HEXDUMP) += hexdump.o
33UTILLINUX-$(CONFIG_HWCLOCK) += hwclock.o
33UTILLINUX-$(CONFIG_LOSETUP) += losetup.o 34UTILLINUX-$(CONFIG_LOSETUP) += losetup.o
34UTILLINUX-$(CONFIG_MKFS_MINIX) += mkfs_minix.o 35UTILLINUX-$(CONFIG_MKFS_MINIX) += mkfs_minix.o
35UTILLINUX-$(CONFIG_MKSWAP) += mkswap.o 36UTILLINUX-$(CONFIG_MKSWAP) += mkswap.o
diff --git a/util-linux/config.in b/util-linux/config.in
index f96fa1823..bcc99bbe1 100644
--- a/util-linux/config.in
+++ b/util-linux/config.in
@@ -23,6 +23,10 @@ if [ "$CONFIG_FSCK_MINIX" = "y" -o "$CONFIG_MKFS_MINIX" = "y" ]; then
23fi 23fi
24bool 'getopt' CONFIG_GETOPT 24bool 'getopt' CONFIG_GETOPT
25bool 'hexdump' CONFIG_HEXDUMP 25bool 'hexdump' CONFIG_HEXDUMP
26bool 'hwclock' CONFIG_HWCLOCK
27if [ "$CONFIG_HWCLOCK" = "y" ]; then
28 bool ' Support long options (--hctosys,...)' CONFIG_FEATURE_HWCLOCK_LONGOPTIONS
29fi
26bool 'losetup' CONFIG_LOSETUP 30bool 'losetup' CONFIG_LOSETUP
27bool 'mkswap' CONFIG_MKSWAP 31bool 'mkswap' CONFIG_MKSWAP
28bool 'more' CONFIG_MORE 32bool 'more' CONFIG_MORE
diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c
new file mode 100644
index 000000000..88222e6ba
--- /dev/null
+++ b/util-linux/hwclock.c
@@ -0,0 +1,229 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * really dumb hwclock implementation for busybox
4 * Copyright (C) 2002 Robert Griebl <griebl@gmx.de>
5 *
6 */
7
8
9#include <sys/utsname.h>
10#include <stdlib.h>
11#include <unistd.h>
12#include <syslog.h>
13#include <string.h>
14#include <ctype.h>
15#include <fcntl.h>
16#include <sys/time.h>
17#include <time.h>
18#include <linux/rtc.h>
19#include <sys/ioctl.h>
20#include "busybox.h"
21
22#ifdef CONFIG_FEATURE_HWCLOCK_LONGOPTIONS
23# ifndef _GNU_SOURCE
24# define _GNU_SOURCE
25# endif
26#endif
27
28#include <getopt.h>
29
30
31enum OpMode {
32 SHOW,
33 SYSTOHC,
34 HCTOSYS
35};
36
37
38time_t read_rtc ( int utc )
39{
40 int rtc;
41 struct tm tm;
42 char *oldtz = 0;
43 time_t t = 0;
44
45 if (( rtc = open ( "/dev/rtc", O_RDONLY )) < 0 ) {
46 if (( rtc = open ( "/dev/misc/rtc", O_RDONLY )) < 0 )
47 perror_msg_and_die ( "Could not access RTC" );
48 }
49 memset ( &tm, 0, sizeof( struct tm ));
50 if ( ioctl ( rtc, RTC_RD_TIME, &tm ) < 0 )
51 perror_msg_and_die ( "Could not read time from RTC" );
52 tm. tm_isdst = -1; // not known
53
54 close ( rtc );
55
56 if ( utc ) {
57 oldtz = getenv ( "TZ" );
58 setenv ( "TZ", "UTC 0", 1 );
59 tzset ( );
60 }
61
62 t = mktime ( &tm );
63
64 if ( utc ) {
65 if ( oldtz )
66 setenv ( "TZ", oldtz, 1 );
67 else
68 unsetenv ( "TZ" );
69 tzset ( );
70 }
71 return t;
72}
73
74void write_rtc ( time_t t, int utc )
75{
76 int rtc;
77 struct tm tm;
78
79 if (( rtc = open ( "/dev/rtc", O_WRONLY )) < 0 ) {
80 if (( rtc = open ( "/dev/misc/rtc", O_WRONLY )) < 0 )
81 perror_msg_and_die ( "Could not access RTC" );
82 }
83
84 printf ( "1\n" );
85
86 tm = *( utc ? gmtime ( &t ) : localtime ( &t ));
87 tm. tm_isdst = 0;
88
89 printf ( "2\n") ;
90
91 if ( ioctl ( rtc, RTC_SET_TIME, &tm ) < 0 )
92 perror_msg_and_die ( "Could not set the RTC time" );
93
94 close ( rtc );
95}
96
97int show_clock ( int utc )
98{
99 struct tm *ptm;
100 time_t t;
101 char buffer [64];
102
103 t = read_rtc ( utc );
104 ptm = localtime ( &t ); /* Sets 'tzname[]' */
105
106 safe_strncpy ( buffer, ctime ( &t ), sizeof( buffer ));
107 if ( buffer [0] )
108 buffer [xstrlen ( buffer ) - 1] = 0;
109
110 //printf ( "%s %.6f seconds %s\n", buffer, 0.0, utc ? "" : ( ptm-> tm_isdst ? tzname [1] : tzname [0] ));
111 printf ( "%s %.6f seconds\n", buffer, 0.0 );
112
113 return 0;
114}
115
116int to_sys_clock ( int utc )
117{
118 struct timeval tv = { 0, 0 };
119 const struct timezone tz = { timezone/60 - 60*daylight, 0 };
120
121 tv. tv_sec = read_rtc ( utc );
122
123 if ( settimeofday ( &tv, &tz ))
124 perror_msg_and_die ( "settimeofday() failed" );
125
126 return 0;
127}
128
129int from_sys_clock ( int utc )
130{
131 struct timeval tv = { 0, 0 };
132 struct timezone tz = { 0, 0 };
133
134 if ( gettimeofday ( &tv, &tz ))
135 perror_msg_and_die ( "gettimeofday() failed" );
136
137 write_rtc ( tv. tv_sec, utc );
138 return 0;
139}
140
141
142int check_utc ( void )
143{
144 int utc = 0;
145 FILE *f = fopen ( "/etc/adjtime", "r" );
146
147 if ( f ) {
148 char buffer [128];
149
150 while ( fgets ( buffer, sizeof( buffer ), f )) {
151 int len = xstrlen ( buffer );
152
153 while ( len && isspace ( buffer [len - 1] ))
154 len--;
155
156 buffer [len] = 0;
157
158 if ( strncmp ( buffer, "UTC", 3 ) == 0 ) {
159 utc = 1;
160 break;
161 }
162 }
163 fclose ( f );
164 }
165 return utc;
166}
167
168extern int hwclock_main ( int argc, char **argv )
169{
170 int opt;
171 enum OpMode mode = SHOW;
172 int utc = 0;
173 int utc_arg = 0;
174
175#ifdef CONFIG_FEATURE_HWCLOCK_LONGOPTIONS
176 struct option long_options[] = {
177 { "show", 0, 0, 'r' },
178 { "utc", 0, 0, 'u' },
179 { "localtime", 0, 0, 'l' },
180 { "hctosys", 0, 0, 's' },
181 { "systohc", 0, 0, 'w' },
182 { 0, 0, 0, 0 }
183 };
184
185 while (( opt = getopt_long ( argc, argv, "rwsul", long_options, 0 )) != EOF ) {
186#else
187 while (( opt = getopt ( argc, argv, "rwsul" )) != EOF ) {
188#endif
189 switch ( opt ) {
190 case 'r':
191 mode = SHOW;
192 break;
193 case 'w':
194 mode = SYSTOHC;
195 break;
196 case 's':
197 mode = HCTOSYS;
198 break;
199 case 'u':
200 utc = 1;
201 utc_arg = 1;
202 break;
203 case 'l': // -l is not supported by the normal hwclock (only --localtime)
204 utc = 0;
205 utc_arg = 1;
206 break;
207 default:
208 show_usage();
209 break;
210 }
211 }
212
213 if ( !utc_arg )
214 utc = check_utc ( );
215
216 switch ( mode ) {
217 case SYSTOHC:
218 return from_sys_clock ( utc );
219
220 case HCTOSYS:
221 return to_sys_clock ( utc );
222
223 case SHOW:
224 default:
225 return show_clock ( utc );
226 }
227}
228
229