NET298 section B - Perl and Apache. HTML: See - http://www.ncsa.uiuc.edu/General/Internet/WWW/HTMLPrimerAll.html for "A Beginner's Guide to HTML" The classic online primer for html. *** PERL: We will learn to use it to do simple things on a web site. The main web page for this class resides at /var/lib/httpd/htdocs/ It is index.html. All web pages will be implemented here as links from this directory to your individual home directories. See page 17 of the (paper) class notes for the Slakware web directory structure. Page 16 for Red Hat structure. See /share/caldrweb.map for Caldera directory structure. *** PERL (and/or Apache) depends on three configuration files: # I think these files are for the web server (Apache) and # they relate to perl only when perl is doing web-related # tasks. True? access.conf httpd.conf srm.conf keep renamed backups at hand: access.conf.dist httpd.conf.dist srm.conf.dist these are in /var/lib/httpd/conf/ These files must be changed synchronously. *** # Access.conf is self documented. See it. #In access.conf: #tells us where the html files will reside. # Controls who can get stuff from this server. order allow,deny allow from all # You could say, for example: allow from all, deny from aol # or for an intranet: allow from nscc.hpux, deny from all *** # Httpd.conf specifies a number of locations and conditions # and limits. It is self documented. See it. cd /var/lib/httpd/logs cat access_log | tail -30 # will show you the last thirty accesses to the server *** # first perl script: # called "hello" print "Hello, World!/n"; # if you say hello to the command line, it won't work # if you remember that the x bit is not set, you can say: sh hello # but that won't work either, because it is not a shell script. so say: perl hello # and that works. *** # Say perl -v # to see the version installed here. *** # 2nd script: # "perl temp" # C2F temperature converter # convert temperature to and from degrees centigrade and Fahrenheit print "Enter the temperature to be converted: "; $original_temp = ; chomp ($original_temp); $fahrenheit = ( $original_temp - 32 ) * 5/9 ; $centigrade = $original_temp * 9/5 + 32; print "$original_temp degrees centigrade = "; print "$centigrade degrees Fahrenheit.\n"; print "$original_temp degrees Fahrenheit = "; print "$fahrenheit degrees centigrade.\n"; # has no shell directive at the top telling how to execute it. # inserting: #!/usr/bin/perl # will let us execute "temp" w/o saying perl first # we have to set the executable bit though, for bash to know to execute it. # If you pass a string that is not a number to this script, it will # interpret it as zero. This happens at the first minus sign. Perl # decides the value must be a number if you are doing arithmetic to it. # Variable typing is missing. This is a bug or a feature depending on # your POV. *** # 3rd script: sys0 #!/usr/bin/perl # Using system. $return_value = system("du"); print "System returned $return_value\n"; # sys.pl *** # We had to use the "rmcr" script to trim the CRs off the sys0 script. *** #!/usr/bin/perl # adding shell directive allows a direct call from command line. print ("Enter the distance in miles or km to be converted: "); $originaldist = ; # chop removes the final character (newline) # # (chop is ver 5 perl, chomp is ver 4) chop ($originaldist); # do the conversion $miles = $originaldist * 0.6214; $kilometers = $originaldist * 1.609; # display the results print ($originaldist, " kilometers = ", $miles, " miles\n"); print ($originaldist, " miles = ", $kilometers, " kilometers\n"); # distance.pl *** #!/usr/bin/perl # sys, a Perl script using system. $return_value = system("df"); print "System returned $return_value\n"; *** #!/usr/bin/perl # sys, a Perl script using system. $return_value = system("distance"); # in the shell, run "distance", and stuff the results into # variable "$return_value" print "System returned $return_value\n"; # spit it out. #sys1.pl *** #!/usr/bin/perl # sys, a Perl script using system. $return_value = system("df"); # same as above but execute a "df" (disk freespace) print "System returned $return_value\n"; # spit it out. # sys2.pl *** # Access environment variables. @key_names = keys(%ENV); print "Key names are: @key_names\n\n"; # Now, access each element from the list. foreach $key (@key_names) { print "$key=$ENV{$key}\n"; } # env.pl # an example of a script using arrays. See page 8 in Learning Perl # for an introduction to arrays *** # perl will read system variables and remember them. # env shows you system variables; perl sees these. # set shows you shell variables; perl does not look at these. *** # perl scripts are generally kept in /var/lib/httpd/cgi-bin/ *** # /var/lib/httpd/cgi-bin/counter.cgi follows. # Notice that comments can be put in between a semi-colon and a newline. #!/usr/bin/perl $file = "$ENV{'DOCUMENT_URI'}"; $file =~ s/\//_/g; substitute / in unix to NT \ but add _ as \_ open(FILE,"data/$file"); data is subfolder of cgi-bin flock (FILE, 2); queue requests fifo $count = ; flock (FILE, 8); close(FILE); $count++; open(FILE,">data/$file"); flock (FILE, 2); print FILE "$count"; flock (FILE, 8); close(FILE); print "Content-type: text/html\n\n"; # 2 carriage returns are required to print count through the browser. # One is to end the command, and the second is to supply a blank # line following. This 2nd \n is required by this "content-type" # statement (only). print "$count"; exit; *** /var/lib/httpd/cgi-bin: /var/lib/httpd/cgi-bin/data: ls -l total 18 -rw-r--r-- 1 nobody 65535 1 Mar 6 10:13 _akomiss.html -rw-r--r-- 1 nobody 65535 1 Mar 6 12:18 _bholland.html -rw-r--r-- 1 nobody 65535 2 Mar 6 12:59 _brader.html -rw-r--r-- 1 nobody root 3 Mar 6 12:06 _class.html -rw-r--r-- 1 nobody root 3 Mar 6 08:38 _count_test.html -rw-r--r-- 1 nobody 65535 2 Mar 6 12:19 _dbaum.html -rw-r--r-- 1 nobody root 3 Mar 6 12:20 _dcshoe.html -rw-r--r-- 1 nobody root 2 Dec 7 10:35 _dshoe.html -rw-r--r-- 1 nobody 65535 1 Mar 6 12:26 _eholt.html -rw-r--r-- 1 nobody root 3 Jan 27 13:51 _index.html -rw-r--r-- 1 nobody 65535 2 Mar 6 12:55 _kjensen.html -rw-r--r-- 1 nobody 65535 1 Mar 6 13:01 _rariri.html -rw-r--r-- 1 nobody 65535 1 Mar 6 13:02 _rhodesh.html -rw-r--r-- 1 nobody 65535 1 Mar 6 12:17 _rkemp.html -rw-r--r-- 1 nobody 65535 2 Mar 6 13:00 _rponce.html -rw-r--r-- 1 nobody 65535 1 Mar 6 13:00 _tiwata.html # root here indicates server root at /httpd # 65535 is the highest number for a user. That indicates ownership of # their own html file. # nobodys have no ownership ability, cuz they are just surfer lowlife :o) /var/lib/httpd/cgi-bin: ls -l|more total 69 -rw-r-xr-x 1 root root 337 Feb 10 1999 cmdline.cgi* -rwxr-xr-x 1 root root 338 Jun 2 1999 counter.cgi* drwxr-xrwx 2 root root 1024 Mar 6 13:04 data/ -rw-r--r-- 1 root root 18 Feb 10 1999 footer.htm -rwxr-xr-x 1 root root 603 Mar 22 1999 form1.cgi* -rw-r--r-- 1 root root 280 Feb 10 1999 form1.htm -rw-r-xr-x 1 root root 905 Jun 8 1999 form2.cgi* -rw-r--r-- 1 root root 644 Mar 12 1999 form2.htm -rw-r-xr-x 1 root root 577 Mar 22 1999 form3.cgi* -rw-r--r-- 1 root root 585 Feb 10 1999 form3.htm -rw-r--r-- 1 root root 242 Feb 10 1999 form4.htm -rwxr-xr-x 1 root root 350 Jun 9 1999 frm2htm.pl* -rwxr-xr-x 1 root root 823 Dec 2 13:36 frm2mail.pl* -rw-r--r-- 1 root root 115 Feb 10 1999 header.htm -rw-r-xr-x 1 root root 469 Feb 10 1999 hello1.cgi* -rw-r-xr-x 1 root root 389 Feb 10 1999 hello2.cgi* -rwxr-xr-x 1 root root 1297 Jun 8 1999 mail2gbk.pl* -rwxr-xr-x 1 root root 502 Mar 2 1999 mail2htm.pl* -rw-r--r-- 1 root root 2634 Feb 10 1999 outfile.htm -rw-r--r-- 1 root root 204 Jun 8 1999 pad.sub -rw-r--r-- 1 root root 126 Dec 8 1996 printenv --More-- /var/lib/httpd/htdocs: cat .htaccess # Options Indexes FollowSymLinks Includes AddType application/x-httpd-cgi .cgi AddType text/x-server-parsed-html .html /var/lib/httpd/htdocs: *** CGI forms # see /var/lib/httpd/cgi-bin/form1.cgi, form2.cgi, form3.cgi, form4.cgi # form1: GET uses URL encoded data ; it includes this in the url sent # back, unencrypted for all to see. # form1: #!/usr/bin/perl # CGI script using CGI.pm module. use CGI; $form = new CGI; # Extract value of order number. The name must match the # name in the Web page for this INPUT field. $orderno = $form->param('orderno'); # Print form header. print $form->header; print $form->start_html( -title=>'Customer Order Tracking', -BGCOLOR=>'yellow'); # HTML body # Heading print "
\n"; print "

The On-Line Order Number Tracking System

\n"; print "Your order number was $orderno.\n"; print "

\n"; # Paragraph print "

\n"; # End HTML form. print $form->end_html; # form1.cgi *** # form2: # POST does not show your data in the URL. Not all servers support POST. #!/usr/bin/perl # # CGI script for form2.htm. # use CGI; $form = new CGI; # Extract value of buzzwords. $web = $form->param('web'); $gui = $form->param('gui'); $oop = $form->param('oop'); $mod = $form->param('mod'); $proj = $form->param('projectname'); # Print form header. print $form->header; print $form->start_html( -title=>'Software Request', -BGCOLOR=>'yellow'); # HTML body # Heading print "

Your Software Request

\n"; print "
    \n"; if ($web eq "yes") { print "
  • Web-page interface.

    \n"; } if ($gui eq "yes") { print "

  • Graphical user interface.

    \n"; } if ($oop eq "yes") { print "

  • Stupendous Object-Oriented programming.

    \n"; } if ($mod eq "yes") { print "

  • Fully modular design.

    \n"; } print "

\n"; print "Estimated completion time for $proj: 5 March 2001."; print "

\n"; # Paragraph # End HTML form. print $form->end_html; *** form3: #!/usr/bin/perl # CGI script for form3.htm. use CGI; $form = new CGI; # Extract value of buzzwords. $favor = $form->param('pro'); $wing = $form->param('wing'); # Print form header. print $form->header; print $form->start_html( -title=>'Political Candidate', -BGCOLOR=>'yellow'); # HTML body # Heading print "

Your Candidate

\n"; if ($favor eq "") { print "Is in favor of: nothing

\n"; } else { print "Is in favor of: $favor

\n"; } print "and leans to the $wing views.

\n"; # End HTML form. print $form->end_html; # form3.cgi *** # and the form3.htm: Form #3

Political Candidate

Political candidates must all meet the following criteria:

Candidate must be:

Political views must be:

*** # form4.htm: # (there is no form4.cgi) Command-Line CGI

Online Query System

Ask the Internet Eight-Ball to answer your questions. *** Data Collection Form 601 using POST

Site Visitor Info

          First  M.I.       Last
   Name: 
Address: 
   City:  
  State:  Zip:  Phone: 
How did you hear about us? Check as many as apply:
Friend   Magazine   Newspaper   Radio
Word of mouth   Saw the dojo   Hospital reports

What belt rank have you achieved in karate?
None   White   Yellow   Orange   Green
Blue   Purple   Red   Brown   Black

    

*** # Contents of mbox, resulting from the above page, reveals that # the messages from nobody (the customer) are not checked for # completeness. # How could we check? *** #/var/lib/httpd/htdocs/kom602.htm Data Collection Form #2 using POST

Site Visitor Info

          First  M.I.        Last
   Name:  
Address:  
   City:   
  State:   Zip:  
  Phone:  
Bankcard: 
How did you hear about us? Check as many as apply:
Friend   Magazine   Newspaper   Radio
Word of mouth   Saw the dojo   Hospital reports

What belt rank have you achieved in karate?
None   White   Yellow   Orange   Green
Blue   Purple   Red   Brown   Black

    

*** # How to get the data out of mbox and into a database #!/usr/bin/perl # mail2dat.pl -- extract form data from e-mail into database # usage: mail2dat.pl infile.msg (you may use *.msg) open(MDAT, ">>visitors.dat"); # append to "visitors.dat" while(<>) # while there is data to read, do { if (/aaFormID/) # if you've found "aaFormID" { print MDAT $_; $a = ; while($a !~ /zzForm/) # stop when you get to "zzForm" { print MDAT $a; $a = ; } print MDAT $a; } } close(MDAT); *** # a summary of the stream of data: kom602.htm (form6) gathers input from the customer frm2mail.pl creates a mailx message which is sent to the mailbox of the person who is to respond mailx puts it in mbox mbox is copied to infile.msg on a daily basis (only today's mail) mail2dat.pl reads infile.msg to visitors.dat dat2phon.pl reads vistors.dat and creates a phonelist from it *** # visitor.dat will look like this: aaFormID:Kom6 Name:Eric A Holt Address:1234 Main City:Seattle State:WA Zip:98133 Phone:123-4567 Card:123456789 Hospital:Yes Belt:Orange zzForm aaFormID:Kom6 Name:Bart D. Holland Address:4925 95th ST SW #27K City:Mukilteo State:WA Zip:98275 Phone:425-514-8989 Card:111111111111 Magazine:Yes Belt:None zzForm aaFormID:Kom6 Name:DC Shoemaker Address:123 4th Ave City:Seattle State:WA Zip:98123 Phone:206.345.5678 Card:123-45-67890 Hospital:Yes Belt:None zzForm # ... etc. (This copy is abbreviated.) *** #!/usr/bin/perl # dat2phone.pl -- make phone list from data file open(DAT, "visitors.dat"); @alldat = ; close(DAT); chop(@alldat); open(PHON, ">phonelist"); $pad = " "; foreach $line (@alldat) { ($head, $tail) = split (/:/,$line); if ($head eq "aaFormID.Kom6") { $alphname = ""; $phone = ""; $addr = ""; $city = ""; $state = ""; $zip = ""; } elsif ($head eq "zzForm") { $alphname .= $phone . "\n " . $addr . "\n " . $city . ", " . $state . " " . $zip . "\n"; $rec{$alphname} = 1; } elsif ($head eq "Name") { @fullname = split (/ /,$tail); $alphname = pop(@fullname) . ", "; $alphname .= join(" ",@fullname) . $pad; $alphname = substr($alphname, 0, 35); } elsif ($head eq "Address") { $addr = $tail; } elsif ($head eq "City") { $city = $tail; } elsif ($head eq "State") { $state = $tail; } elsif ($head eq "Zip") { $zip = $tail; } elsif ($head eq "Phone") { $phone = $tail; } } @phones = sort(keys(%rec)); foreach $visitor (@phones) { print PHON $visitor; } *** # phony, a shell script to check incoming mail # by dcs, 16 Mar 2000 # initialize a variable for the "original" filesize b=0 # start an infinite do-loop while : do x="`ls -l $MAIL`" # get the directory entry a="`echo $x | awk '{print $5}'`" # get filesize # test the "new" size against the "old" size # process mail for website visitor info if [ $a -gt $b ] ; then echo "New website information is being processed..." cp $MAIL infile.msg mail2dat.pl infile.msg dat2phon.pl fi # save the "new" size as the "old" size b=$a # wait specified number of seconds for next loop sleep 300 # go back and loop again done *** 2nd half of quarter was about: file locations file permissions transferring data across the web html perl cgi-bin o perl scripts (*.pl) o cgi scripts (*.cgi) apache o web directory structure o configuration files o file and dir permissions o links (standards) *** telnet: other web: nobody same guy. ***