#! /bin/sh # # view2.sh for testing only, 25 Aug. 2007 # # view/edit/compile/run project files # # R. Perry, Jan. 2003 # # This runs as root in the chroot environment of the web server # # ZZ marks local customization sections # umask 077 PATH="/usr/bin"; export PATH # force sort to use ASCII order LC_COLLATE="C"; export LC_COLLATE MANPATH="/opt/man:/usr/man"; export MANPATH LOG="/vecr/logs/LOG" IDLIST="/vecr/local-lib/id.list" FCLIST="/vecr/local-lib/fc.list" IDN="/vecr/local-lib/id.N" # run with time limit # RUN="/vecr/local-bin/run" # other programs and scripts # SETUIDGID="/vecr/local-bin/chroot+setuidgid" UPDATESH="/vecr/local-bin/update2.sh" RUNSH="/vecr/local-bin/run.sh" JAVA="/opt/bin/java" GDB="/opt/bin/gdb" ### # send stderr to stdout # exec 2>&1 ### # log the connection # echo "`date` \"${REMOTE_USER}\" ${REMOTE_ADDR} ${SERVER_PORT} ${COURSE} $*" >> "${LOG}" ### # function to display error and exit # error() { echo "Content-type: text/plain\n" echo "$@" # if [ "t3" = "$sub" ]; then # echo "\nTest #3 has been collected." # fi exit 1 } ### # functions to check subdir and file name # check_sub() { case "$sub" in a1|a2|a3|a4|a5|a6|a7|a8|a9|a10|iPlot|HTML) READONLY="";; *) error "Bad dir: $sub"; exit 1;; esac } # check_file() { case "$file" in p1.c|p2.c|p3.c|p4.c) ;; p1.java|p2.java|p3.java|p4.java) ;; p1.sh|p2.sh|p3.sh|p4.sh) ;; p1.txt|p2.txt|p3.txt|p4.txt) ;; Makefile) ;; p1.h|p2.h|p3.h|p4.h) ;; *) error "Bad file: $file"; exit 1;; esac } ### # extract user from REMOTE_USER # user=`echo "${REMOTE_USER}" | sed -e 's/,.*//' -e 's/.*=//' -e 's;/;;g' -e 's/\.//g' -e 's/ //g' -e 's/ //g' | tr '[:upper:]' '[:lower:]'` ### # $user can't be empty # if [ -z "$user" ]; then error "Bad user: ${REMOTE_USER} -> $user" exit 1 fi ### # check for admin user - ZZ # #-- RP & TA admin="" case "$user" in rperry) admin=1 admin_user="$user" cookie=`echo "${HTTP_COOKIE}" | grep 'VECR_USER=' | sed -e 's/.*VECR_USER=//' -e 's/;.*//'` if [ -n "$cookie" -a "$cookie" != "$user" ]; then case "$user" in nworon01) x=`grep "^${cookie}\$" "$FCLIST"` if [ -n "$x" ]; then user="$cookie" fi ;; rperry) user="$cookie" ;; esac fi ;; esac #-- #admin="" #case "$user" in # rperry) # admin=1 # admin_user="$user" # cookie=`echo "${HTTP_COOKIE}" | grep 'VECR_USER=' | sed -e 's/.*VECR_USER=//' -e 's/;.*//'` # if [ -n "$cookie" -a "$cookie" != "$user" ]; then # user="$cookie" # fi # ;; #esac #-- # # check for special users # case "$user" in frodo) umask 022 ;; esac # export user ### # set uid, create if necessary # # possible race condition here... # uid=`grep "^${user} " "$IDLIST" | awk '{ print $2 }' | head -1` if [ -z "$uid" ]; then last=`cat "$IDN"` uid=`expr "$last" + 1` echo "$uid" > "$IDN" echo "$user $uid" >> "$IDLIST" fi # if [ "$uid" -lt 3000 ]; then error "Bad uid: $uid - please contact Rick Perry about this!" exit 1 fi ### # set dir, create if necessary # # fname is $user, COURSE env is set by the wrapper # # ZZ - current courses - Fall 2006: osp; Spring 2007: fc, ccs # Summer 2007: N; Fall 2007: osp # #SVS submit="/vecr/$COURSE/submit" # case "$COURSE" in osp) top="/vecr/$COURSE/home" ;; *) error "Bad COURSE: $COURSE" ;; esac # fname="$user" dir="$top/$fname" if [ ! -d "$dir" ]; then mkdir -m 750 "$dir" chgrp "${uid}" "$dir" echo "`date` \"${REMOTE_USER}\" ${REMOTE_ADDR} ${SERVER_PORT} ${COURSE} mkdir $fname $uid" >> "${LOG}" fi ### # create sub-dirs if necessary # for sub in a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 iPlot HTML do s="$dir/$sub" if [ ! -d "$s" ]; then check_sub if [ -z "$READONLY" ]; then mkdir -m 700 "$s" chown "${uid}:${uid}" "$s" fi fi done ### # ZZ - create ccs a2/p3.in if necessary # # f="$dir/a2/p3.in" # if [ ! -r "$f" ]; then # cd /src/sdes-cbc || exit 1 #-- rewrite using chroot+setuidgid --stdout: # /usr/local/bin/fortune | /usr/local/jdk/bin/java CBCEncrypt "$user" > "$f" # chown "${uid}:${uid}" "$f" # chmod 400 "$f" # fi ### # handle GET # # Usage: $0 GET edit|plinenums|mlinenums|view|compile|cerr|preproc|asm|asmopt|zip|frameset #SVS |submit|submit_view|submit_get # subdir file # if [ "$1" = "GET" ]; then mode="$2" sub="$3" file="$4" args="$5" HOME="$dir/$sub" export HOME # ZZ # # if [ -n "$sub" -a -z "$admin" -a "$COURSE" != "N" ]; then # # if [ -n "$sub" -a -z "$admin" ]; then # mode="zip" # fi if [ -z "$mode" ]; then mode="edit" fi case "$mode" in frameset) echo "Content-type: text/html\n ${user} - ${COURSE} - ${sub}/${file} <body bgcolor=white text=black> <h2>${user} - ${COURSE} - ${sub}/${file}</title></h2> <p>This document was designed to be viewed using Frames. You are reading this because your browser doesn't support, or has disabled, the preferred presentation.</p> <p>You may<menu> <li>Return with Frames enabled and reload this URL. <li>Accept that the document will disappear when you select a link, and <a href=\"map1.html\">read it unframed</a>. </menu></body>" exit 0 ;; empty) echo "Content-type: text/html\n ${user} - ${COURSE} - ${sub}/${file} results: " exit 0 ;; edit|plinenums|mlinenums) # # if no arguments, list subdirs # if [ -z "$sub" ]; then echo "Content-type: text/html\n" echo "${user} - ${COURSE} - projects

