#### LISTING ONE #### #!/usr/bin/perl -Tw use strict; $|++; BEGIN { $SIG{__DIE__} = sub { my $incident = unpack "H*", pack "NS", time, $$; my $message = shift; ## record reason for death into the error log warn join "", map "crash $incident: $_\n", split /\n+/, $message; ## now give the user a place to record their experience print <

An error has occurred

An error has occurred. Relevant details have already been logged for us, but if you want to tell us what you were doing at the time, it might help us determine the cause more accurately to fix the problem more easily.

Email address (optional):
Comments:

Or, you can contact us at 1-800-555-5555 and reference incident number $incident.


END_OF_HTML exit 0; }; } use CGI qw(:all); print start_header, start_html("Buggy Program"); / bad syntax print end_html; #### LISTING TWO #### #!/usr/bin/perl -Tw use strict; $|++; use CGI qw(:all); print header, start_html("Incident Reporter"), h1("Thank you!"), p("Thank you for your incident report.", "The appropriate authorities have been notified.", "Remain calm."), end_html; ## save the parameters and environment open ERRLOG, ">>/tmp/crash-reporter.log"; param("\$ENV{$_}", $ENV{$_}) for keys %ENV; $CGI::Q->save(\*ERRLOG); #### LISTING THREE #### #!/usr/bin/perl -w use CGI qw(param); my $FILE = "/tmp/crash-reporter.log"; my @all; open FILE, $FILE or die; until (eof FILE) { $CGI::Q = CGI->new(\*FILE); my %p; for (param) { my @p = param($_); $p{$_} = @p < 2 ? $p[0] : \@p; } push @all, \%p; } use Data::Dumper; print Dumper \@all;