# $Id: Makefile.PL,v 1.20 1998/05/27 16:47:36 rib Exp $
use ExtUtils::MakeMaker;
use File::Path;
use Config;
use strict;

$SIG{INT} = \&sig_handler;
$SIG{QUIT} = \&sig_handler;

umask 022;
#
#	The following three variables contain configuration
# information about the installation of RIB. Mod_info contains info 
# gleaned from the RIB Modules, if RIB has already been installed.
# Current_info contains immediate info from the user running this script,
# and Cache_info contains info from a previous run of this script, if there
# was one.
#
#	Default answers are displayed in square braces and are determined
# as follows. If there was a previous run of this script and the file 
# 'config.cache' is in the current working directory, then all default answers
# come from there, as assined in $cache_info. If there was not a previous
# run, the default answers come from the RIB Modules and initialized in
# %current_info, if a previous installation of RIB was found. If a previous
# installation is not found then there are no default answers. %current_info
# will always contain the most recent answer and will be written to the file
# config.cache.
#
my %mod_info;
my %current_info;
my $cache_info;

sub sig_handler {
    if (open(FILE,"+>config.cache")){
	print FILE Data::Dumper::Dumper(\%current_info);
	close(FILE);
    }
    exit(1);
}
########### Check for another installation of RIB

eval { require 'RIB/Util.pm';};
unless ($@){
    $mod_info{RIBDIR} = RIB::Util::GetRibDir();
    $mod_info{RIBURL} = RIB::Util::GetRibUrl();
    $mod_info{RIBSP} = RIB::Util::GetRibIsearchCgiPath();
    $mod_info{RIBI} = RIB::Util::GetRibIindexPath();
}

############ Check for presence of dependent modules

my $status;
$status = chk_version('Data::Dumper' => '2.07');
if ($status == 0){
    die "\n"
        . "*** To be able to use the RIB modules you *MUST* have\n"
        . "    Data::Dumper installed. You can obtain this from\n"
        . "    CPAN/modules/by-module/Data/Data-Dumper-2.07.tar.gz.\n"
        . "    After you have installed it, run 'perl Makefile.PL' again.\n";
} elsif ($status == 1){
    warn 
    " *** Make sure you have Data::Dumper version 2.07 or later installed.\n";
}
$status = chk_version('HTML::Parser' => '2.01');
if ($status == 0){
    die "\n"
        . "*** To be able to use the RIB modules you *MUST* have\n"
        . "    HTML::Parser installed. You can obtain this from\n"
        . "    CPAN/modules/by-module/LWP/libwww-perl-5.00.tar.gz\n"  
        . "    After you have installed it, run 'perl Makefile.PL' again.\n";
} elsif ($status == 1){
    warn 
    " *** Make sure you have HTML::Parser version 2.01 or later installed.\n";
}
$status = chk_version('HTML::Entities' => '1.06');
if ($status == 0){
    die "\n"
        . "*** To be able to use the RIB modules you *MUST* have\n"
        . "    HTML::Entities installed. You can obtain this from\n"
        . "    CPAN/modules/by-module/LWP/libwww-perl-5.00.tar.gz\n" 
        . "    After you have installed it, run 'perl Makefile.PL' again.\n";
} elsif ($status == 1){
    warn 
    " *** Make sure you have HTML::Entities version 1.06 or later installed.\n";
}
$status = chk_version('LWP::UserAgent' => '1.35');
if ($status == 0){
    die "\n"
        . "*** To be able to use the RIB modules you *MUST* have\n"
        . "    LWP::UserAgent installed. You can obtain this from\n"
        . "    CPAN/modules/by-module/LWP/libwww-perl-5.00.tar.gz\n"
        . "    After you have installed it, run 'perl Makefile.PL' again.\n";
} elsif ($status == 1){
    #warn 
    #" *** Make sure you have LWP::UserAgent version 1.35 or later installed.\n";
}
$status = chk_version('HTTP::Request' => '2.07');
if ($status == 0){
    die "\n"
        . "*** To be able to use the RIB modules you *MUST* have\n"
        . "    HTML::Parser installed. You can obtain this from\n"
        . "    CPAN/modules/by-module/LWP/libwww-perl-5.00.tar.gz\n"
        . "    After you have installed it, run 'perl Makefile.PL' again.\n";
} elsif ($status == 1){
    #warn 
    #" *** Make sure you have HTTP::Request version 2.07 or later installed.\n";
}

