Annotation of embedaddon/strongswan/src/libcharon/plugins/certexpire/certexpire_cron.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2011 Martin Willi
        !             3:  * Copyright (C) 2011 revosec AG
        !             4:  *
        !             5:  * This program is free software; you can redistribute it and/or modify it
        !             6:  * under the terms of the GNU General Public License as published by the
        !             7:  * Free Software Foundation; either version 2 of the License, or (at your
        !             8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !             9:  *
        !            10:  * This program is distributed in the hope that it will be useful, but
        !            11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            13:  * for more details.
        !            14:  */
        !            15: 
        !            16: #include "certexpire_cron.h"
        !            17: 
        !            18: #include <time.h>
        !            19: 
        !            20: #include <utils/debug.h>
        !            21: #include <processing/jobs/callback_job.h>
        !            22: 
        !            23: typedef struct private_certexpire_cron_t private_certexpire_cron_t;
        !            24: 
        !            25: /**
        !            26:  * Private data of an certexpire_cron_t object.
        !            27:  */
        !            28: struct private_certexpire_cron_t {
        !            29: 
        !            30:        /**
        !            31:         * Public certexpire_cron_t interface.
        !            32:         */
        !            33:        certexpire_cron_t public;
        !            34: 
        !            35:        /**
        !            36:         * time when to run export job
        !            37:         */
        !            38:        struct {
        !            39:                bool m[60];
        !            40:                bool h[24];
        !            41:                bool d[32];
        !            42:                bool my[13];
        !            43:                bool dw[8];
        !            44:        } cron;
        !            45: 
        !            46:        /**
        !            47:         * Callback function to execute
        !            48:         */
        !            49:        certexpire_cron_job_t job;
        !            50: 
        !            51:        /**
        !            52:         * Data to pass to callback
        !            53:         */
        !            54:        void *data;
        !            55: };
        !            56: 
        !            57: /**
        !            58:  * Check if we should execute the export job
        !            59:  */
        !            60: static job_requeue_t check_cron(private_certexpire_cron_t *this)
        !            61: {
        !            62:        struct tm tm;
        !            63:        time_t t;
        !            64: 
        !            65:        t = time(NULL);
        !            66:        localtime_r(&t, &tm);
        !            67: 
        !            68:        /* recheck every minute at second 0 */
        !            69:        lib->scheduler->schedule_job(lib->scheduler,
        !            70:                        (job_t*)callback_job_create_with_prio((callback_job_cb_t)check_cron,
        !            71:                        this, NULL, NULL, JOB_PRIO_CRITICAL), 60 - tm.tm_sec);
        !            72: 
        !            73:        /* skip this minute if we had a large negative time shift */
        !            74:        if (tm.tm_sec <= 30)
        !            75:        {
        !            76:                if (this->cron.m[tm.tm_min] &&
        !            77:                        this->cron.h[tm.tm_hour] &&
        !            78:                        this->cron.d[tm.tm_mday] &&
        !            79:                        this->cron.my[tm.tm_mon + 1] &&
        !            80:                        (this->cron.dw[tm.tm_wday] ||
        !            81:                         (this->cron.dw[7] && tm.tm_wday == 0)))
        !            82:                {
        !            83:                        this->job(this->data);
        !            84:                }
        !            85:        }
        !            86:        return JOB_REQUEUE_NONE;
        !            87: }
        !            88: 
        !            89: /**
        !            90:  * Parse a cron range component into boolean fields
        !            91:  */
        !            92: static void parse_ranges(bool *fields, char *label, int mi, int ma, char *range)
        !            93: {
        !            94:        enumerator_t *enumerator;
        !            95:        int from, to, i;
        !            96: 
        !            97:        if (streq(range, "*"))
        !            98:        {
        !            99:                for (i = mi; i <= ma; i++)
        !           100:                {
        !           101:                        fields[i] = TRUE;
        !           102:                }
        !           103:        }
        !           104:        else
        !           105:        {
        !           106:                enumerator = enumerator_create_token(range, ",", "");
        !           107:                while (enumerator->enumerate(enumerator, &range))
        !           108:                {
        !           109:                        switch (sscanf(range, "%d-%d", &from, &to))
        !           110:                        {
        !           111:                                case 1: /* single value */
        !           112:                                        if (from >= mi && from <= ma)
        !           113:                                        {
        !           114:                                                fields[from] = TRUE;
        !           115:                                        }
        !           116:                                        else
        !           117:                                        {
        !           118:                                                DBG1(DBG_CFG, "ignoring cron %s %d, out of range",
        !           119:                                                         label, from);
        !           120:                                        }
        !           121:                                        break;
        !           122:                                case 2: /* range */
        !           123:                                        if (from < mi)
        !           124:                                        {
        !           125:                                                DBG1(DBG_CFG, "cron %s out of range, shortening start "
        !           126:                                                         "from %d to %d", label, from, mi);
        !           127:                                                from = mi;
        !           128:                                        }
        !           129:                                        if (to > ma)
        !           130:                                        {
        !           131:                                                DBG1(DBG_CFG, "cron %s out of range, shortening end "
        !           132:                                                         "from %d to %d", label, to, ma);
        !           133:                                                to = ma;
        !           134:                                        }
        !           135:                                        for (i = from; i <= to; i++)
        !           136:                                        {
        !           137:                                                fields[i] = TRUE;
        !           138:                                        }
        !           139:                                        break;
        !           140:                                default:
        !           141:                                        break;
        !           142:                        }
        !           143:                }
        !           144:                enumerator->destroy(enumerator);
        !           145:        }
        !           146:        DBG3(DBG_CFG, "cron job with enabled %ss:", label);
        !           147:        for (i = mi; i <= ma; i++)
        !           148:        {
        !           149:                if (fields[i])
        !           150:                {
        !           151:                        DBG3(DBG_CFG, "  %d", i);
        !           152:                }
        !           153:        }
        !           154: }
        !           155: 
        !           156: /**
        !           157:  * Start cron processing, if configured
        !           158:  */
        !           159: static void start_cron(private_certexpire_cron_t *this, char *cron)
        !           160: {
        !           161:        enumerator_t *enumerator;
        !           162:        int i = 0;
        !           163: 
        !           164:        enumerator = enumerator_create_token(cron, " ", " ");
        !           165:        for (i = 0; i < 5; i++)
        !           166:        {
        !           167:                if (!enumerator->enumerate(enumerator, &cron))
        !           168:                {
        !           169:                        DBG1(DBG_CFG, "cron misses a field, using '*'");
        !           170:                        cron = "*";
        !           171:                }
        !           172:                switch (i)
        !           173:                {
        !           174:                        case 0:
        !           175:                                parse_ranges(this->cron.m, "minute", 0, 59, cron);
        !           176:                                break;
        !           177:                        case 1:
        !           178:                                parse_ranges(this->cron.h, "hour", 0, 23, cron);
        !           179:                                break;
        !           180:                        case 2:
        !           181:                                parse_ranges(this->cron.d, "day", 1, 31, cron);
        !           182:                                break;
        !           183:                        case 3:
        !           184:                                parse_ranges(this->cron.my, "month", 1, 12, cron);
        !           185:                                break;
        !           186:                        case 4:
        !           187:                                parse_ranges(this->cron.dw, "weekday", 0, 7, cron);
        !           188:                                break;
        !           189:                        default:
        !           190:                                break;
        !           191:                }
        !           192:        }
        !           193:        if (enumerator->enumerate(enumerator, &cron))
        !           194:        {
        !           195:                DBG1(DBG_CFG, "ignoring extra fields in cron");
        !           196:        }
        !           197:        enumerator->destroy(enumerator);
        !           198: 
        !           199:        check_cron(this);
        !           200: }
        !           201: 
        !           202: METHOD(certexpire_cron_t, destroy, void,
        !           203:        private_certexpire_cron_t *this)
        !           204: {
        !           205:        free(this);
        !           206: }
        !           207: 
        !           208: /**
        !           209:  * See header
        !           210:  */
        !           211: certexpire_cron_t *certexpire_cron_create(char *cron, certexpire_cron_job_t job,
        !           212:                                                                                  void *data)
        !           213: {
        !           214:        private_certexpire_cron_t *this;
        !           215: 
        !           216:        INIT(this,
        !           217:                .public = {
        !           218:                        .destroy = _destroy,
        !           219:                },
        !           220:                .job = job,
        !           221:                .data = data,
        !           222:        );
        !           223: 
        !           224:        start_cron(this, cron);
        !           225: 
        !           226:        return &this->public;
        !           227: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>