#!/usr/bin/perl
#
# Reads an old reqmap (mapping file for patched ifcico) and an old 
# noreq (list of files in pubdir, which should not inserted to reqmap)
# and generates a new reqmap.new and noreq.new and an additional 
# reqmap.add, which keeps all new files and a first try of a 8+3-conversion.
# The admin should merge reqmap.add to reqmap.new.
#
# $Id: genreqmap,v 1.3 1996/09/27 02:14:18 roland Exp $
#
# Copyright (C) 1996 Roland Rosenfeld <roland@spinnaker.rhein.de> 2:2450/42
# 
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
# 
# Some small parts of this script are stolen from FidoGate 4.0beta1
# the famous gatewaysoftware written by Martin Junius <mj@fido.de>
#
#############################################################################

$fnet      = "/usr/lib/ifmail";
$reqmap    = "$fnet/reqmap";
$noreq     = "$fnet/noreq";
$newreqmap = "$reqmap.new";
$newnoreq  = "$noreq.new";
$reqmapadd = "$reqmap.add";
$oldreqmap = "$reqmap.old";
$oldnoreq  = "$noreq.old";
$pubdir    = "/home/ftp/pub/";
$files     = "$pubdir/2450-42.lst";
$filesnew  = "$files.new";
$filesold  = "$files.old";
$fileszip  = "$pubdir/2450-42.zip";
$fileshead = "$fnet/filelist.head";
$filesbbs  = "files.bbs";
$admin     = "news";
$report    = "| /bin/mail -s 'New Fido-Requestmap and generated!' $admin";
$zip       = "/usr/bin/zip -kjq";

#############################################################################

require "ctime.pl";

#############################################################################

#
# Generating report:
#
open (REPORT, $report) || die "Can't generate $report: $!\n";
print REPORT "===============================================================";
print REPORT "\nNote the following inconsistencies:\n\n";

#
# Read old reqmap and store it into %longtoshort
#
open (REQMAP, $reqmap) || die "Can't open $reqmap: $!\n";
while (<REQMAP>) {
    chop;
    ($shortname,$longname) = split (/\s+/, $_, 2);
    $longname =~ s/$pubdir//;
    $longtoshort{$longname} .= "$shortname ";
}
close (REQMAP);

#
# Read old noreq and store it into %longtoshort as "-"
#
open (NOREQ, $noreq) || die "Can't open $noreq: $!\n";
while (<NOREQ>) {
    chop;
    s/$pubdir//;
    if (!$longtoshort{$_}) {
        $longtoshort{$_} = "-";
    } else {
        print REPORT "File defined in reqmap and noreq: $_\n";
    }
}
close (NOREQ);

open (FIND, "find $pubdir -type f -print|") || die "Can't open find to pipe\n";
open (NEWREQMAP, ">$newreqmap") || die "Can't open $newreqmap for writing\n";
open (NEWNOREQ, ">$newnoreq") || die "Can't open $newnoreq for writing\n";
open (REQMAPADD, ">$reqmapadd") || die "Can't open $reqmapadd for writing\n";
open (FILESNEW, ">$filesnew") || die "Can't open $filesnew for writing\n";

#
# Generate Filelist-Header
#
open (FILESHEAD, "$fileshead") || die "Can't open $fileshead for reading\n";
while (<FILESHEAD>) {
    print FILESNEW $_;
}
close (FILESHEAD);
print FILESNEW "\nGenerated: ";
print FILESNEW &ctime(time),"\n\n";

#
# Find out, which files really exist
# (Files in $pubdir first!)
#
while (<FIND>) {
    chop;
    if ( /\/files.bbs$/ ) {
        next;
    }
    s/$pubdir//;
    $longname = $_;
    if (!$longtoshort{$longname}) {
        print REQMAPADD &translate($longname) . "\t$longname\n";
    } else {
        if ($longtoshort{$longname} eq "-") {
            print NEWNOREQ "$longname\n";
        } else {
            foreach $oneshort (split (/ /, $longtoshort{$longname})) {
                print NEWREQMAP "$oneshort\t$longname\n";
                $shorttolong{$oneshort} .= "$longname ";
                ($x,$x,$x,$x,$x,$x,$x,$size,$x,$time,$x,$x,$x) 
                    = stat("$pubdir/$longname");
                printf(FILESNEW "%-12s %s %s ~/%s\r\n", 
                       &toupper($oneshort), &ascdate($time), &ksize($size),
                       $longname);
            }
        }
        delete $longtoshort{$longname};
    }
}

