#!/usr/bin/perl # NOTE: the above line must be changed to show the path to the # Perl interpreter on your system! Leave the #! as is, but # the path may have to be changed if yours is different. ######################################################################### # SFEBlackJack v1.0.3 # # Simple online video blackjack game for a website. # # Copyright 2003, Kristina L. Pfaff-Harris # # All rights reserved. # # # ######################################################################### ##### License for SFEBlackJack 1.0.3 ##### ##### This program may be used free of charge under the following ##### conditions: ##### ##### 1. All instructions and Copyright lines must remain unchanged. ##### ##### 2. All pages generated by the program must contain one of the ##### following pieces of HTML code: ##### ##### ##### Powered by SFEBlackJack: ##### ##### OR: ##### ##### ##### ##### You may not remove the information described above from the script ##### without express written permission from the author. ##### ##### 3. You may not sell or distribute this program. You may charge ##### a reasonable fee for installing it for a client as long as ##### you make it clear that you are not the author, and you are ##### not selling the program to them: only charging for installing ##### it. ##### ##### 4. You agree that this program is offered without warranty of ##### any kind, including warranty of fitness for a particular ##### purpose. You further agree that the author and all sites ##### associated in any way with this program are not liable for ##### any damage or loss incurred as a result of using this program. ##### ##### 5. You may modify the program for your own use but you may not ##### distribute modified copies under any circumstances without ##### express written permission from the author. ##### ##### 6. Use of this program requires agreement to all the terms and ##### conditions of this license. If you do not agree to one or ##### more of these terms, you may not use the program. ##### ######################################################################### # # # IMPORTANT: If you FTPed this program to your server in "binary" mode, # # it will NOT work! If you're not sure, please go back and FTP it # # to your server again and make sure you use "ascii" mode. If you get # # "500 Server Error", this is almost always the cause. :) # # # # Using the program: # # This program requires the file "sfeblackjack.cgi" at a minimum in # # order to work. Please read the README.sfeblackjack file for more # # information. Also, check the Scripts for Educators FAQ first # # (http://tesol.net/scripts/FAQ/) if you have problems. If none of that # # helps, email me and I'll at least try to help. :-) # # # # I hope this program proves useful to you! Please contact me # # (http://tesol.net/scriptmail.html) for any bugs or feedback. # ######################################################################### ##### # ##### BEGIN SECTION WHERE YOU WILL NEED TO CHANGE THINGS: # ##### # ##### In this section, there are several places where you'll need # ##### to make changes. Please read all instructions carefully # ##### before you make the changes. # ##### # ######################################################################### # $basedir: This is the base directory on your server where you # want the program to store the files that keep track of # the players' credits and their cards for their games. # *CHANGE* this to the full base system path # to where you want these files to be created and stored. # Please see the README.sfeblackjack file for more # information about $basedir, and how to set it up. # Please note that this is NOT a URL, and should NOT # contain "http://" # # If your web server is a Unix-type system, then this # probably MUST begin a /, and the folder must be writeable # by the web server. For example: # $basedir = "/path/to/your/files"; # # If your web server is a Windows-type system, then this # probably MUST begin a "c:" or "d:" or "e:". For example: # $basedir = "c:/path/to/your/files"; # # One slight exception to the above is this: if you make a directory # called "blackjack" in the same directory where this script is, then # what I have below may work. If nothing else, it's worth a shot. :-) $basedir = "./blackjack/"; # $keep_cookies_time: Information about each player and their # "credits," cards, and so forth, is stored in a cookie in their browser, # but also in files on the server. (This is because it's easy to get # around anything in a browser, but not so easy to get around something # on the server.) $keep_cookies_time is how long, in seconds, you want # to keep these files lying around if the person isn't playing. Note # that if a person closes their browser, they'll probably lose the cookie # and have to create new files anyway. The default timeout is 15 minutes, # meaning that if someone doesn't play for 15 minutes, their session will # time out and they'll start over. If you do not want to ever delete these # files, set $keep_cookies_time = "forever"; (This is not advisable because # eventually this could take up all your disk space.) One hour is # 3600. 24 hours is 86400. One week is 604800. One month is 2592000. $keep_cookies_time = 900; # $cgi_url is the web address of where you've set up this script. # You'll need to change this to the URL of where you've set it up on # your site. If you get a "File not found" error, it usually means # that this isn't set up correctly. **CHANGE** this to the web # address of this script on your web server. $cgi_url = "http://yourdomain.com/sfeblackjack.cgi"; # $image_url is the web address of where you've put the gif images # that came with this program. These images are needed in order to draw the # cards. If the corners of the cards look strange, or show broken images, # it probably means that this setting is not correct. **CHANGE** this # to the URL of where you've put the gif image files that came with this # program. This MUST begin with "http://" and it MUST end with a "/" as # in the example below. $image_url = "http://www.yourdomain.com/images/"; # As you'll notice from the demo, there's a title across the top # of the game page that shows a link. # $game_title_text is the text of that link, or, in other words, # the part of the link you see. # $game_title_url is the site you want this to link to. You can have # it say "Back to My Site" and have the link go to http://yoursite.com, # or **CHANGE** it to whatever you like. # IMPORTANT: DO NOT USE any " or @ signs or the script will break. # ONLY change in between the "" that are already there. $game_title_text = "SFE Presents: Online Video Blackjack"; $game_link_url = "http://tesol.net/scripts/SFEBlackJack"; # $page_title_text is just the text for the title of the pages # generated by the program. # IMPORTANT: DO NOT USE any " or @ signs or the script will break. # ONLY change in between the "" that are already there. $page_title_text = "Welcome to Online Video BlackJack"; # Now, the rest of this is just to make it easier to change the titles # and words that are shown for various things. If you want to translate # this game into another language, just translate the words below. # IMPORTANT: DO NOT USE any " or @ signs or the script will break. # ONLY change in between the "" that are already there. $new_game_text = "New Game."; $betting_text = "Betting 5."; $push_text = "PUSH!"; $bust_text = "BUST!"; $player_wins_text = "Player wins!"; $dealer_wins_text = "Dealer wins!"; $dealer_text = "Dealer"; $player_text = "Player"; $new_game_text = "New Game"; $hit_text = "Hit"; $stand_text = "Stand"; $surrender_text = "Surrender"; $show_dealer_card_text = "Show Dealer Card"; $double_down_text = "Double Down"; $dealers_cards_text = "Dealer's Cards"; $your_cards_text = "Your Cards"; $your_score_text = "Your score: "; $hit_again_text = "Hit again? "; $rules_text = "Rules"; $rules_left_column_text = " Blackjack pays 2.5 to 1
Surrender pays back 1/2 of bet amount
Dealer blackjack vs. Player blackjack is a Push
Dealer must hit on 16 or less.
Dealer must stand on 17 or above (soft 17 included).
You may double down on 10 or 11.
Double down deals only one card. "; $rules_right_column_text =" You will begin with 100 credits, and may play as long as you still have credits. When you run out, you will be given 100 credits again to play some more! "; $entertainment_only_text = " This game is for ENTERTAINMENT ONLY.
Credits are NOT-NEGOTIABLE.
No actual money or currency of any kind is involved in this game. "; ######################################################################### ##### # ##### END SECTION WHERE YOU WILL NEED TO CHANGE THINGS: # ##### # ##### You should not need to change anything beyond this point. In # ##### fact, anything you change beyond this point may completely # ##### break the program and cause it not to function. However, feel # ##### free to browse through the code if you like that sort of thing. # ##### :-) # ##### # ######################################################################### my %data = &get_data(); # If $basedir doesn't exist, or we can't create files there, then the script # won't run. So, we'll run a check or two to make sure we can, and if not, # we'll print an informative error message. &no_basedir_error(); # First, let's clear out old cookie files. Otherwise, they build up # until there are millions of them. if($keep_cookies_time && $keep_cookies_time !~ /^forever$/ && $keep_cookies_time =~ /^\d+$/){ opendir(DIR, "$basedir"); @cookiefiles = readdir(DIR); closedir(DIR); foreach $ckf (@cookiefiles){ if(-f "$basedir/$ckf" && $ckf =~ /^\d\d\d\d\d\d\d\d\d/){ if(time - (stat("$basedir/$ckf"))[9] > $keep_cookies_time){ unlink("$basedir/$ckf"); } } } } # We keep track of the user's cards and money and so forth by setting # a cookie which we use to find the file where we saved their stuff # on the server. $cookie = $ENV{'HTTP_COOKIE'}; # I was kind of sloppy in setting the cookie when I was writing this and I # set two different cookies, which ruined my whole day. This is just for # those beta testers who were using it. $cookie =~ s/Student=;//; if($ENV{'SERVER_NAME'} =~ /linguistic-funland.com$/i || $ENV{'SERVER_NAME'} =~ /tesol.net$/i){ $entertainment_only_text .= "
**DEMO VERSION** All credits will be reset to zero periodically in this demo.
"; } ($stuff,$cookie) = split(/=/, $cookie); if($cookie !~ /^\d+/){ $cookieyear = (CORE::localtime(time))[5] + 1900 + 25; $cookie = time . $$ . $ENV{'REMOTE_ADDR'}; print "Content-type: text/html\n"; print "Set-Cookie: RCV=$cookie; expires=Fri, 26-Dec-$cookieyear 15:45:40 GMT;\n\n"; } else { print "Content-type: text/html\n\n"; } $cookie =~ s/;//; $screenfile = "$basedir/$cookie.screentracker"; $moneyfile = "$basedir/$cookie"; $dealercardfile = "$basedir/$cookie.dealercard"; $playercardfile = "$basedir/$cookie.playercard"; $cardfile = "$basedir/$cookie.cards"; # If the money file based on their cookie doesn't exist, then we'll # create it and give them 100 to start off with. unless(-f $moneyfile){ open(F, ">$moneyfile"); print F "100"; close(F); } # This is just a shortcut so I didn't have to keep typing it. :-) $bg = " bgcolor=\"#FFFFFF\""; $pagetop = "$page_title_text
$game_title_text
"; $pagebottom = <
$rules_left_column_text
$rules_text
$entertainment_only_text
$rules_right_column_text
Powered by SFEBlackJack Online Blackjack program
 
