From 91f585b3fdd9e64c086b21da35bebdc401e2e476 Mon Sep 17 00:00:00 2001 From: cassiopc Date: Fri, 31 Aug 2012 10:08:29 +0200 Subject: inclusion of interface to create the zip of a problem --- .../problemexamples/problemtemplate/compile/pas | 172 +++++++++++++++++++++ boca-1.5.0/src/admin/buildproblem.php | 107 +++++++++++++ boca-1.5.0/src/admin/problem.php | 130 +++++++++++++++- boca-1.5.0/tools/etc/icpc/becomeserver.sh | 4 +- boca-1.5.0/tools/etc/sysctl.d/10-shmmax.conf | 4 +- boca-1.5.0/tools/icpc.etc.tgz | Bin 8648 -> 8653 bytes 6 files changed, 412 insertions(+), 5 deletions(-) create mode 100644 boca-1.5.0/doc/problemexamples/problemtemplate/compile/pas create mode 100644 boca-1.5.0/src/admin/buildproblem.php diff --git a/boca-1.5.0/doc/problemexamples/problemtemplate/compile/pas b/boca-1.5.0/doc/problemexamples/problemtemplate/compile/pas new file mode 100644 index 0000000..e0b73ca --- /dev/null +++ b/boca-1.5.0/doc/problemexamples/problemtemplate/compile/pas @@ -0,0 +1,172 @@ +#!/bin/bash +# //////////////////////////////////////////////////////////////////////////////// +# //BOCA Online Contest Administrator +# // Copyright (C) 2003-2012 by BOCA System (bocasystem@gmail.com) +# // +# // This program is free software: you can redistribute it and/or modify +# // it under the terms of the GNU General Public License as published by +# // the Free Software Foundation, either version 3 of the License, or +# // (at your option) any later version. +# // +# // This program is distributed in the hope that it will be useful, +# // but WITHOUT ANY WARRANTY; without even the implied warranty of +# // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# // GNU General Public License for more details. +# // You should have received a copy of the GNU General Public License +# // along with this program. If not, see . +# //////////////////////////////////////////////////////////////////////////////// +#Last modified: 28/aug/2012 by cassio@ime.usp.br +# +# parameters are: +# $1 source_file +# $2 exe_file (default run.exe) +# $3 timelimit (optional, limit to run all the repetitions, by default only one repetition) +# $4 maximum allowed memory (in MBytes, default 512M) +# +# the output of the submission should be directed to the standard output +# +# the return code show what happened (according to safeexec): +# 0 ok +# 1 compile error +# 2 runtime error +# 3 timelimit exceeded +# 4 internal error +# 5 parameter error +# 6 internal error +# 7 memory limit exceeded +# 8 security threat +# 9 runtime error +# other_codes are unknown to boca: in this case BOCA will present the +# last line of standard output to the judge + +umask 0022 + +if [ "$1" == "" ]; then + echo "parameter problem" + exit 43 +fi +if [ ! -r "$1" ]; then + echo "$1 not found or it's not readable" + exit 44 +fi +name="$1" +if [ ! -r "$1" ]; then + echo "$1 not found or it's not readable" + exit 44 +fi +mkdir -p src +if [ "${name##*.}" == "zip" -a "${name##*.}" == "ZIP" ]; then + unzip "$name" -d src + name="*.c" +else + cp "$name" src +fi +id -u bocajail >/dev/null 2>/dev/null +if [ $? == 0 ]; then + bocau=`id -u bocajail` + bocag=`id -g bocajail` + chown bocajail.nogroup . +else + bocau=`id -u nobody` + bocag=`id -g nobody` + chown nobody.nogroup . +fi +if [ "$bocau" == "" -o "$bocag" == "" ]; then + echo "error finding user to run script" + exit 43 +fi + +# this script makes use of safeexec to execute the code with less privilegies +# make sure that directories below are correct. +sf=`which safeexec` +[ -x "$sf" ] || sf=/usr/bin/safeexec +if [ ! -x $sf ]; then + echo "$sf not found or it's not executable" + exit 46 +fi +maxm=512000 +if [ "$4" != "" ]; then + if [ "$4" -gt "0" ]; then + maxm=${4}000 + fi +fi + +# setting up the timelimit according to the problem +if [ "$3" == "" ]; then +time=5 +else +time=$3 +fi +let "ttime = $time + 30" + +if [ "$2" == "" ]; then + exe=run.exe +else + exe=$2 +fi + +rm -f $exe compileit.retcode runit.retcode 2>/dev/null +cat < compileit.sh +#!/bin/bash +cc=\`which fpc\` +[ -x "\$cc" ] || cc=/usr/bin/fpc +if [ ! -x "\$cc" ]; then + echo "\$cc not found or it's not executable" + exit 47 +fi +cd src +"\$cc" -Xt -XS -O2 -o../$exe $name +echo \$? > ../compileit.retcode +exit 0 +EOF +chmod 755 compileit.sh + +cdir=`pwd` +echo "Current directory is $cdir" >&2 +echo $cdir | grep -q "/bocajail" +if [ $? == 0 ]; then + cdir=`echo $cdir | sed "s/.*\/bocajail//"` + echo "Internal directory is $cdir" + cat < runit.sh +#!/bin/bash +cd "$cdir" +[ -f /proc/cpuinfo ] || /bin/mount -t proc proc /proc +#/bin/mount --bind /dev /dev +[ -d /sys/kernel ] || /bin/mount -t sysfs sysfs /sys +$sf -r1 -F1000 -n0 -U$bocau -G$bocag -C. -ostdout0 -estderr0 -d$maxm -m$maxm -f20000 -t$ttime -T$ttime ./compileit.sh +echo \$? > runit.retcode +if [ ! -d /bocajail ]; then + /bin/umount /proc 2>/dev/null + #/bin/umount /dev + /bin/umount /sys 2>/dev/null +fi +EOF + chmod 755 runit.sh + chroot /bocajail "$cdir/runit.sh" + if [ -r runit.retcode ]; then + ret=`cat runit.retcode` + else + ret=99 + fi +else + echo "COMPILATION IS NOT BEING CHROOTED -- THIS IS NOT AN IDEAL SETTING" + $sf -r1 -F1000 -n0 -U$bocau -G$bocag -C. -ostdout0 -estderr0 -d$maxm -m$maxm -f20000 -t$ttime -T$ttime ./compileit.sh + ret=$? +fi +if [ -f "stdout0" ]; then + cat "stdout0" +fi +if [ -f "stderr0" ]; then + cat "stderr0" +fi +rm -rf src/ +if [ "$ret" != "0" ]; then + echo "Compilation Error: $ret" + exit $ret +fi +ret=`cat compileit.retcode` +if [ "$ret" != "0" ]; then + echo "Compilation Error: $ret" + ret=1 +fi +exit $ret diff --git a/boca-1.5.0/src/admin/buildproblem.php b/boca-1.5.0/src/admin/buildproblem.php new file mode 100644 index 0000000..f651002 --- /dev/null +++ b/boca-1.5.0/src/admin/buildproblem.php @@ -0,0 +1,107 @@ +. +//////////////////////////////////////////////////////////////////////////////// +// Last modified 31/aug/2012 by cassio@ime.usp.br +require('header.php'); +if(($ct = DBContestInfo($_SESSION["usertable"]["contestnumber"])) == null) + ForceLoad("../index.php"); + +?> +