############ Open Cache Info if available

if (open(FILE,"<config.cache")){
    my $buf = ''; while(<FILE>){ $buf .= $_;}; close(FILE);
    $cache_info = eval "my $buf";
}

##### Beginning of Configuration Questions

print <<EOF;

Beginning of configuration questions for RIB. To select the
default answers between the '[' braces ']', just press enter.

RIB Installation Directory: This directory will contain the RIB
software, related configuration files, and the repositories. It
should contain ample disk space. Your web server must be able to
access this directory.
EOF

my $msg = "\nEnter the absolute path to the RIB installation directory:\n";
my (@ribdirs,$i); 
for $i (1..3){
    ($current_info{RIBDIR}) = 
	    Prompt($msg,'dir', (defined $cache_info->{RIBDIR}) ? 
		    $cache_info->{RIBDIR} : $mod_info{RIBDIR});
    @ribdirs = ("$current_info{RIBDIR}",
	map("$current_info{RIBDIR}/$_", 'cgi-bin','cgi-bin/admin',
	'cgi-bin/pub', 'cgi-bin/admin/repositories',
	'cgi-bin/admin/create_delete_repo', 'cgi-scripts','help',
	'conf','images','repositories','show_object.cache'));
    eval { File::Path::mkpath(\@ribdirs,1,0755) };
    if ($@){
	print "\n*** Error: $@\n";	
    } else {
	last;
    }
    if ($i == 3){
	print "ABORTING!!! Too many tries!! Run perl Makefile.PL again.\n";
	exit;
    }
}

print <<EOF;

Base URL for RIB: This url must point to your RIB installation
directory, i.e., your web server must be able to map this URL to
your RIB installation directory.  For example, if you entered
'/usr/local/rib' as your RIB installation directory, and you
enter 'http://www.nhse.org/rib' for your base URL for RIB, then
your web server must know that the url 'http://www.nhse.org/rib'
maps to the directory '/usr/local/rib' on your filesystem.  This
is usually done via the "Alias" server directive in your http
server configuration files.
EOF
$msg = "\nEnter the base URL for RIB:";
($current_info{RIBURL}) = Prompt($msg,'url',$cache_info->{RIBURL} ?
			    $cache_info->{RIBURL} : $mod_info{RIBURL});

print <<EOF;

Isearch and RIB: Currently, RIB supports the indexing and
searching of its software catalogs using Isearch. Answer yes to
the following question if you have installed would like to use
the Isearch software package from www.cnidr.org.
EOF
my $ribsrch;
if (get_bool("Would you like your repositories searchable via Isearch\?",
	(defined $cache_info->{SEARCH}) ? $cache_info->{SEARCH} : 'yes')){
    $current_info{SEARCH} = 'yes';
    $msg = "\nEnter the absolute path to the directory where the Iindex"
	  ." binary\nis installed:";
    ($current_info{RIBI}) = Prompt($msg,'dir',$cache_info->{RIBI} ?
			       	$cache_info->{RIBI} : $mod_info{RIBI});
    $msg = "\nEnter the absolute path to the directory where the isrch_srch\n"
	  ."and isrch_fetch binaries are installed:";
    ($current_info{RIBSP}) = Prompt($msg,'dir',$cache_info->{RIBSP} ?
			       	$cache_info->{RIBSP} : $mod_info{RIBSP});
} else {
    $current_info{RIBI} = $current_info{RIBSP} = '';
    $current_info{SEARCH} = '';
}


###  This is no longer optional
#print <<EOF;
#
#RIB Perl5 Modules: Parts of the RIB software are written as
#PERL5 modules.  If you would like, these modules can be
#installed into your main perl installation directory (which is
#usually at /usr/local/lib/perl5). This will usually require root
#access to this machine.  Otherwise, the modules will be
#installed beneath the RIB Installation Directory.
#
#EOF
#if (get_bool("Would you like to install the RIB modules into your perl distribution\?",
#	(defined $cache_info->{RIBLIB}) ? $cache_info->{RIBLIB} : 'yes')){
#    $current_info{RIBLIB} = 'yes';
#} else {
#    eval { File::Path::mkpath("$current_info{RIBDIR}/lib/RIB",1,0755) };
#    if ($@){
#        print "\n*** Error: $@\n" && exit;
#    }
#    $current_info{RIBLIB} =  '';
#}

