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 }