#!/usr/bin/perl -w # Cgi to show customer's orders # Secure path $ENV{PATH} = '/bin/:/usr/bin:/usr/local/bin'; # Using CGI modules and creating a new CGI instance use CGI; $query = new CGI; # Defining some variables $htmltpl = '/home/httpd/html/result.html'; $basepath = '/var/tables/acmeinc/'; $cusfile = $basepath . 'customer.rdb'; $ctlgfile = $basepath . 'catalog.rdb'; # Getting customer name from the form $cusname = $query->param('cusname'); # Avoid buffer overflow (maximum 50 chars) and command execution # from the customer name: this is a security countermeasure $cusname = substr($cusname, 0, 50); $cusname =~ s/\///g; $cusname =~ s/#//g; $cusname =~ s/\n//g; $cusname =~ s/"//g; $cusname =~ s/'//g; $cusname =~ s/\`//g; $cusname =~ s/!//g; $cusname =~ s/;//g; $cusname =~ s/<//g; $cusname =~ s/>//g; # Extracting customer code for further queries and striping insecure stuffs $cuscode = `nosql row 'NAME=="$cusname"' < $cusfile | nosql column CODE | nosql body`; $cuscode =~ s/\///g; $cuscode =~ s/#//g; $cuscode =~ s/!//g; $cuscode =~ s/\n//g; $cusname =~ s/"//g; $cusname =~ s/\`//g; $cusname =~ s/;//g; $cusname =~ s/<//g; $cusname =~ s/>//g; $cuscode =~ s/\s*//g; # Getting customer datafile that is usually the code plus the ".rdb" # extension $datafile = $basepath . "received/" . $cuscode . ".rdb"; # Getting the rows containing the query of the pending orders # @cusdata = `nosql cat $datafile | nosql join -j PROD - $ctlgfile | nosql addcol SUBTOTAL | nosql compute 'SUBTOTAL = QTY*PRICE' | nosql column PROD DESC QTY PRICE SUBTOTAL | nosql body`; # If no rows found, then customer may not exists or has no pending # orders if (@cusdata == 0) { &log_and_die("No records found on the specified customer") }; # Calculating total amount due chop($total = `nosql cat $datafile | nosql join -j PROD - $ctlgfile | nosql addcol SUBTOTAL | nosql compute 'SUBTOTAL = QTY*PRICE' | nosql subtotal -T SUBTOTAL | nosql body`); # If the string is empty, then something went wrong. if ($total eq '') { &log_and_die("Cannot calculate total") }; # This opens html template file for reading and # it's associated to the standard input space ($_) open(HTMFILE, $htmltpl) || &log_and_die("Can't open file $htmltpl"); $_ = join("", <HTMFILE>); close(HTMFILE); # Keeping out newlines. s/\n//g; # Transforming multiple spaces into one, s/\s+/ /g; # Finding stanza into template and we separate # header, footer and the body (that has to be repeated) /(.+)<\s*!--\s*here\s+starts\s+nosql\s+stanza\s*--->(.+)<\s*!--\s*here \s+ends\s+nosql\s+stanza\s*--\s*>(.+)/i ; # # Copying found pattern on temp vars my $header = $1; my $body = $2; my $footer = $3; # substituting keywords on header and footer with appropriate values $header =~ s/##NAME##/$cusname/; $footer =~ s/##TOTAL##/$total/; # Print html content type and template header print $query->header("text/html"); print $header; # Repeating values substitution in stanza for each query row foreach $data (@cusdata) { my $tmpbody = $body; my ($prod, $desc, $qty, $price, $subtotal) = split(/\t/, $data); $tmpbody =~ s/##PROD##/$prod/; $tmpbody =~ s/##DESC##/$desc/; $tmpbody =~ s/##QTY##/$qty/; $tmpbody =~ s/##PRICE##/$price/; $tmpbody =~ s/##SUBTOTAL##/$subtotal/; print $tmpbody; } # Print template footer print $footer; # sub log_and_die { # Get parms my $message = shift; # Print error message to user's browser print $query->header("text/html"); print $query->start_html(-title=> "Error processing data"); print "<P>An unrecoverable error occurred: $message</P>\n"; print $query->end_html; exit(1); };