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