Exemplo n.º 1
0
 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);
 }