Example #1
0
int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
        const char *utc;
        CalendarSpec *c;
        int r;

        assert(p);
        assert(spec);

        c = new0(CalendarSpec, 1);
        if (!c)
                return -ENOMEM;
        c->dst = -1;
        c->timezone = NULL;

        utc = endswith_no_case(p, " UTC");
        if (utc) {
                c->utc = true;
                p = strndupa(p, utc - p);
        } else {
                const char *e = NULL;
                int j;

                tzset();

                /* Check if the local timezone was specified? */
                for (j = 0; j <= 1; j++) {
                        if (isempty(tzname[j]))
                                continue;

                        e = endswith_no_case(p, tzname[j]);
                        if (!e)
                                continue;
                        if (e == p)
                                continue;
                        if (e[-1] != ' ')
                                continue;

                        break;
                }

                /* Found one of the two timezones specified? */
                if (IN_SET(j, 0, 1)) {
                        p = strndupa(p, e - p - 1);
                        c->dst = j;
                } else {
                        const char *last_space;

                        last_space = strrchr(p, ' ');
                        if (last_space != NULL && timezone_is_valid(last_space + 1)) {
                                c->timezone = strdup(last_space + 1);
                                if (!c->timezone) {
                                        r = -ENOMEM;
                                        goto fail;
                                }

                                p = strndupa(p, last_space - p);
                        }
                }
        }

        if (isempty(p)) {
                r = -EINVAL;
                goto fail;
        }

        if (strcaseeq(p, "minutely")) {
                r = const_chain(0, &c->microsecond);
                if (r < 0)
                        goto fail;

        } else if (strcaseeq(p, "hourly")) {
                r = const_chain(0, &c->minute);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->microsecond);
                if (r < 0)
                        goto fail;

        } else if (strcaseeq(p, "daily")) {
                r = const_chain(0, &c->hour);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->minute);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->microsecond);
                if (r < 0)
                        goto fail;

        } else if (strcaseeq(p, "monthly")) {
                r = const_chain(1, &c->day);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->hour);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->minute);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->microsecond);
                if (r < 0)
                        goto fail;

        } else if (strcaseeq(p, "annually") ||
                   strcaseeq(p, "yearly") ||
                   strcaseeq(p, "anually") /* backwards compatibility */ ) {

                r = const_chain(1, &c->month);
                if (r < 0)
                        goto fail;
                r = const_chain(1, &c->day);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->hour);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->minute);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->microsecond);
                if (r < 0)
                        goto fail;

        } else if (strcaseeq(p, "weekly")) {

                c->weekdays_bits = 1;

                r = const_chain(0, &c->hour);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->minute);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->microsecond);
                if (r < 0)
                        goto fail;

        } else if (strcaseeq(p, "quarterly")) {

                r = const_chain(1, &c->month);
                if (r < 0)
                        goto fail;
                r = const_chain(4, &c->month);
                if (r < 0)
                        goto fail;
                r = const_chain(7, &c->month);
                if (r < 0)
                        goto fail;
                r = const_chain(10, &c->month);
                if (r < 0)
                        goto fail;
                r = const_chain(1, &c->day);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->hour);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->minute);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->microsecond);
                if (r < 0)
                        goto fail;

        } else if (strcaseeq(p, "biannually") ||
                   strcaseeq(p, "bi-annually") ||
                   strcaseeq(p, "semiannually") ||
                   strcaseeq(p, "semi-annually")) {

                r = const_chain(1, &c->month);
                if (r < 0)
                        goto fail;
                r = const_chain(7, &c->month);
                if (r < 0)
                        goto fail;
                r = const_chain(1, &c->day);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->hour);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->minute);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->microsecond);
                if (r < 0)
                        goto fail;

        } else {
                r = parse_weekdays(&p, c);
                if (r < 0)
                        goto fail;

                r = parse_date(&p, c);
                if (r < 0)
                        goto fail;

                if (r == 0) {
                        r = parse_calendar_time(&p, c);
                        if (r < 0)
                                goto fail;
                }

                if (*p != 0) {
                        r = -EINVAL;
                        goto fail;
                }
        }

        r = calendar_spec_normalize(c);
        if (r < 0)
                goto fail;

        if (!calendar_spec_valid(c)) {
                r = -EINVAL;
                goto fail;
        }

        *spec = c;
        return 0;