${user} - ${COURSE} - projects

" # ZZ # echo "Note: starting Mon May 15 06:58:55 EDT 2006 - # only zip download is available, no view, edit, etc.

" for s in a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 iPlot HTML do echo "$s,  " done echo "

zip - download all projects

documentation and source code" if [ -n "$admin" ]; then echo "

" fi echo "

Logout - (UserID logout with empty password)" # # if no file argument, list files # elif [ -z "$file" ]; then check_sub echo "Content-type: text/html\n" echo "${user} - ${COURSE} - ${sub}

${user} - ${COURSE} - ${sub}

Home

Edit: - submit - view submissions" # ZZ # echo "

Note: this environment will be shut down after May 9, # then will be available again, read-only, later next week.

" if [ -z "$READONLY" ]; then echo "

  " case "$sub" in iPlot) files="p1.c p2.c p3.c" ;; *) files="p1.c p2.c p3.c p4.c p1.java p2.java p3.java p4.java BREAK p1.sh p2.sh p3.sh p4.sh p1.txt p2.txt p3.txt p4.txt BREAK Makefile p1.h p2.h p3.h p4.h" ;; esac # for file in $files do if [ "$file" = "BREAK" ]; then echo "

  " else echo "$file,  " fi done fi echo "

View:

"
	  #
	  ls -AlL "${dir}/${sub}" |
	    awk 'NF == 9 { printf("%8s %3s %2s %5s %s\n", \
	      $5,$6,$7,$8,$9,$9); }' sub="$sub" course="$COURSE"
	  #--  sed -e 's/\&/\&/g' -e 's//\>/g' |
	  #--  cut -c33-
	  echo "