EOF $topmsg = <
%MSG%
Credits: %CREDITS%
EOF $dealertable = < EOF $playertable = < EOF # ♠ ♠ # ♣ ♣ # ♥ ♥ # ♯ ♦ # This is a basic deck of cards, all in order from 2 - A, clubs through # spades. @init_suits = ('C','H','D','S'); @init_nums = (2,3,4,5,6,7,8,9,10,'J','Q','K','A'); foreach $suit (@init_suits){ foreach $num (@init_nums){ $init_cards[$i] = "$num.$suit"; $i++; } } # @init_cards should have all the cards in it now. # This shuffles the deck srand; while (@init_cards){ push(@new, splice(@init_cards, rand @init_cards, 1)); } # @new now has the shuffled cards, so we stick it back into the array # @init_cards. @init_cards = @new; open(F, "<$screenfile"); $last_screen = ; close(F); if($last_screen eq "$stand_text"){ open(F, ">$screenfile"); print F "Deal"; close(F); &deal(); exit(); } if($data{'FA'} eq "$stand_text" || $data{'FA'} eq "$show_dealer_card_text"){ # The show_dealer_card_text is only used if they have doubled down. # Therefore, we need to double their winnings if they win. This is # one place you can cheat the game to win double every time if you # want to. :-) if($data{'FA'} eq $show_dealer_card_text){ $double = 2; } else { $double = 1; } open(F, ">$screenfile"); print F "$stand_text"; close(F); &stand(); } if($data{'FA'} eq "$hit_text"){ &hit(); } if($data{'FA'} eq "$surrender_text"){ &surrender(); } if($data{'FA'} eq "$double_down_text"){ &double_down(); } else { &deal(); } exit(); sub deal { open(F, "<$moneyfile"); chomp($money = ); close(F); if($money <= 0){ $money = 100; open(F, ">$moneyfile"); print F $money; close(F); } $new_game_text =~ s/%WINNINGS%/$money/s; $money -= 5; $credits = $money; open(M, ">$moneyfile"); print M $money; close(M); if($data{'gameid'}){ $gameid = $data{'gameid'}; } else { $gameid = time.$$; } # Dealer cards $card = shift(@init_cards); ($face,$suit) = split(/\./, $card); $dcards[0] = $card; $dcard = draw_card($card,"back"); open(D, ">$dealercardfile"); print D "$card\n"; close(D); $card = shift(@init_cards); ($face,$suit) = split(/\./, $card); if($card =~ /H|D/){$fontcolor = "#FF0000"; } if($card =~ /C|S/){$fontcolor = "#000000"; } $dcards[1] = $card; open(D, ">>$dealercardfile"); print D "$card\n"; close(D); $dcard2 = &draw_card($card); foreach $c (@dcards){ if($c =~ /^K/ || $c =~ /^Q/ || $c =~ /^J/ || $c =~ /^10/){ $dgotten = 1; } if($c =~ /^A/){ $dgotace = 1; } } if($dgotten && $dgotace){ $msg = "$new_game_text $betting_text Dealer Blackjack!"; $dcard = draw_card($dcards[0]); } else { $msg = "$new_game_text $betting_text"; } # Your cards open(P, ">$playercardfile"); print P ""; close(P); foreach $num (1,2){ $i = $num - 1; $card = shift(@init_cards); ($face,$suit) = split(/\./, $card); if($card =~ /H|D/){$fontcolor = "#FF0000"; } if($card =~ /C|S/){$fontcolor = "#000000"; } open(P, ">>$playercardfile"); print P "$card\n"; close(P); $pcard = &draw_card($card); $jscard = $card; $d1score = score($card); if($d1score == 11){ $p_ace++; } $p_score += $d1score; $jscard =~ s/\./_/g; $cardrow .= "\n"; $pcards[$num] = $card; } if($p_score == 10 || $p_score == 11){ $double_down_button = 1; } foreach $c (@pcards){ if($c =~ /^K/ || $c =~ /^Q/ || $c =~ /^J/ || $c =~ /^10/){ $gotten = 1; } if($c =~ /^A/){ $gotace = 1; } } &save_deck(@init_cards); if($gotten && $gotace){ $msg .= " !!Player Blackjack!!"; } if($msg =~ /Player Blackjack/ && $msg =~ /Dealer Blackjack/){ $winnings = 5 * 1; } elsif($msg =~ /Player Blackjack/){ $winnings = 5 * 2.5; } elsif($msg =~ /Dealer Blackjack/){ $winnings = 0; } $credits += $winnings; open(M, ">$moneyfile"); print M $credits; close(M); $topmsg =~ s/%MSG%/$msg/s; $topmsg =~ s/%CREDITS%/$credits/s; print $pagetop; print $topmsg; $dealertable =~ s/%DEALERROW%/
$dealers_cards_text
%DEALERROW%
$your_cards_text
%PLAYERROW%
$pcard$dcard<\/td>$dcard2<\/td>/s; print $dealertable; $playertable =~ s/%PLAYERROW%/$cardrow/s; print $playertable; if($double_down_button == 1){ $ddb = ""; } if($msg =~ /blackjack/is){ print "
$pagebottom"; } else { print "
$ddb
$pagebottom"; } exit(); } sub surrender { open(M, "<$moneyfile"); chomp($money = ); close(M); $money += 2.5; open(M, ">$moneyfile"); print M $money; close(M); $credits = $money; &deal; } sub double_down { # bet another 5 $double_down = 1; open(M, "<$moneyfile"); chomp($money = ); close(M); $money -= 5; open(M, ">$moneyfile"); print M $money; close(M); $credits = $money; &hit; } sub hit { # Get dealer cards and print them # Deal dealer another card and print it # Tally up dealer score. If dealer under 17, deal again. # If over 21, dealer busts. # Get player cards open(F, "<$cardfile"); @init_cards = split(/ /, ); close(F); open(D, "<$dealercardfile"); while(){ chomp; $card = $_; if(!$dealerrow){ $dealerrow = "" . draw_card($card, "back") . ""; } else { $dealerrow .= "" . draw_card($card) . ""; } } close(D); open(P, "<$playercardfile"); while(

){ chomp; $card = $_; if($card ne ""){ $pcard .= "" . draw_card($card) . ""; $score = score($card); if($score == 11){ $p_ace++; } $tscore += $score; } } close(P); $new_player_card = shift(@init_cards); $cards = "$pcard" . draw_card($new_player_card) . ""; &save_deck(@init_cards); #print "Player draws $new_player_card.
"; $score = score($new_player_card); if($score == 11){ $p_ace++; } $tscore += $score; #print "$tscore
"; if($tscore > 21 && $p_ace >= 1){ $tscore -= (10 * $p_ace); } # print "$tscore
"; if($tscore > 21){ $busted = 1; $msg = "$bust_text $tscore"; } else { open(P, ">>$playercardfile"); print P "$new_player_card\n"; close(P); $okay = 1; if($double_down == 1){ $msg = "$your_score_text $tscore."; } elsif($tscore == 21){ $msg = "$your_score_text $tscore."; $hit_again = 0; } else { $msg = "$your_score_text $tscore. $hit_again_text"; $hit_again = 1; } } open(M, "<$moneyfile"); chomp($money = ); close(M); $credits = $money; print "$pagetop"; $topmsg =~ s/%MSG%/$msg/s; $topmsg =~ s/%CREDITS%/$credits/s; print "$topmsg"; $dealertable =~ s/%DEALERROW%/$dealerrow/s; print "$dealertable"; $playertable =~ s/%PLAYERROW%/$cards/s; print "$playertable"; if($busted == 1){ print "

