예제 #1
0
    ob_end_flush();
    echo "<p>\n";
    while ($row = $res->next()) {
        echo "s" . specialchars($row['submitid']) . ", ";
        $DB->q('START TRANSACTION');
        // first invalidate old judging, maybe different from prevjudgingid!
        $DB->q('UPDATE judging SET valid=0
		        WHERE submitid=%i', $row['submitid']);
        // then set judging to valid
        $DB->q('UPDATE judging SET valid=1
		        WHERE submitid=%i AND rejudgingid=%i', $row['submitid'], $id);
        // remove relation from submission to rejudge
        $DB->q('UPDATE submission SET rejudgingid=NULL
		        WHERE submitid=%i', $row['submitid']);
        // last update cache
        calcScoreRow($row['cid'], $row['teamid'], $row['probid']);
        $DB->q('COMMIT');
    }
    echo "\n</p>\n";
    $DB->q('UPDATE rejudging
	        SET endtime=%s, userid_finish=%i
	        WHERE rejudgingid=%i', now(), $userdata['userid'], $id);
    auditlog('rejudging', $id, 'applying rejudge', '(end)');
    $time_end = microtime(TRUE);
    echo "<p>Rejudging <a href=\"rejudging.php?id=" . urlencode($id) . "\">r{$id}</a> applied in " . round($time_end - $time_start, 2) . " seconds.</p>\n\n";
    require LIBWWWDIR . '/footer.php';
    return;
} else {
    if (isset($_REQUEST['cancel'])) {
        if (isset($rejdata['endtime'])) {
            error("Rejudging already " . ($rejdata['valid'] ? 'applied.' : 'canceled.'));
예제 #2
0
/**
 * Change the valid status of a given submission.
 *
 * Part of the DOMjudge Programming Contest Jury System and licenced
 * under the GNU GPL. See README and COPYING for details.
 */
require 'init.php';
if (!IS_ADMIN) {
    error("Admin privileges are required for this operation.");
}
$id = @$_POST['id'];
$val = @$_POST['val'];
if (empty($id)) {
    error("No submission ID passed to mark as (in)valid.");
}
$cnt = $DB->q('RETURNAFFECTED UPDATE submission s
               SET s.valid = %i WHERE s.submitid = %i', $val, $id);
auditlog('submission', $id, 'marked ' . ($val ? 'valid' : 'invalid'));
if ($cnt == 0) {
    error("Submission s{$id} not found.");
} else {
    if ($cnt > 1) {
        error("Ignored more than one submission.");
    }
}
$sdata = $DB->q('TUPLE SELECT submitid, cid, teamid, probid
                 FROM submission
                 WHERE submitid = %i', $id);
calcScoreRow($sdata['cid'], $sdata['teamid'], $sdata['probid']);
/* redirect back. */
header('Location: submission.php?id=' . urlencode($sdata['submitid']));
예제 #3
0
파일: index.php 프로젝트: retnan/domjudge
/**
 * Judging_Runs
 */
function judging_runs_POST($args)
{
    global $DB, $api;
    checkargs($args, array('judgingid', 'testcaseid', 'runresult', 'runtime', 'output_run', 'output_diff', 'output_error', 'output_system', 'judgehost'));
    $results_remap = dbconfig_get('results_remap');
    $results_prio = dbconfig_get('results_prio');
    if (array_key_exists($args['runresult'], $results_remap)) {
        logmsg(LOG_INFO, "Testcase {$args['testcaseid']} remapping result " . $args['runresult'] . " -> " . $results_remap[$args['runresult']]);
        $args['runresult'] = $results_remap[$args['runresult']];
    }
    $DB->q('INSERT INTO judging_run (judgingid, testcaseid, runresult,
	        runtime, output_run, output_diff, output_error, output_system)
	        VALUES (%i, %i, %s, %f, %s, %s, %s, %s)', $args['judgingid'], $args['testcaseid'], $args['runresult'], $args['runtime'], base64_decode($args['output_run']), base64_decode($args['output_diff']), base64_decode($args['output_error']), base64_decode($args['output_system']));
    // result of this judging_run has been stored. now check whether
    // we're done or if more testcases need to be judged.
    $probid = $DB->q('VALUE SELECT probid FROM testcase
	                  WHERE testcaseid = %i', $args['testcaseid']);
    $runresults = $DB->q('COLUMN SELECT runresult
	                      FROM judging_run LEFT JOIN testcase USING(testcaseid)
	                      WHERE judgingid = %i ORDER BY rank', $args['judgingid']);
    $numtestcases = $DB->q('VALUE SELECT count(*) FROM testcase WHERE probid = %i', $probid);
    $allresults = array_pad($runresults, $numtestcases, null);
    $before = $DB->q('VALUE SELECT result FROM judging WHERE judgingid = %i', $args['judgingid']);
    if (($result = getFinalResult($allresults, $results_prio)) !== NULL) {
        // Lookup global lazy evaluation of results setting and
        // possible problem specific override.
        $lazy_eval = dbconfig_get('lazy_eval_results', true);
        $prob_lazy = $DB->q('MAYBEVALUE SELECT cp.lazy_eval_results
		                     FROM judging j
		                     LEFT JOIN submission s USING(submitid)
		                     LEFT JOIN contestproblem cp ON (cp.cid=j.cid AND cp.probid=s.probid)
		                     WHERE judgingid = %i', $args['judgingid']);
        if (isset($prob_lazy)) {
            $lazy_eval = (bool) $prob_lazy;
        }
        if (count($runresults) == $numtestcases || $lazy_eval) {
            // NOTE: setting endtime here determines in testcases_GET
            // whether a next testcase will be handed out.
            $DB->q('UPDATE judging SET result = %s, endtime = %s
			        WHERE judgingid = %i', $result, now(), $args['judgingid']);
        } else {
            $DB->q('UPDATE judging SET result = %s
			        WHERE judgingid = %i', $result, $args['judgingid']);
        }
        // Only update if the current result is different from what we
        // had before. This should only happen when the old result was
        // NULL.
        if ($before !== $result) {
            if ($before !== NULL) {
                error('internal bug: the evaluated result changed during judging');
            }
            $row = $DB->q('TUPLE SELECT s.cid, s.teamid, s.probid, s.langid, s.submitid
			               FROM judging
			               LEFT JOIN submission s USING(submitid)
			               WHERE judgingid = %i', $args['judgingid']);
            calcScoreRow($row['cid'], $row['teamid'], $row['probid']);
            // We call alert here before possible validation. Note
            // that this means that these alert messages should be
            // treated as confidential information.
            alert($result === 'correct' ? 'accept' : 'reject', "submission {$row['submitid']}, judging {$args['judgingid']}: {$result}");
            // log to event table if no verification required
            // (case of verification required is handled in www/jury/verify.php)
            if (!dbconfig_get('verification_required', 0)) {
                $DB->q('INSERT INTO event (eventtime, cid, teamid, langid, probid,
				        submitid, judgingid, description)
				        VALUES(%s, %i, %i, %s, %i, %i, %i, "problem judged")', now(), $row['cid'], $row['teamid'], $row['langid'], $row['probid'], $row['submitid'], $args['judgingid']);
                if ($result == 'correct') {
                    // prevent duplicate balloons in case of multiple correct submissions
                    $numcorrect = $DB->q('VALUE SELECT count(submitid)
					                      FROM balloon
					                      LEFT JOIN submission USING(submitid)
					                      WHERE valid = 1 AND probid = %i
					                      AND teamid = %i AND cid = %i', $row['probid'], $row['teamid'], $row['cid']);
                    if ($numcorrect == 0) {
                        $balloons_enabled = (bool) $DB->q("VALUE SELECT process_balloons\n\t\t\t\t\t\t                                  FROM contest WHERE cid = %i", $row['cid']);
                        if ($balloons_enabled) {
                            $DB->q('INSERT INTO balloon (submitid) VALUES(%i)', $row['submitid']);
                        }
                    }
                }
            }
            auditlog('judging', $args['judgingid'], 'judged', $result, $args['judgehost']);
        }
    }
    $DB->q('UPDATE judgehost SET polltime = %s WHERE hostname = %s', now(), $args['judgehost']);
    return '';
}
예제 #4
0
/**
 * This function takes a (set of) temporary file(s) of a submission,
 * validates it and puts it into the database. Additionally it
 * moves it to a backup storage.
 */
function submit_solution($team, $prob, $contest, $lang, $files, $filenames, $origsubmitid = NULL)
{
    global $DB;
    if (empty($team)) {
        error("No value for Team.");
    }
    if (empty($prob)) {
        error("No value for Problem.");
    }
    if (empty($contest)) {
        error("No value for Contest.");
    }
    if (empty($lang)) {
        error("No value for Language.");
    }
    if (!is_array($files) || count($files) == 0) {
        error("No files specified.");
    }
    if (count($files) > dbconfig_get('sourcefiles_limit', 100)) {
        error("Tried to submit more than the allowed number of source files.");
    }
    if (!is_array($filenames) || count($filenames) != count($files)) {
        error("Nonmatching (number of) filenames specified.");
    }
    if (count($filenames) != count(array_unique($filenames))) {
        error("Duplicate filenames detected.");
    }
    $sourcesize = dbconfig_get('sourcesize_limit');
    // If no contest has started yet, refuse submissions.
    $now = now();
    $contestdata = $DB->q('MAYBETUPLE SELECT starttime,endtime FROM contest WHERE cid = %i', $contest);
    if (!isset($contestdata)) {
        error("Contest c{$contest} not found.");
    }
    if (difftime($contestdata['starttime'], $now) > 0) {
        error("The contest is closed, no submissions accepted. [c{$contest}]");
    }
    // Check 2: valid parameters?
    if (!($langid = $DB->q('MAYBEVALUE SELECT langid FROM language
	                        WHERE langid = %s AND allow_submit = 1', $lang))) {
        error("Language '{$lang}' not found in database or not submittable.");
    }
    if (!($teamid = $DB->q('MAYBEVALUE SELECT teamid FROM team
	                        WHERE teamid = %i AND enabled = 1', $team))) {
        error("Team '{$team}' not found in database or not enabled.");
    }
    $probdata = $DB->q('MAYBETUPLE SELECT probid, points FROM problem
	                    INNER JOIN contestproblem USING (probid)
	                    WHERE probid = %s AND cid = %i AND allow_submit = 1', $prob, $contest);
    if (empty($probdata)) {
        error("Problem p{$prob} not found in database or not submittable [c{$contest}].");
    } else {
        $points = $probdata['points'];
        $probid = $probdata['probid'];
    }
    // Reindex arrays numerically to allow simultaneously iterating
    // over both $files and $filenames.
    $files = array_values($files);
    $filenames = array_values($filenames);
    $totalsize = 0;
    for ($i = 0; $i < count($files); $i++) {
        if (!is_readable($files[$i])) {
            error("File '" . $files[$i] . "' not found (or not readable).");
        }
        if (!preg_match(FILENAME_REGEX, $filenames[$i])) {
            error("Illegal filename '" . $filenames[$i] . "'.");
        }
        $totalsize += filesize($files[$i]);
    }
    if ($totalsize > $sourcesize * 1024) {
        error("Submission file(s) are larger than {$sourcesize} kB.");
    }
    logmsg(LOG_INFO, "input verified");
    // Insert submission into the database
    $id = $DB->q('RETURNID INSERT INTO submission
	              (cid, teamid, probid, langid, submittime, origsubmitid)
	              VALUES (%i, %i, %i, %s, %s, %i)', $contest, $teamid, $probid, $langid, $now, $origsubmitid);
    for ($rank = 0; $rank < count($files); $rank++) {
        $DB->q('INSERT INTO submission_file
		        (submitid, filename, rank, sourcecode) VALUES (%i, %s, %i, %s)', $id, $filenames[$rank], $rank, getFileContents($files[$rank], false));
    }
    // Recalculate scoreboard cache for pending submissions
    calcScoreRow($contest, $teamid, $probid);
    // Log to event table
    $DB->q('INSERT INTO event (eventtime, cid, teamid, langid, probid, submitid, description)
	        VALUES(%s, %i, %i, %s, %i, %i, "problem submitted")', now(), $contest, $teamid, $langid, $probid, $id);
    if (is_writable(SUBMITDIR)) {
        // Copy the submission to SUBMITDIR for safe-keeping
        for ($rank = 0; $rank < count($files); $rank++) {
            $fdata = array('cid' => $contest, 'submitid' => $id, 'teamid' => $teamid, 'probid' => $probid, 'langid' => $langid, 'rank' => $rank, 'filename' => $filenames[$rank]);
            $tofile = SUBMITDIR . '/' . getSourceFilename($fdata);
            if (!@copy($files[$rank], $tofile)) {
                warning("Could not copy '" . $files[$rank] . "' to '" . $tofile . "'");
            }
        }
    } else {
        logmsg(LOG_DEBUG, "SUBMITDIR not writable, skipping");
    }
    if (difftime($contestdata['endtime'], $now) <= 0) {
        logmsg(LOG_INFO, "The contest is closed, submission stored but not processed. [c{$contest}]");
    }
    return $id;
}
예제 #5
0
            error('submission is already part of rejudging r' . specialchars($jud['rejudgingid']));
        } else {
            // silently skip that submission
            continue;
        }
    }
    $DB->q('START TRANSACTION');
    if (!$full_rejudge) {
        $DB->q('UPDATE judging SET valid = 0 WHERE judgingid = %i', $jud['judgingid']);
    }
    $DB->q('UPDATE submission SET judgehost = NULL' . ($full_rejudge ? ', rejudgingid=%i ' : '%_ ') . 'WHERE submitid = %i AND rejudgingid IS NULL', @$rejudgingid, $jud['submitid']);
    // Prioritize single submission rejudgings
    if ($table == 'submission') {
        $DB->q('UPDATE team SET judging_last_started = NULL
		        WHERE teamid IN (SELECT teamid FROM submission
		        WHERE submitid = %i)', $jud['submitid']);
    }
    if (!$full_rejudge) {
        calcScoreRow($jud['cid'], $jud['teamid'], $jud['probid']);
    }
    $DB->q('COMMIT');
    if (!$full_rejudge) {
        auditlog('judging', $jud['judgingid'], 'mark invalid', '(rejudge)');
    }
}
/** redirect back. */
if ($full_rejudge) {
    header('Location: rejudging.php?id=' . urlencode($rejudgingid));
} else {
    header('Location: ' . $table . '.php?id=' . urlencode($id));
}
예제 #6
0
    echo "<p>Recalculating all values for the scoreboard cache for contest c{$contest} (" . count($teams) . " teams, " . count($probs) . " problems)...</p>\n\n<pre>\n";
    if (count($teams) == 0) {
        echo "No teams defined, doing nothing.</pre>\n\n";
        continue;
    }
    if (count($probs) == 0) {
        echo "No problems defined, doing nothing.</pre>\n\n";
        continue;
    }
    // for each team, fetch the status of each problem
    foreach ($teams as $team) {
        echo "Team t" . specialchars($team['teamid']) . ":";
        // for each problem fetch the result
        foreach ($probs as $pr) {
            echo " p" . specialchars($pr['probid']);
            calcScoreRow($pr['cid'], $team['teamid'], $pr['probid']);
        }
        // Now recompute the rank
        echo " rankcache";
        updateRankCache($contest, $team['teamid']);
        echo "\n";
        ob_flush();
    }
    echo "</pre>\n\n";
}
echo "<p>Deleting irrelevant data...</p>\n\n";
// Drop all teams and problems that do not exist in each contest
foreach ($contests as $contest) {
    $probids = $DB->q('COLUMN SELECT probid FROM problem
	                   INNER JOIN contestproblem USING (probid)
	                   WHERE cid = %i ORDER BY shortname', $contest);