###############################################################
|
|
# 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 = <SERVER>;
|
|
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 = <SERVER>) {
|
|
if ($line =~ /^\r\n/) {
|
|
last;
|
|
}
|
|
}
|
|
|
|
# Read and return the response from the result server
|
|
$line = <SERVER>;
|
|
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;
|
|
|