1
0
mirror of https://github.com/systemd/systemd.git synced 2024-11-07 01:27:11 +03:00

basic: calendarspec UTC support

Just add " UTC" to the end of the event expression. Works for the
special expressions.
This commit is contained in:
Hristo Venev 2015-10-15 02:57:59 +03:00
parent d08a6b02b5
commit 51ffa239e8
2 changed files with 22 additions and 14 deletions

View File

@ -279,6 +279,9 @@ int calendar_spec_to_string(const CalendarSpec *c, char **p) {
fputc(':', f); fputc(':', f);
format_chain(f, 2, c->second); format_chain(f, 2, c->second);
if (c->utc)
fputs(" UTC", f);
r = fflush_and_check(f); r = fflush_and_check(f);
if (r < 0) { if (r < 0) {
free(buf); free(buf);
@ -657,6 +660,10 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
if (!c) if (!c)
return -ENOMEM; return -ENOMEM;
c->utc = endswith_no_case(p, "UTC");
if (c->utc)
p = strndupa(p, strlen(p) - strlen(" UTC"));
if (strcaseeq(p, "minutely")) { if (strcaseeq(p, "minutely")) {
r = const_chain(0, &c->second); r = const_chain(0, &c->second);
if (r < 0) if (r < 0)
@ -859,13 +866,13 @@ static int find_matching_component(const CalendarComponent *c, int *val) {
return r; return r;
} }
static bool tm_out_of_bounds(const struct tm *tm) { static bool tm_out_of_bounds(const struct tm *tm, bool utc) {
struct tm t; struct tm t;
assert(tm); assert(tm);
t = *tm; t = *tm;
if (mktime(&t) == (time_t) -1) if (mktime_or_timegm(&t, utc) == (time_t) -1)
return true; return true;
/* Did any normalization take place? If so, it was out of bounds before */ /* Did any normalization take place? If so, it was out of bounds before */
@ -878,7 +885,7 @@ static bool tm_out_of_bounds(const struct tm *tm) {
t.tm_sec != tm->tm_sec; t.tm_sec != tm->tm_sec;
} }
static bool matches_weekday(int weekdays_bits, const struct tm *tm) { static bool matches_weekday(int weekdays_bits, const struct tm *tm, bool utc) {
struct tm t; struct tm t;
int k; int k;
@ -886,7 +893,7 @@ static bool matches_weekday(int weekdays_bits, const struct tm *tm) {
return true; return true;
t = *tm; t = *tm;
if (mktime(&t) == (time_t) -1) if (mktime_or_timegm(&t, utc) == (time_t) -1)
return false; return false;
k = t.tm_wday == 0 ? 6 : t.tm_wday - 1; k = t.tm_wday == 0 ? 6 : t.tm_wday - 1;
@ -904,7 +911,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) {
for (;;) { for (;;) {
/* Normalize the current date */ /* Normalize the current date */
mktime(&c); mktime_or_timegm(&c, spec->utc);
c.tm_isdst = -1; c.tm_isdst = -1;
c.tm_year += 1900; c.tm_year += 1900;
@ -916,7 +923,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) {
c.tm_mday = 1; c.tm_mday = 1;
c.tm_hour = c.tm_min = c.tm_sec = 0; c.tm_hour = c.tm_min = c.tm_sec = 0;
} }
if (r < 0 || tm_out_of_bounds(&c)) if (r < 0 || tm_out_of_bounds(&c, spec->utc))
return r; return r;
c.tm_mon += 1; c.tm_mon += 1;
@ -927,7 +934,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) {
c.tm_mday = 1; c.tm_mday = 1;
c.tm_hour = c.tm_min = c.tm_sec = 0; c.tm_hour = c.tm_min = c.tm_sec = 0;
} }
if (r < 0 || tm_out_of_bounds(&c)) { if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
c.tm_year ++; c.tm_year ++;
c.tm_mon = 0; c.tm_mon = 0;
c.tm_mday = 1; c.tm_mday = 1;
@ -938,14 +945,14 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) {
r = find_matching_component(spec->day, &c.tm_mday); r = find_matching_component(spec->day, &c.tm_mday);
if (r > 0) if (r > 0)
c.tm_hour = c.tm_min = c.tm_sec = 0; c.tm_hour = c.tm_min = c.tm_sec = 0;
if (r < 0 || tm_out_of_bounds(&c)) { if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
c.tm_mon ++; c.tm_mon ++;
c.tm_mday = 1; c.tm_mday = 1;
c.tm_hour = c.tm_min = c.tm_sec = 0; c.tm_hour = c.tm_min = c.tm_sec = 0;
continue; continue;
} }
if (!matches_weekday(spec->weekdays_bits, &c)) { if (!matches_weekday(spec->weekdays_bits, &c, spec->utc)) {
c.tm_mday++; c.tm_mday++;
c.tm_hour = c.tm_min = c.tm_sec = 0; c.tm_hour = c.tm_min = c.tm_sec = 0;
continue; continue;
@ -954,7 +961,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) {
r = find_matching_component(spec->hour, &c.tm_hour); r = find_matching_component(spec->hour, &c.tm_hour);
if (r > 0) if (r > 0)
c.tm_min = c.tm_sec = 0; c.tm_min = c.tm_sec = 0;
if (r < 0 || tm_out_of_bounds(&c)) { if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
c.tm_mday ++; c.tm_mday ++;
c.tm_hour = c.tm_min = c.tm_sec = 0; c.tm_hour = c.tm_min = c.tm_sec = 0;
continue; continue;
@ -963,14 +970,14 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) {
r = find_matching_component(spec->minute, &c.tm_min); r = find_matching_component(spec->minute, &c.tm_min);
if (r > 0) if (r > 0)
c.tm_sec = 0; c.tm_sec = 0;
if (r < 0 || tm_out_of_bounds(&c)) { if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
c.tm_hour ++; c.tm_hour ++;
c.tm_min = c.tm_sec = 0; c.tm_min = c.tm_sec = 0;
continue; continue;
} }
r = find_matching_component(spec->second, &c.tm_sec); r = find_matching_component(spec->second, &c.tm_sec);
if (r < 0 || tm_out_of_bounds(&c)) { if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
c.tm_min ++; c.tm_min ++;
c.tm_sec = 0; c.tm_sec = 0;
continue; continue;
@ -991,13 +998,13 @@ int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next)
assert(next); assert(next);
t = (time_t) (usec / USEC_PER_SEC) + 1; t = (time_t) (usec / USEC_PER_SEC) + 1;
assert_se(localtime_r(&t, &tm)); assert_se(localtime_or_gmtime_r(&t, &tm, spec->utc));
r = find_next(spec, &tm); r = find_next(spec, &tm);
if (r < 0) if (r < 0)
return r; return r;
t = mktime(&tm); t = mktime_or_timegm(&tm, spec->utc);
if (t == (time_t) -1) if (t == (time_t) -1)
return -EINVAL; return -EINVAL;

View File

@ -36,6 +36,7 @@ typedef struct CalendarComponent {
typedef struct CalendarSpec { typedef struct CalendarSpec {
int weekdays_bits; int weekdays_bits;
bool utc;
CalendarComponent *year; CalendarComponent *year;
CalendarComponent *month; CalendarComponent *month;