# 
# Now test the other files:
#
foreach $longname (sort keys(%longtoshort)) {
    if ( -f $longname ) {
        if ($longtoshort{$longname} =~ /^-$/) {
            print REPORT "removing $longname from noreq-Liste\n";
        } else {
            foreach $oneshort (split (/ /, $longtoshort{$longname})) {
                print NEWREQMAP "$oneshort\t$longname\n";
                $shorttolong{$oneshort} .= "$longname ";
                ($x,$x,$x,$x,$x,$x,$x,$size,$x,$time,$x,$x,$x) 
                    = stat("$longname");
                printf(FILESNEW "%-12s %s %s %s\r\n", 
                       &toupper($oneshort), &ascdate($time), &ksize($size),
                       $longname);
            }
        }
    } else {
        print REPORT "$longname no longer exists\n";
    }
}

close NEWREQMAP;
close NEWNOREQ;
close REQMAPADD;

print FILESNEW "\n\nFilelist generated by";
print FILESNEW ' $RCSfile: genreqmap,v $ $Revision: 1.3 $';
print FILESNEW "\nwritten by Roland Rosenfeld <roland\@spinnaker.rhein.de ";
print FILESNEW "2:2450/42\n\n";

close FILESNEW;

print REPORT "\n\n\n";
print REPORT "===============================================================";

print REPORT "\n\nThere may be some duplicate names in the (old) mapfile:\n\n";

foreach $short (sort keys(%shorttolong)) {
    if ($shorttolong{$short} =~ / .* /) { 
        @longlist = split (/ /, $shorttolong{$short});
        foreach $long (@longlist) {
            print REPORT "$short\t$long\n";
        }
    }
}

print REPORT "\n\n\n";
print REPORT "===============================================================";

print REPORT "\n\nGenerated $newreqmap and $newnoreq\n";
print REPORT "from $reqmap and $noreq.\n\n";

print REPORT "The following files seem to be new in your archive, please add";
print REPORT "\nthem to your reqmap.\n\n";

open (REQMAPADD, $reqmapadd) || die "Can't open $reqmapadd for reading\n";
while (<REQMAPADD>) {
    print REPORT $_;
}
close (REQMAPADD);

close REPORT;

rename ($reqmap, $oldreqmap);
rename ($newreqmap, $reqmap);
rename ($noreq, $oldnoreq);
rename ($newnoreq, $noreq);
rename ($files, $oldfiles);
rename ($filesnew, $files);

system ("$zip $fileszip $files");

exit(0);



#############################################################################

sub translate {
    local($long) = @_;
    local($name,$ext);

    $long =~ s/^.*\///;

    $long =~ s/\.tar.gz/.tgz/;
    $long =~ s/\.tar.z/.tgz/;
    $long =~ s/\.tar.Z/.taz/;
    $long =~ s/\.ps.gz/.pgz/;
    $long =~ s/\.doc.gz/.dgz/;
    
    $name = $long;
    $ext = "";
    if( $long =~ /^(.*)\.([^.]*)$/ ) {
        $name = $1;
        $ext  = $2;
    }

    $name =~ tr/A-Z/a-z/;
    $ext  =~ tr/A-Z/a-z/;
    
    $name =~ s/\.//g;
    if (length($name)>8) {
        $name =~ s/[^a-z0-9]//g;
    }
    if (length($ext)>3) {
        $ext =~ s/[^a-z0-9]//g;
    }

    $ext =~ s/^(...).*$/$1/;
    
    while ( (length($name)>8) && ($name =~ /[a-z]/) ) {
        $name =~ s/[a-z]([0-9]*)$/$1/;     # remove last character
    }
    
    $name =~ s/^(.{8}).*$/$1/;
    
    return ($ext ? "$name.$ext" : $name);
}


sub ascdate {
    local($time) = @_;

    if($time eq "") {
        return "        ";
    } else {
        local($yr, $mn, $dy, $h, $m, $s, $xx);
        ($s,$m,$h,$dy,$mn,$yr,$xx,$xx,$xx) = localtime($time);
        
        return sprintf("%02d.%02d.%02d", $dy,$mn+1,$yr, $h,$m);
    }
}


sub ksize{
    local($size) = @_;
    local($k);

    if($size eq "") {
        return "   N/A";
    }
    else {
        if($size == 0) {
            $k = 0;
        }
        elsif($size <= 1024) {
            $k = 1;
        }
        else {
            $k = $size / 1024;
        }
        return sprintf("%4dK", $k);
    }
}


sub toupper{
    local($name) = @_;
    $name =~ tr/a-z/A-Z/;
    return $name;
}


#############################################################################
#
# ToDo:
# 
# - use files.bbs to add comments to filelist
# - remove duplicates from files.bbs
# - find new files and announce them via news or mail
#
