diff --git a/livesupport/src/modules/storageServer/var/conf.php b/livesupport/src/modules/storageServer/var/conf.php index d0a49bd6d..e6acbb1f5 100644 --- a/livesupport/src/modules/storageServer/var/conf.php +++ b/livesupport/src/modules/storageServer/var/conf.php @@ -90,6 +90,7 @@ $config = array( 'transDir' => dirname(__FILE__).'/../../storageServer/var/trans', 'accessDir' => dirname(__FILE__).'/../../storageServer/var/access', 'pearPath' => dirname(__FILE__).'/../../../../usr/lib/pear', + 'cronDir' => dirname(__FILE__).'/../../storageServer/var/cron', 'isArchive' => FALSE, 'validate' => TRUE, 'useTrash' => TRUE, @@ -138,8 +139,14 @@ $config = array( ), /* ============================================== auxiliary configuration */ - 'RootNode' => 'RootNode', + 'RootNode' => 'RootNode', 'tmpRootPass' => 'q', + + /* =================================================== cron configuration */ + 'cronUserName' => 'www-data', + 'lockfile' => dirname(__FILE__).'/cron/cron.lock', + 'cronfile' => dirname(__FILE__).'/cron/croncall.php', + 'paramdir' => dirname(__FILE__).'/cron/params', ); $config['sysSubjs'] = array( 'root', $config['AdminsGr'], $config['AllGr'], $config['StationPrefsGr'] diff --git a/livesupport/src/modules/storageServer/var/cron/Cron.php b/livesupport/src/modules/storageServer/var/cron/Cron.php new file mode 100755 index 000000000..07104d419 --- /dev/null +++ b/livesupport/src/modules/storageServer/var/cron/Cron.php @@ -0,0 +1,208 @@ +openCrontab('write'); + * if ($access != 'write') { + * do { + * $access = $this->forceWriteable(); + * } while ($access != 'write'); + * } + * $cron->addCronJob('*','*','*','*','*', + * 'ClassName', + * array('first','secound','third') + * ); + * $cron->closeCrontab(); + * + */ +class Cron { + /** + * @var reference Crontab object reference + */ + var $ct; + + /** + * @var array This array created with getCommand() function + * @access private + */ + var $params; + + /** + * @var string available values: read | write + */ + var $ctAccess = 'read'; + + /** + * Constructor + */ + function Cron() { + global $config; + $this->lockfile = $config['lockfile']; + $this->cronfile = $config['cronfile']; + $this->paramdir = $config['paramdir']; + $this->cronUserName = $config['cronUserName']; + } + + + /* ==================================================== Cronjob functions */ + /** + * Add a cronjob to the crontab + * + * @access public + * @param string $m minute + * @param string $h hour + * @param string $dom day of month + * @param string $mo month + * @param string $dow day of week + * @param string $className name of class, which's execute() is called by croncall.php + * @param string $params the parameter(s) + * @return bool true if success else PEAR error. + */ + function addCronJob($m, $h, $dom, $mo, $dow, $className, $params) + { + if ($this->ctAccess == 'write') { + $this->ct->addCron($m, $h, $dom, $mo, $dow, + $this->getCommand($className, $params)); + return true; + } else { + return PEAR::raiseError('CronJob::addCronJob : '. + 'The crontab is not writable'); + } + } + + /** + * This function return with the active cronjobs + * + * @access public + * @return array array of cronjob struct + */ + function listCronJob() + { + return $this->ct->getByType(CRON_CMD); + } + + /** + * Remove a cronjob. + * + * @access public + * @param int $index index of the cronjobs' array. + * @return bool true if success else PEAR error. + */ + function removeCronJob($index) + { + if ($this->ctAccess == 'write') { + $this->crontab->delEntry($index); + return true; + } else { + return PEAR::raiseError('CronJob::removeCronJob : '. + 'The crontab is not writable'); + } + } + + /* ==================================================== Crontab functions */ + /** + * Open the crontab + * + * @access public + * @param string $access only for listing 'read', for add and delete 'write' + * @return string sucessed access - available values read | write + */ + function openCrontab($access = 'read') + { + $access = strtolower($access); + $this->ct = new Crontab($this->cronUserName); + if ($access == 'write' && + $this->isCrontabWritable() && + $this->lockCrontab()) { + $this->ctAccess = $access; + } else { + $this->ctAccess = 'read'; + } + return $this->ctAccess; + } + + /** + * Close the crontab + * + * @access public + * @return bool true if everything is ok, false is the lock file can't delete + */ + function closeCrontab() + { + if ($this->ctAccess == 'write') { + $this->ct->writeCrontab(); + } + return $this->ctAccess == 'write' ? $this->unlockCrontab() : true; + } + + /** + * Check the crontab is writable + * + * @access private + * @return bool + */ + function isCrontabWritable() + { + return !is_file($this->lockfile); + } + + /** + * Try to lock the crontab + * + * @access private + * @return bool true if the locking is success + */ + function lockCrontab() + { + return touch($this->lockfile); + } + + /** + * Try to unlock the crontab + * + * @access private + * @return bool true if the unlocking is success + */ + function unlockCrontab() + { + return unlink($this->lockfile); + } + + /** + * If the crontab opened with read access. This function force set + * the access to write. + * + * @access public + * @return bool true if the setting is success + */ + function forceWriteable() + { + if ($this->isCrontabWritable() && $this->lockCrontab()) { + $this->ctAccess = 'write'; + return true; + } + return false; + } + + /* ======================================================= Misc functions */ + /** + * Get the shell command for the cronjob + * + * @param string $className name of the class what is called by croncall.php + * @param mixed $params with this parameter could be called the execute() of class + * @return string shell command + */ + function getCommand($className, $params) + { + $this->params = array ( + 'class' => $className, + 'params' => $params + ); + return $this->cronfile.' "'.str_replace('"','\"',serialize($this->params)).'"'; + } +} +?> diff --git a/livesupport/src/modules/storageServer/var/cron/CronJob.php b/livesupport/src/modules/storageServer/var/cron/CronJob.php new file mode 100755 index 000000000..3492512b5 --- /dev/null +++ b/livesupport/src/modules/storageServer/var/cron/CronJob.php @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/livesupport/src/modules/storageServer/var/cron/Crontab.php b/livesupport/src/modules/storageServer/var/cron/Crontab.php new file mode 100755 index 000000000..414d5dc7f --- /dev/null +++ b/livesupport/src/modules/storageServer/var/cron/Crontab.php @@ -0,0 +1,263 @@ + "value" + * or a line can be a comment (string beginning with #) + * or it can be a special command (beginning with an @) + */ + var $crontabs; + + /** + * @var string the user for whom the crontab will be manipulated + */ + var $user; + + /** + * @var string Lists the type of line of each line in $crontabs. + * can be: any of the CRON_* constants. + * so $linetype[5] is the type of $crontabs[5]. + */ + var $linetypes; + + // }}} + + /** + * Constructor + * + * Initialises $this->crontabs + * + * @param string $user the user for whom the crontab will be manipulated + */ + function Crontab($user) + { + $this->user = $user; + $this->readCrontab(); + } + + /** + * This reads the crontab of $this->user and parses it in $this->crontabs + * + */ + function readCrontab() + { + exec("crontab -u {$this->user} -l", $crons, $return); + + foreach ($crons as $line) + { + $line = trim($line); // discarding all prepending spaces and tabs + + // empty lines.. + if (!$line) + { + $this->crontabs[] = "empty line"; + $this->linetypes[] = CRON_EMPTY; + continue; + } + + // checking if this is a comment + if ($line[0] == "#") + { + $this->crontabs[] = trim($line); + $this->linetypes[] = CRON_COMMENT; + continue; + } + + // Checking if this is an assignment + if (ereg("(.*)=(.*)", $line, $assign)) + { + $this->crontabs[] = array ("name" => $assign[1], "value" => $assign[2]); + $this->linetypes[] = CRON_ASSIGN; + continue; + } + + // Checking if this is a special @-entry. check man 5 crontab for more info + if ($line[0] == '@') + { + $this->crontabs[] = split("[ \t]", $line, 2); + $this->linetypes[] = CRON_SPECIAL; + continue; + } + + // It's a regular crontab-entry + $ct = split("[ \t]", $line, 6); + $this->addCron($ct[0], $ct[1], $ct[2], $ct[3], $ct[4], $ct[5], $ct[6]); + } + } + + /** + * Writes the current crontab + */ + function writeCrontab() + { + global $DEBUG, $PATH; + + $filename = ($DEBUG ? tempnam("$PATH/crons", "cron") : tempnam("/tmp", "cron")); + $file = fopen($filename, "w"); + + for ($i = 0; $i < count($this->linetypes); $i ++) + { + switch ($this->linetypes[$i]) + { + case CRON_COMMENT : + $line = $this->crontabs[$i]; + break; + case CRON_ASSIGN : + $line = $this->crontabs[$i][name]." = ".$this->crontabs[$i][value]; + break; + case CRON_CMD : + $line = implode(" ", $this->crontabs[$i]); + break; + case CRON_SPECIAL : + $line = implode(" ", $this->crontabs[$i]); + break; + CASE CRON_EMPTYLINE : + $line = "\n"; // an empty line in the crontab-file + break; + default : + unset ($line); + echo "Something very weird is going on. This line ($i) has an unknown type.\n"; + break; + } + + // echo "line $i : $line\n"; + + if ($line) + fwrite($file, $line."\n"); + } + fclose($file); + + if ($DEBUG) + echo "DEBUGMODE: not updating crontab. writing to $filename instead.\n"; + else + { + exec("crontab -u {$this->user} $filename", $returnar, $return); + if ($return != 0) + echo "Error running crontab ($return). $filename not deleted\n"; + else + unlink($filename); + } + } + + /** + * Add a item of type CRON_CMD to the end of $this->crontabs + * + * @param string $m minute + * @param string $h hour + * @param string $dom day of month + * @param string $mo month + * @param string $dow day of week + * @param string $cmd command + * + */ + function addCron($m, $h, $dom, $mo, $dow, $cmd) + { + $this->crontabs[] = array ("minute" => $m, "hour" => $h, "dayofmonth" => $dom, "month" => $mo, "dayofweek" => $dow, "command" => $cmd); + $this->linetypes[] = CRON_CMD; + } + + /** + * Add a comment to the cron to the end of $this->crontabs + * + * @param string $comment comment + */ + function addComment($comment) + { + $this->crontabs[] = "# $comment\n"; + $this->linetypes[] = CRON_COMMENT; + } + + /** + * Add a special command (check man 5 crontab for more information) + * + * @param string $sdate special date + * string meaning + * ------ ------- + * @reboot Run once, at startup. + * @yearly Run once a year, "0 0 1 1 *". + * @annually (same as @yearly) + * @monthly Run once a month, "0 0 1 * *". + * @weekly Run once a week, "0 0 * * 0". + * @daily Run once a day, "0 0 * * *". + * @midnight (same as @daily) + * @hourly Run once an hour, "0 * * * *". + * @param string $cmd command + */ + function addSpecial($sdate, $cmd) + { + $this->crontabs[] = array ("special" => $sdate, "command" => $cmd); + $this->linetypes[] = CRON_SPECIAL; + } + + /** + * Add an assignment (name = value) + * + * @param string $name name of assingation + * @param string $value value + */ + function addAssign($name, $value) + { + $this->crontabs[] = array ("name" => $name, "value" => $value); + $this->linetypes[] = CRON_ASSIGN; + } + + /** + * Delete a line from the arrays. + * + * @param int $index the index in $this->crontabs + */ + function delEntry($index) + { + unset ($this->crontabs[$index]); + unset ($this->linetypes[$index]); + } + + /** + * Get all the lines of a certain type in an array + * + * @param string $type linetype + */ + function getByType($type) + { + if ($type < CRON_COMMENT || $type > CRON_EMPTY) + { + trigger_error("Wrong type: $type", E_USER_WARNING); + return 0; + } + + $returnar = array (); + for ($i = 0; $i < count($this->linetypes); $i ++) + if ($this->linetypes[$i] == $type) + $returnar[] = $this->crontabs[$i]; + + return $returnar; + } +} +?> + + + diff --git a/livesupport/src/modules/storageServer/var/cron/croncall.php b/livesupport/src/modules/storageServer/var/cron/croncall.php new file mode 100755 index 000000000..bae49815b --- /dev/null +++ b/livesupport/src/modules/storageServer/var/cron/croncall.php @@ -0,0 +1,9 @@ +#!/usr/bin/php +execute($p['params']); +exit(0); +?> \ No newline at end of file