#!/usr/bin/perl -w
#
#   nur    W i n d o w s  32   !!!
#
# wandelt fi.txt in index.html
# es werden nur LFN-Namen verwendet / generiert aus MSDOS-Dir-command
# verwendet DOS-Command: dir
#
#    W I C H T I G :      Vars aktualisieren !!!
#
# (C) Gerd Hoffmann
# 031227

use strict;

# Vars zu aktualisieren !
my $Modified = "2004-01-10T23:54:17+01:00";
my $Author = "Gerd Hoffmann" ;
my $Year = "2003,2004";
my $relPath = "../";       # relative Path: where CSS-File, back file is found
my $Back = "home.html";        # parent file
my $Formate = "formate.css";   # CSS-File
my $Index  = "index.html";     # File to create
my $Index2 = "ndx.html";       # other File to create
my $ThisTitle ="Index";

# uebrige Vars
my ( @Paths, $a, $b, $Line, $Len, $res, $Dir, @DirLines, $DirLine, $Count ) ;
my ( $DOS_83_Name, @FileName, $FileSize, $FileDate, $FileTime, $Answer, $Show);
my ( $FileComment, $LongFileName, $LongFileNameOrg, @FiLines, $FiLine, $Sizes );
my $Fitxt = "fi.txt";  # where to get file-infos
my $Fi = "";  # full path + name of $Fitxt

# Index-Art auswaehlen, entsprechenden Datei-Namen vergeben
print <<Auswahl;
Welchen Index-Datei-Namen vergeben ?
 default ist "index.html",
 alternativ: "ndx.html".
 Bitte "N" eingeben fuer alternativ "ndx.html".
 Sonst beliebige Taste.
Eingabe: 
Auswahl
$Answer = <STDIN> ;
if ( $Answer =~ /^[nN]/ ) {
   $Index = $Index2;
}

# Ausgabe long: FileName, Size, Date, Content
# Ausgabe short: FileName 
print <<Auswahl;

Welchen Anzeige ?
 default ist long:             FileName + Size + Date + Content
 oder "s" waehlen fuer short:  FileName + Size + Date
 oder "f" waehlen fuer File:   FileName
 Sonst <Enter>.
Auswahl
print "Eingabe: ";
$Answer = <STDIN> ;
if ( $Answer =~ /[fF]/ ) {
     $Show = 0;
} elsif ( $Answer =~ /[sS]/ ) {
     $Show = 1;
} else { 
     $Show = 2; 
}

# fi.exe suchen, fi.txt updaten
while(($a,$b) = each(%ENV))  {
   if($a =~ /PATH/) {
      @Paths = split(/;/,$b);
      foreach (@Paths) {
         if(-e "$_\\fi.exe") {
            $Fi = "$_\\fi.exe";
         }
      }
   }
}
if (! $Fi) { die "\tfi.exe nicht gefunden !   Abbruch !\n"; }
if ( -e "fi.bak" ) { unlink("fi.bak"); }
system("$Fi -u");
if ( -e "fi.bak" ) { unlink("fi.bak"); }

# Directory einlesen
$Dir = `command.com /c dir /ogne`;
@DirLines = split( /\n/, $Dir);
$Dir = "";      # Speicher freigeben

# fi.txt zeilenweise einlesen, 
open(IN, "<$Fitxt") || die "Cannot open ${Fitxt}! Abbruch !\n" ;
while(<IN>) {
   if(/^[\s\.]/) { next; };
   chomp;
   push ( @FiLines, $_ );
}
close(IN);

#foreach $_ ( @FiLines ) { print "$_\n"; }  # Test only
#   if( $DirLine =~ /^[\s\.]/ or ! defined $DirLine or $DirLine eq "" ) { next; };