$pagebottom"; } elsif($double_down == 1){ print "
$pagebottom"; } elsif($hit_again == 0){ print "
$pagebottom"; } else { print "
$pagebottom"; } exit(); } sub stand { # Get dealer cards and print them # Deal dealer another card and print it # Tally up dealer score. If dealer under 17, deal again. # If over 21, dealer busts. # Get player cards open(F, "<$cardfile"); @init_cards = split(/ /, ); close(F); open(D, "<$dealercardfile"); while(){ chomp; $card = $_; if($card ne ""){ $dealerrow .= "" . draw_card($card) . ""; # print "Dealer has $_
"; $score = score($_); if($score == 11){ $d_ace = 1; } $tscore += $score; } } close(D); open(P, "<$playercardfile"); while(

){ chomp; $card = $_; if($card ne ""){ $playerrow .= "" . draw_card($card) . ""; $score = score($_); if($score == 11){ $p_ace++; } $pscore += $score; } } close(P); # Get the actual score, accounting for aces. if($pscore > 21 && $p_ace > 0){ for ($i = 0; $i < $p_ace; $i++){ $pscore -= 10; if($pscore <= 21){ last; } } } if($tscore > 21 && $d_ace == 1){ $tscore -= 10; } if($tscore > 16){ #KPH $msg = "$dealer_text: $tscore"; } else { $new_dealer_card = shift(@init_cards); # print "Dealer draws $new_dealer_card.
"; $dealerrow .= "" . draw_card($new_dealer_card) . ""; $score = score($new_dealer_card); #print "score $score
"; if($score == 11){ $d_ace = 1; } #print "score $score
"; $tscore += $score; #print "score $tscore
"; if($tscore > 21 && $d_ace == 1){ $tscore -= 10; } #print "score $tscore
"; if($tscore > 21){ $msg = "$dealer_text: $bust_text $tscore"; $tscore = 0; } elsif($tscore > 16){ $msg = "$dealer_text: $tscore"; } else { $new_dealer_card = shift(@init_cards); #print "Dealer draws $new_dealer_card.
"; $dealerrow .= "" . draw_card($new_dealer_card) . ""; $d_ace = 0; $score = score($new_dealer_card); if($score == 11){ $d_ace = 1; } $tscore += $score; if($tscore > 21 && $d_ace == 1){ $tscore -= 10; } if($tscore > 21){ $msg = "$dealer_text: $bust_text $tscore"; $tscore = 0; } elsif($tscore > 16){ $msg = "$dealer_text: $tscore"; } else { $new_dealer_card = shift(@init_cards); # print "Dealer draws $new_dealer_card.
"; $dealerrow .= "" . draw_card($new_dealer_card) . ""; $d_ace = 0; $score = score($new_dealer_card); if($score == 11){ $d_ace = 1; } $tscore += $score; if($tscore > 21 && $d_ace == 1){ $tscore -= 10; } if($tscore > 21){ $msg = "$dealer_text: $bust_text! $tscore"; $tscore = 0; } elsif($tscore > 16){ $msg = "$dealer_text: $tscore"; } } } } open(M, "<$moneyfile"); chomp($money = ); close(M); $credits = $money; print $pagetop; $msg .= " $player_text: $pscore "; if($tscore > 21){ $tscore = 0; } if($pscore > 21){ $pscore = 0; } if($tscore > $pscore){ $win = "$dealer_wins_text";} if($pscore > $tscore){ $win = "$player_wins_text"; $winnings = ($double * 10); } if($pscore == $tscore){ $win = "$push_text"; $winnings = ($double * 5);} $credits += $winnings; open(M, ">$moneyfile"); print M $credits; close(M); $topmsg =~ s/%MSG%/$msg $win/s; $topmsg =~ s/%CREDITS%/$credits/s; print $topmsg; $dealertable =~ s/%DEALERROW%/$dealerrow/s; print $dealertable; $playertable =~ s/%PLAYERROW%/$playerrow/s; print $playertable; print "

