Mercurial > dovecot > core-2.2
view src/lib/utc-mktime.c @ 22664:fea53c2725c0
director: Fix director_max_parallel_moves/kicks type
Should be uint, not time.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Thu, 09 Nov 2017 12:24:16 +0200 |
parents | c4584d7dc07e |
children | cb108f786fb4 |
line wrap: on
line source
/* Copyright (c) 2007-2017 Dovecot authors, see the included COPYING file */ #include "lib.h" #include "utc-mktime.h" static int tm_cmp(const struct tm *tm1, const struct tm *tm2) { int diff; if ((diff = tm1->tm_year - tm2->tm_year) != 0) return diff; if ((diff = tm1->tm_mon - tm2->tm_mon) != 0) return diff; if ((diff = tm1->tm_mday - tm2->tm_mday) != 0) return diff; if ((diff = tm1->tm_hour - tm2->tm_hour) != 0) return diff; if ((diff = tm1->tm_min - tm2->tm_min) != 0) return diff; return tm1->tm_sec - tm2->tm_sec; } static inline void adjust_leap_second(struct tm *tm) { if (tm->tm_sec == 60) tm->tm_sec = 59; } #ifdef HAVE_TIMEGM /* Normalization done by timegm is considered a failure here, since it means * the timestamp is not valid as-is. Leap second 60 is adjusted to 59 before * this though. */ time_t utc_mktime(const struct tm *tm) { struct tm leap_adj_tm = *tm; adjust_leap_second(&leap_adj_tm); struct tm tmp = leap_adj_tm; time_t t; t = timegm(&tmp); if (tm_cmp(&leap_adj_tm, &tmp) != 0) return (time_t)-1; return t; } #else time_t utc_mktime(const struct tm *tm) { struct tm leap_adj_tm = *tm; adjust_leap_second(&leap_adj_tm); const struct tm *try_tm; time_t t; int bits, dir; /* we'll do a binary search across the entire valid time_t range. when gmtime()'s output matches the tm parameter, we've found the correct time_t value. this also means that if tm contains invalid values, -1 is returned. */ #ifdef TIME_T_SIGNED t = 0; #else t = (time_t)1 << (TIME_T_MAX_BITS - 1); #endif for (bits = TIME_T_MAX_BITS - 2;; bits--) { try_tm = gmtime(&t); dir = tm_cmp(&leap_adj_tm, try_tm); if (dir == 0) return t; if (bits < 0) break; if (dir < 0) t -= (time_t)1 << bits; else t += (time_t)1 << bits; } return (time_t)-1; } #endif