| 136 | } |
| 137 | |
| 138 | int |
| 139 | clock_ct_to_ts(const struct clocktime *ct, struct timespec *ts) |
| 140 | { |
| 141 | int i, year, days; |
| 142 | |
| 143 | if (ct_debug) { |
| 144 | printf("ct_to_ts(["); |
| 145 | clock_print_ct(ct, 9); |
| 146 | printf("])"); |
| 147 | } |
| 148 | |
| 149 | /* |
| 150 | * Many realtime clocks store the year as 2-digit BCD; pivot on 70 to |
| 151 | * determine century. Some clocks have a "century bit" and drivers do |
| 152 | * year += 100, so interpret values between 70-199 as relative to 1900. |
| 153 | */ |
| 154 | year = ct->year; |
| 155 | if (year < 70) |
| 156 | year += 2000; |
| 157 | else if (year < 200) |
| 158 | year += 1900; |
| 159 | |
| 160 | /* Sanity checks. */ |
| 161 | if (ct->mon < 1 || ct->mon > 12 || ct->day < 1 || |
| 162 | ct->day > days_in_month(year, ct->mon) || |
| 163 | ct->hour > 23 || ct->min > 59 || ct->sec > 59 || year < 1970 || |
| 164 | (sizeof(time_t) == 4 && year > 2037)) { /* time_t overflow */ |
| 165 | if (ct_debug) |
| 166 | printf(" = EINVAL\n"); |
| 167 | return (EINVAL); |
| 168 | } |
| 169 | |
| 170 | /* |
| 171 | * Compute days since start of time |
| 172 | * First from years, then from months. |
| 173 | */ |
| 174 | if (year >= recent_base_year) { |
| 175 | i = recent_base_year; |
| 176 | days = recent_base_days; |
| 177 | } else { |
| 178 | i = POSIX_BASE_YEAR; |
| 179 | days = 0; |
| 180 | } |
| 181 | for (; i < year; i++) |
| 182 | days += days_in_year(i); |
| 183 | |
| 184 | /* Months */ |
| 185 | for (i = 1; i < ct->mon; i++) |
| 186 | days += days_in_month(year, i); |
| 187 | days += (ct->day - 1); |
| 188 | |
| 189 | ts->tv_sec = (((time_t)days * 24 + ct->hour) * 60 + ct->min) * 60 + |
| 190 | ct->sec; |
| 191 | ts->tv_nsec = ct->nsec; |
| 192 | |
| 193 | if (ct_debug) |
| 194 | printf(" = %jd.%09ld\n", (intmax_t)ts->tv_sec, ts->tv_nsec); |
| 195 | return (0); |
no test coverage detected