Return to certexpire_cron.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / plugins / certexpire |
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: }