Mod Perl Icon Mod Perl Icon Code Snippets


[ Prev | Main Page | Next ]

Table of Contents:


The Writing Apache Modules with Perl and C book can be purchased online from O'Reilly and Amazon.com.
Your corrections of either technical or grammatical errors are very welcome. You are encouraged to help me to improve this guide. If you have something to contribute please send it directly to me.

[TOC]


More on relative paths

Many people use relative paths for require, use, etc., or open files in the current directory or relative to the current directory. But this will fail if you don't chdir() into the correct directory first (e.g when you call the script by its full path). This code would work:

  /home/httpd/perl/test.pl:
  -------------------------
  #!/usr/bin/perl
  open IN, "./foo.txt";
  -------------------------

if we call the script by:

  % chdir /home/httpd/perl
  % ./test.pl

since foo.txt is located at the same directory the script is being called from. if we call the script by:

  % /home/httpd/perl/test.pl

when we aren't chdir to the /home/httpd/perl, the script will fail to find foo.txt. If you don't want to use hardcoded directories in your scripts, FindBin.pm package will come to rescue.

  use FindBin qw($Bin);
  use lib $Bin;
  open IN, "./foo.txt";

or

  use FindBin qw($Bin);
  open IN, "$Bin/foo.txt";

Now $Bin includes the path of the directory the script resides in, so you can move the script from one directory to the other and call it from anywhere else. The paths will be always correct.

It's different from using "./foo", for you first have to chdir to the directory in which the script is located. (Think about crontabs!!!)

[TOC]


Watching the error_log file without telneting to the server

I wrote this script a long time ago, when I had to debug my CGI scripts but didn't have the access to the error_log file. I asked the admin to install this script and have used it happily since then.

If your scripts are running on these 'Get-free-site' servers, and you cannot debug your script because you can't telnet to the server or can't see the error_log, you can ask your sysadmin to install this script.

Ok, here is the code:

  #!/usr/bin/perl -Tw
  
  use strict;
  $|=1;
  
  my $default   = 10;
  my $error_log = "/usr/local/apache/var/logs/error_log.1";
  use CGI;
  
  # untaint $ENV{PATH}
  $ENV{'PATH'} = '/bin:/usr/bin';
  delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
    
  my $q = new CGI;
  
  my $counts = (defined $q->param('count') and $q->param('count'))
    ? $q->param('count') : $default;
  
  print $q->header,
        $q->start_html(-bgcolor => "white",
                     -title   => "Error logs"),
        $q->start_form,
        $q->center(
                 $q->b('How many lines to fetch? '),
                 $q->textfield('count',10,3,3),
                 $q->submit('', 'Fetch'),
                 $q->reset,
                ),
        $q->end_form,
        $q->hr;
  
  print($q->b("$error_log doesn't exist!!!")),exit unless -e $error_log;
  
  open LOG, "tail -$counts $error_log|" or die "Can't open tail on $error_log :$!\n";
  my @logs = <LOG>;
  print $q->b('Note: Latest logs on the top'),$q->br;
  
  print "<UL>\n";
  
    # format and colorize each line nicely
  foreach (reverse @logs) {
      s{
       \[(.*?)\]\s* # date
       \[(.*?)\]\s* # type of error 
       \[(.*?)\]\s* # client
       (.*)         # the message
      }
      {
        "[$1] <BR> [".
        colorize($2,$2).
        "] <BR> [$3] <PRE>".
        colorize($2,$4).
        "</PRE>"
      }ex;
    print "<BR><LI>$_<BR>"; 
  }
  
  print "</UL>\n";
  
  close LOG;
  
  #############
  sub colorize{
    my ($type,$context) = @_;
  
    my %colors = 
      (
       error  => 'red',
       crit   => 'black',
       notice => 'green',
       warn   => 'brown',
      );
  
    return exists $colors{$type}
        ? qq{<B><FONT COLOR="$colors{$type}">$context</FONT></B>}
        : $context;
  }

[TOC]


Accessing variables from the caller's package

Sometimes you want to access variables from the caller's package. One way is to do:

  my $caller = caller;
  print qq[$caller --- ${"${caller}::var"}];

[TOC]


Handling cookies

Unless you use some well known module like CGI.pm you can handle the cookies yourself.

Cookies come in the $ENV{HTTP_COOKIE} variable. You can print the raw cookie string as $ENV{HTTP_COOKIE}.

Here is a fairly well-known bit of code to take cookie values and put them into a hash:

  sub getCookies {
      # cookies are seperated by a semicolon and a space, this will
      # split them and return a hash of cookies
    local(@rawCookies) = split (/; /,$ENV{'HTTP_COOKIE'});
    local(%cookies);
  
    foreach(@rawCookies){
      ($key, $val) = split (/=/,$_);
      $cookies{$key} = $val;
    }
  
    return %cookies;
  }

[TOC]


The Writing Apache Modules with Perl and C book can be purchased online from O'Reilly and Amazon.com.
Your corrections of either technical or grammatical errors are very welcome. You are encouraged to help me to improve this guide. If you have something to contribute please send it directly to me.
[ Prev | Main Page | Next ]

Written by Stas Bekman.
Last Modified at 09/25/1999
Mod Perl Icon Use of the Camel for Perl is
a trademark of O'Reilly & Associates,
and is used by permission.