print <<EOF;

Creating $current_info{RIBDIR}/lib/RIB.  This is where the perl
modules for RIB will be placed...
EOF
eval { File::Path::mkpath("$current_info{RIBDIR}/lib/RIB",1,0755) };
if ($@){
    print "\n*** Error: $@\n" && exit;
}
push @ribdirs , map("$current_info{RIBDIR}/$_",'lib','lib/RIB');

print "\nAll the files and directories under $current_info{RIBDIR} need to be\n";
print "owned by the username that your http server runs under.\n";
$msg = "\nEnter the username that your http server runs under:";
my ($ribuid, $ribgid);
($ribuid,$ribgid,$current_info{RIBUSER}) = 
	Prompt($msg,'uid',$cache_info->{RIBUSER} ?
	    $cache_info->{RIBUSER} : "nobody");
unless (chown $ribuid,$ribgid, @ribdirs){
    print <<"GROK";

*** $current_info{RIBUSER} does not have permission to own the directories
    under $current_info{RIBDIR}.

    The username that your web server runs as MUST have permission to
    manipulate files and directories under $current_info{RIBDIR}.
    Make sure you change these before running RIB!!!

GROK
}

############# Write Util.pm

print "\nUpdating Util.pm\n";
open(FILE,"<./Util.pm.DIST") || die "Cannot open Util.pm.DIST: $!";
my $file; while (<FILE>) {$file .= $_;}
close(FILE);
unless ($file =~ s/<!---GETRIBDIR--->/$current_info{RIBDIR}/)
	{ die "Could not update GetRibDir";}
unless ($file =~ s/<!---GETRIBURL--->/$current_info{RIBURL}/)
	{ die "Could not update GetRibUrl";}
unless ($file =~ s/<!---GETRIBISEARCHCGIPATH--->/$current_info{RIBSP}/)
	{ die "Could not update GetRibIsearchCgiPath";}
unless ($file =~ s/<!---GETRIBIINDEXPATH--->/$current_info{RIBI}/)
	{ die "Could not update GetRibIindexPath";}
open(FILE,"+>./RIB/Util.pm") || die "Cannot create RIB/Util.pm: $!";
print FILE $file;
close(FILE);

############ Is the Path to PERL Too Long ?

# Usefile config keys in Config:
#
# sharpbang: the symbols that tell the os the file is executable, #!
# shsharp: if the file can execute an interpreter?
# startsh: first line of an executeable shell script file,e.g., #!/bin/sh
# perlpath: path to perl :)
# startperl: first line of an executeable perl script file,e.g., 
#            #!/usr/local/bin/perl

print "\nChecking if your shell can run perl from an executable file... ";

open(FILE,"+>foo$$") or die  "Cannot open foo$$: $!";
print FILE <<"GROK";
$Config{'startperl'}
print 'RIB-0.9.2';
GROK
close(FILE);
chmod 0755, "foo$$";

$current_info{BADSHELL} = `"./foo$$"`;
unlink "foo$$";
if ('RIB-0.9.2' eq $current_info{BADSHELL}){
    print "It can!\n"; $current_info{BADSHELL} = 0;
}
else {
    print "It cannot\n"; $current_info{BADSHELL} = 1;
}

########### Prepare Scripts for Installation

print "\nPreparing RIB Scripts for installation:\n";
unless( -d 'scripts-install'){
    unless (mkdir 'scripts-install',0755){ print "\n*** Error: $!\n" ; exit; }
}
unless(opendir(DIR,'cgi-scripts')){ print "\n*** Error: $!\n" && exit; }
my $f;
foreach $f (grep { !/^.$/ && !/^..$/ } readdir(DIR)){
    open(FILE,"<cgi-scripts/$f") or die  "Cannot open cgi-scripts/$f: $!";
    print "$f... ";
    my $buf = ''; my $pre = '';
    while(<FILE>){ $buf .= $_ ;} close(FILE);
    if ($current_info{BADSHELL}){
	$pre = <<"GROK";
$Config{startsh} -- # perl
eval 'exec $Config{perlpath} -S \$0 \${1+"\$\@"}'
	if 0;
GROK
    } else {
	$pre = "$Config{startperl}\n";
    }
    if ($current_info{RIBLIB} == ''){
    # Installing RIB Modules into RIB directory
	$pre .= "use lib \'$current_info{RIBDIR}/lib\';\n";
    }
    open(FILE,"+>scripts-install/$f") or die "Cannot open scripts-install/$f: $!";
    print FILE $pre , $buf ; close(FILE);
    print "done\n";
}
print "\n";
############ Writing Config.cache File

if (open(FILE,"+>config.cache")){
    print FILE Data::Dumper::Dumper(\%current_info);
    close(FILE);
}

############ Write the Makefile

WriteMakefile(
    'NAME'    => 'RIB',
    'VERSION' => '1.2',
    #'PL_FILES' =>  \%pls,
    #'clean'   => { FILES => 'RIB/Util.pm '. join(' ',values %pls) },
    'clean'   => { FILES => 'config.cache RIB/Util.pm scripts-install'},
    'dist'    => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
);

print <<EOF;

You must now issue the following commands in the order they apear:

make
make test
make install_rib   <---- note : use this command instead of "make install"

And if you are upgrading from a previous release of RIB:

make update

Good luck! If you have any problems installing RIB,
contact rib\@nhse.org
EOF

########### End of Script 

########### Subroutines 

sub MY::postamble {
    my $buf = <<"!GROK!THIS!";

install_rib:
	umask 022;
	cp ./scripts-install/RIB.pl $current_info{RIBDIR}/cgi-bin/admin/
	cp ./scripts-install/delete_repository.pl $current_info{RIBDIR}/cgi-bin/admin/create_delete_repo/
	cp ./scripts-install/create_repository.pl $current_info{RIBDIR}/cgi-bin/admin/create_delete_repo/
	cp ./scripts-install/ifetch $current_info{RIBDIR}/cgi-bin/pub/
	cp ./scripts-install/isearch.pl $current_info{RIBDIR}/cgi-bin/pub/
	cp ./scripts-install/list_local_links.pl $current_info{RIBDIR}/cgi-bin/pub/
	cp ./scripts-install/list_nonlocal_links.pl $current_info{RIBDIR}/cgi-bin/pub/
	cp ./scripts-install/show_object.pl $current_info{RIBDIR}/cgi-bin/pub/
	cp ./scripts-install/add_nonlocal_link.pl $current_info{RIBDIR}/cgi-scripts/
	cp ./scripts-install/admin_repository.pl $current_info{RIBDIR}/cgi-scripts/
	cp ./scripts-install/browse_objects.pl $current_info{RIBDIR}/cgi-scripts/
	cp ./scripts-install/check_nonlocal_links.pl $current_info{RIBDIR}/cgi-scripts/
	cp ./scripts-install/check_disk_space.pl $current_info{RIBDIR}/cgi-scripts/
	cp ./scripts-install/create_object.pl $current_info{RIBDIR}/cgi-scripts/
	cp ./scripts-install/create_object_choices.pl $current_info{RIBDIR}/cgi-scripts/
	cp ./scripts-install/delete_nonlocal_link.pl $current_info{RIBDIR}/cgi-scripts/
	cp ./scripts-install/delete_object.pl $current_info{RIBDIR}/cgi-scripts/
	cp ./scripts-install/describe_field.pl $current_info{RIBDIR}/cgi-scripts/
	cp ./scripts-install/edit_object.pl $current_info{RIBDIR}/cgi-scripts/
	cp ./scripts-install/generate_catalog.pl $current_info{RIBDIR}/cgi-scripts/
	cp ./scripts-install/install_file.pl $current_info{RIBDIR}/cgi-scripts/
	cp ./scripts-install/lwp-download.pl $current_info{RIBDIR}/cgi-scripts/
	cp ./scripts-install/manage_software_files.pl $current_info{RIBDIR}/cgi-scripts/
	cp ./scripts-install/update_mirrors.pl $current_info{RIBDIR}/cgi-scripts/
	cp ./scripts-install/view_nonlocal_links.pl $current_info{RIBDIR}/cgi-scripts/
	cp ./scripts-install/generate_grid.pl $current_info{RIBDIR}/cgi-scripts/
	cp ./conf/*.conf $current_info{RIBDIR}/conf/
	cp ./conf/*.html $current_info{RIBDIR}/conf/
	cp ./help/*.gif $current_info{RIBDIR}/help/
	cp ./help/*.html $current_info{RIBDIR}/help/
	cp ./images/*.gif $current_info{RIBDIR}/images/
	cp ./RIB/*.pm $current_info{RIBDIR}/lib/RIB/
	chmod -R 755 $current_info{RIBDIR}/cgi-bin
!GROK!THIS!
    $buf .= <<"!GROK!THIS!";
	echo \"Done!\"; \\
	echo \\    
	echo \"Please remember to 'make update' if You are updating a previous release of RIB!\"; \\
	echo \"To start using RIB, go to:\"; \\
	echo \"$current_info{RIBURL}/cgi-bin/admin/RIB.pl\"; 

update:
	echo \"One Moment Please...\" ;
	umask 022;
	if [ -d $current_info{RIBDIR}/cgi-bin/repositories ]; then \\
	  echo \"Updating cgi paths\" ;\\
	  for repopath in $current_info{RIBDIR}/cgi-bin/repositories/* ; do \\
	      mv -f \$\$repopath $current_info{RIBDIR}/cgi-bin/admin/repositories ; \\
	  done ; \\
	  rm -rf $current_info{RIBDIR}/cgi-bin/RIB.pl $current_info{RIBDIR}/cgi-bin/repositories $current_info{RIBDIR}/cgi-bin/create_delete_repo ; \\
	fi;
	echo \"Upgrading cgi scripts\" ;
	for repopath in $current_info{RIBDIR}/cgi-bin/admin/repositories/*; do \\
		set var repo; repo=`basename \$\$repopath` ; \\
		cp $current_info{RIBDIR}/cgi-scripts/* \$\$repopath/ ; \\
	done;
	chmod -R 755 $current_info{RIBDIR}/cgi-bin ;
	echo \"Creating new catalog directories\" ;
	for repopath in $current_info{RIBDIR}/cgi-bin/admin/repositories/*; do \\
		set var repo; repo=`basename \$\$repopath` ; \\
		test -d $current_info{RIBDIR}/repositories/\$\$repo/catalog/Asset || mkdir $current_info{RIBDIR}/repositories/\$\$repo/catalog/Asset; \\
		test -d $current_info{RIBDIR}/repositories/\$\$repo/catalog/Certificate || mkdir $current_info{RIBDIR}/repositories/\$\$repo/catalog/Certificate; \\
		test -d $current_info{RIBDIR}/repositories/\$\$repo/catalog/CertificationArtifact || mkdir $current_info{RIBDIR}/repositories/\$\$repo/catalog/CertificationArtifact; \\
		test -d $current_info{RIBDIR}/repositories/\$\$repo/catalog/CertificationLevel || mkdir $current_info{RIBDIR}/repositories/\$\$repo/catalog/CertificationLevel; \\
		test -d $current_info{RIBDIR}/repositories/\$\$repo/catalog/CertificationPolicy || mkdir $current_info{RIBDIR}/repositories/\$\$repo/catalog/CertificationPolicy; \\
		test -d $current_info{RIBDIR}/repositories/\$\$repo/catalog/CertificationProperty || mkdir $current_info{RIBDIR}/repositories/\$\$repo/catalog/CertificationProperty; \\
		test -d $current_info{RIBDIR}/repositories/\$\$repo/catalog/CertificationQualityFactor || mkdir $current_info{RIBDIR}/repositories/\$\$repo/catalog/CertificationQualityFactor; \\
		test -d $current_info{RIBDIR}/repositories/\$\$repo/catalog/Element || mkdir $current_info{RIBDIR}/repositories/\$\$repo/catalog/Element; \\
		test -d $current_info{RIBDIR}/repositories/\$\$repo/catalog/Library || mkdir $current_info{RIBDIR}/repositories/\$\$repo/catalog/Library; \\
		test -d $current_info{RIBDIR}/repositories/\$\$repo/catalog/Organization || mkdir $current_info{RIBDIR}/repositories/\$\$repo/catalog/Organization; \\
		echo \"Creating new files directory\" ; \\
		test -d $current_info{RIBDIR}/repositories/\$\$repo/files || mkdir $current_info{RIBDIR}/repositories/\$\$repo/files ; \\
	done; \\
	echo \"Removing any entries currently in the show_object.cache directory\" ; \\
	test -d $current_info{RIBDIR}/show_object.cache && rm -rf $current_info{RIBDIR}/show_object.cache;
	echo \"Creating new cache directory for dynamically generated catalog entries\" ; \\
	test -d $current_info{RIBDIR}/show_object.cache || mkdir $current_info{RIBDIR}/show_object.cache;
	chown $current_info{RIBUSER} $current_info{RIBDIR}/show_object.cache;
	chown -R $current_info{RIBUSER} $current_info{RIBDIR}/cgi-bin/admin/repositories;
	chown -R $current_info{RIBUSER} $current_info{RIBDIR}/repositories;
	echo \"Updating nonlocal files\" ;
!GROK!THIS!
    my $update_nonlocal;
    my $update_centry;
    $update_nonlocal = $Config{'perlpath'}.' -I'. $current_info{RIBDIR} .
	    '/lib ./update_scripts/update_nonlocal.pl ;\\';
    $update_centry = $Config{'perlpath'}.' -I'. $current_info{RIBDIR} .
	    '/lib ./update_scripts/update_catalog_entry.pl ;\\';
    $buf .= <<"!GROK!THIS!";
	$update_nonlocal
	echo \"Updating catalog entries\" ;\\
	$update_centry
	echo \"Done!\" ;\\
	echo \"To start using RIB, go to:\"; \\
	echo \"$current_info{RIBURL}/cgi-bin/admin/RIB.pl\";
!GROK!THIS!
    return $buf;
}


sub chk_version
{
 my($pkg,$wanted,$msg) = @_;

 local($|) = 1;
 print "Checking for $pkg...";

 eval { my $p; ($p = $pkg . ".pm") =~ s#::#/#g; require $p; };
 print " NOT INSTALLED\n" and return 0 if $@;

 no strict 'refs';
 my $vstr = ${"${pkg}::VERSION"} ? "found v" . ${"${pkg}::VERSION"}
                                 : "installed, but can't find version. ok";
 my $vnum = ${"${pkg}::VERSION"} || 0;
 use strict 'refs';

 print $vnum >= $wanted ? "ok\n" : " " . $vstr . "\n";

 if ($vnum >= $wanted){
    return 2;
 } else {
    return 1;
 }
}

sub Prompt
{
 my ($prompt,$kind,$default) = @_;
 my ($val,$val1,$val2);

 chomp($prompt);
 $val = ' ';
 while ($val =~ /\s+/ || $val eq ''){
     if (defined $default){
	 $val = ExtUtils::MakeMaker::prompt($prompt,$default);
     } else {
         $val = ExtUtils::MakeMaker::prompt($prompt);
     }
     if ($kind eq 'dir'){
	 $val =~ s/\/$//;
	 unless (-e $val){
	    print "\n*** $val does not exist.\n";
	    if (get_bool("     Would you like me to create it\?","yes")){
		eval { File::Path::mkpath($val, 1) };
		if ($@){
		    print "\n***Error creating $val: $@\n"; $val = ' ';
		}
            } else {
		$val = ' ';
            }
	 }
     } elsif ($kind eq 'url'){
	 $val =~ s/\/$//;
         unless ($val =~ m|^http://|){
            print "\n*** $val is not a valid url.\n"
                 ."      Please enter a valid url at the prompt\n";
            $val = ' ';
	 }
     } elsif ($kind eq 'bin'){
	unless (-e $val){ 
           print "\n*** $val Does not exist.\n";
	    $val = ' ';
	}
     } elsif ($kind eq 'uid'){
	 my @person = getpwnam($val); # returns (login,passwd,uid,gid)
         if (!@person){
	    print "\n*** $val is not known by this computer.\n";
	    $val = ' ';
	 } else {
	    $val = $person[2];
	    $val1 = $person[3];
	    $val2 = $person[0];
	 }
     }
 }
 ($val,$val1,$val2);
}

sub get_bool
{
 my($prompt,$def) = @_;

 chomp($prompt);

 my $val = ExtUtils::MakeMaker::prompt($prompt,$def ? "yes" : "no");

 $val =~ /^y/i ? 1 : 0;
}
