############################################################### # Driverlib.pm - A package of helper functions for Perl drivers # # Copyright (c) 2005 David R. O'Hallaron, All rights reserved. ############################################################### package Driverlib; use Socket; # Autogenerated header file with lab-specific constants use lib "."; use Driverhdrs; require Exporter; @ISA = qw(Exporter); @EXPORT = qw( driver_post ); use strict; ##### # Public functions # # # driver_post - This is the routine that a driver calls when # it needs to transmit an autoresult string to the result server. # sub driver_post ($$) { my $userid = shift; # User id for this submission my $result = shift; # Autoresult string my $autograded = shift; # Set if called by an autograder # Echo the autoresult string to stdout if the driver was called # by an autograder if ($autograded) { print "\n"; print "AUTORESULT_STRING=$result\n"; return; } # If the driver was called with a specific userid, then submit # the autoresult string to the result server over the Internet. if ($userid) { my $status = submitr($Driverhdrs::SERVER_NAME, $Driverhdrs::SERVER_PORT, $Driverhdrs::COURSE_NAME, $userid, $Driverhdrs::LAB, $result); # Print the status of the transfer if (!($status =~ /OK/)) { print "$status\n"; print "Did not send autoresult string to the result server.\n"; exit(1); } print "Success: Sent autoresult string for $userid to the result server.\n"; } } ##### # Private functions # # # submitr - Sends an autoresult string to the result server # sub submitr ($$$$$$) { my $hostname = shift; my $port = shift; my $course = shift; my $userid = shift; my $lab = shift; my $result = shift; my $internet_addr; my $enc_result; my $paddr; my $line; my $http_version; my $errcode; my $errmsg; # Establish the connection to the server socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp')); $internet_addr = inet_aton($hostname) or die "Could not convert $hostname to an internet address: $!\n"; $paddr = sockaddr_in($port, $internet_addr); connect(SERVER, $paddr) or die "Could not connect to $hostname:$port:$!\n"; select((select(SERVER), $| = 1)[0]); # enable command buffering # Send HTTP request to server $enc_result = url_encode($result); print SERVER "GET /$course/submitr.pl/?userid=$userid&lab=$lab&result=$enc_result&submit=submit HTTP/1.0\r\n\r\n"; # Get first HTTP response line $line = ; chomp($line); ($http_version, $errcode, $errmsg) = split(/\s+/, $line); if ($errcode != 200) { return "Error: HTTP request failed with error $errcode: $errmsg"; } # Read the remaining HTTP response header lines while ($line = ) { if ($line =~ /^\r\n/) { last; } } # Read and return the response from the result server $line = ; chomp($line); close SERVER; return $line; } # # url_encode - Encode text string so it can be included in URI of GET request # sub url_encode ($) { my $value = shift; $value =~s/([^a-zA-Z0-9_\-.])/uc sprintf("%%%02x",ord($1))/eg; return $value; } # Always end a module with a 1 so that it returns TRUE 1;