#include "entry.h" #include static int sub_inc_year(struct tm *t, int n) { if (n == 0) return 0; t->tm_year += n; if (mktime(t) == -1) return -1; return 0; } static int sub_inc_month(struct tm *t, int n) { unsigned i; if (n == 0) return 0; for (i = 0; i < n; i++) { t->tm_mon++; if (mktime(t) == -1) { t->tm_mon = 0; if (sub_inc_year(t, 1) == -1) return -1; } } return 0; } static int sub_inc_day(struct tm *t, int n) { unsigned i; if (n == 0) return 0; for (i = 0; i < n; i++) { t->tm_mday++; if (mktime(t) == -1) { t->tm_mday = 1; if (sub_inc_month(t, 1) == -1) return -1; } } return 0; } static int sub_inc_hour(struct tm *t, int n) { unsigned i; if (n == 0) return 0; for (i = 0; i < n; i++) { t->tm_hour++; if (mktime(t) == -1) { t->tm_hour = 0; if (sub_inc_day(t, 1) == -1) return -1; } } return 0; } static int sub_inc_minute(struct tm *t, int n) { unsigned i; if (n == 0) return 0; for (i = 0; i < n; i++) { t->tm_min++; if (mktime(t) == -1) { t->tm_min = 0; if (sub_inc_hour(t, 1) == -1) return -1; } } return 0; } static int sub_inc_second(struct tm *t, int n) { time_t r; struct tm *tmp; if (n == 0) return 0; r = mktime(t); if (r + n <= r) return -1; r += n; tmp = localtime(&r); *t = *tmp; return 0; } /* super inefficient, but should best-possible avoid any weird leap * years/seconds/dst-problems/other future changes */ bool entry_is_active(struct entry_s *e, time_t now) { struct tm t, *tmp; time_t rtmp, now_plus_warn; assert(e != NULL); tmp = localtime(&now); assert(tmp != NULL); t = *tmp; if (sub_inc_year(&t, e->warn.year)) return false; if (sub_inc_month(&t, e->warn.month)) return false; if (sub_inc_day(&t, e->warn.day)) return false; if (sub_inc_hour(&t, e->warn.hour)) return false; if (sub_inc_minute(&t, e->warn.minute)) return false; if (sub_inc_second(&t, e->warn.second)) return false; now_plus_warn = mktime(&t); if (e->type == ENTRY_TYPE_ON) { if (e->start >= now && e->start <= now_plus_warn) return true; return false; } tmp = localtime(&(e->start)); assert(tmp != NULL); t = *tmp; if (e->has_end && now > e->end) return false; for (rtmp = e->start;;) { rtmp = mktime(&t); if (rtmp > now_plus_warn) return false; if (rtmp >= now) return true; if (sub_inc_year(&t, e->every.year)) return false; if (sub_inc_month(&t, e->every.month)) return false; if (sub_inc_day(&t, e->every.day)) return false; if (sub_inc_hour(&t, e->every.hour)) return false; if (sub_inc_minute(&t, e->every.minute)) return false; if (sub_inc_second(&t, e->every.second)) return false; } }