#!/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/august/2014 by cassio@ime.usp.br # # parameters are: # $1 source_file # $2 exe_file (default run.exe) # $3 timelimit # $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 gcc\` [ -x "\$cc" ] || cc=/usr/bin/gcc if [ ! -x "\$cc" ]; then echo "\$cc not found or it's not executable" exit 47 fi cd src "\$cc" -static -O2 -o "../$exe" "$name" -lm 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 [ ! -e /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