ubase

suckless linux base utils
git clone git://git.suckless.org/ubase
Log | Files | Refs | README | LICENSE

hwclock.c (2616B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include <sys/ioctl.h>
      3 #include <sys/stat.h>
      4 #include <sys/time.h>
      5 #include <sys/types.h>
      6 
      7 #include <fcntl.h>
      8 #include <stdio.h>
      9 #include <stdlib.h>
     10 #include <string.h>
     11 #include <time.h>
     12 #include <unistd.h>
     13 
     14 #include "rtc.h"
     15 #include "util.h"
     16 
     17 static void
     18 readrtctm(struct tm *tm, int fd)
     19 {
     20 	struct rtc_time rt;
     21 
     22 	memset(&rt, 0, sizeof(rt));
     23 	if (ioctl(fd, RTC_RD_TIME, &rt) < 0)
     24 		eprintf("RTC_RD_TIME:");
     25 	tm->tm_sec = rt.tm_sec;
     26 	tm->tm_min = rt.tm_min;
     27 	tm->tm_hour = rt.tm_hour;
     28 	tm->tm_mday = rt.tm_mday;
     29 	tm->tm_mon = rt.tm_mon;
     30 	tm->tm_year = rt.tm_year;
     31 	tm->tm_wday = rt.tm_wday;
     32 	tm->tm_yday = rt.tm_yday;
     33 	tm->tm_isdst = rt.tm_isdst;
     34 }
     35 
     36 static void
     37 writertctm(struct tm *tm, int fd)
     38 {
     39 	struct rtc_time rt;
     40 
     41 	rt.tm_sec = tm->tm_sec;
     42 	rt.tm_min = tm->tm_min;
     43 	rt.tm_hour = tm->tm_hour;
     44 	rt.tm_mday = tm->tm_mday;
     45 	rt.tm_mon = tm->tm_mon;
     46 	rt.tm_year = tm->tm_year;
     47 	rt.tm_wday = tm->tm_wday;
     48 	rt.tm_yday = tm->tm_yday;
     49 	rt.tm_isdst = tm->tm_isdst;
     50 	if (ioctl(fd, RTC_SET_TIME, &rt) < 0)
     51 		eprintf("RTC_SET_TIME:");
     52 }
     53 
     54 static void
     55 show(char *dev)
     56 {
     57 	struct tm tm;
     58 	time_t t;
     59 	int fd;
     60 
     61 	fd = open(dev, O_RDONLY);
     62 	if (fd < 0)
     63 		eprintf("open %s:", dev);
     64 	readrtctm(&tm, fd);
     65 	t = mktime(&tm);
     66 	printf("%s", asctime(localtime(&t)));
     67 	close(fd);
     68 }
     69 
     70 static void
     71 hctosys(char *dev)
     72 {
     73 	struct timeval tv;
     74 	struct tm tm;
     75 	int r;
     76 	int fd;
     77 
     78 	fd = open(dev, O_RDONLY);
     79 	if (fd < 0)
     80 		eprintf("open %s:", dev);
     81 	readrtctm(&tm, fd);
     82 	tv.tv_sec = mktime(&tm);
     83 	tv.tv_usec = 0;
     84 	r = settimeofday(&tv, NULL);
     85 	if (r < 0)
     86 		eprintf("settimeofday:");
     87 	close(fd);
     88 }
     89 
     90 static void
     91 systohc(char *dev)
     92 {
     93 	struct timeval tv;
     94 	struct tm *tm;
     95 	time_t t;
     96 	int fd;
     97 
     98 	fd = open(dev, O_WRONLY);
     99 	if (fd < 0)
    100 		eprintf("open %s:", dev);
    101 	gettimeofday(&tv, NULL);
    102 	t = tv.tv_sec;
    103 	tm = gmtime(&t);
    104 	weprintf("warning: assuming UTC for systohc\n");
    105 	writertctm(tm, fd);
    106 	close(fd);
    107 }
    108 
    109 static void
    110 usage(void)
    111 {
    112 	eprintf("usage: %s [-rsw] [-u] [dev]\n", argv0);
    113 }
    114 
    115 int
    116 main(int argc, char *argv[])
    117 {
    118 	char *dev = "/dev/rtc";
    119 	int rflag = 0;
    120 	int sflag = 0;
    121 	int wflag = 0;
    122 
    123 	ARGBEGIN {
    124 	case 'r':
    125 		rflag = 1;
    126 		break;
    127 	case 's':
    128 		sflag = 1;
    129 		break;
    130 	case 'w':
    131 		wflag = 1;
    132 		break;
    133 	case 'u':
    134 		break;
    135 	default:
    136 		usage();
    137 	} ARGEND;
    138 
    139 	if (argc > 1)
    140 		usage();
    141 	else if (argc == 1)
    142 		dev = argv[0];
    143 
    144 	if ((rflag ^ sflag ^ wflag) == 0)
    145 		eprintf("missing or incompatible function\n");
    146 
    147 	/* Only UTC support at the moment */
    148 	setenv("TZ", "UTC0", 1);
    149 	tzset();
    150 
    151 	if (rflag == 1)
    152 		show(dev);
    153 	else if (sflag == 1)
    154 		hctosys(dev);
    155 	else if (wflag == 1)
    156 		systohc(dev);
    157 
    158 	return 0;
    159 }