busybox/util-linux/hwclock.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * Mini hwclock implementation for busybox
   4 *
   5 * Copyright (C) 2002 Robert Griebl <griebl@gmx.de>
   6 *
   7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
   8*/
   9
  10#include <sys/utsname.h>
  11#include "libbb.h"
  12#include "rtc_.h"
  13
  14#if ENABLE_FEATURE_HWCLOCK_LONG_OPTIONS
  15# ifndef _GNU_SOURCE
  16#  define _GNU_SOURCE
  17# endif
  18#endif
  19
  20static const char *rtcname;
  21
  22static time_t read_rtc(int utc)
  23{
  24        time_t ret;
  25        int fd;
  26
  27        fd = rtc_xopen(&rtcname, O_RDONLY);
  28        ret = rtc_read_time(fd, utc);
  29        close(fd);
  30
  31        return ret;
  32}
  33
  34static void write_rtc(time_t t, int utc)
  35{
  36        struct tm tm;
  37        int rtc = rtc_xopen(&rtcname, O_WRONLY);
  38
  39        tm = *(utc ? gmtime(&t) : localtime(&t));
  40        tm.tm_isdst = 0;
  41
  42        xioctl(rtc, RTC_SET_TIME, &tm);
  43
  44        close(rtc);
  45}
  46
  47static void show_clock(int utc)
  48{
  49        //struct tm *ptm;
  50        time_t t;
  51        char *cp;
  52
  53        t = read_rtc(utc);
  54        //ptm = localtime(&t);  /* Sets 'tzname[]' */
  55
  56        cp = ctime(&t);
  57        if (cp[0])
  58                cp[strlen(cp) - 1] = '\0';
  59
  60        //printf("%s  %.6f seconds %s\n", cp, 0.0, utc ? "" : (ptm->tm_isdst ? tzname[1] : tzname[0]));
  61        printf("%s  0.000000 seconds\n", cp);
  62}
  63
  64static void to_sys_clock(int utc)
  65{
  66        struct timeval tv;
  67        const struct timezone tz = { timezone/60 - 60*daylight, 0 };
  68
  69        tv.tv_sec = read_rtc(utc);
  70        tv.tv_usec = 0;
  71        if (settimeofday(&tv, &tz))
  72                bb_perror_msg_and_die("settimeofday() failed");
  73}
  74
  75static void from_sys_clock(int utc)
  76{
  77        struct timeval tv;
  78
  79        gettimeofday(&tv, NULL);
  80        //if (gettimeofday(&tv, NULL))
  81        //      bb_perror_msg_and_die("gettimeofday() failed");
  82        write_rtc(tv.tv_sec, utc);
  83}
  84
  85#define HWCLOCK_OPT_LOCALTIME   0x01
  86#define HWCLOCK_OPT_UTC         0x02
  87#define HWCLOCK_OPT_SHOW        0x04
  88#define HWCLOCK_OPT_HCTOSYS     0x08
  89#define HWCLOCK_OPT_SYSTOHC     0x10
  90#define HWCLOCK_OPT_RTCFILE     0x20
  91
  92int hwclock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  93int hwclock_main(int argc UNUSED_PARAM, char **argv)
  94{
  95        unsigned opt;
  96        int utc;
  97
  98#if ENABLE_FEATURE_HWCLOCK_LONG_OPTIONS
  99        static const char hwclock_longopts[] ALIGN1 =
 100                "localtime\0" No_argument "l"
 101                "utc\0"       No_argument "u"
 102                "show\0"      No_argument "r"
 103                "hctosys\0"   No_argument "s"
 104                "systohc\0"   No_argument "w"
 105                "file\0"      Required_argument "f"
 106                ;
 107        applet_long_options = hwclock_longopts;
 108#endif
 109        opt_complementary = "r--ws:w--rs:s--wr:l--u:u--l";
 110        opt = getopt32(argv, "lurswf:", &rtcname);
 111
 112        /* If -u or -l wasn't given check if we are using utc */
 113        if (opt & (HWCLOCK_OPT_UTC | HWCLOCK_OPT_LOCALTIME))
 114                utc = (opt & HWCLOCK_OPT_UTC);
 115        else
 116                utc = rtc_adjtime_is_utc();
 117
 118        if (opt & HWCLOCK_OPT_HCTOSYS)
 119                to_sys_clock(utc);
 120        else if (opt & HWCLOCK_OPT_SYSTOHC)
 121                from_sys_clock(utc);
 122        else
 123                /* default HWCLOCK_OPT_SHOW */
 124                show_clock(utc);
 125
 126        return 0;
 127}
 128