#!/usr/bin/perl
#
# Pack and check a new distribution of yabasic
#

use IPC::Open3;
use Time::Local;

# Variables, that can be configured
$sourcedir="yabasic";
$linuxdir="yablinux";
$yabexe="yabasic";
$yabsrc="yabasic.c";
$yabdoku="yabasic.htm";

# files to copy from floppy
@fromlist=("yabasic.htm",
	   "yabasic.c",
	   "yabasic.h");

# files to copy to floppy, name of rpm-file will be pushed below
@tolist=("yabasic.tar.Z",
	 "$sourcedir/yabasic.c",
	 "$sourcedir/yabasic.h",
	 "$sourcedir/bison.c",
	 "$sourcedir/bison.h",
	 "$sourcedir/flex.c",
	 "$sourcedir/yabasic.htm",
	 "$sourcedir/yabasic.bison",
	 "$sourcedir/yabasic.flex",
);
# list of files, that need to be renamed 
%torename=("yabasic.flex"=>"flex.txt",
	   "yabasic.bison"=>"bison.txt",
	   "yabasic.tar.Z"=>"yab.tar.Z");
# list of files, that need non default options for mcopy
%tooptions=("yabasic.tar.Z"=>"-n -o -m"); # rpm-file will be added below

# content of sourcepack
@sourcepack=("COPYING",
	     "README",
	     "pack",
	     "yabasic.spec",
	     "demo.yab",
	     "animals.yab",
	     "runme",
	     "configure",
	     "configure.in",
	     "Makefile.in",
	     "flex.c",
	     "bison.c",
	     "bison.h",
	     "yabasic.bison",
	     "yabasic.c",
	     "yabasic.flex",
	     "yabasic.h",
	     "yabasic.htm");

# name of sourcepack
$spackfile="yab.tar";

# name of rpm specfile
$specfile="yabasic.spec";

# Autoflush stdout
$|=1;

$stages=$ARGV[0];
$stages="123" if !$stages;

if (index($stages,"1")>=0) {
#
# Check date of files
#
    print "\nChecking file modification times:\n";
    for $name (@fromlist) {
	$totime=(stat($name))[9];
	$fromtime=&floptime($name);
	if (!fromtime<0) {
	    print "WARNING: Can't find $name on floppy !\n";
	    next;
	}
	if ($fromtime>$totime+120) {
	    $diff=$fromtime-$totime;
	    $difft=$diff." sec";
	    $difft=sprintf("%.2g",($diff/60))." min" if ($diff>60*2);
	    $difft=sprintf("%.2g",($diff/3600))." hours" if ($diff>3600*2);
	    $difft=sprintf("%.2g",($diff/86400))." days" if ($diff>86400*2);
	    print "$name is $difft newer on floppy, need to copy ... ";
	    $command="mcopy -t -n -m a:$name . 2>/dev/null";
	    if (system($command)) {
		print "error ! ($command)\n";
		exit;
	    }
	    else {
		print "done.\n";
		$copied++;
	    }
	}
    }

    if ($copied) {
	print "\nCopied $copied file(s), you better check ...\n\n";
	exit;
    }
    print "All files are up to date.\n";
}

