#!/usr/bin/perl -w
#
# 27/2/03 V0.13
#

use strict;

## Globals ##
my ($dname,$nname,$lcguname,$hostcert,$hostkey,$sename,$sedomain,$infouser,$batchtype,$batchpath,$batchqueue);
my ($hostsubject,$dn_host,$dn_org);
my $progname = $0; $progname =~ s/^.*\///;
##

umask 0022;
select(STDERR); $| = 1;
select(STDOUT); $| = 1;
do_main(@ARGV);
exit 0;

sub verify_host_from_good_ca {
  open(SSL,"openssl verify -CApath /etc/grid-security/certificates /etc/grid-security/hostcert.pem |") ||
    my_fatal("Could not open pipe from openssl");

  my $ok=0;
  while(<SSL>) {
    my $line; chomp($line = $_);
    $ok=1 if $line =~ m|^/etc/grid-security/hostcert.pem: OK$|;
  }
  close(SSL);

  my_fatal("The host certificate does not appear to be signed by a trusted CA") unless $ok;
}

sub lookup_from_cgi_list {
  my ($array_ref,$fullname_ref) = @_;
  my $found = 0;

  my $filename = $$fullname_ref;
  foreach my $addr (@$array_ref) {
    my @names = split('/',$addr);
    if ($names[$#names] eq $filename) {
      if (!$found) {
        $$fullname_ref = $addr; $found = 1;
      } else {
        my_fatal("Server has multiple files named ".$filename);
      }
    }
  }
  return 0 if $found;
  return 1;
}

sub my_fullpath {
  my ($path_ref) = @_;
  return if $$path_ref =~ m|^/|;

  chomp(my $pwd=`pwd`);

  if ($$path_ref eq "") {
    $$path_ref = $pwd;
  } else {
    $$path_ref = $pwd."/".$$path_ref;
  }
}

sub verify_host_pair {
  my ($hcert,$hkey) = @_;

  my ($pubmod,$privmod);

  open(SSL,"openssl x509 -modulus -noout -in ".$hcert." 2>/dev/null |") ||
    my_fatal("Could not open pipe from openssl");
  while(<SSL>) {
    my $line; chomp($line = $_);
    if ($line =~ /Modulus=(.*)/) {
      $pubmod = $1;
    }
  }
  close(SSL);

  open(SSL,"openssl rsa -modulus -noout -in ".$hkey." 2>/dev/null |") ||
    my_fatal("Could not open pipe from openssl");
  while(<SSL>) {
    my $line; chomp($line = $_);
    if ($line =~ /Modulus=(.*)/) {
      $privmod = $1;
    }
  }
  close(SSL);
  
  return 1 if (!defined $pubmod || !defined $privmod);
  return 1 if ($pubmod ne $privmod);

  return 0;
}

sub exec_globus_postinstall {
  my $res;

## Globus postinstall scripts,  NB they give (harmless) warnings about /opt/vdt/var
## and /opt/vdt/mds-2.2/sbin/globus-mds

  my $tf = "/tmp/ce-install-temp.$$";
  print "Executing globus postinstall scripts...";
  $res = system("source /opt/vdt/setup.sh; sh /opt/vdt/setup/globus-postinstall.sh < /dev/null 1>/dev/null 2>".$tf.";".
                "export GLOBUS_LOCATION=/opt/vdt/mds-2.2; source /opt/vdt/mds-2.2/setup.sh;".
                "sh /opt/vdt/mds-2.2/setup/globus-postinstall.sh < /dev/null 1>/dev/null 2>>".$tf.";".
                "export GLOBUS_LOCATION=/opt/vdt/");
  my_fatal("Could not rerun the globus-postinstall scripts") if $res;
  print " Done\n";
  open(TF,"< ".$tf) || my_fatal("Could not open $tf in exec_globus_postinstall");
  while(<TF>) {
    my $line; chomp($line=$_);
    next if ($line =~ m|^mkdir: cannot create directory \`/opt/vdt//var\': File exists$|);
    next if ($line =~ m|^ln: \`/opt/vdt/mds-2.2/sbin/globus-mds\': File exists$|);
    my_print("Warning: globus-postinstall reported error: $line");
  }
  close(TF);
  unlink $tf;
}

sub update_file_max {
  open(FM,"> /proc/sys/fs/file-max") || my_fatal("Could not open file-max");
  print FM "120000\n";
  close(FM);

  my_chdir("/etc/rc.d");
  my_rename("rc.local");

  my $skip = 0;
  open(RCIN,"< rc.local.orig") ||
    my_fatal("Could not read from rc.local.orig");
  open(RCOUT,"> rc.local") ||
    my_fatal("Could not write to rc.local");
  while(<RCIN>) {
    my $line; chomp($line = $_);

    if ($line =~ m|^if \[ -f /proc/sys/fs/file-max|) {
      $skip = 3;
    }

    if ($skip) {
      $skip--;
      next;
    }
    print RCOUT $line."\n";
  }
  close(RCIN);
  print RCOUT "if [ -f /proc/sys/fs/file-max ]; then\n";
  print RCOUT "  echo 120000 > /proc/sys/fs/file-max\n";
  print RCOUT "fi\n";
  close(RCOUT);

  chmod 0755, 'rc.local' || my_fatal("Could not chmod rc.local");
}

sub update_startup_scripts {
  my ($tdir) = @_;
  my $res;

  mkdir $tdir."/xinet_removed", 0755 || my_fatal("Could not mkdir ".$tdir."/xinet_removed");

  $res = system("mv /etc/xinetd.d/globus-gatekeeper ".$tdir."/xinet_removed/globus-gatekeeper_EDG");
  my_fatal("Could not move /etc/xinetd.d/globus-gatekeeper") if $res;

  $res = system("/sbin/chkconfig globus-gatekeeper on");
  my_fatal("Could not chkconfig globus-gatekeeper") if $res;

  $res = system("/etc/rc.d/init.d/globus-gatekeeper start");
  my_fatal("Could not start the globus-gatekeeper") if $res;

  $res = system("/sbin/chkconfig globus-gsi_wuftpd on");
  my_fatal("Could not chkconfig globus-gsi_wuftpd") if $res;

  $res = system("/etc/rc.d/init.d/globus-gsi_wuftpd start");
  my_fatal("Could not start globus-gsi_wuftpd") if $res;

  symlink("/etc/rc.d/init.d/gris","/etc/rc.d/rc3.d/S99gris") ||
    my_fatal("Could not make symlink for gris");

  $res = system("/etc/rc.d/init.d/gris start");
  my_fatal("Could not start gris") if $res;

  $res = system("/sbin/chkconfig locallogger on");
  my_fatal("Could not chkconfig locallogger") if $res;

  $res = system("/etc/rc.d/init.d/locallogger start");
  my_fatal("Could not start the locallogger") if $res;
}  

sub update_services {
  my $res;

  $res = system("cp -f /etc/services /etc/services.old");
  my_fatal("Could not backup /etc/services") if $res;

  open(SVIN,"< /etc/services.old") ||
    my_fatal("Could not read from services.old");
  open(SVOUT,"> /etc/services") ||
    my_fatal("Could not write to services");
  while(<SVIN>) {
    my $line; chomp($line = $_);

    next if $line =~ /^gsiftp\s/;
    next if $line =~ /^globus-gatekeeper\s/;

    print SVOUT $line."\n";
  }
  close(SVIN);
  print SVOUT "gsiftp 2811/tcp #Grid-FTP Server\n";
  print SVOUT "globus-gatekeeper 2119/tcp #Globus Gatekeeper\n";
  close(SVOUT);
}


sub init_gridmap_file {
  my $res;
  my $my_cron_cmd = "/opt/edg/etc/cron/mkgridmap-cron";

  $res = system($my_cron_cmd);
  my_fatal("Could not run mkgridmap-cron") if $res;

  my @ct_lines;
  open(CT,"crontab -l 2>/dev/null|") || my_fatal("Could not list roots crontab");
  while(<CT>) {
    my $line; chomp($line = $_);
    next if $line =~ /^#/;
    if ($line =~ /^[^ ]+ +[^ ]+ +[^ ]+ +[^ ]+ +[^ ]+ +([^ ]+)/) {
      my $cmd = $1;
      next if $cmd =~ m|^$my_cron_cmd|;
      push(@ct_lines,$line);
    }
  }
  close(CT);
  my $min = int(rand(60));

  open(CT,"| crontab") || my_fatal("Could not setup roots crontab");
  foreach my $ct_line (@ct_lines) {
    print CT $ct_line."\n";
  }
  print CT $min." * * * * ".$my_cron_cmd."\n";
  close(CT);
}


sub rewrite_mkgridmap_conf {
  my_chdir("/opt/edg/etc");
  my_rename("mkgridmap.conf");

  open(GCIN,"< mkgridmap.conf.orig") ||
    my_fatal("Could not read from mkgridmap.conf.orig");
  open(GCOUT,"> mkgridmap.conf") ||
    my_fatal("Could not write to mkgridmap.conf");
  print GCOUT "group ldap://lxshare0229.cern.ch/ou=users,o=lcg,dc=cern,dc=ch ".$lcguname."\n";
  while(<GCIN>) {
    my $line; chomp($line=$_);
    $line =~ s/^(auth|group)/#$1/;
    print GCOUT $line."\n";
  }
  close(GCOUT);
  close(GCIN);
}

sub my_rename {
  my ($name) = @_;

  my_fatal("my_rename: $name does not exist") unless -e $name;
#  return unless -e $name;

  if ( -e $name.".orig" ) {
    my_fatal("my_rename: ".$name.".orig is not a plain file") unless -f $name.".orig";

    my_fatal("my_rename: ".$name.".orig already exists");
##   NOT REACHED   ##
##    unlink $name.".orig";
  }

  rename($name,$name.".orig") || my_fatal("Could not rename $name");
}

sub rewrite_glue_confs {
  my $res;
  my $my_fqhn = $nname.".".$dname;
  my $my_jm = "jobmanager-".lc($batchtype)."-".$batchqueue;
  my $se_fqhn = $sename.".".$sedomain;


  my_chdir("/opt/vdt/mds-2.2/etc");
  my_rename("grid-info-resource-ldif.conf");
  open(GCIN,"< grid-info-resource-ldif.conf.TEMPLATE") ||
    my_fatal("Could not read from grid-info-resouce-ldif.conf.TEMPLATE");
  open(GCOUT,"> grid-info-resource-ldif.conf") ||
    my_fatal("Could not write to grid-info-resouce-ldif.conf");
  while(<GCIN>) {
    my $line; chomp($line=$_);
    if ($line =~ /^args:/) {
      my $new_line = $line;

      $new_line =~ s| -lrms +[^-]*| -lrms $batchtype |g;
      $new_line =~ s| -cluster-batch-system-bin-path +[^-]*| -cluster-batch-system-bin-path $batchpath |g;
      $new_line =~ s| -queue +[^-]*| -queue $batchqueue |g;
      $new_line =~ s| -cluster +[^-]*| -cluster $my_fqhn |g;

      print GCOUT $new_line."\n";
      next;
    }
    print GCOUT $line."\n";
  }
  close(GCOUT);
  close(GCIN);

  my_rename("grid-info-slapd.conf");
  $res = system("cp grid-info-slapd.conf.TEMPLATE grid-info-slapd.conf");
  my_fatal("Could not copy grid-info-slapd.conf.TEMPLATE into place") if $res;

  my_chdir("/opt/vdt/mds-2.2/etc/ldif");
  my_rename("glue-ce-static.ldif");

  open(GCIN,"< glue-ce-static.ldif.orig") ||
    my_fatal("Could not read from glue-ce-static.ldif.orig");
  open(GCOUT,"> glue-ce-static.ldif") ||
    my_fatal("Could not write to glue-ce-static.ldif");

  while(<GCIN>) {
    my $line; chomp($line=$_);
    $line =~ s|lxshare0247\.cern\.ch|$my_fqhn|g;
    print GCOUT $line."\n";
  }
  close(GCOUT);
  close(GCIN);
  
  my_rename("glue-ce-se-bind.ldif");
  open(GCIN,"< glue-ce-se-bind.ldif.TEMPLATE") ||
    my_fatal("Could not read from glue-ce-se-bind.ldif.TEMPLATE");
  open(GCOUT,"> glue-ce-se-bind.ldif") ||
    my_fatal("Could not write to glue-ce-se-bind.ldif");
  while(<GCIN>) {
    my $line; chomp($line=$_);
    $line =~ s|lxshare0247\.cern\.ch|$my_fqhn|g;
    $line =~ s|jobmanager-pbs-workq|$my_jm|g;
    $line =~ s|lxshare0206\.cern\.ch|$se_fqhn|g;
    print GCOUT $line."\n";
  }
  close(GCOUT);
  close(GCIN);

  $res = system("/opt/vdt/mds-2.2/etc/hostdata.sh > /opt/vdt/mds-2.2/etc/subcluster.data");
  my_fatal("Could not run hostdata.sh") if $res;
}

sub rewrite_globus_conf {
  open(GCIN,"< /etc/globus.conf.TEMPLATE") || my_fatal("Could not open /etc/globus.conf.TEMPLATE for reading");
  open(GCOUT,"> /etc/globus.conf") || my_fatal("Could not open /etc/globus.conf for writing");

  while(<GCIN>) {
    my $line; chomp($line = $_);
    if ($line =~ /^GLOBUS_GATEKEEPER_SUBJECT=/) {
      print GCOUT "GLOBUS_GATEKEEPER_SUBJECT=\"".$hostsubject."\"\n";
      next;
    }
    if ($line =~ /^GLOBUS_HOST_DN=/) {
      print GCOUT "GLOBUS_HOST_DN=\"".$dn_host."\"\n";
      next;
    }
    if ($line =~ /^GLOBUS_ORG_DN=/) {
      print GCOUT "GLOBUS_ORG_DN=\"".$dn_org."\"\n";
      next;
    }
    if ($line =~ /^GLOBUS_GATEKEEPER_HOST=/) {
      print GCOUT "GLOBUS_GATEKEEPER_HOST=\"".$nname.".".$dname."\"\n";
      next;
    }
    if ($line =~ /^GLOBUS_JOBMANAGERS=/) {
      print GCOUT "GLOBUS_JOBMANAGERS=\"fork ".lc($batchtype)."\"\n";
      next;
    }
    if ($line =~ /^GRID_INFO_GRIS_REG_HOST=/) {
      print GCOUT "GRID_INFO_GRIS_REG_HOST=".$nname.".".$dname."\n";
      next;
    }
    if ($line =~ /^GRID_INFO_USER=/) {
      print GCOUT "GRID_INFO_USER=".$infouser."\n";
      next;
    }
    if ($line =~ /^GLOBUS_GRAM_JOB_MANAGER_QSUB=/) {
      print GCOUT "GLOBUS_GRAM_JOB_MANAGER_QSUB=".$batchpath."/qsub\n";
      next;
    }
    if ($line =~ /^GLOBUS_GRAM_JOB_MANAGER_QDEL=/) {
      print GCOUT "GLOBUS_GRAM_JOB_MANAGER_QDEL=".$batchpath."/qdel\n";
      next;
    }
    if ($line =~ /^GLOBUS_GRAM_JOB_MANAGER_QSTAT=/) {
      print GCOUT "GLOBUS_GRAM_JOB_MANAGER_QSTAT=".$batchpath."/qstat\n";
      next;
    }
    if ($line =~ /^GLOBUS_GRAM_JOB_MANAGER_MPIRUN=/) {
      print GCOUT "GLOBUS_GRAM_JOB_MANAGER_MPIRUN=".$batchpath."/qrun\n";
      next;
    }
    if ($line =~ /^GLOBUS_GRAM_JOB_MANAGER_QSELECT=/) {
      print GCOUT "GLOBUS_GRAM_JOB_MANAGER_QSELECT=".$batchpath."/qselect\n";
      next;
    }
    print GCOUT $line."\n";
  }
  close(GCOUT);
  close(GCIN);
}

sub get_host_dn_params {
  open(SSL,"openssl x509 -noout -subject < /etc/grid-security/hostcert.pem |") ||
    my_fatal("Could not pipe from openssl");

  my $ok=0;
  while(<SSL>) {
    if (/subject= *(.*)/) {
      $hostsubject = $1;
      $ok=1;
    }
  }
  close(SSL);
  my_fatal("Could not get host subject from hostcert.pem file") unless $ok;

  $dn_org = "";
  foreach my $dn_part (split('\.',$dname)) {
    $dn_org .= "dc=".$dn_part.", ";
  }
 $dn_org .= "o=Grid";

 $dn_host = "hn=".$nname.".".$dname.", ".$dn_org;
}

sub add_to_ld {
  my @list = @_;

  my %found;
  my %in_list;

  my @output;

  foreach my $path (@list) {
    $in_list{$path} = 1;
  }

  open(LDCONF,"< /etc/ld.so.conf") || my_fatal("Could not open /etc/ld.so.conf for reading");
  while(<LDCONF>) {
    my $line; chomp($line = $_);

    if (!defined $found{$line} &&
        !defined $in_list{$line}) {
      push(@output,$line);
      $found{$line} = 1;
    }
  }
  close(LDCONF);

  foreach my $path (@list) {
    push(@output,$path);
  }

  open(LDCONF,"> /etc/ld.so.conf") || my_fatal("Could not open /etc/ld.so.conf for writing");
  foreach my $path (@output) {
    print LDCONF $path."\n";
  }
  close(LDCONF);

  my $res = system("/sbin/ldconfig -v > /dev/null 2>&1");
  my_fatal("ldconfig returned non zero return code") if $res;
}

sub my_chdir {
  my ($dir) = @_;

  chdir $dir || my_fatal("Could not chdir to $dir");
}


sub verify_batch_params {
  if ($batchtype ne "PBS") {
    my_print("Unknown batch system type $batchtype");
    return 1;
  }

  my $missing=0;
  $missing++ if ( ! -e "$batchpath/qrun" );
  $missing++ if ( ! -e "$batchpath/qdel" );
  $missing++ if ( ! -e "$batchpath/qstat" );
  $missing++ if ( ! -e "$batchpath/qsub" );
  $missing++ if ( ! -e "$batchpath/qselect" );
  $missing++ if ( ! -e "$batchpath/qmgr" );

  if ($missing) {
    my_print("Could not find all the required PBS commands under $batchpath");
    return 1;
  }

  my $tf = "/tmp/ce-install-temp.$$";
  open(OUT,"> ".$tf) || my_fatal("Could not write temporary file $tf");
  print OUT "p q $batchqueue\n";
  print OUT "quit\n";
  close(OUT);

  my $qok = 1;
  open(QMGR,$batchpath."/qmgr < ".$tf." 2>&1 |") || my_fatal("Could not open pipe from qmgr");
  while(<QMGR>) {
    my $line = $_;
    $qok = 0 if $line =~ /Unknown queue/;
  }
  close(QMGR);
  unlink $tf;

  if (!$qok) {
    my_print("Could not verify that queue $batchqueue exists");
    return 1;
  }
  return 0;
}

sub install_list {
  my @list = @_;
  my $listname = "file.cgi?version=LCG-0";
  my $res;

  print "Fetching list of LCG components from distribution site...";
  $res = system("wget -nd \"http://grid-deployment.web.cern.ch/grid-deployment/cgi-bin/".$listname."\"".
                " > /dev/null 2>&1");
  if ($res) {
    print "\n";
    my_fatal("wget returned non zero exit status, could not get component list");
  }
  print " Done\n";

  my @cgi_list;
  open(CGILIST,"< ".$listname) ||
    my_fatal("Could not open component list");
  while(<CGILIST>) {
    my $line; chomp($line = $_);
    if ($line =~ /href=\" *([^\" ]*) *\"/) {
      my $addr = $1;
      push(@cgi_list,$addr);
    }
  }
  close(CGILIST);

  my @fullname_list;
  foreach my $item (@list) {
    my ($args,$filename) = split(':',$item);
    my $fullname = $filename;
    $res = lookup_from_cgi_list(\@cgi_list,\$fullname);
    my_fatal("Could not find $filename on LCG component server") if $res;
    push(@fullname_list,$args."|".$fullname."|".$filename);
  }

  foreach my $item (@fullname_list) {
    my ($args,$fullname,$filename) = split('\|',$item);

    my_fatal("Fatal, malformed installation component $item")
      if (!defined $filename || $filename eq "" ||
          !defined $fullname || $fullname eq "" );

    my $ftype;
    if ($filename =~ /^(.*)\.([^.]*)$/) {
      $ftype = $2;
    }

    my_fatal("Fatal, malformed installation component $item") unless defined $ftype;
    my_fatal("Fatal, unknown file type for $item")
      if ($ftype ne "rpm" && $ftype ne "tar" && $ftype ne "tgz");

    my $inst_prog = "tar";
    $inst_prog = "rpm" if $ftype eq "rpm";

    print "Fetching ".$filename."...";
    $res = system("wget -nd \"".$fullname."\" > /dev/null 2>&1");

    if ($res || ! -e $filename) {
      print "\n";
      my_fatal("wget returned non zero exit status while retrieving $filename ($fullname)") if $res;
      my_fatal("Could not find $filename");
    }

    my $command = $inst_prog." ".$args." ".$filename." > /dev/null 2>&1";
    print " Now installing\n";
    my $res = system($command);
    my_fatal("Command:\n\n$command\n\nreturned non zero return status") if $res;
  }
}

sub my_fatal {
  my ($line) = @_;

  my_print("Fatal: ".$line);
  exit 1;
}

sub my_print {
  my ($line) = @_;

  print $progname.": ".$line."\n";
}

sub parse_args {
  my @args = @_;

  if (scalar(@args) == 9) {
    my $res;

    $lcguname = $args[1];
    $hostcert = $args[2];
    $hostkey = $args[3];
    $infouser = $args[5];
    $batchtype = uc($args[6]);
    $batchpath = $args[7];
    $batchqueue = $args[8];
    $res = parse_fqhn(\$nname,\$dname,$args[0]);
    my_fatal("Bad host name") if $res;
    $res = parse_fqhn(\$sename,\$sedomain,$args[4]);
    my_fatal("Bad close SE name") if $res;

    my $uname;
    open(COM,"uname -n|") || my_fatal("Could not open pipe from uname");
    chomp($uname=<COM>);
    close(COM);
    $uname =~  s/\..*//;

    if ($nname ne $uname) {
      my_print("Warning: the machine name you gave ($nname) does not match node name ($uname)");
      print "\nThe name you gave for this machine does not match up with the node name".
            "\nIf this is correct please type 'ok' at the prompt: ===>";
      chomp(my $answer = <STDIN>);
      my_fatal("Machine name does not match node name") if lc($answer) ne "ok";
      print "\n";
    }
    if ($dname ne $sedomain) {
      my_print("Warning: the domain name for this machine ($dname) and".
               " that of the close SE ($sedomain) do not match");
      print "\nThe domain names of the CE and the close SE are different".
            "\nIf this is correct please type 'ok' at the prompt: ===>";
      chomp(my $answer = <STDIN>);
      my_fatal("Machine domain name does not match close SE domain name") if lc($answer) ne "ok";
      print "\n";
    }

    if (verify_username($lcguname)) {
      my_fatal("Username $lcguname does not exist");
      # NOT REACHED #
      return 1;
    }

    if (verify_username($infouser)) {
      my_fatal("Username $infouser does not exist");
      # NOT REACHED #
      return 1;
    }

    if ($lcguname eq $infouser) {
      my_fatal("The grid user and the info user should be different");
      # NOT REACHED #
      return 1;
    }

    if ( !defined($hostcert) || !defined($hostkey) ||
         ! -e "$hostcert" || ! -e "$hostkey" ) {
      my_fatal("Could not verify that the host keys exist");
      # NOT REACHED #
      return 1;
    }
    my_fullpath(\$hostcert);
    my_fullpath(\$hostkey);

    if (verify_host_pair($hostcert,$hostkey)) {
      my_fatal("Could not verify that the hostcert - hostkey pair correspond");
      # NOT REACHED #
      return 1;
    }

    $batchpath =~ s|//*|/|g;
    $batchpath =~ s|/+$||;
    $batchpath = '/' if $batchpath eq "";
    my_fullpath(\$batchpath);
    if (verify_batch_params()) {
      my_fatal("Error verifying batch system parameters");
      # NOT REACHED #
      return 1;
    }
    return 0;
  }
  return 1;
}

sub verify_username {
  my ($name) = @_;

  my ($login,$pass,$uid,$gid) = getpwnam($name);
  return 1 unless defined $uid;

  return 0;
}

sub parse_fqhn {
  my ($host_ref,$domain_ref,$fqhn) = @_;

  ($$host_ref,$$domain_ref) = split('\.',$fqhn,2);

  if ($$host_ref eq "" || !defined $$domain_ref || $$domain_ref eq "") {
    my_print("Warning: could not get machine name and domain name from $fqhn");
    return 1;
  }

  my $null_element = 0;
  foreach my $domain_element (split('\.',$$domain_ref,-1)) {
    $null_element++ if $domain_element eq "";
  }
  if ($null_element) {
    my_print("Warning: invalid domain name (".$$domain_ref.")");
    return 1;
  }

  return 0;
}

sub do_main {
  my @args = @_;
  my $res;

  my_fatal("This script must be run with the effective id of root") if $> != 0;

  chomp(my $init_pwd=`pwd`);
  my $my_tdir = $init_pwd."/rpm_lcg";

  $res = parse_args(@args);
  if ($res) {
    print "\nUsage: $progname\n".'
       <hostname.domain>    The fully qualified name of this machine
       <lcguname>           The username of the grid user
       <hostcert.pem>       Location of a copy of the host certificate
       <hostkey.pem>        Location of a copy of the host certificate key
       <closese.domain>     The fully qualified name of the close storage element
       <infouname>          The username of the info user
       <Batch system>       Type of batch system: currently only type PBS is supported
       <Batch system path>  Path under which to find the batch system commands
       <Batch queue>        The batch queue name that grid jobs should be submitted to
    '."\n";
    exit 1;
  }

  print "\n ++ Starting the installation of LCG Compute Element ++ \n\n";

  my @install_files = (
    "xPfvz:globus_VDT_CE.tgz",
    "-ivh:GNU.LANG_gcc-alt-2.95.2-6.i386.rpm",
    "-ivh:BrokerInfo-gcc32-3.2-0.i386.rpm",
    "-ivh:ReplicaCatalogue-gcc32-3.2-3.i386.rpm",
    "-ivh:edg-replica-manager-gcc32-2.0-6.i386.rpm",
    "-ivh --nodeps:workload-profile-1.2.19-1.i386.rpm",
    "-ivh --nodeps:locallogger-profile-1.2.21-1.i386.rpm",
    "-ivh:locallogger-1.2.21-1.i386.rpm",
    "-ivh:globus_gatekeeper-edgconfig-0.17-nodep.1.noarch.rpm",
    "-ivh:globus_gsi_wuftpd-edgconfig-0.17-nodep2.noarch.rpm",
    "-ivh:globus_profile-edgconfig-0.17-nodep.noarch.rpm",
    "-ivh:edg-user-env-0.3-1.noarch.rpm",
    "-ivh:edg-profile-0.3-1.noarch.rpm",
    "-ivh:perl-Convert-ASN1-0.16-7.i386.rpm",
    "-ivh:perl-Net_SSLeay-1.21-7.i386.rpm",
    "-ivh:perl-IO-Socket-SSL-0.92-7.i386.rpm",
    "-ivh:perl-perl-ldap-0.26-7.i386.rpm",
    "-ivh:edg-mkgridmap-1.0.9-2.i386.rpm",
    "-ivh --nodeps:edg-utils-system-1.3.2-1.noarch.rpm");

  my_fatal("Temporary directory $my_tdir already exists") if ( -e $my_tdir );
  mkdir($my_tdir, 0755) || my_fatal("Could not mkdir ".$my_tdir);
  my_chdir($my_tdir);

  install_list(@install_files);
  my_chdir("..");
#  $res = system("rm -rf rpm_lcg");
#  my_fatal("rm -rf rpm_lcg returned non zero exit status") if $res;

  my @add_ld_list = ("/opt/globus/lib","/opt/edg/lib","/opt/globus-24/lib");
  add_to_ld(@add_ld_list);

  if ($hostcert ne "/etc/grid-security/hostcert.pem") {
    $res = system("cp -f ".$hostcert." /etc/grid-security/hostcert.pem");
    my_fatal("could not copy $hostcert") if $res;
  }
  if ($hostkey ne "/etc/grid-security/hostkey.pem") {
    $res = system("cp -f ".$hostkey." /etc/grid-security/hostkey.pem");
    my_fatal("could not copy $hostkey") if $res;
  }

  chown 0, 0, "/etc/grid-security/hostcert.pem" || my_fatal("Could not chown hostcert.pem");
  chown 0, 0, "/etc/grid-security/hostkey.pem" || my_fatal("Could not chown hostkey.pem");
  chmod 0644, "/etc/grid-security/hostcert.pem" || my_fatal("Could not chmod hostcert.pem");
  chmod 0400, "/etc/grid-security/hostkey.pem" || my_fatal("Could not chmod hostkey.pem");

  verify_host_from_good_ca();

  get_host_dn_params();
  rewrite_globus_conf();

  exec_globus_postinstall();

  rewrite_glue_confs();
  rewrite_mkgridmap_conf();
  init_gridmap_file();

  update_services();
  update_startup_scripts($my_tdir);

  update_file_max();

  $res = system("cp -f /opt/edg/etc/lcg/rc.conf.TEMPLATE /opt/edg/etc/lcg/rc.conf");
  my_fatal("Could not copy rc.conf into place") if $res;

  print "LCG CE install completed\n";
  print "Leaving temporary directory ".$my_tdir." for reference\n";
}
