diff options
| author | sandman <sandman@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2002-07-21 16:50:49 +0000 |
|---|---|---|
| committer | sandman <sandman@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2002-07-21 16:50:49 +0000 |
| commit | 2d351780fbacf9408d331ddad01e7619e296cca3 (patch) | |
| tree | d552f7d94cac8240a89a5e498b73c0c60299de2c /util-linux | |
| parent | 89025b51201240d76228179ce321fda17f8f285e (diff) | |
| download | busybox-w32-2d351780fbacf9408d331ddad01e7619e296cca3.tar.gz busybox-w32-2d351780fbacf9408d331ddad01e7619e296cca3.tar.bz2 busybox-w32-2d351780fbacf9408d331ddad01e7619e296cca3.zip | |
Initial checkin of a very primitive hwclock replacement
git-svn-id: svn://busybox.net/trunk/busybox@5072 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'util-linux')
| -rw-r--r-- | util-linux/Makefile.in | 1 | ||||
| -rw-r--r-- | util-linux/config.in | 4 | ||||
| -rw-r--r-- | util-linux/hwclock.c | 229 |
3 files changed, 234 insertions, 0 deletions
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 | |||
| 30 | UTILLINUX-$(CONFIG_FSCK_MINIX) += fsck_minix.o | 30 | UTILLINUX-$(CONFIG_FSCK_MINIX) += fsck_minix.o |
| 31 | UTILLINUX-$(CONFIG_GETOPT) += getopt.o | 31 | UTILLINUX-$(CONFIG_GETOPT) += getopt.o |
| 32 | UTILLINUX-$(CONFIG_HEXDUMP) += hexdump.o | 32 | UTILLINUX-$(CONFIG_HEXDUMP) += hexdump.o |
| 33 | UTILLINUX-$(CONFIG_HWCLOCK) += hwclock.o | ||
| 33 | UTILLINUX-$(CONFIG_LOSETUP) += losetup.o | 34 | UTILLINUX-$(CONFIG_LOSETUP) += losetup.o |
| 34 | UTILLINUX-$(CONFIG_MKFS_MINIX) += mkfs_minix.o | 35 | UTILLINUX-$(CONFIG_MKFS_MINIX) += mkfs_minix.o |
| 35 | UTILLINUX-$(CONFIG_MKSWAP) += mkswap.o | 36 | UTILLINUX-$(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 | |||
| 23 | fi | 23 | fi |
| 24 | bool 'getopt' CONFIG_GETOPT | 24 | bool 'getopt' CONFIG_GETOPT |
| 25 | bool 'hexdump' CONFIG_HEXDUMP | 25 | bool 'hexdump' CONFIG_HEXDUMP |
| 26 | bool 'hwclock' CONFIG_HWCLOCK | ||
| 27 | if [ "$CONFIG_HWCLOCK" = "y" ]; then | ||
| 28 | bool ' Support long options (--hctosys,...)' CONFIG_FEATURE_HWCLOCK_LONGOPTIONS | ||
| 29 | fi | ||
| 26 | bool 'losetup' CONFIG_LOSETUP | 30 | bool 'losetup' CONFIG_LOSETUP |
| 27 | bool 'mkswap' CONFIG_MKSWAP | 31 | bool 'mkswap' CONFIG_MKSWAP |
| 28 | bool 'more' CONFIG_MORE | 32 | bool '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 | |||
| 31 | enum OpMode { | ||
| 32 | SHOW, | ||
| 33 | SYSTOHC, | ||
| 34 | HCTOSYS | ||
| 35 | }; | ||
| 36 | |||
| 37 | |||
| 38 | time_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 | |||
| 74 | void 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 | |||
| 97 | int 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 | |||
| 116 | int 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 | |||
| 129 | int 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 | |||
| 142 | int 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 | |||
| 168 | extern 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 | |||