if (index($stages,"2")>=0) {
#
# Crosscheck Versions
#
    print "\nChecking versions:\n";
    open3(*WRT,*RDR,*ERR,"./$yabexe -?") || die "Can't open $yabexe\n";
    while(<ERR>) {
	if (/yabasic\s*(\d\.\d{1,2}),/) {
	    $exever=$1;
	    print "  $exever ($yabexe)\n";
	    last;
	}
    }
    die "Can't get version from $yabexe\n" if (!defined($exever));
    
    open(RDR,$yabsrc) || die "Can't open $yabsrc\n";
    while(<RDR>) {
	if (/#define\s*BASIC_VERSION\s*\"(\d\.\d{1,2})\"/) {
	    $sourcever=$1;
	    print "  $sourcever ($yabsrc)\n";
	    last;
	}
    }
    die "Can't get version from $yabsrc\n" if (!defined($sourcever));
    
    open(RDR,$yabdoku) || die "Can't open $yabdoku\n";
    while(<RDR>) {
	if (/Version\s+(\d\.\d{1,2})/) {
	    $dokuver=$1;
	    print "  $dokuver ($yabdoku)\n";
	    last;
	}
    }
    die "Can't get version from $yabdoku\n" if (!defined($dokuver));
    
    if ($exever eq $dokuver && $dokuver eq $sourcever) {
	print "Okay.\n";
    }
    else {
	print "Mismatch !\n";
	die "Better go and bring them in line\n";
    }
    
    if ($>) {die "Need to be root to create rpm-file !\n";}
    
#
# create, compress and copy sourcepack for rpm
#
    $sourcelist="";
    $tempdir="$sourcedir-$exever";
    for $source (@sourcepack) {
	$sourcelist.="$sourcedir/$source ";
    }
    $command="cd .. ; rm -fr $tempdir ; mkdir $tempdir ; cp $sourcelist $tempdir ; rm -f $spackfile; tar cf $spackfile $tempdir 2>/dev/null ; rm -r $tempdir";
    print "Creating tar archive $tempdir with sources ... ";
    die "error !\nCommand has been:\n\n$command\n\n" if (system($command));
    print "done.\n";
    print "Compressing tar archive ... ";
    $command="cd .. ; compress -f $spackfile";
    die "error !\nCommand has been:\n\n$command\n\n" if (system($command));
    print "done.\n";
    die "Can't move $spackfile.Z\n" if (system("cd .. ; cp -f $spackfile.Z /usr/src/packages/SOURCES 2>/dev/null"));

#
# rename sourcepack
#
    print "Renaming tar archive with sources ... ";
    die "Can't rename $spackfile.Z to yabasic.tar.Z\n" if (system("cd .. ; mv -f $spackfile.Z yabasic.tar.Z 2>/dev/null"));
    print "done.\n";

#    
# create rpm package
#
    print "Putting version into $specfile ... ";
    open(SPEC,$specfile) || die "Can't open $specfile\n";
    @spec=<SPEC>;
    close(SPEC);
    open(SPEC,"> $specfile") || die "Can't open $specfile\n";
    while($line=shift(@spec)) {
	if ($line=~/Version:\s*\d\.\d+/) {
	    print SPEC "Version: $exever\n";
	}
	else {
	    print SPEC $line;
	}
    }
    close(SPEC);
    print "done.\n";
    
    print "Creating rpm-package with linux binaries ";
    $command="rpm -bb --clean yabasic.spec";
    die "Couldn't execute $command\n" if (!open(RPM,"$command 2>&1|"));
    while(<RPM>) {
	push @rpmout,$_;
	if (/^Wrote:\s*(\S*)\s*$/) {print " done.\n$_";$wrote=$1;}
	$lcount++;
	print "." if (!$wrote && !($lcount%5));
    }
    close(RPM);
    if (!$wrote) {
	print " something went wrong,\nrpm output:\n    ";
	print join "   ",@rpmout;
	die "\n";
    }
    
    $command="rpm  -i yabasic";
    die "Couldn't execute $command\n" if (!open(RPM,"$command 2>&1|"));
    undef @rpmout;
    die "Couldn't copy $wrote\n" if (qx(cp $wrote ../yabasic.rpm 2>&1));
    print "Trying to install ... ";
    if ($out=qx(rpm -i --force --nodeps ../yabasic.rpm 2>&1)) {
	print "Error !\n";
	print "rpm returned: $out\n";
	exit;
    } else {
	print "done.\n";
    }

#
# add rpm file to lists
#
    push @tolist,$wrote;
    $short=substr($wrote,rindex($wrote,"/")+1);
    $tooptions{$short}="-n -o -m";
    $torename{$short}="yabasic.rpm";
    system("cp -f $wrote ../yabasic.rpm");
}    

if (index($stages,"3")>=0) {
#
# copy selected files to floppy
#
    print "\nCopying files to floppy\n";
    for ${toname} (@tolist) {
	$rename="";
	$sopt="";
	$pos=rindex(${toname},"/");
        if ($pos>0) {$shortname=substr(${toname},$pos+1);} else {$shortname=${toname};}
        if (exists($tooptions{$shortname})) {
	    $opt=$tooptions{$shortname};
            $sopt=$opt;
        }
        else {
	    $opt="-n -o -m";
	}
        if (exists($torename{$shortname})) {
	    $rename=$torename{$shortname};
        }
        else {
	    $rename=$shortname;
        }
        if (substr($toname,0,1) eq "/") {
	    $fromtime=(stat(${toname}))[9];
        }
        else {
	    $fromtime=(stat("../${toname}"))[9];
        }
        $totime=&floptime($rename);
        if ($fromtime>$totime+120) {
	    $command="cd ..; mcopy $opt ${toname} a:$rename 2>/dev/null";
	    system("mdel a:$rename 2>/dev/null");
	    if (system($command)) {
		print "... error !\n";
		print "Command has been:\n\n$command\n\n";
		exit;
   	    }
            print "  $shortname";
            print " as $rename" if ($rename ne $shortname);
            print " options: $sopt" if ($sopt);
            print "\n";
       }
   }
   print "done.\n";
   exit;
}

#
# get modification time of file on floppy
#
sub floptime {

    my $filename,$size,$mon,$day,$year,$hr,$min,$pm,$name;
    $filename="A:\\@_[0]";
    
    open(MDIR,"mdir $filename 2>/dev/null |") || die "Need a floppy !\n";
    while(<MDIR>) {
	if (/\s*\S+\s+\S+\s*(\d+)\s+(\d+)-(\d+)-(\d+)\s+(\d+):(\d+)(\S)?\s+(\S+)/) {
	    ($size,$mon,$day,$year,$hr,$min,$pm,$name)=
		($1,$2,$3,$4,$5,$6,$7,$8);
	    $hr+=12 if ($pm eq "p" and $hr!=12);
	    $year-=1900;
	    $mon--;
	    close(MDIR);
	    return timelocal(0,$min,$hr,$day,$mon,$year);
	}
    }
    close(MDIR);
    return -1;
}

