commit dacfb76c75bbd9a5020d4a3bd22b993e1e9dfebd
Author: sin <[email protected]>
Date:   Tue Jun 3 14:46:27 2014 +0100

    Add initial version of hwclock(8)

diff --git a/Makefile b/Makefile
index e55d770..d0b6acd 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@ include config.mk
 .POSIX:
 .SUFFIXES: .c .o
 
-HDR = arg.h config.def.h proc.h reboot.h util.h
+HDR = arg.h config.def.h proc.h reboot.h rtc.h util.h
 LIB = \
        util/agetcwd.o        \
        util/apathmax.o       \
@@ -29,6 +29,7 @@ SRC = \
        free.c              \
        getty.c             \
        halt.c              \
+       hwclock.c           \
        id.c                \
        insmod.c            \
        killall5.c          \
diff --git a/hwclock.c b/hwclock.c
new file mode 100644
index 0000000..093d5bd
--- /dev/null
+++ b/hwclock.c
@@ -0,0 +1,106 @@
+/* See LICENSE file for copyright and license details. */
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include "rtc.h"
+#include "util.h"
+
+static void echotime(char *);
+static void readrtctm(struct tm *, int);
+static void writertctm(struct tm *, int);
+static void writetime(char *);
+
+static void
+usage(void)
+{
+       eprintf("usage: %s [-rw] [-u]
", argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+       char *dev = "/dev/rtc";
+       int rflag = 0;
+       int wflag = 0;
+
+       ARGBEGIN {
+       case 'r':
+               rflag = 1;
+               break;
+       case 'w':
+               wflag = 1;
+               break;
+       case 'u':
+               break;
+       default:
+               usage();
+       } ARGEND;
+
+       if ((rflag ^ wflag) == 0)
+               eprintf("missing or incompatible function
");
+
+       /* Only UTC support at the moment */
+       setenv("TZ", "UTC0", 1);
+       tzset();
+
+       if (rflag == 1)
+               echotime(dev);
+       else if (wflag == 1)
+               writetime(dev);
+
+       return EXIT_SUCCESS;
+}
+
+static void
+echotime(char *dev)
+{
+       struct tm tm;
+       time_t t;
+       int fd;
+
+       fd = open(dev, O_RDONLY);
+       if (fd < 0)
+               eprintf("open %s:", dev);
+       readrtctm(&tm, fd);
+       t = mktime(&tm);
+       printf("%s", asctime(localtime(&t)));
+       close(fd);
+}
+
+static void
+readrtctm(struct tm *tm, int fd)
+{
+       memset(tm, 0, sizeof(*tm));
+       ioctl(fd, RTC_RD_TIME, tm);
+}
+
+static void
+writertctm(struct tm *tm, int fd)
+{
+       ioctl(fd, RTC_SET_TIME, tm);
+}
+
+static void
+writetime(char *dev)
+{
+       struct timeval tv;
+       struct tm *tm;
+       time_t t;
+       int fd;
+
+       fd = open(dev, O_WRONLY);
+       if (fd < 0)
+               eprintf("open %s:", dev);
+       gettimeofday(&tv, NULL);
+       t = tv.tv_sec;
+       tm = gmtime(&t);
+       writertctm(tm, fd);
+       close(fd);
+}
diff --git a/rtc.h b/rtc.h
new file mode 100644
index 0000000..9dd76c1
--- /dev/null
+++ b/rtc.h
@@ -0,0 +1,2 @@
+#define RTC_RD_TIME    _IOR('p', 0x09, struct tm) /* Read RTC time   */
+#define RTC_SET_TIME   _IOW('p', 0x0a, struct tm) /* Set RTC time    */


Reply via email to