| 196 | } |
| 197 | |
| 198 | int |
| 199 | clock_bcd_to_ts(const struct bcd_clocktime *bct, struct timespec *ts, bool ampm) |
| 200 | { |
| 201 | struct clocktime ct; |
| 202 | int bcent, byear; |
| 203 | |
| 204 | /* |
| 205 | * Year may come in as 2-digit or 4-digit BCD. Split the value into |
| 206 | * separate BCD century and year values for validation and conversion. |
| 207 | */ |
| 208 | bcent = bct->year >> 8; |
| 209 | byear = bct->year & 0xff; |
| 210 | |
| 211 | /* |
| 212 | * Ensure that all values are valid BCD numbers, to avoid assertions in |
| 213 | * the BCD-to-binary conversion routines. clock_ct_to_ts() will further |
| 214 | * validate the field ranges (such as 0 <= min <= 59) during conversion. |
| 215 | */ |
| 216 | if (!validbcd(bcent) || !validbcd(byear) || !validbcd(bct->mon) || |
| 217 | !validbcd(bct->day) || !validbcd(bct->hour) || |
| 218 | !validbcd(bct->min) || !validbcd(bct->sec)) { |
| 219 | if (ct_debug) |
| 220 | printf("clock_bcd_to_ts: bad BCD: " |
| 221 | "[%04x-%02x-%02x %02x:%02x:%02x]\n", |
| 222 | bct->year, bct->mon, bct->day, |
| 223 | bct->hour, bct->min, bct->sec); |
| 224 | return (EINVAL); |
| 225 | } |
| 226 | |
| 227 | ct.year = FROMBCD(byear) + FROMBCD(bcent) * 100; |
| 228 | ct.mon = FROMBCD(bct->mon); |
| 229 | ct.day = FROMBCD(bct->day); |
| 230 | ct.hour = FROMBCD(bct->hour); |
| 231 | ct.min = FROMBCD(bct->min); |
| 232 | ct.sec = FROMBCD(bct->sec); |
| 233 | ct.dow = bct->dow; |
| 234 | ct.nsec = bct->nsec; |
| 235 | |
| 236 | /* If asked to handle am/pm, convert from 12hr+pmflag to 24hr. */ |
| 237 | if (ampm) { |
| 238 | if (ct.hour == 12) |
| 239 | ct.hour = 0; |
| 240 | if (bct->ispm) |
| 241 | ct.hour += 12; |
| 242 | } |
| 243 | |
| 244 | return (clock_ct_to_ts(&ct, ts)); |
| 245 | } |
| 246 | |
| 247 | void |
| 248 | clock_ts_to_ct(const struct timespec *ts, struct clocktime *ct) |
no test coverage detected