open(OUT, ">$Index") || die "Cannot open ${Index}! Abbruch !\n" ;
PrintIndexFirst();
$Count = 0;
$Sizes = 0; 
# Zeilen aus DIR-Liste von DOS-Command "dir" lesen
foreach $DirLine ( @DirLines ) { 
    # Leerzeilen, Zeilen mit Spaces am Anfang, FI.TXT, index.html nicht anzeig.
   if( $DirLine =~ /^[\s\.]/ or $DirLine eq "" or $DirLine =~ /fi.txt$/i or
       $DirLine =~ /index.html$/i ) { next; };
   $FileComment = "";
   $DOS_83_Name = substr($DirLine, 0, 12); # DOS 8.3 Name extrahieren
   
   # FileComment aus fi.txt in Var. kop., KommentarSonderzeichen -> HTML
   foreach $FiLine ( @ FiLines ) {
      chomp $FiLine;
      # wenn NAme identisch und Kommentar vorhanden ...
      if( $FiLine =~ /^$DOS_83_Name(.*)/i && length $FiLine > 14 ) {
         $FileComment =  rtrim( $1 );
         $FileComment =~ s//&Auml;/g ;
         $FileComment =~ s//&auml;/g ;
         $FileComment =~ s//&Oauml;/g ;
         $FileComment =~ s//&ouml;/g ;
         $FileComment =~ s//&Uuml;/g ;
         $FileComment =~ s//&uuml;/g ;
         $FileComment =~ s//&szlig;/g ;
         last ;
      }
   }
   $LongFileName = substr($DirLine, 44) ;  # LFN extrahieren
   $LongFileNameOrg = $LongFileName ;      # LFN retten
   
   # DOS-Datei-Namen (8.3) in Kleinbuchstaben wandeln
   ( @FileName ) = split( /\./, $LongFileName );
   # wenn keine Extension vorhanden ...
   if(! defined $FileName[1] ) { $FileName[1] = ""; }
   # Wenn korrekter DOS 8.3 Name (Def. von DOS-Name) ...
   if(  ( @FileName > 0 )
        && ( scalar @FileName  < 3 ) 
        && (( length( $FileName[0] ) <= 8 ) && ( length( $FileName[0] ) > 0 ))
        && ( length( $FileName[1] ) < 4 )
        && ! ( $LongFileName =~ /[a-z]/ ) ) {
      $LongFileName = &FilterChars( $LongFileName );
      $LongFileName = lc( $LongFileName );
   } else {
      $LongFileName = &FilterChars( $LongFileName );
   }
   # Falls der DateiName veraendert wurde, Datei umbenennen
   if( $LongFileNameOrg ne $LongFileName ) {
#      printf("%-38s %s\n", 
#             "+ LFN.ORG: $LongFileNameOrg", "LFN.NEW: $LongFileName" ) ; 
      print "rename  \"$LongFileNameOrg\" $LongFileName \n";
      system( "start /w command.com /c ren \"$LongFileNameOrg\" $LongFileName" );
#      system( "command.com /c ren $LongFileNameOrg, $LongFileName" );
#      rename( $LongFileNameOrg, $LongFileName );
   } 
#   else { printf( "%-38s %s\n", 
#             "- LFN.ORG: $LongFileNameOrg", "LFN.new: $LongFileName" ); 
#   }

   $FileSize = substr($DirLine, 13, 13) ;
   if( !( $FileSize =~ /DIR/i )) {
      $a = $FileSize = ltrim( $FileSize );
      $a =~ s/\.//g ;
      $Sizes += $a ;              # Sum of all File-Sizes
   } 
   else {
      $FileSize = "&lt;DIR&gt;";
   }
   $FileDate = substr($DirLine, 28, 8) ;
   $FileTime = substr($DirLine, 38, 5) ;
   $FileTime = ltrim( $FileTime );
   if( length( $FileTime ) < 5 ) { $FileTime = "0$FileTime" ; }
   # bei Subdir: "/index.html" ergaenzen !
   if( $FileSize =~ /DIR/ ) { $DOS_83_Name .= "/index.html"; }
   
   PrintIndexRow();
   ++$Count;   
}

PrintIndexLast() ;

######   end main

################################
# PrintIndexFirst()
#
sub PrintIndexFirst {

print OUT <<IndexFirst;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="GENERATOR" content="fi2ndx.prl">
<meta name="Author" content="$Author">
<meta name="date" content="$Modified">
<meta name="robots" content="noindex">
<meta name="keywords" lang="en" content="Index">
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<meta http-equiv="Content-Style-Type" content="text/css">
  <!-- ... Link !  ... -->
<link rel="stylesheet" media="all" href="$relPath$Formate">
<title>$ThisTitle</title>
</head>
<body>

<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td><h2>Index&nbsp;</h2></td>
</tr>
</table>

<table width="100%" cellpadding="4" cellspacing="0" border="0">
   <tr>
      <th align="left">File-Name</th>
IndexFirst
# Ende HERE-Dokument
   if ( $Show ) {
      print OUT<<next
      <th align="right">Size&nbsp;/&nbsp;Dir&nbsp;&nbsp;&nbsp;</th>
      <th align="left">&nbsp;&nbsp;&nbsp;&nbsp;Date</th>
next
# Ende HERE-Dokument
   }
   if ( $Show == 2 ) {
      print OUT<<next
      <th align="left">Content</th><br>
next
# Ende HERE-Dokument
   }
   print OUT "   </tr>";
}

