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: