Thu Oct 28 19:00:00 EST 1999      Answers are in blue.

CSCI A348/A548

Mastering the World-Wide Web

Fall99 - Midterm Examination


Max number of points: 114 Time allotted: 75'
Write your name or username here: ___________________________________
Work as fast as you can, without being careless. Good luck and do well! The exam is open-book.

1. (10 points) Write a Perl program that opens a text file and prints the contents of the file to the standard output such that all vowels (uppercase or lowercase) are surrounded by parentheses. Here's an example assuming the program is called one and that it always opens the file called file, whose contents is also shown below.

school.cs.indiana.edu%cat file
If a packet hits a pocket on a socket on a port,
and the bus is interrupted and the interrupt's not caught,
then the socket packet pocket has an error to report. 
      -- Programmer's traditional nursery rhyme. 
school.cs.indiana.edu%./one
(I)f (a) p(a)ck(e)t h(i)ts (a) p(o)ck(e)t (o)n (a) s(o)ck(e)t (o)n (a) p(o)rt,
(a)nd th(e) b(u)s (i)s (i)nt(e)rr(u)pt(e)d (a)nd th(e) (i)nt(e)rr(u)pt's n(o)t c(a)(u)ght,
th(e)n th(e) s(o)ck(e)t p(a)ck(e)t p(o)ck(e)t h(a)s (a)n (e)rr(o)r t(o) r(e)p(o)rt. 
      -- Pr(o)gr(a)mm(e)r's tr(a)d(i)t(i)(o)n(a)l n(u)rs(e)ry rhym(e). 
school.cs.indiana.edu%
Here's a solution:
#!/usr/bin/perl
open (AB, "file");
while ($x = <AB>) {
  $x =~ s/([aeiou])/($1)/ig;
  print $x; 
} 
close(AB);
2. (10 points) Write a Perl program that accepts two command-line arguments, a string and a filename, opens the file specified by the filename and lists all the lines in the file that contain the string. When the lines are printed the occurrences of the string in the line should be surrounded by parentheses. (This is almost a grep kind of program). Here's an example assuming the program is called two and we invoke it on the file file looking for the lines that contain the string packet:
school.cs.indiana.edu%./two packet file
If a (packet) hits a pocket on a socket on a port,
then the socket (packet) pocket has an error to report. 
school.cs.indiana.edu%
Here's a solution:
#!/usr/bin/perl
 
open (AB, $ARGV[1]);
while ($x =) {
  if ($x =~ s/($ARGV[0])/($1)/g) {
    print $x; 
  } 
} 
close(AB); 
3. (15 points) Assume you have a datafile that looks like this:
A348:dgerman:Adrian German:Franklin M005:5-2510
A346:kinzler:Steve Kinzler:LH 430B:5-3478
A202:asengupt:Jit Sengupta:LH 225B:5-3703
A592:sebroadl:Sean Broadley:Sycamore 910:5-6663
Write a CGI script that provides the following interface:
Course name (e.g., A348)

Press to search.

That is, an HTML form with a text field and a submit button labeled 'Proceed'. When 'Proceed' is pressed the script returns the line (or lines) that match the course name in the file:
Your search for A348 produced the following result:
  • A348
  • dgerman
  • Adrian German
  • Franklin M005
  • 5-2510
If more than one line matches the search string, you can separate the lists returned with <hr>'s.

Here's a solution:

#!/usr/bin/perl

use CGI; 

$q = new CGI;

print $q->header. $q->start_html;

if ($q->request_method eq 'GET') {
  print $q->startform, "Course name (e.g., A348) ", 
        $q->textfield(-name=>'key'), $q->p, "Press ", 
        $q->submit(-value=>'Proceed'), " to search."; 
} else {
    open (AB, "/u/dgerman/data/mte3"); 
    $t = $q->param('key'); 
    while ($line = ) {
	if ($line =~ /^$t:/i) {
	    &show($line); 
        } 
    } 
    close(AB); 
} 

print $q->end_html;

sub show {
  ($line) = @_;
  @a = split(/:/, $line); 
  print "<hr>" unless ($found == 0); 
  print "<ul>"; 
  foreach $a (@a) {
      print "<li> $a "; 
  } 
  print "</ul>"; 
  $found += 1; 
} 
4. (10 points) Draw a diagram of your Apache web server directory structure
 1. /u/username/httpd/                    # directory 
 2. /u/username/httpd/httpd               # file 
 3.                  /conf/               # directory
 4.                  /conf/httpd.conf     # file 
 5.                       /srm.conf       # file 
 6.                       /access_conf    # file 
 7.                  /htdocs/             # directory
 8.                  /htdocs/index.html   # file 
 9.                  /cgi-bin/            # directory 
10.                  /logs/               # directory
11.                  /logs/access_log     # file 
12.                  /logs/error_log      # file 
13.                  /logs/httpd.pid      # file 
and clearly identify on the diagram the following files (or write the absolute path for each one of them): 5. (3 points) Suppose that you still have the default (initial) setting in your httpd.conf file as:
User nobody
and a script script in your cgi-bin directory that looks like this:
-rwx------   1 username  students     192 Sep 15 01:32 script
where username is your username. Assume that the script has the following code:
#!/usr/bin/perl
print "Content-type: text/html\n\nHello world!"; 
What will happen when you call this script from a web browser? Why?

The server will not be able to start the script, which is executable only by the owner. So the browser will display an error message.
6. (7 points) Explain what the following lines of perl do:
open (AB, "datafile");
@lines = <AB>; 
foreach $line (@lines) {
  ($a, $b) = split(/:/, $line, 2); 
  open (MAIL, "| mail $a\@indiana.edu"); 
  print "$a:\n"; 
  print "This message is for you."; 
  close(MAIL); 
} 
close(AB); 
The program opens the datafile and puts its lines into a list, @lines. It then splits each one of them into two strings, at the first occurence of : (colon).So the lines must be of this form:
dobedobe:restofline...
yabadaba:undsoveiter...
and so forth. We notice though that the strings that appear before colons are used as usernames (at indiana.edu) to send a message to. And this happens forevery line in the file. Plugging in our example below there will be two messages sent, one to
dobedobe@indiana.edu
with the following contents:
dobedobe:

This message is for you.
and then another message to yabadaba@indiana.edu with a similar message.

Can you guess the structure of the file datafile?

From this we can say that datafile is a roster kind of file, with the student usernames in the first column and that the program is mailing a common message (announcement) to the students one by one.
7. (2 point) Which file contains the port number on which the server runs?
httpd.conf
8. (2 point) The CGI specifies an interface whereby a CGI script called with method POST should expect to receive the data from the server in STDIN.

9. (2 point) The CGI specifies an interface whereby a CGI script called with method GET should expect to receive the data from the server in $ENV{'QUERY_STRING'}.

10. (6 points) Assume the following program:

#!/usr/bin/perl
$x = $ARGV[0]; 
while ($x =~ s/([^a-z]+)//) {
  $i += 1; 
  print "(", $i, ".: ", $1, ")\n"; 
}
What is the program going to print when called as follows:
./program "Thu Oct 28 15:59:59 EST 1999 Dow closed 10.22 higher"
It will print a numbered list of strings of any characters but lowercase letters, one such string per line:
(1.: T)
(2.:  O) 
(3.:  28 15:59:59 EST 1999 D)
(4.:  )
(5.:  10.22)

Now remove the caret (^) and run the program again, same way. What does it output this time?

It will be the complement, the sequences of characters that have been skipped when we produced the answer above. Therefore:

(1.: hu)
(2.: ct)
(3.: ow)
(4.: closed)
(5.: higher)

11. (3 points) Explain what the following perl program (called prog) does:

