#!/bin/bash # //////////////////////////////////////////////////////////////////////////////// # //BOCA Online Contest Administrator # // Copyright (C) 2003-2014 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: 21/aug/2014 by cassio@ime.usp.br # # parameters are: # $1 main_class # $2 input_file # $3 timelimit (limit to run all the repetitions, by default only one repetition) # $4 number_of_repetitions_to_run (optional, can be used for better tuning the timelimit) # $5 maximum allowed memory (in MBytes) # $6 maximum allowed output size (in KBytes) # # 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 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 [ "$1" == "" -o "$2" == "" -o "$3" == "" ]; then echo "parameter problem" exit 43 fi if [ -r run.exe ]; then rm -f run.jar cp run.exe run.jar fi if [ -r "$1" ]; then rm -f run.jar cp "$1" run.jar fi if [ ! -r run.jar ]; then echo "ERROR: file run.jar not found - possible error during compilation" exit 1 fi name=`basename "$1"` if [ "${name##*.}" == "class" -a "${name##*.}" == "CLASS" ]; then echo "WARNING: removing .class file extension" fi if [ "${name##*.}" == "class" ]; then name=`basename "$1" .class` fi if [ "${name##*.}" == "CLASS" ]; then name=`basename "$1" .CLASS` fi if [ ! -r "$2" ]; then echo "$2 not found (or is not in the current dir) or it's not readable" exit 45 fi if [ ! -x "$sf" ]; then echo "$sf not found or it's not executable" exit 46 fi time=$3 if [ "$time" -gt "0" ]; then let "ttime = $time + 30" else time=1 ttime=30 fi nruns=1 if [ "$4" != "" ]; then if [ "$4" -gt "0" ]; then nruns=$4 fi fi maxm=512000 if [ "$5" != "" ]; then if [ "$5" -gt "0" ]; then maxm=${5}000 fi fi maxf=1024 if [ "$6" != "" ]; then if [ "$6" -gt "0" ]; then maxf=${6} fi fi rm -f runit.retcode 2>/dev/null cp "$2" stdin0 2>/dev/null cdir=`pwd` echo "Current directory is $cdir" >&2 echo $cdir | grep -q "/bocajail" if [ $? == 0 ]; then cdir=`echo $cdir | sed "s/.*\/bocajail//"` 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 java=`which java` [ -x "\$java" ] || java=/usr/bin/java if [ ! -x "\$java" ]; then echo "\$java not found or it's not executable" exit 47 fi export CLASSPATH=.:./run.jar:$CLASSPATH "$sf" -r$nruns -t$time -T$ttime -istdin0 -F256 -u256 -ostdout0 -estderr0 -U$bocau -G$bocag -n0 -C. -f20000 -d20000000 -m20000000 -- "\$java" -Xmx${maxm}K -Xms${maxm}K "$name" retval=\$? echo \$retval > 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` fi if [ "$ret" == "" ]; then echo "Execution error - check autojudging" exit 49 fi else echo "CODE NOT BEING CHROOTED. DO NOT RUN THIS ON THE MAIN SERVER" >&2 echo "CODE NOT BEING CHROOTED. DO NOT RUN THIS ON THE MAIN SERVER" >&2 echo "CODE NOT BEING CHROOTED. DO NOT RUN THIS ON THE MAIN SERVER" >&2 java=`which java` [ -x "$java" ] || java=/usr/bin/java if [ ! -x "$java" ]; then echo "$java not found or it's not executable" exit 47 fi "$sf" -r$nruns -t$time -T$ttime -istdin0 -F256 -u256 -U$bocau -G$bocag -ostdout0 -estderr0 -n0 -C. -d20000000 -m20000000 -- "$java" -cp run.jar -Xmx${maxm}K -Xms${maxm}K "$name" ret=$? fi if [ $ret -gt 10 ]; then echo "> > > > > > > Nonzero return code - possible runtime error - I'M GUESSING IT IS RUNTIME ERROR < < < < < < < <" ret=9 fi if [ -f stdout0 ]; then cat stdout0 fi exit $ret