public function start() { global $ConfSitePATH, $Conf; assert($this->checkt === null && $this->logfile === null); // collect user information $this->username = "******"; if ($this->runner->username) { $this->username = $this->runner->username; } else { if ($this->pset->run_username) { $this->username = $this->pset->run_username; } } if (!preg_match('/\\A\\w+\\z/', $this->username)) { throw new RunnerException("bad run_username"); } $info = posix_getpwnam($this->username); $this->userhome = $info ? $info["dir"] : "/home/jail61"; $this->userhome = preg_replace(',/+\\z,', '', $this->userhome); $this->jaildir = preg_replace(',/+\\z,', '', $this->expand($this->pset->run_dirpattern)); if (!$this->jaildir) { throw new RunnerException("bad run_dirpattern"); } $this->jailhomedir = $this->jaildir . "/" . preg_replace(',\\A/+,', '', $this->userhome); if (!chdir($ConfSitePATH)) { throw new RunnerException("can't cd to main directory"); } if (!is_executable("jail/pa-jail")) { throw new RunnerException("the pa-jail program has not been compiled"); } // create logfile and lockfile $this->checkt = time(); $this->logfile = ContactView::runner_logfile($this->info, $this->checkt); $this->lockfile = $this->logfile . ".pid"; file_put_contents($this->lockfile, ""); $this->inputfifo = $this->logfile . ".in"; if (!posix_mkfifo($this->inputfifo, 0660)) { $this->inputfifo = null; } $this->logstream = fopen($this->logfile, "a"); if ($this->queue) { Dbl::qe("update ExecutionQueue set runat=?, status=1, lockfile=?, inputfifo=? where queueid=?", $this->checkt, $this->lockfile, $this->inputfifo, $this->queue->queueid); } register_shutdown_function(array($this, "cleanup")); // create jail $this->remove_old_jails(); if ($this->run_and_log("jail/pa-jail init " . escapeshellarg($this->jaildir) . " " . escapeshellarg($this->username))) { throw new RunnerException("can't initialize jail"); } // check out code $this->checkout_code(); // save commit settings if ($runsettings = $this->info->commit_info("runsettings")) { $this->add_run_settings($runsettings); } // actually run $command = "echo; jail/pa-jail run" . " -p" . escapeshellarg($this->lockfile); $skeletondir = $this->pset->run_skeletondir ?: $Conf->opt("run_skeletondir"); $binddir = $this->pset->run_binddir ?: $Conf->opt("run_binddir"); if ($skeletondir && $binddir) { $binddir = preg_replace(',/+\\z,', '', $binddir); $contents = "/ <- " . $skeletondir . " [bind-ro]\n" . $this->userhome . " <- " . $this->jailhomedir . " [bind]\n"; $command .= " -u" . escapeshellarg($this->jailhomedir) . " -F" . escapeshellarg($contents); $homedir = $binddir; } else { $command .= " -h -f" . escapeshellarg($this->expand($this->pset->run_jailfiles)); if ($skeletondir) { $command .= " -S" . escapeshellarg($skeletondir); } $homedir = $this->jaildir; } if ($this->runner->timeout > 0) { $command .= " -T" . $this->runner->timeout; } else { if ($this->pset->run_timeout > 0) { $command .= " -T" . $this->pset->run_timeout; } } if ($this->inputfifo) { $command .= " -i" . escapeshellarg($this->inputfifo); } $command .= " " . escapeshellarg($homedir) . " " . escapeshellarg($this->username) . " " . escapeshellarg($this->expand($this->runner->command)); $this->lockfile = null; /* now owned by command */ return $this->run_and_log($command); }