################################
# FilterChars()
#
sub FilterChars {
   my $str = $_[0];
   my ( $key, $value );
   
   my %hChars = (
      "" => "AE",
      "" => "ae",
      "" => "OE",
      "" => "oe",
      "" => "UE",
      "" => "ue",
      "" => "ss",
      "\$" => "_",
      "~" => "_",
      "'" => "_",
      "`" => "_",
      "#" => "_",
      "&" => "_",
      "; " => "_",
      "\!" => "_",
      "\+" => "_",
      "\{" => "_",
      "\[" => "_",
      "\(" => "_",
      "\)" => "_",
      "\]" => "_",
      "\}" => "_"
   ) ;
   
   while( ( $key, $value ) = each( %hChars ) ) {
      $str =~ s/[$key]+/$value/g ;
   }
   return $str ;
}

################################
# PrintIndexRow()
#
sub PrintIndexRow {
#my $CutName = substr( $LongFileName, 0, 14 );

   print OUT <<IndexRow;
   <tr>
      <td align="left" valign="top"><a href="$LongFileName">$LongFileName</a></td>
IndexRow
# Ende HERE-Dokument
   if ( $Show ) {
   print OUT <<IndexRow;
      <td align="right" valign="top">$FileSize</td>
      <td align="left" valign="top">${FileDate}&nbsp;${FileTime}</td>
IndexRow
# Ende HERE-Dokument
   }
   if ( $Show == 2 ) {
      print OUT "     <td align=\"left\" valign=\"top\">$FileComment</td>" ;
   }
   print OUT "   </tr>";
}


################################
# PrintIndexLast()
#
sub PrintIndexLast {
print OUT <<IndexLast;
</table>
<p>
$Count Files with total size of $Sizes Bytes
</p>
<p>
<hr>
(C)opyright by $Author $Year
</p>
</body>
</html>
IndexLast
# Ende HERE-Dokument
}


################################
# ltrim()
#
sub ltrim {
   $_[0] =~ /^\s*(.*?)$/ ;
   return ( $1 );
}


################################
# rtrim()
#
sub rtrim {
   $_[0] =~ /^(.*?)\s*$/ ;
   return ( $1 );
}


################################
# rpad()
#
sub rpad {
   return ( $_[0] . " " x ( $_[1] - length( $_[0] )) );
}

__END__
   
# Kann bei FileTest DIR nicht von File unterscheiden:
# Test: -f: beidemal richtig bei DIR und bei File
# Test: -e: beidemal richtig bei DIR und bei File
# Test: -d: beidemal falsch  bei DIR und bei File
# Func "rename" benennt unter Win98 auch SubDIRs um !
# Func "rename" benennt unter Win98 Dateien mit "+" im Namen nicht um

#   ==============
#   = !  ToDo  ! =
#   ==============
#
#   =  ndx.html:
# alle auch die in index.html nicht aufgefuehrten Dateien/SubDIRs auffuehren:
# only: Name, Size, Time
# 
#   =  Title:
# aktuelles DIR ohne Pfad
#   if ( $Path =~ m#/$#) {
#      chop($Path);
#   };
#   $Path =~ m#/(.*?)$#
# 
# 
#   =  $relPath:
# ersetzen durch cwd !!!
# 
# 

# Err in sub FilterChars bei regexpr:
  #      "^" => "_",      # err !
  #      "\^" => "_",     # err !
  # Unmatched [ before HERE mark in regex m/[ << HERE ^]+/ 
  # at fi2ndx.prl line 217, <IN> line 38.
  # ebenso bei "\\"

  
Welchen Anzeige ?
 default ist long: FileName + Size + Date + Content
 oder waehlen: (F)ileName, (S)ize, (D)ate, (C)ontent
 Sonst <Enter>..
 mehrfache Auswahl moeglich durch Angabe der Buchstaben.
 z.B.   fcs
  
 
 