#!/usr/bin/perl
print $ARGV[1] + $ARGV[0] + $#ARGV;
It adds the first two command line arguments to the number of arguments minus 1 ($#ARGV) and prints the result.

Consider the following cases:

Call Result
./prog 1 2 3 4 6
./prog 5 10 16
./prog one two 1
and write down what the output is in each of the cases.

12. (10 points) Write the code for a JavaScript program that keeps track of how many times a button is pressed in a form on a web page and prints that to the user, somewhere where the user can see it.

<SCRIPT>var w = null;
   
function debug(msg) {
  if ((w == null) || (w.closed)) { 
    w = window.open("","console","width=600,height=300,resizable");
    w.document.open("text/plain");
  }
  w.document.writeln(msg);
}</SCRIPT>

<FORM>
<INPUT TYPE="button" VALUE="Push Me"
       onClick="debug('You've pushed me:\t' + ++n + ' times.');">
</FORM>
13.1 (15 points) Write a simple calculator with JavaScript. The set up is as follows: the screen is split in two frames, one that has the add, sub, div and mul buttons, and a text field for the number (arg) that is to be added, subtracted, multiplied or used to divide the accumulator, and the other frame reports the current value of the accumulator (originally 0).

<html> 
  <frameset cols="50%,*">
    <frame src="controls.html" name="keyboard">
    <frame src="welcome.html"  name="display">
  </frameset>
</html>
is the frame set and here's the control panel:
<html>
<body bgcolor=white> 
<script> var acc = 0; 

function add(val) { acc += eval(val); } 
function mul(val) { acc *= eval(val); } 
function sub(val) { acc -= eval(val); } 
function div(val) { acc /= eval(val); } 

function show(aDoc) { 
  aDoc.clear(); 
  aDoc.open("text/html"); 
  aDoc.writeln("<html><body bgcolor=white>The accumulator is " 
              + "currently:" + acc + "</body></html>"); 
  aDoc.close();  
} </script> 

<form> Argument: <input type="text" name="arg"> <p> 
<input type="button" value="Add (+)" 
  onClick="add(this.form.arg.value); show(parent.display.document)"> 
<input type="button" value="Sub (-)" 
  onClick="sub(this.form.arg.value); show(parent.display.document)">  
<input type="button" value="Mul (*)" 
  onClick="mul(this.form.arg.value); show(parent.display.document)">
<input type="button" value="Div (/)" 
  onClick="div(this.form.arg.value); show(parent.display.document)"> 

<form></body></html>
There are of course many other ways of implementing it.

13.2 (10 points) When the user is done computing a Proceed button should generate (either in one of the frames or in a separate window) an HTML form that contains:

This means that we need to add a new button to the form and to label it Proceed. The onClick even handler for this button should call a function 'order' (see the shopping cart application) very much like this one:
function order() { 
  var orderWin = window.open(""); 
  var a = orderWin.document;
  a.clear(); 
  a.open("text/html"); 
  a.writeln("<html><body bgcolor=white>"); 
  a.writeln("<p> <form method=POST action=/cgi-bin/myscript>"); 
  a.writeln("<p> Acc: <input type=text name=acc value=" + acc + ">"); 
  a.writeln("<p> Name: <input type=text name=name>"); 
  a.writeln("<p> Comments: <p> <textarea name=comments></textarea>"); 
  a.writeln("<p> <input type=submit value=Submit>");
  a.writeln("<p> </form>"); 
  a.writeln("</body></html>"); 
  a.close();   
}

When the user pushes the submit button the information is sent to a perl script that mails the data to you and also outputs it on the screen for the user to see (and possibly print) the contents of what has been sent by e-mail. (Please provide the perl script as well).

#!/usr/bin/perl
use CGI;
$q = new CGI;
print $q->header, $q->start_html;
if ($q->request_method eq 'POST') {
  print $q->dump;
  open (MAIL, "! mail dgerman\@indiana.edu"); 
  print $q->dump;
  close(MAIL); 
} 
print $q->end_html;
14. (3 points) Let's say you want to schedule a certain command (starthttpd -r) to run every day at 5am, but on Fridays you want it to run every 4 hours, and on the 1st and the 15th of each month you want it to run every hour. How would you set your crontab file?

Here are the patterns for the dates:

0 5            *    * * /u/dgerman/bin/starthttpd -r
0 9,13,17,21,1 *    * 5 /u/dgerman/bin/starthttpd -r
0 *            1,15 * * /u/dgerman/bin/starthttpd -r 

15. (3 points) Describe how you can start, stop, and/or restart the server without the use of starthttpd. The correct answer to this question would include

16. (3 points) Consider the following JavaScript code:

function a(x, y) {  
  return x(y, y);
} 
function b(x, y) {  
  return x * y;
} 
document.write(a(b, b(2, 3))); 
What will the browser display when you load the page in it?
36