$pagebottom"; exit(); } sub get_data { use CGI; use CGI::Carp qw/fatalsToBrowser/; $CGI::POST_MAX=4096; $CGI::DISABLE_UPLOADS=1; my $q = new CGI; my ($par, %data); @held = $q->param('hold'); foreach $par ($q->param()){ if($data{$par}){ $data{$par} .= "\0" . $q->param($par); } else { $data{$par} = $q->param($par); } } return %data; } sub draw_card { my($pcard) = $_[0]; my($num,$suit) = split(/\./, $pcard); if($suit =~ /H|D/){$fontcolor = "#FF0000"; } if($suit =~ /C|S/){$fontcolor = "#000000"; } $suit =~ s/S/♠/; $suit =~ s/C/♣/; $suit =~ s/H/♥/; $suit =~ s/D/♦/; my($back) = $_[1]; $pcard =~ s/S/♠/; $pcard =~ s/C/♣/; $pcard =~ s/H/♥/; $pcard =~ s/D/♦/; if($back){ $ur = "${image_url}upperrightb.gif"; $lr = "${image_url}lowerrightb.gif"; $ul = "${image_url}upperleftb.gif"; $ll = "${image_url}lowerleftb.gif"; $bg = " bgcolor=\"#000000\""; $mid = " ‡‡‡
‡‡‡
"; } else { $ur = "${image_url}upperright.gif"; $lr = "${image_url}lowerright.gif"; $ul = "${image_url}upperleft.gif"; $ll = "${image_url}lowerleft.gif"; $bg = " bgcolor=\"#FFFFFF\""; $mid = "$pcard
$suit "; } $pcard = " $mid
"; return $pcard; } sub score { my ($card) = $_[0]; my ($score); my ($c,$s) = split(/\./, $card); if($c eq "K" || $c eq "Q" || $c eq "J"){ $score = 10; } elsif($c eq "A"){ $score = 11; } else { $score = $c; } return $score; } sub save_deck { my(@init_cards) = @_; my ($deck); # save the rest of the deck for drawing while(@init_cards){ $deck .= shift(@init_cards) . " "; } open(F, ">$cardfile"); print F $deck; close(F); } sub no_basedir_error { unless(-d "$basedir"){ $err = "Your base directory \$basedir does not appear to be a directory, or does not exist. You have set:

