#!/usr/bin/perl #============================================================================= # ParkeCalc C : server-side calculator # If someone is authenticated, it adds a greeting. # Will welcome them back, if they return. #----------------------------------------------------------------------------- use bignum; use CGI qw(:all); #============================================================================= # Configuration. my $inputSize = 20; #============================================================================= # Get POSTed parameters. # Read stadard input (POST) to pick up the parameters (key-value pairs). # Should be on a single line, but loop over lines, just in case. my %param; while (<>) { # Tokenize, splitting on "&". my @kv = split("&", $_); # key = value # Put into a hash (a "map" in Java-speak), for easy access. foreach my $pair (@kv) { $pair =~ /(.*)=(.*)/; $param{$1} = $2; } } %ops = ( "none" => "", "add" => "", "mult" => "", "power" => "" ); # Validate & fix. if (!defined($param{"one"}) || !&isNumber($param{"one"})) { $param{"one"} = ""; } if (!defined($param{"two"}) || !&isNumber($param{"two"})) { $param{"two"} = ""; } if (!defined($param{"op"}) || !defined($ops{$param{"op"}})) { $param{"op"} = "none"; } # Mode my $mode; if ($param{"one"} eq "" || $param{"two"} eq "" || $param{"op"} eq "none") { $mode = "inc"; } else { $mode = "run"; } #----------------------------------------------------------------------------- # See if we can identify who is calling. my $user = $ENV{'REMOTE_USER'}; #============================================================================= # HTTP Response #----------------------------------------------------------------------------- # Header #print "Set-Cookie: ", &mkCookie("when", time), "\n" if (defined($user)); print "Set-Cookie: ", &mkCookie("when", time), "\n"; print "Content-Type: text/html\n"; print "\n"; #============================================================================= # Payload #----------------------------------------------------------------------------- # HTML start print << "START"; Parke's Great Calculator! START #----------------------------------------------------------------------------- # HTML content # Store values in a simpler way for ease in in-place print. my $one = $param{"one"}; my $two = $param{"two"}; my $answer = ""; # If in mode RUN, delivery is with answer and is read-only. my $readonly = ""; if ($mode eq "run") { $readonly = "disabled readonly"; $answer = &compute(); } # One of the options is selected. Set up for which one is. my $none = ""; my $add = ""; my $mult = ""; my $power = ""; $none = "selected" if ($param{"op"} eq "none"); $add = "selected" if ($param{"op"} eq "add"); $mult = "selected" if ($param{"op"} eq "mult"); $power = "selected" if ($param{"op"} eq "power"); print << "CONTENT";

Parke's Great Calculator!

CONTENT if (length($answer) <= $inputSize) { print << "CONTENT"; CONTENT } else { my $rows = int((length($answer) - 1) / $inputSize) + 1; print << "CONTENT"; CONTENT } print << "CONTENT";
Number One
Number Two
 
Answer
Answer
CONTENT if ($mode eq "inc") { print << "CONTENT";
CONTENT } print << "CONTENT";
CONTENT if ($mode eq "run") { print << "CONTENT";
CONTENT } print << "CONTENT"; CONTENT #----------------------------------------------------------------------------- # Welcome the user, if we know who it is. # Welcome back, if we can tell they are returning. # Let's only do this in mode = "inc". if ($mode eq "inc") { if (defined($user)) { my $when = ""; my $cData = $ENV{'HTTP_COOKIE'}; if (defined($cData)) { my @cookies = split(/;/, $cData); foreach my $pair (@cookies) { my ($name, $value) = split(/=/, $pair); $when = $value if ($name eq "when"); } } if ($when eq "") { print << "CONTENT";

Welcome, $user.

CONTENT } else { my $visit = &formatTime($when); print << "CONTENT";

Welcome back, $user. You last visited $visit.

CONTENT } } else { print << "CONTENT";

Welcome, whoever you are.

CONTENT } } print << "CONTENT"; CONTENT #----------------------------------------------------------------------------- # HTML finish print << "FINISH"; FINISH #============================================================================= # SUBROUTINES #----------------------------------------------------------------------------- # Compute the requested operation. sub compute { # Compute the answer. if ($param{"op"} eq "add") { return 1->bmul($param{"one"}) + 1->bmul($param{"two"}); } elsif ($param{"op"} eq "mult") { return 1->bmul($param{"one"}) * 1->bmul($param{"two"}); } elsif ($param{"op"} eq "power") { return 1->bmul($param{"one"})** 1->bmul($param{"two"}); } } #----------------------------------------------------------------------------- # Make a cookie. sub mkCookie { my ($name, $value) = @_; my $expires = time + 7 * 24 * 60 * 60; # In 7 days from now (in seconds). # Set the name and value as the method call parameters requested. my $cookie = "$name=$value"; # Format the expiration time in the format HTTP likes. $cookie .= "; expires=" . &formatTime($expires); # SCOPE: Localize the cookie to just this path. $cookie .= "; path=" . "/~godfrey/2041/secure"; # SCOPE: Cookie belongs to this domain. $cookie .= "; domain=" . ".cse.yorku.ca"; # Client should only send back if over HTTPS. $cookie .= "; secure"; return $cookie; } #----------------------------------------------------------------------------- # Format time like HTTP likes it. sub formatTime { my ($stardate) = @_; my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = gmtime($stardate); my @day = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"); my @month = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); return $day[$wday] . ", ". $mday . " " . $month[$mon] . " " . ($year + 1900) . " " . "$hour:$min:$sec " . "GMT"; } #----------------------------------------------------------------------------- # Perl has no simple isNumber check. sub isNumber { my ($x) = @_; return 1 if ((2 * $x) / 2 eq $x); return 0; }