+To build a problem package using standard script files, fill in the following fields. + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Problem Fullname: + +
Problem Basename (a.k.a. name of class expected to have the main): + +
Description file (PDF, txt, ...): + +
Problem input file: + +
Problem correct output file: + +
Timelimit (in sec): + +(optional: use a , followed by the number of repetitions to run) +
+
+
+ + +
+ +
+ + + diff --git a/boca-1.5.0/src/admin/problem.php b/boca-1.5.0/src/admin/problem.php index 365d059..36e5e00 100644 --- a/boca-1.5.0/src/admin/problem.php +++ b/boca-1.5.0/src/admin/problem.php @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . //////////////////////////////////////////////////////////////////////////////// -// Last modified 21/jul/2012 by cassio@ime.usp.br +// Last modified 31/aug/2012 by cassio@ime.usp.br require('header.php'); if(($ct = DBContestInfo($_SESSION["usertable"]["contestnumber"])) == null) ForceLoad("../index.php"); @@ -31,6 +31,127 @@ if (isset($_GET["delete"]) && is_numeric($_GET["delete"]) && isset($_GET["input" ForceLoad("problem.php"); } +if(isset($_POST['Submit5']=='Send') && + isset($_POST['probleminput']) && + isset($_POST['problemsol']) && + isset($_POST['basename']) && + isset($_POST['fullname']) && + isset($_POST['timelimit'])) { + if ($_POST["confirmation"] == "confirm") { + if ($_FILES["probleminput"]["name"] != "") { + $type=myhtmlspecialchars($_FILES["probleminput"]["type"]); + $size=myhtmlspecialchars($_FILES["probleminput"]["size"]); + $name=myhtmlspecialchars($_FILES["probleminput"]["name"]); + $temp=myhtmlspecialchars($_FILES["probleminput"]["tmp_name"]); + if (!is_uploaded_file($temp)) { + IntrusionNotify("file upload problem."); + ForceLoad("../index.php"); + } + } else $name = ""; + if ($_FILES["problemsol"]["name"] != "") { + $type1=myhtmlspecialchars($_FILES["problemsol"]["type"]); + $size1=myhtmlspecialchars($_FILES["problemsol"]["size"]); + $name1=myhtmlspecialchars($_FILES["problemsol"]["name"]); + $temp1=myhtmlspecialchars($_FILES["problemsol"]["tmp_name"]); + if (!is_uploaded_file($temp1)) { + IntrusionNotify("file upload problem."); + ForceLoad("../index.php"); + } + } else $name1 = ""; + if (isset($_FILES["problemdesc"]) && $_FILES["problemdesc"]["name"] != "") { + $type2=myhtmlspecialchars($_FILES["problemsol"]["type"]); + $size2=myhtmlspecialchars($_FILES["problemsol"]["size"]); + $name2=myhtmlspecialchars($_FILES["problemsol"]["name"]); + $temp2=myhtmlspecialchars($_FILES["problemsol"]["tmp_name"]); + if (!is_uploaded_file($temp2)) { + IntrusionNotify("file upload problem."); + ForceLoad("../index.php"); + } + } else $name2 = ""; + + $ds = DIRECTORY_SEPARATOR; + if($ds=="") $ds = "/"; + $tmpdir = getenv("TMP"); + if($tmpdir=="") $tmpdir = getenv("TMPDIR"); + if($tmpdir[0] != $ds) $tmdir = $ds . "tmp"; + if($tmpdir=="") $tmpdir = $ds . "tmp"; + $locr = $_SESSION["locr"]; + $dir = tempnam($tmpdir, "problem"); + if(@mkdir($dir, 0700)) { + @mkdir($dir . $ds . 'limits'); + @mkdir($dir . $ds . 'compare'); + @mkdir($dir . $ds . 'compile'); + @mkdir($dir . $ds . 'run'); + @mkdir($dir . $ds . 'input'); + @mkdir($dir . $ds . 'output'); + @mkdir($dir . $ds . 'tests'); + @mkdir($dir . $ds . 'description'); + $filea = array('compare' . $ds . 'c','compare' . $ds . 'cpp','compare' . $ds . 'java', + 'compile' . $ds . 'c','compile' . $ds . 'cpp','compile' . $ds . 'java', + 'run' . $ds . 'c','run' . $ds . 'cpp','run' . $ds . 'java'); + foreach($filea as $file) { + if(is_readable($locr . $ds . '..' . $ds . 'doc' . $ds . 'problemtemplate' . $ds . $file)) { + @copy($locr . $ds . '..' . $ds . 'doc' . $ds . 'problemtemplate' . $ds . $file, $dir . $ds . $file); + } else { + cleardir($dir); + ob_end_flush(); + MSGError('Could not read problem template file ' . $file); + ForceLoad('problem.php'); + } + } + $tl = explode('/',$_POST['timelimit']); + if(!isset($tl[1]) || !is_numeric(trim($tl[1]))) $tl[1]='1'; + $str = "echo " . trim($tl[0]) . "\necho " . trim($tl[1]) . "\necho 512\necho " . ($size1 / 512) . "\nexit 0\n"; + file_put_contents($dir . $ds . 'limits' . $ds . 'c',$str); + file_put_contents($dir . $ds . 'limits' . $ds . 'cpp',$str); + file_put_contents($dir . $ds . 'limits' . $ds . 'java',$str); + $str = "basename=" . trim($_POST['basename']) . "\nfullname=" . trim($_POST['fullname']); + if($name2) { + @copy($temp2, $dir . $ds . 'description' . $ds . $name2); + @unlink($temp2); + $str .= "\ndescfile=" . $name2; + } + $str .= "\n"; + file_put_contents($dir . $ds . 'description' . $ds . 'problem.info',$str); + if($name && $name1) { + @copy($temp, $dir . $ds . 'input' . $ds . 'file1'); + @unlink($temp); + @copy($temp1, $dir . $ds . 'output' . $ds . 'file1'); + @unlink($temp1); + } else { + cleardir($dir); + ob_end_flush(); + MSGError('Could not read problem input/output files'); + ForceLoad('problem.php'); + } + $ret=create_zip($dir, glob($dir . $ds . '*'),$dir . '.zip'); + cleardir($dir); + if($ret <= 0) { + @unlink($dir . '.zip'); + ob_end_flush(); + MSGError('Could not write to zip file'); + ForceLoad('problem.php'); + } + $str = file_get_contents($dir . '.zip'); + @unlink($dir . '.zip'); + header ("Expires: " . gmdate("D, d M Y H:i:s") . " GMT"); + header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + header ("Cache-Control: no-cache, must-revalidate"); + header ("Pragma: no-cache"); + header ("Content-transfer-encoding: binary\n"); + header ("Content-type: application/force-download"); + header ("Content-Disposition: attachment; filename=" . basename($dir . '.zip')); + ob_end_flush(); + echo $str; + exit; + } else { + ob_end_flush(); + MSGError('Could not write to temporary directory'); + ForceLoad('problem.php'); + } + } +} + if (isset($_POST["Submit3"]) && isset($_POST["problemnumber"]) && is_numeric($_POST["problemnumber"]) && isset($_POST["problemname"]) && $_POST["problemname"] != "") { if ($_POST["confirmation"] == "confirm") { @@ -164,6 +285,9 @@ To replace the data of a problem, proceed as if it did not exist (data will be r