" # # have subdir and file arguments # else check_sub check_file if [ -n "$READONLY" ]; then error "Readonly dir: $sub"; exit 1 fi cd "${dir}/${sub}" P="`pwd`" # if [ "$P" != "${dir}/${sub}" ]; then # error "Bad dir: $P != ${dir}/${sub}"; exit 1 # fi # exec "$SETUIDGID" --setuidgid "$uid" "$uid" \ "$UPDATESH" "$mode" "$user" "$sub" "$file" "$args" exit 0 fi ;; view) # # must have subdir and file arguments # if [ -z "$file" ]; then error "missing subdir and file arguments" exit 1; fi # check_sub # # set uid/gid, and run the script # exec "$SETUIDGID" --setuidgid "$uid" "$uid" \ "$RUN" "$RUNSH" "$mode" "$top/$fname" "$sub" "$file" exit 0 ;; compile|cerr|preproc|asm|asmopt) check_sub check_file if [ -n "$READONLY" ]; then error "Readonly dir: $sub"; exit 1 fi # # set uid/gid, and run the script # exec "$SETUIDGID" --setuidgid "$uid" "$uid" \ "$RUN" "$RUNSH" "$mode" "$top/$fname" "$sub" "$file" exit 0 ;; zip) cd "$top" || exit 1 #echo "Content-type: application/zip\n" echo "Content-type: application/octet-stream Content-Disposition: attachment; filename=\"$user.zip\"\n" exec "$SETUIDGID" --setuidgid "$uid" "$uid" \ /usr/bin/zip -rq - "$user" exit 0 ;; #SVS submit|submit_view|submit_get) #SVS check_sub #SVS cd "$top" || exit 1 #SVS d="$submit/$user" #SVS if [ ! -d "$d" ]; then #SVS mkdir "$d" #SVS fi #SVS # #SVS case "$mode" in #SVS submit) #SVS d="$d/$sub-`date '+%Y-%m-%d-%H:%M:%S'`.tar.gz" #SVS echo "Content-type: text/plain\n\nSubmitting ${COURSE} $sub\n\nCreating $d...\n" #SVS tar cvf - "$user/$sub" | gzip > "$d" #SVS echo "\nDone." #SVS exit 0 #SVS ;; #SVS submit_view) #SVS echo "Content-type: text/html\n #SVS ${user} - ${COURSE} - ${sub} #SVS ${user} ${COURSE} ${sub} submissions #SVS
"
#SVS		ls "$d" | grep "^${sub}-" | while read f
#SVS		 do
#SVS		    echo "\n$f"
#SVS		    gzip -d < "$d/$f" | tar tvf - 2>/dev/null | cut -c21-
#SVS		 done
#SVS		echo "\nEnd.
" #SVS exit 0 #SVS ;; #SVS submit_get) #SVS # #SVS # careful here, $file is unsafe #SVS # #SVS (ls "$d"; echo "NOT_FOUND") | while read f #SVS do #SVS if [ "$f" = "NOT_FOUND" ]; then #SVS error "File $file not found." #SVS exit 1 #SVS elif [ "$f" = "$file" ]; then #SVS echo "Content-type: application/octet-stream #SVSContent-Disposition: attachment; filename=\"${user}-${COURSE}-${f}\"\n" #SVS cat "$d/$f" #SVS exit 0 #SVS fi #SVS done #SVS exit 0 #SVS ;; #SVS esac #SVS ;; *) error "Bad request" exit 1 ;; esac ### # handle POST # # compile|upload|update| #UCR update_compile|update_compile_run # |copy|run|crun|IO|debug|IOD|plot|splot|audio|setuser # subdir file args # else read mode sub file args echo "`date` \"${user}\" ${REMOTE_ADDR} ${SERVER_PORT} ${COURSE} POST $mode $sub $file $args" >> "${LOG}" HOME="$dir/$sub" export HOME # ZZ # # if [ -z "$admin" -a "$COURSE" != "N" ]; then # # if [ -z "$admin" ]; then # exec "$0" GET zip # exit 0 # fi # setuser special case # if [ -n "$admin" -a "$mode" = "setuser" ]; then echo "Content-type: text/html Set-Cookie: VECR_USER=$args; path=/ Status: 302 Moved Temporarily Location: http://${HTTP_HOST}/prog/${COURSE}\n" exit fi check_sub check_file if [ -n "$READONLY" ]; then error "Readonly dir: $sub"; exit 1 fi case "$mode" in compile) # # set uid/gid, and run the script # exec "$SETUIDGID" --setuidgid "$uid" "$uid" \ "$RUN" "$RUNSH" "$mode" "$top/$fname" "$sub" "$file" exit 0 ;; upload|update|copy) #UCR |update_compile|update_compile_run # # update file, then redisplay # cd "${dir}/${sub}" P="`pwd`" if [ "$P" != "${dir}/${sub}" ]; then error "Bad dir: $P != ${dir}/${sub}"; exit 1 fi # "$SETUIDGID" --setuidgid "$uid" "$uid" \ "$UPDATESH" "$mode" "$user" "$sub" "$file" "$args" # #UCR case "$mode" in #UCR update_compile) #UCR exec "$0" GET compile "$sub" "$file" "$args" #UCR ;; #UCR update_compile_run) #UCR echo "crun $sub $file $args" | exec "$0" POST #UCR ;; #UCR *) #UCR exec "$0" GET edit "$sub" "$file" "$args" #UCR ;; #UCR esac # exec "$0" GET edit "$sub" "$file" "$args" exit 0 ;; run|crun|debug|plot|splot|audio|cmd) # # flush stdin ??? why ??? -- removed 11/12/2006 # # cat >/dev/null # # set some limits # # -c maximum core file size (in 512-byte blocks) # -d maximum size of data segment or heap (in kbytes) # -f maximum file size (in 512-byte blocks) # -n maximum file descriptor plus 1 # -s maximum size of stack segment (in kbytes) # -t maximum CPU time (in seconds) # -v maximum size of virtual memory (in kbytes) # ulimit -c 0 ulimit -d 8192 ulimit -f 1024 ulimit -n 64 ulimit -s 8192 ulimit -t 10 # ulimit -v 65536 # jdk1.3 has a problem with this limit # # set uid/gid, and run the script # exec "$SETUIDGID" --setuidgid "$uid" "$uid" \ "$RUN" "$RUNSH" "$mode" "$top/$fname" "$sub" "$file" "$args" exit 0 ;; IO|IOD) # # generate IO applet HTML # case "$file" in # add debug here to run gdb ZZ *.c) if [ "$mode" = "IO" ]; then prog=./`basename "$file" .c` else prog="$GDB"; b=./`basename "$file" .c`; args="$b $args" fi ;; *.java) prog="$JAVA"; b=`basename "$file" .java`; args="$b $args" ;; *.sh) prog="/opt/bin/ksh"; args="$file $args" ;; esac echo "Content-type: text/html\n VECR/IO ${user} - ${COURSE} - ${sub}/${file} - ${sub} - Home - Running: $prog $args
" cd "/vecr/IO/bin" || exit 1 $JAVA IOticket "$user" "$uid" echo " Your browser does not support Java, or Java is not enabled. Sorry! " exit 0 ;; *) error "Bad request" exit 1 ;; esac fi