\$basedir = \"$basedir\";

in the script, but it doesn't appear to be correct."; if($basedir =~ /^http:/){ $err .= "\$basedir cannot begin with \"http://\". You may need to ask your web hosting provider, \"What is the full system path to files on my website?\".

"; } } else { open(F, ">$basedir/sfe_blackjack_testfile.$$"); print F ""; close(F); unless(-e "$basedir/sfe_blackjack_testfile.$$"){ $err .= "I cannot create files in your base directory \$basedir ($basedir). When I tried to create a file there, the server said \"$!\". \$basedir should be chmod 777 (on Unix/Linux-type systems) or otherwise set up so that the server can create files in that directory. Sometimes, you cannot chmod something to 777 if it is in your cgi-bin. If this is the case, try creating this directory outside your cgi-bin, change the path to \$basedir in the script, and try again.

"; } else { unlink("$basedir/sfe_blackjack_testfile.$$"); } close(F); } if($err){ $err .= "The following information may help you find the correct path. If not, please feel free to email me this information and tell me what was going wrong, and I'll try to help.

"; if($ENV{'PATH_TRANSLATED'}){ $err .= "Path Translated: $ENV{'PATH_TRANSLATED'}
"; } if($ENV{'DOCUMENT_ROOT'}){ $err .= "Document Root: $ENV{'DOCUMENT_ROOT'}
"; } if($ENV{'SCRIPT_FILENAME'}){ $err .= "Script Filename: $ENV{'SCRIPT_FILENAME'}
"; } if($ENV{'SERVER_SOFTWARE'}){ $err .= "Server Software: $ENV{'SERVER_SOFTWARE'}
"; } print "Content-type: text/html\n\n"; print "Ooooops! CONFIGURATION ERROR!

$err"; exit(); } }