1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108:
109:
110: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123: $PC_cronTab = $cfg['path']['contenido_cronlog'] . 'crontab.txt';
124: $PC_localCronTab = $cfg['path']['contenido_cronlog'] . 'crontab.local.txt';
125:
126:
127:
128: $PC_writeDir = $cfg['path']['contenido_cronlog'];
129:
130:
131:
132: $PC_jobDir = cRegistry::getBackendPath() . $cfg['path']['cronjobs'];
133:
134:
135: $PC_reqDir = getcwd();
136:
137:
138: $PC_useLog = 1;
139:
140:
141:
142: $PC_debug = false;
143:
144:
145:
146:
147:
148: define("PC_MINUTE", 1);
149: define("PC_HOUR", 2);
150: define("PC_DOM", 3);
151: define("PC_MONTH", 4);
152: define("PC_DOW", 5);
153: define("PC_CMD", 7);
154: define("PC_CRONLINE", 8);
155:
156: if ($PC_debug) {
157: echo "<pre>Configuration:";
158: echo "\nPC_cronTab = " . $PC_cronTab;
159: echo "\nPC_writeDir = " . $PC_writeDir;
160: echo "\nPC_jobDir = " . $PC_jobDir;
161: echo "\nPC_reqDir = " . $PC_reqDir;
162: echo "\nPC_useLog = " . $PC_useLog;
163: echo "\n";
164: }
165:
166: global $bJobRunned;
167:
168: $bJobRunned = false;
169:
170: chdir($PC_jobDir);
171: $PC_jobs = parseCronFile($PC_cronTab, $PC_debug);
172:
173: for ($i = 0; $i < count($PC_jobs); $i++) {
174: $bJobRunned = true;
175: runJob($PC_jobs[$i], $PC_jobDir, $PC_writeDir, $PC_useLog, $PC_debug);
176: }
177:
178: $PC_jobs = parseCronFile($PC_localCronTab, $PC_debug);
179: for ($i = 0; $i < count($PC_jobs); $i++) {
180: $bJobRunned = true;
181: runJob($PC_jobs[$i], $PC_jobDir, $PC_writeDir, $PC_useLog, $PC_debug);
182: }
183: chdir($PC_reqDir);
184:
185: if ($PC_debug) {
186: echo "\n</pre>";
187: }
188:
189: 190: 191: 192: 193: 194: 195:
196: function logMessage($msg, $PC_writeDir, $PC_useLog, $PC_debug) {
197: if ($PC_useLog == 1) {
198: $logfile = $PC_writeDir . "pseudo-cron.log";
199:
200: if (is_writable($logfile)) {
201: $file = fopen($logfile, "ab");
202: if ($msg[cString::getStringLength($msg) - 1] != "\n") {
203: $msg.="\r\n";
204: }
205: if ($PC_debug) {
206: echo $msg;
207: }
208: fputs($file, date("r", time()) . " " . $msg);
209: fclose($file);
210: }
211: }
212: }
213:
214: 215: 216: 217: 218:
219: function lTrimZeros($number)
220: {
221: return (int)ltrim($number, '0');
222: }
223:
224: 225: 226: 227: 228: 229:
230: function parseElement($element, &$targetArray, $numberOfElements) {
231: $subelements = explode(",", $element);
232: for ($i = 0; $i < $numberOfElements; $i++) {
233: $targetArray[$i] = $subelements[0] == "*";
234: }
235:
236: for ($i = 0; $i < count($subelements); $i++) {
237: if (preg_match("~^(\\*|([0-9]{1,2})(-([0-9]{1,2}))?)(/([0-9]{1,2}))?$~", $subelements[$i], $matches)) {
238: if ($matches[1] == "*") {
239: $matches[2] = 0;
240: $matches[4] = $numberOfElements;
241: } elseif (!array_key_exists(4, $matches) || $matches[4] == "") {
242: $matches[4] = $matches[2];
243: }
244: if (array_key_exists(5, $matches)) {
245: if ($matches[5][0] != "/") {
246: $matches[6] = 1;
247: }
248: } else {
249: $matches[6] = 1;
250: }
251: for ($j = lTrimZeros($matches[2]); $j <= lTrimZeros($matches[4]); $j+=lTrimZeros($matches[6])) {
252: $targetArray[$j] = TRUE;
253: }
254: }
255: }
256: }
257:
258: 259: 260: 261: 262: 263: 264:
265: function decDate(&$dateArr, $amount, $unit, $PC_debug) {
266: if ($PC_debug) {
267: echo sprintf("Decreasing from %02d.%02d. %02d:%02d by %d %6s ", $dateArr['mday'], $dateArr['mon'], $dateArr['hours'], $dateArr['minutes'], $amount, $unit);
268: }
269: if ($unit == "mday") {
270: $dateArr["hours"] = 23;
271: $dateArr["minutes"] = 59;
272: $dateArr["seconds"] = 59;
273: $dateArr["mday"] -= $amount;
274: $dateArr["wday"] -= $amount % 7;
275: if ($dateArr["wday"] < 0) {
276: $dateArr["wday"]+=7;
277: }
278: if ($dateArr["mday"] < 1) {
279: $dateArr["mon"]--;
280: switch ($dateArr["mon"]) {
281: case 0:
282: $dateArr["mon"] = 12;
283: $dateArr["year"]--;
284:
285: case 1:
286: case 3:
287: case 5:
288: case 7:
289: case 8:
290: case 10:
291: case 12:
292: $dateArr["mday"] = 31;
293: break;
294: case 4:
295: case 6:
296: case 9:
297: case 11:
298: $dateArr["mday"] = 30;
299: break;
300: case 2:
301: $dateArr["mday"] = 28;
302: break;
303: }
304: }
305: } elseif ($unit == "hour") {
306: if ($dateArr["hours"] == 0) {
307: decDate($dateArr, 1, "mday", $PC_debug);
308: } else {
309: $dateArr["minutes"] = 59;
310: $dateArr["seconds"] = 59;
311: $dateArr["hours"]--;
312: }
313: } elseif ($unit == "minute") {
314: if ($dateArr["minutes"] == 0) {
315: decDate($dateArr, 1, "hour", $PC_debug);
316: } else {
317: $dateArr["seconds"] = 59;
318: $dateArr["minutes"]--;
319: }
320: }
321: if ($PC_debug) {
322: echo sprintf("to %02d.%02d. %02d:%02d\n", $dateArr['mday'], $dateArr['mon'], $dateArr['hours'], $dateArr['minutes']);
323: }
324: }
325:
326: 327: 328: 329: 330: 331:
332: function getLastScheduledRunTime($job, $PC_debug) {
333: $dateArr = getdate();
334: $minutesBack = 0;
335: while (
336: $minutesBack < 525600 AND
337: (!$job[PC_MINUTE][$dateArr["minutes"]] OR
338: !$job[PC_HOUR][$dateArr["hours"]] OR
339: (!$job[PC_DOM][$dateArr["mday"]] OR !$job[PC_DOW][$dateArr["wday"]]) OR
340: !$job[PC_MONTH][$dateArr["mon"]])
341: ) {
342: if (!$job[PC_DOM][$dateArr["mday"]] OR !$job[PC_DOW][$dateArr["wday"]]) {
343: decDate($dateArr, 1, "mday", $PC_debug);
344: $minutesBack+=1440;
345: continue;
346: }
347: if (!$job[PC_HOUR][$dateArr["hours"]]) {
348: decDate($dateArr, 1, "hour", $PC_debug);
349: $minutesBack+=60;
350: continue;
351: }
352: if (!$job[PC_MINUTE][$dateArr["minutes"]]) {
353: decDate($dateArr, 1, "minute", $PC_debug);
354: $minutesBack++;
355: continue;
356: }
357: }
358:
359: if ($PC_debug) {
360: print_r($dateArr);
361: }
362:
363: return mktime($dateArr["hours"], $dateArr["minutes"], 0, $dateArr["mon"], $dateArr["mday"], $dateArr["year"]);
364: }
365:
366: 367: 368: 369: 370: 371:
372: function getJobFileName($jobname, $PC_writeDir) {
373: $jobfile = $PC_writeDir . urlencode($jobname) . ".job";
374: return $jobfile;
375: }
376:
377: 378: 379: 380: 381: 382:
383: function getLastActialRunTime($jobname, $PC_writeDir) {
384: $jobfile = getJobFileName($jobname, $PC_writeDir);
385: if (cFileHandler::exists($jobfile)) {
386: $file = fopen($jobfile, "rb");
387: $lastRun = fgets($file, 100);
388: fclose($file);
389: if (is_numeric($lastRun)) {
390: return $lastRun;
391: }
392: }
393: return 0;
394: }
395:
396: 397: 398: 399: 400: 401:
402: function markLastRun($jobname, $lastRun, $PC_writeDir) {
403: $jobfile = getJobFileName($jobname, $PC_writeDir);
404:
405: if ($file = @fopen($jobfile, "w")) {
406: fputs($file, $lastRun);
407: fclose($file);
408: } else {
409:
410: }
411: }
412:
413: 414: 415: 416: 417: 418: 419: 420: 421: 422:
423: function runJob($job, $PC_jobDir, $PC_writeDir, $PC_useLog, $PC_debug = false) {
424: global $sess;
425: $extjob = array();
426:
427: parseElement($job[PC_MINUTE], $extjob[PC_MINUTE], 60);
428: parseElement($job[PC_HOUR], $extjob[PC_HOUR], 24);
429: parseElement($job[PC_DOM], $extjob[PC_DOM], 31);
430: parseElement($job[PC_MONTH], $extjob[PC_MONTH], 12);
431: parseElement($job[PC_DOW], $extjob[PC_DOW], 7);
432:
433: $lastActual = getLastActialRunTime($job[PC_CMD], $PC_writeDir);
434: $lastScheduled = getLastScheduledRunTime($extjob, $PC_debug);
435:
436: if ($lastScheduled > $lastActual) {
437: logMessage("Running " . $job[PC_CRONLINE], $PC_writeDir, $PC_useLog, $PC_debug);
438: logMessage(" Last run: " . date("r", $lastActual), $PC_writeDir, $PC_useLog, $PC_debug);
439: logMessage(" Last scheduled: " . date("r", $lastScheduled), $PC_writeDir, $PC_useLog, $PC_debug);
440: markLastRun($job[PC_CMD], $lastScheduled, $PC_writeDir);
441:
442: if ($PC_debug) {
443: echo getcwd();
444: include($PC_jobDir . $job[PC_CMD]);
445: } else {
446: if (is_object($sess)) {
447: $sess->freeze();
448: }
449: @include($PC_jobDir . $job[PC_CMD]);
450: if (is_object($sess)) {
451: $sess->thaw();
452: }
453: }
454: logMessage("Completed " . $job[PC_CRONLINE], $PC_writeDir, $PC_useLog, $PC_debug);
455: return true;
456: } else {
457: if ($PC_debug) {
458: logMessage("Skipping " . $job[PC_CRONLINE], $PC_writeDir, $PC_useLog, $PC_debug);
459: logMessage(" Last run: " . date("r", $lastActual), $PC_writeDir, $PC_useLog, $PC_debug);
460: logMessage(" Last scheduled: " . date("r", $lastScheduled), $PC_writeDir, $PC_useLog, $PC_debug);
461: logMessage("Completed " . $job[PC_CRONLINE], $PC_writeDir, $PC_useLog, $PC_debug);
462: }
463: return false;
464: }
465: }
466:
467: 468: 469: 470: 471: 472: 473:
474: function parseCronFile($PC_cronTabFile, $PC_debug) {
475: $file = @file($PC_cronTabFile);
476: $job = array();
477: $jobs = array();
478:
479: if (!is_array($file)) {
480: return $jobs;
481: }
482:
483: for ($i = 0; $i < count($file); $i++) {
484: if ($file[$i][0] != '#') {
485:
486:
487: if (preg_match("~^([-0-9,/*]+)\\s+([-0-9,/*]+)\\s+([-0-9,/*]+)\\s+([-0-9,/*]+)\\s+([-0-7,/*]+|(-|/|Sun|Mon|Tue|Wed|Thu|Fri|Sat)+)\\s+([^#]*)(#.*)?$~i", $file[$i], $job)) {
488: $jobNumber = count($jobs);
489: $jobs[$jobNumber] = $job;
490: if ($jobs[$jobNumber][PC_DOW][0] != '*' AND !is_numeric($jobs[$jobNumber][PC_DOW])) {
491: $jobs[$jobNumber][PC_DOW] = str_replace(
492: array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"), array(0, 1, 2, 3, 4, 5, 6), $jobs[$jobNumber][PC_DOW]
493: );
494: }
495: $jobs[$jobNumber][PC_CMD] = trim($job[PC_CMD]);
496: $jobs[$jobNumber][PC_CRONLINE] = $file[$i];
497: }
498: }
499: }
500:
501: if ($PC_debug) {
502: var_dump($jobs);
503: }
504: return $jobs;
505: }
506: