function presentDiff($old, $new) { $oldsourcefile = getSourceFilename($old); $newsourcefile = getSourceFilename($new); $difftext = createDiff($new, SUBMITDIR . '/' . $newsourcefile, $new['submitid'], $old, SUBMITDIR . '/' . $oldsourcefile, $old['submitid']); return '<div class="tabbertab">' . '<h2 class="filename">' . specialchars($old['filename']) . "</h2>\n\n" . '<pre class="output_text">' . parseSourceDiff($difftext) . "</pre>\n\n" . '</div>'; }
/** * 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; }