fail:
        calendar_spec_free(c);
        return r;
}
Example #2
0
int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
        CalendarSpec *c;
        int r;

        assert(p);
        assert(spec);

        if (isempty(p))
                return -EINVAL;

        c = new0(CalendarSpec, 1);
        if (!c)
                return -ENOMEM;

        if (strcaseeq(p, "hourly")) {
                r = const_chain(0, &c->minute);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->second);
                if (r < 0)
                        goto fail;

        } else if (strcaseeq(p, "daily")) {
                r = const_chain(0, &c->hour);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->minute);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->second);
                if (r < 0)
                        goto fail;

        } else if (strcaseeq(p, "monthly")) {
                r = const_chain(1, &c->day);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->hour);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->minute);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->second);
                if (r < 0)
                        goto fail;

        } else if (strcaseeq(p, "weekly")) {

                c->weekdays_bits = 1;

                r = const_chain(0, &c->hour);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->minute);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->second);
                if (r < 0)
                        goto fail;

        } else {
                r = parse_weekdays(&p, c);
                if (r < 0)
                        goto fail;

                r = parse_date(&p, c);
                if (r < 0)
                        goto fail;

                r = parse_time(&p, c);
                if (r < 0)
                        goto fail;

                if (*p != 0) {
                        r = -EINVAL;
                        goto fail;
                }
        }

        r = calendar_spec_normalize(c);
        if (r < 0)
                goto fail;

        if (!calendar_spec_valid(c)) {
                r = -EINVAL;
                goto fail;
        }

        *spec = c;
        return 0;

fail:
        calendar_spec_free(c);
        return r;
}
Example #3
0
int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
        CalendarSpec *c;
        int r;
        const char *utc;

        assert(p);
        assert(spec);

        if (isempty(p))
                return -EINVAL;

        c = new0(CalendarSpec, 1);
        if (!c)
                return -ENOMEM;

        utc = endswith_no_case(p, " UTC");
        if (utc) {
                c->utc = true;
                p = strndupa(p, utc - p);
        }

        if (strcaseeq(p, "minutely")) {
                r = const_chain(0, &c->second);
                if (r < 0)
                        goto fail;

        } else if (strcaseeq(p, "hourly")) {
                r = const_chain(0, &c->minute);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->second);
                if (r < 0)
                        goto fail;

        } else if (strcaseeq(p, "daily")) {
                r = const_chain(0, &c->hour);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->minute);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->second);
                if (r < 0)
                        goto fail;

        } else if (strcaseeq(p, "monthly")) {
                r = const_chain(1, &c->day);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->hour);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->minute);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->second);
                if (r < 0)
                        goto fail;

        } else if (strcaseeq(p, "annually") ||
                   strcaseeq(p, "yearly") ||
                   strcaseeq(p, "anually") /* backwards compatibility */ ) {

                r = const_chain(1, &c->month);
                if (r < 0)
                        goto fail;
                r = const_chain(1, &c->day);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->hour);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->minute);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->second);
                if (r < 0)
                        goto fail;

        } else if (strcaseeq(p, "weekly")) {

                c->weekdays_bits = 1;

                r = const_chain(0, &c->hour);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->minute);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->second);
                if (r < 0)
                        goto fail;

        } else if (strcaseeq(p, "quarterly")) {

                r = const_chain(1, &c->month);
                if (r < 0)
                        goto fail;
                r = const_chain(4, &c->month);
                if (r < 0)
                        goto fail;
                r = const_chain(7, &c->month);
                if (r < 0)
                        goto fail;
                r = const_chain(10, &c->month);
                if (r < 0)
                        goto fail;
                r = const_chain(1, &c->day);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->hour);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->minute);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->second);
                if (r < 0)
                        goto fail;

        } else if (strcaseeq(p, "biannually") ||
                   strcaseeq(p, "bi-annually") ||
                   strcaseeq(p, "semiannually") ||
                   strcaseeq(p, "semi-annually")) {

                r = const_chain(1, &c->month);
                if (r < 0)
                        goto fail;
                r = const_chain(7, &c->month);
                if (r < 0)
                        goto fail;
                r = const_chain(1, &c->day);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->hour);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->minute);
                if (r < 0)
                        goto fail;
                r = const_chain(0, &c->second);
                if (r < 0)
                        goto fail;

        } else {
                r = parse_weekdays(&p, c);
                if (r < 0)
                        goto fail;

                r = parse_date(&p, c);
                if (r < 0)
                        goto fail;

                r = parse_time(&p, c);
                if (r < 0)
                        goto fail;

                if (*p != 0) {
                        r = -EINVAL;
                        goto fail;
                }
        }

        r = calendar_spec_normalize(c);
        if (r < 0)
                goto fail;

        if (!calendar_spec_valid(c)) {
                r = -EINVAL;
                goto fail;
        }

        *spec = c;
        return 0;

fail:
        calendar_spec_free(c);
        return r;
}