Netscape Acknowledged My Directory Listing Script

Netscape’s web servers have a built-in feature for directory listings. If a directory does not have an index file, the server generates an HTML page showing all the files. The problem is that you cannot customize what it shows. You cannot hide certain file types, you cannot change the icons, and you cannot control the layout. For a newspaper web site where we have CGI scripts, source files, and other things mixed in with the files readers should see, the default listing shows too much.

I needed a way to show only certain files, with appropriate icons, in a clean format. So I wrote a Perl CGI script that replaces the built-in directory listing entirely. You turn off automatic indexing in the server config and put my script in as the index handler instead.

The script has two configuration sections at the top. First, an exclude list:

@exclude = # These are not displayed
(
'.zip',
'.c',
'.cgi'
) ;

Any file ending in one of those extensions is hidden from the listing. Readers never see the CGI scripts or source code that lives alongside the published files.

Second, an icon mapping:

%icons = # These are the icons for the displayed ones
(
'gif',	'image',
'jpg',	'image',
'jpeg',	'image',
'au',	'sound',
'bin',	'binary',
'txt',	'text',
'text',	'text'
) ;

Each file extension maps to an icon name. The script generates a standard directory listing with file sizes, modification dates, and the right icon for each type. Files with extensions not in the mapping get a generic unknown icon. Directories get a folder icon.

The output looks like what Netscape would generate natively, with the <PRE> tag formatting and column alignment, but you have full control over what appears. It uses Perl’s format and write for the column layout, which gives you fixed-width output without fussing with sprintf.

I submitted this to Netscape Technical Support, and they published it as Tech Note 20021. Their note describes it as a solution for “turning off automatic indexing or showing only certain files.” It is a good feeling when the company that makes the server software points people to your script as the answer to a common question.

The script is straightforward CGI. It reads the current directory, filters files through the exclude list, looks up icons, formats the output, and prints HTML. No modules required beyond ctime.pl for formatting the modification dates. It runs on any system with Perl and a web server that supports CGI.

If you run a Netscape server and want more control over directory listings, the script is freely available. Drop it into any directory where you want custom listings, turn off the built-in indexing for that directory, and you are set.

Here is the full source code:

#!/usr/local/bin/perl
# index.cgi
# by Rajiv Pant (Betul) http://rajiv.org for Netscape Communications
# Re: Netscape Technical Note 20021
# Turning off "automatic indexing" or showing only certain files


# --- user defines begin ---

$document_root = '/extra/web' ;

@exclude = # These are not displayed
(
'.zip',
'.c',
'.cgi'
) ;

%icons = # These are the icons for the displayed ones
(
'gif',	'image',
'jpg',	'image',
'jpeg',	'image',
'au',	'sound',
'bin',	'binary',
'txt',	'text',
'text',	'text'
) ;

$icon_back     ='back' ;
$icon_menu    = 'menu' ;
$icon_unknown = 'unknown' ;

# --- user defines end ---

require "ctime.pl" ;

$this_dir = `pwd` ;
$this_dir =~ s#^$document_root(.*)$#$1/# ;

&header ;
&get_files ;
&show_files ;


sub header
{
print <<EOM;
Content-type: text/html

EOM
}


sub get_files
{
opendir (THIS_DIR, ".") ;
@files = grep (!/^\.$/, readdir (THIS_DIR)) ;
close (THIS_DIR) ;
}

sub show_files
{

$long_line =
"<IMG SRC=\"/mc-icons/blank.gif\" ALT=\"     \">" .
"  Name                   Last modified     Size  Description" ;

print <<EOM;
<TITLE>Index of $this_dir</TITLE>
<h1>Index of $this_dir</h1>
<PRE>
$long_line
<HR>
EOM

foreach $file (sort @files)
  {
  $show = 1 ;
  foreach $exclude (@exclude)
    {
    if ($file =~ /$exclude$/) { $show = 0 ; }
    }
  if ($show)
    {
    $date_last_modified = (stat ($file))[9] ;
    @date_last_modified = split (" ", &ctime ($date_last_modified)) ;
    $day = $date_last_modified [2] ;
    $day = "0" . $day if (length ($day) == 1) ;
    $month = $date_last_modified [1] ;
    ($yr) = $date_last_modified [5] =~ m/(..)$/ ;
    ($time) = $date_last_modified [3] =~ m/^(\d{1,2}:\d{1,2})/ ;
    $last_modified = "$day-$month-$yr $time" ;
    $size = -s $file ;
    ($size > 1024) ? $size = int ($size / 1024) ."K"
    : ($size != 0) && ($size = "1K") ;
    $file_name_truncated = $file ;
    $file_name_truncated =~ s/^(.{21}).*/$1+/ ;
    ($ext) = $file =~ /\.([^\.]*)$/ ;
    $ext =~ tr/A-Z/a-z/ ;
    ($icon, $alt) = (defined ($icons{$ext})) ?
    ($icons{$ext}, "IMG") : ($icon_unknown, "   ") ;
    (-d $file) && ($icon = $icon_menu) ;
    if ($file eq '..')
      {
      $file_name_truncated = 'Parent Directory' ;
      $icon = $icon_back ;
      }
    $img_src = "<IMG SRC=\"/mc-icons/$icon.gif\" ALT=\"[$alt]\" BORDER=0>  " ;
    print "<a href=\"$file\" name=\"$file\">" , $img_src ;
    write
    }
  }
print "</pre>\n" ;
}


format STDOUT =
@<<<<<<<<<<<<<<<<<<<<< </a>@<<<<<<<<<<<<<<< @>>>>
$file_name_truncated, $last_modified, $size
.

# End of program listing.  Rajiv Pant [email protected]  http://rajiv.org