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: while (!empty($number) && $number[0] == '0') {
221: $number = cString::getPartOfString($number, 1);
222: }
223: if (empty($number)) {
224: $number = 0;
225: }
226: return cSecurity::toInteger($number);
227: }
228:
229: 230: 231: 232: 233: 234:
235: function parseElement($element, &$targetArray, $numberOfElements) {
236: $subelements = explode(",", $element);
237: for ($i = 0; $i < $numberOfElements; $i++) {
238: $targetArray[$i] = $subelements[0] == "*";
239: }
240:
241: for ($i = 0; $i < count($subelements); $i++) {
242: if (preg_match("~^(\\*|([0-9]{1,2})(-([0-9]{1,2}))?)(/([0-9]{1,2}))?$~", $subelements[$i], $matches)) {
243: if ($matches[1] == "*") {
244: $matches[2] = 0;
245: $matches[4] = $numberOfElements;
246: } elseif (!array_key_exists(4, $matches) || $matches[4] == "") {
247: $matches[4] = $matches[2];
248: }
249: if (array_key_exists(5, $matches)) {
250: if ($matches[5][0] != "/") {
251: $matches[6] = 1;
252: }
253: } else {
254: $matches[6] = 1;
255: }
256: for ($j = lTrimZeros($matches[2]); $j <= lTrimZeros($matches[4]); $j+=lTrimZeros($matches[6])) {
257: $targetArray[$j] = TRUE;
258: }
259: }
260: }
261: }
262:
263: 264: 265: 266: 267: 268: 269:
270: function decDate(&$dateArr, $amount, $unit, $PC_debug) {
271: if ($PC_debug) {
272: echo sprintf("Decreasing from %02d.%02d. %02d:%02d by %d %6s ", $dateArr['mday'], $dateArr['mon'], $dateArr['hours'], $dateArr['minutes'], $amount, $unit);
273: }
274: if ($unit == "mday") {
275: $dateArr["hours"] = 23;
276: $dateArr["minutes"] = 59;
277: $dateArr["seconds"] = 59;
278: $dateArr["mday"] -= $amount;
279: $dateArr["wday"] -= $amount % 7;
280: if ($dateArr["wday"] < 0) {
281: $dateArr["wday"]+=7;
282: }
283: if ($dateArr["mday"] < 1) {
284: $dateArr["mon"]--;
285: switch ($dateArr["mon"]) {
286: case 0:
287: $dateArr["mon"] = 12;
288: $dateArr["year"]--;
289:
290: case 1:
291: case 3:
292: case 5:
293: case 7:
294: case 8:
295: case 10:
296: case 12:
297: $dateArr["mday"] = 31;
298: break;
299: case 4:
300: case 6:
301: case 9:
302: case 11:
303: $dateArr["mday"] = 30;
304: break;
305: case 2:
306: $dateArr["mday"] = 28;
307: break;
308: }
309: }
310: } elseif ($unit == "hour") {
311: if ($dateArr["hours"] == 0) {
312: decDate($dateArr, 1, "mday", $PC_debug);
313: } else {
314: $dateArr["minutes"] = 59;
315: $dateArr["seconds"] = 59;
316: $dateArr["hours"]--;
317: }
318: } elseif ($unit == "minute") {
319: if ($dateArr["minutes"] == 0) {
320: decDate($dateArr, 1, "hour", $PC_debug);
321: } else {
322: $dateArr["seconds"] = 59;
323: $dateArr["minutes"]--;
324: }
325: }
326: if ($PC_debug) {
327: echo sprintf("to %02d.%02d. %02d:%02d\n", $dateArr['mday'], $dateArr['mon'], $dateArr['hours'], $dateArr['minutes']);
328: }
329: }
330:
331: 332: 333: 334: 335: 336:
337: function getLastScheduledRunTime($job, $PC_debug) {
338: $dateArr = getdate();
339: $minutesBack = 0;
340: while (
341: $minutesBack < 525600 AND
342: (!$job[PC_MINUTE][$dateArr["minutes"]] OR
343: !$job[PC_HOUR][$dateArr["hours"]] OR
344: (!$job[PC_DOM][$dateArr["mday"]] OR !$job[PC_DOW][$dateArr["wday"]]) OR
345: !$job[PC_MONTH][$dateArr["mon"]])
346: ) {
347: if (!$job[PC_DOM][$dateArr["mday"]] OR !$job[PC_DOW][$dateArr["wday"]]) {
348: decDate($dateArr, 1, "mday", $PC_debug);
349: $minutesBack+=1440;
350: continue;
351: }
352: if (!$job[PC_HOUR][$dateArr["hours"]]) {
353: decDate($dateArr, 1, "hour", $PC_debug);
354: $minutesBack+=60;
355: continue;
356: }
357: if (!$job[PC_MINUTE][$dateArr["minutes"]]) {
358: decDate($dateArr, 1, "minute", $PC_debug);
359: $minutesBack++;
360: continue;
361: }
362: }
363:
364: if ($PC_debug) {
365: print_r($dateArr);
366: }
367:
368: return mktime($dateArr["hours"], $dateArr["minutes"], 0, $dateArr["mon"], $dateArr["mday"], $dateArr["year"]);
369: }
370:
371: 372: 373: 374: 375: 376:
377: function getJobFileName($jobname, $PC_writeDir) {
378: $jobfile = $PC_writeDir . urlencode($jobname) . ".job";
379: return $jobfile;
380: }
381:
382: 383: 384: 385: 386: 387:
388: function getLastActialRunTime($jobname, $PC_writeDir) {
389: $jobfile = getJobFileName($jobname, $PC_writeDir);
390: if (cFileHandler::exists($jobfile)) {
391: $file = fopen($jobfile, "rb");
392: $lastRun = fgets($file, 100);
393: fclose($file);
394: if (is_numeric($lastRun)) {
395: return $lastRun;
396: }
397: }
398: return 0;
399: }
400:
401: 402: 403: 404: 405: 406:
407: function markLastRun($jobname, $lastRun, $PC_writeDir) {
408: $jobfile = getJobFileName($jobname, $PC_writeDir);
409:
410: if ($file = @fopen($jobfile, "w")) {
411: fputs($file, $lastRun);
412: fclose($file);
413: } else {
414:
415: }
416: }
417:
418: 419: 420: 421: 422: 423: 424: 425: 426: 427:
428: function runJob($job, $PC_jobDir, $PC_writeDir, $PC_useLog, $PC_debug = false) {
429: global $sess;
430: $extjob = array();
431:
432: parseElement($job[PC_MINUTE], $extjob[PC_MINUTE], 60);
433: parseElement($job[PC_HOUR], $extjob[PC_HOUR], 24);
434: parseElement($job[PC_DOM], $extjob[PC_DOM], 31);
435: parseElement($job[PC_MONTH], $extjob[PC_MONTH], 12);
436: parseElement($job[PC_DOW], $extjob[PC_DOW], 7);
437:
438: $lastActual = getLastActialRunTime($job[PC_CMD], $PC_writeDir);
439: $lastScheduled = getLastScheduledRunTime($extjob, $PC_debug);
440:
441: if ($lastScheduled > $lastActual) {
442: logMessage("Running " . $job[PC_CRONLINE], $PC_writeDir, $PC_useLog, $PC_debug);
443: logMessage(" Last run: " . date("r", $lastActual), $PC_writeDir, $PC_useLog, $PC_debug);
444: logMessage(" Last scheduled: " . date("r", $lastScheduled), $PC_writeDir, $PC_useLog, $PC_debug);
445: markLastRun($job[PC_CMD], $lastScheduled, $PC_writeDir);
446:
447: if ($PC_debug) {
448: echo getcwd();
449: include($PC_jobDir . $job[PC_CMD]);
450: } else {
451: if (is_object($sess)) {
452: $sess->freeze();
453: }
454: @include($PC_jobDir . $job[PC_CMD]);
455: if (is_object($sess)) {
456: $sess->thaw();
457: }
458: }
459: logMessage("Completed " . $job[PC_CRONLINE], $PC_writeDir, $PC_useLog, $PC_debug);
460: return true;
461: } else {
462: if ($PC_debug) {
463: logMessage("Skipping " . $job[PC_CRONLINE], $PC_writeDir, $PC_useLog, $PC_debug);
464: logMessage(" Last run: " . date("r", $lastActual), $PC_writeDir, $PC_useLog, $PC_debug);
465: logMessage(" Last scheduled: " . date("r", $lastScheduled), $PC_writeDir, $PC_useLog, $PC_debug);
466: logMessage("Completed " . $job[PC_CRONLINE], $PC_writeDir, $PC_useLog, $PC_debug);
467: }
468: return false;
469: }
470: }
471:
472: 473: 474: 475: 476: 477: 478:
479: function parseCronFile($PC_cronTabFile, $PC_debug) {
480: $file = @file($PC_cronTabFile);
481: $job = array();
482: $jobs = array();
483:
484: if (!is_array($file)) {
485: return $jobs;
486: }
487:
488: for ($i = 0; $i < count($file); $i++) {
489: if ($file[$i][0] != '#') {
490:
491:
492: 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)) {
493: $jobNumber = count($jobs);
494: $jobs[$jobNumber] = $job;
495: if ($jobs[$jobNumber][PC_DOW][0] != '*' AND !is_numeric($jobs[$jobNumber][PC_DOW])) {
496: $jobs[$jobNumber][PC_DOW] = str_replace(
497: array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"), array(0, 1, 2, 3, 4, 5, 6), $jobs[$jobNumber][PC_DOW]
498: );
499: }
500: $jobs[$jobNumber][PC_CMD] = trim($job[PC_CMD]);
501: $jobs[$jobNumber][PC_CRONLINE] = $file[$i];
502: }
503: }
504: }
505:
506: if ($PC_debug) {
507: var_dump($jobs);
508: }
509: return $jobs;
510: }
511: